Skip to content

Commit 6944a21

Browse files
committed
Add MCP support
Signed-off-by: Stan Lo <stan.lo@shopify.com>
1 parent 1506268 commit 6944a21

File tree

15 files changed

+3940
-1
lines changed

15 files changed

+3940
-1
lines changed

.cursor/mcp.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"mcpServers": {
3+
"rubyMcp": {
4+
"command": "./.ruby-lsp/ruby-mcp-bridge"
5+
}
6+
}
7+
}

.vscode/mcp.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"inputs": [],
3+
"servers": {
4+
"rubyMcp": {
5+
"type": "stdio",
6+
"command": "${workspaceFolder}/.ruby-lsp/ruby-mcp-bridge"
7+
}
8+
}
9+
}

Gemfile.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ PATH
22
remote: .
33
specs:
44
ruby-lsp (0.23.24)
5+
json_rpc_handler (~> 0.1.1)
56
language_server-protocol (~> 3.17.0)
67
prism (>= 1.2, < 2.0)
78
rbs (>= 3, < 5)
89
sorbet-runtime (>= 0.5.10782)
10+
webrick (>= 1.8)
911

1012
GEM
1113
remote: https://rubygems.org/
@@ -23,6 +25,7 @@ GEM
2325
rdoc (>= 4.0.0)
2426
reline (>= 0.4.2)
2527
json (2.10.2)
28+
json_rpc_handler (0.1.1)
2629
language_server-protocol (3.17.0.4)
2730
lint_roller (1.1.0)
2831
logger (1.7.0)
@@ -117,6 +120,7 @@ GEM
117120
unicode-display_width (3.1.4)
118121
unicode-emoji (~> 4.0, >= 4.0.4)
119122
unicode-emoji (4.0.4)
123+
webrick (1.9.1)
120124
yard (0.9.37)
121125
yard-sorbet (0.9.0)
122126
sorbet-runtime

lib/ruby_lsp/global_state.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ class GlobalState
3333
#: String?
3434
attr_reader :telemetry_machine_id
3535

36+
#: bool
37+
attr_reader :uses_ruby_mcp
38+
3639
#: -> void
3740
def initialize
3841
@workspace_uri = URI::Generic.from_path(path: Dir.pwd) #: URI::Generic
@@ -56,6 +59,7 @@ def initialize
5659
@enabled_feature_flags = {} #: Hash[Symbol, bool]
5760
@mutex = Mutex.new #: Mutex
5861
@telemetry_machine_id = nil #: String?
62+
@uses_ruby_mcp = false #: bool
5963
end
6064

6165
#: [T] { -> T } -> T
@@ -151,6 +155,9 @@ def apply_options(options)
151155
)
152156
end
153157

158+
@uses_ruby_mcp = detects_ruby_mcp
159+
notifications << Notification.window_log_message("Uses Ruby MCP: #{@uses_ruby_mcp}")
160+
154161
encodings = options.dig(:capabilities, :general, :positionEncodings)
155162
@encoding = if !encodings || encodings.empty?
156163
Encoding::UTF_16LE
@@ -205,8 +212,30 @@ def supports_watching_files
205212
@client_capabilities.supports_watching_files
206213
end
207214

215+
#: -> bool
216+
def detects_ruby_mcp
217+
check_mcp_file(".vscode/mcp.json", ["servers", "rubyMcp"]) ||
218+
check_mcp_file(".cursor/mcp.json", ["mcpServers", "rubyMcp"])
219+
end
220+
208221
private
209222

223+
# Helper method to check for rubyMcp configuration in a specific file
224+
#: (String relative_path, Array[String] keys_to_check) -> bool
225+
def check_mcp_file(relative_path, keys_to_check)
226+
file_path = File.join(workspace_path, relative_path)
227+
return false unless File.exist?(file_path)
228+
229+
begin
230+
config = JSON.parse(File.read(file_path))
231+
# Check if the nested keys exist
232+
!!config.dig(*keys_to_check)
233+
rescue JSON::ParserError
234+
# If JSON parsing fails, consider it not configured
235+
false
236+
end
237+
end
238+
210239
#: (Array[String] direct_dependencies, Array[String] all_dependencies) -> String
211240
def detect_formatter(direct_dependencies, all_dependencies)
212241
# NOTE: Intentionally no $ at end, since we want to match rubocop-shopify, etc.

lib/ruby_lsp/internal.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
require "securerandom"
3232
require "shellwords"
3333
require "set"
34+
require "webrick"
35+
require "json_rpc_handler"
3436

3537
require "ruby-lsp"
3638
require "ruby_lsp/base_server"
@@ -41,6 +43,7 @@
4143
require "ruby_lsp/client_capabilities"
4244
require "ruby_lsp/global_state"
4345
require "ruby_lsp/server"
46+
require "ruby_lsp/mcp_server"
4447
require "ruby_lsp/type_inferrer"
4548
require "ruby_lsp/node_context"
4649
require "ruby_lsp/document"

0 commit comments

Comments
 (0)