Migration Guide: Claude Code SDK → Claude Agent SDK (Python)
Migration Guide: Claude Code SDK → Claude Agent SDK (Python)
Section titled “Migration Guide: Claude Code SDK → Claude Agent SDK (Python)”Version: 2025.1 Target Audience: Developers migrating from Claude Code SDK to Claude Agent SDK Status: Official Migration Guide
Table of Contents
Section titled “Table of Contents”- Overview
- Critical Changes
- Step-by-Step Migration
- Breaking Changes
- New Features in 2025
- Code Migration Examples
- Troubleshooting
Overview
Section titled “Overview”What Changed?
Section titled “What Changed?”The Claude Code SDK has been rebranded and significantly expanded into the Claude Agent SDK to reflect its broader capabilities beyond coding tasks. This evolution represents Anthropic’s commitment to building a comprehensive framework for general-purpose autonomous agents.
Why the Change?
Section titled “Why the Change?”Claude Code SDK focused primarily on:
- Code analysis and generation
- Development workflows
- Software engineering tasks
Claude Agent SDK now supports:
- General-purpose task automation
- CSV processing and data manipulation
- Web research and information gathering
- Visualization building
- Digital work automation
- Complex multi-agent orchestration
- All previous coding capabilities
Timeline
Section titled “Timeline”- Pre-2025: Claude Code SDK (coding-focused)
- 2025+: Claude Agent SDK (general-purpose agents)
- Support: Claude Code SDK will be deprecated in Q4 2025
Critical Changes
Section titled “Critical Changes”1. Package Name Change
Section titled “1. Package Name Change”# OLD - Claude Code SDKfrom claude_code import query
# NEW - Claude Agent SDKfrom claude_agent_sdk import query2. Python Version Requirement
Section titled “2. Python Version Requirement”- Minimum: Python 3.10+ (previously 3.8+)
- Recommended: Python 3.11+ for best performance
- Reason: Leverage modern async improvements and type hints
# Check your Python versionpython --version
# Should output: Python 3.10.0 or higher3. Model Naming Updates
Section titled “3. Model Naming Updates”# OLDmodel = "claude-3-5-sonnet-20241022"
# NEW - Claude Sonnet 4.5 (recommended)model = "claude-sonnet-4-5"
# Still supported for compatibilitymodel = "claude-3-5-sonnet-20241022"4. Enhanced Built-in Tools
Section titled “4. Enhanced Built-in Tools”New Built-in Tools:
Read- File reading operationsWrite- File writing operationsEdit- File editing operationsBash- Command-line executionGrep- Content searchingGlob- File pattern matchingWebFetch- Web content retrievalWebSearch- Internet search capabilities
Code Example:
from claude_agent_sdk import query
# Agent automatically selects appropriate toolsasync for message in query( prompt="Search the web for the latest TypeScript features and create a summary document"): print(message)Step-by-Step Migration
Section titled “Step-by-Step Migration”Step 1: Update Dependencies
Section titled “Step 1: Update Dependencies”Remove Old Package:
pip uninstall claude-code-sdkInstall New Package:
pip install claude-agent-sdk
# Or with all extraspip install claude-agent-sdk[full]Update requirements.txt:
# OLDclaude-code-sdk>=0.9.0
# NEWclaude-agent-sdk>=1.0.0python-dotenv>=1.0.0pydantic>=2.0.0aiohttp>=3.9.0Step 2: Update Import Statements
Section titled “Step 2: Update Import Statements”Find and Replace:
# OLDfrom claude_code import query, ClaudeAgentOptionsfrom claude_code.tools import tool, create_mcp_server
# NEWfrom claude_agent_sdk import query, ClaudeAgentOptionsfrom claude_agent_sdk.tools import tool, create_sdk_mcp_serverAutomated Migration Script:
import osimport refrom pathlib import Path
def migrate_imports(file_path: Path): """Automatically update import statements.""" with open(file_path, 'r') as f: content = f.read()
# Replace package imports content = content.replace('from claude_code', 'from claude_agent_sdk') content = content.replace('import claude_code', 'import claude_agent_sdk')
# Replace specific tool imports content = content.replace('create_mcp_server', 'create_sdk_mcp_server')
with open(file_path, 'w') as f: f.write(content)
print(f"✓ Migrated: {file_path}")
# Usagefor py_file in Path('.').rglob('*.py'): if 'venv' not in str(py_file) and 'node_modules' not in str(py_file): migrate_imports(py_file)Step 3: Update Configuration
Section titled “Step 3: Update Configuration”Environment Variables:
# .env file - NO CHANGES REQUIREDANTHROPIC_API_KEY=sk-ant-your-key-hereANTHROPIC_MODEL=claude-sonnet-4-5Python Configuration:
# OLDfrom claude_code import ClaudeAgentOptions
options = ClaudeAgentOptions( model="claude-3-5-sonnet-20241022")
# NEW - Enhanced with 2025 featuresfrom claude_agent_sdk import ClaudeAgentOptions
options = ClaudeAgentOptions( model="claude-sonnet-4-5", # Latest model max_budget_usd=5.0, # Cost controls allowed_tools=[ # Fine-grained tool permissions "Read", "Write", "WebSearch", "Bash" ], hooks={ # NEW: Hooks system "pre_tool_execution": validate_tool_input, "post_tool_execution": log_tool_result }, enable_subagents=True # NEW: Subagent support)Step 4: Update Code Patterns
Section titled “Step 4: Update Code Patterns”Basic Query Pattern - UNCHANGED:
# This pattern works in both versionsimport asynciofrom claude_agent_sdk import query
async def main(): async for message in query(prompt="Analyze this code"): print(message)
asyncio.run(main())Advanced Patterns - ENHANCED:
# NEW: Leverage 2025 featuresfrom claude_agent_sdk import query, ClaudeAgentOptions
async def advanced_agent(): options = ClaudeAgentOptions( model="claude-sonnet-4-5", system_prompt="You are a research and analysis specialist.", allowed_tools=["WebSearch", "WebFetch", "Read", "Write"], enable_subagents=True # NEW )
async for message in query( prompt="""Research the latest trends in AI agents, create a summary document, and generate visualizations.""", options=options ): if message.type == "tool_call": print(f"Using tool: {message.tool_name}") elif message.type == "assistant": print(message.content)Breaking Changes
Section titled “Breaking Changes”1. MCP Server Creation
Section titled “1. MCP Server Creation”BREAKING: Function renamed for clarity
# OLDfrom claude_code.tools import create_mcp_server
server = create_mcp_server( name="my-tools", tools=[my_tool])
# NEWfrom claude_agent_sdk.tools import create_sdk_mcp_server
server = create_sdk_mcp_server( name="my-tools", version="1.0.0", # NEW: Version required tools=[my_tool])2. Message Types
Section titled “2. Message Types”ENHANCED: New message subtypes added
# OLDif message.type == "system": print("System message")
# NEW - More granularif message.type == "system": if message.subtype == "subagent_start": print("Subagent started") elif message.subtype == "subagent_end": print("Subagent completed") elif message.subtype == "hook_execution": print("Hook executed")3. Permission Callbacks
Section titled “3. Permission Callbacks”ENHANCED: Additional context provided
# OLDasync def can_use_tool(tool_name: str, tool_input: dict): return {"behavior": "allow"}
# NEW - Enhanced with contextasync def can_use_tool(tool_name: str, tool_input: dict, context: dict): # context includes: session_id, previous_tools, cost_so_far, etc. if context.get("cost_so_far", 0) > 10.0: return {"behavior": "deny", "message": "Budget exceeded"} return {"behavior": "allow"}4. Python 3.10+ Required Features
Section titled “4. Python 3.10+ Required Features”Leverage new Python features:
# Pattern matching (Python 3.10+)match message.type: case "assistant": print(message.content) case "tool_call": print(f"Calling: {message.tool_name}") case "error": print(f"Error: {message.error}") case _: pass
# Union types (Python 3.10+)from typing import Literal
MessageType = Literal["assistant", "user", "system", "tool_call"]New Features in 2025
Section titled “New Features in 2025”1. Claude Sonnet 4.5 Integration
Section titled “1. Claude Sonnet 4.5 Integration”Frontier Model Capabilities:
from claude_agent_sdk import query, ClaudeAgentOptions
# Use the latest Claude Sonnet 4.5options = ClaudeAgentOptions( model="claude-sonnet-4-5", temperature=1.0)
async for message in query( prompt="Design a complete microservices architecture", options=options): print(message)Benefits:
- Superior reasoning for complex tasks
- Enhanced multi-step planning
- Better context understanding
- Improved tool use accuracy
2. Subagents for Task Decomposition
Section titled “2. Subagents for Task Decomposition”NEW FEATURE: Specialized subagents for parallel execution
from claude_agent_sdk import query, ClaudeAgentOptions
options = ClaudeAgentOptions( model="claude-sonnet-4-5", enable_subagents=True, agents={ "researcher": { "description": "Web research and information gathering", "tools": ["WebSearch", "WebFetch", "Read"], "model": "claude-sonnet-4-5" }, "analyst": { "description": "Data analysis and insights", "tools": ["Read", "Write"], "model": "claude-3-5-sonnet" }, "visualizer": { "description": "Create charts and visualizations", "tools": ["Write", "Bash"], "model": "claude-3-5-haiku" } })
async for message in query( prompt="""Research AI safety trends, analyze the data, and create visualizations showing key insights.""", options=options): if message.subtype == "subagent_start": print(f"Starting subagent: {message.agent_name}") elif message.subtype == "subagent_end": print(f"Completed subagent: {message.agent_name}")3. Hooks System
Section titled “3. Hooks System”NEW FEATURE: Inject logic at key execution points
from claude_agent_sdk import query, ClaudeAgentOptionsfrom pathlib import Path
# Define hooksasync def validate_file_path(tool_name: str, tool_input: dict, context: dict): """Pre-execution hook to validate file paths.""" if tool_name in ["Read", "Write", "Edit"]: file_path = Path(tool_input.get("file_path", ""))
# Prevent access to sensitive directories forbidden_dirs = ["/etc", "/sys", "/root", "C:\\Windows"] if any(str(file_path).startswith(d) for d in forbidden_dirs): return { "allow": False, "message": f"Access to {file_path} is forbidden" }
return {"allow": True}
async def log_tool_result(tool_name: str, tool_result: str, context: dict): """Post-execution hook to log results.""" with open("tool_audit.log", "a") as f: f.write(f"{context['timestamp']}: {tool_name} -> {len(tool_result)} bytes\n")
# Use hooksoptions = ClaudeAgentOptions( model="claude-sonnet-4-5", hooks={ "pre_tool_execution": validate_file_path, "post_tool_execution": log_tool_result, "session_start": lambda ctx: print(f"Session {ctx['session_id']} started"), "session_end": lambda ctx: print(f"Session completed in {ctx['duration']}s") })
async for message in query( prompt="Read all configuration files and create a backup", options=options): print(message)4. Model Context Protocol (MCP) Enhancements
Section titled “4. Model Context Protocol (MCP) Enhancements”ENHANCED: Define custom Python functions as tools
from claude_agent_sdk import tool, create_sdk_mcp_server, query
@tool( name="process_csv", description="Process CSV file and return statistics", parameters={ "file_path": str, "operations": list[str] })async def process_csv(args: dict) -> dict: """Custom CSV processing tool.""" import pandas as pd
df = pd.read_csv(args["file_path"])
results = { "rows": len(df), "columns": list(df.columns), "statistics": {} }
if "summary" in args["operations"]: results["statistics"]["summary"] = df.describe().to_dict()
if "missing" in args["operations"]: results["statistics"]["missing"] = df.isnull().sum().to_dict()
return { "content": [{ "type": "text", "text": f"Processed {results['rows']} rows, {len(results['columns'])} columns" }] }
# Create MCP server with custom toolcsv_server = create_sdk_mcp_server( name="csv-tools", version="1.0.0", tools=[process_csv])
# Use in agentoptions = ClaudeAgentOptions( mcp_servers={"csv": csv_server}, allowed_tools=["mcp__csv__process_csv", "Read", "Write"])
async for message in query( prompt="Process the sales_data.csv file and create a summary report", options=options): print(message)5. General-Purpose Agent Development
Section titled “5. General-Purpose Agent Development”NEW CAPABILITY: Beyond coding tasks
from claude_agent_sdk import query, ClaudeAgentOptions
# Example 1: Web Research Agentasync def research_agent(topic: str): """Agent that researches a topic and creates a comprehensive report.""" options = ClaudeAgentOptions( model="claude-sonnet-4-5", system_prompt="You are a research specialist with access to web search.", allowed_tools=["WebSearch", "WebFetch", "Write"] )
async for message in query( prompt=f"""Research the topic: {topic}
Tasks: 1. Search for recent articles and papers 2. Gather key findings and statistics 3. Identify trends and patterns 4. Create a comprehensive report in Markdown 5. Save the report as research_report.md """, options=options ): print(message)
# Example 2: Data Processing Agentasync def data_processor(csv_file: str): """Agent that processes CSV data and generates visualizations.""" options = ClaudeAgentOptions( model="claude-sonnet-4-5", system_prompt="You are a data analysis specialist.", allowed_tools=["Read", "Write", "Bash"] )
async for message in query( prompt=f"""Process the CSV file: {csv_file}
Tasks: 1. Read and analyze the data 2. Calculate statistics (mean, median, std dev) 3. Identify outliers 4. Generate a Python script to create visualizations 5. Run the script to produce charts 6. Create a summary report """, options=options ): print(message)
# Example 3: Document Automation Agentasync def document_automator(template: str, data: dict): """Agent that generates documents from templates.""" options = ClaudeAgentOptions( model="claude-3-5-sonnet", allowed_tools=["Read", "Write"] )
async for message in query( prompt=f"""Generate a document using this template: {template}
Data: {data}
Tasks: 1. Read the template 2. Fill in the data 3. Format appropriately 4. Save as output_document.pdf """, options=options ): print(message)6. Enhanced Built-in Tools
Section titled “6. Enhanced Built-in Tools”All Built-in Tools Available:
from claude_agent_sdk import query, ClaudeAgentOptions
options = ClaudeAgentOptions( model="claude-sonnet-4-5", allowed_tools=[ "Read", # Read file contents "Write", # Create or overwrite files "Edit", # Modify specific sections "Bash", # Execute shell commands "Grep", # Search file contents "Glob", # File pattern matching "WebSearch", # Search the internet "WebFetch" # Fetch web content ])
async for message in query( prompt=""" 1. Search the web for Python best practices 2. Create a summary document 3. Find all Python files in the project 4. Run the test suite """, options=options): print(message)Code Migration Examples
Section titled “Code Migration Examples”Example 1: Simple Agent
Section titled “Example 1: Simple Agent”Before (Claude Code SDK):
from claude_code import queryimport asyncio
async def main(): async for message in query(prompt="Explain async/await"): print(message)
asyncio.run(main())After (Claude Agent SDK):
from claude_agent_sdk import query, ClaudeAgentOptionsimport asyncio
async def main(): # Enhanced with 2025 features options = ClaudeAgentOptions( model="claude-sonnet-4-5", # Latest model max_budget_usd=1.0 # Cost control )
async for message in query( prompt="Explain async/await with modern Python 3.10+ examples", options=options ): print(message)
asyncio.run(main())Example 2: Custom Tool
Section titled “Example 2: Custom Tool”Before (Claude Code SDK):
from claude_code.tools import tool, create_mcp_server
@tool("my_tool", "Description")async def my_tool(args): return {"result": "data"}
server = create_mcp_server( name="my-server", tools=[my_tool])After (Claude Agent SDK):
from claude_agent_sdk import tool, create_sdk_mcp_server
@tool( name="my_tool", description="Enhanced tool with Pydantic validation", parameters={ "input_data": str, "options": dict })async def my_tool(args: dict) -> dict: """Enhanced tool with better type safety.""" return { "content": [{ "type": "text", "text": f"Processed: {args['input_data']}" }] }
server = create_sdk_mcp_server( name="my-server", version="2.0.0", # Required in new version tools=[my_tool])Example 3: Multi-Agent System
Section titled “Example 3: Multi-Agent System”Before (Claude Code SDK):
# Sequential execution onlyfrom claude_code import query
async def pipeline(): # Agent 1 async for msg in query(prompt="Task 1"): result1 = msg
# Agent 2 (uses result1) async for msg in query(prompt=f"Task 2: {result1}"): result2 = msg
return result2After (Claude Agent SDK with Subagents):
from claude_agent_sdk import query, ClaudeAgentOptions
async def pipeline(): options = ClaudeAgentOptions( model="claude-sonnet-4-5", enable_subagents=True, agents={ "agent1": { "description": "First task specialist", "tools": ["Read", "WebSearch"] }, "agent2": { "description": "Second task specialist", "tools": ["Write", "Bash"] } } )
# Automatic subagent orchestration async for message in query( prompt="Complete Task 1, then use results for Task 2", options=options ): if message.subtype == "subagent_start": print(f"Starting: {message.agent_name}") elif message.subtype == "subagent_end": print(f"Completed: {message.agent_name}")Troubleshooting
Section titled “Troubleshooting”Issue 1: Import Errors
Section titled “Issue 1: Import Errors”Problem:
ModuleNotFoundError: No module named 'claude_code'Solution:
# Uninstall old packagepip uninstall claude-code-sdk
# Install new packagepip install claude-agent-sdk
# Update all imports# From: from claude_code import query# To: from claude_agent_sdk import queryIssue 2: Python Version Compatibility
Section titled “Issue 2: Python Version Compatibility”Problem:
SyntaxError: invalid syntax (pattern matching not supported)Solution:
# Check Python versionpython --version
# Upgrade if necessary# Option 1: Use pyenvpyenv install 3.11.7pyenv global 3.11.7
# Option 2: Use system package manager# Ubuntu/Debian:sudo apt updatesudo apt install python3.11
# macOS:brew install python@3.11Issue 3: Tool Function Signature Changed
Section titled “Issue 3: Tool Function Signature Changed”Problem:
TypeError: create_mcp_server() got an unexpected keyword argument 'version'Solution:
# OLD (won't work)from claude_code.tools import create_mcp_server
server = create_mcp_server(name="my-tools", tools=[...])
# NEW (correct)from claude_agent_sdk.tools import create_sdk_mcp_server
server = create_sdk_mcp_server( name="my-tools", version="1.0.0", # Now required tools=[...])Issue 4: Model Name Not Recognized
Section titled “Issue 4: Model Name Not Recognized”Problem:
ValueError: Unknown model: claude-code-20241022Solution:
# Update model namesoptions = ClaudeAgentOptions( # OLD (may not work) # model="claude-code-20241022"
# NEW (recommended) model="claude-sonnet-4-5"
# Or use previous models # model="claude-3-5-sonnet-20241022")Issue 5: Hooks Not Working
Section titled “Issue 5: Hooks Not Working”Problem:
TypeError: hooks must be a dictionary of callablesSolution:
# Ensure hooks are async functionsasync def my_hook(tool_name: str, tool_input: dict, context: dict): return {"allow": True}
# Correct hook definitionoptions = ClaudeAgentOptions( hooks={ "pre_tool_execution": my_hook # async function, not my_hook() })Migration Checklist
Section titled “Migration Checklist”Pre-Migration
Section titled “Pre-Migration”- Review current Claude Code SDK usage
- Identify all custom tools and MCP servers
- Document current agent configurations
- Check Python version (must be 3.10+)
- Review deprecated features being used
Migration Steps
Section titled “Migration Steps”- Install Claude Agent SDK (
pip install claude-agent-sdk) - Run automated import migration script
- Update model names to Claude Sonnet 4.5
- Update
create_mcp_servertocreate_sdk_mcp_server - Add version numbers to MCP servers
- Test basic agent functionality
- Test custom tools and MCP integrations
- Implement hooks if needed
- Configure subagents for complex workflows
- Update error handling for new message types
Post-Migration
Section titled “Post-Migration”- Run comprehensive test suite
- Verify all tools function correctly
- Monitor costs with new models
- Update documentation
- Train team on new features
- Remove Claude Code SDK dependencies
- Uninstall
claude-code-sdkpackage
Additional Resources
Section titled “Additional Resources”Official Documentation
Section titled “Official Documentation”- Claude Agent SDK Docs: https://docs.anthropic.com/agent-sdk
- API Reference: https://docs.anthropic.com/api
- Migration Support: https://docs.anthropic.com/agent-sdk/migration
Community Resources
Section titled “Community Resources”- GitHub Examples: https://github.com/anthropics/claude-agent-sdk-examples
- Discord Community: https://discord.gg/anthropic
- Stack Overflow: Tag questions with
claude-agent-sdk
Getting Help
Section titled “Getting Help”For migration assistance:
- Check the official documentation
- Search GitHub issues
- Ask in the Discord community
- Contact Anthropic support for enterprise customers
Summary
Section titled “Summary”Key Takeaways:
- Package Renamed:
claude-code-sdk→claude-agent-sdk - Python 3.10+ Required: Upgrade if on older versions
- New Model: Claude Sonnet 4.5 recommended for best performance
- Enhanced Features: Subagents, hooks, and expanded tool ecosystem
- General-Purpose: Now supports non-coding tasks (research, data processing, automation)
- Breaking Changes: MCP server creation function renamed
Migration Effort:
- Simple Projects: 1-2 hours (mostly find/replace)
- Medium Projects: 4-8 hours (custom tools, testing)
- Complex Projects: 1-2 days (subagents, hooks, full integration)
Recommended Approach:
- Start with automated import updates
- Update one agent at a time
- Test thoroughly before production deployment
- Leverage new features (subagents, hooks) for complex workflows
Questions or issues? Consult the comprehensive guide or reach out to the community.
Ready to unlock the full potential of Claude Agent SDK? Start migrating today!