Code Mode API reference
Last updated Jul 22, 2026 Code Mode publishes six package entry points. Import framework-specific APIs from their matching entry point:
| Entry point | Purpose |
|---|---|
@cloudflare/codemode |
Runtime, connectors, Workers executor, and framework-independent utilities |
@cloudflare/codemode/ai |
AI SDK tools and connector adapter |
@cloudflare/codemode/mcp |
Model Context Protocol (MCP) server wrappers |
@cloudflare/codemode/tanstack-ai |
TanStack AI tools and adapter |
@cloudflare/codemode/browser |
Browser tool descriptor and iframe executor |
@cloudflare/codemode/vite |
Vite plugin for connector discovery and Worker exports |
@cloudflare/codemode
The main entry point does not require the optional AI SDK, TanStack AI, or Zod peer dependencies to be installed.
Runtime construction
createCodemodeRuntime()
function createCodemodeRuntime(
options: CreateCodemodeRuntimeOptions,
): CodemodeRuntimeHandle;
Creates the host-side control plane for a named Code Mode runtime.
CreateCodemodeRuntimeOptions has these fields:
| Field | Type | Required | Description |
|---|---|---|---|
ctx |
DurableObjectState |
Yes | Durable Object state that hosts the runtime facet. |
connectors |
CodemodeConnector[] |
Yes | Connectors exposed as sandbox globals. Connector names must be unique, and codemode is reserved. |
executor |
Executor |
Yes | Sandbox that runs generated code. |
name |
string |
No | Durable runtime identity. Defaults to "default". Valid characters are letters, digits, _, -, and .. |
maxExecutions |
number |
No | Terminal records kept when a new run begins. Defaults to 50. Running and paused executions are not pruned. |
transformResult |
TransformResult |
No | Reshapes a completed result returned to the model. The audit trail retains the unmodified result. |
interface CodemodeRuntimeHandle {
tool(
options?: CodemodeRuntimeToolOptions,
): Tool<ProxyToolInput, ProxyToolOutput>;
execute(input: ProxyToolInput): Promise<ProxyToolOutput>;
search(query: string): Promise<SearchOutput>;
describe(target: string): Promise<DescribeOutput>;
approve(options: CodemodeApproveOptions): Promise<ProxyToolOutput>;
reject(options: CodemodeRejectOptions): Promise<boolean>;
rollback(options: CodemodeRollbackOptions): Promise<void>;
pending(executionId?: string): Promise<PendingAction[]>;
expirePaused(options?: CodemodeExpireOptions): Promise<string[]>;
executions(limit?: number): Promise<ExecutionState[]>;
deleteExecution(id: string): Promise<boolean>;
pruneExecutions(keep?: number): Promise<number>;
saveSnippet(name: string, options: SaveSnippetOptions): Promise<Snippet>;
snippets(): Promise<Snippet[]>;
deleteSnippet(name: string): Promise<boolean>;
}
The handle methods have these effects:
| Method | Effect |
|---|---|
tool(options?) |
Returns the AI SDK tool given to the model. description replaces the default description. connectorHints adds a one-line hint for each connector when using the default description. |
execute({ code }) |
Runs code directly without adapting the runtime to an AI SDK tool. The result can complete, pause for approval, or return an error status. |
search(query) |
Searches connector methods and saved snippets without running sandbox code. |
describe(target) |
Returns on-demand TypeScript documentation for a connector, method, or saved snippet. |
approve({ executionId }) |
Resumes a paused execution through replay. The result can complete, pause again, or return an error status. It does not revive a non-paused execution. |
reject({ seq, executionId }) |
Rejects one pending action and terminates the execution. Returns false if the action is no longer pending. It does not roll back earlier actions. |
rollback({ executionId }) |
Calls available revert functions in reverse call order. Missing connectors and methods without revert remain applied. It attempts later reverts after a failure. |
pending(executionId?) |
Lists pending actions. Without an ID, it combines actions from all paused executions. |
expirePaused({ maxAgeMs? }) |
Terminates stale paused or running executions and returns their IDs. The default age is 24 hours. |
executions(limit?) |
Returns audit records, newest first. |
deleteExecution(id) |
Deletes one audit record. It also disposes resources for a non-terminal execution. Returns whether the record existed. |
pruneExecutions(keep?) |
Deletes older terminal records and returns the count deleted. Defaults to keeping 50. |
saveSnippet(name, options) |
Saves code from options.executionId as a reusable snippet. It accepts any execution status, so applications should verify successful completion first. Replaces the same name. |
snippets() |
Returns saved snippets, ordered by name. |
deleteSnippet(name) |
Deletes a snippet and returns whether it existed. |
The method option types are:
type CodemodeRuntimeToolOptions = {
description?: string;
connectorHints?: Record<string, string>;
};
type CodemodeApproveOptions = { executionId: string };
type CodemodeRejectOptions = { seq: number; executionId: string };
type CodemodeRollbackOptions = { executionId: string };
type CodemodeExpireOptions = { maxAgeMs?: number };
CodemodeRuntime
class CodemodeRuntime extends DurableObject<unknown> {
constructor(ctx: DurableObjectState, env: unknown);
}
CodemodeRuntime is the durable facet behind the runtime handle. The Vite plugin exports this class from the Worker entry module. Use createCodemodeRuntime() for application code instead of constructing the facet directly.
The main entry point also exports these runtime constants:
| Constant | Value | Purpose |
|---|---|---|
DEFAULT_MAX_EXECUTIONS |
50 |
Default terminal execution retention count |
DEFAULT_PAUSED_TTL_MS |
86400000 |
Default stale execution age in milliseconds (24 hours) |
MAX_DURABLE_VALUE_BYTES |
1000000 |
Serialized JavaScript string-length limit for one durable value |
Runtime tool input and output
type ProxyToolInput = { code: string };
type ProxyToolOutput =
| {
status: "completed";
executionId: string;
result: unknown;
logs?: string[];
}
| {
status: "paused";
executionId: string;
pending: PendingAction[];
}
| {
status: "error";
executionId: string;
error: string;
logs?: string[];
};
type TransformResult = (result: unknown) => unknown | Promise<unknown>;
Sandbox and replay errors use the error output variant. They do not throw through the model tool call.
Execution records
type ExecutionStatus =
| "running"
| "paused"
| "completed"
| "error"
| "rejected"
| "rolled_back";
type ExecutionState = {
id: string;
code: string;
status: ExecutionStatus;
log: ToolLogEntry[];
result?: unknown;
error?: string;
logs?: string[];
connectors?: string[];
createdAt: number;
updatedAt: number;
};
type ToolLogEntry = {
seq: number;
connector: string;
method: string;
args: unknown;
result?: unknown;
requiresApproval: boolean;
ephemeral?: boolean;
state: "executing" | "applied" | "pending" | "reverted" | "error";
};
type PendingAction = {
executionId: string;
seq: number;
connector: string;
method: string;
args: unknown;
};
createdAt and updatedAt contain epoch milliseconds. An ephemeral log entry comes from a connector tool with replay: "reexecute". Its result is not stored and the call runs again during replay.
The runtime decision type is:
type ToolDecision =
| { kind: "replay"; result: unknown }
| { kind: "execute"; seq: number }
| { kind: "pause"; seq: number };
Sandbox codemode API
runtime.tool() injects a codemode global into generated sandbox code.
declare const codemode: {
search(query: string): Promise<SearchOutput>;
describe(target: string): Promise<DescribeOutput>;
step<T>(name: string, fn: () => T | Promise<T>): Promise<T>;
run(name: string, input?: unknown): Promise<unknown>;
};
The sandbox methods behave as follows:
| Method | Description |
|---|---|
search(query) |
Searches connector methods and saved snippets. Results are ranked and limited to 50. |
describe(target) |
Returns generated TypeScript for a connector, connector.method, or snippet name. |
step(name, fn) |
Runs a closure once and records its result. Replay returns the recorded result without running the closure again. |
run(name, input?) |
Runs a saved snippet. A missing snippet or recorded connector resolves to an object with an error property. |
Use step() around nondeterministic or side-effectful sandbox work that does not use a connector. Issue connector calls sequentially when an execution can pause. Concurrent calls can reach the replay cursor in a different order.
The discovery output types are:
type SearchResult = {
path: string;
connector: string;
method: string;
description?: string;
requiresApproval?: boolean;
kind: "method" | "snippet";
score: number;
};
type SearchOutput = {
results: SearchResult[];
total: number;
truncated: boolean;
};
type DescribeOutput = {
path: string;
description?: string;
requiresApproval?: boolean;
types: string;
kind: "connector" | "method" | "snippet";
};
requiresApproval is true when a connector method pauses before execution. It is omitted for methods that do not require approval and for snippets.
Snippet types
interface SaveSnippetOptions {
description?: string;
inputSchema?: unknown;
executionId: string;
}
interface Snippet {
name: string;
description: string;
code: string;
savedAt: number;
inputSchema?: unknown;
connectors?: string[];
}
connectors records every namespace configured when the source execution started. savedAt contains epoch milliseconds. Before calling saveSnippet(), verify that the source ExecutionState.status is completed.
Executor API
Executor
interface Executor {
execute(
code: string,
providersOrFns:
| ResolvedProvider[]
| Record<string, (...args: unknown[]) => Promise<unknown>>,
options?: ExecuteOptions,
): Promise<ExecuteResult>;
}
Custom executors should report failures in ExecuteResult.error instead of throwing.
interface ExecuteResult {
result: unknown;
error?: string;
logs?: string[];
}
interface ResolvedProvider {
name: string;
fns: Record<string, (...args: unknown[]) => Promise<unknown>>;
prelude?: string;
}
interface ConnectorBinding {
name: string;
binding: {
callTool(method: string, args: unknown): Promise<unknown>;
};
}
interface ExecuteOptions {
connectors?: ConnectorBinding[];
}
Passing a function record instead of ResolvedProvider[] is deprecated. It creates one provider named codemode.
DynamicWorkerExecutor
class DynamicWorkerExecutor implements Executor {
constructor(options: DynamicWorkerExecutorOptions);
execute(
code: string,
providersOrFns:
| ResolvedProvider[]
| Record<string, (...args: unknown[]) => Promise<unknown>>,
options?: ExecuteOptions,
): Promise<ExecuteResult>;
}
DynamicWorkerExecutorOptions has these fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
loader |
WorkerLoader |
Yes | — | Worker Loader binding used to create isolated Workers. |
timeout |
number |
No | 60000 |
Execution timeout in milliseconds. |
globalOutbound |
Fetcher \| null |
No | null |
Outbound network policy. null blocks access. A Fetcher receives all outbound requests. |
modules |
Record<string, string> |
No | {} |
Module source keyed by import specifier. The reserved executor.js key is ignored. |
bindings |
Record<string, unknown> |
No | {} |
Additional environment bindings injected into each sandbox Worker. |
The executor validates provider and connector namespaces. Names must be valid JavaScript identifiers, unique, and must not shadow executor globals.
ToolDispatcher
class ToolDispatcher extends RpcTarget {
constructor(fns: Record<string, (...args: unknown[]) => Promise<unknown>>);
call(name: string, argsJson?: string): Promise<string>;
}
ToolDispatcher is the Workers RPC bridge used by DynamicWorkerExecutor. call() accepts serialized positional arguments and returns a serialized result or error envelope.
runCode()
function runCode(options: {
code: string;
executor: Executor;
providers: ResolvedProvider[];
connectors?: ConnectorBinding[];
}): Promise<{ result: unknown; logs?: string[] }>;
Normalizes and executes code. An ExecuteResult.error causes runCode() to throw an Error that includes captured console output.
Tool providers
interface ToolProvider {
name?: string;
tools: ToolDescriptors | ToolSet | SimpleToolRecord;
types?: string;
}
Tool providers have these fields:
| Field | Description |
|---|---|
name |
Sandbox namespace. Defaults to codemode. |
tools |
Tool descriptors, an AI SDK ToolSet, or records containing execute. |
types |
TypeScript declarations shown to the model. Code Mode generates them when omitted. |
function resolveProvider(provider: ToolProvider): ResolvedProvider;
The main-entry implementation does not validate inputs against schemas. It excludes tools whose needsApproval is true or a function. Use runtime connectors for durable approval flows.
Connector base classes
CodemodeConnector
abstract class CodemodeConnector<
Env = unknown,
Props = unknown,
> extends WorkerEntrypoint<Env, Props> {
constructor(ctx: DurableObjectState | ExecutionContext, env: Env);
abstract name(): string;
protected instructions(): string | undefined;
protected abstract tools(): ConnectorTools | Promise<ConnectorTools>;
protected tool(name: string, tool: ConnectorTool): ConnectorTool;
describe(): Promise<ConnectorDescription>;
executeTool(
method: string,
args: unknown,
ctx?: ToolExecuteContext,
): Promise<unknown>;
revertAction(
method: string,
args: unknown,
result: unknown,
ctx?: ToolExecuteContext,
): Promise<boolean>;
onPassEnd(executionId: string, status: PassEndStatus): Promise<void>;
disposeExecution(
executionId: string,
status: ExecutionEndStatus,
): Promise<void>;
getTypeScriptTypes(): Promise<string>;
}
Connector authors implement or override these hooks:
| Hook | Required | Description |
|---|---|---|
name() |
Yes | Returns the unique sandbox namespace. |
instructions() |
No | Returns connector guidance included by describe(). |
tools() |
Yes | Returns the connector tool record. Derived connectors implement this hook. |
tool(name, tool) |
No | Decorates a resolved tool. Use it to add approval, replay, or revert behavior to derived tools. |
onPassEnd(executionId, status) |
No | Releases per-pass resources. Runs after every pass, including a paused pass. |
disposeExecution(executionId, status) |
No | Releases per-execution resources after a terminal transition. It does not run on pause. |
Lifecycle hooks should be idempotent, should not rely on instance memory, and should not throw. On a terminal pass, onPassEnd() runs before disposeExecution().
The base class derives describe(), executeTool(), revertAction(), and getTypeScriptTypes() from the tool record. Connector authors do not need to implement these methods.
Connector tool types
type ConnectorTool = {
description?: string;
inputSchema?: JSONSchema7;
outputSchema?: JSONSchema7;
requiresApproval?: boolean;
replay?: "log" | "reexecute";
execute: (
args: unknown,
ctx?: ToolExecuteContext,
) => Promise<unknown> | unknown;
revert?: (
args: unknown,
result: unknown,
ctx?: ToolExecuteContext,
) => Promise<void> | void;
};
type ConnectorTools = Record<string, ConnectorTool>;
type ToolExecuteContext = { executionId: string };
inputSchema defaults to an open object. requiresApproval: true pauses before execution. replay: "reexecute" skips durable result storage and re-executes the call on each resume. These two options cannot be combined.
