claude-code-sdk-python/README.md
kashyap murali 9ef57859af
feat: Add in-process SDK MCP server support (#142)
## Summary

Adds in-process SDK MCP server support to the Python SDK, building on
the control protocol from #139.

**Note: Targets `dickson/control` branch (PR #139), not `main`.**

## Key Changes

- Added `@tool` decorator and `create_sdk_mcp_server()` API for defining
in-process MCP servers
- SDK MCP servers run directly in the Python process (no subprocess
overhead)
- Moved SDK MCP handling from Transport to Query class for proper
architectural layering
- Added `McpSdkServerConfig` type and integrated with control protocol

## Example

```python
from claude_code_sdk import tool, create_sdk_mcp_server

@tool("greet", "Greet a user", {"name": str})
async def greet_user(args):
    return {"content": [{"type": "text", "text": f"Hello, {args['name']}!"}]}

server = create_sdk_mcp_server(name="my-tools", tools=[greet_user])

options = ClaudeCodeOptions(mcp_servers={"tools": server})
```

## Testing

- Added integration tests in `test_sdk_mcp_integration.py`
- Added example calculator server in `examples/mcp_calculator.py`

---------

Co-authored-by: Dickson Tsai <dickson@anthropic.com>
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-09-03 08:29:32 -07:00

217 lines
5.1 KiB
Markdown

# Claude Code SDK for Python
Python SDK for Claude Code. See the [Claude Code SDK documentation](https://docs.anthropic.com/en/docs/claude-code/sdk) for more information.
## Installation
```bash
pip install claude-code-sdk
```
**Prerequisites:**
- Python 3.10+
- Node.js
- Claude Code: `npm install -g @anthropic-ai/claude-code`
## Quick Start
```python
import anyio
from claude_code_sdk import query
async def main():
async for message in query(prompt="What is 2 + 2?"):
print(message)
anyio.run(main)
```
## Usage
### Basic Query
```python
from claude_code_sdk import query, ClaudeCodeOptions, AssistantMessage, TextBlock
# Simple query
async for message in query(prompt="Hello Claude"):
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(block.text)
# With options
options = ClaudeCodeOptions(
system_prompt="You are a helpful assistant",
max_turns=1
)
async for message in query(prompt="Tell me a joke", options=options):
print(message)
```
### Using Tools
```python
options = ClaudeCodeOptions(
allowed_tools=["Read", "Write", "Bash"],
permission_mode='acceptEdits' # auto-accept file edits
)
async for message in query(
prompt="Create a hello.py file",
options=options
):
# Process tool use and results
pass
```
### Working Directory
```python
from pathlib import Path
options = ClaudeCodeOptions(
cwd="/path/to/project" # or Path("/path/to/project")
)
```
### SDK MCP Servers (In-Process)
The SDK now supports in-process MCP servers that run directly within your Python application, eliminating the need for separate processes.
#### Creating a Simple Tool
```python
from claude_code_sdk import tool, create_sdk_mcp_server
# Define a tool using the @tool decorator
@tool("greet", "Greet a user", {"name": str})
async def greet_user(args):
return {
"content": [
{"type": "text", "text": f"Hello, {args['name']}!"}
]
}
# Create an SDK MCP server
server = create_sdk_mcp_server(
name="my-tools",
version="1.0.0",
tools=[greet_user]
)
# Use it with Claude
options = ClaudeCodeOptions(
mcp_servers={"tools": server}
)
async for message in query(prompt="Greet Alice", options=options):
print(message)
```
#### Benefits Over External MCP Servers
- **No subprocess management** - Runs in the same process as your application
- **Better performance** - No IPC overhead for tool calls
- **Simpler deployment** - Single Python process instead of multiple
- **Easier debugging** - All code runs in the same process
- **Type safety** - Direct Python function calls with type hints
#### Migration from External Servers
```python
# BEFORE: External MCP server (separate process)
options = ClaudeCodeOptions(
mcp_servers={
"calculator": {
"type": "stdio",
"command": "python",
"args": ["-m", "calculator_server"]
}
}
)
# AFTER: SDK MCP server (in-process)
from my_tools import add, subtract # Your tool functions
calculator = create_sdk_mcp_server(
name="calculator",
tools=[add, subtract]
)
options = ClaudeCodeOptions(
mcp_servers={"calculator": calculator}
)
```
#### Mixed Server Support
You can use both SDK and external MCP servers together:
```python
options = ClaudeCodeOptions(
mcp_servers={
"internal": sdk_server, # In-process SDK server
"external": { # External subprocess server
"type": "stdio",
"command": "external-server"
}
}
)
```
## API Reference
### `query(prompt, options=None)`
Main async function for querying Claude.
**Parameters:**
- `prompt` (str): The prompt to send to Claude
- `options` (ClaudeCodeOptions): Optional configuration
**Returns:** AsyncIterator[Message] - Stream of response messages
### Types
See [src/claude_code_sdk/types.py](src/claude_code_sdk/types.py) for complete type definitions:
- `ClaudeCodeOptions` - Configuration options
- `AssistantMessage`, `UserMessage`, `SystemMessage`, `ResultMessage` - Message types
- `TextBlock`, `ToolUseBlock`, `ToolResultBlock` - Content blocks
## Error Handling
```python
from claude_code_sdk import (
ClaudeSDKError, # Base error
CLINotFoundError, # Claude Code not installed
CLIConnectionError, # Connection issues
ProcessError, # Process failed
CLIJSONDecodeError, # JSON parsing issues
)
try:
async for message in query(prompt="Hello"):
pass
except CLINotFoundError:
print("Please install Claude Code")
except ProcessError as e:
print(f"Process failed with exit code: {e.exit_code}")
except CLIJSONDecodeError as e:
print(f"Failed to parse response: {e}")
```
See [src/claude_code_sdk/_errors.py](src/claude_code_sdk/_errors.py) for all error types.
## Available Tools
See the [Claude Code documentation](https://docs.anthropic.com/en/docs/claude-code/settings#tools-available-to-claude) for a complete list of available tools.
## Examples
See [examples/quick_start.py](examples/quick_start.py) for a complete working example.
## License
MIT