claude-agent-sdk-typescript

Expert guidance for building AI agents with the Claude Agent SDK in TypeScript/JavaScript. Use when the user writes TypeScript or JavaScript code with the SDK, imports from "@anthropic-ai/claude-agent-sdk", uses query(), allowedTools, permissionMode, creates custom tools with createSdkMcpServer, sets up hooks, integrates MCP servers, manages sessions, or debugs SDK issues in TypeScript/Node.js. Also triggers on: "@anthropic-ai/claude-agent-sdk", "allowedTools", "permissionMode", "npm install", "for await", "AgentDefinition", or "settingSources".

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "claude-agent-sdk-typescript" with this command: npx skills add waltersumbon/claude-agent-sdk-skill/waltersumbon-claude-agent-sdk-skill-claude-agent-sdk-typescript

Claude Agent SDK — TypeScript Guide

Production guidance for building AI agents with the Claude Agent SDK in TypeScript.

Naming: The Claude Code SDK was renamed to the Claude Agent SDK (v0.1.0+). Package: npm install @anthropic-ai/claude-agent-sdk · Import: import { query } from "@anthropic-ai/claude-agent-sdk"

Quick Reference — Two Interaction Modes

1. query() — Stateless, One-Shot

Best for: independent tasks, automation scripts, CI pipelines.

import { query, type ClaudeAgentOptions } from "@anthropic-ai/claude-agent-sdk";

const options: ClaudeAgentOptions = {
  allowedTools: ["Read", "Edit", "Glob"],
  permissionMode: "acceptEdits",
};

for await (const message of query({
  prompt: "Review utils.ts for bugs. Fix any issues you find.",
  options,
})) {
  if (message.type === "assistant") {
    for (const block of message.message.content) {
      if ("text" in block) console.log(block.text);
      else if ("name" in block) console.log(`Tool: ${block.name}`);
    }
  }
  if (message.type === "result") {
    console.log(`Done: ${message.subtype}`);
  }
}

2. ClaudeSDKClient — Stateful, Multi-Turn

Best for: conversations, follow-up questions, interactive apps.

import { ClaudeSDKClient } from "@anthropic-ai/claude-agent-sdk";

const client = new ClaudeSDKClient({
  options: {
    allowedTools: ["Read", "Write", "Bash"],
    permissionMode: "acceptEdits",
  },
});

try {
  await client.query("Analyze the codebase structure");
  for await (const msg of client.receiveMessages()) {
    console.log(msg);
  }
  // Continue the conversation with context preserved
  await client.query("Now refactor the largest file you found");
  for await (const msg of client.receiveMessages()) {
    console.log(msg);
  }
} finally {
  await client.close();
}

ClaudeAgentOptions — Complete Configuration

All options are optional. Key fields (all camelCase):

FieldTypeDescription
allowedToolsstring[]Tools Claude can use. See Built-in Tools below.
disallowedToolsstring[]Explicitly block specific tools.
permissionModestring"default", "acceptEdits", or "bypassPermissions".
systemPromptstring | objectCustom instructions. Use { type: "preset", preset: "claude_code" } for CC default.
modelstringe.g. "sonnet", "opus", "haiku", or full model string.
cwdstringWorking directory for the agent.
maxTurnsnumberMaximum agentic loop iterations.
settingSourcesstring[]["user", "project"] to load Skills/CLAUDE.md from filesystem.
mcpServersRecord<string, McpServerConfig>MCP server configurations.
agentsRecord<string, AgentDefinition>Named subagent definitions.
hooksobjectLifecycle hook callbacks.

Built-in Tools

Tool names for allowedTools:

  • File ops: Read, Write, Edit, MultiEdit
  • Search: Glob, Grep
  • Execution: Bash
  • Web: WebSearch, WebFetch
  • Delegation: Task (required for subagents)
  • Skills: Skill (requires settingSources)

Custom Tools via SDK MCP Server

Define in-process tools without a separate MCP server process:

import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";

const searchOrders = tool(
  "search_orders",
  "Search orders by customer ID",
  { customer_id: "string", status: "string" },
  async (args) => {
    const results = await db.queryOrders(args.customer_id, args.status);
    return { content: [{ type: "text", text: JSON.stringify(results) }] };
  }
);

const sendEmail = tool(
  "send_email",
  "Send an email notification",
  { to: "string", subject: "string", body: "string" },
  async (args) => {
    await emailService.send(args.to, args.subject, args.body);
    return { content: [{ type: "text", text: `Email sent to ${args.to}` }] };
  }
);

const server = createSdkMcpServer({
  name: "business-tools",
  tools: [searchOrders, sendEmail],
});

