The Claude Agent SDK exposes the same agent loop Claude Code runs: tools, file operations, permissions, compaction, sessions, subagents, skills, and MCP. Install @anthropic-ai/claude-agent-sdk for TypeScript or claude-agent-sdk for Python, authenticate with an API key, and call query(). Use the CLI with -p when you are automating a task; use the SDK when a program needs structured events as they happen.
- It is the Claude Code loop as a library, not a thin API wrapper.
- Packages:
@anthropic-ai/claude-agent-sdkandclaude-agent-sdk. Python and TypeScript only. - Both packages bundle a Claude Code binary, so most installs need nothing else.
maxBudgetUsdis a hard client-side stop. Set it before the first run.- It reads your
.claude/config by default.settingSources: []turns that off.
What it saves you writing
The raw Messages API against the Agent SDK.
| You need | Raw API | Agent SDK |
|---|---|---|
| The agent loop | You write it | Built in |
| File read, write, edit tools | You write them | Built in |
| Command execution | You write it | Built in |
| Permission handling | You design it | Built in, configurable |
| Context compaction | You implement it | Built in |
| Session persistence, resume, fork | You build it | Built in |
| Subagents | You orchestrate them | Built in |
| Skills and slash commands | Not applicable | Loaded from .claude/ |
| MCP servers | You wire them | Built in |
Installing it and running one agent
Prerequisites are Node.js 18 or later, or Python 3.10 or later.
# TypeScript
npm install @anthropic-ai/claude-agent-sdk
npm install --save-dev tsx
# Python, with uv
uv add claude-agent-sdk
# Python, with pip
pip install claude-agent-sdk
# then, in the shell that runs your agent
export ANTHROPIC_API_KEY=your-api-key
import { query } from "@anthropic-ai/claude-agent-sdk";
const result = query({
prompt: "Review src/auth/session.ts for security defects. Report only "
+ "issues with a concrete exploit path.",
options: {
cwd: "/Users/you/code/project",
model: "claude-opus-5",
// Capability is the control. An instruction is not.
allowedTools: ["Read", "Grep", "Glob"],
permissionMode: "default",
// Two independent stops.
maxTurns: 12,
maxBudgetUsd: 2,
},
});
for await (const message of result) {
if (message.type === "assistant") {
for (const block of message.message.content) {
if (block.type === "text") process.stdout.write(block.text);
}
}
if (message.type === "result") {
console.error(
`\ncost $${message.total_cost_usd} in ${message.num_turns} turns`,
);
}
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, ResultMessage
async def main():
async for message in query(
prompt="Review src/auth/session.py for security defects.",
options=ClaudeAgentOptions(
cwd="/Users/you/code/project",
model="claude-opus-5",
allowed_tools=["Read", "Grep", "Glob"],
permission_mode="default",
max_turns=12,
),
):
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())
The options that actually matter
The TypeScript option surface is large. These are the ones that change whether your agent is safe, bounded, and reproducible.
TypeScript names; Python uses the snake_case equivalents.
| Option | Why it matters |
|---|---|
allowedTools | The real security boundary. Auto-approves; does not restrict Claude to only these |
disallowedTools | Actually removes a tool. A bare name drops it from context entirely |
maxTurns | Bounds a loop that cannot make progress |
maxBudgetUsd | Stops the query at a client-side cost estimate. The one people wish they had set |
cwd | Scopes the filesystem. Set it deliberately, never inherit it |
settingSources | Which filesystem settings load. [] disables user, project, and local |
strictMcpConfig | Use only the servers you passed; ignore .mcp.json and user settings |
systemPrompt | A string replaces the default; the preset form appends to Claude Code own |
effort | Reasoning depth, from low to max, on models that support it |
permissionMode and canUseTool | How approvals are handled, and your own callback when one is needed |
outputFormat | A JSON schema for the agent result, when a program consumes it |
Sessions, and why they are the reason to use this
A single query() is easy to build yourself. What is not easy is everything that happens when a task spans more than one call: persisting the transcript, resuming it on a different machine, forking it so two branches share a prefix, and compacting it when it outgrows the window. The SDK gives you all four as options rather than as a subsystem you own.
| Option | What it buys |
|---|---|
sessionId | Supply your own UUID instead of generating one, so your database owns the key |
resume | Continue a stored session by id |
resumeSessionAt | Resume at a specific message, discarding what came after |
forkSession | Resume into a new session id, leaving the original intact |
persistSession: false | Run without writing a transcript to disk at all |
sessionStore | Mirror transcripts to your own backend, so any host can resume them |
enableFileCheckpointing | Track file changes so a run can be rewound |
Streaming or collecting
The example above streams, because query() returns an async iterator and each iteration yields the next event: reasoning, a tool call, a tool result, or the final outcome. That is what you want behind a user interface, where minutes of silence is not an acceptable loading state.
For a background job or a CI step there is nothing to show, so collect the messages and read the result at the end. The trade is only about who is watching, not about capability, and the same code shape works either way.
SDK, CLI, Client SDK, or Managed Agents
Four Anthropic surfaces that all sound like each other.
| If you are | Use | Because |
|---|---|---|
| Building an agent without writing the tool loop | Agent SDK | The loop runs in your own process |
| Automating a task in CI or a script | Claude Code CLI with -p | One dependency lighter and easier to reason about |
| Calling the API and writing the loop yourself | Client SDK | Direct Messages API access, maximum control |
| Running long agents without managing a sandbox | Managed Agents | Anthropic runs the loop and hosts the container |
| Working in Go, Rust, Ruby, or anything else | CLI as a subprocess | The SDK is Python and TypeScript only |
Four things that surprise people
- It reads your project files.
CLAUDE.md,.claude/settings.json, skills, and configured MCP servers all load based oncwd. Convenient in development, surprising in production, and occasionally a real leak. PasssettingSources: []andstrictMcpConfig: truewhen you want a hermetic agent. - Cost is per session, not per call. The loop makes many model calls.
total_cost_usdon the result message is the number that matters, andmaxBudgetUsdis the only thing that stops it climbing while nobody is looking. - You cannot resell claude.ai login. Unless previously approved, Anthropic does not permit third-party developers to offer claude.ai login or subscription rate limits in their products, including agents built on this SDK. Ship API-key authentication, or your own billing on top of it.
- Branding is constrained. "Claude Agent" and "Powered by Claude" are permitted. "Claude Code", "Claude Code Agent", and Claude Code ASCII art are not. Your product should not look like it is Claude Code.
Questions people ask
A library that exposes the same agent loop Claude Code runs: tool use, file operations, permission handling, context compaction, sessions, subagents, skills, and MCP. It is available for Python and TypeScript, and runs the loop in your own process.
@anthropic-ai/claude-agent-sdk on npm and claude-agent-sdk on PyPI. Prerequisites are Node.js 18 or later, or Python 3.10 or later. Both packages bundle a native Claude Code binary, so a separate CLI install is usually unnecessary.
The Messages API gives you one model call. The Agent SDK gives you the loop around it, plus the tools, permissions, sessions, and compaction that make an agent work across a long task. If you want to write that loop yourself, use the Client SDK instead.
The CLI with -p for automation and scripts. The SDK when a program needs structured events as they happen, such as streaming into a user interface. In any language other than Python or TypeScript, run the CLI as a subprocess with --output-format json.
No. Authenticate with an API key, or with Amazon Bedrock, Google Cloud, Microsoft Foundry, or Claude Platform on AWS credentials. Anthropic does not permit third-party developers to offer claude.ai login or subscription rate limits in their products without prior approval.
Set both maxTurns and maxBudgetUsd. Turns bound a loop that cannot make progress; the budget bounds a loop that can, expensively. Without either, an agent keeps trying until something else intervenes.
Yes, along with .claude/settings.json, skills, and configured MCP servers, based on cwd. Pass settingSources: [] to disable user, project, and local settings, and strictMcpConfig: true to ignore .mcp.json, when you need a hermetic agent.
No. It auto-approves the listed tools without prompting; it does not remove the others. To actually deny a tool, use disallowedTools, where a bare name drops the tool from context entirely.
Sources
Every figure above was read from these pages on August 2026. Vendors reprice without notice; if you find a stale number, tell us.