Room 42, home

Claude Agent SDK

Build production agents on the harness behind Claude Code: built-in tools, permissions, sessions, and your own custom tools, all from one SDK.

Agentsadvanced3 min readUpdated 12 Jun 2026

In short

  1. 01The Claude Agent SDK is the agent loop from Claude Code, packaged as a library for TypeScript and Python.
  2. 02It hands you the built-in tools, a permission system, and resumable sessions, so you just bring the task and the rules.
  3. 03Start an agent with a prompt and an allowed-tools list, then stream back typed messages as it works.
  4. 04Add your own capabilities as in-process MCP tools, and combine an allow-list with a permission mode to control autonomy.
Contents · 5 sections
  1. 1What does the Claude Agent SDK give you?
  2. 2How do I write a minimal agent?
  3. 3How do I control which tools an agent can use?
  4. 4How do I add my own tools to an agent?
  5. 5Sessions, streaming, and production

The Claude Agent SDK is the agent loop from Claude Code, packaged as a library you can build on. Instead of wiring the model, tools, and permission handling yourself, you describe what the agent can do and the SDK runs the loopThe repeating cycle where the model decides what to do, runs a tool, reads the result, and decides again until the task is finished. It is available for both TypeScript and Python.

What does the Claude Agent SDK give you?

The hard parts of an agent come built in: the loop that calls the model and runs tools until the task is done, a set of capable built-in tools, a permission system, and session persistenceSaving the full state of a run so it can be reloaded later and continue where it left off. You bring the task and the rules.

That loop is the whole point, the SDK runs this cycle for you until the task is done:

Install whichever you need:

npm install @anthropic-ai/claude-agent-sdk     # TypeScript
pip install claude-agent-sdk                   # Python 3.10+

Set your ANTHROPIC_API_KEY and you can run an agent in a few lines.

How do I write a minimal agent?

The simplest entry point is query. You give it a prompt and options, and it streams back typed messages as the agent works:

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"]),
    ):
        print(message)
 
asyncio.run(main())

The TypeScript shape is the same idea:

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"] },
})) {
  console.log(message);
}

How do I control which tools an agent can use?

The SDK ships with the tools that make Claude Code useful: reading, writing, and editing files, running shell commands, searching with glob and grep, and fetching from the web. You decide which an agent may use with allowed_tools.

Permission modesPreset rules that decide which actions run automatically and which pause to ask you first set how cautious the agent is:

  • default · ask before anything risky
  • acceptEdits · auto-approve file edits, still gate the rest
  • plan · explore and propose, do not change anything yet
  • bypassPermissions · skip prompts entirely (only for trusted, sandboxedRun in an isolated environment so the code cannot touch anything outside it runs)

Combine an allow-list with a mode to get exactly the autonomy you want, and no more.Common gotchaDo not reach for bypassPermissions just to stop the prompts. It skips every check, so a stray shell command can wipe files or hit the network.Keep it for runs inside a throwaway sandbox, and use acceptEdits for normal local work.

How do I add my own tools to an agent?

When the built-ins are not enough, give the agent your own tools. You can define them in-process and hand them to the agent as a small MCPModel Context Protocol, an open standard for exposing tools and data to an agent through a uniform interface server:

from claude_agent_sdk import tool, create_sdk_mcp_server
 
@tool("get_temp", "Get the temperature for a location", {"lat": float, "lon": float})
async def get_temp(args):
    temp = await lookup(args["lat"], args["lon"])
    return {"content": [{"type": "text", "text": f"{temp} degrees"}]}
 
server = create_sdk_mcp_server(name="weather", tools=[get_temp])

You then pass that server in the options and reference the tool by its qualified name.Common gotchaThe agent calls your tool by its qualified name mcp__weather__get_temp, not the bare get_temp you wrote in the decorator, and a tool that is not in allowed_tools is silently skipped rather than erroring.Add the full mcp__server__tool string to the allow-list, or the agent never sees the tool and you spend an hour debugging a "lazy" model. Because it is MCP underneath, the same mechanism connects external servers too: anything from the previous phase plugs straight in.

Sessions, streaming, and production

Every run writes a session you can resume, so an agent can pick up a long task with full context instead of starting over. Pass a session id to resume, or continue the most recent one in the working directory.

Output is a stream of typed messages, which is what makes the SDK production-fit: you watch the agent's steps as they happen, log them, and read the final result message for the outcome and the cost. For multi-turn work in one process, the stateful client class holds the session for you across calls.

A realistic flow is: set your options (allowed tools, system prompt, permission mode, any custom or MCP tools), call query with the task, stream the messages to your logs, and read the result. That is a deployable agent, built on the same loop that ships in Claude Code. The next guide covers letting Anthropic run that loop for you with Claude Managed Agents.