for await (const msg of query({
  prompt: "Find recent orders for customer C-123",
  options: {
    mcpServers: { biz: server },
    allowedTools: ["mcp__biz__search_orders", "mcp__biz__send_email"],
  },
})) {
  console.log(msg);
}

Tool naming convention: MCP tools are accessed as mcp__<server-name>__<tool-name>.

Subagents

Delegate specialized tasks to isolated agents with their own context and tool permissions:

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Review auth module for security issues, then write tests",
  options: {
    allowedTools: ["Read", "Grep", "Glob", "Task"], // Task is required
    agents: {
      "security-reviewer": {
        description: "Security specialist. Use for vulnerability analysis.",
        prompt: "You are a security expert. Analyze code for OWASP Top 10...",
        tools: ["Read", "Grep", "Glob"],
        model: "opus",
      },
      "test-writer": {
        description: "Test specialist. Use to generate test suites.",
        prompt: "You are a testing expert. Write comprehensive unit tests...",
        tools: ["Read", "Write", "Bash"],
        model: "sonnet",
      },
    },
  },
})) {
  if (message.type === "result") console.log(message.result);
}

Factory pattern for dynamic agents:

import type { AgentDefinition } from "@anthropic-ai/claude-agent-sdk";

function createReviewer(language: string): AgentDefinition {
  return {
    description: `${language} code review specialist`,
    prompt: `You are an expert ${language} developer...`,
    tools: ["Read", "Grep", "Glob"],
    model: ["rust", "c++"].includes(language) ? "opus" : "sonnet",
  };
}

Hooks — Lifecycle Callbacks

Available events: PreToolUse, PostToolUse, Stop, SessionStart, SessionEnd, UserPromptSubmit.

import { query, type HookCallback } from "@anthropic-ai/claude-agent-sdk";
import { appendFileSync } from "node:fs";

const blockDangerousCommands: HookCallback = async (input) => {
  if (input.tool_name === "Bash") {
    const cmd = input.tool_input?.command ?? "";
    const dangers = ["rm -rf /", "DROP TABLE", "mkfs"];
    if (dangers.some((d) => cmd.includes(d))) {
      return {
        hookSpecificOutput: {
          hookEventName: "PreToolUse",
          permissionDecision: "deny",
          permissionDecisionReason: `Blocked dangerous command: ${cmd}`,
        },
      };
    }
  }
  return {};
};

const auditLog: HookCallback = async (input) => {
  appendFileSync(
    "audit.log",
    `${new Date().toISOString()}: ${input.tool_name}: ${JSON.stringify(input.tool_input)}\n`
  );
  return {};
};

for await (const msg of query({
  prompt: "Refactor utils.ts",
  options: {
    permissionMode: "acceptEdits",
    hooks: {
      PreToolUse: [
        { matcher: "Bash", hooks: [blockDangerousCommands] },
        { matcher: ".*", hooks: [auditLog] },
      ],
    },
  },
})) {
  if (message.type === "result") console.log(msg.result);
}

MCP Integration (External Servers)

for await (const msg of query({
  prompt: "List open issues in the repo",
  options: {
    mcpServers: {
      github: {
        type: "stdio",
        command: "npx",
        args: ["-y", "@modelcontextprotocol/server-github"],
        env: { GITHUB_TOKEN: process.env.GITHUB_TOKEN! },
      },
      postgres: {
        type: "stdio",
        command: "docker",
        args: ["run", "mcp-postgres-server"],
        env: { DATABASE_URL: process.env.DATABASE_URL! },
      },
    },
    allowedTools: ["mcp__github", "mcp__postgres"],
  },
})) {
  console.log(msg);
}

You can mix SDK MCP servers (in-process) and external MCP servers in the same config.

Using Skills in the SDK

Skills are filesystem-based and must be explicitly enabled:

for await (const msg of query({
  prompt: "Help me process this PDF",
  options: {
    cwd: "/path/to/project",
    settingSources: ["user", "project"], // REQUIRED — loads Skills from filesystem
    allowedTools: ["Skill", "Read", "Write", "Bash"],
  },
})) {
  console.log(msg);
}

Common mistake: forgetting settingSources. Without it, Skills won't be discovered even if "Skill" is in allowedTools.

Skill locations:

  • Project: .claude/skills/*/SKILL.md (shared via git)
  • User: ~/.claude/skills/*/SKILL.md (personal, cross-project)

Note: The allowed-tools field in SKILL.md frontmatter only works in Claude Code CLI, not in the SDK. Use allowedTools in options to control tool access.

Sessions and Conversation Management

import { query } from "@anthropic-ai/claude-agent-sdk";

let sessionId: string | undefined;

// First interaction — capture sessionId
for await (const msg of query({
  prompt: "Review this codebase and identify the top 3 issues",
  options: { allowedTools: ["Read", "Glob", "Grep"] },
})) {
  if (msg.type === "system" && "session_id" in msg) {
    sessionId = msg.session_id;
  }
  console.log(msg);
}

