The Claude Agent SDK: Building Agents Programmatically
The Claude Agent SDK exposes the same agentic engine that powers Claude Code as a Python and TypeScript library. Learn the core query() API, how it relates to Claude Code, and how to build production agents with full control over tools, hooks, and MCP servers.
Learning objectives
- Understand what the Claude Agent SDK is and how it differs from the Client SDK
- Learn the core query() API shape in both Python and TypeScript
- Build a minimal agent that reads, edits, and verifies code autonomously
- Understand how permissions, hooks, MCP servers, and subagents work in the SDK
- Know when to use the SDK vs. Claude Code CLI vs. the Client SDK
ToolDix original visual
Frame
Name the outcome and constraints.
Build
Try one bounded workflow.
Review
Keep evidence, revise, and share.
What the Agent SDK is
The Claude Agent SDK is a Python and TypeScript library that exposes the same agentic engine that powers Claude Code. Instead of interacting with Claude Code via the CLI, you use the SDK to build agents programmatically and embed them in applications, scripts, CI/CD pipelines, or production services.
The SDK includes:
- Built-in tools (Read, Write, Edit, Bash, Glob, Grep, WebSearch, WebFetch, Monitor)
- The agentic loop (plan → act → observe, repeated until done)
- Permissions and hooks (fine-grained control over what the agent can do)
- MCP servers (connectors to databases, APIs, browsers)
- Subagents (delegation to specialized workers)
- Sessions and persistence (context maintained across turns or resumed later)
You do not need to implement the tool loop yourself. The SDK handles it. You provide the prompt, tools, and policy, and the SDK runs the agent.
SDK vs. CLI vs. Client SDK
| Tool | Interface | Autonomy | Best for | Complexity |
|---|---|---|---|---|
| Claude Code CLI | Interactive terminal | Claude decides actions; you approve/redirect | Interactive development; one-off tasks | Low |
| Agent SDK | Python or TypeScript library | Claude autonomous; you set policy upfront | CI/CD pipelines; production agents; custom apps | Medium |
| Anthropic Client SDK | Direct API access | You implement the loop | Fine-grained control; custom tool execution | High |
Quick rule:
- Use Claude Code CLI when you're developing interactively
- Use Agent SDK when you want to run agents unattended in production (CI, scripts, servers)
- Use Client SDK when you need total control over the agent loop or custom tool execution
The core query() API shape
The SDK provides one main entry point: query(). It returns an async iterator of messages as Claude works.
Python API
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="Find and fix the bug in auth.py",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Edit", "Bash"],
permission_mode="acceptEdits"
),
):
print(message)
asyncio.run(main())
The query() function is async and returns an async iterator. Each iteration yields a message as Claude thinks, calls tools, or reports results.
TypeScript API
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Find and fix the bug in auth.ts",
options: {
allowedTools: ["Read", "Edit", "Bash"],
permissionMode: "acceptEdits"
}
})) {
console.log(message);
}
Same shape: async iterator, each message is a step in the agent's work.
ClaudeAgentOptions schema
The options object controls agent behavior. All fields are optional; defaults are sensible:
| Field | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| allowed_tools (Python) allowedTools (TS) | string[] | All tools | Array of tool names to auto-approve (e.g., ["Read", "Bash"]). Unlisted tools fall through to permission mode. |
| disallowed_tools (Python) disallowedTools (TS) | string[] | None | Tools to block entirely. MCP patterns supported (e.g., "mcp__*" blocks all MCP tools). |
| permission_mode (Python) permissionMode (TS) | string | "default" | How to handle permission prompts: "acceptEdits", "plan", "dontAsk", "auto", "bypassPermissions", or "default" (requires callback). |
| system_prompt (Python) systemPrompt (TS) | string | None | Custom system prompt prepended to Claude's instructions. |
| mcp_servers (Python) mcpServers (TS) | object[] | None | MCP server configurations (e.g., {"playwright": {"command": "npx", "args": ["@playwright/mcp@latest"]}}) |
| agents (Python) agents (TS) | object | None | Subagent definitions; see SDK subagents guide. |
| skills (Python) skills (TS) | string[] or "all" | Discovered | Which skills to enable (from .claude/skills/). |
| resume (Python) resume (TS) | string | None | Session ID to resume (for multi-turn or continuation). |
| cwd (Python) cwd (TS) | string | Current dir | Working directory for the agent. |
| max_turns (Python) maxTurns (TS) | number | No limit | Max turns before stopping. |
| effort (Python) effort (TS) | string | "medium" | Reasoning effort: "low", "medium", "high", "xhigh", "max", or a number. |
The most important fields: allowed_tools, permission_mode, and optionally system_prompt and mcp_servers.
Production deployment patterns
Pattern 1: CI/CD pipeline
#!/bin/bash
python agent.py \
--prompt "Run tests and report failures" \
--allowed-tools Bash,Read,Grep \
--permission-mode acceptEdits
The agent runs autonomously without interactive prompts.
Pattern 2: Webhook responder
from fastapi import FastAPI, WebhookPayload
from claude_agent_sdk import query, ClaudeAgentOptions
app = FastAPI()
@app.post("/fix-issue")
async def fix_github_issue(payload: WebhookPayload):
async for message in query(
prompt=f"Fix GitHub issue {payload.issue_id}",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Edit", "Bash", "Agent"],
permission_mode="acceptEdits",
max_turns=20
),
):
pass # Run silently, report results at the end
return {"status": "fixed"}
Pattern 3: Background job
import asyncio
from agent import run_codebase_audit
# Dispatch in background; user gets a result URL
asyncio.create_task(run_codebase_audit())
The agent runs without blocking the request.
Common mistake
Treating the Agent SDK as a direct replacement for Claude Code CLI. The SDK is powerful but requires you to handle edge cases, error recovery, and timeout logic yourself. For interactive work, the CLI is simpler. For production automation, the SDK is the right choice.
Also, confusing the Agent SDK with the Client SDK (Anthropic's low-level message API). The Client SDK requires you to implement the tool loop and handle all orchestration. The Agent SDK does this for you, making production agents much simpler to build.
Sources and license context
These references informed the lesson. ToolDix adds its own explanation, workflow, and practice rather than reproducing source material. Every link below leaves ToolDix and opens the publisher's own site in a new tab.
- Agent SDK overview (opens code.claude.com in a new tab)External · code.claude.com (Anthropic terms apply)
- Quickstart (opens code.claude.com in a new tab)External · code.claude.com (Anthropic terms apply)
- Subagents in the SDK (opens code.claude.com in a new tab)External · code.claude.com (Anthropic terms apply)
- Agent Skills in the SDK (opens code.claude.com in a new tab)External · code.claude.com (Anthropic terms apply)
Keep going
Read these next on ToolDix.
Original lessons that build on what you just read.