Skip to main content

Installation

Install the package into a virtual environment. On recent Debian, Ubuntu, and Homebrew Python installs, running pip install against system Python fails with error: externally-managed-environment.
For uv, Windows PowerShell, and API key setup, see Setup in the Agent SDK quickstart.

Choosing between query() and ClaudeSDKClient

The Python SDK provides two ways to interact with Claude Code: Use ClaudeSDKClient for interactive applications such as chat interfaces, or when the next action depends on Claude’s response.

Functions

Signature blocks and bare async for / async with fragments on this page are illustrative. To run them, wrap the body in async def main(): ... and call asyncio.run(main()).

query()

Creates a new session for each interaction with Claude Code by default. Returns an async iterator that yields messages as they arrive. Each call to query() starts fresh with no memory of previous interactions unless you pass continue_conversation=True or resume in ClaudeAgentOptions. See Sessions.

Parameters

Returns

Returns an AsyncIterator[Message] that yields messages from the conversation.

Example - With options

tool()

Decorator for defining MCP tools with type safety.

Parameters

Input schema options

  1. Simple type mapping (recommended):
  2. JSON Schema format (for complex validation):

Returns

A decorator function that wraps the tool implementation and returns an SdkMcpTool instance.

Example

ToolAnnotations

Behavioral hints for a tool, passed as the annotations argument of tool(). ToolAnnotations extends the MCP SDK’s mcp.types.ToolAnnotations with a maxResultSizeChars field, and you can write each hint in camelCase or snake_case: ToolAnnotations(readOnlyHint=True) and ToolAnnotations(read_only_hint=True) are equivalent. You can also pass a plain mcp.types.ToolAnnotations wherever the SDK accepts annotations. The snake_case names and the typed maxResultSizeChars field require Python Agent SDK 0.2.140 or later. Versions 0.1.31 through 0.2.139 re-export mcp.types.ToolAnnotations unchanged. On versions 0.1.55 through 0.2.139 you can still pass maxResultSizeChars as a keyword argument: the MCP class accepts extra fields, and the SDK forwards the value to Claude Code. All fields are optional. Clients shouldn’t rely on the hints for security decisions.

create_sdk_mcp_server()

Create an in-process MCP server that runs within your Python application.

Parameters

Returns

Returns an McpSdkServerConfig object that can be passed to ClaudeAgentOptions.mcp_servers.

Example

list_sessions()

Lists past sessions with metadata. Filter by project directory or list sessions across all projects. Synchronous; returns immediately.

Parameters

Return type: SDKSessionInfo

Example

Print the 10 most recent sessions for a project. Results are sorted by last_modified descending, so the first item is the newest. Omit directory to search across all projects.

get_session_messages()

Retrieves messages from a past session. Synchronous; returns immediately.

Parameters

Return type: SessionMessage

Example

get_session_info()

Reads metadata for a single session by ID without scanning the full project directory. Synchronous; returns immediately.

Parameters

Returns SDKSessionInfo, or None if the session is not found.

Example

Look up a single session’s metadata without scanning the project directory. Useful when you already have a session ID from a previous run.

rename_session()

Renames a session by appending a custom-title entry. Repeated calls are safe; the most recent title wins. Synchronous.

Parameters

Raises ValueError if session_id is not a valid UUID or title is empty; FileNotFoundError if the session cannot be found.

Example

Rename the most recent session so it’s easier to find later. The new title appears in SDKSessionInfo.custom_title on subsequent reads.

tag_session()

Tags a session. Pass None to clear the tag. Repeated calls are safe; the most recent tag wins. Synchronous.

Parameters

Raises ValueError if session_id is not a valid UUID or tag is empty after sanitization; FileNotFoundError if the session cannot be found.

Example

Tag a session, then filter by that tag on a later read. Pass None to clear an existing tag.

Classes

ClaudeSDKClient