// Resume with context
for await (const msg of query({
  prompt: "Now fix issue #1 that you found",
  options: {
    sessionId,
    allowedTools: ["Read", "Edit", "Bash"],
    permissionMode: "acceptEdits",
  },
})) {
  console.log(msg);
}

System Prompt Configuration

// 1. Custom system prompt (v0.1.0+ default: minimal prompt)
const options = { systemPrompt: "You are a senior TypeScript engineer..." };

// 2. Claude Code's full system prompt (opt-in)
const options = {
  systemPrompt: { type: "preset", preset: "claude_code" },
};

// 3. No system prompt — SDK default (minimal)
const options = {}; // uses minimal built-in prompt

Breaking change in v0.1.0: The SDK no longer loads Claude Code's system prompt by default. If you need the old behavior, explicitly set preset: "claude_code".

Authentication

# Direct API (default)
export ANTHROPIC_API_KEY=your-api-key

# Amazon Bedrock
export CLAUDE_CODE_USE_BEDROCK=1
# + configure AWS credentials

# Google Vertex AI
export CLAUDE_CODE_USE_VERTEX=1
# + configure GCP credentials

# Microsoft Azure AI Foundry
export CLAUDE_CODE_USE_FOUNDRY=1
# + configure Azure credentials

Common Patterns

Batch Processing (Parallel Agents)

async function processFile(filepath: string): Promise<string | undefined> {
  for await (const msg of query({
    prompt: `Review ${filepath} for security issues`,
    options: {
      allowedTools: ["Read", "Grep"],
      maxTurns: 50,
    },
  })) {
    if (msg.type === "result") return msg.result;
  }
}

const results = await Promise.all([
  processFile("auth.ts"),
  processFile("payments.ts"),
  processFile("users.ts"),
]);

Structured Output Collection

const messages: Message[] = [];
for await (const msg of query({ prompt: "Analyze this codebase", options })) {
  messages.push(msg);
}

// Extract final result
const result = messages.findLast((m) => "result" in m)?.result;

Error Handling

import { CLINotFoundError, CLIConnectionError } from "@anthropic-ai/claude-agent-sdk";

try {
  for await (const msg of query({ prompt: "...", options })) {
    console.log(msg);
  }
} catch (error) {
  if (error instanceof CLINotFoundError) {
    console.error("Claude Code CLI not found. Install: curl -fsSL https://claude.ai/install.sh | bash");
  } else if (error instanceof CLIConnectionError) {
    console.error(`Connection error: ${error.message}`);
  } else {
    throw error;
  }
}

Migration from Claude Code SDK (< v0.1.0)

Key changes:

  1. @anthropic-ai/claude-code@anthropic-ai/claude-agent-sdk
  2. ClaudeCodeOptionsClaudeAgentOptions (type name)
  3. System prompt no longer loads Claude Code's prompt by default
  4. settingSources must be explicitly set (was auto-loaded before)

Best Practices

  1. Principle of least privilege: Only grant tools the agent actually needs.
  2. Use permissionMode: "acceptEdits" for automation, "default" for interactive use.
  3. Prefer SDK MCP servers over external ones for custom tools — less overhead, easier debugging.
  4. Use subagents for specialized tasks — isolate context and apply the right model per task.
  5. Add hooks for safety — block dangerous commands and audit tool usage in production.
  6. Set maxTurns to prevent runaway agents in production environments.
  7. Use cwd to scope the agent to a specific directory.
  8. Capture sessionId from system messages if you need conversation continuity.

For troubleshooting common issues, see references/troubleshooting.md.

Official Resources

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Web3

Onchain Analyzer

Analyze wallet addresses and on-chain activity — transaction history, token holdings, DeFi positions, and trading patterns across EVM chains and Solana. Use...

Registry SourceRecently Updated
Web3

Idiom Dictionary

成语词典。成语查询、典故故事、成语接龙、成语猜谜、造句示例、分类浏览。Chinese idiom dictionary with stories, chain game, quiz. 成语、典故、国学。

Registry SourceRecently Updated
1341Profile unavailable
Web3

Crypto Price Pro

查询虚拟币实时价格和历史数据,支持生成趋势图、周报和邮件推送。当用户询问虚拟币价格、加密货币行情、需要币价分析报告或定时推送时使用此技能。

Registry SourceRecently Updated
00Profile unavailable
Web3

Crypto Whale Tracker

Track large cryptocurrency transfers (whale movements) using public APIs like Whale Alert and Etherscan. Set thresholds, monitor wallets, and generate format...

Registry SourceRecently Updated
1580Profile unavailable