Skip to content

feat: add supports_parallel_tool_calls for MCP servers - #9944

Closed
teknium1 wants to merge 1 commit into
mainfrom
codex-port/mcp-parallel-tool-calls
Closed

feat: add supports_parallel_tool_calls for MCP servers#9944
teknium1 wants to merge 1 commit into
mainfrom
codex-port/mcp-parallel-tool-calls

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Port of openai/codex#17667: MCP servers can now opt-in to parallel tool execution via a per-server config flag.

Problem

All MCP tools were forced to run sequentially because they weren't in the static _PARALLEL_SAFE_TOOLS set in run_agent.py. This was unnecessarily slow for MCP servers whose tools are safe to run concurrently (e.g. read-only query servers, independent API endpoints).

Solution

Add supports_parallel_tool_calls: true config option for MCP servers:

mcp_servers:
  docs:
    command: "docs-server"
    supports_parallel_tool_calls: true

When set, tools from that server are eligible for concurrent execution in the same tool-call batch, matching the behavior already available for built-in read-only tools (web_search, read_file, etc.).

Implementation

  • tools/mcp_tool.py: New _parallel_safe_servers set tracks sanitized server names with the flag enabled. Populated during register_mcp_servers() (idempotent, handles toggling on/off). New public API is_mcp_tool_parallel_safe(tool_name) checks if a tool belongs to a parallel-safe server.
  • run_agent.py: New _is_mcp_tool_parallel_safe() lazy-import wrapper. _should_parallelize_tool_batch() now checks MCP tools against server config when they're not in the static parallel-safe set.
  • Tests: 7 unit tests for is_mcp_tool_parallel_safe() and register_mcp_servers tracking, plus 4 integration tests for _should_parallelize_tool_batch() with MCP tools.
  • Docs: Updated MCP feature docs, config reference, and module docstring.

Architectural differences from Codex

Codex is Rust and threads the config through ToolRouter at the crate level. Hermes uses a module-level set (_parallel_safe_servers) populated during MCP server registration, queried via a function that does server name extraction from tool names. The server name matching handles underscores in sanitized server names by checking all registered parallel-safe prefixes.

Test plan

  • 11 new tests all passing
  • All 172 existing MCP tests still pass
  • All 15 parallel-related run_agent tests still pass

Port from openai/codex#17667: MCP servers can now opt-in to parallel
tool execution by setting supports_parallel_tool_calls: true in their
config. This allows tools from the same server to run concurrently
within a single tool-call batch, matching the behavior already available
for built-in tools like web_search and read_file.

Previously all MCP tools were forced sequential because they weren't in
the _PARALLEL_SAFE_TOOLS set. Now _should_parallelize_tool_batch checks
is_mcp_tool_parallel_safe() which looks up the server's config flag.

Config example:
  mcp_servers:
    docs:
      command: "docs-server"
      supports_parallel_tool_calls: true

Changes:
- tools/mcp_tool.py: Track parallel-safe servers in _parallel_safe_servers
  set, populated during register_mcp_servers(). Add is_mcp_tool_parallel_safe()
  public API.
- run_agent.py: Add _is_mcp_tool_parallel_safe() lazy-import wrapper. Update
  _should_parallelize_tool_batch() to check MCP tools against server config.
- 11 new tests covering the feature end-to-end.
- Updated MCP docs and config reference.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have tool/mcp MCP client and OAuth comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint labels Apr 26, 2026
@teknium1

Copy link
Copy Markdown
Contributor Author

Closing in favor of #26825, which salvages this PR onto current main with the cherry-pick conflict (circuit breaker block landed on main after this PR's branch point) resolved and two stale test mocks of the removed _sync_mcp_toolsets helper fixed. Your authorship preserved via rebase-merge.

@teknium1 teknium1 closed this May 16, 2026
@teknium1

Copy link
Copy Markdown
Contributor Author

Correction on the earlier close comment: #26825 was squash-merged (not rebase-merged). Authorship is preserved in either case since both PRs were authored by you.

cameronpyne-smith referenced this pull request in cameronpyne-smith/Argus Jun 13, 2026
The post-filing decoration re-queried issues created since a timestamp and
stopped at the first non-empty result — racing GitHub's index, so the
last-created issue often wasn't returned yet and went undecorated (#9951
got no type/board this round; #9944 earlier). Capture each issue number
straight from `gh issue create` output and decorate exactly those — no
re-query, no race, no settle delay.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have tool/mcp MCP client and OAuth type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants