Claude Agent SDK
Programmatic agent construction with Python and TypeScript. Build autonomous workflows, CI/CD integrations, scheduled tasks, and custom toolchains using the official SDK.
What is Claude Agent SDK?
The Claude Agent SDK is Anthropic’s official framework for building AI agents with Claude that you can use programmatically (in Python or Node.js/TypeScript). Think of it as the “programmable version” of Claude Code.
Key Purpose
Instead of typing commands into Claude Code’s CLI, you write code that:
- Creates agents that run autonomously
- Gives them specific tools and constraints
- Handles their responses programmatically
- Integrates with your applications
Core Analogy
- Claude Code CLI — Interactive tool you run in your terminal (human-driven)
- Agent SDK — Framework you import into your code (automation-driven)
Both use the same underlying Claude Code runtime and tools, but the SDK lets you integrate agents into applications, CI/CD pipelines, scheduled jobs, and custom workflows.
If you’ve been using Claude Code CLI for months, you already understand the concepts. The SDK just lets you automate them programmatically instead of typing interactively.
How Does It Relate to Claude Code CLI?
The Relationship
graph TB A[Claude API] B[Agent SDK] C[Claude Code CLI] A --> B B --> C style A fill:#FAF9F6,stroke:#F55036,stroke-width:2px,color:#2D2926 style B fill:#FAF9F6,stroke:#F55036,stroke-width:2px,color:#2D2926 style C fill:#FAF9F6,stroke:#F55036,stroke-width:2px,color:#2D2926
The Agent SDK:
- Requires Claude Code CLI to be installed (acts as the runtime)
- Builds on top of the Claude API for model interactions
- Provides a higher-level abstraction than raw API calls (like Express vs raw Node HTTP)
- Handles tool orchestration (Read, Write, Bash, WebSearch, etc.) automatically
Can You Use Both Together?
Yes, absolutely. They’re complementary:
- Use Claude Code CLI for interactive development and debugging
- Use Agent SDK for automation, integrations, and programmatic workflows
sequenceDiagram actor Dev as Developer participant CLI as Claude Code CLI participant SDK as Agent SDK participant Prod as CI/CD and Scheduled Jobs Dev->>CLI: Test agent manually CLI->>Dev: Show results Dev->>SDK: Convert to SDK SDK->>SDK: Write Python/TypeScript SDK->>Prod: Deploy Prod->>Prod: Run autonomously
Use this workflow: Develop with CLI → Test behavior → Convert to SDK → Deploy to production
What Can You Build With Agent SDK?
Real-World Use Cases
| Use Case | Example | Why Agent SDK |
|---|---|---|
| Code Analysis Agents | Find bugs, refactor, add tests | Runs autonomously on repos |
| CI/CD Integration | Run PR reviews, tests, linting | Automated, no user interaction |
| Email Assistants | Process emails, draft responses | Continuous background operation |
| Research Agents | Gather info, summarize findings | Multi-step autonomous tasks |
| Document Generation | Create reports, specs, docs | Driven by external data |
| Scheduled Tasks | Nightly data processing | Cron-compatible, headless |
| Chat Interfaces | Build conversational apps | Multi-turn with state |
| Slack/Discord Bots | Slack commands, interactions | Event-driven automation |
| Web Dashboard | Backend agent for web apps | REST API wrapper around agents |
Key Capabilities
The SDK supports:
- Tool use: Read files, write code, run bash, search web, fetch URLs, edit notebooks
- Sessions: Multi-turn conversations with context retention
- Permissions: Fine-grained control over what agents can do
- Hooks: Intercept and modify behavior at key points
- MCP servers: Connect to external APIs, databases, services
- Subagents: Delegate tasks to specialized agents
- Structured outputs: Get predictable JSON results
- Extended thinking: Complex reasoning tasks
- Streaming: Real-time output delivery
The SDK doesn’t limit you to what Claude Code CLI can do—it extends those capabilities into your applications.
How Do You Use It? (Basic Workflow)
Installation
uv init && uv add claude-agent-sdk
# or: pip install claude-agent-sdk npm install @anthropic-ai/claude-agent-sdk Step 1: Install Claude Code
The SDK needs Claude Code installed:
brew install --cask claude-code
# or: npm install -g @anthropic-ai/claude-code
claude # authenticate
Step 2: Create Your First Agent
Hello World Agent - Create a simple agent that autonomously creates a Python file.
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
options = ClaudeAgentOptions(
allowed_tools=["Read", "Write", "Bash"],
permission_mode="acceptEdits" # Auto-approve file changes
)
async for message in query(
prompt="Create a Python file that prints hello world",
options=options
):
# Process each message as it arrives
if hasattr(message, 'content'):
print(f"Response: {message}")
asyncio.run(main()) import { query } from "@anthropic-ai/claude-agent-sdk";
async function main() {
const options = {
allowedTools: ["Read", "Write", "Bash"],
permissionMode: "acceptEdits"
};
for await (const message of query({
prompt: "Create a Python file that prints hello world",
options
})) {
if (message.type === "assistant") {
console.log("Response:", message);
}
}
}
main(); Step 3: Run It
# Python
python3 agent.py
# TypeScript
npx tsx agent.ts
That’s it! Claude will autonomously:
- Create the Python file
- Show you what it did
- Report results
Start with permission_mode="acceptEdits" for autonomous agents. Use "default" for approval-based workflow.
Key APIs and Methods
Two Main Approaches
| Feature | query() | ClaudeSDKClient |
|---|---|---|
| Use Case | One-off tasks | Continuous conversations |
| Session | Fresh each time | Maintains context |
| Interrupts | No | Yes |
| Hooks | No | Yes |
| Best For | Automation scripts, CI/CD | Chat apps, interactive tools |
query() - One-Shot Execution
Use query() for fire-and-forget tasks that don’t need ongoing context:
async for message in query(
prompt="Your task here",
options=ClaudeAgentOptions(...)
):
# Process message
pass
ClaudeSDKClient - Continuous Conversation
Use ClaudeSDKClient for multi-turn conversations where Claude remembers previous context:
async with ClaudeSDKClient(options) as client:
# Ask a question
await client.query("What's the capital of France?")
# Get response
async for message in client.receive_response():
pass
# Ask follow-up (Claude remembers context!)
await client.query("What's its population?")
async for message in client.receive_response():
pass
Core Options (ClaudeAgentOptions)
ClaudeAgentOptions(
allowed_tools=["Read", "Write", "Bash", "WebSearch"], # What agent can use
permission_mode="acceptEdits", # "default", "acceptEdits", "bypassPermissions", "plan"
system_prompt="You are a senior engineer", # Custom instructions
mcp_servers={...}, # Connect to external tools
max_turns=10, # Stop after N interactions
cwd="/path/to/project", # Working directory
env={"NODE_ENV": "production"}, # Environment variables
can_use_tool=custom_permission_handler, # Custom permission logic
)
Tools Available
Built-in tools agents can use (if allowed):
- Read: Read files (text, images, PDFs, notebooks)
- Write: Create files
- Edit: Modify files (find-replace)
- Bash: Run shell commands
- Glob: Find files with patterns
- Grep: Search file contents (regex)
- WebFetch: Fetch and analyze URLs
- WebSearch: Search the web
- NotebookEdit: Edit Jupyter notebooks
- Task: Delegate to subagents
- MCP tools: Custom tools from MCP servers
Code Examples (Python & Node.js)
Example 1: Code Review Agent
A read-only agent that reviews code for bugs, performance, and security issues.
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage
async def review_code():
options = ClaudeAgentOptions(
allowed_tools=["Read", "Grep"], # Read-only for safety
system_prompt="You are a senior code reviewer. Focus on: bugs, performance, security."
)
async for message in query(
prompt="Review all .py files in src/ directory. Look for bugs and security issues.",
options=options,
cwd="/path/to/project"
):
if isinstance(message, AssistantMessage):
for block in message.content:
if hasattr(block, 'text'):
print(block.text)
asyncio.run(review_code()) import { query } from "@anthropic-ai/claude-agent-sdk";
async function reviewCode() {
const options = {
allowedTools: ["Read", "Grep"],
systemPrompt: "You are a senior code reviewer. Focus on: bugs, performance, security.",
cwd: "/path/to/project"
};
for await (const message of query({
prompt: "Review all .py files in src/ directory. Look for bugs and security issues.",
options
})) {
if (message.type === "assistant" && message.message?.content) {
for (const block of message.message.content) {
if ("text" in block) {
console.log(block.text);
}
}
}
}
}
reviewCode(); Example 2: Interactive Chat Agent
A multi-turn agent that remembers conversation context across turns.
import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, AssistantMessage, TextBlock
async def interactive_chat():
options = ClaudeAgentOptions(
allowed_tools=["Read", "Write", "Bash"],
permission_mode="acceptEdits"
)
async with ClaudeSDKClient(options=options) as client:
print("Chat started. Type 'exit' to quit.\n")
turn = 1
while True:
user_input = input(f"[Turn {turn}] You: ")
if user_input.lower() == "exit":
break
# Send message
await client.query(user_input)
turn += 1
# Get response (Claude remembers previous messages!)
print(f"[Turn {turn}] Claude: ", end="", flush=True)
async for message in client.receive_response():
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(block.text, end="", flush=True)
print("\n")
turn += 1
asyncio.run(interactive_chat()) import { query } from "@anthropic-ai/claude-agent-sdk";
import * as readline from "readline";
async function interactiveChat() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const askUser = (prompt: string) => {
return new Promise<string>(resolve => {
rl.question(prompt, resolve);
});
};
let turn = 1;
let g = query({
prompt: "Hello! Start a conversation. You'll remember context across turns.",
options: {
allowedTools: ["Read", "Write", "Bash"],
permissionMode: "acceptEdits"
}
});
// Continue conversation
for await (const message of g) {
if (message.type === "result") {
const nextInput = await askUser(`\n[Turn ${turn + 1}] You: `);
if (nextInput === "exit") {
rl.close();
break;
}
// Start next query in same session
g = query({
prompt: nextInput,
options: {
continue: true // Continue previous conversation
}
});
turn += 2;
}
}
}
interactiveChat(); When to Use Agent SDK vs Claude Code CLI
Quick Comparison
| Scenario | Use | Why |
|---|---|---|
| Interactive terminal development | Claude Code CLI | Real-time feedback, manual testing |
| Python/Node application integration | Agent SDK | Programmatic control, automation |
| CI/CD pipelines | Agent SDK | Headless execution, automated workflows |
| Chat/conversational interfaces | Agent SDK with ClaudeSDKClient | Multi-turn context retention |
| Background/scheduled jobs | Agent SDK | Cron-compatible, no user interaction |
| Quick one-off tasks | Either | CLI faster for ad-hoc, SDK for repeatability |
| Debugging and prototyping | Claude Code CLI → Agent SDK | Develop interactively, deploy programmatically |
Recommended Workflow
- Develop with Claude Code CLI for interactive testing
- Test behavior and iterate quickly
- Convert to Agent SDK for automation
- Deploy to production environments
When to Choose CLI
- Learning and experimenting
- Manual code reviews
- Interactive debugging sessions
- Quick file operations
- Testing agent capabilities
When to Choose SDK
- Building applications (web apps, APIs, services)
- Automation (CI/CD, scheduled tasks, batch processing)
- Custom integrations (Slack bots, Discord bots, dashboards)
- Multi-turn conversations with state
- Production deployments requiring programmatic control
Key Concepts & Patterns
Core Concepts
Agents
- Autonomous programs that use Claude’s reasoning to accomplish tasks
- Can use tools (Read, Write, Bash, etc.) to interact with the environment
- Operate with configurable permissions and constraints
Tools
- Functions agents can call to perform actions
- Built-in tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch
- Custom tools via MCP (Model Context Protocol) servers
Permissions
- Control what agents can and cannot do
- Permission modes:
default(ask),acceptEdits(auto-approve),bypassPermissions(no checks),plan(planning mode) - Custom permission handlers for fine-grained control
Sessions & Context
query(): One-shot execution, fresh context each timeClaudeSDKClient: Multi-turn conversations with persistent context- Sessions maintain conversation history across interactions
Hooks
- Intercept and modify agent behavior at key points
- Hook types:
PreToolUse,PostToolUse,PreMessage,PostMessage - Use cases: logging, validation, custom tool routing
Common Patterns
Pattern 1: Read-Only Agents Use for safe operations like code review, analysis, research:
options = ClaudeAgentOptions(
allowed_tools=["Read", "Grep", "WebSearch"],
# No Write or Bash - read-only
)
Pattern 2: Autonomous File Editors Auto-approve edits for trusted automation:
options = ClaudeAgentOptions(
allowed_tools=["Read", "Write", "Edit"],
permission_mode="acceptEdits" # Auto-approve
)
Pattern 3: Interactive Multi-Turn Maintain context across conversation:
async with ClaudeSDKClient(options) as client:
await client.query("First question")
# Claude remembers context
await client.query("Follow-up question")
Pattern 4: Custom Tool Integration Extend agent capabilities with MCP:
my_server = create_sdk_mcp_server(
name="custom",
tools=[custom_tool_1, custom_tool_2]
)
options = ClaudeAgentOptions(
mcp_servers={"custom": my_server}
)
Start restrictive (read-only, default permissions) and progressively add capabilities as trust is established.
Getting Started (Your First Steps)
Prerequisites
-
Claude Code CLI installed
brew install --cask claude-code # or: npm install -g @anthropic-ai/claude-code -
Authenticate Claude Code
claude # Follow authentication prompts -
Python 3.9+ or Node.js 18+
Installation
Python:
pip install claude-agent-sdk
# or with uv:
uv add claude-agent-sdk
TypeScript/Node:
npm install @anthropic-ai/claude-agent-sdk
Your First Agent (5 Minutes)
Step 1: Create a file (my_agent.py or my_agent.ts)
Step 2: Write minimal code:
# Python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for msg in query(
prompt="Create a file called hello.txt with 'Hello World'",
options=ClaudeAgentOptions(
allowed_tools=["Write"],
permission_mode="acceptEdits"
)
):
print(msg)
asyncio.run(main())
Step 3: Run it:
python my_agent.py
Expected result: A hello.txt file is created with “Hello World” content.
Next Steps
-
Try different permission modes
"default"- Asks for approval"acceptEdits"- Auto-approves file changes"plan"- Shows plan before execution
-
Add more tools
["Read", "Write", "Bash"]for file operations + shell["WebSearch", "WebFetch"]for internet access["Grep", "Glob"]for searching
-
Explore multi-turn conversations
- Use
ClaudeSDKClientfor context retention - Build interactive chat interfaces
- Use
-
Create custom tools
- Define MCP tools for domain-specific actions
- Integrate with your APIs and services
- ✅ Claude Code CLI authenticated
- ✅ SDK installed (
pipornpm) - ✅ First agent runs successfully
- ✅ Ready to build more complex agents!
Troubleshooting
“Claude Code CLI not found”
- Install:
brew install --cask claude-codeornpm install -g @anthropic-ai/claude-code - Verify:
claude --version
“Authentication failed”
- Run:
claudeto re-authenticate - Check API key/credentials
“Permission denied”
- Use
permission_mode="acceptEdits"for autonomous execution - Or approve prompts when using
"default"mode
Documentation References
Official Documentation
Claude Agent SDK
Claude Code CLI
Claude API
Model Context Protocol (MCP)
Community Resources
GitHub Repositories
Example Projects
Support
Related Guides
- Architecture Guide - Claude Code configuration and best practices
- Tool Patterns - Advanced tool use patterns
- Prompting Guide - Effective prompting strategies for agents