The Claude Agent SDK is a Python and TypeScript library that gives your application the same agent loop, built-in tools and context management that power Claude Code. This guide shows when to use it, how to build a first agent, how to add tools and permissions, and how to host it in production.
- The Agent SDK runs Claude Code's agent loop inside your app: file, shell and web tools, hooks, subagents, MCP, sessions and permissions come built in.
- Install with
pip install claude-agent-sdkornpm install @anthropic-ai/claude-agent-sdk, and authenticate with an API key or a cloud provider. - Add your own functions as tools with
@tool(Python) ortool()(TypeScript) wrapped in an in-process MCP server. - Lock agents down with
allowed_tools, deny rules and a permission mode such asdontAsk; setmax_turnsbecause sessions have no timeout. - Each session is a long-lived subprocess with local state, so plan containers, session storage and per-tenant isolation before you ship.
What is the Claude Agent SDK?
The Claude Agent SDK is Anthropic's library for building agents in Python or TypeScript on top of Claude Code's engine. It gives your code the same agent loop, built-in tools (read, write and edit files, run shell commands, search the web) and context management that Claude Code uses, so you write the task and the guardrails instead of the plumbing (Agent SDK overview).
Under the hood, the SDK starts a claude CLI subprocess and talks to it over stdio. That detail explains most of how the SDK behaves: each session has a working directory, a shell and transcript files on disk, and it loads CLAUDE.md, skills and settings the way Claude Code does.
Built-in capabilities you get without writing them:
- Tools: file read, write and edit, glob and grep search, Bash, web search and fetch.
- Hooks: your code runs at points in the agent lifecycle, for example before a tool call.
- Subagents: specialized agents for focused subtasks.
- MCP: connect external tools and data sources, or define your own tools in-process.
- Permissions: decide which tools run automatically and which need approval.
- Sessions: keep context across turns, resume or fork later.
If you are new to agents, the core idea is a loop: the model plans, acts with a tool, observes the result and repeats until the task is done. The SDK runs that loop for you.
When should you use the Agent SDK instead of other Claude tools?
Use the Agent SDK when you want an agent that works on files and commands inside your own application or service. Anthropic offers four ways to build with Claude, and they differ in who runs the loop and what comes built in.
| You want to | Use | What you get |
|---|---|---|
| Embed an agent with tools in your own Python or TypeScript app | Agent SDK | Claude Code's loop, tools, permissions, sessions and hooks as a library |
| Work interactively or script one-off tasks | Claude Code CLI (claude, claude -p) | The terminal agent; headless mode for scripts and CI |
| Call the model directly and control every request | Client SDK (Claude API) | Raw API access; you write the tool loop yourself |
| Have Anthropic host the agent loop | Managed Agents | Anthropic runs the loop; tools run in cloud or self-hosted sandboxes |
A quick rule of thumb:
- If a shell script with
claude -pdoes the job, start there. It shares the same engine (headless docs). - If you need typed messages, approval callbacks, custom tools in your own process or a web UI around the agent, use the Agent SDK.
- If your app needs a chat completion or a single tool call, not a multi-step agent, the plain Client SDK is simpler. Our Claude API tutorial covers it, and our guide to building an AI agent in Python shows how to write the loop yourself.
For a comparison with LangGraph, CrewAI, the OpenAI Agents SDK and others, see AI agent frameworks.
How do you install and authenticate the Agent SDK?
Install the package for your language, set an API key, and you are ready. You need Python 3.10+ or Node.js 18+; both SDKs bundle a native Claude Code binary for most platforms, so you don't install the CLI separately (quickstart).
Create a project folder. The agent can read files in that directory and its subdirectories by default.
Install the SDK.
Python pip install claude-agent-sdkTypeScript npm init -y && npm pkg set type=modulenpm install @anthropic-ai/claude-agent-sdknpm install --save-dev tsxSet your API key from the Claude Console. The SDK reads it from the process environment and does not load
.envfiles on its own.terminal export ANTHROPIC_API_KEY=your-api-keyOr use a cloud provider. Set
CLAUDE_CODE_USE_BEDROCK=1(Amazon Bedrock),CLAUDE_CODE_USE_VERTEX=1(Google Cloud) orCLAUDE_CODE_USE_FOUNDRY=1(Microsoft Foundry) and configure that provider's credentials.
Anthropic does not allow third-party developers to offer claude.ai login or subscription rate limits in their products, including agents built on the Agent SDK, unless previously approved. Anything you ship to users should authenticate with an API key or a cloud provider.
How do you build your first agent with the Claude Agent SDK?
A first agent is one call to query() with a prompt and options. query() returns an async iterator that streams messages as Claude thinks, calls tools and finishes, ending with a result message.
This Python agent reviews a file for crash bugs and fixes them. It pre-approves three tools and auto-accepts file edits:
import asynciofrom claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, ResultMessageasync def main(): async for message in query( prompt="Review utils.py for bugs that would cause crashes. Fix any issues you find.", options=ClaudeAgentOptions( allowed_tools=["Read", "Edit", "Glob"], permission_mode="acceptEdits", max_turns=20, ), ): if isinstance(message, AssistantMessage): for block in message.content: if hasattr(block, "text"): print(block.text) elif hasattr(block, "name"): print(f"Tool: {block.name}") elif isinstance(message, ResultMessage): print(f"Done: {message.subtype}")asyncio.run(main())The TypeScript version has the same shape:
import { query } from "@anthropic-ai/claude-agent-sdk";for await (const message of query({ prompt: "Review utils.py for bugs that would cause crashes. Fix any issues you find.", options: { allowedTools: ["Read", "Edit", "Glob"], permissionMode: "acceptEdits", maxTurns: 20, },})) { if (message.type === "assistant" && message.message?.content) { for (const block of message.message.content) { if ("text" in block) console.log(block.text); else if ("name" in block) console.log(`Tool: ${block.name}`); } } else if (message.type === "result") { console.log(`Done: ${message.subtype}`); }}Run it with python agent.py or npx tsx agent.ts. A successful run ends with Done: success. If the agent hits the turn limit, the result subtype is error_max_turns and query() raises after yielding it, so wrap the loop in try when the process must exit cleanly.
Change behavior through options, not code:
| Option (Python / TypeScript) | Use it to |
|---|---|
allowed_tools / allowedTools | Pre-approve tools, for example ["Read", "Grep", "Bash"] |
disallowed_tools / disallowedTools | Remove a tool ("Bash") or block patterns ("Bash(rm *)") |
tools | Limit which built-in tools exist at all; [] leaves only your MCP tools |
permission_mode / permissionMode | Set the baseline: default, acceptEdits, plan, dontAsk, auto, bypassPermissions |
system_prompt / systemPrompt | Add role and rules for the agent |
max_turns / maxTurns | Bound how many tool-use round trips the agent may take |
cwd | Run the session in a specific working directory |
mcp_servers / mcpServers | Attach external or in-process MCP servers |
How do you give an Agent SDK agent custom tools?
You define custom tools as functions and register them through an in-process MCP server. Each tool has a name, a description Claude reads to decide when to call it, an input schema and an async handler (custom tools docs).
This example gives an agent a read-only tool that looks up an order in your own system:
import asynciofrom typing import Annotated, Anyfrom claude_agent_sdk import ( tool, create_sdk_mcp_server, query, ClaudeAgentOptions, ResultMessage, ToolAnnotations,)@tool( "get_order", "Look up an order by ID and return its status, items and total", {"order_id": Annotated[str, "Order ID such as ord_123"]}, annotations=ToolAnnotations(readOnlyHint=True),)async def get_order(args: dict[str, Any]) -> dict[str, Any]: order = await fetch_order_from_db(args["order_id"]) # your own function if order is None: return {"content": [{"type": "text", "text": "No order with that ID."}], "is_error": True} return {"content": [{"type": "text", "text": str(order)}]}orders = create_sdk_mcp_server(name="orders", version="1.0.0", tools=[get_order])async def main(): options = ClaudeAgentOptions( mcp_servers={"orders": orders}, allowed_tools=["mcp__orders__get_order"], tools=[], permission_mode="dontAsk", ) async for message in query(prompt="Why is order ord_123 delayed?", options=options): if isinstance(message, ResultMessage) and message.subtype == "success": print(message.result)asyncio.run(main())Details that matter:
- Tool names in permission rules follow
mcp__{server}__{tool}, so this tool ismcp__orders__get_order. tools=[]removes every built-in tool, so this support agent can't touch files or run shell commands.- Returning
is_error: Truelets you write the error message Claude sees. An uncaught exception is also turned into an error result, but with the raw message. readOnlyHintlets Claude call the tool in parallel with other read-only tools. Annotations are hints; the handler decides what really happens.- In TypeScript, use
tool()with a Zod schema andcreateSdkMcpServer().
Tool search is on by default, so Claude sees tool names in a compact list and loads full schemas on demand. That keeps dozens of tools from filling the context window. To connect existing servers instead of writing your own, see what MCP is.
How do permissions work in the Claude Agent SDK?
The SDK checks every tool request in a fixed order: hooks, deny rules, ask rules, the permission mode, allow rules, and finally your canUseTool callback (permissions docs). The first step that decides wins, and deny rules apply even in bypassPermissions mode.
| Mode | Behavior | Good for |
|---|---|---|
default | Calls that need approval go to canUseTool; without one, they are denied | Apps with an approval UI |
dontAsk | Anything not pre-approved is denied; canUseTool is never called | Headless agents with a fixed tool surface |
acceptEdits | File edits and filesystem commands inside the working directory are auto-approved | Coding agents in an isolated directory |
plan | Claude explores and plans without editing source files | Review and proposal steps |
auto | A classifier model reviews actions such as shell commands | Fewer prompts with a safety check |
bypassPermissions | Everything runs except a few protected actions | Disposable sandboxes only |
Three behaviors catch people out:
allowed_toolsdoes not restrictbypassPermissions. In bypass mode every tool is approved, listed or not. Block tools withdisallowed_toolsinstead.- Auto-approved calls never reach
canUseTool. If a tool is allowed by a rule or the mode, checks in your callback are skipped. Put checks that must always run in aPreToolUsehook. - Subagents inherit the parent's mode. A parent in
bypassPermissionsgives its subagents full access too.
For a locked-down agent, pair a short allowed_tools list with permission_mode="dontAsk". For coding agents, prefer scoped rules such as Bash(npm test *) over a bare Bash. The same rule syntax is used by Claude Code hooks and settings files.
How do you deploy a Claude Agent SDK agent to production?
Deploy each agent session as a long-lived process with its own working directory, ideally in a sandboxed container. Hosting an agent is closer to hosting a small dev machine than a stateless API, because the subprocess keeps a shell, files and transcripts on local disk (hosting docs).
Pick a session pattern first:
| Pattern | How it works | Example workloads |
|---|---|---|
| Ephemeral | One container per task, destroyed when done | Bug fix, document extraction, translation |
| Long-running | Persistent containers holding many sessions | Email triage, Slack bot, per-user site builder |
| Hybrid | Containers spin down when idle and restore from a SessionStore | Research that pauses, support with history |
| Multi-agent container | Several SDK processes in one container | Agents that collaborate in a shared environment |
Production checklist from Anthropic's hosting guide:
- Resources: start at 1 GiB RAM, 5 GiB disk and 1 CPU per agent, then measure peak memory for your real session lengths.
- Persistence: local transcripts disappear on restart. Configure a
SessionStoreadapter for sessions users expect to resume, and store working-directory files separately. - Time limits: sessions have no top-level timeout. Set
max_turns, and cap subagents with their ownmaxTurns. - Network: allow outbound HTTPS to
api.anthropic.com(or your cloud provider) and route other egress through a proxy with a domain allowlist. - Secrets: supply
ANTHROPIC_API_KEYfrom a secret manager, and inject tool credentials at a proxy rather than putting them in the agent's environment. - Multi-tenant isolation: pass
setting_sources=[], setCLAUDE_CODE_DISABLE_AUTO_MEMORY=1, use a per-tenantCLAUDE_CONFIG_DIRand a per-tenantcwd, so one customer's files and memory never reach another's session. - Observability: the SDK reads OpenTelemetry settings from the environment (
CLAUDE_CODE_ENABLE_TELEMETRY=1plus standardOTEL_*variables). Prompt text and tool inputs are excluded from exports by default. - Cost: Anthropic estimates a minimal container at roughly $0.05 an hour, while one long session can spend dollars in tokens. Track tokens per session, not servers.
The SDK version pins the bundled CLI version, so updating the SDK is how you update the engine. Take patch releases and read the changelog before a minor upgrade.
If what you need is Claude Code itself working unattended on your repositories, not a custom product, you may not need the SDK at all. A server running Claude Code headless or a hosted box such as Orkio, which keeps Claude Code agents running on an always-on cloud server and opens pull requests for review, covers that case.
Next steps: ship a small agent this week
Start narrow, measure, then widen what the agent can do.
- Pick one repetitive task with a clear output, such as triaging new issues or fixing lint errors in a directory.
- Build it with
query(), a three-toolallowed_toolslist,permission_mode="dontAsk"oracceptEdits, andmax_turns. - Move any domain logic the agent needs into one or two custom tools with clear error messages and accurate annotations.
- Add a
PreToolUsehook for any rule that must hold on every call, such as never touchingmigrations/. - Run it in a container with its own working directory and log every result message, including cost.
- Review twenty runs by hand before you remove a human from the loop. Our guide to Claude Code subagents is the next step once one agent works and you want to split the work.
Frequently asked questions
Is the Claude Agent SDK the same as the Claude Code SDK?
Yes, in the sense that the Agent SDK is the renamed and expanded successor of the Claude Code SDK packages. Anthropic publishes a migration guide for moving from the old package names to claude-agent-sdk and @anthropic-ai/claude-agent-sdk.
Can I use my Claude Pro or Max subscription with the Agent SDK?
Anthropic's quickstart authenticates the SDK with an API key from the Claude Console or with a cloud provider such as Amazon Bedrock. Anthropic also does not allow third-party developers to offer claude.ai login or subscription rate limits in their products without prior approval, so anything you ship to others should use API key or cloud provider authentication.
How much does the Claude Agent SDK cost?
The SDK itself is free to install; you pay for model tokens through your API account or cloud provider. Anthropic's hosting docs note that token cost typically outweighs container cost by an order of magnitude or more, so track cost per session from the result messages.
Which languages does the Claude Agent SDK support?
There are official SDKs for Python 3.10+ and TypeScript on Node.js 18+. From any other language you can run the Claude Code CLI as a subprocess with claude -p and --output-format json to drive the same agent loop.
What is the difference between the Agent SDK and Managed Agents?
With the Agent SDK you run the agent loop in a process you operate, on your own servers or containers. With Managed Agents, Anthropic hosts the agent loop and you interact with it through the Claude API, with tools running in an Anthropic-managed or self-hosted sandbox.



