---
title: "Agent SDK TypeScript API Reference"
aliases: [typescript-sdk-reference, agent-sdk-typescript, ts-api-reference]
tags: [agent-sdk, typescript, api-reference, anthropic, claude, mcp, hooks]
sources: [raw/Agent SDK reference - TypeScript.md]
created: 2026-04-17
updated: 2026-04-17
---

# Agent SDK — TypeScript API Reference

Complete API reference for `@anthropic-ai/claude-agent-sdk` (TypeScript/Node.js).

> A simplified V2 interface with `send()` and `stream()` patterns is in preview. This doc covers the current stable API.

## Installation

```bash
npm install @anthropic-ai/claude-agent-sdk
```

---

## Core Functions

### query()

Primary entry point. Returns an async generator that streams `SDKMessage` objects.

```typescript
function query({
  prompt: string | AsyncIterable<SDKUserMessage>,
  options?: Options
}): Query;
```

- `prompt` — string or async iterable (for streaming multi-turn input)
- `options` — see [[#Options]] below
- Returns a `Query` object (extends `AsyncGenerator<SDKMessage>`)

### startup()

Pre-warms the CLI subprocess before a prompt is ready. Moves spawn + handshake cost off the critical path.

```typescript
const warm = await startup({ options: { maxTurns: 3 } });
for await (const msg of warm.query("What files are here?")) { ... }
```

- Returns `Promise<WarmQuery>`
- `initializeTimeoutMs` defaults to `60000` ms
- `WarmQuery.query()` can only be called once; use `WarmQuery.close()` to discard
- Implements `AsyncDisposable` — supports `await using` for auto-cleanup

### tool()

Creates a type-safe MCP tool definition using a Zod schema.

```typescript
const myTool = tool("search", "Search the web", { query: z.string() },
  async ({ query }) => ({ content: [{ type: "text", text: `Results for: ${query}` }] }),
  { annotations: { readOnlyHint: true, openWorldHint: true } }
);
```

Supports both Zod 3 and Zod 4. Pass to `createSdkMcpServer()`.

### createSdkMcpServer()

Creates an in-process MCP server.

```typescript
createSdkMcpServer({ name: "my-server", version: "1.0", tools: [myTool] })
```

### Session Management

| Function | Description |
|----------|-------------|
| `listSessions(options?)` | List past sessions; filter by `dir`, `limit`, `includeWorktrees` |
| `getSessionMessages(sessionId, options?)` | Read messages from a session transcript |
| `getSessionInfo(sessionId, options?)` | Fetch metadata for one session by ID |
| `renameSession(sessionId, title, options?)` | Set a custom title (most recent wins) |
| `tagSession(sessionId, tag \| null, options?)` | Tag or clear tag on a session |

`listSessions` returns `SDKSessionInfo[]` sorted by `lastModified` descending.

---

## Options

Key properties for `query()` / `startup()`:

| Property | Type | Default | Notes |
|----------|------|---------|-------|
| `prompt` | `string` | — | Initial prompt |
| `model` | `string` | CLI default | Claude model to use |
| `maxTurns` | `number` | unlimited | Max tool-use round trips |
| `effort` | `'low'\|'medium'\|'high'\|'xhigh'\|'max'` | `'high'` | Guides thinking depth |
| `thinking` | `ThinkingConfig` | `{type:'adaptive'}` | `adaptive` / `enabled` / `disabled` |
| `permissionMode` | `PermissionMode` | `'default'` | See [[#Permission Mode]] |
| `allowedTools` | `string[]` | `[]` | Auto-approve (does NOT restrict) |
| `disallowedTools` | `string[]` | `[]` | Always deny; overrides allowedTools |
| `canUseTool` | `CanUseTool` | — | Custom permission function |
| `mcpServers` | `Record<string, McpServerConfig>` | `{}` | MCP server map |
| `agents` | `Record<string, AgentDefinition>` | — | Programmatic subagent definitions |
| `systemPrompt` | `string \| {type:'preset'}` | minimal | Use `preset: 'claude_code'` to load full CC prompt |
| `settingSources` | `SettingSource[]` | all | Control which filesystem settings load |
| `resume` | `string` | — | Resume a session by ID |
| `sessionId` | `string` | auto | Pin session to specific UUID |
| `persistSession` | `boolean` | `true` | Set `false` to skip disk persistence |
| `maxBudgetUsd` | `number` | — | Hard cost cap (client-side estimate) |
| `enableFileCheckpointing` | `boolean` | `false` | Enable file rewind |
| `hooks` | `Partial<Record<HookEvent, HookCallbackMatcher[]>>` | `{}` | Programmatic hook callbacks |
| `sandbox` | `SandboxSettings` | — | Sandbox configuration |
| `plugins` | `SdkPluginConfig[]` | `[]` | Local plugin paths |
| `outputFormat` | `{type:'json_schema', schema}` | — | Structured output schema |
| `promptSuggestions` | `boolean` | `false` | Emit predicted next prompt after each turn |

### settingSources

Controls which filesystem settings are loaded. Precedence: local > project > user > managed policy (always loaded).

```typescript
settingSources: []              // SDK-only — no filesystem settings
settingSources: ["project"]     // CI: only .claude/settings.json
settingSources: ["user","project","local"]  // Default (same as omitting)
```

---

## Query Object

The object returned by `query()` — extends `AsyncGenerator<SDKMessage>`.

| Method | Description |
|--------|-------------|
| `interrupt()` | Interrupt (streaming input mode only) |
| `rewindFiles(msgId, {dryRun?})` | Restore files to checkpoint; requires `enableFileCheckpointing` |
| `setPermissionMode(mode)` | Change permission mode mid-session |
| `setModel(model?)` | Change model mid-session |
| `streamInput(stream)` | Feed async iterable of `SDKUserMessage` for multi-turn |
| `stopTask(taskId)` | Stop a background task |
| `setMcpServers(servers)` | Dynamically replace MCP servers; returns `McpSetServersResult` |
| `mcpServerStatus()` | Status of all connected MCP servers |
| `supportedModels()` | Available models with display info |
| `supportedAgents()` | Available subagents as `AgentInfo[]` |
| `accountInfo()` | Authenticated account info |
| `initializationResult()` | Full init data (commands, agents, models, etc.) |
| `close()` | Terminate process and clean up |

---

## Permission Types

### PermissionMode

```
"default"           Standard prompting
"acceptEdits"       Auto-accept file edits
"bypassPermissions" Skip all checks (requires allowDangerouslySkipPermissions)
"plan"              Planning only — no execution
"dontAsk"           Deny if not pre-approved
"auto"              Model classifier approves/denies each tool call
```

### CanUseTool

Custom permission callback with full context:

```typescript
type CanUseTool = (
  toolName: string,
  input: Record<string, unknown>,
  options: { signal, suggestions?, blockedPath?, decisionReason?, toolUseID, agentID? }
) => Promise<{ behavior: "allow"; updatedInput?; updatedPermissions? }
           | { behavior: "deny"; message; interrupt? }>;
```

### PermissionUpdate operations

`addRules` / `replaceRules` / `removeRules` / `setMode` / `addDirectories` / `removeDirectories`

Destinations: `"userSettings"` | `"projectSettings"` | `"localSettings"` | `"session"` | `"cliArg"`

---

## Message Types

`SDKMessage` is a discriminated union on the `type` field:

| Type | Subtype | Description |
|------|---------|-------------|
| `assistant` | — | Assistant response; `message` is `BetaMessage` from Anthropic SDK |
| `user` | — | User input; set `shouldQuery: false` to inject context without triggering a turn |
| `result` | `success` / `error_*` | Final result with cost, usage, turns, structured output |
| `system` | `init` | Session initialization (tools, MCP servers, model, permission mode) |
| `system` | `compact_boundary` | Conversation compaction event |
| `system` | `status` | Status update (e.g., `"compacting"`) |
| `system` | `task_started` / `task_progress` / `task_notification` | Background task lifecycle |
| `system` | `hook_started` / `hook_progress` / `hook_response` | Hook execution events |
| `system` | `plugin_install` | Plugin install progress |
| `system` | `files_persisted` | File checkpointing event |
| `stream_event` | — | Partial assistant message (only with `includePartialMessages: true`) |
| `tool_progress` | — | Periodic tool execution progress |
| `rate_limit_event` | — | Rate limit status |
| `prompt_suggestion` | — | Predicted next prompt (only with `promptSuggestions: true`) |
| `auth_status` | — | Auth flow events |

---

## Hook System

Hook events fire at lifecycle points. Attach via `options.hooks` in `query()`.

### HookEvent values

`PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `Notification`, `UserPromptSubmit`, `SessionStart`, `SessionEnd`, `Stop`, `SubagentStart`, `SubagentStop`, `PreCompact`, `PermissionRequest`, `Setup`, `TeammateIdle`, `TaskCompleted`, `ConfigChange`, `WorktreeCreate`, `WorktreeRemove`

### HookCallbackMatcher

```typescript
interface HookCallbackMatcher {
  matcher?: string;       // Optional glob/regex filter
  hooks: HookCallback[];
  timeout?: number;       // Seconds
}
```

### SyncHookJSONOutput — key fields

- `continue`: `false` to block
- `decision`: `"approve"` | `"block"`
- `hookSpecificOutput.permissionDecision`: `"allow"` | `"deny"` | `"ask"` (for `PreToolUse`)
- `hookSpecificOutput.additionalContext`: inject context into the next turn
- `hookSpecificOutput.updatedInput`: modify tool input (for `PreToolUse`)
- `hookSpecificOutput.updatedMCPToolOutput`: modify MCP result (for `PostToolUse`)

---

## AgentDefinition

Programmatically define subagents in `options.agents`:

```typescript
type AgentDefinition = {
  description: string;   // When to use this agent (required)
  prompt: string;        // System prompt (required)
  tools?: string[];
  disallowedTools?: string[];
  model?: "sonnet" | "opus" | "haiku" | "inherit";
  mcpServers?: AgentMcpServerSpec[];
  skills?: string[];
  maxTurns?: number;
};
```

---

## MCP Server Config Types

| Type | Transport | Key fields |
|------|-----------|------------|
| `McpStdioServerConfig` | stdio (default) | `command`, `args?`, `env?` |
| `McpSSEServerConfig` | SSE | `url`, `headers?` |
| `McpHttpServerConfig` | HTTP | `url`, `headers?` |
| `McpSdkServerConfigWithInstance` | in-process | `name`, `instance` |
| `McpClaudeAIProxyServerConfig` | proxy | `url`, `id` |

---

## Built-in Tool I/O Types

All exported from `@anthropic-ai/claude-agent-sdk` as `ToolInputSchemas` / `ToolOutputSchemas`.

### Key tool input shapes

| Tool | Key inputs |
|------|-----------|
| `Bash` | `command`, `timeout?`, `run_in_background?`, `dangerouslyDisableSandbox?` |
| `Read` | `file_path`, `offset?`, `limit?`, `pages?` |
| `Write` | `file_path`, `content` |
| `Edit` | `file_path`, `old_string`, `new_string`, `replace_all?` |
| `Glob` | `pattern`, `path?` |
| `Grep` | `pattern`, `path?`, `glob?`, `output_mode?`, `multiline?` |
| `Agent` | `description`, `prompt`, `subagent_type`, `run_in_background?`, `isolation?` |
| `WebSearch` | `query`, `allowed_domains?`, `blocked_domains?` |
| `TodoWrite` | `todos: [{content, status, activeForm}]` |
| `EnterWorktree` | `name?` or `path?` (mutually exclusive) |

### SDKResultMessage cost fields

- `total_cost_usd` — client-side estimate (see cost-tracking docs for accuracy caveats)
- `modelUsage` — per-model breakdown with `inputTokens`, `outputTokens`, `costUSD`, `contextWindow`

---

## Sandbox Settings

```typescript
sandbox: {
  enabled: true,
  autoAllowBashIfSandboxed: true,     // default true
  excludedCommands: ["docker"],        // always bypass, no model control
  allowUnsandboxedCommands: true,      // model can request dangerouslyDisableSandbox
  network: {
    allowedDomains: ["api.example.com"],
    allowLocalBinding: true,
    allowUnixSockets: ["/var/run/docker.sock"]  // ⚠️ grants full Docker/host access
  },
  filesystem: {
    allowWrite: ["/tmp/*"],
    denyRead: ["/etc/secrets"]
  }
}
```

**`excludedCommands` vs `allowUnsandboxedCommands`:** excluded commands always bypass silently; `allowUnsandboxedCommands` lets the model *request* bypass at runtime, which then falls through to `canUseTool`.

> **Warning:** `bypassPermissions` + `allowUnsandboxedCommands` = model can escape sandbox silently.

---

## ThinkingConfig

```typescript
{ type: "adaptive" }                      // Model decides when/how much (Opus 4.6+)
{ type: "enabled", budgetTokens?: number } // Fixed token budget
{ type: "disabled" }
```

`effort` option also guides thinking depth without hard token limits.

---

## Key Takeaways

- **`query()`** is the main entry point — async generator returning `SDKMessage` stream
- **`startup()`** pre-warms the subprocess for latency-sensitive applications; returns `WarmQuery`
- **`tool()` + `createSdkMcpServer()`** let you define in-process MCP tools with Zod schemas
- **`settingSources: []`** for fully programmatic SDK apps; `["project"]` for CI consistency
- **`canUseTool`** callback gives fine-grained runtime control over tool permissions
- **Hooks** (`options.hooks`) run in-process; can block tools, modify inputs/outputs, inject context
- **`AgentDefinition`** allows defining subagents programmatically without CLAUDE.md / settings files
- **`SDKResultMessage`** contains `total_cost_usd`, `usage`, `modelUsage` — always a client-side estimate
- **Sandbox** `excludedCommands` is static; `allowUnsandboxedCommands` is model-controlled — don't combine with `bypassPermissions`
- **`rewindFiles()`** requires `enableFileCheckpointing: true`; use `dryRun` to preview
- **`setMcpServers()`** on a live Query object replaces the MCP server set mid-session

---

## Related Articles

- [[wiki/agent-sdk/python-api-reference|Python API Reference]] — Python equivalent of this reference
- [[wiki/agent-sdk/overview|Agent SDK Overview]] — SDK capabilities, built-in tools, Client SDK comparison
- [[wiki/tech-patterns/ai-patterns|AI Patterns]] — How agents are wired into Oliver Agency projects

---

## Sources

- `raw/Agent SDK reference - TypeScript.md` (clipped from https://code.claude.com/docs/en/agent-sdk/typescript)
