Skip to content

MCP tools that return string[] get different schema from SomethingElse[] #698

@AArnott

Description

@AArnott

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);
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions