From b720b2e13a722b05ad0a74759c271a3544d8f3c2 Mon Sep 17 00:00:00 2001 From: peter-luminova Date: Fri, 20 Feb 2026 12:48:01 +0530 Subject: [PATCH] feat(types): add mcp_servers field to AgentDefinition ROOT CAUSE: The Python SDK's AgentDefinition was missing the mcpServers field that is documented in Claude Code docs and supported by the CLI via .claude/agents/*.md frontmatter. This prevented subagents from having their own MCP server configurations. CHANGES: - Added mcp_servers: dict[str, "McpServerConfig"] | None field to AgentDefinition - Added test_build_command_agents_with_mcp_servers test - Added agent_with_mcp_servers_example() to examples/agents.py IMPACT: - Subagents can now have their own MCP server configurations - Matches CLI behavior and TypeScript SDK capabilities - Fully backward compatible (optional field, defaults to None) FILES MODIFIED: - src/claude_agent_sdk/types.py - tests/test_transport.py - examples/agents.py Co-Authored-By: Claude Sonnet 4.6 --- examples/agents.py | 37 +++++++++++++++++++++++++++++++++++ src/claude_agent_sdk/types.py | 1 + tests/test_transport.py | 27 +++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/examples/agents.py b/examples/agents.py index 9e7439ee..1983836e 100644 --- a/examples/agents.py +++ b/examples/agents.py @@ -113,11 +113,48 @@ async def multiple_agents_example(): print() +async def agent_with_mcp_servers_example(): + """Example using an agent with MCP servers.""" + print("=== Agent with MCP Servers Example ===") + + options = ClaudeAgentOptions( + agents={ + "data-analyst": AgentDefinition( + description="Analyzes data using PostgreSQL", + prompt="You are a data analyst. Use the PostgreSQL MCP server to query and analyze data.", + tools=["Bash"], # Can use Bash + MCP tools + mcp_servers={ + "postgres": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-postgres"], + "env": { + "POSTGRES_CONNECTION_STRING": "postgresql://localhost:5432/mydb" + }, + } + }, + ), + }, + ) + + async for message in query( + prompt="Use the data-analyst agent to list all tables in the database", + options=options, + ): + if isinstance(message, AssistantMessage): + for block in message.content: + if isinstance(block, TextBlock): + print(f"Claude: {block.text}") + elif isinstance(message, ResultMessage) and message.total_cost_usd and message.total_cost_usd > 0: + print(f"\nCost: ${message.total_cost_usd:.4f}") + print() + + async def main(): """Run all agent examples.""" await code_reviewer_example() await documentation_writer_example() await multiple_agents_example() + await agent_with_mcp_servers_example() if __name__ == "__main__": diff --git a/src/claude_agent_sdk/types.py b/src/claude_agent_sdk/types.py index 3ea89d5a..f269aec6 100644 --- a/src/claude_agent_sdk/types.py +++ b/src/claude_agent_sdk/types.py @@ -47,6 +47,7 @@ class AgentDefinition: prompt: str tools: list[str] | None = None model: Literal["sonnet", "opus", "haiku", "inherit"] | None = None + mcp_servers: dict[str, "McpServerConfig"] | None = None # Permission Update types (matching TypeScript SDK) diff --git a/tests/test_transport.py b/tests/test_transport.py index 65e6ada7..eec7de8f 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -867,6 +867,33 @@ async def fake_stream(): assert "--input-format" in cmd2 assert "stream-json" in cmd2 + def test_build_command_agents_with_mcp_servers(self): + """Test that agents with mcp_servers are properly serialized.""" + from claude_agent_sdk.types import AgentDefinition, McpStdioServerConfig + + # Create agent with MCP servers + mcp_config: McpStdioServerConfig = { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-everything"], + } + + agents = { + "test-agent": AgentDefinition( + description="A test agent with MCP servers", + prompt="You are a test agent", + mcp_servers={"everything": mcp_config}, + ) + } + + # Test that agents are sent via initialize (not CLI flag) + transport = SubprocessCLITransport( + prompt="Hello", + options=make_options(agents=agents), + ) + cmd = transport._build_command() + assert "--agents" not in cmd + assert "--input-format" in cmd + def test_build_command_always_uses_streaming(self): """Test that streaming mode is always used, even for string prompts.