Skip to main content
The Claude Code SDK is a control protocol for embedding Claude Code in other applications — IDEs, automation scripts, CI/CD pipelines, or any host that can spawn a subprocess and communicate over stdin/stdout. Rather than exposing a library API directly, the SDK communicates with a running claude process over a structured JSON message stream. The host process sends user messages and control requests; the CLI process streams back assistant messages, tool progress events, and result payloads.
The TypeScript types described on this page are exported from @anthropic-ai/claude-code under the agentSdkTypes entry point. Control protocol types (prefixed SDKControl) are @alpha and subject to change.

How it works

1

Spawn a Claude Code process

Start claude with --output-format stream-json and --print (non-interactive mode). Pipe its stdin and stdout into your host process.
claude --output-format stream-json --print --verbose
For a persistent session that accepts multiple prompts over time, omit --print and instead send SDKUserMessage objects to stdin after the session initializes.
2

Send an initialize request

Write a control_request with subtype: "initialize" to stdin. The CLI responds with an SDKControlInitializeResponse containing available commands, models, agents, and account information.
{
  "type": "control_request",
  "request_id": "init-1",
  "request": {
    "subtype": "initialize",
    "systemPrompt": "You are a code reviewer.",
    "appendSystemPrompt": "Always suggest tests."
  }
}
3

Stream messages from stdout

Read newline-delimited JSON from stdout. Each line is one of the SDKMessage union types — assistant turns, tool progress, system events, and result summaries.
4

Send user messages

Write SDKUserMessage objects to stdin to continue the conversation. Each message contains an Anthropic API-compatible message payload.

Output formats

Pass --output-format to control what Claude Code writes to stdout.
FormatDescription
textPlain text responses only. Default for interactive mode.
jsonSingle JSON object written at completion. Suitable for one-shot scripts.
stream-jsonNewline-delimited JSON stream. One message per line, emitted as events occur. Required for SDK use.
Use stream-json when you need to render progress incrementally or handle tool events. Use json when you only care about the final result.

Control protocol messages

The control protocol uses two top-level envelope types that flow bidirectionally over stdin/stdout.

SDKControlRequest

Sent to the CLI process to configure the session or issue commands.
{
  "type": "control_request",
  "request_id": "<unique-string>",
  "request": { "subtype": "...", ...payload }
}
type
literal: 'control_request'
required
Always "control_request".
request_id
string
required
Unique identifier for this request. The CLI echoes it back in the corresponding control_response.
request
SDKControlRequestInner
required
The request payload. subtype identifies which operation to perform.

SDKControlResponse

Emitted from the CLI process in response to a control_request.
{
  "type": "control_response",
  "response": {
    "subtype": "success",
    "request_id": "<echoed-id>",
    "response": { ...payload }
  }
}
On error, subtype is "error" and the error field contains a human-readable message.

Initialize request and response

The initialize request is the first control message you must send. It configures the session and returns available capabilities.

SDKControlInitializeRequest

{
  "type": "control_request",
  "request_id": "init-1",
  "request": {
    "subtype": "initialize",
    "systemPrompt": "You are a CI automation agent.",
    "appendSystemPrompt": "Always add test coverage.",
    "hooks": {
      "PreToolUse": [
        {
          "matcher": "Bash",
          "hookCallbackIds": ["my-hook-id"]
        }
      ]
    },
    "agents": {
      "CodeReviewer": {
        "description": "Reviews code for quality and security.",
        "prompt": "You are an expert code reviewer...",
        "model": "opus"
      }
    }
  }
}
subtype
literal: 'initialize'
required
Identifies this as an initialize request.
systemPrompt
string
Replaces the default system prompt for this session.
appendSystemPrompt
string
Appended to the system prompt without replacing it. Use this to add context while keeping the default behavior.
hooks
Record<HookEvent, SDKHookCallbackMatcher[]>
Registers SDK-side hook callbacks. The CLI calls back into the SDK process when hook events fire. See Hooks reference.
sdkMcpServers
string[]
Names of in-process SDK MCP servers (created with createSdkMcpServer) to connect to this session.
agents
Record<string, AgentDefinition>
Custom subagent definitions available to the Agent tool during this session.

SDKControlInitializeResponse

The CLI responds with the session’s current capabilities.
{
  "type": "control_response",
  "response": {
    "subtype": "success",
    "request_id": "init-1",
    "response": {
      "commands": [...],
      "agents": [...],
      "output_style": "stream-json",
      "available_output_styles": ["text", "json", "stream-json"],
      "models": [...],
      "account": {
        "email": "[email protected]",
        "organization": "Acme Corp",
        "apiProvider": "firstParty"
      }
    }
  }
}
commands
SlashCommand[]
Available slash commands (e.g., /compact, /cost). Each entry has name, description, and argumentHint.
agents
AgentInfo[]
Available subagent types. Each has name, description, and an optional model.
output_style
string
The active output format ("stream-json", "json", "text").
models
ModelInfo[]
Available models for this account.
account
AccountInfo
Logged-in account details.

