@@ -78,6 +78,99 @@ func resultToString(result *mcp.CallToolResult) (string, error) {
78
78
return b .String (), nil
79
79
}
80
80
81
+ func TestServerWithToolStructuredContent (t * testing.T ) {
82
+ ctx := context .Background ()
83
+
84
+ srv , err := mcptest .NewServer (t , server.ServerTool {
85
+ Tool : mcp .NewTool ("get_user" ,
86
+ mcp .WithDescription ("Gets user information with structured data." ),
87
+ mcp .WithString ("user_id" , mcp .Description ("The user ID to look up." )),
88
+ ),
89
+ Handler : structuredContentHandler ,
90
+ })
91
+ if err != nil {
92
+ t .Fatal (err )
93
+ }
94
+ defer srv .Close ()
95
+
96
+ client := srv .Client ()
97
+
98
+ var req mcp.CallToolRequest
99
+ req .Params .Name = "get_user"
100
+ req .Params .Arguments = map [string ]any {
101
+ "user_id" : "123" ,
102
+ }
103
+
104
+ result , err := client .CallTool (ctx , req )
105
+ if err != nil {
106
+ t .Fatal ("CallTool:" , err )
107
+ }
108
+
109
+ if result .IsError {
110
+ t .Fatalf ("unexpected error result: %+v" , result )
111
+ }
112
+
113
+ if result .Meta .AdditionalFields ["key" ] != "value" {
114
+ t .Errorf ("Expected Meta.AdditionalFields['key'] to be 'value', got %v" , result .Meta .AdditionalFields ["key" ])
115
+ }
116
+
117
+ if len (result .Content ) != 1 {
118
+ t .Fatalf ("Expected 1 content item, got %d" , len (result .Content ))
119
+ }
120
+
121
+ // Check text content (fallback)
122
+ textContent , ok := result .Content [0 ].(mcp.TextContent )
123
+ if ! ok {
124
+ t .Fatalf ("Expected content to be TextContent, got %T" , result .Content [0 ])
125
+ }
126
+ expectedText := "User found"
127
+ if textContent .Text != expectedText {
128
+ t .Errorf ("Expected text %q, got %q" , expectedText , textContent .Text )
129
+ }
130
+
131
+ // Check structured content
132
+ if result .StructuredContent == nil {
133
+ t .Fatal ("Expected StructuredContent to be present" )
134
+ }
135
+
136
+ structuredData , ok := result .StructuredContent .(map [string ]any )
137
+ if ! ok {
138
+ t .Fatalf ("Expected StructuredContent to be map[string]any, got %T" , result .StructuredContent )
139
+ }
140
+
141
+ // Verify structured data
142
+ if structuredData ["id" ] != "123" {
143
+ t .Errorf ("Expected id '123', got %v" , structuredData ["id" ])
144
+ }
145
+ if structuredData ["name" ] != "John Doe" {
146
+ t .Errorf ("Expected name 'John Doe', got %v" , structuredData ["name" ])
147
+ }
148
+ if structuredData [
"email" ]
!= "[email protected] " {
149
+ t .
Errorf (
"Expected email '[email protected] ', got %v" ,
structuredData [
"email" ])
150
+ }
151
+ if structuredData ["active" ] != true {
152
+ t .Errorf ("Expected active true, got %v" , structuredData ["active" ])
153
+ }
154
+ }
155
+
156
+ func structuredContentHandler (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
157
+ userID , ok := request .GetArguments ()["user_id" ].(string )
158
+ if ! ok {
159
+ return mcp .NewToolResultError ("user_id parameter is required" ), nil
160
+ }
161
+
162
+ // Create structured data
163
+ userData := map [string ]any {
164
+ "id" : userID ,
165
+ "name" : "John Doe" ,
166
+
167
+ "active" : true ,
168
+ }
169
+
170
+ // Use NewToolResultStructured to create result with both text fallback and structured content
171
+ return mcp .NewToolResultStructured (userData , "User found" ), nil
172
+ }
173
+
81
174
func TestServerWithPrompt (t * testing.T ) {
82
175
ctx := context .Background ()
83
176
@@ -188,91 +281,6 @@ func TestServerWithResource(t *testing.T) {
188
281
}
189
282
}
190
283
191
- func TestServerWithToolStructuredContent (t * testing.T ) {
192
- ctx := context .Background ()
193
-
194
- srv , err := mcptest .NewServer (t , server.ServerTool {
195
- Tool : mcp .NewTool ("get_user" ,
196
- mcp .WithDescription ("Gets user information with structured data." ),
197
- mcp .WithString ("user_id" , mcp .Description ("The user ID to look up." )),
198
- ),
199
- Handler : structuredContentHandler ,
200
- })
201
- if err != nil {
202
- t .Fatal (err )
203
- }
204
- defer srv .Close ()
205
-
206
- client := srv .Client ()
207
-
208
- var req mcp.CallToolRequest
209
- req .Params .Name = "get_user"
210
- req .Params .Arguments = map [string ]any {
211
- "user_id" : "123" ,
212
- }
213
-
214
- result , err := client .CallTool (ctx , req )
215
- if err != nil {
216
- t .Fatal ("CallTool:" , err )
217
- }
218
-
219
- if len (result .Content ) != 1 {
220
- t .Fatalf ("Expected 1 content item, got %d" , len (result .Content ))
221
- }
222
-
223
- // Check text content (fallback)
224
- textContent , ok := result .Content [0 ].(mcp.TextContent )
225
- if ! ok {
226
- t .Fatalf ("Expected content to be TextContent, got %T" , result .Content [0 ])
227
- }
228
- expectedText := "User found"
229
- if textContent .Text != expectedText {
230
- t .Errorf ("Expected text %q, got %q" , expectedText , textContent .Text )
231
- }
232
-
233
- // Check structured content
234
- if result .StructuredContent == nil {
235
- t .Fatal ("Expected StructuredContent to be present" )
236
- }
237
-
238
- structuredData , ok := result .StructuredContent .(map [string ]any )
239
- if ! ok {
240
- t .Fatalf ("Expected StructuredContent to be map[string]any, got %T" , result .StructuredContent )
241
- }
242
-
243
- // Verify structured data
244
- if structuredData ["id" ] != "123" {
245
- t .Errorf ("Expected id '123', got %v" , structuredData ["id" ])
246
- }
247
- if structuredData ["name" ] != "John Doe" {
248
- t .Errorf ("Expected name 'John Doe', got %v" , structuredData ["name" ])
249
- }
250
- if structuredData [
"email" ]
!= "[email protected] " {
251
- t .
Errorf (
"Expected email '[email protected] ', got %v" ,
structuredData [
"email" ])
252
- }
253
- if structuredData ["active" ] != true {
254
- t .Errorf ("Expected active true, got %v" , structuredData ["active" ])
255
- }
256
- }
257
-
258
- func structuredContentHandler (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
259
- userID , ok := request .GetArguments ()["user_id" ].(string )
260
- if ! ok {
261
- return mcp .NewToolResultError ("user_id parameter is required" ), nil
262
- }
263
-
264
- // Create structured data
265
- userData := map [string ]any {
266
- "id" : userID ,
267
- "name" : "John Doe" ,
268
-
269
- "active" : true ,
270
- }
271
-
272
- // Use NewToolResultStructured to create result with both text fallback and structured content
273
- return mcp .NewToolResultStructured (userData , "User found" ), nil
274
- }
275
-
276
284
func TestServerWithResourceTemplate (t * testing.T ) {
277
285
ctx := context .Background ()
278
286
0 commit comments