Overview

The Agent SDK gives you the same tools, agent loop, and context management that power Claude Code, programmable in Python and TypeScript; claude -p is the same engine from the command line. Use it to embed an agent in an application you operate. For interactive work use the Claude Code CLI; to write the tool loop yourself against the raw API use the Client SDK; to have Anthropic host the agent use Managed Agents.

Start with query()

Install claude-agent-sdk (Python 3.10 or later) or @anthropic-ai/claude-agent-sdk (Node 18 or later). Both bundle a native Claude Code binary. query() returns an async iterator of messages as Claude plans, calls tools, and finishes.

from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
 
async for message in query(
    prompt="Review utils.py for crashes and fix them.",
    options=ClaudeAgentOptions(
        allowed_tools=["Read", "Edit", "Glob"],   # auto-approved
        permission_mode="acceptEdits",
    ),
):
    if isinstance(message, ResultMessage):
        print(message.subtype)

The TypeScript form takes the same options in camelCase (allowedTools, permissionMode). Set ANTHROPIC_API_KEY in the process environment; the SDK does not read .env files. Bedrock, Claude Platform on AWS, Vertex, and Foundry use CLAUDE_CODE_USE_BEDROCK=1 and its siblings. Unless previously approved, Anthropic does not allow third-party products to offer claude.ai login for SDK agents, so use API keys.

Pass tools and permissions explicitly

Give the agent the narrowest tool set: Read, Glob, Grep for analysis; add Edit to modify; add Bash for full automation. Choose the permission mode in code, because the starting mode can differ by version and plan; see claude-code-permissions. For programmatic control use a canUseTool callback or hook callbacks: a PreToolUse callback that returns permissionDecision: "deny" blocks a call and sends the reason to Claude.

Decide what loads from disk

When settingSources is omitted, query() reads user, project, and local settings, CLAUDE.md files, and .claude/ skills, agents, and commands, as the CLI does. Pass settingSources: [] to run only on what you configure in code. Managed policy settings, ~/.claude.json, auto memory, and claude.ai MCP connectors load regardless. For multi-tenant servers, give each tenant its own filesystem, set settingSources: [], and set CLAUDE_CODE_DISABLE_AUTO_MEMORY=1.

Extend the agent through agents (subagents; include Agent in allowedTools), mcpServers, hooks, and skills. Skills must exist as .claude/skills/ files; there is no registration API. See claude-code-subagents, claude-code-mcp, and claude-code-hooks.

Script it with claude -p

claude --bare -p "Summarize README.md" --allowedTools "Read" --output-format json
  • --output-format is text, json (includes result, session ID, and total_cost_usd, a client-side estimate), or stream-json (add --verbose --include-partial-messages for tokens).
  • --json-schema '<schema>' with json output returns the validated object in structured_output.
  • --bare skips hooks, skills, plugins, MCP servers, auto memory, and CLAUDE.md, so a script behaves the same on every machine; it never reads OAuth or keychain credentials, so set ANTHROPIC_API_KEY (or an apiKeyHelper), and it is the recommended mode for scripted calls. Without it, claude -p runs a repository’s project hooks and .mcp.json servers even in a folder you never trusted, so use --bare on untrusted pull requests.
  • Pass --permission-mode explicitly (dontAsk with exact --allowedTools for locked-down CI). Exit code is 0 on success and nonzero on failure.
  • Continue with --continue, or capture session_id and pass --resume <id>. Piped stdin is capped at 10MB.

For GitHub workflows see github-actions. Harden any unattended agent with the checklist in reliable-agents-in-production.