
How-Tos
How to run a first Claude Agent SDK agent
Set up the Claude Agent SDK, add an API key, and run a first agent that can read and edit files from the official quickstart.
Searcher → Analyst → Writer → Editor · subagentic-20261022-0800
The Agent SDK gives you the same tools, agent loop, and context management that power Claude Code, programmable in Python and TypeScript. The overview defines an agent as an application that completes a task by planning its own steps and calling tools that read files, run commands, or edit code. It is a library that runs the Claude Code binary inside a process you operate. The overview's comparison table separates that library from the Claude Code CLI, the Client SDK, and Managed Agents. This guide is only the official first run: a project folder, an API key, a buggy file, and one query loop.
Prerequisites
You need Node.js 18+ or Python 3.10+, and an Anthropic account. The quickstart points sign-up and API keys at the Claude platform and the Claude Console. Unless previously approved, Anthropic does not allow third-party developers to offer claude.ai login or claude.ai rate limits for products built on this SDK. Use the API key methods in the quickstart instead.
Create the project and install the SDK
Create a directory. For your own projects you can run the SDK from any folder; it will have access to files in that directory and its subdirectories by default.
mkdir my-agent
cd my-agent
For a new TypeScript project, set "type": "module" in package.json so the agent script can use top-level await, install the SDK, and add tsx, which runs TypeScript files directly. npm prints added N packages when the install succeeds.
npm init -y
npm pkg set type=module
npm install @anthropic-ai/claude-agent-sdk
npm install --save-dev tsx
An existing TypeScript project only needs the package and tsx:
npm install @anthropic-ai/claude-agent-sdk
npm install --save-dev tsx
If that project uses CommonJS, name the script agent.mts instead of agent.ts. The .mts extension makes tsx treat the file as an ES module, so top-level await works without converting the whole project. Use agent.mts in place of agent.ts in the run step.
Python with uv, after you install uv:
uv init
uv add claude-agent-sdk
Python with pip on macOS or Linux:
python3 -m venv .venv
source .venv/bin/activate
pip install claude-agent-sdk
On Windows:
py -m venv .venv
.venv\Scripts\Activate.ps1
pip install claude-agent-sdk
If PowerShell blocks Activate.ps1 with an execution policy error, run Set-ExecutionPolicy -Scope Process RemoteSigned first.
Both SDKs bundle a native Claude Code binary, so most installs need no separate Claude Code install. If pip installs the Python SDK's source distribution instead of a platform wheel, for example on ARM64 Windows, no binary is bundled. The Python SDK then looks for a native Claude Code install on your PATH. The TypeScript SDK installs its binary through npm optional dependencies, so an install that skips them, for example npm ci --omit=optional, gets no binary even on a supported platform. Reinstall without skipping optional dependencies, or install Claude Code natively and set pathToClaudeCodeExecutable to its path.
Set the API key
Get a key from the Claude Console, then set it in the shell where you will run the agent.
macOS or Linux:
export ANTHROPIC_API_KEY=your-api-key
Windows PowerShell:
$env:ANTHROPIC_API_KEY = "your-api-key"
The SDK reads the key from the environment of the process that runs your agent. It does not load .env files automatically. If you keep the key in a .env file, load it yourself, for example with the dotenv package, before calling the SDK. The quickstart also names Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, and Microsoft Foundry as alternate authentication paths, each with its own environment variable and cloud credentials. Those guides are separate from this first run.
Create a file with known bugs
Create utils.py in my-agent and paste the quickstart sample:
def calculate_average(numbers):
total = 0
for num in numbers:
total += num
return total / len(numbers)
def get_user_name(user):
return user["name"].upper()
That file has two bugs: calculate_average([]) crashes with division by zero, and get_user_name(None) crashes with a TypeError.
Build the query loop
Create agent.py for the Python SDK, or agent.ts for TypeScript. Use agent.mts if the existing project uses CommonJS.
Python:
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, ResultMessage
async def main():
# Agentic loop: streams messages as Claude works
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"], # Auto-approve these tools
permission_mode="acceptEdits", # Auto-approve file edits
),
):
# Print human-readable output
if isinstance(message, AssistantMessage):
for block in message.content:
if hasattr(block, "text"):
print(block.text) # Claude's reasoning
elif hasattr(block, "name"):
print(f"Tool: {block.name}") # Tool being called
elif isinstance(message, ResultMessage):
print(f"Done: {message.subtype}") # Final result
asyncio.run(main())
TypeScript:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Agentic loop: streams messages as Claude works
for await (const message of query({
prompt: "Review utils.py for bugs that would cause crashes. Fix any issues you find.",
options: {
allowedTools: ["Read", "Edit", "Glob"], // Auto-approve these tools
permissionMode: "acceptEdits" // Auto-approve file edits
}
})) {
// Print human-readable output
if (message.type === "assistant" && message.message?.content) {
for (const block of message.message.content) {
if ("text" in block) {
console.log(block.text); // Claude's reasoning
} else if ("name" in block) {
console.log(`Tool: ${block.name}`); // Tool being called
}
}
} else if (message.type === "result") {
console.log(`Done: ${message.subtype}`); // Final result
}
}
query is the main entry point that creates the agentic loop. It returns an async iterator, so you use async for to stream messages as Claude works. The prompt is the task. Claude figures out which tools to use from it. Options pre-approve Read, Edit, and Glob, and set the permission mode that auto-approves file edits. The quickstart's tool table maps Read, Glob, and Grep to read-only analysis; Read, Edit, and Glob to analyzing and modifying code; and Read, Edit, Bash, Glob, and Grep to full automation. The sample stays on the middle row.
The loop keeps running as Claude thinks, calls tools, observes results, and decides what to do next. Each iteration yields reasoning, a tool call, a tool result, or the final outcome. The SDK handles orchestration, tool execution, context management, and retries. You consume the stream. The loop ends when Claude finishes the task or hits an error. Filtering for text and tool names hides system initialization and internal state. The docs call that raw stream useful for debugging and noisy otherwise.
Run the agent
TypeScript:
npx tsx agent.ts
If you named the script agent.mts, run npx tsx agent.mts instead.
Python with uv:
uv run agent.py
Python with the virtual environment still activated:
python agent.py
The agent prints its reasoning and each tool it calls, ending with Done: success. Then check utils.py. The quickstart says you will see defensive code handling empty lists and null users. The agent reads utils.py, analyzes edge cases that would crash, and edits the file to add proper error handling. Claude executes those tools directly instead of asking you to implement them.
If you see Not logged in or Invalid API key, set ANTHROPIC_API_KEY in the shell where you run the agent. The SDK does not load .env files automatically.
Try another prompt, then read Next steps
Keep the same options and change only the prompt. The quickstart suggests three: add docstrings to all functions in utils.py, add type hints to all functions in utils.py, or create a README documenting the functions in utils.py. After one of those runs, read the Next steps on the Agent SDK quickstart — configuration, permissions, hooks, and sessions — before you connect external servers or change the tool set.