·SDKs & Tooling
How to embed the Claude Code agent loop in your own programs with the Claude Agent SDK — installation, a minimal async example, custom tools via MCP, loop control with tool limits and hooks, and patterns that hold up in production.
Building Autonomous Workflows With the Claude Agent SDK
Claude Code is a great interactive tool, but once you want an agent inside a real product — a CI pipeline that triages failing tests, a support bot that resolves tickets, a research assistant that reads a repo and writes a report — you need the same agent loop available programmatically. That is what the Claude Agent SDK provides: the same tools, agent loop, and context management that power Claude Code, exposed as a library in Python and TypeScript. This guide covers installation, a minimal working example, how to wire in custom tools, how to control the agent loop, and the patterns that hold up in production.
What the Agent SDK is
The Agent SDK gives you, as a library, the capabilities Claude Code offers interactively. It bundles a native Claude Code binary for your platform, so behind the scenes it is running the same battle-tested agent loop — not a re-implementation. That matters because you inherit the tool implementations (Read, Write, Bash, Grep, and friends), the context-management behavior, and the permission model without rebuilding any of it.
The SDK is recommended for CI/CD pipelines, custom applications, and production automation. For interactive development and one-off tasks, the Claude Code CLI itself is the better fit. Think of the SDK as the "embed Claude Code in your own program" path.
It ships in two languages with first-class support:
- Python —
pip install claude-agent-sdk(oruv add claude-agent-sdk) - TypeScript —
npm install @anthropic-ai/claude-agent-sdk
For other languages, the documented approach is to run the Claude Code CLI programmatically using the -p flag with --output-format json, parsing the JSON stream from your language of choice.
Installing and authenticating
Install the Python SDK into a project that uses Python 3.10 or newer:
pip install claude-agent-sdk
Authentication follows Claude Code: the SDK uses your ANTHROPIC_API_KEY environment variable (or the same auth Claude Code uses if you are already logged in). Set the key before running your program:
export ANTHROPIC_API_KEY="sk-ant-..."
You also need the Claude Code CLI available on the machine, because the SDK drives it under the hood. On a fresh CI box, installing the SDK and ensuring the CLI is on the PATH is the setup; on a developer machine that already runs Claude Code, you usually have everything.
A minimal agent
The SDK exposes an async query function that streams messages back at you. Here is the smallest useful program — it asks the agent to list the files in the current directory, allowing the Bash and Glob tools so it can actually do the work:
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="What files are in this directory? Summarize the project structure.",
options=ClaudeAgentOptions(allowed_tools=["Bash", "Glob"]),
):
# Each message is an event in the agent's run: assistant text, tool
# calls, tool results, and a final result. The .result attribute marks
# the final assistant message of the run.
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
A few things worth noticing:
query(...)is an async generator. You iterate over it and react to messages as they arrive. This is the streaming interface — you see tool calls and results in real time, not just the final answer.ClaudeAgentOptionscontrols the run.allowed_toolsis the most important knob: it restricts what the agent may do, the same way permission rules do in interactive Claude Code. Start narrow and widen as you build trust.- The agent loop is implicit. You do not write the "call the model, parse for tool calls, execute them, feed back results" loop yourself — the SDK runs it. Your code reacts to the stream.
The TypeScript equivalent has the same shape: an async iteration over a query() call, with options that include the allowed tools and other settings.
Custom tools and MCP
Real workflows need tools beyond the built-ins. The Agent SDK inherits Claude Code's MCP support, so you can connect any MCP server the same way you would in .mcp.json. Define your server in a config the SDK reads, or pass the server definitions through options, and the agent can call your custom tools with the same tool-use loop.
This is the bridge between the Agent SDK and the broader MCP ecosystem: write a tool once as an MCP server (using @modelcontextprotocol/sdk in TypeScript or the Python MCP SDK), and it becomes available to both interactive Claude Code and any Agent SDK program you build. That portability is the main reason to expose custom capabilities as MCP servers rather than ad-hoc functions.
Controlling the loop
Autonomy is powerful, but in production you usually want guardrails. The Agent SDK gives you several ways to keep the agent on a leash:
- Restrict the tool set. The single most effective control. An agent that can only read and grep cannot mutate state, by construction. Grant write tools only when a task genuinely needs them.
- Set a working directory and permission mode. Just like interactive Claude Code, the SDK respects permission modes. For automated runs, pre-approve exactly the tools and command patterns the task needs so no interactive prompt blocks the run.
- Cap the run. Bound the number of turns or the wall-clock time so a confused agent cannot loop forever. Long-running agents that drift are a real failure mode; a cap turns it into a retryable error instead.
- Use hooks for policy. The SDK supports hooks at lifecycle events, so you can block dangerous tool calls or validate outputs deterministically — the same PreToolUse/PostToolUse model as interactive Claude Code.
- Stream and observe. Because
queryis a generator, you can log every tool call and result to an audit trail as it happens. For any production agent, this observability is not optional — it is the only way to answer "what did the agent do?" after the fact.
A real scenario: PR triage
To make this concrete, here is the shape of a real workflow — triaging a failing CI build. The agent reads the failing test output, looks at the relevant source, and posts a comment summarizing the likely cause.
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def triage(failing_test_log: str, repo_dir: str):
prompt = f"""
A CI build is failing. Here is the test output:
<failing_log>
{failing_test_log}
</failing_log>
Investigate the likely cause: read the failing test, read the source it
exercises, and write a 3-5 sentence summary of the probable root cause and
the file:line where the fix likely belongs. Do not modify any files.
"""
async for message in query(
prompt=prompt,
options=ClaudeAgentOptions(
allowed_tools=["Read", "Grep", "Glob"],
cwd=repo_dir,
),
):
if hasattr(message, "result"):
return message.result
return ""
# In the CI step: read the log, call triage(), post the result as a comment.
The decisions that make this safe in production: the tool set is read-only (Read, Grep, Glob — no Bash, no Write), so the agent literally cannot change anything. The working directory is pinned to the checked-out repo. The output is a bounded summary, not free-form code. This is the pattern: narrow tools, pinned scope, structured output, human in the loop for any actual change.
When to use the SDK vs the CLI vs raw API calls
Three related tools, three different fits:
- Claude Code CLI — interactive development, one-off tasks in a terminal. Best when a human is driving.
- Claude Agent SDK — production automation, custom applications, CI/CD. Best when you want the full agent loop (tools, context management, the works) embedded in your own program.
- Raw Claude API (
anthropicSDK) — when you need direct control over messages, tool use, and the model call itself, and you are willing to build your own agent loop. Best for custom designs that do not match Claude Code's loop.
A useful rule: if your first instinct is "I wish Claude Code could do X automatically," reach for the Agent SDK. If your first instinct is "I want to call the model with this exact set of messages and tools," reach for the raw API.
Production considerations
A few things that matter once an agent runs unattended:
- Idempotency. Agents get retried. Make sure the side effects of your tools are idempotent, or guard them so a retry does not double-apply a change.
- Cost monitoring. Each agent run costs tokens, and agentic runs cost more than single calls. Instrument the token usage and set budget alerts. A runaway agent is also a runaway bill.
- Secrets. Be careful what you expose to the agent through tool results or file reads. An agent with broad read access can surface secrets into its output. Apply the same deny rules you would in interactive Claude Code.
- Determinism boundaries. Agents are non-deterministic. Use them for judgement work (triage, summarization, exploration) and keep deterministic logic in plain code. Do not let an agent decide whether a deploy proceeds — let it gather information for a human or a rule to act on.
- Evaluation. Before shipping, run the agent against a fixed set of inputs and capture the outputs. When you change the prompt, the tools, or the model, re-run and diff. Without this, agent quality drifts invisibly.
Frequently asked questions
What is the Claude Agent SDK and how does it differ from Claude Code?
The Claude Agent SDK exposes the same agent loop, tools, and context management that power Claude Code, as a library in Python and TypeScript. Claude Code is the interactive CLI you run in a terminal; the Agent SDK is what you embed inside your own programs for CI/CD, custom applications, and production automation. Behind the scenes the SDK drives a bundled Claude Code binary, so you inherit the same battle-tested behavior.
How do I install the Claude Agent SDK?
Install the Python SDK with pip install claude-agent-sdk (Python 3.10 or newer) or uv add claude-agent-sdk, and install the TypeScript SDK with npm install @anthropic-ai/claude-agent-sdk. You also need the Claude Code CLI available on the machine and an ANTHROPIC_API_KEY environment variable set. For other languages, run the Claude Code CLI programmatically with the -p flag and --output-format json.
How do I control what tools the agent can use?
Pass an allowed_tools list through ClaudeAgentOptions (or its TypeScript equivalent). Restricting the tool set is the single most effective way to keep an agent safe — an agent that can only Read and Grep cannot mutate state by construction. Grant write or shell tools only when a task genuinely needs them, and combine this with permission modes and hooks for policy.
Should I use the Agent SDK or call the Claude API directly?
Use the Agent SDK when you want the full Claude Code agent loop (tools, context management, the works) embedded in your program without rebuilding it. Use the raw Claude API (the anthropic SDK) when you need direct control over messages and tool use and are willing to build your own agent loop. A rule of thumb: if you wish Claude Code could do something automatically, reach for the Agent SDK; if you want to call the model with an exact set of messages, use the raw API.
Official references
- Claude Agent SDK overview
- Claude Agent SDK — Python (anthropics/claude-agent-sdk-python)
- Claude Code documentation
- Model Context Protocol
- Anthropic engineering blog
This article reflects publicly available information as of July 2026; relevant APIs may evolve.