Maintains a conversation session across multiple exchanges. This is the Python equivalent of how the TypeScript SDK’s query() function works internally - it creates a client object that can continue conversations. See the comparison with query().

Methods

Context Manager Support

The client can be used as an async context manager for automatic connection management:
Important: When iterating over messages, avoid using break to exit early as this can cause asyncio cleanup issues. Instead, let the iteration complete naturally or use flags to track when you’ve found what you need.

Example - Continuing a conversation

Example - Streaming input with ClaudeSDKClient

Example - Using interrupts

Buffer behavior after interrupt: interrupt() sends a stop signal but does not clear the message buffer. Messages already produced by the interrupted task, including its ResultMessage, remain in the stream. You must drain them with receive_response() before reading the response to a new query. If you send a new query immediately after interrupt() and call receive_response() only once, you’ll receive the interrupted task’s messages, not the new query’s response.

Example - Advanced permission control

Types

@dataclass vs TypedDict: This SDK uses two kinds of types. Classes decorated with @dataclass (such as ResultMessage, AgentDefinition, TextBlock) are object instances at runtime and support attribute access: msg.result. Classes defined with TypedDict (such as ThinkingConfigEnabled, McpStdioServerConfig, SyncHookJSONOutput) are plain dicts at runtime and require key access: config["budget_tokens"], not config.budget_tokens. The ClassName(field=value) call syntax works for both, but only dataclasses produce objects with attributes.

SdkMcpTool

Definition for an SDK MCP tool created with the @tool decorator.

Transport

Abstract base class for custom transport implementations. Use this to communicate with the Claude process over a custom channel (for example, a remote connection instead of a local subprocess).
This is a low-level internal API. The interface may change in future releases. Custom implementations must be updated to match any interface changes.
Import: from claude_agent_sdk import Transport

ClaudeAgentOptions

Configuration dataclass for Claude Code queries.

Handle slow or stalled API responses

The CLI subprocess reads several environment variables that control API timeouts and stall detection. Pass them through ClaudeAgentOptions.env:
  • API_TIMEOUT_MS: per-request timeout on the Anthropic client, in milliseconds. Default 600000. Applies to the main loop and all subagents.
  • CLAUDE_CODE_MAX_RETRIES: maximum API retries. Default 10, capped at 15. Each retry gets its own API_TIMEOUT_MS window, so worst-case wall time is roughly API_TIMEOUT_MS × (CLAUDE_CODE_MAX_RETRIES + 1) plus backoff. For unattended runs that need to wait through longer outages, set CLAUDE_CODE_RETRY_WATCHDOG=1: it retries transient capacity errors indefinitely and, on Claude Code v2.1.199 or later, raises the default for other transient errors to 300 and removes the cap on this variable.
  • CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS: stall watchdog for subagents. While the stream watchdog is on, the default is CLAUDE_STREAM_IDLE_TIMEOUT_MS plus 5 minutes, which comes to 600000 unless you raise that variable. With the stream watchdog off, the default is 600000. Before v2.1.257, the default was always 600000. The timer resets on each stream event. On a stall, Claude Code aborts the subagent and reports the stall to the parent. For a background subagent, it also marks the task failed and attaches any partial result.
  • CLAUDE_ENABLE_STREAM_WATCHDOG with CLAUDE_STREAM_IDLE_TIMEOUT_MS: stream watchdog that aborts the request when headers have arrived but the response body stops streaming. The watchdog is on by default for all providers; set CLAUDE_ENABLE_STREAM_WATCHDOG=0 to disable it. CLAUDE_STREAM_IDLE_TIMEOUT_MS defaults to 300000 and is clamped to that minimum. After the abort, Automatic retries covers what Claude Code does, based on how far the response had progressed. While the watchdog waits out a response that a gateway behind ANTHROPIC_BASE_URL holds open with keep-alive pings, a host that sets include_partial_messages keeps receiving ping StreamEvent messages. Read those frames as liveness rather than timing the session out on silence. Before v2.1.257, the frames stopped 5 minutes after the last real stream event.

