Skip to content

External /mcp task surface bypasses dispatch-boundary argument coercion #423

@mgoldsborough

Description

@mgoldsborough

Context

#422 added schema-aware argument coercion (coerceInputForSchema) at the MCP dispatch boundary in McpSource.execute, recovering models' string-encoded structured args (e.g. an array param emitted as "[\"a@b.com\"]") before they reach the wire, where the upstream validator would otherwise reject them ("Input should be a valid list on parameter X").

Gap

execute() covers the agent-loop dispatch path (inline + task-augmented). The external /mcp task surface dispatches differently: src/api/mcp-server.ts:888 calls taskAwareSource.startToolAsTask(localName, args, …) directly, bypassing execute() and therefore the coercion. An external MCP client (e.g. another agent driving this platform as a remote MCP server) invoking a task-augmented tool with a stringified-array argument reproduces the original bug.

Why deferred

The production incident behind #422 was on the agent-loop path (now fixed). The /mcp task surface is slated for a broader overhaul, so the fix belongs there rather than bolted onto the current dispatch.

Options when addressed

  • Move coerce + scrub into the wire-dispatch primitives (callToolInline and startToolAsTask), keyed on this.findTool(toolName)?.inputSchema, so every caller — execute and the direct /mcp path — converges on one normalization point; or
  • Coerce at the /mcp call site in mcp-server.ts before startToolAsTask.

The first is the structurally cleaner convergence and should be folded into the /mcp overhaul.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions