Claude Agent SDK Basics
9 examples to get you started with the Claude Agent SDK - 6 basic and 3 intermediate.
Search across all documentation pages
9 examples to get you started with the Claude Agent SDK - 6 basic and 3 intermediate.
pip install claude-agent-sdk (TypeScript: npm install @anthropic-ai/claude-agent-sdk).export ANTHROPIC_API_KEY=sk-ant-....asyncio since the Python SDK's query() is an async generator.The minimal shape: one prompt, default tools, streamed response.
import asyncio
from claude_agent_sdk import query
async def main():
async for message in query(prompt="What is 17 * 34?"):
print(message)
asyncio.run(main())query() returns an async iterator of messages, not a single string.options passed, the agent runs with the SDK's default tool set.Related: The Claude Agent SDK Mental Model - what's happening under this call
Choose a specific model instead of the SDK default.
from claude_agent_sdk import query, AgentOptions
options = AgentOptions(model="claude-sonnet-5")
async for message in query(prompt="Summarize this changelog.", options=options):
print(message)AgentOptions is where most per-call configuration lives.claude-sonnet-5 is the current balanced default; claude-haiku-4-5 trades quality for speed and cost.Restrict which built-in tools the agent can call.
from claude_agent_sdk import query, AgentOptions
options = AgentOptions(allowed_tools=["file_edit"])
async for message in query(
prompt="Fix the typo in README.md",
options=options,
):
print(message)allowed_tools is an explicit allowlist; anything not listed is unavailable to the loop.file_edit means this agent cannot run bash commands or fetch the web, even if it wanted to.Related: Enabling File Edit, Bash, and Web Tools in the Agent SDK - full tool scoping guide
Point the agent at a specific project root.
from claude_agent_sdk import query, AgentOptions
options = AgentOptions(
cwd="/path/to/project",
allowed_tools=["file_edit", "bash"],
)
async for message in query(prompt="List failing tests.", options=options):
print(message)cwd scopes file and bash operations to a specific directory tree.cwd explicitly avoids surprises when the SDK runs from a different process working directory.allowed_tools so the agent can both inspect and act on that project.Print only the assistant's text content instead of every message type.
from claude_agent_sdk import query
async for message in query(prompt="Explain what this repo does."):
if message.get("type") == "text":
print(message["text"], end="", flush=True)type gets you just the prose.type as the primary discriminator.Wrap query() for callers that don't want to deal with async iteration.
import asyncio
from claude_agent_sdk import query
def ask(prompt: str) -> str:
async def _run():
chunks = []
async for message in query(prompt=prompt):
if message.get("type") == "text":
chunks.append(message["text"])
return "".join(chunks)
return asyncio.run(_run())
print(ask("Give me a one-sentence summary of asyncio."))Enable multiple built-in tools while requiring approval on risky ones.
from claude_agent_sdk import query, AgentOptions
options = AgentOptions(
allowed_tools=["file_edit", "bash", "web_search"],
permission_mode="default", # pauses before destructive actions
)
async for message in query(
prompt="Investigate the failing CI run and propose a fix.",
options=options,
):
print(message)permission_mode="default" keeps the loop's tool-use decisions intact but inserts an approval gate before destructive calls.Related: Adding Human-in-the-Loop Checkpoints to an Agent SDK Workflow - approval gates in depth
Continue a prior run instead of starting from a blank context.
from claude_agent_sdk import query, AgentOptions
first = query(prompt="Start reviewing src/orders/", options=AgentOptions())
session_id = None
async for message in first:
if message.get("type") == "session_start":
session_id = message["session_id"]
# later, possibly in a new process
resume_options = AgentOptions(resume=session_id)
async for message in query(prompt="Continue where you left off.", options=resume_options):
print(message)resume on a later call continues the loop with that history already in context.Related: Persisting Sessions Across Runs with the Claude Agent SDK - storage and resume patterns
Spin off an isolated child agent for one part of a larger task.
from claude_agent_sdk import query, AgentOptions, SubagentConfig
options = AgentOptions(
allowed_tools=["file_edit", "bash"],
subagents=[
SubagentConfig(
name="test-runner",
allowed_tools=["bash"],
description="Runs the test suite and reports failures only.",
)
],
)
async for message in query(
prompt="Use the test-runner subagent to check if the suite passes, then fix any failures.",
options=options,
):
print(message)bash only) and its own isolated context, separate from the parent's.Related: Delegating Work to Subagents in the Claude Agent SDK - parallelizing independent workstreams
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5 - and the Claude Agent SDK (latest release, Python and TypeScript). Model names, SDK versions, and pricing move quickly - verify current specifics at platform.claude.com/docs before relying on them.
Reviewed by Chris St. John·Last updated Jul 18, 2026