Back to blog

April 25, 2026

Agent SDK

Claude Agent SDK Tutorial: Build Production AI Agents in Python & TypeScript (2026)

The Claude Agent SDK is the same agent loop that powers Claude Code, exposed as a Python and TypeScript library. One function call gives you a fully autonomous agent with built-in file, shell, web, and MCP tools. This guide walks the entire API.

TL;DR -- The Claude Agent SDK in 60 Seconds

The Claude Agent SDK is Anthropic's Python and TypeScript library for building autonomous AI agents. Install with pip install claude-agent-sdk or npm install @anthropic-ai/claude-agent-sdk. You call query() with a prompt, declare which tools the agent can use, and iterate the async message stream as Claude reasons, calls tools, and produces a result. It is the same agent loop that runs inside the Claude Code CLI, formerly known as the Claude Code SDK.

What Is the Claude Agent SDK?

The Claude Agent SDK is a programmable library that runs Claude with the same tool execution loop as Claude Code. Anthropic renamed it from the Claude Code SDK in v0.1.0 because the SDK is now used to build all kinds of agents -- legal assistants, SRE bots, research agents, support copilots -- not just coding tools.

What you get

  • ● Built-in tools: Read, Write, Edit, Bash, Glob, Grep, WebSearch, WebFetch, Monitor, Agent
  • ● Permission modes for production safety
  • ● Hooks for lifecycle events
  • ● MCP server support out of the box
  • ● Subagents for parallel work
  • ● Sessions you can resume or fork

What you skip

  • ● Implementing your own tool executor
  • ● Managing the assistant -- tool -- result loop
  • ● Context window pruning
  • ● Retry and error handling
  • ● Streaming plumbing

The CLI version of Claude Code is built on top of this SDK. Workflows you build in the CLI translate directly to SDK code, and many teams use both: CLI for daily development, SDK for production deployment.

Install the SDK

Pick your language. Both packages are published by Anthropic and ship the same agent loop. The TypeScript package bundles the Claude Code binary as an optional dependency, so you do not need to install Claude Code separately.

TYPESCRIPT

Node.js 18+

npm install @anthropic-ai/claude-agent-sdk
PYTHON

Python 3.10+

pip install claude-agent-sdk

Set your API key

Grab a key from platform.claude.com and put it in a .env file or your shell.

export ANTHROPIC_API_KEY=sk-ant-...

Want to route through your cloud provider? Set CLAUDE_CODE_USE_BEDROCK=1, CLAUDE_CODE_USE_VERTEX=1, or CLAUDE_CODE_USE_FOUNDRY=1 and configure the corresponding AWS, Google Cloud, or Azure credentials.

Your First Agent: Find and Fix a Bug

The "hello world" of agent SDKs is a code-fixing agent. You point it at a buggy file, allow Read and Edit tools, and let Claude autonomously diagnose and patch the problem. This is two dozen lines of code in either language.

The buggy file

# utils.py
def calculate_average(numbers):
    total = 0
    for num in numbers:
        total += num
    return total / len(numbers)  # crashes on []

def get_user_name(user):
    return user["name"].upper()  # crashes on None

Python agent

import asyncio
from claude_agent_sdk import (
    query, ClaudeAgentOptions, AssistantMessage, ResultMessage
)

async def main():
    async for message in query(
        prompt="Review utils.py for crash bugs and fix them.",
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Edit", "Glob"],
            permission_mode="acceptEdits",
        ),
    ):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if hasattr(block, "text"):
                    print(block.text)
        elif isinstance(message, ResultMessage):
            print(f"Done: {message.subtype}")

asyncio.run(main())

TypeScript agent

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Review utils.py for crash bugs and fix them.",
  options: {
    allowedTools: ["Read", "Edit", "Glob"],
    permissionMode: "acceptEdits",
  },
})) {
  if (message.type === "assistant" && message.message?.content) {
    for (const block of message.message.content) {
      if ("text" in block) console.log(block.text);
    }
  } else if (message.type === "result") {
    console.log("Done:", message.subtype);
  }
}

Run with python3 agent.py or npx tsx agent.ts. The agent reads the file, identifies the divide-by-zero and null-deref, edits the file in place, and exits. You wrote a prompt -- Claude wrote the fix.

Built-In Tools Reference

