Claude Agent SDK vs Writing the Agent Loop Yourself (2026): When Each Wins
Should you use the Claude Agent SDK or hand-roll the agent loop with the Anthropic Client SDK? An honest 2026 comparison with runnable TypeScript for both and a decision table.
Updated on July 3, 2026
On this page
The Claude Agent SDK gives you Claude Code's agent loop, built-in tools, permissions, subagents, MCP support, and session memory as a library you call with query(). As of July 2026 the honest answer to "should I use the Claude Agent SDK or write the agent loop myself" is this: use the SDK when you want an agent that reads files, runs commands, and edits code with production plumbing you did not write; hand-roll the loop with the plain Anthropic Client SDK when you need a small, dependency-light loop over your own domain tools and full control of every turn. This post shows both, in TypeScript, with runnable code, and gives you a decision table so you pick on purpose instead of by default.
The two things people mean by "build a Claude agent"
"Build a Claude agent" collapses two very different jobs.
The first is an autonomous coding-style agent: it works against a filesystem, greps a codebase, runs a test suite, edits files, and keeps going until a task is done. That is exactly what Claude Code does, and the Claude Agent SDK exposes the same engine as a library in Python and TypeScript
.
The second is a domain agent: it calls a handful of tools you define (charge a card, look up an order, book a slot) inside your own application, and you want to own every message that goes back and forth. For that you can write the loop yourself against the plain Anthropic Client SDK in about forty lines.
Neither is "better." They optimize for different things. The mistake is reaching for the SDK because it sounds official when you only needed the forty-line loop, or hand-rolling a filesystem coding agent that the SDK already ships.
What the Agent SDK actually gives you
Straight from the Agent SDK overview (2026), here is what you get without writing it:
- Built-in tools:
Read,Write,Edit,Bash,Glob,Grep,WebSearch,WebFetch, andAskUserQuestion. Your agent can touch a filesystem and shell on turn one. - A managed agent loop and context management: the same loop that powers Claude Code, including how it compacts and carries context across turns.
- Permissions:
allowedToolspre-approves safe tools;permissionMode(for exampleacceptEdits) controls when the agent may act without asking. - Hooks:
PreToolUse,PostToolUse,Stop,SessionStart,SessionEnd,UserPromptSubmit, and more, so you can log, validate, or block behavior. - Subagents: define specialized agents with their own tools and prompt, invoked through the
Agenttool. - MCP: connect external systems (databases, browsers, APIs) over the Model Context Protocol through the
mcpServersoption. - Sessions: capture a
session_id, thenresumeor fork it later with full context.
Here is a complete SDK agent that fixes a failing test and runs the suite:
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Find the failing test in this repo, fix the code, then run the suite.",
options: {
allowedTools: ["Read", "Edit", "Bash", "Grep", "Glob"],
permissionMode: "acceptEdits",
},
})) {
if ("result" in message) console.log(message.result);
}
Install it with npm install @anthropic-ai/claude-agent-sdk and set ANTHROPIC_API_KEY. The TypeScript package bundles a native Claude Code binary as an optional dependency, so there is no separate Claude Code install. That is the trade you are making: a lot of capability, and a real runtime dependency, for almost no code.
When the SDK wins
Reach for the Agent SDK when most of these are true:
- Your agent works on files or a shell. Coding agents, repo migrators, doc generators, log triagers. The built-in
Read/Edit/Bash/Greptools are the whole point, and reimplementing them well is a project in itself. - You want permissions, hooks, and subagents without building them. A
PreToolUsehook that blocksrm -rf, anacceptEditsmode for CI, acode-reviewersubagent: these are one option away. - You need MCP servers. If your agent should talk to Postgres, a browser, or an internal API through MCP, the SDK wires it up with
mcpServersinstead of you writing a client. - You want sessions and context management handled. Long, multi-turn tasks where the loop must compact history and resume later benefit from the SDK's built-in context handling.
The SDK is the right call for a bug-fixing agent in CI, an internal "explain and patch this repo" tool, or any assistant that lives close to a codebase.
When hand-rolling the loop wins
Write the loop yourself, against the plain Anthropic Client SDK, when most of these are true:
- Your tools are your own functions, not files and shells. A support agent that calls
lookupOrderandissueRefunddoes not needBashorGlob. It needs three domain tools and a tight loop. - You want minimal dependencies and a small attack surface. The Client SDK is one package. No bundled binary, no filesystem tools you then have to lock down.
- You need to own every turn. Custom retry policy, custom logging of each
tool_use, deterministic ordering, your own persistence oftool_resultblocks, or streaming each tool call as it arrives. Hand-rolling gives you the raw messages array to do whatever you want. - You are teaching or debugging. Nothing explains an agent like the loop itself. If you have not seen it before, work through your first Claude agent from scratch first.
The distinction the docs draw is exact: with the Client SDK you implement the tool loop; with the Agent SDK, Claude handles it. Here is the loop the SDK is hiding, written out in full:
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic(); // reads ANTHROPIC_API_KEY
const tools: Anthropic.Tool[] = [
{
name: "get_weather",
description: "Get the current weather for a city.",
input_schema: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
},
},
];
async function runTool(name: string, input: any): Promise {
if (name === "get_weather") {
// Your real implementation goes here.
return JSON.stringify({ city: input.city, tempC: 19, sky: "clear" });
}
throw new Error(`Unknown tool: ${name}`);
}
async function runAgent(userPrompt: string) {
const messages: Anthropic.MessageParam[] = [
{ role: "user", content: userPrompt },
];
for (let turn = 0; turn < 10; turn++) {
const response = await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 1024,
tools,
messages,
});
messages.push({ role: "assistant", content: response.content });
if (response.stop_reason !== "tool_use") {
const text = response.content.find((b) => b.type === "text");
return text?.type === "text" ? text.text : "";
}
const toolResults: Anthropic.ToolResultBlockParam[] = [];
for (const block of response.content) {
if (block.type !== "tool_use") continue;
try {
const output = await runTool(block.name, block.input);
toolResults.push({
type: "tool_result",
tool_use_id: block.id,
content: output,
});
} catch (err) {
toolResults.push({
type: "tool_result",
tool_use_id: block.id,
content: String(err),
is_error: true,
});
}
}
messages.push({ role: "user", content: toolResults });
}
throw new Error("Agent did not finish within the turn budget.");
}
runAgent("What is the weather in Lisbon?").then(console.log);
Install it with npm install @anthropic-ai/sdk. This loop uses claude-sonnet-5, a sensible default for tool use at $3 per million input tokens and $15 per million output tokens (Anthropic list pricing, July 2026; introductory $2 and $10 through August 31, 2026). Swap in claude-opus-4-8 when a task needs heavier reasoning, or claude-haiku-4-5 when latency and cost matter more than depth. That is the entire agent: send the messages, if stop_reason is tool_use run every requested tool and append one tool_result per call, loop until the model stops asking for tools. You now own the retry policy, the turn budget, the logging, and the persistence. Nothing is hidden.
Decision table
Scroll to see more
| If you need... | Use the Agent SDK | Hand-roll the loop |
|---|---|---|
| Filesystem and shell tools out of the box | Yes | No, you build them |
| A handful of your own domain tools | Overkill | Yes |
| Permissions, hooks, subagents prebuilt | Yes | You write them |
| MCP server connections | Built in | You add an MCP client |
| Minimal dependencies, small surface | No, bundles a binary | Yes, one package |
| Full control of every message and retry | Partial | Yes |
| Fastest path to a coding agent | Yes | No |
| A teaching or debugging exercise | No | Yes |
The third option: Managed Agents
There is a middle path the SDK docs name explicitly. Managed Agents is a hosted REST API where Anthropic runs the agent and a sandbox per session, and your app sends events and streams results back. You give up running the loop in your own process; you gain not having to operate sandboxes or session storage. The honest framing from the docs is a common path: prototype locally with the Agent SDK, then move to Managed Agents when you want production sessions without owning the infrastructure. If you are hand-rolling today because you want control, Managed Agents is not for you yet. If you picked the SDK for convenience, it is worth a look.
For teams standardizing on a different ecosystem, the same build-versus-buy question shows up with the Vercel AI SDK and its own agent abstractions; the reasoning in this post transfers directly, just with different package names.
Gotchas
- The bundled binary is real infrastructure. The Agent SDK's TypeScript package ships a native Claude Code binary as an optional dependency. That is fine on a normal machine and can be a surprise in a locked-down container. Check it in CI before you assume it "just works."
allowedToolsis not the same as safe. Pre-approvingBashmeans the agent can run shell commands without asking. Pair broad tool access with aPreToolUsehook or a stricterpermissionMode.- Hand-rolled loops need a turn budget. The
forloop above caps at ten turns for a reason. Without a ceiling, a confused model can loop until you run out of tokens or patience. - Model ids move. This post uses
claude-sonnet-5andclaude-opus-4-8, current in July 2026. Pin the id you test against; Anthropic model ids are pinned snapshots, not evergreen pointers. - Do not mix the two SDKs in one loop. They are different packages (
@anthropic-ai/claude-agent-sdkversus@anthropic-ai/sdk) with different shapes. Pick one per agent.
Limitations and open questions
- Cost attribution differs. With the hand-rolled loop you see every
messages.createcall and can meter it directly. The Agent SDK's managed loop makes per-turn accounting less obvious; budget observability inside the SDK is still an open area. - Context compaction is a black box. The SDK's context management is a feature until it silently drops something your task needed. Hand-rolling means you decide what stays in the messages array, at the cost of doing that work.
- Portability is not symmetric. Moving a hand-rolled loop to another provider is a rewrite of one file. Moving off the Agent SDK means unwinding tools, hooks, and session assumptions.
- The right cut point is task-specific. A domain agent that starts with three tools can grow into wanting file access and subagents, at which point the SDK you skipped becomes the cheaper option. Revisit the choice when the tool list crosses roughly a dozen.
- Neither choice fixes evals. Whichever loop you run, you still need a way to measure whether the agent does the job. That is a separate build, and it is the one most teams skip.
FAQ
Should I use the Claude Agent SDK or build the agent loop myself?
Use the Agent SDK when your agent works on files and shells and you want prebuilt tools, permissions, subagents, and MCP. Build the loop yourself when you have a small set of your own domain tools and want minimal dependencies and full control of every turn.
What is the difference between the Claude Agent SDK and the Anthropic Client SDK?
The Client SDK (@anthropic-ai/sdk) gives you direct API access and you implement the tool loop. The Agent SDK (@anthropic-ai/claude-agent-sdk) runs the loop for you with built-in tools, hooks, subagents, and session management, using the same engine as Claude Code.
Is the Claude Agent SDK free?
The SDK itself is a library governed by Anthropic's commercial terms; you pay for the Claude API tokens it consumes. As of July 2026, claude-sonnet-5 is $3 per million input and $15 per million output tokens at list, with introductory pricing of $2 and $10 through August 31, 2026.
Does the Agent SDK support Python and TypeScript?
Yes. Install pip install claude-agent-sdk (Python 3.10 or later) or npm install @anthropic-ai/claude-agent-sdk for TypeScript.
Can I add my own tools to the Agent SDK?
Yes, through in-process functions and MCP servers. If your agent is only your own tools and nothing filesystem-related, a hand-rolled loop is often simpler.
When should I use Managed Agents instead?
When you want production, long-running, or asynchronous agent sessions without operating sandboxes or session storage yourself. A common path is to prototype with the Agent SDK, then move to Managed Agents for production.
Sources
- Anthropic, Claude Agent SDK overview, 2026.
- Anthropic, Models overview: model ids and pricing, July 2026.
- Claude Agent SDK for TypeScript, source and changelog on GitHub, 2026.
- AgentNotebook, Build your first Claude agent from scratch.
- AgentNotebook, Stream Claude tool calls in a TypeScript agent loop.
Written by
Ren OkabeRen builds agent infrastructure and writes copy-paste tutorials for engineers shipping LLM tool-use systems.
Frequently asked questions
Should I use the Claude Agent SDK or build the agent loop myself?
Use the Agent SDK when your agent works on files and shells and you want prebuilt tools, permissions, subagents, and MCP. Build the loop yourself when you have a small set of your own domain tools and want minimal dependencies and full control of every turn.
What is the difference between the Claude Agent SDK and the Anthropic Client SDK?
The Client SDK (@anthropic-ai/sdk) gives you direct API access and you implement the tool loop. The Agent SDK (@anthropic-ai/claude-agent-sdk) runs the loop for you with built-in tools, hooks, subagents, and session management, using the same engine as Claude Code.
Is the Claude Agent SDK free?
The SDK itself is a library governed by Anthropic's commercial terms; you pay for the Claude API tokens it consumes. As of July 2026, claude-sonnet-5 is $3 per million input and $15 per million output tokens at list, with introductory pricing of $2 and $10 through August 31, 2026.
Does the Agent SDK support Python and TypeScript?
Yes. Install pip install claude-agent-sdk (Python 3.10 or later) or npm install @anthropic-ai/claude-agent-sdk for TypeScript.
Can I add my own tools to the Agent SDK?
Yes, through in-process functions and MCP servers. If your agent is only your own tools and nothing filesystem-related, a hand-rolled loop is often simpler.
When should I use Managed Agents instead?
When you want production, long-running, or asynchronous agent sessions without operating sandboxes or session storage yourself. A common path is to prototype with the Agent SDK, then move to Managed Agents for production.
Related tutorials
Build your first AI agent from scratch in 30 minutes
An AI agent is just a loop: you call a model, the model asks to run a tool, you run it, you feed the result back, and you repeat until the model is done. In this tutorial you build that loop yourself in plain TypeScript against the Anthropic Messages API, no framework. You will wire up two tools (read a file, run a calculation), let the model orchestrate them, add a turn cap and basic guardrails, then verify the whole thing end to end. The result is a small research agent you fully understand and can extend with your own tools.
Stream Claude tool calls in a TypeScript agent loop (June 2026)
A complete TypeScript tutorial for the streaming agent loop on Claude: input_json_delta accumulation, multi-turn dispatch, AbortController cancellation, and the eager_input_streaming workaround for the verified 5 second first-content delay on tool use. About $0.03 per call with claude-sonnet-4-6 at June 2026 pricing.
Run Claude Tool Calls in Parallel (TypeScript, 2026)
Speed up your Claude agent loop by running independent tool calls concurrently in TypeScript. Copy-paste code for parallel tool_use, is_error handling, and disable_parallel_tool_use.
