Python SDK for programmatically interacting with Claude Code, enabling AI-powered automation workflows with support for bidirectional conversations, custom in-process tools, hooks, and fine-grained permission control
—
—
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
—
The risk profile of this skill
This plugin was archived by the owner on Jun 3, 2026
Reason: Retiring all tiles created prior to the transition to plugin support
The ClaudeAgentOptions dataclass provides comprehensive configuration for the Claude SDK, covering tools, prompts, permissions, budgets, models, MCP servers, hooks, and more.
Complete configuration for Claude SDK client and query function.
@dataclass
class ClaudeAgentOptions:
"""Configuration options for Claude SDK."""
# Tool configuration
allowed_tools: list[str] = field(default_factory=list)
disallowed_tools: list[str] = field(default_factory=list)
# Prompt configuration
system_prompt: str | SystemPromptPreset | None = None
# MCP server configuration
mcp_servers: dict[str, McpServerConfig] | str | Path = field(default_factory=dict)
# Permission configuration
permission_mode: PermissionMode | None = None
permission_prompt_tool_name: str | None = None
can_use_tool: CanUseTool | None = None
# Session configuration
continue_conversation: bool = False
resume: str | None = None
fork_session: bool = False
# Budget and limits
max_turns: int | None = None
max_budget_usd: float | None = None
max_thinking_tokens: int | None = None
# Model configuration
model: str | None = None
fallback_model: str | None = None
# Working directory and CLI
cwd: str | Path | None = None
cli_path: str | Path | None = None
add_dirs: list[str | Path] = field(default_factory=list)
# Settings and sources
settings: str | None = None
setting_sources: list[SettingSource] | None = None
# Environment
env: dict[str, str] = field(default_factory=dict)
extra_args: dict[str, str | None] = field(default_factory=dict)
# Callbacks
stderr: Callable[[str], None] | None = None
debug_stderr: Any = sys.stderr # Deprecated: Use stderr callback instead
# Hooks and plugins
hooks: dict[HookEvent, list[HookMatcher]] | None = None
agents: dict[str, AgentDefinition] | None = None
plugins: list[SdkPluginConfig] = field(default_factory=list)
# Advanced features
include_partial_messages: bool = False
output_format: dict[str, Any] | None = None
max_buffer_size: int | None = None
user: str | None = NoneControl which tools Claude can use.
Fields:
allowed_tools (list[str]): List of tools Claude is allowed to use. Common tools include:
"Read": Read files"Write": Write new files"Edit": Edit existing files"MultiEdit": Edit multiple files"Bash": Execute shell commands"Glob": Search for files by pattern"Grep": Search file contentsdisallowed_tools (list[str]): List of tools to explicitly disallow. Takes precedence over allowed_tools.
Usage Example:
from claude_agent_sdk import ClaudeAgentOptions
# Allow specific tools
options = ClaudeAgentOptions(
allowed_tools=["Read", "Write", "Bash"]
)
# Allow all except specific tools
options = ClaudeAgentOptions(
disallowed_tools=["Bash"] # Allow everything except shell commands
)
# Combine with custom MCP tools
options = ClaudeAgentOptions(
allowed_tools=["Read", "Write", "calculate", "fetch_data"],
mcp_servers={"my_server": my_mcp_server}
)Configure Claude's system prompt.
Fields:
system_prompt (str | SystemPromptPreset | None): System prompt configuration. Can be:
SystemPromptPreset:
class SystemPromptPreset(TypedDict):
"""System prompt preset configuration."""
type: Literal["preset"]
preset: Literal["claude_code"]
append: NotRequired[str]Usage Example:
from claude_agent_sdk import ClaudeAgentOptions
# Custom system prompt
options = ClaudeAgentOptions(
system_prompt="You are an expert Python developer specializing in async programming."
)
# Use Claude Code preset
options = ClaudeAgentOptions(
system_prompt={"type": "preset", "preset": "claude_code"}
)
# Extend Claude Code preset
options = ClaudeAgentOptions(
system_prompt={
"type": "preset",
"preset": "claude_code",
"append": "Always explain your reasoning step by step."
}
)Configure Model Context Protocol servers for custom tools.
Fields:
mcp_servers (dict[str, McpServerConfig] | str | Path): MCP server configurations. Can be:
Usage Example:
from claude_agent_sdk import ClaudeAgentOptions, create_sdk_mcp_server, tool
# In-process SDK server
@tool("calculate", "Perform calculation", {"expression": str})
async def calculate(args):
result = eval(args["expression"])
return {"content": [{"type": "text", "text": str(result)}]}
calc_server = create_sdk_mcp_server("calculator", tools=[calculate])
options = ClaudeAgentOptions(
mcp_servers={"calc": calc_server},
allowed_tools=["calculate"]
)
# Subprocess stdio server
options = ClaudeAgentOptions(
mcp_servers={
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
}
)
# Multiple servers
options = ClaudeAgentOptions(
mcp_servers={
"calc": calc_server,
"web": {
"type": "sse",
"url": "http://localhost:3000/sse"
}
}
)Control tool execution permissions.
Fields:
permission_mode (PermissionMode | None): Permission mode. Options:
"default": CLI prompts for dangerous tools"acceptEdits": Auto-accept file edits"plan": Plan mode, no execution"bypassPermissions": Allow all tools (use with caution)permission_prompt_tool_name (str | None): Tool name for custom permission prompts. Set to "stdio" for programmatic control.
can_use_tool (CanUseTool | None): Callback function for programmatic permission control. See Permission Control for details.
Usage Example:
from claude_agent_sdk import ClaudeAgentOptions
# Auto-accept file edits
options = ClaudeAgentOptions(
permission_mode="acceptEdits",
allowed_tools=["Read", "Write", "Edit"]
)
# Plan mode (no execution)
options = ClaudeAgentOptions(
permission_mode="plan",
allowed_tools=["Read", "Write", "Bash"]
)
# Programmatic control
async def my_permission_handler(tool_name, tool_input, context):
if tool_name == "Bash":
# Review bash commands
if "rm -rf" in tool_input.get("command", ""):
return PermissionResultDeny(message="Dangerous command blocked")
return PermissionResultAllow()
options = ClaudeAgentOptions(
can_use_tool=my_permission_handler,
allowed_tools=["Read", "Write", "Bash"]
)Control conversation session behavior.
Fields:
continue_conversation (bool): Continue previous conversation in current directory. Default: False.
resume (str | None): Resume specific session by ID.
fork_session (bool): Fork resumed session to new ID instead of continuing. Default: False.
Usage Example:
from claude_agent_sdk import ClaudeAgentOptions
# Continue last conversation
options = ClaudeAgentOptions(
continue_conversation=True,
cwd="/path/to/project"
)
# Resume specific session
options = ClaudeAgentOptions(
resume="session-id-123"
)
# Fork from existing session
options = ClaudeAgentOptions(
resume="session-id-123",
fork_session=True
)Set spending and token limits.
Fields:
max_turns (int | None): Maximum conversation turns before stopping.
max_budget_usd (float | None): Maximum spending limit in USD.
max_thinking_tokens (int | None): Maximum tokens for extended thinking blocks.
Usage Example:
from claude_agent_sdk import ClaudeAgentOptions
# Limit turns
options = ClaudeAgentOptions(
max_turns=10
)
# Limit spending
options = ClaudeAgentOptions(
max_budget_usd=1.00
)
# Limit thinking tokens
options = ClaudeAgentOptions(
max_thinking_tokens=5000
)
# Combined limits
options = ClaudeAgentOptions(
max_turns=20,
max_budget_usd=5.00,
max_thinking_tokens=10000
)Configure AI models.
Fields:
model (str | None): AI model to use. Examples:
"claude-sonnet-4-5-20250929""claude-opus-4-1-20250805""claude-haiku-4-20250514"fallback_model (str | None): Fallback model if primary fails.
Usage Example:
from claude_agent_sdk import ClaudeAgentOptions
# Specific model
options = ClaudeAgentOptions(
model="claude-sonnet-4-5-20250929"
)
# With fallback
options = ClaudeAgentOptions(
model="claude-opus-4-1-20250805",
fallback_model="claude-sonnet-4-5-20250929"
)Configure working directory and CLI path.
Fields:
cwd (str | Path | None): Working directory for tool execution.
cli_path (str | Path | None): Path to Claude Code CLI executable. If None, uses bundled CLI.
add_dirs (list[str | Path]): Additional directories to add to permissions.
Usage Example:
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions
# Set working directory
options = ClaudeAgentOptions(
cwd="/path/to/project"
)
# Use custom CLI
options = ClaudeAgentOptions(
cli_path="/usr/local/bin/claude"
)
# Add permission directories
options = ClaudeAgentOptions(
cwd="/path/to/project",
add_dirs=[
"/path/to/project/src",
"/path/to/project/tests"
]
)Configure settings sources.
Fields:
settings (str | None): Settings string.
setting_sources (list[SettingSource] | None): Setting sources to load. Options:
"user": User-level settings"project": Project-level settings"local": Local directory settingsUsage Example:
from claude_agent_sdk import ClaudeAgentOptions
# Specific setting sources
options = ClaudeAgentOptions(
setting_sources=["project", "local"]
)
# Custom settings
options = ClaudeAgentOptions(
settings='{"theme": "dark", "verbose": true}'
)Configure environment variables and extra arguments.
Fields:
env (dict[str, str]): Environment variables for CLI process.
extra_args (dict[str, str | None]): Extra CLI arguments. Maps flag names to values.
Usage Example:
from claude_agent_sdk import ClaudeAgentOptions
# Set environment variables
options = ClaudeAgentOptions(
env={
"ANTHROPIC_API_KEY": "sk-...",
"DEBUG": "true"
}
)
# Pass extra CLI flags
options = ClaudeAgentOptions(
extra_args={
"--verbose": None, # Boolean flag
"--log-level": "debug" # Flag with value
}
)Configure callback functions.
Fields:
stderr (Callable[[str], None] | None): Callback for stderr output from CLI. Receives each stderr line as it's produced.
debug_stderr (Any): Deprecated. File-like object for debug output. Use stderr callback instead. Default: sys.stderr.
Usage Example:
from claude_agent_sdk import ClaudeAgentOptions
def handle_stderr(line: str):
print(f"CLI stderr: {line}")
options = ClaudeAgentOptions(
stderr=handle_stderr
)Note: The debug_stderr field is deprecated and maintained only for backwards compatibility. Use the stderr callback for all new code.
Configure hooks and plugins.
Fields:
hooks (dict[HookEvent, list[HookMatcher]] | None): Hook configurations. See Hook System for details.
agents (dict[str, AgentDefinition] | None): Custom agent definitions. See Agent Definitions for details.
plugins (list[SdkPluginConfig]): Plugin configurations. See Plugin Support for details.
Usage Example:
from claude_agent_sdk import ClaudeAgentOptions, HookMatcher
async def pre_bash_hook(input, tool_use_id, context):
# Validate bash commands
if "rm -rf" in input["tool_input"]["command"]:
return {"decision": "block", "reason": "Dangerous command"}
return {}
options = ClaudeAgentOptions(
hooks={
"PreToolUse": [
HookMatcher(matcher="Bash", hooks=[pre_bash_hook])
]
}
)Advanced configuration options.
Fields:
include_partial_messages (bool): Include partial streaming messages (StreamEvent). Default: False.
output_format (dict[str, Any] | None): Structured output schema. Follows Anthropic Messages API format.
max_buffer_size (int | None): Maximum bytes when buffering CLI stdout.
user (str | None): User identifier.
Usage Example:
from claude_agent_sdk import ClaudeAgentOptions
# Enable partial messages
options = ClaudeAgentOptions(
include_partial_messages=True
)
# Structured output
options = ClaudeAgentOptions(
output_format={
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"answer": {"type": "number"},
"explanation": {"type": "string"}
},
"required": ["answer"]
}
}
)
# Set buffer size
options = ClaudeAgentOptions(
max_buffer_size=1024 * 1024 # 1MB
)
# Set user identifier
options = ClaudeAgentOptions(
user="user-123"
)from claude_agent_sdk import (
ClaudeAgentOptions, create_sdk_mcp_server, tool,
HookMatcher, AgentDefinition
)
# Define custom tool
@tool("search_docs", "Search documentation", {"query": str})
async def search_docs(args):
# Implementation
return {"content": [{"type": "text", "text": "Found..."}]}
# Create MCP server
docs_server = create_sdk_mcp_server("docs", tools=[search_docs])
# Define hook
async def validate_writes(input, tool_use_id, context):
if input["tool_name"] in ["Write", "Edit"]:
# Validate file operations
pass
return {}
# Complete configuration
options = ClaudeAgentOptions(
# Tools
allowed_tools=["Read", "Write", "Edit", "search_docs"],
disallowed_tools=["Bash"],
# Prompt
system_prompt="You are an expert technical writer.",
# MCP servers
mcp_servers={"docs": docs_server},
# Permissions
permission_mode="acceptEdits",
# Limits
max_turns=50,
max_budget_usd=10.00,
max_thinking_tokens=20000,
# Model
model="claude-sonnet-4-5-20250929",
fallback_model="claude-opus-4-1-20250805",
# Working directory
cwd="/path/to/project",
add_dirs=["/path/to/project/docs"],
# Hooks
hooks={
"PreToolUse": [
HookMatcher(matcher="Write|Edit", hooks=[validate_writes])
]
},
# Agents
agents={
"reviewer": AgentDefinition(
description="Code reviewer",
prompt="Review code for quality",
tools=["Read", "Grep"],
model="sonnet"
)
},
# Environment
env={"LOG_LEVEL": "debug"},
# Callbacks
stderr=lambda line: print(f"[CLI] {line}"),
# Advanced
include_partial_messages=False,
user="developer-123"
)The SDK validates configuration at runtime:
can_use_tool requires streaming mode (ClaudeSDKClient or AsyncIterable prompt)can_use_tool and permission_prompt_tool_name are mutually exclusiveValidation errors raise ValueError with descriptive messages.
docs