DS DevShelfHub Projects · AI tools
Tutorials / Claude Code / Agent SDK
Claude Code Expert · 12 min read Page 23 of 25

The Agent SDK

By DevShelfHub

When the built-in workflow isn't flexible enough, the Agent SDK exposes Claude Code's capabilities as a programmable API. Instantiate agents with scoped tools and permissions, wire them into orchestration pipelines, stream their events in real time, and run them inside your own infrastructure.

Series progress23 / 25
The Agent SDK — Claude Code tutorial on programmatic agents, permission scoping, and event streaming

When to reach for the SDK

The Agent SDK is for cases where the interactive CLI, sub-agents, and routines can't express what you need. It costs more code, so use it deliberately. If you mainly need to extend Claude Code with new tools rather than orchestrate agents in code, see Building Custom MCP Servers instead.

Use the SDK when you need

  • Programmatic control over which tools agents can use
  • Custom orchestration logic beyond "run agents in parallel"
  • Integration with your existing application code
  • Fine-grained permission management
  • Custom session lifecycle control

Stick with built-ins when

Sub-agents and routines can already do the job. The SDK requires meaningfully more code to write and maintain — don't pay that cost for a task the standard workflow handles.

SDK architecture

The SDK surfaces Claude Code's engine as five composable capabilities:

Capability What it does
Agent creationInstantiate agents with specific configs
Tool accessGrant or restrict specific tools programmatically
Permission controlScope exactly what each agent is allowed to do
Session managementCreate, attach, fork, and terminate sessions
Event streamingReceive real-time updates as agents work

Basic usage

Create an agent with a model, a working directory, an explicit tool allow/deny list, scoped permissions, and an inline CLAUDE.md — then run it and inspect the structured result.

typescript
import { ClaudeCodeAgent } from "@anthropic-ai/claude-code-sdk";

// Create an agent with specific permissions
const agent = new ClaudeCodeAgent({
  model: "claude-sonnet-4-6",
  workingDirectory: "./packages/api",
  tools: {
    allowed: ["read_file", "write_file", "bash"],
    denied: ["web_search"]  // No external access for this agent
  },
  permissions: {
    mode: "acceptEdits",
    allowedCommands: ["npm test", "npm run build", "git status"]
  },
  claudeMd: `
    # API Agent
    You only work on the packages/api directory.
    Always run tests after making changes.
  `
});

// Run the agent
const result = await agent.run(
  "Fix all TypeScript errors in src/ and ensure tests pass"
);

console.log(result.summary);
console.log(result.filesModified);
console.log(result.commandsRun);

Orchestration patterns

Because agents are just objects, you compose them with ordinary control flow. Two patterns cover most production workflows: a sequential pipeline (one agent's output feeds the next) and a fan-out (run many agents in parallel, then synthesize).

typescript
// Sequential pipeline
async function reviewAndFix(prNumber: string) {
  const reviewer = new ClaudeCodeAgent({
    model: "claude-opus-4-5",
    task: `Review PR #${prNumber} for issues`
  });

  const issues = await reviewer.run();

  if (issues.criticalIssuesFound) {
    const fixer = new ClaudeCodeAgent({
      model: "claude-sonnet-4-6",
      context: issues.summary,
      task: "Fix the critical issues identified in the review"
    });

    await fixer.run();
  }

  return issues;
}

// Fan-out pattern
async function parallelAudit(directories: string[]) {
  const agents = directories.map(dir =>
    new ClaudeCodeAgent({
      workingDirectory: dir,
      task: "Audit this directory for security vulnerabilities"
    })
  );

  const results = await Promise.all(agents.map(a => a.run()));

  const synthesizer = new ClaudeCodeAgent({
    context: results.map(r => r.summary).join("\n"),
    task: "Synthesize the audit findings and create a prioritized remediation plan"
  });

  return await synthesizer.run();
}

Event streaming

Subscribe to lifecycle events to observe an agent as it works — surface tool use in a UI, notify developers on file changes, or react when a test fails. The events fire while run() is in flight.

typescript
const agent = new ClaudeCodeAgent({ task: "Implement the new feature" });

agent.on("tool_use", (event) => {
  console.log(`Claude is using: ${event.tool} on ${event.file}`);
});

agent.on("file_modified", (event) => {
  notifyDeveloper(`${event.file} was modified`);
});

agent.on("test_result", (event) => {
  if (!event.passed) {
    console.warn(`Test failed: ${event.test_name}`);
  }
});

const result = await agent.run();

Production considerations

An SDK agent running unattended needs the same guardrails as any production service:

Timeout management

Set reasonable timeouts so long-running agents can't hang indefinitely.

Retry logic

Handle transient API errors with exponential backoff.

Cost management

Track token usage per agent and set hard spend limits.

Audit logging

Log every agent action for compliance and debugging.

Rollback

Always checkpoint before large changes and keep a rollback plan ready.

Practice project: Build a custom code-quality enforcement system — agents that review PRs, run quality gates, post detailed feedback, and autonomously fix certain categories of issues. Before deploying, read production deployment patterns for secrets, observability, and failure handling.

Notes

Reach for CLI first, SDK last

Sub-agents, routines, and CI actions cover most orchestration. The SDK pays off when you need custom fan-out, external event buses, or embedding agents inside an existing service — not for one-off scripts.

Permission scopes are your safety boundary

Deny-by-default tool lists beat broad allowlists. An agent that can run arbitrary shell commands in production needs the same review bar as deploying a new microservice.

Event streams need backpressure

High-volume tool events can overwhelm a UI or webhook receiver. Batch, sample, or filter at the subscriber — don't assume every file edit needs a real-time notification.

SDK version skew with the CLI

Pin SDK and CLI to compatible releases in CI. A green local session with a mismatched SDK in Docker is a common source of "tool not found" errors in production pipelines.

Agent SDK FAQ

What is the Claude Code Agent SDK?

The Agent SDK exposes Claude Code's capabilities as a programmable API. It lets you instantiate agents with scoped tools and permissions, wire them into orchestration pipelines, stream their events in real time, and run them inside your own infrastructure.

What can you build with the Agent SDK?

You can build custom orchestration that goes beyond the built-in workflow, such as sequential pipelines where one agent's output feeds the next and fan-out workflows that run many agents in parallel and synthesize the results. A practice project is a custom code-quality enforcement system that reviews PRs, runs quality gates, posts feedback, and fixes certain issues autonomously.

How does permission scoping work in the Agent SDK?

Each agent is configured with an explicit tool allow/deny list and scoped permissions, so you control exactly which tools it can use and what it is allowed to do. You can set a permission mode and an allowed-commands list to fine-tune access programmatically.

What is event streaming in the Agent SDK?

Event streaming lets you subscribe to lifecycle events to observe an agent as it works, such as tool use, file modifications, and test results. The events fire while run() is in flight, so you can surface tool use in a UI, notify developers on file changes, or react when a test fails.

How is the Agent SDK different from the Claude Code CLI?

Reach for the SDK only when the interactive CLI, sub-agents, and routines can't express what you need. It gives programmatic control over tools, permissions, sessions, and orchestration, but costs meaningfully more code to write and maintain, so stick with the built-ins when they already do the job.

Quick summary

  • Use the SDK only when sub-agents and routines aren't flexible enough — it costs more code
  • Agents are configurable objects with scoped tools, permissions, and an inline CLAUDE.md
  • Compose them with ordinary control flow: sequential pipelines and parallel fan-out + synthesis
  • In production add timeouts, retries, spend caps, audit logging, and a rollback checkpoint

Want to revisit an earlier chapter? Browse the full Claude Code tutorial series.