Most teams that try to build an AI agent from scratch end up rebuilding the same plumbing: a loop that sends a prompt to the model, executes whatever tool calls come back, feeds the results back in, and repeats until the model produces a final answer. The Claude Agent SDK skips that step. It is the same agent loop, tool execution, and context management that powers Claude Code, packaged as a library you can call from Python or TypeScript.
This post is a practitioner's guide, not a marketing overview. It covers the parts that actually matter when you sit down to ship something: how the loop behaves, how to define and restrict tools, when subagents earn their complexity, how permission modes decide what runs without a prompt, and the operational details that separate a demo from a production ops agent.
The Agent Loop, and Why You Don't Write It Yourself
With the raw Anthropic API, you implement the loop: send a message, check if the stop reason is tool use, execute the tool yourself, send the result back, and repeat. The Agent SDK inverts that. You call query with a prompt and a list of allowed tools, and Claude reads files, runs commands, and edits code autonomously, streaming messages back to you as it works.
Under the hood this is the exact harness that ships inside Claude Code: the same built-in tools, the same context management, and the same session model. That matters more than it sounds, because it means the agent already knows how to decide when to stop, when to ask a clarifying question, and when a task is actually done, instead of you hand-rolling termination heuristics.
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Find and fix the failing test in payments.ts",
options: {
allowedTools: ["Read", "Edit", "Bash", "Grep"],
},
})) {
if ("result" in message) console.log(message.result);
}The example below is close to the smallest useful agent you can write. It grants Read, Edit, Bash, and Grep, then lets the model figure out the rest: find the failing test, understand why it fails, and patch the code.
Start every new agent with a narrow allowed tool list, even during prototyping. It is much easier to notice a missing capability than to notice an agent quietly running commands you never intended to grant.
Tool Definitions: Built-in, Custom, and MCP
The SDK ships with the same built-in tools Claude Code uses day to day, so you rarely write a file-reading or shell-execution tool yourself. The set you will reach for most often in a coding or ops agent includes:
- Read, Write, and Edit for precise file operations without hand-rolled diffing logic
- Bash for running scripts, git operations, and test suites
- Glob and Grep for finding files by pattern and searching file contents with regex
- WebSearch and WebFetch for pulling in current information the model was not trained on
For anything outside that set, the SDK connects to external systems through the Model Context Protocol. Point it at an MCP server for a database, a browser automation tool, or an internal API, and its tools show up in the same tool list as the built-ins, with no separate integration code on your side.
Subagents: Delegating Without Polluting Context
A single long-running agent conversation accumulates everything it has ever done: every file it read, every command it ran, every intermediate result. For a focused bug fix that is fine. For a full codebase review, it means your main agent's context fills up with noise that has nothing to do with the final answer.
const options = {
allowedTools: ["Read", "Grep", "Glob", "Agent"],
agents: {
"code-reviewer": {
description: "Expert code reviewer for quality and security reviews.",
prompt: "Analyze code quality, flag security issues, suggest fixes.",
tools: ["Read", "Grep", "Glob"],
model: "sonnet",
},
"test-runner": {
description: "Runs and analyzes the test suite.",
prompt: "Run tests, report failures, and propose minimal fixes.",
tools: ["Bash", "Read", "Grep"],
},
},
};Subagents solve this by running in a fresh context of their own. The parent agent delegates a subtask, the subagent explores and works in isolation, and only its final summary comes back to the parent. Because each subagent can carry its own system prompt and its own restricted tool list, you can build a read-only code reviewer alongside a test runner that has shell access, and run both concurrently instead of one after another.
When the parent session runs in bypassPermissions or acceptEdits mode, every subagent it spawns inherits that same mode and cannot be locked down individually. A subagent with a looser system prompt than your main agent then gets the same unrestricted access. If you need one subagent tightly sandboxed, keep the parent session in a stricter mode instead of relying on the subagent's own tool list.
Permission Modes: Deciding What Runs Without Asking
Every tool call the agent wants to make passes through a permission check before it executes. Allowed tool lists and deny rules are evaluated first, and whatever is left over falls through to the active permission mode. The four modes you will actually use in practice behave very differently:
| Mode | Behavior | When to use it |
|---|---|---|
| default | No auto-approvals; anything not explicitly allowed triggers your approval callback | Interactive sessions where a human is watching and approving |
| acceptEdits | File edits and filesystem operations are auto-approved; other tools still require normal permission checks | Fast iteration in an isolated working directory you already trust |
| plan | Claude explores and proposes a plan; file edits are never auto-approved, even with a matching allow rule | Code review workflows where changes need human sign-off before they land |
| bypassPermissions | Every tool call is approved automatically with no prompts, aside from explicit deny rules | Fully sandboxed, disposable environments only, never a shared machine |
The mistake worth calling out explicitly: an allowed tool list does not shrink what bypassPermissions can do. Naming only Read in your allow list while the mode is set to bypassPermissions still lets the agent run Bash, Write, and Edit, because the allow list only pre-approves tools, it does not restrict the ones you left out. If you need bypassPermissions but want a specific command blocked, use an explicit deny rule instead of trimming the allow list.
Shipping a Production Ops Agent
The gap between a working prototype and something you would actually run against production infrastructure is mostly about defaults, not features. A short checklist that has saved me from regret more than once:
- Pin the model and the SDK version explicitly rather than tracking latest, so a provider-side update does not silently change agent behavior
- Log every tool call and its result to a durable audit trail, not just to stdout, before the agent touches anything with side effects
- Use deny rules for destructive shell patterns, such as blocking recursive delete on specific paths, rather than trusting the model's judgment alone
- Cap the number of agentic turns for unattended runs, so a confused agent fails loudly instead of looping indefinitely and burning tokens
- Resume sessions instead of restarting from scratch when a run needs a human-approved follow-up, so context from the first pass is not lost
None of this is exotic. It is the same operational discipline you would apply to any automated system that can run commands and edit files unattended, just applied to a system whose next action is chosen by a model instead of a fixed script.
The TypeScript package ships as @anthropic-ai/claude-agent-sdk on npm, and it bundles a native Claude Code binary as an optional dependency, so a fresh install does not require a separate Claude Code installation on the host.
When to Reach for the SDK Instead of the Raw API
The Agent SDK is not the right tool for every integration. It earns its keep specifically when the task benefits from autonomous multi-step tool use:
- Coding agents that need to read, search, and edit a real codebase across many files in one session
- Ops and support agents that chain several tool calls together before producing a useful answer
- Anything you would otherwise prototype as a Claude Code workflow and then need to run headless in CI or as a backend service
If your use case is a single prompt with a single expected response and no tool use, the plain Anthropic client SDK is simpler and has less surface area to secure. Reach for the Agent SDK when the value is in the loop itself, not just the model's output.

