feat: add supports_parallel_tool_calls for MCP servers (#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.
This commit is contained in:
Teknium 2026-05-16 01:04:28 -07:00 committed by GitHub
parent c445f48b78
commit 395e9dd9e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 260 additions and 2 deletions

View file

@ -393,6 +393,19 @@ def _is_destructive_command(cmd: str) -> bool:
return False
def _is_mcp_tool_parallel_safe(tool_name: str) -> bool:
"""Check if an MCP tool comes from a server with parallel tool calls enabled.
Lazy-imports from ``tools.mcp_tool`` to avoid circular dependencies.
Returns False if the MCP module is not available.
"""
try:
from tools.mcp_tool import is_mcp_tool_parallel_safe
return is_mcp_tool_parallel_safe(tool_name)
except Exception:
return False
def _should_parallelize_tool_batch(tool_calls) -> bool:
"""Return True when a tool-call batch is safe to run concurrently."""
if len(tool_calls) <= 1:
@ -432,7 +445,9 @@ def _should_parallelize_tool_batch(tool_calls) -> bool:
continue
if tool_name not in _PARALLEL_SAFE_TOOLS:
return False
# Check if it's an MCP tool from a server that opted into parallel calls.
if not _is_mcp_tool_parallel_safe(tool_name):
return False
return True