@@ -160,6 +160,264 @@ def test_call_tool_handles_empty_response
160160 assert_nil ( response )
161161 end
162162
163+ def test_raises_bad_request_error
164+ tool = Tool . new (
165+ "name" => "test_tool" ,
166+ "description" => "A test tool" ,
167+ "inputSchema" => {
168+ "type" => "object" ,
169+ "properties" => { } ,
170+ } ,
171+ )
172+ input = { "param" => "value" }
173+
174+ stub_request ( :post , url )
175+ . with (
176+ body : {
177+ jsonrpc : "2.0" ,
178+ id : mock_request_id ,
179+ method : "tools/call" ,
180+ params : {
181+ name : "test_tool" ,
182+ arguments : input ,
183+ } ,
184+ mcp : {
185+ jsonrpc : "2.0" ,
186+ id : mock_request_id ,
187+ method : "tools/call" ,
188+ params : {
189+ name : "test_tool" ,
190+ arguments : input ,
191+ } ,
192+ } ,
193+ } ,
194+ )
195+ . to_return ( status : 400 )
196+
197+ error = assert_raises ( RequestHandlerError ) do
198+ client . call_tool ( tool : tool , input : input )
199+ end
200+
201+ assert_equal ( "The tools/call request is invalid" , error . message )
202+ assert_equal ( :bad_request , error . error_type )
203+ assert_equal ( { method : "tools/call" , params : { name : "test_tool" , arguments : input } } , error . request )
204+ end
205+
206+ def test_raises_unauthorized_error
207+ tool = Tool . new (
208+ "name" => "test_tool" ,
209+ "description" => "A test tool" ,
210+ "inputSchema" => {
211+ "type" => "object" ,
212+ "properties" => { } ,
213+ } ,
214+ )
215+ input = { "param" => "value" }
216+
217+ stub_request ( :post , url )
218+ . with (
219+ body : {
220+ jsonrpc : "2.0" ,
221+ id : mock_request_id ,
222+ method : "tools/call" ,
223+ params : {
224+ name : "test_tool" ,
225+ arguments : input ,
226+ } ,
227+ mcp : {
228+ jsonrpc : "2.0" ,
229+ id : mock_request_id ,
230+ method : "tools/call" ,
231+ params : {
232+ name : "test_tool" ,
233+ arguments : input ,
234+ } ,
235+ } ,
236+ } ,
237+ )
238+ . to_return ( status : 401 )
239+
240+ error = assert_raises ( RequestHandlerError ) do
241+ client . call_tool ( tool : tool , input : input )
242+ end
243+
244+ assert_equal ( "You are unauthorized to make tools/call requests" , error . message )
245+ assert_equal ( :unauthorized , error . error_type )
246+ assert_equal ( { method : "tools/call" , params : { name : "test_tool" , arguments : input } } , error . request )
247+ end
248+
249+ def test_raises_forbidden_error
250+ tool = Tool . new (
251+ "name" => "test_tool" ,
252+ "description" => "A test tool" ,
253+ "inputSchema" => {
254+ "type" => "object" ,
255+ "properties" => { } ,
256+ } ,
257+ )
258+ input = { "param" => "value" }
259+
260+ stub_request ( :post , url )
261+ . with (
262+ body : {
263+ jsonrpc : "2.0" ,
264+ id : mock_request_id ,
265+ method : "tools/call" ,
266+ params : {
267+ name : "test_tool" ,
268+ arguments : input ,
269+ } ,
270+ mcp : {
271+ jsonrpc : "2.0" ,
272+ id : mock_request_id ,
273+ method : "tools/call" ,
274+ params : {
275+ name : "test_tool" ,
276+ arguments : input ,
277+ } ,
278+ } ,
279+ } ,
280+ )
281+ . to_return ( status : 403 )
282+
283+ error = assert_raises ( RequestHandlerError ) do
284+ client . call_tool ( tool : tool , input : input )
285+ end
286+
287+ assert_equal ( "You are forbidden to make tools/call requests" , error . message )
288+ assert_equal ( :forbidden , error . error_type )
289+ assert_equal ( { method : "tools/call" , params : { name : "test_tool" , arguments : input } } , error . request )
290+ end
291+
292+ def test_raises_not_found_error
293+ tool = Tool . new (
294+ "name" => "test_tool" ,
295+ "description" => "A test tool" ,
296+ "inputSchema" => {
297+ "type" => "object" ,
298+ "properties" => { } ,
299+ } ,
300+ )
301+ input = { "param" => "value" }
302+
303+ stub_request ( :post , url )
304+ . with (
305+ body : {
306+ jsonrpc : "2.0" ,
307+ id : mock_request_id ,
308+ method : "tools/call" ,
309+ params : {
310+ name : "test_tool" ,
311+ arguments : input ,
312+ } ,
313+ mcp : {
314+ jsonrpc : "2.0" ,
315+ id : mock_request_id ,
316+ method : "tools/call" ,
317+ params : {
318+ name : "test_tool" ,
319+ arguments : input ,
320+ } ,
321+ } ,
322+ } ,
323+ )
324+ . to_return ( status : 404 )
325+
326+ error = assert_raises ( RequestHandlerError ) do
327+ client . call_tool ( tool : tool , input : input )
328+ end
329+
330+ assert_equal ( "The tools/call request is not found" , error . message )
331+ assert_equal ( :not_found , error . error_type )
332+ assert_equal ( { method : "tools/call" , params : { name : "test_tool" , arguments : input } } , error . request )
333+ end
334+
335+ def test_raises_unprocessable_entity_error
336+ tool = Tool . new (
337+ "name" => "test_tool" ,
338+ "description" => "A test tool" ,
339+ "inputSchema" => {
340+ "type" => "object" ,
341+ "properties" => { } ,
342+ } ,
343+ )
344+ input = { "param" => "value" }
345+
346+ stub_request ( :post , url )
347+ . with (
348+ body : {
349+ jsonrpc : "2.0" ,
350+ id : mock_request_id ,
351+ method : "tools/call" ,
352+ params : {
353+ name : "test_tool" ,
354+ arguments : input ,
355+ } ,
356+ mcp : {
357+ jsonrpc : "2.0" ,
358+ id : mock_request_id ,
359+ method : "tools/call" ,
360+ params : {
361+ name : "test_tool" ,
362+ arguments : input ,
363+ } ,
364+ } ,
365+ } ,
366+ )
367+ . to_return ( status : 422 )
368+
369+ error = assert_raises ( RequestHandlerError ) do
370+ client . call_tool ( tool : tool , input : input )
371+ end
372+
373+ assert_equal ( "The tools/call request is unprocessable" , error . message )
374+ assert_equal ( :unprocessable_entity , error . error_type )
375+ assert_equal ( { method : "tools/call" , params : { name : "test_tool" , arguments : input } } , error . request )
376+ end
377+
378+ def test_raises_internal_error
379+ tool = Tool . new (
380+ "name" => "test_tool" ,
381+ "description" => "A test tool" ,
382+ "inputSchema" => {
383+ "type" => "object" ,
384+ "properties" => { } ,
385+ } ,
386+ )
387+ input = { "param" => "value" }
388+
389+ stub_request ( :post , url )
390+ . with (
391+ body : {
392+ jsonrpc : "2.0" ,
393+ id : mock_request_id ,
394+ method : "tools/call" ,
395+ params : {
396+ name : "test_tool" ,
397+ arguments : input ,
398+ } ,
399+ mcp : {
400+ jsonrpc : "2.0" ,
401+ id : mock_request_id ,
402+ method : "tools/call" ,
403+ params : {
404+ name : "test_tool" ,
405+ arguments : input ,
406+ } ,
407+ } ,
408+ } ,
409+ )
410+ . to_return ( status : 500 )
411+
412+ error = assert_raises ( RequestHandlerError ) do
413+ client . call_tool ( tool : tool , input : input )
414+ end
415+
416+ assert_equal ( "Internal error handling tools/call request" , error . message )
417+ assert_equal ( :internal_error , error . error_type )
418+ assert_equal ( { method : "tools/call" , params : { name : "test_tool" , arguments : input } } , error . request )
419+ end
420+
163421 private
164422
165423 def stub_request ( method , url )
0 commit comments