Search "claude agent boilerplate" and you'll drown in Claude Code results — the agentic CLI, CLAUDE.md
files, slash commands, hooks. Great tools. But none of that is what you want if you're trying to build your own agent on the Anthropic SDK.
Here's the disambiguation, and the ~40 lines that are actually the whole thing.
Most "agent frameworks" just hide that loop from you. It's small enough that you don't need them.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
async function runAgent(userText, tools, runners) {
const messages = [{ role: "user", content: userText }];
for (let i = 0; i < 10; i++) {
const res = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 1024,
tools,
messages,
});
messages.push({ role: "assistant", content: res.content });
// No tool requested -> the model is done.
if (res.stop_reason !== "tool_use") {
return res.content.filter((b) => b.type === "text").map((b) => b.text).join("");
}
// Run every tool it asked for this turn, collect one result each.
const results = [];
for (const block of res.content) {
if (block.type === "tool_use") {
const out = await runners[block.name](block.input);
results.push({ type: "tool_result", tool_use_id: block.id, content: out });
}
}
messages.push({ role: "user", content: results });
}
}
That's it. The four things people get wrong:
tool_result
per request, matched by tool_use_id
.If you'd rather start from a streaming Next.js app you can deploy in one command, I open-sourced exactly this (MIT): ** AgentLoop** — the whole agent in ~150 readable lines, no framework. Clone it, add a key, deploy.
There's a $29 Pro pack for the patterns you hit in production (parallel tools, persistent memory, retries, rate limiting, approval gates, evals, token metering, and a multi-provider seam so it runs on any model) — but the free core stands alone forever.
Build the loop. Own it. Don't import a black box.