- Published on
Claude Agent SDK A Comprehensive Tutorial
- Authors

- Name
- Yinhuan Yuan
What is the Claude Agent SDK?
The Claude Agent SDK is the infrastructure that powers Claude Code, but it's designed for building all kinds of agents - not just coding tools. It was originally called "Claude Code SDK" but was renamed to reflect its broader capabilities.
Key Principle: The SDK gives your agents access to a computer, allowing them to work like humans do - reading files, running commands, creating visualizations, and executing complex workflows.
Why It Matters
The SDK provides production-ready capabilities including context management, rich tool ecosystem, advanced permissions, built-in error handling, session management, and optimized Claude integration.
Available in both TypeScript and Python, making it accessible to most developers.
What Can You Build?
The SDK enables various agent types including finance agents for portfolio analysis, personal assistants for booking and scheduling, customer support agents handling ambiguous requests, and much more.
Real-World Examples:
1. Coding Agents
- Code review bots that check for security issues
- Migration assistants for legacy codebases
- Automated debugging and testing
2. Research Agents
- Deep analysis of documents and data
- Web research with synthesis
- Report generation with citations
3. Business Automation
- Financial analysis with API integration
- Customer support ticket resolution
- Data processing and visualization
4. Personal Assistants
- Calendar and email management
- Travel booking
- Task coordination across apps
Getting Started
Installation
TypeScript:
npm install @anthropic-ai/claude-agent-sdk
Python:
pip install claude-agent-sdk
Authentication
You need a Claude API key from the Claude Console. Set the ANTHROPIC_API_KEY environment variable.
export ANTHROPIC_API_KEY='your-api-key-here'
The SDK also supports Amazon Bedrock and Google Vertex AI authentication.
Core Concepts
The Agent Loop
Agents typically operate in a feedback loop: gather context → take action → verify work → repeat.
This mirrors how humans work:
- Gather Context: Read files, search documentation, fetch data
- Take Action: Edit files, run commands, call APIs
- Verify Work: Check outputs, run tests, validate results
- Repeat: Iterate until the task is complete
File System as Context
The file system represents information that can be pulled into the model's context. Claude uses bash tools like grep and tail to efficiently load large files into its context.
Tutorial: Building Your First Agent
Let me show you how to build a simple agent in both Python and TypeScript.
Example 1: Simple Query (Python)
import anyio
from claude_agent_sdk import query
async def main():
async for message in query(prompt="What is 2 + 2?"):
print(message)
anyio.run(main)
Example 2: File Processing Agent (Python)
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock
async def process_data():
options = ClaudeAgentOptions(
allowed_tools=["Read", "Write", "Bash"],
permission_mode='acceptEdits', # auto-accept file edits
cwd="/path/to/project"
)
prompt = """
Read the data.csv file, analyze the sales trends,
and create a summary report in markdown format.
"""
async for message in query(prompt=prompt, options=options):
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(block.text)
anyio.run(process_data)
Example 3: Custom Tools (Python)
from claude_agent_sdk import tool, create_sdk_mcp_server, ClaudeAgentOptions, ClaudeSDKClient
# Define a custom tool
@tool("greet", "Greet a user", {"name": str})
async def greet_user(args):
return {
"content": [
{"type": "text", "text": f"Hello, {args['name']}!"}
]
}
# Another custom tool for calculations
@tool("calculate_roi", "Calculate ROI", {"investment": float, "return": float})
async def calculate_roi(args):
roi = ((args['return'] - args['investment']) / args['investment']) * 100
return {
"content": [
{"type": "text", "text": f"ROI: {roi:.2f}%"}
]
}
# Create an MCP server with your tools
server = create_sdk_mcp_server(
name="my-tools",
version="1.0.0",
tools=[greet_user, calculate_roi]
)
# Use it with Claude
async def main():
options = ClaudeAgentOptions(
mcp_servers={"tools": server},
allowed_tools=["mcp__tools__greet", "mcp__tools__calculate_roi"]
)
async with ClaudeSDKClient(options=options) as client:
await client.query("Calculate ROI for $10,000 investment with $15,000 return")
async for msg in client.receive_response():
print(msg)
anyio.run(main)
Example 4: Interactive Agent (TypeScript)
import { ClaudeSDKClient, ClaudeAgentOptions } from '@anthropic-ai/claude-agent-sdk';
const options: ClaudeAgentOptions = {
allowedTools: ['Read', 'Write', 'Bash', 'WebSearch'],
systemPrompt: 'You are a helpful coding assistant.',
maxTurns: 10
};
const client = new ClaudeSDKClient(options);
// Query the agent
await client.query('Create a Python script that analyzes CSV data');
// Process streaming responses
for await (const message of client.receiveResponse()) {
console.log(message);
}
await client.close();
Advanced Features
1. Context Management
The SDK automatically handles context window management, ensuring your agent doesn't run out of space.
2. Permission Control
options = ClaudeAgentOptions(
permission_mode='acceptEdits', # Auto-accept file changes
allowed_tools=['Read', 'Write', 'Bash'] # Limit available tools
)
3. Subagents
Launch specialized agents for subtasks with different permissions or capabilities.
4. MCP Integration
Use Model Context Protocol for extensible tool integration.
5. Hooks
Add custom logic at different points in the agent lifecycle.
Real-World Use Case: Email Agent
Let me walk through building an email processing agent:
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, tool, create_sdk_mcp_server
# Define email-related tools
@tool("fetch_emails", "Fetch unread emails", {})
async def fetch_emails(args):
# Your email API integration here
emails = get_unread_emails()
return {"content": [{"type": "text", "text": str(emails)}]}
@tool("send_email", "Send an email", {"to": str, "subject": str, "body": str})
async def send_email(args):
# Your email sending logic
send_email_via_api(args['to'], args['subject'], args['body'])
return {"content": [{"type": "text", "text": "Email sent successfully"}]}
@tool("categorize_email", "Categorize email", {"email_id": str, "category": str})
async def categorize_email(args):
# Your categorization logic
return {"content": [{"type": "text", "text": f"Categorized as {args['category']}"}]}
# Create the agent
async def email_agent():
server = create_sdk_mcp_server(
name="email-tools",
version="1.0.0",
tools=[fetch_emails, send_email, categorize_email]
)
options = ClaudeAgentOptions(
mcp_servers={"email": server},
system_prompt="""
You are an email assistant. You can:
- Fetch and read emails
- Categorize emails by importance
- Draft responses
- Send emails
Always ask for confirmation before sending emails.
"""
)
async with ClaudeSDKClient(options=options) as client:
await client.query("""
Check my unread emails, categorize them by urgency,
and draft responses to the urgent ones.
""")
async for msg in client.receive_response():
print(msg)
anyio.run(email_agent)
Best Practices
1. Start Small
Begin with simple queries and gradually add complexity.
2. Clear Prompts
Be explicit about what you want the agent to do:
# ✅ Good
"Read the sales_data.csv file, calculate total revenue by region, and create a bar chart"
# ❌ Vague
"Analyze sales"
3. Tool Permissions
Only grant the tools your agent actually needs:
options = ClaudeAgentOptions(
allowed_tools=['Read', 'Bash'], # Only read and bash, no writes
permission_mode='ask' # Ask before each action
)
4. Error Handling
Always handle async errors properly:
try:
async for message in query(prompt=my_prompt, options=options):
process_message(message)
except Exception as e:
logger.error(f"Agent error: {e}")
5. Context Efficiency
Use targeted file reads rather than loading everything:
# ✅ Good: Use grep to find relevant sections
"Use grep to find all TODO comments in Python files"
# ❌ Wasteful: Loading entire large files
"Read all files and find TODOs"
Resources
- Official Documentation: https://docs.claude.com/en/docs/agent-sdk/overview
- TypeScript SDK: https://github.com/anthropics/claude-agent-sdk-typescript
- Python SDK: https://github.com/anthropics/claude-agent-sdk-python
- Engineering Blog: https://www.anthropic.com/engineering/building-agents-with-the-claude-agent-sdk
- Discord Community: Join the Claude Developers Discord for support
Key Takeaways
- The Claude Agent SDK lets you build autonomous agents that can read files, run commands, and execute complex workflows
- It's the same infrastructure that powers Claude Code, but for any use case
- Available in Python and TypeScript with similar APIs
- Supports custom tools via MCP for extending capabilities
- Production-ready with built-in context management, permissions, and error handling
Try It Yourself
Want to experiment? Here's a simple starter project:
Goal: Build an agent that analyzes your React codebase for common issues
from claude_agent_sdk import query, ClaudeAgentOptions
async def code_analyzer():
options = ClaudeAgentOptions(
allowed_tools=['Read', 'Bash'],
cwd='/path/to/your/react/project'
)
prompt = """
Analyze this React codebase:
1. Find all useState hooks
2. Check for missing dependency arrays in useEffect
3. Look for performance issues (inline functions, etc.)
4. Generate a markdown report
"""
async for message in query(prompt=prompt, options=options):
print(message)
anyio.run(code_analyzer)
Would you like me to:
- Create a specific agent for your React/TypeScript work?
- Build an STM32 code review agent using the SDK?
- Show more advanced patterns like subagents or custom MCP servers?