Python SDK for Claude Code providing simple query functions and advanced bidirectional interactive conversations with custom tool support
npx @tessl/cli install tessl/pypi-claude-code-sdk@0.0.0Python SDK for Claude Code providing comprehensive integration with Claude AI capabilities through both simple query functions and advanced bidirectional interactive conversations. The SDK supports custom tools implemented as in-process MCP servers that run directly within Python applications, eliminating the need for separate processes while providing better performance and easier debugging.
pip install claude-code-sdkfrom claude_code_sdk import queryFor interactive conversations with custom tools and hooks:
from claude_code_sdk import ClaudeSDKClient, ClaudeCodeOptionsFor creating custom tools:
from claude_code_sdk import tool, create_sdk_mcp_server, SdkMcpToolFor type safety:
from claude_code_sdk import (
AssistantMessage, UserMessage, SystemMessage, ResultMessage,
TextBlock, ToolUseBlock, ToolResultBlock,
PermissionMode, McpServerConfig
)import anyio
from claude_code_sdk import query
async def main():
# Simple one-shot query
async for message in query(prompt="What is 2 + 2?"):
print(message)
anyio.run(main)With options and tool usage:
from claude_code_sdk import query, ClaudeCodeOptions, AssistantMessage, TextBlock
async def main():
options = ClaudeCodeOptions(
allowed_tools=["Read", "Write", "Bash"],
permission_mode='acceptEdits', # auto-accept file edits
cwd="/path/to/project"
)
async for message in query(
prompt="Create a hello.py file",
options=options
):
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(block.text)
anyio.run(main)The Claude Code SDK is built around two main interaction patterns:
query() function for simple, stateless interactions where all inputs are known upfrontClaudeSDKClient class for interactive, stateful conversations with full control over message flowKey Components:
Unidirectional query interface for one-shot interactions with Claude Code. Ideal for simple questions, batch processing, code generation, and automated scripts where all inputs are known upfront.
async def query(
*,
prompt: str | AsyncIterable[dict[str, Any]],
options: ClaudeCodeOptions | None = None,
transport: Transport | None = None,
) -> AsyncIterator[Message]:Bidirectional client for interactive, stateful conversations with Claude Code. Provides full control over conversation flow with support for streaming, interrupts, dynamic message sending, custom tools, and hooks.
class ClaudeSDKClient:
def __init__(self, options: ClaudeCodeOptions | None = None): ...
async def connect(self, prompt: str | AsyncIterable[dict[str, Any]] | None = None) -> None: ...
async def receive_messages(self) -> AsyncIterator[Message]: ...
async def query(self, prompt: str | AsyncIterable[dict[str, Any]], session_id: str = "default") -> None: ...
async def interrupt(self) -> None: ...
async def receive_response(self) -> AsyncIterator[Message]: ...
async def disconnect(self) -> None: ...
async def __aenter__(self) -> "ClaudeSDKClient": ...
async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> bool: ...In-process MCP tools that run directly within your Python application. Create custom tools that Claude can invoke, with better performance than external MCP servers, simpler deployment, and direct access to your application's state.
def tool(
name: str,
description: str,
input_schema: type | dict[str, Any]
) -> Callable[[Callable[[Any], Awaitable[dict[str, Any]]]], SdkMcpTool[Any]]: ...
def create_sdk_mcp_server(
name: str,
version: str = "1.0.0",
tools: list[SdkMcpTool[Any]] | None = None
) -> McpSdkServerConfig: ...Comprehensive configuration system for controlling Claude Code behavior including tool permissions, working directory, system prompts, MCP server configurations, and advanced features.
@dataclass
class ClaudeCodeOptions:
allowed_tools: list[str] = field(default_factory=list)
system_prompt: str | None = None
permission_mode: PermissionMode | None = None
cwd: str | Path | None = None
mcp_servers: dict[str, McpServerConfig] | str | Path = field(default_factory=dict)
can_use_tool: CanUseTool | None = None
hooks: dict[HookEvent, list[HookMatcher]] | None = None
# ... additional fieldsPython functions that the Claude Code application invokes at specific points of the Claude agent loop. Hooks provide deterministic processing and automated feedback for Claude, enabling custom validation, permission checks, and automated responses.
@dataclass
class HookMatcher:
matcher: str | None = None
hooks: list[HookCallback] = field(default_factory=list)
HookCallback = Callable[
[dict[str, Any], str | None, HookContext],
Awaitable[HookJSONOutput]
]Rich message system with structured content blocks supporting text, tool usage, tool results, thinking blocks, and streaming events. Includes complete type definitions for all message and content types.
Message = UserMessage | AssistantMessage | SystemMessage | ResultMessage | StreamEvent
ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock
@dataclass
class AssistantMessage:
content: list[ContentBlock]
model: str
parent_tool_use_id: str | None = NoneAbstract transport interface for custom Claude Code communication implementations. Enables custom transport implementations for remote Claude Code connections or alternative communication methods.
class Transport(ABC):
@abstractmethod
async def connect(self) -> None: ...
@abstractmethod
async def write(self, data: str) -> None: ...
@abstractmethod
def read_messages(self) -> AsyncIterator[dict[str, Any]]: ...
# ... additional abstract methodsComprehensive error handling with specific exception types for different failure modes. Includes connection errors, process failures, JSON parsing issues, and message parsing errors.
class ClaudeSDKError(Exception): ...
class CLIConnectionError(ClaudeSDKError): ...
class CLINotFoundError(CLIConnectionError): ...
class ProcessError(ClaudeSDKError): ...
class CLIJSONDecodeError(ClaudeSDKError): ...__version__: str # "0.0.23"