Blog
5 min read

The Claude Agent SDK: Building Your Own Agents on Claude Code's Engine

The Claude Agent SDK gives you the agent loop behind Claude Code as a library: file and shell tools, permissions, MCP, subagents and sessions. When to use it instead of the plain API or claude -p, a minimal TypeScript example, custom tools, permissions, and running it safely.

Claude Code is an agent: a loop where Claude reads files, runs commands, edits code, checks results and keeps going. The Claude Agent SDK packages that same engine as a library for TypeScript and Python, so you can build your own agents — a support agent that investigates tickets, a code-review bot, an internal ops assistant — without writing the loop, the tools or the context management yourself.

This post reflects the SDK as of autumn 2026; check Anthropic's Agent SDK docs for the latest options.

Three ways to put Claude to work

Claude API (Messages) claude -p (headless CLI) Agent SDK
What you get Raw model calls Claude Code in a script Claude Code's loop as a library
Agent loop You build it Built in Built in
Built-in tools (files, bash, search) No Yes Yes
Custom tools You implement calling Via MCP In-process functions or MCP
Control from code Full Flags and output parsing Typed messages, callbacks, hooks
Best for Chat features, single-shot tasks CI jobs, shell scripts Products and services built on agents

If your feature is "answer a question" or "extract fields," use the plain API. (OpenAI API vs Claude API) If it's a one-off script, claude -p is enough. (Claude Code headless mode) When you need an agent inside your own program, use the SDK.

A minimal agent (TypeScript)

npm install @anthropic-ai/claude-agent-sdk
import { query } from '@anthropic-ai/claude-agent-sdk'

for await (const message of query({
  prompt: 'Find why the test in tests/cart.test.ts fails and fix it.',
  options: {
    cwd: '/srv/projects/shop',
    allowedTools: ['Read', 'Grep', 'Glob', 'Edit', 'Bash'],
    permissionMode: 'acceptEdits',
    maxTurns: 30,
  },
})) {
  if (message.type === 'assistant') {
    // stream progress to your UI or logs
  }
  if (message.type === 'result') {
    console.log(message.result)          // final summary
    console.log(message.total_cost_usd)  // what the run cost
  }
}

query() runs the whole loop and yields messages as it goes: the model's turns, tool calls and results, and a final result message with the outcome, usage and cost. The Python package (claude-agent-sdk) has the same shape.

Authentication works like the API: an ANTHROPIC_API_KEY (or a supported cloud provider). Usage is billed at API rates.

Adding your own tools

Custom tools are how your agent touches your systems — look up an order, query metrics, open a ticket. Define them in-process and expose them as an MCP server:

import { query, tool, createSdkMcpServer } from '@anthropic-ai/claude-agent-sdk'
import { z } from 'zod'

const orders = createSdkMcpServer({
  name: 'orders',
  version: '1.0.0',
  tools: [
    tool(
      'get_order',
      'Look up an order by ID. Returns status, items and customer email.',
      { orderId: z.string() },
      async ({ orderId }) => {
        const order = await db.order.find(orderId)
        return { content: [{ type: 'text', text: JSON.stringify(order) }] }
      },
    ),
  ],
})

query({
  prompt: 'Why hasn’t order 8812 shipped?',
  options: {
    mcpServers: { orders },
    allowedTools: ['mcp__orders__get_order'],
  },
})

External MCP servers (GitHub, databases, your own) plug in the same way. (What is MCP?, connecting MCP servers)

Write tool descriptions as if for a new colleague: what it does, when to use it, what it returns. The model chooses tools based on those words. (Function calling explained)

Controlling what it may do

The SDK has the same safety model as Claude Code:

  • allowedTools / disallowedTools — the tool allowlist. Start narrow: read-only tools for an investigator agent.
  • permissionMode — default (ask), acceptEdits, plan, dontAsk, auto, or bypassPermissions. Only bypass inside an isolated sandbox. (Permission modes)
  • A permission callback — decide per tool call in your own code ("allow Bash only for npm test").
  • Hooks — run code before/after tool use, e.g. block writes outside a directory, log every command. (Claude Code hooks)
  • maxTurns and budget limits so a confused agent can't loop forever.

Context, sessions and settings

  • System prompt — use Claude Code's built-in prompt (good for coding agents), extend it, or replace it with your own for non-coding agents.
  • Project settings and CLAUDE.md — by default the SDK loads user, project and local settings from the filesystem, just like Claude Code. For a service, set settingSources explicitly (e.g. ['project'], or [] for none) so behaviour doesn't change silently when someone edits a settings file on the machine.
  • Sessions — capture the session ID from the messages and pass it back to resume a conversation later. (Resume a Claude Code session)
  • Subagents — define specialised helpers (a "test-runner," a "researcher") that work in their own context and report back. (Claude Code subagents)

Running agents safely

An agent with Bash and Edit can do anything that user account can do. Treat it like untrusted code:

The summary

  • The Agent SDK is Claude Code's agent loop as a TypeScript/Python library.
  • Use the API for single calls, claude -p for scripts, the SDK for agents in your product.
  • query() streams messages and ends with a result including cost.
  • Add custom tools via in-process MCP servers; describe them well.
  • Narrow tools and permissions, use hooks and limits, and run agents in isolated workspaces.

EasySpawn gives agents a persistent, isolated server each — files, terminal, database and running app — so SDK-built agents have a safe place to work that's still there for the next task. See how it works or join the waitlist.

Related: Claude Code Headless Mode · Claude Code Subagents · Connecting MCP Servers to Claude Code · How Coding Agents Work

Keep reading