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 => new TextContentBlock { Text = x ?? string.Empty })], |
|
StructuredContent = structuredContent, |
|
}, |
Repro server:
[McpServerToolType]
public class TimeTool
{
[McpServerTool, Description("Gets a list of interesting animals.")]
public static Animal[] GetAnimals(
IMcpServer server,
CancellationToken cancellationToken)
{
return [new Animal("Bear", 500), new Animal("Elephant", 6000)];
}
[McpServerTool, Description("Gets a list of interesting animals.")]
public static string[] GetAnimalStrings(
IMcpServer server,
CancellationToken cancellationToken)
{
return ["Bear", "Elephant"];
}
public record Animal(string Name, int Weight);
}
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: