@@ -1960,6 +1960,58 @@ def read_resource_request(uri)
19601960 assert_equal [ "custom" ] , seen
19611961 end
19621962
1963+ test "#handle accepts any string as the request id and echoes it" do
1964+ # MCP, like JSON-RPC 2.0, allows any string or integer id; the TypeScript and Python servers accept these.
1965+ [ "req.1" , "call:42" , "urn:uuid:6f1c4e0a-2b7d-4c1e-9a3f-0d2c8b1e5f77" , "request 123" , "<script>alert('x')</script>" , "" ] . each do |id |
1966+ response = @server . handle ( { jsonrpc : "2.0" , id : id , method : "ping" } )
1967+
1968+ assert_equal ( { jsonrpc : "2.0" , id : id , result : { } } , response , id . inspect )
1969+ end
1970+ end
1971+
1972+ test "#handle_json keeps a request id with a newline on one line of the response" do
1973+ json = @server . handle_json ( { jsonrpc : "2.0" , id : "line1\n line2" , method : "ping" } . to_json )
1974+
1975+ refute_includes json , "\n "
1976+ assert_equal "line1\n line2" , JSON . parse ( json ) [ "id" ]
1977+ end
1978+
1979+ test "#handle echoes a string request id on an error response" do
1980+ response = @server . handle ( { jsonrpc : "2.0" , id : "req.1" , method : "unsupported_method" } )
1981+
1982+ assert_equal "req.1" , response [ :id ]
1983+ assert_equal ( -32601 , response [ :error ] [ :code ] )
1984+ end
1985+
1986+ test "#handle still refuses a request id that is neither a string nor an integer" do
1987+ [ 3.14 , true , false , { a : 1 } , [ 1 ] ] . each do |id |
1988+ response = @server . handle ( { jsonrpc : "2.0" , id : id , method : "ping" } )
1989+
1990+ assert_nil response [ :id ] , id . inspect
1991+ assert_equal ( -32600 , response [ :error ] [ :code ] , id . inspect )
1992+ end
1993+ end
1994+
1995+ test "#handle refuses a request id that is not valid UTF-8 without running the method" do
1996+ # Such an id cannot be written into the response; refused up front, the write it asks for does not run.
1997+ calls = 0
1998+ @server . define_tool ( name : "count" ) do
1999+ calls += 1
2000+ Tool ::Response . new ( [ { type : "text" , text : "ok" } ] )
2001+ end
2002+
2003+ response = @server . handle ( {
2004+ jsonrpc : "2.0" ,
2005+ id : [ 0xFF ] . pack ( "C" ) . force_encoding ( Encoding ::UTF_8 ) ,
2006+ method : "tools/call" ,
2007+ params : { name : "count" , arguments : { } } ,
2008+ } )
2009+
2010+ assert_nil response [ :id ]
2011+ assert_equal ( -32600 , response [ :error ] [ :code ] )
2012+ assert_equal 0 , calls
2013+ end
2014+
19632015 test "#handle handles custom methods" do
19642016 @server . define_custom_method ( method_name : "add" ) do |params |
19652017 params [ :a ] + params [ :b ]
0 commit comments