Merge pull request #448 from koic/handle_non_object_json_rpc_messages

Handle non-object JSON-RPC messages without raising
This commit is contained in:
Koichi ITO 2026-07-12 02:12:46 +09:00 • committed by GitHub
commit 3d442d0a65
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 134 additions and 1 deletions

View file

@ -63,12 +63,29 @@ module JsonRpcHandler
message: "Parse error",
data: "Invalid JSON",
})
rescue StandardError
# Last-resort guard so an unexpected handling error returns a JSON-RPC error
# instead of escaping to the transport loop.
response = error_response(id: :unknown_id, id_validation_pattern: id_validation_pattern, error: {
code: ErrorCode::INTERNAL_ERROR,
message: "Internal error",
})
end
response&.to_json
end
def process_request(request, id_validation_pattern:, &method_finder)
# A batch element can be any JSON value; a non-object element cannot carry an id or a method,
# so reject it before the `request[:id]` access below.
unless request.is_a?(Hash)
return error_response(id: :unknown_id, id_validation_pattern: id_validation_pattern, error: {
code: ErrorCode::INVALID_REQUEST,
message: "Invalid Request",
data: "Request must be an object",
})
end
id = request[:id]
error = if !valid_version?(request[:jsonrpc])

View file

@ -259,7 +259,9 @@ module MCP
parsed = JSON.parse(line.strip)
next unless parsed.key?("id")
# A JSON-RPC message is an object; skip a non-object frame (array or scalar)
# the same way as a frame without an id.
next unless parsed.is_a?(Hash) && parsed.key?("id")
return parsed if parsed["id"] == request_id
end