claude-agent-sdk


Nameclaude-agent-sdk JSON
Version 0.1.1 PyPI version JSON
download
home_pageNone
SummaryPython SDK for Claude Code
upload_time2025-10-07 00:21:14
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT
keywords ai anthropic claude sdk
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Claude Agent SDK for Python

Python SDK for Claude Agent. See the [Claude Agent SDK documentation](https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-python) for more information.

## Installation

```bash
pip install claude-agent-sdk
```

**Prerequisites:**
- Python 3.10+
- Node.js
- Claude Code 2.0.0+: `npm install -g @anthropic-ai/claude-code`

## Quick Start

```python
import anyio
from claude_agent_sdk import query

async def main():
    async for message in query(prompt="What is 2 + 2?"):
        print(message)

anyio.run(main)
```

## Basic Usage: query()

`query()` is an async function for querying Claude Code. It returns an `AsyncIterator` of response messages. See [src/claude_agent_sdk/query.py](src/claude_agent_sdk/query.py).

```python
from claude_agent_sdk import query, ClaudeAgentOptions, 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 = ClaudeAgentOptions(
    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 = ClaudeAgentOptions(
    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 = ClaudeAgentOptions(
    cwd="/path/to/project"  # or Path("/path/to/project")
)
```

## ClaudeSDKClient

`ClaudeSDKClient` supports bidirectional, interactive conversations with Claude
Code. See [src/claude_agent_sdk/client.py](src/claude_agent_sdk/client.py).

Unlike `query()`, `ClaudeSDKClient` additionally enables **custom tools** and **hooks**, both of which can be defined as Python functions.

### Custom Tools (as In-Process SDK MCP Servers)

A **custom tool** is a Python function that you can offer to Claude, for Claude to invoke as needed.

Custom tools are implemented in-process MCP servers that run directly within your Python application, eliminating the need for separate processes that regular MCP servers require.

For an end-to-end example, see [MCP Calculator](examples/mcp_calculator.py).

#### Creating a Simple Tool

```python
from claude_agent_sdk import tool, create_sdk_mcp_server, ClaudeAgentOptions, ClaudeSDKClient

# 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 = ClaudeAgentOptions(
    mcp_servers={"tools": server},
    allowed_tools=["mcp__tools__greet"]
)

async with ClaudeSDKClient(options=options) as client:
    await client.query("Greet Alice")

    # Extract and print response
    async for msg in client.receive_response():
        print(msg)
```

#### 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 = ClaudeAgentOptions(
    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 = ClaudeAgentOptions(
    mcp_servers={"calculator": calculator}
)
```

#### Mixed Server Support

You can use both SDK and external MCP servers together:

```python
options = ClaudeAgentOptions(
    mcp_servers={
        "internal": sdk_server,      # In-process SDK server
        "external": {                # External subprocess server
            "type": "stdio",
            "command": "external-server"
        }
    }
)
```

### Hooks

A **hook** is a Python function that the Claude Code *application* (*not* Claude) invokes at specific points of the Claude agent loop. Hooks can provide deterministic processing and automated feedback for Claude. Read more in [Claude Code Hooks Reference](https://docs.anthropic.com/en/docs/claude-code/hooks).

For more examples, see examples/hooks.py.

#### Example

```python
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient, HookMatcher

async def check_bash_command(input_data, tool_use_id, context):
    tool_name = input_data["tool_name"]
    tool_input = input_data["tool_input"]
    if tool_name != "Bash":
        return {}
    command = tool_input.get("command", "")
    block_patterns = ["foo.sh"]
    for pattern in block_patterns:
        if pattern in command:
            return {
                "hookSpecificOutput": {
                    "hookEventName": "PreToolUse",
                    "permissionDecision": "deny",
                    "permissionDecisionReason": f"Command contains invalid pattern: {pattern}",
                }
            }
    return {}

options = ClaudeAgentOptions(
    allowed_tools=["Bash"],
    hooks={
        "PreToolUse": [
            HookMatcher(matcher="Bash", hooks=[check_bash_command]),
        ],
    }
)

async with ClaudeSDKClient(options=options) as client:
    # Test 1: Command with forbidden pattern (will be blocked)
    await client.query("Run the bash command: ./foo.sh --help")
    async for msg in client.receive_response():
        print(msg)

    print("\n" + "=" * 50 + "\n")

    # Test 2: Safe command that should work
    await client.query("Run the bash command: echo 'Hello from hooks example!'")
    async for msg in client.receive_response():
        print(msg)
