Skip to content

feat: #1167 add opt-in server-prefixed MCP tool names#3019

Open
mavrickdeveloper wants to merge 4 commits intoopenai:mainfrom
mavrickdeveloper:fix/mcp-duplicate-tool-names
Open

feat: #1167 add opt-in server-prefixed MCP tool names#3019
mavrickdeveloper wants to merge 4 commits intoopenai:mainfrom
mavrickdeveloper:fix/mcp-duplicate-tool-names

Conversation

@mavrickdeveloper
Copy link
Copy Markdown

Summary

This fixes the duplicate local MCP tool-name case from #1167 without changing the default behavior. By default, duplicate MCP tool names still fail fast. When include_server_in_tool_names is enabled, local MCP tools are exposed with deterministic server-prefixed public names, while calls still go back to the original MCP tool name on the original server.

The generated names are kept safe for function-tool payloads: ASCII-only, capped at 64 characters, and collision-resistant when server names or tool names normalize to the same value. The reservation set also includes local function tool names on the agent so an MCP alias cannot shadow an existing tool.

Test plan

  • uv run pytest tests/mcp/test_mcp_util.py tests/mcp/test_runner_calls_mcp.py -q
  • uv run mypy src/agents/agent.py src/agents/mcp/util.py tests/mcp/test_mcp_util.py tests/mcp/test_runner_calls_mcp.py
  • uv run pyright --project pyrightconfig.json src/agents/agent.py src/agents/mcp/util.py tests/mcp/test_mcp_util.py tests/mcp/test_runner_calls_mcp.py
  • uv run ruff check src/agents/agent.py src/agents/mcp/util.py tests/mcp/test_mcp_util.py tests/mcp/test_runner_calls_mcp.py
  • make build-docs
  • Manual check with two real filesystem MCP servers via npx @modelcontextprotocol/server-filesystem: verified unique server-prefixed names and invoked list_allowed_directories through the prefixed public name.

I also ran the repo verification script. make format and make lint passed, but the full make tests / repo-wide make typecheck are currently blocked locally by unrelated optional dependency, runloop, voice, and sandbox failures. The focused MCP checks above pass.

Issue number

Closes #1167

Checks

  • I've added new tests (if relevant)
  • I've added/updated the relevant documentation
  • I've run make lint and make format
  • I've made sure tests pass

@github-actions github-actions Bot added bug Something isn't working documentation Improvements or additions to documentation feature:mcp labels Apr 24, 2026
@mavrickdeveloper mavrickdeveloper marked this pull request as ready for review April 24, 2026 02:10
@mavrickdeveloper mavrickdeveloper changed the title fix: add opt-in server-prefixed MCP tool names feat: add opt-in server-prefixed MCP tool names Apr 24, 2026
@mavrickdeveloper mavrickdeveloper changed the title feat: add opt-in server-prefixed MCP tool names feat: #1167 add opt-in server-prefixed MCP tool names Apr 24, 2026
Copy link
Copy Markdown
Member

@seratch seratch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One remaining collision surface seems worth covering before merge: handoff tool names are not included in reserved_tool_names.

Agent.get_mcp_tools() currently reserves existing local FunctionTool names, but handoffs are also serialized as function tools in the same model request via handoff.tool_name. During turn resolution, handoff_map is checked before function-tool lookup, so an agent with a handoff named mcp_calendar__search plus a calendar MCP server exposing search would publish a duplicate public function name, and a model call to mcp_calendar__search would be treated as a handoff instead of the MCP tool.

Could we include enabled handoff tool names in the reserved set too, or otherwise validate and fail fast on this collision? That would make the new collision-avoidance behavior cover all local function-like tools, not just entries in agent.tools.

@github-actions github-actions Bot added enhancement New feature or request and removed bug Something isn't working labels Apr 26, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c11fd67dd6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/mcp/util.py Outdated
Comment on lines +348 to +350
candidate = cls._shorten_tool_name(base_name, seed)
if candidate not in reserved_names:
return candidate
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Make prefixed MCP names stable across list_tools order changes

When include_server_in_tool_names is enabled, this returns the unsuffixed base_name for whichever colliding tool is seen first, and only later tools get hashed suffixes. If a server returns tools in a different order between turns (or across resumed runs), two MCP tools whose names normalize to the same safe form (for example search and search!) can swap public aliases, so a previously emitted tool name can dispatch to a different underlying MCP tool. This violates the commit’s deterministic-name guarantee and can route model calls to the wrong tool in multi-turn runs.

Useful? React with 👍 / 👎.

@mavrickdeveloper
Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Use batch-local server/tool coordinates for prefixed MCP tool name allocation so the override map is scoped to a single listing pass and does not rely on Python object identity.
@mavrickdeveloper
Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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

Labels

documentation Improvements or additions to documentation enhancement New feature or request feature:mcp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicate tool names in multiple MCP tools cause the agent list to hang

2 participants