@@ -56,7 +56,12 @@ func TestMCPServerModule(t *testing.T) {
5656 fxhealthcheck .FxHealthcheckModule ,
5757 fxmcpserver .FxMCPServerModule ,
5858 fx .Options (
59- fxmcpserver .AsMCPServerTools (tool .NewSimpleTestTool , tool .NewAdvancedTestTool ),
59+ fxmcpserver .AsMCPServerTools (
60+ tool .NewSimpleTestTool ,
61+ tool .NewAdvancedTestTool ,
62+ tool .NewTypedTestTool ,
63+ tool .NewStructuredTestTool ,
64+ ),
6065 fxmcpserver .AsMCPServerPrompts (prompt .NewSimpleTestPrompt ),
6166 fxmcpserver .AsMCPServerResources (resource .NewSimpleTestResource ),
6267 fxmcpserver .AsMCPServerResourceTemplates (resourcetemplate .NewSimpleTestResourceTemplate ),
@@ -187,7 +192,7 @@ func TestMCPServerModule(t *testing.T) {
187192
188193 _ , err = tt .client .CallTool (ctx , callToolRequest )
189194 assert .Error (t , err )
190- assert .Equal (t , "advanced tool test failure" , err . Error () )
195+ assert .Contains (t , err . Error (), "advanced tool test failure" )
191196
192197 logtest .AssertHasLogRecord (t , logBuffer , map [string ]any {
193198 "level" : "error" ,
@@ -222,6 +227,104 @@ func TestMCPServerModule(t *testing.T) {
222227 )
223228 assert .NoError (t , err )
224229
230+ // send success typed tools/call request
231+ expectedRequest = `{"method":"tools/call","params":{"name":"typed-test-tool","arguments":{"input":"test-value"}}}`
232+ expectedResponse = `{"content":[{"type":"text","text":"input: test-value"}]}`
233+
234+ callToolRequest = mcp.CallToolRequest {}
235+ callToolRequest .Params .Name = "typed-test-tool"
236+ callToolRequest .Params .Arguments = map [string ]interface {}{
237+ "input" : "test-value" ,
238+ }
239+
240+ callToolResult , err = tt .client .CallTool (ctx , callToolRequest )
241+ assert .NoError (t , err )
242+ assert .False (t , callToolResult .IsError )
243+ assert .Equal (t , "input: test-value" , callToolResult .Content [0 ].(mcp.TextContent ).Text )
244+
245+ logtest .AssertHasLogRecord (t , logBuffer , map [string ]any {
246+ "level" : "info" ,
247+ "mcpMethod" : "tools/call" ,
248+ "mcpTool" : "typed-test-tool" ,
249+ "mcpRequest" : expectedRequest ,
250+ "mcpResponse" : expectedResponse ,
251+ "mcpTransport" : tt .transport ,
252+ "message" : "MCP request success" ,
253+ })
254+
255+ tracetest .AssertHasTraceSpan (
256+ t ,
257+ traceExporter ,
258+ "MCP tools/call typed-test-tool" ,
259+ attribute .String ("mcp.method" , "tools/call" ),
260+ attribute .String ("mcp.tool" , "typed-test-tool" ),
261+ attribute .String ("mcp.request" , expectedRequest ),
262+ attribute .String ("mcp.response" , expectedResponse ),
263+ attribute .String ("mcp.transport" , tt .transport ),
264+ )
265+
266+ expectedMetric = `
267+ # HELP foo_bar_mcp_server_requests_total Number of processed MCP requests
268+ # TYPE foo_bar_mcp_server_requests_total counter
269+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="advanced-test-tool"} 1
270+ foo_bar_mcp_server_requests_total{method="tools/call",status="error",target="advanced-test-tool"} 1
271+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="typed-test-tool"} 1
272+ `
273+ err = testutil .GatherAndCompare (
274+ metricsRegistry ,
275+ strings .NewReader (expectedMetric ),
276+ "foo_bar_mcp_server_requests_total" ,
277+ )
278+ assert .NoError (t , err )
279+
280+ // send success structured tools/call request
281+ expectedRequest = `{"method":"tools/call","params":{"name":"structured-test-tool","arguments":{"input":"structured-value"}}}`
282+
283+ callToolRequest = mcp.CallToolRequest {}
284+ callToolRequest .Params .Name = "structured-test-tool"
285+ callToolRequest .Params .Arguments = map [string ]interface {}{
286+ "input" : "structured-value" ,
287+ }
288+
289+ callToolResult , err = tt .client .CallTool (ctx , callToolRequest )
290+ assert .NoError (t , err )
291+ assert .False (t , callToolResult .IsError )
292+ assert .Equal (t , "{\" output\" :\" input: structured-value\" }" , callToolResult .Content [0 ].(mcp.TextContent ).Text )
293+
294+ logtest .AssertHasLogRecord (t , logBuffer , map [string ]any {
295+ "level" : "info" ,
296+ "mcpMethod" : "tools/call" ,
297+ "mcpTool" : "structured-test-tool" ,
298+ "mcpRequest" : expectedRequest ,
299+ "mcpTransport" : tt .transport ,
300+ "message" : "MCP request success" ,
301+ })
302+
303+ tracetest .AssertHasTraceSpan (
304+ t ,
305+ traceExporter ,
306+ "MCP tools/call structured-test-tool" ,
307+ attribute .String ("mcp.method" , "tools/call" ),
308+ attribute .String ("mcp.tool" , "structured-test-tool" ),
309+ attribute .String ("mcp.request" , expectedRequest ),
310+ attribute .String ("mcp.transport" , tt .transport ),
311+ )
312+
313+ expectedMetric = `
314+ # HELP foo_bar_mcp_server_requests_total Number of processed MCP requests
315+ # TYPE foo_bar_mcp_server_requests_total counter
316+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="advanced-test-tool"} 1
317+ foo_bar_mcp_server_requests_total{method="tools/call",status="error",target="advanced-test-tool"} 1
318+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="structured-test-tool"} 1
319+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="typed-test-tool"} 1
320+ `
321+ err = testutil .GatherAndCompare (
322+ metricsRegistry ,
323+ strings .NewReader (expectedMetric ),
324+ "foo_bar_mcp_server_requests_total" ,
325+ )
326+ assert .NoError (t , err )
327+
225328 // send success prompts/get request
226329 expectedRequest = `{"method":"prompts/get","params":{"name":"simple-test-prompt"}}`
227330 expectedResponse = `{"description":"ok","messages":[{"role":"assistant","content":{"type":"text","text":"context hook value: bar"}}]}`
@@ -261,6 +364,8 @@ func TestMCPServerModule(t *testing.T) {
261364 foo_bar_mcp_server_requests_total{method="prompts/get",status="success",target="simple-test-prompt"} 1
262365 foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="advanced-test-tool"} 1
263366 foo_bar_mcp_server_requests_total{method="tools/call",status="error",target="advanced-test-tool"} 1
367+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="structured-test-tool"} 1
368+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="typed-test-tool"} 1
264369 `
265370 err = testutil .GatherAndCompare (
266371 metricsRegistry ,
@@ -277,7 +382,7 @@ func TestMCPServerModule(t *testing.T) {
277382
278383 _ , err = tt .client .GetPrompt (ctx , getPromptRequest )
279384 assert .Error (t , err )
280- assert .Equal (t , "prompt 'invalid-test-prompt' not found: prompt not found" , err . Error () )
385+ assert .Contains (t , err . Error (), "prompt 'invalid-test-prompt' not found: prompt not found" )
281386
282387 logtest .AssertHasLogRecord (t , logBuffer , map [string ]any {
283388 "level" : "error" ,
@@ -306,6 +411,8 @@ func TestMCPServerModule(t *testing.T) {
306411 foo_bar_mcp_server_requests_total{method="prompts/get",status="success",target="simple-test-prompt"} 1
307412 foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="advanced-test-tool"} 1
308413 foo_bar_mcp_server_requests_total{method="tools/call",status="error",target="advanced-test-tool"} 1
414+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="structured-test-tool"} 1
415+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="typed-test-tool"} 1
309416 `
310417 err = testutil .GatherAndCompare (
311418 metricsRegistry ,
@@ -354,6 +461,8 @@ func TestMCPServerModule(t *testing.T) {
354461 foo_bar_mcp_server_requests_total{method="resources/read",status="success",target="simple-test://resources"} 1
355462 foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="advanced-test-tool"} 1
356463 foo_bar_mcp_server_requests_total{method="tools/call",status="error",target="advanced-test-tool"} 1
464+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="structured-test-tool"} 1
465+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="typed-test-tool"} 1
357466 `
358467 err = testutil .GatherAndCompare (
359468 metricsRegistry ,
@@ -370,7 +479,7 @@ func TestMCPServerModule(t *testing.T) {
370479
371480 _ , err = tt .client .ReadResource (ctx , readResourceRequest )
372481 assert .Error (t , err )
373- assert .Equal (t , "handler not found for resource URI 'simple-test://invalid': resource not found" , err . Error () )
482+ assert .Contains (t , err . Error (), "handler not found for resource URI 'simple-test://invalid': resource not found" )
374483
375484 logtest .AssertHasLogRecord (t , logBuffer , map [string ]any {
376485 "level" : "error" ,
@@ -401,6 +510,8 @@ func TestMCPServerModule(t *testing.T) {
401510 foo_bar_mcp_server_requests_total{method="resources/read",status="success",target="simple-test://resources"} 1
402511 foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="advanced-test-tool"} 1
403512 foo_bar_mcp_server_requests_total{method="tools/call",status="error",target="advanced-test-tool"} 1
513+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="structured-test-tool"} 1
514+ foo_bar_mcp_server_requests_total{method="tools/call",status="success",target="typed-test-tool"} 1
404515 `
405516 err = testutil .GatherAndCompare (
406517 metricsRegistry ,
0 commit comments