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.