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.

💡 Pro Tip

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:

  1. Requires Claude Code CLI to be installed (acts as the runtime)
  2. Builds on top of the Claude API for model interactions
  3. Provides a higher-level abstraction than raw API calls (like Express vs raw Node HTTP)
  4. 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
Best Practice

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 CaseExampleWhy Agent SDK
Code Analysis AgentsFind bugs, refactor, add testsRuns autonomously on repos
CI/CD IntegrationRun PR reviews, tests, lintingAutomated, no user interaction
Email AssistantsProcess emails, draft responsesContinuous background operation
Research AgentsGather info, summarize findingsMulti-step autonomous tasks
Document GenerationCreate reports, specs, docsDriven by external data
Scheduled TasksNightly data processingCron-compatible, headless
Chat InterfacesBuild conversational appsMulti-turn with state
Slack/Discord BotsSlack commands, interactionsEvent-driven automation
Web DashboardBackend agent for web appsREST 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
💡 Key Insight

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:

  1. Create the Python file
  2. Show you what it did
  3. Report results
Tip

Start with permission_mode="acceptEdits" for autonomous agents. Use "default" for approval-based workflow.

Key APIs and Methods

Two Main Approaches

Featurequery()ClaudeSDKClient
Use CaseOne-off tasksContinuous conversations
SessionFresh each timeMaintains context
InterruptsNoYes
HooksNoYes
Best ForAutomation scripts, CI/CDChat 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

ScenarioUseWhy
Interactive terminal developmentClaude Code CLIReal-time feedback, manual testing
Python/Node application integrationAgent SDKProgrammatic control, automation
CI/CD pipelinesAgent SDKHeadless execution, automated workflows
Chat/conversational interfacesAgent SDK with ClaudeSDKClientMulti-turn context retention
Background/scheduled jobsAgent SDKCron-compatible, no user interaction
Quick one-off tasksEitherCLI faster for ad-hoc, SDK for repeatability
Debugging and prototypingClaude Code CLI → Agent SDKDevelop interactively, deploy programmatically
Best Practice
  1. Develop with Claude Code CLI for interactive testing
  2. Test behavior and iterate quickly
  3. Convert to Agent SDK for automation
  4. 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 time
  • ClaudeSDKClient: 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}
)
💡 Design Principle

Start restrictive (read-only, default permissions) and progressively add capabilities as trust is established.

Getting Started (Your First Steps)

Prerequisites

  1. Claude Code CLI installed

    brew install --cask claude-code
    # or: npm install -g @anthropic-ai/claude-code
    
  2. Authenticate Claude Code

    claude  # Follow authentication prompts
    
  3. 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

  1. Try different permission modes

    • "default" - Asks for approval
    • "acceptEdits" - Auto-approves file changes
    • "plan" - Shows plan before execution
  2. Add more tools

    • ["Read", "Write", "Bash"] for file operations + shell
    • ["WebSearch", "WebFetch"] for internet access
    • ["Grep", "Glob"] for searching
  3. Explore multi-turn conversations

    • Use ClaudeSDKClient for context retention
    • Build interactive chat interfaces
  4. Create custom tools

    • Define MCP tools for domain-specific actions
    • Integrate with your APIs and services
Success Checklist
  • ✅ Claude Code CLI authenticated
  • ✅ SDK installed (pip or npm)
  • ✅ First agent runs successfully
  • ✅ Ready to build more complex agents!

Troubleshooting

“Claude Code CLI not found”

  • Install: brew install --cask claude-code or npm install -g @anthropic-ai/claude-code
  • Verify: claude --version

“Authentication failed”

  • Run: claude to 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