insidejob

Building your first agent with the Claude Agent SDK

The Claude Code SDK was renamed to the Claude Agent SDK — but the name change is less interesting than what you can build with it. Here’s a working guide.

SDK vs CLI vs Managed Agents — when to use which

Agent SDKClaude Code CLIManaged Agents
Use caseCustom apps, CI/CD, production automationInteractive dev, one-off tasksLong-running autonomous work
LanguagePython, TypeScriptTerminalAPI (Python, TS, curl)
Model selectionYou pick per-agentSession-levelYou pick per-agent
CostAPI billing (pay per token)Subscription$0.08/hr + API tokens
Tools includedRead, Write, Edit, Bash, Glob, Grep, WebSearch, WebFetchAll of the above + Agent, MonitorSame as SDK
When it’s bestYou need programmatic control, CI integration, or multi-agent orchestrationDaily development, exploring codebases, manual tasksTasks that run for hours, need cloud infra, or run when your machine is off

A working agent in 10 lines

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions

async def main():
    async for message in query(
        prompt="Find all TODO comments in this repo and summarize them",
        options=ClaudeAgentOptions(allowed_tools=["Read", "Glob", "Grep"]),
    ):
        if hasattr(message, "result"):
            print(message.result)

asyncio.run(main())

This agent reads your codebase, greps for TODOs, and summarizes — using the same tools that power Claude Code. No tool implementation needed.

Multi-agent: specialist delegation

async for message in query(
    prompt="Use the security-reviewer to audit this codebase",
    options=ClaudeAgentOptions(
        allowed_tools=["Read", "Glob", "Grep", "Agent"],
        agents={
            "security-reviewer": AgentDefinition(
                description="Security expert for code review",
                prompt="Analyze for OWASP Top 10 vulnerabilities. Check for injection, auth issues, data exposure.",
                tools=["Read", "Glob", "Grep"],
            )
        },
    ),
):
    ...

The main agent delegates to security-reviewer, which runs in its own context with restricted tools. Results flow back.

Hooks: intercepting agent behavior

async def block_dangerous_commands(input_data, tool_use_id, context):
    cmd = input_data.get("tool_input", {}).get("command", "")
    if any(danger in cmd for danger in ["rm -rf", "curl", "wget"]):
        return {"decision": "block", "message": "Blocked dangerous command"}
    return {}

options = ClaudeAgentOptions(
    hooks={"PreToolUse": [HookMatcher(matcher="Bash", hooks=[block_dangerous_commands])]}
)

Hooks give you programmatic guardrails — block dangerous commands, log file changes, require approval for specific actions.

Key decisions

Use the SDK when: You’re building a product, running agents in CI, need multi-model routing, or want programmatic control over permissions and tool access.

Use the CLI when: You’re exploring a codebase, doing daily development, or want the fastest path to a working result.

Use Managed Agents when: You need cloud-hosted execution, long-running sessions, or Anthropic to handle the infrastructure.