Agent SDK Basics
The Claude Agent SDK is a library that lets you control Claude Code's capabilities programmatically. Beyond simple conversation, you can build agents in code that plan and execute work autonomously.
Agent SDK vs Claude Code CLIโ
| Aspect | Claude Code CLI | Agent SDK |
|---|---|---|
| How you use it | Terminal conversation | Controlled from code |
| Best suited for | Immediate help while developing | Automated pipelines |
| Customization | CLAUDE.md, Skills | Full programmatic control |
| User | Individual developer | System / application |
Installationโ
# TypeScript
npm install @anthropic-ai/claude-agent-sdk
# Python
pip install claude-agent-sdk
Running a Basic Agentโ
TypeScriptโ
import { query } from "@anthropic-ai/claude-agent-sdk";
async function runAgent() {
// query() is an async generator โ iterate it with for await
for await (const message of query({
prompt: "List the TypeScript files in the current directory and tell me the size of each one",
options: {
maxTurns: 5, // Allow up to 5 tool calls
}
})) {
if (message.type === "assistant") {
for (const block of message.content) {
if (block.type === "text") {
console.log(block.text);
}
}
}
}
}
runAgent();
Pythonโ
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def run_agent():
"""Run the Claude agent and print the results."""
async for message in query(
prompt="Find every TODO comment under src/ and organize them into a list",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Glob", "Grep"],
max_turns=5,
),
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(run_agent())
Handling Messages in Real Timeโ
query() returns an async generator (AsyncGenerator). You can process each message the moment it arrives:
import { query } from "@anthropic-ai/claude-agent-sdk";
async function streamingAgent() {
for await (const message of query({
prompt: "Analyze the project structure and suggest improvements",
options: {
maxTurns: 10,
}
})) {
if (message.type === "assistant") {
// Handle the agent's response
for (const block of message.content) {
if (block.type === "text") {
process.stdout.write(block.text);
}
}
} else if (message.type === "tool_use") {
// Monitor tool execution
console.log(`\n[Tool call] ${message.name}`);
}
}
}
Setting a System Promptโ
Define the agent's role and constraints:
import { query } from "@anthropic-ai/claude-agent-sdk";
const agentConfig = {
prompt: "Find security vulnerabilities in the codebase",
options: {
systemPrompt: `
You are a security expert.
You analyze vulnerabilities against the OWASP Top 10.
You classify each finding as [Severity: High/Medium/Low].
You provide concrete remediation steps.
You never modify files โ you only analyze.
`,
maxTurns: 20,
}
};
const result = await query(agentConfig);
Restricting Toolsโ
Limit which tools the agent may use:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Read-only agent (cannot modify anything)
const readOnlyAgent = {
prompt: "Analyze the project architecture",
options: {
allowedTools: ["Read", "Glob", "Grep"], // Read tools only
maxTurns: 15,
}
};
// Agent that can modify files (scoped to a specific directory)
const limitedAgent = {
prompt: "Refactor the files under src/utils/",
options: {
allowedTools: ["Read", "Glob", "Grep", "Edit", "Write"],
maxTurns: 30,
}
};
Processing Agent Resultsโ
import { query, SDKMessage } from "@anthropic-ai/claude-agent-sdk";
async function processResult(prompt: string) {
// To collect messages, push them into an array with for await
const messages: SDKMessage[] = [];
for await (const msg of query({ prompt })) {
messages.push(msg);
}
// Extract the final text response
const finalResponse = messages
.filter(m => m.type === "assistant")
.flatMap(m => (m as any).content)
.filter(c => c.type === "text")
.map(c => c.text)
.join("\n");
// Extract the list of tools used
const toolsUsed = messages
.filter(m => m.type === "tool_use")
.map(m => (m as any).name);
console.log("Response:", finalResponse);
console.log("Tools used:", [...new Set(toolsUsed)]);
return { response: finalResponse, tools: toolsUsed };
}
Setting the Working Directoryโ
Specify the directory the agent should work in:
import { query } from "@anthropic-ai/claude-agent-sdk";
const result = await query({
prompt: "Check the test coverage for this project",
options: {
cwd: "/path/to/project", // Set the working directory
maxTurns: 10,
}
});
Choosing the right tool
- Simple automation:
claude --print(headless CLI) - Complex pipelines: Agent SDK (programmatic control)
- Interactive work: Claude Code CLI (terminal conversation)
Found an issue on this page? Report it โ