mirror of
https://github.com/anthropics/claude-code-sdk-python.git
synced 2025-12-23 09:19:52 +00:00
## 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>
217 lines
5.1 KiB
Markdown
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
|