Skip to content

Commit 87ef436

Browse files
committed
Drop webrick
1 parent fd62980 commit 87ef436

File tree

8 files changed

+66
-2957
lines changed

8 files changed

+66
-2957
lines changed

Gemfile.lock

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ PATH
66
prism (>= 1.2, < 2.0)
77
rbs (>= 3, < 5)
88
sorbet-runtime (>= 0.5.10782)
9-
webrick (>= 1.8)
109

1110
GEM
1211
remote: https://rubygems.org/
@@ -118,7 +117,6 @@ GEM
118117
unicode-display_width (3.1.4)
119118
unicode-emoji (~> 4.0, >= 4.0.4)
120119
unicode-emoji (4.0.4)
121-
webrick (1.9.1)
122120
yard (0.9.37)
123121
yard-sorbet (0.9.0)
124122
sorbet-runtime

lib/ruby_lsp/internal.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
require "open3"
3131
require "securerandom"
3232
require "shellwords"
33-
require "webrick"
3433

3534
require "ruby-lsp"
3635
require "ruby_lsp/base_server"

lib/ruby_lsp/mcp_server.rb

Lines changed: 45 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# frozen_string_literal: true
33

44
require "ruby_lsp/mcp/tool"
5+
require "socket"
56

67
module RubyLsp
78
class MCPServer
@@ -35,21 +36,12 @@ def initialize(global_state)
3536
FileUtils.mkdir_p(lsp_dir)
3637

3738
# Write port to file
38-
port_file = File.join(lsp_dir, "mcp-port")
39-
File.write(port_file, @port.to_s)
40-
41-
# Create WEBrick server
42-
@server = WEBrick::HTTPServer.new(
43-
Port: @port,
44-
BindAddress: "127.0.0.1",
45-
Logger: WEBrick::Log.new(File.join(lsp_dir, "mcp-webrick.log")),
46-
AccessLog: [],
47-
) #: WEBrick::HTTPServer
48-
49-
# Mount the MCP handler
50-
@server.mount_proc("/mcp") do |req, res|
51-
handle_mcp_request(req, res)
52-
end
39+
@port_file = File.join(lsp_dir, "mcp-port") #: String
40+
File.write(@port_file, @port.to_s)
41+
42+
# Create TCP server
43+
@server = TCPServer.new("127.0.0.1", @port) #: TCPServer
44+
@server_thread = nil #: Thread?
5345

5446
@running = false #: T::Boolean
5547
@global_state = global_state #: GlobalState
@@ -58,75 +50,64 @@ def initialize(global_state)
5850

5951
#: -> void
6052
def start
61-
puts "[MCP] Server started on TCP port #{@port}"
62-
Thread.new do
63-
@server.start
53+
puts "[MCP] Server started on port #{@port}"
54+
@running = true
55+
56+
@server_thread = Thread.new do
57+
while @running
58+
begin
59+
# Accept incoming connections
60+
client = @server.accept
61+
62+
# Handle each client in a separate thread
63+
Thread.new(client) do |client_socket|
64+
handle_client(client_socket)
65+
end
66+
rescue => e
67+
puts "[MCP] Error accepting connection: #{e.message}" if @running
68+
end
69+
end
6470
end
6571
end
6672

6773
#: -> void
6874
def stop
69-
puts "[MCP] Stopping server"
70-
@server.shutdown
75+
puts "[MCP] Server stopping"
76+
@running = false
77+
@server.close
78+
@server_thread&.join
7179
ensure
72-
# Clean up port file
73-
lsp_dir = File.join(@workspace_path, ".ruby-lsp")
74-
port_file = File.join(lsp_dir, "mcp-port")
75-
File.delete(port_file) if File.exist?(port_file)
76-
77-
# Clean up log file
78-
log_file = File.join(lsp_dir, "mcp-webrick.log")
79-
File.delete(log_file) if File.exist?(log_file)
80+
File.delete(@port_file) if File.exist?(@port_file)
8081
end
8182

8283
private
8384

84-
#: (WEBrick::HTTPRequest, WEBrick::HTTPResponse) -> void
85-
def handle_mcp_request(request, response)
86-
body = request.body || ""
85+
#: (TCPSocket) -> void
86+
def handle_client(client_socket)
87+
# Read JSON-RPC request from client
88+
request_line = client_socket.gets
89+
return unless request_line
8790

88-
puts "[MCP] Received request: #{body}"
91+
request_line = request_line.strip
8992

90-
result = process_jsonrpc_request(body)
93+
# Process the JSON-RPC request
94+
response = process_jsonrpc_request(request_line)
9195

92-
if result.nil?
93-
response.status = 500
94-
response.body = {
95-
jsonrpc: "2.0",
96-
id: nil,
97-
error: {
98-
code: ErrorCode::INTERNAL_ERROR,
99-
message: "Internal error",
100-
data: "No response from the server",
101-
},
102-
}.to_json
103-
else
104-
response.status = 200
105-
response.content_type = "application/json"
106-
response.body = result
96+
if response
97+
client_socket.puts(response)
10798
end
108-
109-
puts "[MCP] Sent response: #{response.body}"
11099
rescue => e
111-
puts "[MCP] Error processing request: #{e.message}"
112-
puts e.backtrace&.join("\n")
100+
puts "[MCP] Client error: #{e.message}"
113101

114-
response.status = 500
115-
response.body = {
116-
jsonrpc: "2.0",
117-
id: nil,
118-
error: {
119-
code: ErrorCode::INTERNAL_ERROR,
120-
message: "Internal error",
121-
data: e.message,
122-
},
123-
}.to_json
102+
# Send error response
103+
error_response = generate_error_response(nil, ErrorCode::INTERNAL_ERROR, "Internal error", e.message)
104+
client_socket.puts(error_response)
105+
ensure
106+
client_socket.close
124107
end
125108

126109
#: (String) -> String?
127110
def process_jsonrpc_request(json)
128-
puts "[MCP] Processing request: #{json.inspect}"
129-
130111
# Parse JSON
131112
begin
132113
request = JSON.parse(json, symbolize_names: true)
@@ -193,7 +174,6 @@ def process_request(method_name, params)
193174
end,
194175
}
195176
when "tools/call"
196-
puts "[MCP] Received tools/call request: #{params.inspect}"
197177
tool_name = params[:name]
198178
tool_class = RubyLsp::MCP::Tool.get(tool_name)
199179

ruby-lsp.gemspec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ Gem::Specification.new do |s|
2323
s.add_dependency("prism", ">= 1.2", "< 2.0")
2424
s.add_dependency("rbs", ">= 3", "< 5")
2525
s.add_dependency("sorbet-runtime", ">= 0.5.10782")
26-
s.add_dependency("webrick", ">= 1.8")
2726

2827
s.required_ruby_version = ">= 3.0"
2928
end

0 commit comments

Comments
 (0)