11# frozen_string_literal: true
22
3+ require "json_rpc_handler"
4+
35module ModelContextProtocol
46 class Server
57 PROTOCOL_VERSION = "2024-11-05"
@@ -26,20 +28,20 @@ def initialize(name: "model_context_protocol", tools: [], prompts: [], resources
2628 end
2729
2830 def handle ( request )
29- response = begin
30- parsed_request = JsonRPC ::Request . parse ( request )
31- parsed_request . validate!
32-
33- if parsed_request . notification?
34- handle_notification ( parsed_request )
31+ JsonRpcHandler . handle ( request ) do |method |
32+ handler = case method
33+ when "tools/list"
34+ -> ( params ) { { tools : @handlers [ "tools/list" ] . call ( params ) } }
35+ when "prompts/list"
36+ -> ( params ) { { prompts : @handlers [ "prompts/list" ] . call ( params ) } }
37+ when "resources/list"
38+ -> ( params ) { { resources : @handlers [ "resources/list" ] . call ( params ) } }
3539 else
36- handle_method ( parsed_request )
40+ @handlers [ method ]
3741 end
38- rescue JsonRPC ::Error => e
39- JsonRPC ::Response . new ( id : parsed_request &.id , error : e )
40- end
4142
42- response
43+ handler
44+ end
4345 end
4446
4547 def resources_list_handler ( &block )
@@ -86,29 +88,6 @@ def server_info
8688 }
8789 end
8890
89- def handle_notification ( request )
90- nil
91- end
92-
93- def handle_method ( request )
94- request_handler = @handlers [ request . method ]
95- raise JsonRPC ::MethodNotFoundError . new ( message : "Method not found #{ request . method } " ) unless request_handler
96-
97- result = request_handler . call ( request )
98- wrapped_result = case request . method
99- when "tools/list"
100- { tools : result }
101- when "prompts/list"
102- { prompts : result }
103- when "resources/list"
104- { resources : result }
105- else
106- result
107- end
108-
109- JsonRPC ::Response . new ( id : request . id , result : wrapped_result )
110- end
111-
11291 def init ( request )
11392 {
11493 protocolVersion : PROTOCOL_VERSION ,
@@ -121,43 +100,33 @@ def ping(request)
121100 "pong"
122101 end
123102
103+ def list_tools ( request )
104+ @tools . map { |_ , tool | tool . to_h }
105+ end
106+
124107 def call_tool ( request )
125- tool_name = request . params &. dig ( " name" )
108+ tool_name = request [ : name]
126109 tool = tools [ tool_name ]
127- raise JsonRPC ::MethodNotFoundError . new ( message : "Tool not found #{ tool_name } " ) unless tool
128-
129- tool_args = request . params &.dig ( "arguments" )
130-
131- result = begin
132- tool . call ( **tool_args )
133- rescue => e
134- raise JsonRPC ::InternalError . new ( message : e . message )
135- end
110+ raise "Tool not found #{ tool_name } " unless tool
136111
112+ result = tool . call ( **request [ :arguments ] )
137113 result . to_h
138114 end
139115
140- def list_tools ( request )
141- @tools . map { |_ , tool | tool . to_h }
142- end
143-
144116 def list_prompts ( request )
145117 @prompts . map { |_ , prompt | prompt . to_h }
146118 end
147119
148120 def get_prompt ( request )
149- prompt_name = request . params &. dig ( " name" )
121+ prompt_name = request [ : name]
150122 prompt = @prompts [ prompt_name ]
151- raise JsonRPC ::MethodNotFoundError . new ( message : "Prompt not found #{ prompt_name } " ) unless prompt
152123
153- begin
154- prompt_args = request . params &.dig ( "arguments" )
155- prompt . validate_arguments! ( prompt_args )
124+ raise "Prompt not found #{ prompt_name } " unless prompt
156125
157- result = prompt . template ( prompt_args )
158- rescue ArgumentError => e
159- raise JsonRPC :: InvalidParamsError . new ( message : e . message )
160- end
126+ prompt_args = request [ :arguments ]
127+ prompt . validate_arguments! ( prompt_args )
128+
129+ result = prompt . template ( prompt_args )
161130
162131 result . to_h
163132 end
@@ -167,10 +136,10 @@ def list_resources(request)
167136 end
168137
169138 def read_resource ( request )
170- resource_uri = request . params &. dig ( " uri" )
139+ resource_uri = request [ : uri]
171140
172141 resource = @resource_index [ resource_uri ]
173- raise JsonRPC :: MethodNotFoundError . new ( message : "Resource not found #{ resource_uri } " ) unless resource
142+ raise "Resource not found #{ resource_uri } " unless resource
174143
175144 resource . to_h
176145 end
0 commit comments