OutputFormat

Configuration for structured output validation. Pass this as a dict to the output_format field on ClaudeAgentOptions:

SystemPromptPreset

Configuration for using Claude Code’s preset system prompt with optional additions.

SystemPromptFile

Configuration for loading a custom system prompt from a file instead of passing it as a string. The SDK maps this to the CLI --system-prompt-file flag. Use the file form when the prompt is large: the SDK passes a string system_prompt on the CLI subprocess argv, which is subject to OS command-line length limits before the SDK sends any API request. On Linux a single argument longer than roughly 128 KB fails at process spawn with Argument list too long. On Windows the whole command line is capped at roughly 32 KB, so the string form fails at a lower threshold.

SettingSource

Controls which filesystem-based configuration sources the SDK loads settings from.

Default behavior

When setting_sources is omitted or None, query() loads the same filesystem settings as the Claude Code CLI: user, project, and local. Endpoint-managed policy is loaded in all cases; server-managed settings are fetched when the session authenticates with an organization credential on an eligible configuration. See What settingSources does not control for inputs that are read regardless of this option, and how to disable them.

Why use setting_sources

Disable filesystem settings:
In Python SDK 0.1.59 and earlier, an empty list was treated the same as omitting the option, so setting_sources=[] did not disable filesystem settings. Upgrade to a newer release if you need an empty list to take effect. The TypeScript SDK is not affected.
Load only specific setting sources:
SDK-only applications:
To load CLAUDE.md project instructions, include "project" in setting_sources. See Modify system prompts for how CLAUDE.md loading interacts with the system prompt options.

Settings precedence

When multiple sources are loaded, settings are merged with this precedence (highest to lowest):
  1. Local settings (.claude/settings.local.json)
  2. Project settings (.claude/settings.json)
  3. User settings (~/.claude/settings.json)
Programmatic options such as agents and allowed_tools override user, project, and local filesystem settings. Managed policy settings take precedence over programmatic options.

AgentDefinition

Configuration for a subagent defined programmatically.
AgentDefinition field names use camelCase, such as disallowedTools, permissionMode, and maxTurns. These names map directly to the wire format shared with the TypeScript SDK. This differs from ClaudeAgentOptions, which uses Python snake_case for the equivalent top-level fields such as disallowed_tools and permission_mode. Because AgentDefinition is a dataclass, passing a snake_case keyword raises a TypeError at construction time.

PermissionMode

Permission modes for controlling tool execution.

EffortLevel

Effort levels for guiding thinking depth.

CanUseTool

Type alias for tool permission callback functions.
The callback receives:
  • tool_name: Name of the tool being called
  • input_data: The tool’s input parameters
  • context: A ToolPermissionContext with additional information
Returns a PermissionResult (either PermissionResultAllow or PermissionResultDeny). The callback is the SDK replacement for the interactive permission prompt: it’s invoked only when the permission evaluation flow resolves to a prompt. Tool calls already approved by an allowed_tools entry, a settings allow rule, or the permission mode, such as acceptEdits or bypassPermissions, never invoke it. To gate every tool call, use a PreToolUse hook instead. An allow rule doesn’t pre-approve the actions no mode auto-approves; see How permissions are evaluated for which of them reach the callback and what happens in dontAsk and auto mode.

ToolPermissionContext

Context information passed to tool permission callbacks.

PermissionResult

Union type for permission callback results.

PermissionResultAllow

Result indicating the tool call should be allowed.

PermissionResultDeny

Result indicating the tool call should be denied.

PermissionUpdate

Configuration for updating permissions programmatically.

PermissionRuleValue

A rule to add, replace, or remove in a permission update.

ToolsPreset

Preset tools configuration for using Claude Code’s default tool set.

ThinkingConfig

Controls extended thinking behavior. A union of three configurations: