Summary
The claude-agent-sdk provider (src/conductor/providers/claude_agent_sdk.py) declares mcp_tools=False in its CAPABILITIES and rejects workflow-level runtime.mcp_servers at the factory. The comment at claude_agent_sdk.py:115-116 says why:
MCP servers are rejected at the factory (no translation from Conductor's MCP config to the SDK's MCP dict is implemented).
This is an implementation gap, not an upstream SDK limitation. claude-agent-sdk (locked at 0.2.87 in uv.lock) genuinely supports MCP servers via ClaudeAgentOptions.mcp_servers: dict[str, McpServerConfig], where McpServerConfig is one of McpStdioServerConfig (command/args/env), McpSSEServerConfig (url/headers), or McpHttpServerConfig (url/headers).
Conductor's own MCPServerDef (src/conductor/config/schema.py:1605) already has an almost 1:1 shape: type: "stdio"|"http"|"sse", command, args, env, url, headers, timeout, tools (allowlist, ["*"] = all).
Proposal
- Translate
MCPServerDef → the SDK's McpStdioServerConfig / McpSSEServerConfig / McpHttpServerConfig shapes and pass them via ClaudeAgentOptions.mcp_servers.
- Use the SDK's
allowed_tools (or equivalent scoping) to honor each server's per-tool tools: allowlist and the per-agent resolved tools: list from resolve_agent_tools(), mirroring how claude.py filters MCP tools today (_convert_mcp_tools_to_claude's tool_filter).
- Flip
CAPABILITIES.mcp_tools to True once wired, and update the _resolve_tool_config docstring/behavior in claude_agent_sdk.py (it currently refuses any non-empty per-agent tools: allowlist because there's no MCP-name → CLI-tool-ID mapping — that refusal reasoning goes away once MCP servers route through the SDK's own MCP support instead of native CLI tool IDs).
- Update
docs/providers/experimental.md and the provider-parity notes in AGENTS.md accordingly.
Why it matters
Today, workflows that want to use claude-agent-sdk (e.g. to get the full Claude Code CLI tool preset) cannot also attach custom MCP tool servers (web search, internal APIs, etc.) — they have to choose between the CLI preset and MCP tools, even though the underlying SDK supports both simultaneously.
Summary
The
claude-agent-sdkprovider (src/conductor/providers/claude_agent_sdk.py) declaresmcp_tools=Falsein itsCAPABILITIESand rejects workflow-levelruntime.mcp_serversat the factory. The comment atclaude_agent_sdk.py:115-116says why:This is an implementation gap, not an upstream SDK limitation.
claude-agent-sdk(locked at0.2.87inuv.lock) genuinely supports MCP servers viaClaudeAgentOptions.mcp_servers: dict[str, McpServerConfig], whereMcpServerConfigis one ofMcpStdioServerConfig(command/args/env),McpSSEServerConfig(url/headers), orMcpHttpServerConfig(url/headers).Conductor's own
MCPServerDef(src/conductor/config/schema.py:1605) already has an almost 1:1 shape:type: "stdio"|"http"|"sse",command,args,env,url,headers,timeout,tools(allowlist,["*"]= all).Proposal
MCPServerDef→ the SDK'sMcpStdioServerConfig/McpSSEServerConfig/McpHttpServerConfigshapes and pass them viaClaudeAgentOptions.mcp_servers.allowed_tools(or equivalent scoping) to honor each server's per-tooltools:allowlist and the per-agent resolvedtools:list fromresolve_agent_tools(), mirroring howclaude.pyfilters MCP tools today (_convert_mcp_tools_to_claude'stool_filter).CAPABILITIES.mcp_toolstoTrueonce wired, and update the_resolve_tool_configdocstring/behavior inclaude_agent_sdk.py(it currently refuses any non-empty per-agenttools:allowlist because there's no MCP-name → CLI-tool-ID mapping — that refusal reasoning goes away once MCP servers route through the SDK's own MCP support instead of native CLI tool IDs).docs/providers/experimental.mdand the provider-parity notes inAGENTS.mdaccordingly.Why it matters
Today, workflows that want to use
claude-agent-sdk(e.g. to get the full Claude Code CLI tool preset) cannot also attach custom MCP tool servers (web search, internal APIs, etc.) — they have to choose between the CLI preset and MCP tools, even though the underlying SDK supports both simultaneously.