The SDK ships ten built-in tools. List the ones you want in allowedTools and Claude can call them autonomously. You never implement the tool executor yourself.

ToolPurpose
ReadRead any file in the working directory
WriteCreate new files
EditMake precise string-replace edits
BashRun terminal commands, scripts, git
MonitorWatch a background process line-by-line
GlobFind files by pattern (**/*.ts)
GrepSearch file contents with regex
WebSearchSearch the web for current info
WebFetchFetch and parse a web page
AgentSpawn a configured subagent

Read-only analysis

["Read", "Glob", "Grep"]

Analyze and modify

["Read", "Edit", "Glob"]

Full automation

["Read", "Edit", "Bash", "Glob", "Grep"]

Permission Modes: Pick Your Safety Level

Permission modes control how much human oversight your agent requires. The right choice depends on your deployment surface -- an interactive desktop app needs different defaults than a sandboxed CI runner.

ModeBehaviorUse case
acceptEditsAuto-approves file edits and common filesystem commands; asks for everything elseTrusted dev workflows
dontAskDenies anything not in allowedToolsLocked-down headless agents
auto (TS only)Model classifier approves or denies each tool callAutonomous agents with guardrails
bypassPermissionsRuns every tool without promptsSandboxed CI, fully trusted envs
defaultRequires a canUseTool callback to approve each callCustom approval flows

For production apps, the most common pattern is default with a canUseTool callback that allows reads automatically and shows the user a confirmation modal for writes or shell commands.

Build agents that ship

The KaiShips Guide to Claude Code covers everything you need to ship production agents -- from local CLI to SDK deployment.

Includes prompt patterns, cost control, MCP integrations, hooks, and the full pipeline we use to run a 24/7 agent that writes blogs, scouts jobs, and posts to Discord.

Get the KaiShips Guide to Claude Code -- $29

System Prompts: Custom or Claude Code Preset

Since v0.1.0, the Agent SDK ships a minimal system prompt by default instead of inheriting Claude Code's CLI-focused instructions. You either pass a custom string or opt into the old preset explicitly.

Custom system prompt (recommended)

# Python
options = ClaudeAgentOptions(
    allowed_tools=["Read", "Edit", "Glob"],
    permission_mode="acceptEdits",
    system_prompt="You are a senior Python developer. Follow PEP 8.",
)

// TypeScript
const options = {
  allowedTools: ["Read", "Edit", "Glob"],
  permissionMode: "acceptEdits",
  systemPrompt: "You are a senior Python developer. Follow PEP 8.",
};

Inherit the Claude Code preset

If you want the same behavior as the Claude Code CLI, pass the preset explicitly:

# Python
options = ClaudeAgentOptions(
    system_prompt={"type": "preset", "preset": "claude_code"},
)

// TypeScript
const options = {
  systemPrompt: { type: "preset", preset: "claude_code" },
};

Hooks: Audit, Validate, Block, Transform

Hooks are callback functions that run at specific points in the agent lifecycle. Use them to log every file edit, block dangerous shell commands, transform tool inputs, or trigger side effects in your application.

Available hooks

  • PreToolUse -- before tool runs
  • PostToolUse -- after tool completes
  • UserPromptSubmit -- when user sends prompt
  • SessionStart -- new session
  • SessionEnd -- session end
  • Stop -- agent finishes turn

Audit-log every file change (Python)

from datetime import datetime
from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher

async def log_change(input_data, tool_use_id, context):
    file_path = input_data.get("tool_input", {}).get("file_path", "unknown")
    with open("./audit.log", "a") as f:
        f.write(f"{datetime.now()}: modified {file_path}\n")
    return {}

async for message in query(
    prompt="Refactor utils.py.",
    options=ClaudeAgentOptions(
        permission_mode="acceptEdits",
        hooks={
            "PostToolUse": [
                HookMatcher(matcher="Edit|Write", hooks=[log_change])
            ]
        },
    ),
):
    pass

The matcher is a regex against the tool name. Multiple matchers can fire for the same hook event, and hooks can return data that modifies or blocks the tool call.

Subagents: Specialized Workers, Parallel Execution

Subagents are scoped Claude instances with their own system prompt and tool list. Your main agent delegates focused subtasks to them via the Agent tool. They run in their own context window, return a result, and keep the main conversation lean.

# Python
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition

async for message in query(
    prompt="Use code-reviewer to audit src/auth/",
    options=ClaudeAgentOptions(
        allowed_tools=["Read", "Glob", "Grep", "Agent"],
        agents={
            "code-reviewer": AgentDefinition(
                description="Security and code quality reviewer.",
                prompt="Look for SQL injection, XSS, secrets in code.",
                tools=["Read", "Glob", "Grep"],
            )
        },
    ),
):
    pass

Isolation

Subagent context never leaks back to main agent.

Specialization

Each subagent gets its own prompt and tool whitelist.

Parallelism

Spawn multiple subagents in one turn for independent work.

MCP Servers: Connect to Anything

The Model Context Protocol (MCP) is an open standard for plugging external tools into agents. The SDK speaks MCP natively, so you can give your agent browser automation, database access, GitHub API, Slack, Linear, and hundreds more servers with a config block.

Browser automation with Playwright MCP

// TypeScript
for await (const message of query({
  prompt: "Open example.com and describe what you see.",
  options: {
    mcpServers: {
      playwright: {
        command: "npx",
        args: ["@playwright/mcp@latest"],
      },
    },
  },
})) {
  if ("result" in message) console.log(message.result);
}

You can also define custom in-process MCP tools by writing a regular Python or TypeScript function and registering it with createSdkMcpServer. Read more in the Claude Code MCP servers guide.

Sessions: Resume, Fork, Persist

By default each query() call is independent. To build chatbots, code review flows, or stateful agents, capture the session ID from the first call's init message and pass it to resume on the next.

// TypeScript
let sessionId: string | undefined;

for await (const message of query({
  prompt: "Read the authentication module",
  options: { allowedTools: ["Read", "Glob"] },
})) {
  if (message.type === "system" && message.subtype === "init") {
    sessionId = message.session_id;
  }
}

for await (const message of query({
  prompt: "Now find all places that call it",
  options: { resume: sessionId },
})) {
  if ("result" in message) console.log(message.result);
}

Sessions can also be forked to explore alternate paths -- useful for "what if" tooling and A/B agent experiments.

Migrating from Claude Code SDK

The Claude Code SDK was renamed to the Claude Agent SDK in v0.1.0. Most apps migrate in five minutes. There are three breaking changes worth flagging.

Package + import renames

OldNew
@anthropic-ai/claude-code@anthropic-ai/claude-agent-sdk
claude-code-sdk (pip)claude-agent-sdk (pip)
ClaudeCodeOptionsClaudeAgentOptions
BREAKING #1

Default system prompt is gone

Old SDK injected Claude Code's CLI prompt automatically. New SDK uses a minimal prompt. To restore old behavior, pass { type: "preset", preset: "claude_code" } as systemPrompt.

BREAKING #2

settingSources behavior shifted

v0.1.0 stopped loading CLAUDE.md, settings.json, and slash commands by default. Recent releases reverted to the old default for query(). Pass settingSources: [] to opt into isolation. Python SDK 0.1.59 and earlier treated empty list as "load default" -- upgrade first.

BREAKING #3

Opus 4.7 needs SDK v0.2.111+

Claude Opus 4.7 replaced thinking.type.enabled with thinking.type.adaptive. Older SDK versions throw a 400 invalid_request_error when you select claude-opus-4-7. Upgrade to v0.2.111 or later.

Pricing: SDK Free, Tokens Pay-As-You-Go

The Claude Agent SDK itself is free and open source. You pay only for Claude API tokens. According to Anthropic, a typical agent run analyzing a medium codebase costs between $0.05 and $0.50 depending on the model. Pick the model that matches your task, not the most powerful one available.

ModelInput ($/MTok)Output ($/MTok)Best for
Claude Opus 4.7$15.00$75.00Complex reasoning, multi-file refactors
Claude Sonnet 4.6$3.00$15.00Default daily driver, most workloads
Claude Haiku 4.5$0.25$1.25High-volume background jobs, classification

Enable prompt caching to drop per-call costs by 50-80% on long-running agents -- cached tokens cost 10% of the standard rate. See the Claude Code pricing guide for the full token-cost breakdown.

Production Patterns I Use Every Day

The SDK is a toolkit. These five patterns cover most production deployments and keep agents predictable, observable, and cheap.

1

Lock the tool whitelist

Pair permissionMode: "dontAsk" with an explicit allowedTools list. Anything not in the list is denied. This is the safest default for headless agents.

2

Audit log every write

Wire a PostToolUse hook with matcher "Edit|Write|Bash" that appends to a structured log. You will thank yourself the first time an agent does something weird in production.

3

Set a hard turn limit

Pass maxTurns: 25 (or whatever fits your task). Agents stuck in tool loops are the #1 cost blowout source.

4

Subagents over giant prompts

When the main agent's instructions exceed two screens, split into specialized subagents (planner, executor, reviewer). Smaller context windows produce better results.

5

Stream messages to the UI

The async iterator gives you AssistantMessage, ToolUseBlock, and ResultMessage events. Forward them to your frontend over Server-Sent Events for a Claude-Code-style live log.

Build agents that ship

The KaiShips Guide to Claude Code covers everything you need to ship production agents -- from local CLI to SDK deployment.

Includes prompt patterns, cost control, MCP integrations, hooks, and the full pipeline we use to run a 24/7 agent that writes blogs, scouts jobs, and posts to Discord.

Get the KaiShips Guide to Claude Code -- $29

Frequently Asked Questions

What is the Claude Agent SDK?

The Claude Agent SDK is Anthropic's Python and TypeScript library for building autonomous AI agents. It exposes the same agent loop, built-in tools, and context management that power Claude Code, so you can embed Claude into your own applications, CI pipelines, or custom workflows. It was renamed from the Claude Code SDK in late 2025.

Is the Claude Agent SDK the same as the Claude Code SDK?

Yes. The Claude Code SDK was renamed to the Claude Agent SDK in v0.1.0. The TypeScript package moved from @anthropic-ai/claude-code to @anthropic-ai/claude-agent-sdk and the Python package moved from claude-code-sdk to claude-agent-sdk. ClaudeCodeOptions was renamed to ClaudeAgentOptions.

How much does the Claude Agent SDK cost?

The SDK itself is free and open source. You pay only for Claude API tokens consumed by your agent. According to Anthropic, a typical agent run analyzing a medium codebase costs between $0.05 and $0.50 depending on the model. Use Sonnet 4.6 ($3 / $15 per MTok) for most workloads and Haiku 4.5 ($0.25 / $1.25) for cheap background tasks.

What is the difference between the Agent SDK and the Anthropic Client SDK?

The Anthropic Client SDK gives you raw API access -- you implement the tool execution loop yourself. The Agent SDK gives you Claude with built-in tool execution: file reads, edits, bash, web search, and MCP all work out of the box. You write a prompt and consume an async stream of messages.

Which permission mode should I use in production?

For locked-down headless agents, use 'dontAsk' which denies anything not in allowedTools. For trusted CI pipelines, use 'bypassPermissions'. For production apps with custom approval flows, use 'default' with a canUseTool callback. The 'auto' mode (TypeScript only) uses a model classifier to approve each tool call, which is good for autonomous agents that still need safety guardrails.

Can I use the Claude Agent SDK with AWS Bedrock or Google Vertex AI?

Yes. Set CLAUDE_CODE_USE_BEDROCK=1 for Amazon Bedrock, CLAUDE_CODE_USE_VERTEX=1 for Google Vertex AI, or CLAUDE_CODE_USE_FOUNDRY=1 for Microsoft Azure AI Foundry, then configure the underlying cloud credentials. The SDK routes through the same agent loop regardless of provider.

Bottom Line

The Claude Agent SDK collapses agent development from a multi-week project into an afternoon. You get the same agent loop that powers Claude Code, the same built-in tools, and the same MCP plumbing -- as a programmable library you can drop into any Python or TypeScript app.

Start with the bug-fixing agent above, swap in your own prompt, and add tools as you need them. The SDK is free; you only pay for tokens. Pair Sonnet 4.6 with prompt caching and most production agents run for cents per task.

Related reading on KaiShips: MCP servers guide, subagents tutorial, hooks guide, and pricing guide.

Build agents that ship

The KaiShips Guide to Claude Code covers everything you need to ship production agents -- from local CLI to SDK deployment.

Includes prompt patterns, cost control, MCP integrations, hooks, and the full pipeline we use to run a 24/7 agent that writes blogs, scouts jobs, and posts to Discord.

Get the KaiShips Guide to Claude Code -- $29