Skip to content

Commit 40b048b

Browse files
authored
Merge pull request #294 from koic/post_response_sse_stream
Support POST response SSE streams for server-to-client messages
2 parents 0d700d7 + 8278ca6 commit 40b048b

File tree

10 files changed

+671
-154
lines changed

10 files changed

+671
-154
lines changed

lib/json_rpc_handler.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def process_request(request, id_validation_pattern:, &method_finder)
9292
end
9393

9494
begin
95-
method = method_finder.call(method_name)
95+
method = method_finder.call(method_name, id)
9696

9797
if method.nil?
9898
return error_response(id: id, id_validation_pattern: id_validation_pattern, error: {

lib/mcp/progress.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
module MCP
44
class Progress
5-
def initialize(notification_target:, progress_token:)
5+
def initialize(notification_target:, progress_token:, related_request_id: nil)
66
@notification_target = notification_target
77
@progress_token = progress_token
8+
@related_request_id = related_request_id
89
end
910

1011
def report(progress, total: nil, message: nil)
@@ -16,6 +17,7 @@ def report(progress, total: nil, message: nil)
1617
progress: progress,
1718
total: total,
1819
message: message,
20+
related_request_id: @related_request_id,
1921
)
2022
end
2123
end

lib/mcp/server.rb

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ def initialize(
127127
# When `nil`, progress and logging notifications from tool handlers are silently skipped.
128128
# @return [Hash, nil] The JSON-RPC response, or `nil` for notifications.
129129
def handle(request, session: nil)
130-
JsonRpcHandler.handle(request) do |method|
131-
handle_request(request, method, session: session)
130+
JsonRpcHandler.handle(request) do |method, request_id|
131+
handle_request(request, method, session: session, related_request_id: request_id)
132132
end
133133
end
134134

@@ -140,8 +140,8 @@ def handle(request, session: nil)
140140
# When `nil`, progress and logging notifications from tool handlers are silently skipped.
141141
# @return [String, nil] The JSON-RPC response as JSON, or `nil` for notifications.
142142
def handle_json(request, session: nil)
143-
JsonRpcHandler.handle_json(request) do |method|
144-
handle_request(request, method, session: session)
143+
JsonRpcHandler.handle_json(request) do |method, request_id|
144+
handle_request(request, method, session: session, related_request_id: request_id)
145145
end
146146
end
147147

@@ -220,7 +220,8 @@ def create_sampling_message(
220220
stop_sequences: nil,
221221
metadata: nil,
222222
tools: nil,
223-
tool_choice: nil
223+
tool_choice: nil,
224+
related_request_id: nil
224225
)
225226
unless @transport
226227
raise "Cannot send sampling request without a transport."
@@ -371,7 +372,7 @@ def schema_contains_ref?(schema)
371372
end
372373
end
373374

374-
def handle_request(request, method, session: nil)
375+
def handle_request(request, method, session: nil, related_request_id: nil)
375376
handler = @handlers[method]
376377
unless handler
377378
instrument_call("unsupported_method") do
@@ -399,7 +400,7 @@ def handle_request(request, method, session: nil)
399400
when Methods::RESOURCES_TEMPLATES_LIST
400401
{ resourceTemplates: @handlers[Methods::RESOURCES_TEMPLATES_LIST].call(params) }
401402
when Methods::TOOLS_CALL
402-
call_tool(params, session: session)
403+
call_tool(params, session: session, related_request_id: related_request_id)
403404
when Methods::COMPLETION_COMPLETE
404405
complete(params)
405406
when Methods::LOGGING_SET_LEVEL
@@ -499,7 +500,7 @@ def list_tools(request)
499500
@tools.values.map(&:to_h)
500501
end
501502

502-
def call_tool(request, session: nil)
503+
def call_tool(request, session: nil, related_request_id: nil)
503504
tool_name = request[:name]
504505

505506
tool = tools[tool_name]
@@ -531,7 +532,7 @@ def call_tool(request, session: nil)
531532

532533
progress_token = request.dig(:_meta, :progressToken)
533534

534-
call_tool_with_args(tool, arguments, server_context_with_meta(request), progress_token: progress_token, session: session)
535+
call_tool_with_args(tool, arguments, server_context_with_meta(request), progress_token: progress_token, session: session, related_request_id: related_request_id)
535536
rescue RequestHandlerError
536537
raise
537538
rescue => e
@@ -611,12 +612,12 @@ def accepts_server_context?(method_object)
611612
parameters.any? { |type, name| type == :keyrest || name == :server_context }
612613
end
613614

614-
def call_tool_with_args(tool, arguments, context, progress_token: nil, session: nil)
615+
def call_tool_with_args(tool, arguments, context, progress_token: nil, session: nil, related_request_id: nil)
615616
args = arguments&.transform_keys(&:to_sym) || {}
616617

617618
if accepts_server_context?(tool.method(:call))
618-
progress = Progress.new(notification_target: session, progress_token: progress_token)
619-
server_context = ServerContext.new(context, progress: progress, notification_target: session)
619+
progress = Progress.new(notification_target: session, progress_token: progress_token, related_request_id: related_request_id)
620+
server_context = ServerContext.new(context, progress: progress, notification_target: session, related_request_id: related_request_id)
620621
tool.call(**args, server_context: server_context).to_h
621622
else
622623
tool.call(**args).to_h

0 commit comments

Comments
 (0)