§15.09

Claude Agent SDK for Python: Your First Agent

Install claude-agent-sdk, run an agent that reads and edits real files, control which tools it may use, and read the final result.

published 06 Sept 2026 checked against docs 06 Sept 2026 4 min in Building with the API Markdown

On this page5 sections
  1. 1. Install
  2. 2. Set the key
  3. 3. Write the agent
  4. 4. Run it
  5. 5. Tighten it

The Claude Agent SDK is Claude Code packaged as a library: the agent loop, the built-in Read/Edit/Bash/Glob/Grep tools, context management and permissions, driven from your own code. It is not the Anthropic API SDK — different package, different job.

1. Install

Python 3.10 or later.

python3 -m venv .venv
source .venv/bin/activate
pip install claude-agent-sdk
py -m venv .venv
.venv\Scripts\Activate.ps1
pip install claude-agent-sdk

What it does: installs the SDK plus a bundled Claude Code binary, so there’s usually no separate install. If pip falls back to the source distribution (ARM64 Windows, for example), install Claude Code natively and the SDK will find it on your PATH. If PowerShell blocks Activate.ps1, run Set-ExecutionPolicy -Scope Process RemoteSigned first.

2. Set the key

export ANTHROPIC_API_KEY=your-api-key

What it does: authenticates the agent. The SDK reads it from the process environment and does not load .env files for you — load them yourself with dotenv if that’s where the key lives.

3. Write the agent

agent.py:

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, ResultMessage


async def main():
    async for message in query(
        prompt="Review utils.py for bugs that would cause crashes. Fix any issues you find.",
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Edit", "Glob"],
            permission_mode="acceptEdits",
        ),
    ):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if hasattr(block, "text"):
                    print(block.text)
                elif hasattr(block, "name"):
                    print(f"Tool: {block.name}")
        elif isinstance(message, ResultMessage):
            print(f"Done: {message.subtype}")


asyncio.run(main())

What it does: query() returns an async iterator, so the async for streams messages as Claude thinks, calls tools and observes results. AssistantMessage.content holds the blocks — text and tool calls; ResultMessage arrives last and carries the outcome (subtype, plus terminal_reason for why the loop stopped).

4. Run it

python agent.py

What it does: runs the loop against files in the current directory and its subdirectories, which is the agent’s default working scope. Watch the file actually change on disk — that’s the proof it worked.

5. Tighten it

allowed_tools is an allowlist: listed tools are auto-approved, anything else falls through to permission_mode. Drop Edit for read-only analysis; add Bash only when the agent genuinely needs to run tests. Other useful options: system_prompt, max_turns, cwd, mcp_servers. For a multi-turn conversation that keeps context between prompts, use ClaudeSDKClient instead of query().


Next: the same agent in TypeScript or tool use with the Claude API.

← All Building with the API plates · Search all guides

↑↓ move↵ openalt+↵ copy first command

Keyboard

⌘/ctrl+K or /
Search all guides
alt+↵
In search: copy the guide's first command
j / k
Move through a list of guides
c
On a guide: copy its first command
t
Toggle light / dark
?
This list