@@ -19,6 +19,73 @@ import (
1919 "github.com/DataDog/dd-trace-go/v2/instrumentation/testutils/testtracer"
2020)
2121
22+ func TestIntentCapturePredicate (t * testing.T ) {
23+ // The predicate must gate per-request: when it returns false, no schema
24+ // injection and the telemetry argument reaches the handler.
25+ tt := testTracer (t )
26+ defer tt .Stop ()
27+ ctx := context .Background ()
28+
29+ var enabled bool
30+ server := mcp .NewServer (& mcp.Implementation {Name : "test-server" , Version : "1.0.0" }, nil )
31+ AddTracing (server , WithIntentCapturePredicate (func (context.Context ) bool {
32+ return enabled
33+ }))
34+
35+ var receivedArgs map [string ]any
36+ server .AddTool (& mcp.Tool {
37+ Name : "tool" ,
38+ Description : "tool" ,
39+ InputSchema : & jsonschema.Schema {Type : "object" , Properties : map [string ]* jsonschema.Schema {"q" : {Type : "string" }}},
40+ }, func (_ context.Context , req * mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
41+ _ = json .Unmarshal (req .Params .Arguments , & receivedArgs )
42+ return & mcp.CallToolResult {Content : []mcp.Content {& mcp.TextContent {Text : "ok" }}}, nil
43+ })
44+
45+ client := mcp .NewClient (& mcp.Implementation {Name : "test-client" , Version : "1.0.0" }, nil )
46+ clientTransport , serverTransport := mcp .NewInMemoryTransports ()
47+ serverSession , err := server .Connect (ctx , serverTransport , nil )
48+ require .NoError (t , err )
49+ defer serverSession .Close ()
50+ clientSession , err := client .Connect (ctx , clientTransport , nil )
51+ require .NoError (t , err )
52+ defer clientSession .Close ()
53+
54+ // Predicate false: schema not injected, telemetry argument passed through.
55+ enabled = false
56+ listResult , err := clientSession .ListTools (ctx , & mcp.ListToolsParams {})
57+ require .NoError (t , err )
58+ require .Len (t , listResult .Tools , 1 )
59+ if schema , ok := listResult .Tools [0 ].InputSchema .(map [string ]any ); ok {
60+ if props , _ := schema ["properties" ].(map [string ]any ); props != nil {
61+ assert .NotContains (t , props , "telemetry" )
62+ }
63+ }
64+
65+ _ , err = clientSession .CallTool (ctx , & mcp.CallToolParams {
66+ Name : "tool" ,
67+ Arguments : map [string ]any {"q" : "x" , "telemetry" : map [string ]any {"intent" : "ignored" }},
68+ })
69+ require .NoError (t , err )
70+ assert .Contains (t , receivedArgs , "telemetry" , "telemetry should pass through when predicate is false" )
71+
72+ // Predicate true: schema injected, telemetry stripped.
73+ enabled = true
74+ listResult , err = clientSession .ListTools (ctx , & mcp.ListToolsParams {})
75+ require .NoError (t , err )
76+ schema , ok := listResult .Tools [0 ].InputSchema .(map [string ]any )
77+ require .True (t , ok )
78+ assert .Contains (t , schema ["properties" ].(map [string ]any ), "telemetry" )
79+
80+ receivedArgs = nil
81+ _ , err = clientSession .CallTool (ctx , & mcp.CallToolParams {
82+ Name : "tool" ,
83+ Arguments : map [string ]any {"q" : "x" , "telemetry" : map [string ]any {"intent" : "captured" }},
84+ })
85+ require .NoError (t , err )
86+ assert .NotContains (t , receivedArgs , "telemetry" )
87+ }
88+
2289func TestIntentCapturePreservesUnknownSchemaKeywords (t * testing.T ) {
2390 // *jsonschema.Schema doesn't model additionalProperties/oneOf; the map-based
2491 // injection must pass those through verbatim instead of dropping them.
0 commit comments