Skip to content

feat(mcp): supports_parallel_tool_calls for MCP servers (salvage of #9944)#26825

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-db18949e
May 16, 2026
Merged

feat(mcp): supports_parallel_tool_calls for MCP servers (salvage of #9944)#26825
teknium1 merged 1 commit into
mainfrom
hermes/hermes-db18949e

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Salvage of #9944 — MCP servers can opt-in to parallel tool execution by setting supports_parallel_tool_calls: true in their config. Tools from opted-in servers can run concurrently within a single tool-call batch, matching the behavior already available for read-only built-ins like web_search and read_file.

Port from openai/codex#17667.

Why salvage

Original PR is 4,266 commits stale. Cherry-picking onto current main hit one conflict in tools/mcp_tool.py (circuit breaker module-level state block was added on main between the PR's branch point and today) — resolved by keeping main's block and appending the PR's _parallel_safe_servers set. Also fixed two tests that mocked _sync_mcp_toolsets, a helper that no longer exists on main.

Changes

  • tools/mcp_tool.py: _parallel_safe_servers module-level set, populated during register_mcp_servers() (idempotent, handles toggling). New public is_mcp_tool_parallel_safe(tool_name) walks registered prefixes (server names can contain underscores after sanitization).
  • run_agent.py: lazy-import wrapper _is_mcp_tool_parallel_safe(). _should_parallelize_tool_batch() now consults it for MCP tools that aren't in the static _PARALLEL_SAFE_TOOLS set.
  • 11 new tests covering server tracking, toggle behavior, prefix lookup, integration with _should_parallelize_tool_batch.
  • Docs: mcp.md + mcp-config-reference.md updated.

Validation

Result
tests/tools/test_mcp_tool.py 193/193
tests/run_agent/test_run_agent.py + parallel MCP tests 336/336
E2E (manual): opted-in detection, non-opted, non-MCP, edge cases, run_agent lazy import All OK

Architectural note

Codex implements this through ToolRouter at the Rust crate level. We use a module-level set populated during server registration and queried via is_mcp_tool_parallel_safe(tool_name), which handles underscores-in-server-names by checking all registered parallel-safe prefixes. Same external behavior, different glue.

Credit

@teknium1's original scout work in #9944. This PR salvages it onto current main.

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.
@teknium1 teknium1 merged commit 395e9dd into main May 16, 2026
17 of 18 checks passed
@teknium1 teknium1 deleted the hermes/hermes-db18949e branch May 16, 2026 08:04
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-db18949e vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8323 on HEAD, 8323 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 4350 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists comp/agent Core agent loop, run_agent.py, prompt builder tool/mcp MCP client and OAuth labels May 16, 2026
DIZ-admin pushed a commit to DIZ-admin/hermes-agent that referenced this pull request May 16, 2026
…26825)

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.
venyon2k pushed a commit to venyon2k/hermes-agent that referenced this pull request May 17, 2026
…26825)

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.
teknium1 added a commit that referenced this pull request May 17, 2026
…t to tool_dispatch_helpers

Original commit 395e9dd by Teknium targeted module-level _is_mcp_tool_parallel_safe
and _should_parallelize_tool_batch helpers in pre-refactor run_agent.py. Both
helpers now live in agent/tool_dispatch_helpers.py — re-applied to that
module.

The tools/mcp_tool.py portion (the public is_mcp_tool_parallel_safe API
+ _parallel_safe_servers tracking) merged cleanly from main via the prior
merge commit.

Co-authored-by: Teknium <127238744+teknium1@users.noreply.github.com>
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
…26825)

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.
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
…26825) — port to tool_dispatch_helpers

Original commit 395e9dd by Teknium targeted module-level _is_mcp_tool_parallel_safe
and _should_parallelize_tool_batch helpers in pre-refactor run_agent.py. Both
helpers now live in agent/tool_dispatch_helpers.py — re-applied to that
module.

The tools/mcp_tool.py portion (the public is_mcp_tool_parallel_safe API
+ _parallel_safe_servers tracking) merged cleanly from main via the prior
merge commit.

Co-authored-by: Teknium <127238744+teknium1@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P2 Medium — degraded but workaround exists 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