Skip to main content

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โ€‹

AspectClaude Code CLIAgent SDK
How you use itTerminal conversationControlled from code
Best suited forImmediate help while developingAutomated pipelines
CustomizationCLAUDE.md, SkillsFull programmatic control
UserIndividual developerSystem / 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)