From latestaiagents
Build your first Claude Agent SDK agent — TypeScript or Python. Covers installation, minimal agent loop, tool definitions, and the difference between "roll-your-own" and Managed Agents. Use this skill when starting a new AI agent project, migrating from raw messages.create loops to the Agent SDK, or evaluating SDK vs direct API. Activate when: Claude Agent SDK, @anthropic-ai/claude-agent-sdk, build agent, agent SDK quickstart, agent tutorial.
npx claudepluginhub latestaiagents/agent-skills --plugin skills-authoringThis skill uses the workspace's default tool permissions.
**The Claude Agent SDK is Anthropic's framework for building agents. It handles the tool-use loop, context compaction, sub-agent spawning, and MCP integration so you don't reinvent them.**
Builds and troubleshoots Claude Agent SDK apps in Python and TypeScript, covering APIs, sessions, permissions, streaming, tools, plugins, and extensibility.
Builds AI agents and automates Claude Code programmatically using Python Agent SDK, headless CLI mode (claude -p), MCP servers, hooks, and sessions. For programmatic agent creation without raw API keys.
Builds and deploys in-process autonomous AI agents using Open Agent SDK, an open-source CLI-free alternative to Anthropic's Claude agent SDK for TypeScript/Node.js in serverless, Docker, or CI/CD.
Share bugs, ideas, or general feedback.
The Claude Agent SDK is Anthropic's framework for building agents. It handles the tool-use loop, context compaction, sub-agent spawning, and MCP integration so you don't reinvent them.
messages.create loops| Approach | Best for | Tradeoff |
|---|---|---|
Direct messages.create | Simple one-shot calls | You manage everything |
| Agent SDK (client-side) | Custom agents with full control | You run the loop, manage state |
Managed Agents API (/v1/agents) | Production agents at scale | Anthropic runs the loop server-side |
Use the SDK when you need more control than Managed Agents but don't want to rewrite the tool loop.
TypeScript:
npm i @anthropic-ai/claude-agent-sdk
Python:
pip install claude-agent-sdk
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "What files are in the current directory?",
options: {
model: "claude-sonnet-4-6",
permissionMode: "default",
},
})) {
if (message.type === "assistant") {
for (const block of message.message.content) {
if (block.type === "text") process.stdout.write(block.text);
}
}
}
Under the hood: the SDK connects to Claude, provides default tools (file read, bash, web fetch), runs the tool-use loop, and streams results back.
import asyncio
from claude_agent_sdk import query
async def main():
async for msg in query(
prompt="What files are here?",
options={"model": "claude-sonnet-4-6"},
):
if msg.type == "assistant":
for block in msg.message.content:
if block.type == "text":
print(block.text, end="")
asyncio.run(main())
import { query, tool } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";
const getWeather = tool({
name: "get_weather",
description: "Get current weather for a city.",
inputSchema: z.object({ city: z.string() }),
handler: async ({ city }) => ({
content: [{ type: "text", text: `Weather in ${city}: sunny, 72°F` }],
}),
});
for await (const message of query({
prompt: "What's the weather in SF?",
options: {
model: "claude-sonnet-4-6",
tools: [getWeather],
},
})) { /* ... */ }
Tools are plain objects with a name, description, schema, and async handler. No magic.
options: {
permissionMode: "default", // prompt user for risky actions
// or "acceptEdits" // auto-approve edits, prompt for bash
// or "bypassPermissions" // YOLO (dev only)
// or "plan" // read-only, no writes
}
Use plan for dry-runs, default for interactive tools, acceptEdits only when you trust the agent.
Intercept tool calls before/after execution:
options: {
hooks: {
PreToolUse: async ({ toolName, input }) => {
console.log(`About to run ${toolName}`);
if (toolName === "bash" && input.command.includes("rm -rf")) {
return { decision: "block", reason: "Blocked destructive command" };
}
},
PostToolUse: async ({ toolName, output }) => {
await audit.log({ toolName, output });
},
},
}
Hooks run on your machine and can block, modify, or observe every tool call.
options: {
mcpServers: {
github: { command: "npx", args: ["-y", "@modelcontextprotocol/server-github"] },
},
}
MCP tools appear alongside built-in tools. See the mcp-client-integration skill.
options: {
systemPrompt: "You are a code reviewer. Be concise and actionable.",
// or append to the default:
appendSystemPrompt: "Always use TypeScript in examples.",
}
Use resume to continue a previous session:
const sessionId = "session-123";
for await (const msg of query({
prompt: "Follow up: what about tests?",
options: { model: "claude-sonnet-4-6", resume: sessionId },
})) { /* ... */ }
See the session-lifecycle skill for more.
bypassPermissions in production — first hallucinated rm is your lastmessages.create in the same agent — confuses session stateplan or default permission mode in prod; never bypassPermissionsresume for multi-turn rather than rebuilding history yourself