User messages

Send user messages to stdin to drive the conversation forward.

SDKUserMessage

{
  "type": "user",
  "message": {
    "role": "user",
    "content": "Refactor this function to use async/await."
  },
  "parent_tool_use_id": null
}
type
literal: 'user'
required
Always "user".
message
APIUserMessage
required
An Anthropic API-compatible user message. content can be a string or a content block array (for images and other media).
parent_tool_use_id
string | null
required
Tool use ID this message is responding to, or null for top-level user messages.
uuid
string
Optional UUID to track this message. Echoed back in related events.
priority
'now' | 'next' | 'later'
Scheduling hint for async message queuing.

SDK message stream types

Claude Code emits a stream of JSON messages to stdout. The type field identifies each message.
Emitted once at session start with subtype: "init". Contains the active model, tool list, MCP server statuses, permission mode, and session ID.
{
  "type": "system",
  "subtype": "init",
  "model": "claude-sonnet-4-6",
  "tools": ["Bash", "Read", "Write", "Edit", "Glob", "Grep"],
  "mcp_servers": [],
  "permissionMode": "default",
  "session_id": "abc123",
  "uuid": "..."
}
Emitted when the model produces a turn. Contains the full Anthropic API response object, including any tool_use blocks.
{
  "type": "assistant",
  "message": { "role": "assistant", "content": [...] },
  "parent_tool_use_id": null,
  "uuid": "...",
  "session_id": "abc123"
}
Emitted during streaming with RawMessageStreamEvent payloads. Use these to render incremental output.
Emitted periodically for tools that take more than a few seconds (e.g., Bash commands). Contains tool_name, tool_use_id, and elapsed time.
Emitted at the end of each turn. subtype is "success" or one of the error subtypes.
{
  "type": "result",
  "subtype": "success",
  "result": "The function has been refactored.",
  "duration_ms": 4200,
  "total_cost_usd": 0.0042,
  "num_turns": 3,
  "is_error": false,
  "stop_reason": "end_turn",
  "session_id": "abc123",
  "uuid": "..."
}
Error subtypes: "error_during_execution", "error_max_turns", "error_max_budget_usd", "error_max_structured_output_retries".
Emitted with subtype: "status" when the permission mode or session status changes (e.g., "compacting").

Other control requests

Beyond initialize, the control protocol exposes these operations.
subtypeDirectionDescription
interrupthost → CLIInterrupt the current turn.
set_permission_modehost → CLIChange the active permission mode.
set_modelhost → CLISwitch to a different model mid-session.
can_use_toolCLI → hostPermission request for a tool call (requires SDK permission handler).
mcp_statushost → CLIGet MCP server connection statuses.
mcp_set_servershost → CLIReplace dynamically managed MCP servers.
get_context_usagehost → CLIGet context window usage breakdown.
get_settingshost → CLIRead the effective merged settings.
apply_flag_settingshost → CLIMerge settings into the flag settings layer.
rewind_fileshost → CLIRevert file changes made since a given message.
hook_callbackCLI → hostDeliver a hook event for an SDK-registered hook callback.
reload_pluginshost → CLIReload plugins from disk.

Session management API

For scripting scenarios, the SDK exports functions that operate on saved session transcripts stored in ~/.claude/.
import {
  query,
  listSessions,
  getSessionInfo,
  getSessionMessages,
  forkSession,
  renameSession,
  tagSession,
} from '@anthropic-ai/claude-code'
The primary SDK entry point. Accepts a prompt string or AsyncIterable<SDKUserMessage> and returns an async iterable of SDKMessage.
for await (const message of query({
  prompt: 'What files are in this directory?',
  options: { cwd: '/my/project' }
})) {
  if (message.type === 'result') {
    console.log(message.result)
  }
}
Returns session metadata for a project directory. Pass dir to scope to a specific project, or omit to list all sessions.
const sessions = await listSessions({ dir: '/my/project', limit: 50 })
Parses the JSONL transcript file for a session and returns messages in chronological order.
const messages = await getSessionMessages(sessionId, {
  dir: '/my/project',
  includeSystemMessages: false,
})
Copies a session’s transcript into a new session with remapped UUIDs. Supports upToMessageId to fork from a specific point.
const { sessionId: newId } = await forkSession(originalSessionId, {
  upToMessageId: 'msg-uuid',
  title: 'Experimental branch',
})
await renameSession(sessionId, 'My refactor session')
await tagSession(sessionId, 'needs-review')
await tagSession(sessionId, null) // clear tag

Use cases

IDEs can spawn a persistent Claude Code process and route messages through the control protocol. Send the initialize request with a custom systemPrompt that describes the IDE context, then forward user messages from the editor’s chat panel. Use PreToolUse hook callbacks to intercept file edits and display diffs in the IDE’s native UI before they are applied.