@@ -67,6 +67,63 @@ func TestIntentCapturePreservesUnknownSchemaKeywords(t *testing.T) {
6767 assert .NotNil (t , schema ["oneOf" ])
6868}
6969
70+ func TestIntentCaptureSkipsUIOnlyTools (t * testing.T ) {
71+ // Tools whose _meta.ui.visibility omits "model" cannot be model-invoked, so
72+ // telemetry injection should be skipped for them.
73+ tt := testTracer (t )
74+ defer tt .Stop ()
75+ ctx := context .Background ()
76+
77+ server := mcp .NewServer (& mcp.Implementation {Name : "test-server" , Version : "1.0.0" }, nil )
78+ AddTracing (server , WithIntentCapture ())
79+
80+ addTool := func (name string , visibility []any ) {
81+ tool := & mcp.Tool {
82+ Name : name ,
83+ Description : name ,
84+ InputSchema : & jsonschema.Schema {Type : "object" , Properties : map [string ]* jsonschema.Schema {"q" : {Type : "string" }}},
85+ }
86+ if visibility != nil {
87+ tool .Meta = mcp.Meta {"ui" : map [string ]any {"visibility" : visibility }}
88+ }
89+ server .AddTool (tool , func (_ context.Context , _ * mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
90+ return & mcp.CallToolResult {Content : []mcp.Content {& mcp.TextContent {Text : "ok" }}}, nil
91+ })
92+ }
93+ addTool ("plain" , nil )
94+ addTool ("ui_only" , []any {"app" })
95+ addTool ("dual" , []any {"model" , "app" })
96+
97+ client := mcp .NewClient (& mcp.Implementation {Name : "test-client" , Version : "1.0.0" }, nil )
98+ clientTransport , serverTransport := mcp .NewInMemoryTransports ()
99+ serverSession , err := server .Connect (ctx , serverTransport , nil )
100+ require .NoError (t , err )
101+ defer serverSession .Close ()
102+ clientSession , err := client .Connect (ctx , clientTransport , nil )
103+ require .NoError (t , err )
104+ defer clientSession .Close ()
105+
106+ listResult , err := clientSession .ListTools (ctx , & mcp.ListToolsParams {})
107+ require .NoError (t , err )
108+ props := func (name string ) map [string ]any {
109+ for _ , tl := range listResult .Tools {
110+ if tl .Name != name {
111+ continue
112+ }
113+ schema , ok := tl .InputSchema .(map [string ]any )
114+ if ! ok {
115+ return nil
116+ }
117+ p , _ := schema ["properties" ].(map [string ]any )
118+ return p
119+ }
120+ return nil
121+ }
122+ assert .Contains (t , props ("plain" ), "telemetry" )
123+ assert .NotContains (t , props ("ui_only" ), "telemetry" , "UI-only tool should not have telemetry injected" )
124+ assert .Contains (t , props ("dual" ), "telemetry" )
125+ }
126+
70127func TestIntentCapture (t * testing.T ) {
71128 tt := testTracer (t )
72129 defer tt .Stop ()
0 commit comments