Skip to content

OpenAI-compatible and Responses runs persist MCP tool calls without mcpServerName #15487

Description

@danny-avila

Summary

buildRunToolSet takes allowAmbiguousMcpToolNamesWithoutIdentity, which defaults to false. The chat path leaves it at the default; the OpenAI-compatible and Responses paths pass true and never wire resolveMcpServerName / stampMcpServerIdentities. Tool calls persisted on those paths therefore carry no mcpServerName, and continuing the same conversation in the chat UI can drop those turns from context.

Flagged by a static analyzer on a downstream merge; verified by reading the call sites, not reproduced.

The asymmetry

packages/api/src/agents/tools.ts:

allowAmbiguousMcpToolNamesWithoutIdentity = false,

api/server/controllers/agents/client.js (chat) passes four arguments, so the flag stays false:

const toolSet = buildRunToolSet(
  this.options.agent,
  this.agentConfigs?.values(),
  this.options.subagentTasks == null ? undefined : [Constants.CHECK_BACKGROUND_TASK],
  payload,
);

api/server/controllers/agents/openai.js (~809) passes a fifth positional true:

const toolSet = buildRunToolSet(
  primaryConfig,
  handoffAgentConfigs.values(),
  undefined,
  openaiMessages,
  true,
);

responses.js (~1007) does the same.

Separately, stampMcpServerIdentities and resolveMcpServerName appear only in client.js and callbacks.js. Neither openai.js nor responses.js references them.

Consequence

A run through the OpenAI-compatible or Responses endpoint persists MCP tool calls without an identity stamp. That is self-consistent while the flag is on, but the chat path reads the same history with the flag off, so delimiter-bearing historical MCP names cannot be resolved unambiguously and formatAgentMessages can strip those turns.

The visible effect would be a conversation started via API losing MCP tool-call history when continued in the UI — which reads as context loss rather than a tool-naming problem, so it seems worth an explicit decision either way.

Questions

  • Is the permissive flag on the API paths deliberate, on the grounds that those runs never round-trip into the chat UI? If so a comment stating that would help, since the flag's default and these two overrides now disagree.
  • If they can round-trip, wiring resolveMcpServerName / stampMcpServerIdentities on both API paths would make the persisted history readable by the chat path.

Caveat

Static read of the three call sites and the flag default. Not reproduced against a live API-then-UI continuation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions