diff --git a/.gitignore b/.gitignore
index 21c2ae9f8c74d796449fe31b4e726e08e9d21795..0199e0b6b9a209d725510aa6589fab9edd2133c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 .rtclientrc
 *.cookie
+config.yml
 
 # Ignore patterns for Ruby
 *.gem
diff --git a/Gemfile b/Gemfile
index 496d59b7088ebd2df31c681e554cd0bcf66705ba..131d7b8935ddca76625bcc704af262956bcf2f68 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,8 +4,12 @@ source 'https://rubygems.org'
 
 gem 'rt-client', '~> 1.0'
 gem 'sinatra', '~> 2.0'
+gem 'sinatra-contrib', '~> 2.0'
 
 group :development do
+  gem 'pry', '~> 0.12.2'
+  gem 'pry-byebug', '~> 3.7'
   gem 'rerun', '~> 0.13.0', require: false
   gem 'rubocop', '~> 0.76.0', require: false
+  gem 'solargraph'
 end
diff --git a/Gemfile.lock b/Gemfile.lock
index c57e5459f17a42807cf45f01d253d33472439282..ff4ec94100d25f0ef28597d1b40236f0732760d2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -2,9 +2,14 @@ GEM
   remote: https://rubygems.org/
   specs:
     ast (2.4.0)
+    backport (1.1.2)
+    backports (3.15.0)
+    byebug (11.0.1)
+    coderay (1.1.2)
     domain_name (0.5.20190701)
       unf (>= 0.0.5, < 1.0.0)
     ffi (1.11.2)
+    htmlentities (4.3.4)
     http-accept (1.7.0)
     http-cookie (1.0.3)
       domain_name (~> 0.5)
@@ -12,14 +17,25 @@ GEM
     listen (3.2.0)
       rb-fsevent (~> 0.10, >= 0.10.3)
       rb-inotify (~> 0.9, >= 0.9.10)
+    method_source (0.9.2)
     mime-types (3.3)
       mime-types-data (~> 3.2015)
     mime-types-data (3.2019.1009)
+    mini_portile2 (2.4.0)
+    multi_json (1.14.1)
     mustermann (1.0.3)
     netrc (0.11.0)
+    nokogiri (1.10.5)
+      mini_portile2 (~> 2.4.0)
     parallel (1.19.0)
     parser (2.6.5.0)
       ast (~> 2.4.0)
+    pry (0.12.2)
+      coderay (~> 1.1.0)
+      method_source (~> 0.9.0)
+    pry-byebug (3.7.0)
+      byebug (~> 11.0)
+      pry (~> 0.10)
     rack (2.0.7)
     rack-protection (2.0.7)
       rack
@@ -34,6 +50,8 @@ GEM
       http-cookie (>= 1.0.2, < 2.0)
       mime-types (>= 1.16, < 4.0)
       netrc (~> 0.8)
+    reverse_markdown (1.3.0)
+      nokogiri
     rt-client (1.0.2)
       rest-client (~> 2.0, >= 2.0.0)
     rubocop (0.76.0)
@@ -49,20 +67,45 @@ GEM
       rack (~> 2.0)
       rack-protection (= 2.0.7)
       tilt (~> 2.0)
+    sinatra-contrib (2.0.7)
+      backports (>= 2.8.2)
+      multi_json
+      mustermann (~> 1.0)
+      rack-protection (= 2.0.7)
+      sinatra (= 2.0.7)
+      tilt (~> 2.0)
+    solargraph (0.37.2)
+      backport (~> 1.1)
+      bundler (>= 1.17.2)
+      htmlentities (~> 4.3, >= 4.3.4)
+      jaro_winkler (~> 1.5)
+      nokogiri (~> 1.9, >= 1.9.1)
+      parser (~> 2.3)
+      reverse_markdown (~> 1.0, >= 1.0.5)
+      rubocop (~> 0.52)
+      thor (~> 0.19, >= 0.19.4)
+      tilt (~> 2.0)
+      yard (~> 0.9)
+    thor (0.20.3)
     tilt (2.0.10)
     unf (0.1.4)
       unf_ext
     unf_ext (0.0.7.6)
     unicode-display_width (1.6.0)
+    yard (0.9.20)
 
 PLATFORMS
   ruby
 
 DEPENDENCIES
+  pry (~> 0.12.2)
+  pry-byebug (~> 3.7)
   rerun (~> 0.13.0)
   rt-client (~> 1.0)
   rubocop (~> 0.76.0)
   sinatra (~> 2.0)
+  sinatra-contrib (~> 2.0)
+  solargraph
 
 BUNDLED WITH
    2.0.2
diff --git a/config.sample.yml b/config.sample.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a7b68e3bf72b0cfb33c3be6b80e9e903cf7335f5
--- /dev/null
+++ b/config.sample.yml
@@ -0,0 +1,7 @@
+---
+issue_tag: RT
+rt:
+  server: https://rt.example.org/
+  user: gl-bridge
+  pass: hunter2
+  cookies: /srv/www/gl-rt-bridge
diff --git a/gl-rt-bridge.rb b/gl-rt-bridge.rb
index 69a358ad172b9cf71123a3d5ee1bdc36fde57229..b148c27dd73d5d079de722b332acc0bca3b193d3 100755
--- a/gl-rt-bridge.rb
+++ b/gl-rt-bridge.rb
@@ -4,10 +4,16 @@
 require 'rt_client'
 require 'set'
 require 'sinatra'
+require 'sinatra/config_file'
 
-ISSUE_TAG = 'FSMPI'
+config_file 'config.yml'
 
-rt = RT_Client.new
+rx = /#{settings.issue_tag}[ -]?#(\d+)/
+
+rt = RT_Client.new(server: settings.rt[:server],
+                   user: settings.rt[:user],
+                   pass: settings.rt[:pass],
+                   cookies: settings.rt[:cookies])
 
 post '/' do # rubocop:disable Metrics/BlockLength
   gitlab_event = request.env['HTTP_X_GITLAB_EVENT']
@@ -18,7 +24,7 @@ post '/' do # rubocop:disable Metrics/BlockLength
     # results is a Hash mapping an issue to a set of commits referring to it
     results = {}
     d[:commits].each do |c|
-      issues = c[:message].scan(/#{ISSUE_TAG}[ -]?#(\d+)/)
+      issues = c[:message].scan rx
       # String#scan always returns a list of lists when using capture groups,
       # even if it's only one
       issues.each do |i, _|