A tool that returns an array of things should have a consistent schema for the array itself, leaving the changes to only the type of thing being returned.
When I call a method that returns Animal[], this is the result:
{
"content": [
{
"type": "text",
"text": "[{\"name\":\"Bear\",\"weight\":500},{\"name\":\"Elephant\",\"weight\":6000}]"
}
],
"isError": false
}Yet when I call a method that returns string[], this is the result:
{
"content": [
{
"type": "text",
"text": "Bear"
},
{
"type": "text",
"text": "Elephant"
}
]
}Note the subtle yet significant difference of where the 2 element array is.
- For
Animal[] we get a content array of 1, and a JSON-formatted string containing an array of 2. - For
string[] we get a content array of 2, and no JSON-formatted string at all.
@stephentoub found that the MCP server library special cases IEnumerable<string> leading to this inconsistency:
| IEnumerable<string>texts=>new() |
| { |
| Content=[.. texts.Select(x =>newTextContentBlock{Text=x??string.Empty})], |
| StructuredContent=structuredContent, |
| }, |
Repro server:
[McpServerToolType]publicclassTimeTool{[McpServerTool,Description("Gets a list of interesting animals.")]publicstaticAnimal[]GetAnimals(IMcpServerserver,CancellationTokencancellationToken){return[newAnimal("Bear",500),newAnimal("Elephant",6000)];}[McpServerTool,Description("Gets a list of interesting animals.")]publicstaticstring[]GetAnimalStrings(IMcpServerserver,CancellationTokencancellationToken){return["Bear","Elephant"];}publicrecordAnimal(stringName,intWeight);}
A tool that returns an array of things should have a consistent schema for the array itself, leaving the changes to only the type of thing being returned.
When I call a method that returns
Animal[], this is the result:{ "content": [ { "type": "text", "text": "[{\"name\":\"Bear\",\"weight\":500},{\"name\":\"Elephant\",\"weight\":6000}]" } ], "isError": false }Yet when I call a method that returns
string[], this is the result:{ "content": [ { "type": "text", "text": "Bear" }, { "type": "text", "text": "Elephant" } ] }Note the subtle yet significant difference of where the 2 element array is.
Animal[]we get acontentarray of 1, and a JSON-formatted string containing an array of 2.string[]we get acontentarray of 2, and no JSON-formatted string at all.@stephentoub found that the MCP server library special cases
IEnumerable<string>leading to this inconsistency:csharp-sdk/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs
Lines 273 to 277 in 329f848
Repro server: