No description
Find a file
Michael Gendy 0aab45be7d
Some checks are pending
Lint / lint (push) Waiting to run
Test / test-e2e (3.12) (push) Blocked by required conditions
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
Test / test-e2e (3.10) (push) Blocked by required conditions
Test / test-e2e (3.11) (push) Blocked by required conditions
Test / test-e2e (3.13) (push) Blocked by required conditions
Test / test-examples (3.10) (push) Blocked by required conditions
Test / test-examples (3.11) (push) Blocked by required conditions
Test / test-examples (3.12) (push) Blocked by required conditions
Test / test-examples (3.13) (push) Blocked by required conditions
Remove max thinking tokens (#144)
It's not used anywhere and it can be set through the env parameter

`ClaudeCodeOptions(env={"MAX_THINKING_TOKENS" : 8000})`
2025-09-12 02:22:01 -07:00
.claude Add PostToolUse hook for automatic ruff formatting (#158) 2025-09-08 07:06:46 -07:00
.github/workflows Add custom tool callbacks and e2e tests (#157) 2025-09-08 08:51:40 -07:00
e2e-tests Add custom tool callbacks and e2e tests (#157) 2025-09-08 08:51:40 -07:00
examples Remove max thinking tokens (#144) 2025-09-12 02:22:01 -07:00
scripts Fix "Publish to PyPI" workflow: Add commit signing and improve diff (#82) 2025-07-21 09:53:24 -07:00
src/claude_code_sdk Remove max thinking tokens (#144) 2025-09-12 02:22:01 -07:00
tests Remove max thinking tokens (#144) 2025-09-12 02:22:01 -07:00
.gitignore Implement control protocol support for Python SDK (#139) 2025-09-01 23:04:22 -07:00
CHANGELOG.md Support --add-dir flag (#104) 2025-07-31 20:52:30 -07:00
CLAUDE.md Fix lint and test 2025-07-19 20:04:58 -07:00
LICENSE Initial Python SDK import 2025-06-12 00:16:19 -07:00
pyproject.toml chore: bump version to 0.0.21 (#152) 2025-09-05 13:40:30 -07:00
README.md Add custom tool callbacks and e2e tests (#157) 2025-09-08 08:51:40 -07:00

Claude Code SDK for Python

Python SDK for Claude Code. See the Claude Code SDK documentation for more information.

Installation

pip install claude-code-sdk

Prerequisites:

  • Python 3.10+
  • Node.js
  • Claude Code: npm install -g @anthropic-ai/claude-code

Quick Start

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

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

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

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

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

# 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:

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 for complete type definitions:

  • ClaudeCodeOptions - Configuration options
  • AssistantMessage, UserMessage, SystemMessage, ResultMessage - Message types
  • TextBlock, ToolUseBlock, ToolResultBlock - Content blocks

Error Handling

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 for all error types.

Available Tools

See the Claude Code documentation for a complete list of available tools.

Examples

See examples/quick_start.py for a complete working example.

License

MIT