All skills
Skillintermediate

Agent SDK reference - Python

> ## Documentation Index > Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt > Use this file to discover all available pages before exploring further.

Claude Code Knowledge Pack7/10/2026

Overview

Documentation Index

Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt Use this file to discover all available pages before exploring further.

Agent SDK reference - Python

Complete API reference for the Python Agent SDK, including all functions, types, and classes.

Installation

pip install claude-agent-sdk

Choosing between query() and ClaudeSDKClient

The Python SDK provides two ways to interact with Claude Code:

Quick comparison

Featurequery()ClaudeSDKClient
SessionCreates new session each timeReuses same session
ConversationSingle exchangeMultiple exchanges in same context
ConnectionManaged automaticallyManual control
Streaming Input✅ Supported✅ Supported
Interrupts❌ Not supported✅ Supported
Hooks✅ Supported✅ Supported
Custom Tools✅ Supported✅ Supported
Continue Chat❌ New session each time✅ Maintains conversation
Use CaseOne-off tasksContinuous conversations

When to use query() (new session each time)

Best for:

  • One-off questions where you don't need conversation history
  • Independent tasks that don't require context from previous exchanges
  • Simple automation scripts
  • When you want a fresh start each time

When to use ClaudeSDKClient (continuous conversation)

Best for:

  • Continuing conversations - When you need Claude to remember context
  • Follow-up questions - Building on previous responses
  • Interactive applications - Chat interfaces, REPLs
  • Response-driven logic - When next action depends on Claude's response
  • Session control - Managing conversation lifecycle explicitly

Functions

query()

Creates a new session for each interaction with Claude Code. Returns an async iterator that yields messages as they arrive. Each call to query() starts fresh with no memory of previous interactions.

async def query(
    *,
    prompt: str | AsyncIterable[dict[str, Any]],
    options: ClaudeAgentOptions | None = None,
    transport: Transport | None = None
) -> AsyncIterator[Message]

Parameters

ParameterTypeDescription
prompt`str \AsyncIterable[dict]`
options`ClaudeAgentOptions \None`
transport`Transport \None`

Returns

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

Example - With options


from claude_agent_sdk import query, ClaudeAgentOptions

async def main():
    options = ClaudeAgentOptions(
        system_prompt="You are an expert Python developer",
        permission_mode="acceptEdits",
        cwd="/home/user/project",
    )

    async for message in query(prompt="Create a Python web server", options=options):
        print(message)

asyncio.run(main())

tool()

Decorator for defining MCP tools with type safety.

def tool(
    name: str,
    description: str,
    input_schema: type | dict[str, Any],
    annotations: ToolAnnotations | None = None
) -> Callable[[Callable[[Any], Awaitable[dict[str, Any]]]], SdkMcpTool[Any]]

Parameters

ParameterTypeDescription
namestrUnique identifier for the tool
descriptionstrHuman-readable description of what the tool does
input_schema`type \dict[str, Any]`
annotationsToolAnnotations` \None`

Input schema options

  1. Simple type mapping (recommended):

    {"text": str, "count": int, "enabled": bool}
    
  2. JSON Schema format (for complex validation):

    {
        "type": "object",
        "properties": {
            "text": {"type": "string"},
            "count": {"type": "integer", "minimum": 0},
        },
        "required": ["text"],
    }
    

Returns

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

Example

from claude_agent_sdk import tool
from typing import Any

@tool("greet", "Greet a user", {"name": str})
async def greet(args: dict[str, Any]) -> dict[str, Any]:
    return {"content": [{"type": "text", "text": f"Hello, {args['name']}!"}]}

ToolAnnotations

Re-exported from mcp.types (also available as from claude_agent_sdk import ToolAnnotations). All fields are optional hints; clients should not rely on them for security decisions.

FieldTypeDefaultDescription
title`str \None`None
readOnlyHint`bool \None`False
destructiveHint`bool \None`True
idempotentHint`bool \None`False
openWorldHint`bool \None`True
from claude_agent_sdk import tool, ToolAnnotations
from typing import Any

@tool(
    "search",
    "Search the web",
    {"query": str},
    annotations=ToolAnnotations(readOnlyHint=True, openWorldHint=True),
)
async def search(args: dict[str, Any]) -> dict[str, Any]:
    return {"content": [{"type": "text", "text": f"Results for: {args['query']}"}]}

create_sdk_mcp_server()

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

def create_sdk_mcp_server(
    name: str,
    version: str = "1.0.0",
    tools: list[SdkMcpTool[Any]] | None = None
) -> McpSdkServerConfig

Parameters

ParameterTypeDefaultDescription
namestr-Unique identifier for the server
versionstr"1.0.0"Server version string
tools`list[SdkMcpTool[Any]] \None`None

Returns

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

Example

from claude_agent_sdk import tool, create_sdk_mcp_server

@tool("add", "Add two numbers", {"a": float, "b": float})
async def add(args):
    return {"content": [{"type": "text", "text": f"Sum: {args['a'] + args['b']}"}]}

@tool("multiply", "Multiply two numbers", {"a": float, "b": float})
async def multiply(args):
    return {"content": [{"type": "text", "text": f"Product: {args['a'] * args['b']}"}]}

calculator = create_sdk_mcp_server(
    name="calculator",
    version="2.0.0",
    tools=[add, multiply],  # Pass decorated functions
)

# Use with Claude
options = ClaudeAgentOptions(
    mcp_servers={"calc": calculator},
    allowed_tools=["mcp__calc__add", "mcp__calc__multiply"],
)

list_sessions()

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

def list_sessions(
    directory: str | None = None,
    limit: int | None = None,
    include_worktrees: bool = True
) -> list[SDKSessionInfo]

Parameters

ParameterTypeDefaultDescription
directory`str \None`None
limit`int \None`None
include_worktreesboolTrueWhen directory is inside a git repository, include sessions from all worktree paths

Return type: SDKSessionInfo

PropertyTypeDescription
session_idstrUnique session identifier
summarystrDisplay title: custom title, auto-generated summary, or first prompt
last_modifiedintLast modified time in milliseconds since epoch
file_size`int \None`
custom_title`str \None`
first_prompt`str \None`
git_branch`str \None`
cwd`str \None`
tag`str \None`
created_at`int \None`

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.

from claude_agent_sdk import list_sessions

for session in list_sessions(directory="/path/to/project", limit=10):
    print(f"{session.summary} ({session.session_id})")

get_session_messages()

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

def get_session_messages(
    session_id: str,
    directory: str | None = None,
    limit: int | None = None,
    offset: int = 0
) -> list[SessionMessage]

Parameters

ParameterTypeDefaultDescription
session_idstrrequiredThe session ID to retrieve messages for
directory`str \None`None
limit`int \None`None
offsetint0Number of messages to skip from the start

Return type: SessionMessage

PropertyTypeDescription
typeLiteral["user", "assistant"]Message role
uuidstrUnique message identifier
session_idstrSession identifier
messageAnyRaw message content
parent_tool_use_idNoneReserved for future use

Example

from claude_agent_sdk import list_sessions, get_session_messages

sessions = list_sessions(limit=1)
if sessions:
    messages = get_session_messages(sessions[0].session_id)
    for msg in messages:
        print(f"[{msg.type}] {msg.uuid}")

get_session_info()

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

def get_session_info(
    session_id: str,
    directory: str | None = None,
) -> SDKSessionInfo | None

Parameters

ParameterTypeDefaultDescription
session_idstrrequiredUUID of the session to look up
directory`str \None`None

Returns [SDKSessionInfo](#r