API reference
The whole SDK is one entry point: query(options). It returns an async generator of SDKMessages. Everything else — tools, sandboxes, providers, sessions, teams — is configured through the options object.
query(options)
Mirrors @anthropic-ai/claude-agent-sdk's query(). Returns a Query — an AsyncGenerator<SDKMessage> with an interrupt() method.
import { query, createOpenAIClient, LocalSandbox } from 'anyclaude-sdk'
const q = query({
prompt: 'List the files and summarize the project.',
workspace: new LocalSandbox({ cwd: process.cwd() }),
llm: createOpenAIClient({ baseUrl: 'https://api.openai.com/v1', model: 'gpt-4o', apiKey: process.env.OPENAI_API_KEY }),
model: 'gpt-4o',
})
for await (const msg of q) {
if (msg.type === 'assistant') console.log(msg.message.content)
if (msg.type === 'result') console.log('done', msg.usage)
}
// q.interrupt() // abort the in-flight run from elsewhereThe prompt may be a plain string (single turn) or an AsyncIterable<SDKUserMessage> for multi-turn / interactive sessions (see PromptStream below).
QueryOptions
Only prompt, workspace, and llm are required. Everything else is optional.
Core
| Option | Type | Notes |
|---|---|---|
prompt | string | AsyncIterable<SDKUserMessage> | Required. One turn, or a stream of turns. |
workspace | Workspace | Required. FileSystem + CommandExecutor. See Sandboxes. |
llm | LLMClient | Required. See LLM providers. |
model | string | Model id sent to the client (overrides the client default per call). |
maxTurns | number | Max tool-loop iterations. Default 50. |
cwd | string | Working directory the agent operates in. |
abortController | AbortController | Stops the LLM stream + pending tools. Or use q.interrupt(). |
includePartialMessages | boolean | Emit stream_event text deltas as they arrive (live streaming UI). |
System prompt
systemPrompt | string | Replace the default system prompt entirely. |
appendSystemPrompt | string | Append to the default (e.g. describe the real OS/shell). |
Tools
tools | Tool[] | REPLACES the builtin set. Default: all builtins. |
extraTools | Tool[] | ADDS to the builtins. Use defineTool. See Tools. |
allowedTools | string[] | Whitelist by name. |
disallowedTools | string[] | Denylist (applied after allow). |
limits | Partial<FileReadLimits> | Tune read_file caps (size/tokens/image/pdf). |
onAskUser | (q) => Promise<string | string[]> | Enables the ask_user_question tool; resolve with the chosen label(s). See Tools. |
clientTools | string[] | Tool names executed on the client — the run pauses with a client_tool_request. See Tools. |
clientToolResults | { id, content, isError? }[] | On resume, injects the client's results for the pending client-tool calls. |
Survivor (serverless time caps)
maxDurationMs | number | Pause at the next turn boundary once elapsed; persists to the sessionStore and emits { system, subtype: 'paused' }. |
continueRun | boolean | Resume the loop with no new user message (continue the paused run). Use with resume: true. |
Adapters that satisfy SessionStoreLike: SessionStore (IndexedDB), MemorySessionStore, KVSessionStore, RedisSessionStore, PostgresSessionStore, SupabaseSessionStore. See Deploy.
Permissions & hooks
canUseTool | CanUseTool | Gate invoked before each tool call. |
permissionMode | PermissionMode | bypassPermissions · default · acceptEdits · plan · dontAsk. |
permissionRules | { allow?, deny?, ask? } | Rule strings → builds a gate. |
onPermissionAsk | (tool, input) => Promise<boolean> | Prompt callback for "ask" decisions. |
hooks | Partial<Record<HookEvent, HookCallback[]>> | Lifecycle hooks. See Hooks. |
settings | boolean | Settings | Load .claude/settings.json cascade, or pass a Settings object. |
Sub-agents, teams & background
agents | Record<string, AgentDefinition> | Custom sub-agents for the task tool. |
maxSubagentDepth | number | Max nesting. Default 2. |
background | boolean | Enable background tasks (task_list/output/stop). |
backgroundManager | BackgroundTaskManager | Inject a shared manager so tasks persist across turns. |
team | boolean | Teammate coordination (mailbox + board + coordinator prompt). |
mailbox / board | Mailbox / TaskBoard | Inject shared instances so they persist across turns. |
agentName | string | This agent's name for messaging. Default 'coordinator'. |
deliverTeamMessages | boolean | Auto-inject unread mailbox messages addressed to this agent at each turn boundary (push delivery). Default true when team is on. |
messageQueue | MessageQueue | Interject user messages mid-run (one per turn boundary). |
MCP
mcpServers | McpServers | External (HTTP/SSE) or in-process SDK servers. See MCP. |
mcpProxy | McpProxy | Route remote MCP through a proxy (browser CORS). |
commands | SlashCommand[] | Custom slash commands (merged with builtins). |
Sessions, memory & compaction
sessionStore | SessionStore | Persist the transcript (keyed by sessionId). |
sessionId | string | Session key. |
resume | boolean | Load the stored transcript before the first turn. |
memory | MemoryStore | Persistent memory loaded into the system prompt. |
skills | boolean | Skill[] | Load .claude/skills/*.md, or pass a Skill[]. |
autoCompact | boolean | Summarize the transcript near the context limit. |
contextLimit / compactThreshold | number | Context window (default model window or 200k) and trigger fraction (default 0.8). |
SDKMessage
The generator yields a discriminated union on type:
// 1. system / init — first message: model, tools, cwd, mcp status, permissionMode
{ type: 'system', subtype: 'init', tools: string[], model: string, cwd: string, … }
// 2. assistant — a model turn: text + tool_use blocks
{ type: 'assistant', message: { role: 'assistant', content: ContentBlock[] } }
// 3. stream_event — partial deltas (only when includePartialMessages: true)
{ type: 'stream_event', event: { type: 'content_block_delta', delta: { type: 'text_delta', text } } }
// 4. user — synthetic tool results (isSynthetic: true) or queued user turns
{ type: 'user', message: { role: 'user', content: ContentBlock[] }, isSynthetic?: boolean }
// 5. system / local_command_output — output of a slash command
{ type: 'system', subtype: 'local_command_output', content: string }
// 6. system / compact_boundary — emitted when the transcript was compacted
{ type: 'system', subtype: 'compact_boundary', compact_metadata: { trigger, pre_tokens } }
// 7. system / paused — survivor hit maxDurationMs; transcript persisted, resume with continueRun
{ type: 'system', subtype: 'paused', sessionId: string }
// 8. system / client_tool_request — a clientTools call; run pauses, resume with clientToolResults
{ type: 'system', subtype: 'client_tool_request', requests: { id, name, input }[] }
// 9. result — terminal: success or error, with usage + cost
{ type: 'result', subtype: 'success' | 'error_max_turns' | 'error_during_execution',
result?: string, usage: { input_tokens, output_tokens, … }, total_cost_usd: number,
duration_ms: number, num_turns: number }Multi-turn: PromptStream
For interactive sessions, feed turns with a push-based queue instead of a single string:
import { query, PromptStream } from 'anyclaude-sdk'
const prompts = new PromptStream()
const q = query({ prompt: prompts, workspace, llm, model })
;(async () => { for await (const m of q) render(m) })()
prompts.push('first message')
prompts.push('follow-up') // each push is a new user turn
// prompts.end() // close the conversationTo interject a message while a turn is still running (delivered at the next turn boundary), use messageQueue instead — see Sessions, hooks & more.
Key exports
Entry
query, PromptStream
LLM
createOpenAIClient, createAnthropicClient, createResponsesClient
Sandboxes
LocalSandbox, E2BSandbox, VercelSandbox, DaytonaSandbox, CloudflareSandbox, WebContainerWorkspace, composeWorkspace
Filesystems
MemoryFileSystem, DexieFileSystem, OpfsFileSystem, seedLinuxTree
Tools
defineTool, ALL_CLAUDE_CODE_TOOLS
Teams & bg
BackgroundTaskManager, Mailbox, TaskBoard, MessageQueue
Sessions
SessionStore, MemorySessionStore, KVSessionStore, RedisSessionStore, PostgresSessionStore, SupabaseSessionStore
MCP
createSdkMcpServer, tool
Commands
BUILTIN_COMMANDS, loadSkillsFromFs