Skip to content

McpToolResponse.isError is dropped before MCP tool result reaches the client #444

Description

McpToolResponse accepts isError: true, but the Node.js worker conversion path appears to drop that field before the result is sent to the Azure Functions MCP extension. As a result, MCP clients receive a
successful tools/call result instead of a tool-error result.

Environment

  • @azure/functions: 4.16.0
  • Azure Functions MCP extension: observed with extension bundle preview using MCP extension 1.5.0
  • Runtime: Node.js Azure Functions app using app.mcpTool(...)

Reproduction

Return an MCP tool response with isError: true:

return new McpToolResponse({
  content: [
    new McpTextContent("Invalid file")
  ],
  isError: true,
});

The public type supports this:

export interface McpToolResponseInit {
  content: McpContentBlock[];
  structuredContent?: unknown;
  isError?: boolean;
}

But toMcpToolResult() serializes only type, content, and optional structuredContent:

const out: McpToolResult = { type, content: contentStr };

if (response.structuredContent !== undefined && response.structuredContent !== null) {
  out.structuredContent =
    typeof response.structuredContent === "string"
      ? response.structuredContent
      : JSON.stringify(response.structuredContent);
}

return out;

Actual Behavior

A handler-level error response reaches the MCP client like this:

{
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Invalid file"
      }
    ]
  },
  "id": 5,
  "jsonrpc": "2.0"
}

There is no isError field.

Expected Behavior

The client-visible MCP result should include:

{
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Invalid file"
      }
    ],
    "isError": true
  },
  "id": 5,
  "jsonrpc": "2.0"
}

Per the MCP schema, missing isError defaults to false, so clients currently treat handler-level tool errors as successful tool results.

Spec reference: https://modelcontextprotocol.io/specification/2025-06-18/schema#tools-call

Notes

I'm unsure if this would best be solved in the node library, or in the extension handler same way _meta is (in preview builds)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    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