```


## Types

See [src/claude_agent_sdk/types.py](src/claude_agent_sdk/types.py) for complete type definitions:
- `ClaudeAgentOptions` - Configuration options
- `AssistantMessage`, `UserMessage`, `SystemMessage`, `ResultMessage` - Message types
- `TextBlock`, `ToolUseBlock`, `ToolResultBlock` - Content blocks

## Error Handling

```python
from claude_agent_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_agent_sdk/_errors.py](src/claude_agent_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.

See [examples/streaming_mode.py](examples/streaming_mode.py) for comprehensive examples involving `ClaudeSDKClient`. You can even run interactive examples in IPython from [examples/streaming_mode_ipython.py](examples/streaming_mode_ipython.py).

## Migrating from Claude Code SDK

If you're upgrading from the Claude Code SDK (versions < 0.1.0), please see the [CHANGELOG.md](CHANGELOG.md#010) for details on breaking changes and new features, including:

- `ClaudeCodeOptions` → `ClaudeAgentOptions` rename
- Merged system prompt configuration
- Settings isolation and explicit control
- New programmatic subagents and session forking features

## License

MIT

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "claude-agent-sdk",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "ai, anthropic, claude, sdk",
    "author": null,
    "author_email": "Anthropic <support@anthropic.com>",
    "download_url": "https://files.pythonhosted.org/packages/e6/85/5e0364d8b567375bc5561a5ca30d73db46072573308677e3db1c435dec69/claude_agent_sdk-0.1.1.tar.gz",
    "platform": null,
    "description": "# Claude Agent SDK for Python\n\nPython SDK for Claude Agent. See the [Claude Agent SDK documentation](https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-python) for more information.\n\n## Installation\n\n```bash\npip install claude-agent-sdk\n```\n\n**Prerequisites:**\n- Python 3.10+\n- Node.js\n- Claude Code 2.0.0+: `npm install -g @anthropic-ai/claude-code`\n\n## Quick Start\n\n```python\nimport anyio\nfrom claude_agent_sdk import query\n\nasync def main():\n    async for message in query(prompt=\"What is 2 + 2?\"):\n        print(message)\n\nanyio.run(main)\n```\n\n## Basic Usage: query()\n\n`query()` is an async function for querying Claude Code. It returns an `AsyncIterator` of response messages. See [src/claude_agent_sdk/query.py](src/claude_agent_sdk/query.py).\n\n```python\nfrom claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock\n\n# Simple query\nasync for message in query(prompt=\"Hello Claude\"):\n    if isinstance(message, AssistantMessage):\n        for block in message.content:\n            if isinstance(block, TextBlock):\n                print(block.text)\n\n# With options\noptions = ClaudeAgentOptions(\n    system_prompt=\"You are a helpful assistant\",\n    max_turns=1\n)\n\nasync for message in query(prompt=\"Tell me a joke\", options=options):\n    print(message)\n```\n\n### Using Tools\n\n```python\noptions = ClaudeAgentOptions(\n    allowed_tools=[\"Read\", \"Write\", \"Bash\"],\n    permission_mode='acceptEdits'  # auto-accept file edits\n)\n\nasync for message in query(\n    prompt=\"Create a hello.py file\",\n    options=options\n):\n    # Process tool use and results\n    pass\n```\n\n### Working Directory\n\n```python\nfrom pathlib import Path\n\noptions = ClaudeAgentOptions(\n    cwd=\"/path/to/project\"  # or Path(\"/path/to/project\")\n)\n```\n\n## ClaudeSDKClient\n\n`ClaudeSDKClient` supports bidirectional, interactive conversations with Claude\nCode. See [src/claude_agent_sdk/client.py](src/claude_agent_sdk/client.py).\n\nUnlike `query()`, `ClaudeSDKClient` additionally enables **custom tools** and **hooks**, both of which can be defined as Python functions.\n\n### Custom Tools (as In-Process SDK MCP Servers)\n\nA **custom tool** is a Python function that you can offer to Claude, for Claude to invoke as needed.\n\nCustom tools are implemented in-process MCP servers that run directly within your Python application, eliminating the need for separate processes that regular MCP servers require.\n\nFor an end-to-end example, see [MCP Calculator](examples/mcp_calculator.py).\n\n#### Creating a Simple Tool\n\n```python\nfrom claude_agent_sdk import tool, create_sdk_mcp_server, ClaudeAgentOptions, ClaudeSDKClient\n\n# Define a tool using the @tool decorator\n@tool(\"greet\", \"Greet a user\", {\"name\": str})\nasync def greet_user(args):\n    return {\n        \"content\": [\n            {\"type\": \"text\", \"text\": f\"Hello, {args['name']}!\"}\n        ]\n    }\n\n# Create an SDK MCP server\nserver = create_sdk_mcp_server(\n    name=\"my-tools\",\n    version=\"1.0.0\",\n    tools=[greet_user]\n)\n\n# Use it with Claude\noptions = ClaudeAgentOptions(\n    mcp_servers={\"tools\": server},\n    allowed_tools=[\"mcp__tools__greet\"]\n)\n\nasync with ClaudeSDKClient(options=options) as client:\n    await client.query(\"Greet Alice\")\n\n    # Extract and print response\n    async for msg in client.receive_response():\n        print(msg)\n```\n\n#### Benefits Over External MCP Servers\n\n- **No subprocess management** - Runs in the same process as your application\n- **Better performance** - No IPC overhead for tool calls\n- **Simpler deployment** - Single Python process instead of multiple\n- **Easier debugging** - All code runs in the same process\n- **Type safety** - Direct Python function calls with type hints\n\n#### Migration from External Servers\n\n```python\n# BEFORE: External MCP server (separate process)\noptions = ClaudeAgentOptions(\n    mcp_servers={\n        \"calculator\": {\n            \"type\": \"stdio\",\n            \"command\": \"python\",\n            \"args\": [\"-m\", \"calculator_server\"]\n        }\n    }\n)\n\n# AFTER: SDK MCP server (in-process)\nfrom my_tools import add, subtract  # Your tool functions\n\ncalculator = create_sdk_mcp_server(\n    name=\"calculator\",\n    tools=[add, subtract]\n)\n\noptions = ClaudeAgentOptions(\n    mcp_servers={\"calculator\": calculator}\n)\n```\n\n#### Mixed Server Support\n\nYou can use both SDK and external MCP servers together:\n\n```python\noptions = ClaudeAgentOptions(\n    mcp_servers={\n        \"internal\": sdk_server,      # In-process SDK server\n        \"external\": {                # External subprocess server\n            \"type\": \"stdio\",\n            \"command\": \"external-server\"\n        }\n    }\n)\n```\n\n### Hooks\n\nA **hook** is a Python function that the Claude Code *application* (*not* Claude) invokes at specific points of the Claude agent loop. Hooks can provide deterministic processing and automated feedback for Claude. Read more in [Claude Code Hooks Reference](https://docs.anthropic.com/en/docs/claude-code/hooks).\n\nFor more examples, see examples/hooks.py.\n\n#### Example\n\n```python\nfrom claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient, HookMatcher\n\nasync def check_bash_command(input_data, tool_use_id, context):\n    tool_name = input_data[\"tool_name\"]\n    tool_input = input_data[\"tool_input\"]\n    if tool_name != \"Bash\":\n        return {}\n    command = tool_input.get(\"command\", \"\")\n    block_patterns = [\"foo.sh\"]\n    for pattern in block_patterns:\n        if pattern in command:\n            return {\n                \"hookSpecificOutput\": {\n                    \"hookEventName\": \"PreToolUse\",\n                    \"permissionDecision\": \"deny\",\n                    \"permissionDecisionReason\": f\"Command contains invalid pattern: {pattern}\",\n                }\n            }\n    return {}\n\noptions = ClaudeAgentOptions(\n    allowed_tools=[\"Bash\"],\n    hooks={\n        \"PreToolUse\": [\n            HookMatcher(matcher=\"Bash\", hooks=[check_bash_command]),\n        ],\n    }\n)\n\nasync with ClaudeSDKClient(options=options) as client:\n    # Test 1: Command with forbidden pattern (will be blocked)\n    await client.query(\"Run the bash command: ./foo.sh --help\")\n    async for msg in client.receive_response():\n        print(msg)\n\n    print(\"\\n\" + \"=\" * 50 + \"\\n\")\n\n    # Test 2: Safe command that should work\n    await client.query(\"Run the bash command: echo 'Hello from hooks example!'\")\n    async for msg in client.receive_response():\n        print(msg)\n```\n\n\n## Types\n\nSee [src/claude_agent_sdk/types.py](src/claude_agent_sdk/types.py) for complete type definitions:\n- `ClaudeAgentOptions` - Configuration options\n- `AssistantMessage`, `UserMessage`, `SystemMessage`, `ResultMessage` - Message types\n- `TextBlock`, `ToolUseBlock`, `ToolResultBlock` - Content blocks\n\n## Error Handling\n\n```python\nfrom claude_agent_sdk import (\n    ClaudeSDKError,      # Base error\n    CLINotFoundError,    # Claude Code not installed\n    CLIConnectionError,  # Connection issues\n    ProcessError,        # Process failed\n    CLIJSONDecodeError,  # JSON parsing issues\n)\n\ntry:\n    async for message in query(prompt=\"Hello\"):\n        pass\nexcept CLINotFoundError:\n    print(\"Please install Claude Code\")\nexcept ProcessError as e:\n    print(f\"Process failed with exit code: {e.exit_code}\")\nexcept CLIJSONDecodeError as e:\n    print(f\"Failed to parse response: {e}\")\n```\n\nSee [src/claude_agent_sdk/_errors.py](src/claude_agent_sdk/_errors.py) for all error types.\n\n## Available Tools\n\nSee the [Claude Code documentation](https://docs.anthropic.com/en/docs/claude-code/settings#tools-available-to-claude) for a complete list of available tools.\n\n## Examples\n\nSee [examples/quick_start.py](examples/quick_start.py) for a complete working example.\n\nSee [examples/streaming_mode.py](examples/streaming_mode.py) for comprehensive examples involving `ClaudeSDKClient`. You can even run interactive examples in IPython from [examples/streaming_mode_ipython.py](examples/streaming_mode_ipython.py).\n\n## Migrating from Claude Code SDK\n\nIf you're upgrading from the Claude Code SDK (versions < 0.1.0), please see the [CHANGELOG.md](CHANGELOG.md#010) for details on breaking changes and new features, including:\n\n- `ClaudeCodeOptions` \u2192 `ClaudeAgentOptions` rename\n- Merged system prompt configuration\n- Settings isolation and explicit control\n- New programmatic subagents and session forking features\n\n## License\n\nMIT\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python SDK for Claude Code",
    "version": "0.1.1",
    "project_urls": {
        "Documentation": "https://docs.anthropic.com/en/docs/claude-code/sdk",
        "Homepage": "https://github.com/anthropics/claude-agent-sdk-python",
        "Issues": "https://github.com/anthropics/claude-agent-sdk-python/issues"
    },
    "split_keywords": [
        "ai",
        " anthropic",
        " claude",
        " sdk"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bb17d18977ef5089064bced8cbf056a4317fc175e986a4a98391fc4121c3cb5b",
                "md5": "c5fa11af4cecdc357ac987f7bb2193cb",
                "sha256": "4e95ed38786b045c5d42c942d5ce2870cd7e7c4c836cc22b5b9526b1543bfd8a"
            },
            "downloads": -1,
            "filename": "claude_agent_sdk-0.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c5fa11af4cecdc357ac987f7bb2193cb",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 33672,
            "upload_time": "2025-10-07T00:21:12",
            "upload_time_iso_8601": "2025-10-07T00:21:12.717582Z",
            "url": "https://files.pythonhosted.org/packages/bb/17/d18977ef5089064bced8cbf056a4317fc175e986a4a98391fc4121c3cb5b/claude_agent_sdk-0.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e6855e0364d8b567375bc5561a5ca30d73db46072573308677e3db1c435dec69",
                "md5": "7bc5be4bba1020013341d5e049c9158a",
                "sha256": "dcb224d4a65699cd9ceaddf4b9f9501606ba4f10d37fa691aff1ab60b9849b65"
            },
            "downloads": -1,
            "filename": "claude_agent_sdk-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "7bc5be4bba1020013341d5e049c9158a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 43941,
            "upload_time": "2025-10-07T00:21:14",
            "upload_time_iso_8601": "2025-10-07T00:21:14.018541Z",
            "url": "https://files.pythonhosted.org/packages/e6/85/5e0364d8b567375bc5561a5ca30d73db46072573308677e3db1c435dec69/claude_agent_sdk-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-07 00:21:14",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "anthropics",
    "github_project": "claude-agent-sdk-python",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "claude-agent-sdk"
}
        
Elapsed time: 0.66265s