import { n as AgentEmail } from "./internal_context-BvuGZieY.js"; import { t as RetryOptions } from "./retries-fLD8cGNf.js"; import { n as Observability, r as ObservabilityEvent, s as MCPObservabilityEvent } from "./index-Biv6K70p.js"; import { t as AgentMcpOAuthProvider } from "./do-oauth-client-provider-C38aWbFV.js"; import { _ as WorkflowPage, g as WorkflowInfo, h as WorkflowEventPayload, l as WorkflowCallback, s as RunWorkflowOptions, y as WorkflowQueryCriteria } from "./workflow-types-DHs0L0KP.js"; import { t as MessageType } from "./types-DAHCZC_W.js"; import { r as EmailResolver } from "./email-X72-zjuq.js"; import { ToolSet, UIMessage } from "ai"; import { RpcTarget } from "cloudflare:workers"; import { Connection, Connection as Connection$1, ConnectionContext, ConnectionContext as ConnectionContext$1, PartyServerOptions, Server, WSMessage, WSMessage as WSMessage$1 } from "partyserver"; import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { SSEClientTransport, SSEClientTransportOptions } from "@modelcontextprotocol/sdk/client/sse.js"; import { StreamableHTTPClientTransport, StreamableHTTPClientTransportOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; import { CallToolRequest, CallToolResultSchema, CompatibilityCallToolResultSchema, ElicitRequest, ElicitRequest as ElicitRequest$1, ElicitRequestSchema as ElicitRequestSchema$1, ElicitResult, ElicitResult as ElicitResult$1, GetPromptRequest, InitializeRequestParams, JSONRPCMessage, MessageExtraInfo, Prompt, ReadResourceRequest, RequestId, Resource, ResourceTemplate, ServerCapabilities, Tool as Tool$1 } from "@modelcontextprotocol/sdk/types.js"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js"; import { Transport, TransportSendOptions } from "@modelcontextprotocol/sdk/shared/transport.js"; import { Server as Server$1 } from "@modelcontextprotocol/sdk/server/index.js"; import { Client as Client$1 } from "@modelcontextprotocol/sdk/client"; import { EventStore } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; //#region src/sub-routing.d.ts /** * URL segment marking a parent↔child boundary. * * Exposed as a constant so callers can build URLs symbolically, but * not configurable — the routing layer matches on the literal `sub` * token everywhere (parent fetch, client, helpers). */ declare const SUB_PREFIX = "sub"; interface SubAgentPathMatch { /** CamelCase class name of the child, as it appears in `ctx.exports`. */ childClass: string; /** URL-decoded child name. */ childName: string; /** * Request path to forward to the child, with the * `/sub/{class}/{name}` segment stripped. Always begins with `/`; * may itself contain further `/sub/...` markers when a * recursively nested sub-agent is being routed. */ remainingPath: string; } /** * Parse a URL and extract the first `/sub/{class}/{name}` segment, * if any. Recursive nesting is handled naturally: callers parse one * level at a time; the child then parses its own URL (which still * contains any deeper `/sub/...` markers). * * Names are URL-decoded. Classes are kebab-to-CamelCase converted * via a best-effort match against a provided lookup — pass * `ctx.exports` keys to get exact CamelCase; pass `undefined` for * a tolerant conversion without validation. * * Returns `null` when the URL doesn't contain the marker at a * recognized position, or when the marker has no following * class+name pair. */ declare function parseSubAgentPath( url: string, options?: { /** CamelCase class names to match against (usually `ctx.exports` keys). */ knownClasses?: readonly string[]; } ): SubAgentPathMatch | null; /** * Route a request into a sub-agent via its parent DO. * * Use this in a custom fetch handler when your URL shape doesn't * match the `/agents/{class}/{name}` default — you identify and * fetch the parent yourself, then let this helper parse the * `/sub/{child}/...` tail and forward it. * * Runs `onBeforeSubAgent` on the parent DO (authorization / request * mutation / short-circuit response). * * For the default `/agents/...` URL shape, use `routeAgentRequest` * instead — it handles the parent lookup and this dispatch in one * call. * * @example * ```ts * export default { * async fetch(req, env) { * const { parentName, rest } = myCustomParse(req.url); * const parent = await getAgentByName(env.Inbox, parentName); * return routeSubAgentRequest(req, parent, { fromPath: rest }); * } * }; * ``` * * @experimental The API surface may change before stabilizing. */ declare function routeSubAgentRequest( req: Request, parent: unknown, options?: { /** * Path to route on. Defaults to `req.url`'s pathname. Useful * when your outer URL is custom (e.g. `/api/v1/...`) and you * want to route the sub-agent tail without rewriting the * Request first. */ fromPath?: string; } ): Promise; /** * Get a typed RPC stub for a sub-agent from outside the parent DO. * * The returned stub proxies method calls through the parent via a * stateless per-call bridge (caller → parent → facet), so each * method invocation costs one extra RPC hop. Works across parent * hibernation — no cached references to go stale. * * Limitations: * - RPC methods only. `.fetch()` is not supported (will throw). * Use `routeSubAgentRequest` for external HTTP/WS. * - Arguments and return values must be structured-cloneable, * same as any DO RPC call. * - Does not run `onBeforeSubAgent` on the parent — analogous to * `getAgentByName` not running `onBeforeConnect`. The caller is * assumed to have performed whatever access checks are needed. * * @example * ```ts * const inbox = await getAgentByName(env.MyInbox, userId); * const chat = await getSubAgentByName(inbox, MyChat, chatId); * await chat.addMessage({ role: "user", content: "hi" }); * ``` * * @experimental The API surface may change before stabilizing. */ declare function getSubAgentByName( parent: unknown, cls: SubAgentClass, name: string ): Promise>; //#endregion //#region src/core/events.d.ts interface Disposable { dispose(): void; } type Event = (listener: (e: T) => void) => Disposable; declare class Emitter implements Disposable { private _listeners; readonly event: Event; fire(data: T): void; dispose(): void; } //#endregion //#region src/mcp/types.d.ts type MaybePromise = T | Promise; type HttpTransportType = "sse" | "streamable-http"; type BaseTransportType = HttpTransportType | "rpc"; type TransportType = BaseTransportType | "auto"; interface CORSOptions { origin?: string; methods?: string; headers?: string; maxAge?: number; exposeHeaders?: string; } interface ServeOptions { binding?: string; corsOptions?: CORSOptions; transport?: TransportType; jurisdiction?: DurableObjectJurisdiction; } type McpClientOptions = ConstructorParameters[1]; //#endregion //#region src/mcp/client-transports.d.ts /** * @deprecated Use SSEClientTransport from @modelcontextprotocol/sdk/client/sse.js instead. This alias will be removed in the next major version. */ declare class SSEEdgeClientTransport extends SSEClientTransport { constructor(url: URL, options: SSEClientTransportOptions); } /** * @deprecated Use StreamableHTTPClientTransport from @modelcontextprotocol/sdk/client/streamableHttp.js instead. This alias will be removed in the next major version. */ declare class StreamableHTTPEdgeClientTransport extends StreamableHTTPClientTransport { constructor(url: URL, options: StreamableHTTPClientTransportOptions); } //#endregion //#region src/mcp/worker-transport.d.ts interface MCPStorageApi { get(): Promise | TransportState | undefined; set(state: TransportState): Promise | void; } interface TransportState { sessionId?: string; initialized: boolean; initializeParams?: InitializeRequestParams; } interface WorkerTransportOptions { /** * Function that generates a session ID for the transport. * The session ID SHOULD be globally unique and cryptographically secure. * Return undefined to disable session management (stateless mode). */ sessionIdGenerator?: () => string; /** * Enable traditional Request/Response mode, this will disable streaming. */ enableJsonResponse?: boolean; /** * Callback fired when a new session is initialized. */ onsessioninitialized?: (sessionId: string) => void; /** * Callback fired when a session is closed via DELETE request. */ onsessionclosed?: (sessionId: string) => void; corsOptions?: CORSOptions; /** * Optional storage api for persisting transport state. * Use this to store session state in Durable Object/Agent storage * so it survives hibernation/restart. */ storage?: MCPStorageApi; /** * Event store for resumability support. * If provided, enables clients to reconnect and resume messages using Last-Event-ID. */ eventStore?: EventStore; /** * Retry interval in milliseconds to suggest to clients in SSE retry field. * Controls client reconnection timing for polling behavior. */ retryInterval?: number; } declare class WorkerTransport implements Transport { started: boolean; private initialized; private sessionIdGenerator?; private enableJsonResponse; private onsessioninitialized?; private onsessionclosed?; private standaloneSseStreamId; private streamMapping; private requestToStreamMapping; private requestResponseMap; private corsOptions?; private storage?; private stateRestored; private eventStore?; private retryInterval?; private initializeParams?; sessionId?: string; onclose?: () => void; onerror?: (error: Error) => void; onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void; constructor(options?: WorkerTransportOptions); /** * Restore transport state from persistent storage. * This is automatically called on start. */ private restoreState; /** * Persist current transport state to storage. */ private saveState; start(): Promise; /** * Validates the MCP-Protocol-Version header on incoming requests. * * This performs a simple check: if a version header is present, it must be * in the SUPPORTED_PROTOCOL_VERSIONS list. We do not track the negotiated * version or enforce version consistency across requests - the SDK handles * version negotiation during initialization, and we simply reject any * explicitly unsupported versions. * * - Header present and supported: Accept * - Header present and unsupported: 400 Bad Request * - Header missing: Accept (version validation is optional) */ private validateProtocolVersion; private getHeaders; handleRequest(request: Request, parsedBody?: unknown): Promise; private handleGetRequest; private handlePostRequest; private handleDeleteRequest; private handleOptionsRequest; private handleUnsupportedRequest; private validateSession; close(): Promise; /** * Close an SSE stream for a specific request, triggering client reconnection. * Use this to implement polling behavior during long-running operations - * client will reconnect after the retry interval specified in the priming event. */ closeSSEStream(requestId: RequestId): void; send(message: JSONRPCMessage, options?: TransportSendOptions): Promise; } //#endregion //#region src/mcp/auth-context.d.ts interface McpAuthContext { props: Record; } declare function getMcpAuthContext(): McpAuthContext | undefined; //#endregion //#region src/mcp/handler.d.ts interface CreateMcpHandlerOptions extends WorkerTransportOptions { /** * The route path that this MCP handler should respond to. * If specified, the handler will only process requests that match this route. * @default "/mcp" */ route?: string; /** * An optional auth context to use for handling MCP requests. * If not provided, the handler will look for props in the execution context. */ authContext?: McpAuthContext; /** * An optional transport to use for handling MCP requests. * If not provided, a WorkerTransport will be created with the provided WorkerTransportOptions. */ transport?: WorkerTransport; } declare function createMcpHandler( server: McpServer | Server$1, options?: CreateMcpHandlerOptions ): (request: Request, env: unknown, ctx: ExecutionContext) => Promise; /** * @deprecated This has been renamed to createMcpHandler, and experimental_createMcpHandler will be removed in the next major version */ declare function experimental_createMcpHandler( server: McpServer | Server$1, options?: CreateMcpHandlerOptions ): (request: Request, env: unknown, ctx: ExecutionContext) => Promise; //#endregion //#region src/mcp/index.d.ts declare abstract class McpAgent< Env extends Cloudflare.Env = Cloudflare.Env, State = unknown, Props extends Record = Record > extends Agent { private _transport?; private _pendingElicitations; props?: Props; shouldSendProtocolMessages( _connection: Connection$1, ctx: ConnectionContext$1 ): boolean; abstract server: MaybePromise; abstract init(): Promise; setInitializeRequest(initializeRequest: JSONRPCMessage): Promise; getInitializeRequest(): Promise; /** Read the transport type for this agent. * This relies on the naming scheme being `sse:${sessionId}`, * `streamable-http:${sessionId}`, or `rpc:${sessionId}`. */ getTransportType(): BaseTransportType; /** Read the sessionId for this agent. * This relies on the naming scheme being `sse:${sessionId}` * or `streamable-http:${sessionId}`. */ getSessionId(): string; /** Get the unique WebSocket. SSE transport only. */ getWebSocket(): Connection$1 | null; /** * Returns options for configuring the RPC server transport. * Override this method to customize RPC transport behavior (e.g., timeout). * * @example * ```typescript * class MyMCP extends McpAgent { * protected getRpcTransportOptions() { * return { timeout: 120000 }; // 2 minutes * } * } * ``` */ protected getRpcTransportOptions(): RPCServerTransportOptions; /** Returns a new transport matching the type of the Agent. */ private initTransport; /** Update and store the props */ updateProps(props?: Props): Promise; reinitializeServer(): Promise; /** Sets up the MCP transport and server every time the Agent is started.*/ onStart(props?: Props): Promise; /** Validates new WebSocket connections. */ onConnect( conn: Connection$1, { request: req }: ConnectionContext$1 ): Promise; /** Handles MCP Messages for the legacy SSE transport. */ onSSEMcpMessage( _sessionId: string, messageBody: unknown, extraInfo?: MessageExtraInfo ): Promise; /** Elicit user input with a message and schema */ elicitInput(params: { message: string; requestedSchema: unknown; }): Promise; /** Handle elicitation responses via in-memory resolver */ private _handleElicitationResponse; /** * Handle an RPC message for MCP * This method is called by the RPC stub to process MCP messages * @param message The JSON-RPC message(s) to handle * @returns The response message(s) or undefined */ handleMcpMessage( message: JSONRPCMessage | JSONRPCMessage[] ): Promise; /** Return a handler for the given path for this MCP. * Defaults to Streamable HTTP transport. */ static serve( path: string, { binding, corsOptions, transport, jurisdiction }?: ServeOptions ): { fetch( this: void, request: Request, env: Env, ctx: ExecutionContext ): Promise; }; /** * Legacy api **/ static mount( path: string, opts?: Omit ): { fetch( this: void, request: Request, env: Env, ctx: ExecutionContext ): Promise; }; static serveSSE( path: string, opts?: Omit ): { fetch( this: void, request: Request, env: Env, ctx: ExecutionContext ): Promise; }; } //#endregion //#region src/mcp/rpc.d.ts declare const RPC_DO_PREFIX = "rpc:"; interface RPCClientTransportOptions { namespace: DurableObjectNamespace; name: string; props?: Record; } declare class RPCClientTransport implements Transport { private _namespace; private _name; private _props?; private _stub?; private _started; private _protocolVersion?; sessionId?: string; onclose?: () => void; onerror?: (error: Error) => void; onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void; constructor(options: RPCClientTransportOptions); setProtocolVersion(version: string): void; getProtocolVersion(): string | undefined; start(): Promise; close(): Promise; send( message: JSONRPCMessage | JSONRPCMessage[], options?: TransportSendOptions ): Promise; } interface RPCServerTransportOptions { timeout?: number; } declare class RPCServerTransport implements Transport { private _started; private _pendingResponse; private _responseResolver; private _protocolVersion?; private _timeout; sessionId?: string; onclose?: () => void; onerror?: (error: Error) => void; onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void; constructor(options?: RPCServerTransportOptions); setProtocolVersion(version: string): void; getProtocolVersion(): string | undefined; start(): Promise; close(): Promise; send(message: JSONRPCMessage, _options?: TransportSendOptions): Promise; /** * @internal Called by McpAgent.handleMcpMessage() — not for external use. * * Wait for the next send() call and return whatever it produces. * * Used after resolving an elicitation response: the tool handler is still * running and will eventually call send() with either another elicitation * request or the final tool result. This method captures that send() using * the same _responseResolver / _pendingResponse / timeout mechanism as * handle(). */ _awaitPendingResponse(): Promise< JSONRPCMessage | JSONRPCMessage[] | undefined >; handle( message: JSONRPCMessage | JSONRPCMessage[] ): Promise; } //#endregion //#region src/mcp/client-connection.d.ts /** * Connection state machine for MCP client connections. * * State transitions: * - Non-OAuth: init() → CONNECTING → DISCOVERING → READY * - OAuth: init() → AUTHENTICATING → (callback) → CONNECTING → DISCOVERING → READY * - Any state can transition to FAILED on error */ declare const MCPConnectionState: { /** Waiting for OAuth authorization to complete */ readonly AUTHENTICATING: "authenticating" /** Establishing transport connection to MCP server */; readonly CONNECTING: "connecting" /** Transport connection established */; readonly CONNECTED: "connected" /** Discovering server capabilities (tools, resources, prompts) */; readonly DISCOVERING: "discovering" /** Fully connected and ready to use */; readonly READY: "ready" /** Connection failed at some point */; readonly FAILED: "failed"; }; /** * Connection state type for MCP client connections. */ type MCPConnectionState = (typeof MCPConnectionState)[keyof typeof MCPConnectionState]; /** * Transport options for MCP client connections. * Combines transport-specific options with auth provider and type selection. */ type MCPTransportOptions = ( | SSEClientTransportOptions | StreamableHTTPClientTransportOptions | RPCClientTransportOptions ) & { authProvider?: AgentMcpOAuthProvider; type?: TransportType; }; /** * Result of a discovery operation. * success indicates whether discovery completed successfully. * error is present when success is false. */ type MCPDiscoveryResult = { success: boolean; error?: string; }; declare class MCPClientConnection { url: URL; options: { transport: MCPTransportOptions; client: McpClientOptions; }; client: Client; connectionState: MCPConnectionState; connectionError: string | null; lastConnectedTransport: BaseTransportType | undefined; instructions?: string; tools: Tool$1[]; private _transport?; prompts: Prompt[]; resources: Resource[]; resourceTemplates: ResourceTemplate[]; serverCapabilities: ServerCapabilities | undefined; /** True when resuming a streamable-http session without cached capabilities */ private _probingCapabilities; /** Tracks in-flight discovery to allow cancellation */ private _discoveryAbortController; private readonly _onObservabilityEvent; readonly onObservabilityEvent: Event; constructor( url: URL, info: ConstructorParameters[0], options?: { transport: MCPTransportOptions; client: McpClientOptions; } ); /** * Initialize a client connection, if authentication is required, the connection will be in the AUTHENTICATING state * Sets connection state based on the result and emits observability events * * @returns Error message if connection failed, undefined otherwise */ init(): Promise; /** * Finish OAuth by probing transports based on configured type. * - Explicit: finish on that transport * - Auto: try streamable-http, then sse on 404/405/Not Implemented */ private finishAuthProbe; /** * Complete OAuth authorization */ completeAuthorization(code: string): Promise; /** * Discover server capabilities and register tools, resources, prompts, and templates. * This method does the work but does not manage connection state - that's handled by discover(). */ discoverAndRegister(): Promise; /** * Discover server capabilities with timeout and cancellation support. * If called while a previous discovery is in-flight, the previous discovery will be aborted. * * @param options Optional configuration * @param options.timeoutMs Timeout in milliseconds (default: 15000) * @returns Result indicating success/failure with optional error message */ discover(options?: { timeoutMs?: number }): Promise; /** * Cancel any in-flight discovery operation. * Called when closing the connection. */ cancelDiscovery(): void; /** * Notification handler registration for tools * Should only be called if serverCapabilities.tools exists */ registerTools(): Promise; /** * Notification handler registration for resources * Should only be called if serverCapabilities.resources exists */ registerResources(): Promise; /** * Notification handler registration for prompts * Should only be called if serverCapabilities.prompts exists */ registerPrompts(): Promise; registerResourceTemplates(): Promise; fetchTools(): Promise< { inputSchema: { [x: string]: unknown; type: "object"; properties?: | { [x: string]: object; } | undefined; required?: string[] | undefined; }; name: string; description?: string | undefined; outputSchema?: | { [x: string]: unknown; type: "object"; properties?: | { [x: string]: object; } | undefined; required?: string[] | undefined; } | undefined; annotations?: | { title?: string | undefined; readOnlyHint?: boolean | undefined; destructiveHint?: boolean | undefined; idempotentHint?: boolean | undefined; openWorldHint?: boolean | undefined; } | undefined; execution?: | { taskSupport?: "optional" | "required" | "forbidden" | undefined; } | undefined; _meta?: | { [x: string]: unknown; } | undefined; icons?: | { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; }[] >; fetchResources(): Promise< { uri: string; name: string; description?: string | undefined; mimeType?: string | undefined; size?: number | undefined; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: | { [x: string]: unknown; } | undefined; icons?: | { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; }[] >; fetchPrompts(): Promise< { name: string; description?: string | undefined; arguments?: | { name: string; description?: string | undefined; required?: boolean | undefined; }[] | undefined; _meta?: | { [x: string]: unknown; } | undefined; icons?: | { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; }[] >; fetchResourceTemplates(): Promise< { uriTemplate: string; name: string; description?: string | undefined; mimeType?: string | undefined; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: | { [x: string]: unknown; } | undefined; icons?: | { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; }[] >; /** * Handle elicitation request from server * Automatically uses the Agent's built-in elicitation handling if available */ handleElicitationRequest(_request: ElicitRequest): Promise; private isResumedStreamableHttpSession; get sessionId(): string | undefined; private getTransportName; close(): Promise; /** * Get the transport for the client * @param transportType - The transport type to get * @returns The transport for the client */ getTransport( transportType: BaseTransportType ): StreamableHTTPClientTransport | SSEClientTransport | RPCClientTransport; private tryConnect; private _capabilityErrorHandler; } //#endregion //#region src/mcp/client-storage.d.ts /** * Represents a row in the cf_agents_mcp_servers table */ type MCPServerRow = { id: string; name: string; server_url: string; client_id: string | null; auth_url: string | null; callback_url: string; server_options: string | null; }; //#endregion //#region src/mcp/client.d.ts /** * Options that can be stored in the server_options column * This is what gets JSON.stringify'd and stored in the database */ type MCPServerOptions = { client?: ConstructorParameters[1]; transport?: { headers?: HeadersInit; type?: TransportType; sessionId?: string; } /** Retry options for connection and reconnection attempts */; retry?: RetryOptions; }; /** * Result of an OAuth callback request */ type MCPOAuthCallbackResult = | { serverId: string; authSuccess: true; authError?: undefined; } | { serverId?: string; authSuccess: false; authError: string; }; /** * Options for registering an MCP server */ type RegisterServerOptions = { url: string; name: string; callbackUrl?: string; client?: ConstructorParameters[1]; transport?: MCPTransportOptions; authUrl?: string; clientId?: string /** Retry options for connection and reconnection attempts */; retry?: RetryOptions; }; /** * Result of attempting to connect to an MCP server. * Discriminated union ensures error is present only on failure. */ type MCPConnectionResult = | { state: typeof MCPConnectionState.FAILED; error: string; } | { state: typeof MCPConnectionState.AUTHENTICATING; authUrl: string; clientId?: string; } | { state: typeof MCPConnectionState.CONNECTED; }; /** * Result of discovering server capabilities. * success indicates whether discovery completed successfully. * state is the current connection state at time of return. * error is present when success is false. */ type MCPDiscoverResult = { success: boolean; state: MCPConnectionState; error?: string; }; type MCPClientOAuthCallbackConfig = { successRedirect?: string; errorRedirect?: string; customHandler?: (result: MCPClientOAuthResult) => Response; }; type MCPClientOAuthResult = | { serverId: string; authSuccess: true; authError?: undefined; } | { serverId?: string; authSuccess: false /** May contain untrusted content from external OAuth providers. Escape appropriately for your output context. */; authError: string; }; type MCPClientManagerOptions = { storage: DurableObjectStorage; createAuthProvider?: (callbackUrl: string) => AgentMcpOAuthProvider; }; /** * Filter options for scoping tools, prompts, resources, and resource templates * to a subset of connected MCP servers. All specified criteria are AND'd together. */ type MCPServerFilter = { /** Include only connections matching this server ID (or IDs). */ serverId?: | string | string[] /** Include only connections whose stored name matches (or is in) this value. */; serverName?: | string | string[] /** Include only connections currently in this state (or states). */; state?: MCPConnectionState | MCPConnectionState[]; }; /** * Utility class that aggregates multiple MCP clients into one */ declare class MCPClientManager { private _name; private _version; mcpConnections: Record; private _didWarnAboutUnstableGetAITools; private _oauthCallbackConfig?; private _connectionDisposables; private _storage; private _createAuthProviderFn?; private _isRestored; private _pendingConnections; /** @internal Protected for testing purposes. */ protected readonly _onObservabilityEvent: Emitter; readonly onObservabilityEvent: Event; private readonly _onServerStateChanged; /** * Event that fires whenever any MCP server state changes (registered, connected, removed, etc.) * This is useful for broadcasting server state to clients. */ readonly onServerStateChanged: Event; /** * @param _name Name of the MCP client * @param _version Version of the MCP Client * @param options Storage adapter for persisting MCP server state */ constructor( _name: string, _version: string, options: MCPClientManagerOptions ); private sql; private saveServerToStorage; private removeServerFromStorage; private getServersFromStorage; private filterConnections; /** * Get the retry options for a server from stored server_options */ private getServerRetryOptions; private clearServerAuthUrl; private updateStoredSessionId; private failConnection; /** * Create an auth provider for a server * @internal */ private createAuthProvider; /** * Get saved RPC servers from storage (servers with rpc:// URLs). * These are restored separately by the Agent class since they need env bindings. */ getRpcServersFromStorage(): MCPServerRow[]; /** * Save an RPC server to storage for hibernation recovery. * The bindingName is stored in server_options so the Agent can look up * the namespace from env during restore. */ saveRpcServerToStorage( id: string, name: string, normalizedName: string, bindingName: string, props?: Record ): void; /** * Restore MCP server connections from storage * This method is called on Agent initialization to restore previously connected servers. * RPC servers (rpc:// URLs) are skipped here -- they are restored by the Agent class * which has access to env bindings. * * @param clientName Name to use for OAuth client (typically the agent instance name) */ restoreConnectionsFromStorage(clientName: string): Promise; /** * Track a pending connection promise for a server. * The promise is removed from the map when it settles. */ private _trackConnection; /** * Wait for all in-flight connection and discovery operations to settle. * This is useful when you need MCP tools to be available before proceeding, * e.g. before calling getAITools() after the agent wakes from hibernation. * * Returns once every pending connection has either connected and discovered, * failed, or timed out. Never rejects. * * @param options.timeout - Maximum time in milliseconds to wait. * `0` returns immediately without waiting. * `undefined` (default) waits indefinitely. */ waitForConnections(options?: { timeout?: number }): Promise; /** * Internal method to restore a single server connection and discovery */ private _restoreServer; /** * Connect to and register an MCP server * * @deprecated This method is maintained for backward compatibility. * For new code, use registerServer() and connectToServer() separately. * * @param url Server URL * @param options Connection options * @returns Object with server ID, auth URL (if OAuth), and client ID (if OAuth) */ connect( url: string, options?: { reconnect?: { id: string; oauthClientId?: string; oauthCode?: string; }; transport?: MCPTransportOptions; client?: ConstructorParameters[1]; } ): Promise<{ id: string; authUrl?: string; clientId?: string; }>; /** * Create an in-memory connection object and set up observability * Does NOT save to storage - use registerServer() for that * @returns The connection object (existing or newly created) */ private createConnection; /** * Register an MCP server connection without connecting * Creates the connection object, sets up observability, and saves to storage * * @param id Server ID * @param options Registration options including URL, name, callback URL, and connection config * @returns Server ID */ registerServer(id: string, options: RegisterServerOptions): Promise; /** * Connect to an already registered MCP server and initialize the connection. * * For OAuth servers, returns `{ state: "authenticating", authUrl, clientId? }`. * The user must complete the OAuth flow via the authUrl, which triggers a * callback handled by `handleCallbackRequest()`. * * For non-OAuth servers, establishes the transport connection and returns * `{ state: "connected" }`. Call `discoverIfConnected()` afterwards to * discover capabilities and transition to "ready" state. * * @param id Server ID (must be registered first via registerServer()) * @returns Connection result with current state and OAuth info (if applicable) */ connectToServer(id: string): Promise; private extractServerIdFromState; isCallbackRequest(req: Request): boolean; private validateCallbackRequest; handleCallbackRequest(req: Request): Promise; /** * Discover server capabilities if connection is in CONNECTED or READY state. * Transitions to DISCOVERING then READY (or CONNECTED on error). * Can be called to refresh server capabilities (e.g., from a UI refresh button). * * If called while a previous discovery is in-flight for the same server, * the previous discovery will be aborted. * * @param serverId The server ID to discover * @param options Optional configuration * @param options.timeoutMs Timeout in milliseconds (default: 30000) * @returns Result with current state and optional error, or undefined if connection not found */ discoverIfConnected( serverId: string, options?: { timeoutMs?: number; } ): Promise; /** * Establish connection in the background after OAuth completion. * This method connects to the server and discovers its capabilities. * The connection is automatically tracked so that `waitForConnections()` * will include it. * @param serverId The server ID to establish connection for */ establishConnection(serverId: string): Promise; private _doEstablishConnection; /** * Configure OAuth callback handling * @param config OAuth callback configuration */ configureOAuthCallback(config: MCPClientOAuthCallbackConfig): void; /** * Get the current OAuth callback configuration * @returns The current OAuth callback configuration */ getOAuthCallbackConfig(): MCPClientOAuthCallbackConfig | undefined; /** * @param filter - Optional filter to scope results to specific servers * @returns namespaced list of tools */ listTools(filter?: MCPServerFilter): NamespacedData["tools"]; /** * @param filter - Optional filter to scope results to specific servers * @returns a set of tools that you can use with the AI SDK */ getAITools(filter?: MCPServerFilter): ToolSet; /** * @deprecated this has been renamed to getAITools(), and unstable_getAITools will be removed in the next major version * @param filter - Optional filter to scope results to specific servers * @returns a set of tools that you can use with the AI SDK */ unstable_getAITools(filter?: MCPServerFilter): ToolSet; /** * Closes all active in-memory connections to MCP servers. * * Note: This only closes the transport connections - it does NOT remove * servers from storage. Servers will still be listed and their callback * URLs will still match incoming OAuth requests. * * Use removeServer() instead if you want to fully clean up a server * (closes connection AND removes from storage). */ private cleanupClosedConnection; closeAllConnections(): Promise; /** * Closes a connection to an MCP server * @param id The id of the connection to close */ closeConnection(id: string): Promise; /** * Remove an MCP server - closes connection if active and removes from storage. */ removeServer(serverId: string): Promise; /** * List all MCP servers from storage */ listServers(): MCPServerRow[]; /** * Dispose the manager and all resources. */ dispose(): Promise; /** * @param filter - Optional filter to scope results to specific servers * @returns namespaced list of prompts */ listPrompts(filter?: MCPServerFilter): NamespacedData["prompts"]; /** * @param filter - Optional filter to scope results to specific servers * @returns namespaced list of resources */ listResources(filter?: MCPServerFilter): NamespacedData["resources"]; /** * @param filter - Optional filter to scope results to specific servers * @returns namespaced list of resource templates */ listResourceTemplates( filter?: MCPServerFilter ): NamespacedData["resourceTemplates"]; /** * Namespaced version of callTool */ callTool( params: CallToolRequest["params"] & { serverId: string; }, resultSchema?: | typeof CallToolResultSchema | typeof CompatibilityCallToolResultSchema, options?: RequestOptions ): Promise< | { [x: string]: unknown; content: ( | { type: "text"; text: string; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: Record | undefined; } | { type: "image"; data: string; mimeType: string; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: Record | undefined; } | { type: "audio"; data: string; mimeType: string; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: Record | undefined; } | { type: "resource"; resource: | { uri: string; text: string; mimeType?: string | undefined; _meta?: Record | undefined; } | { uri: string; blob: string; mimeType?: string | undefined; _meta?: Record | undefined; }; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: Record | undefined; } | { uri: string; name: string; type: "resource_link"; description?: string | undefined; mimeType?: string | undefined; size?: number | undefined; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: | { [x: string]: unknown; } | undefined; icons?: | { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; } )[]; _meta?: | { [x: string]: unknown; progressToken?: string | number | undefined; "io.modelcontextprotocol/related-task"?: | { taskId: string; } | undefined; } | undefined; structuredContent?: Record | undefined; isError?: boolean | undefined; } | { [x: string]: unknown; toolResult: unknown; _meta?: | { [x: string]: unknown; progressToken?: string | number | undefined; "io.modelcontextprotocol/related-task"?: | { taskId: string; } | undefined; } | undefined; } >; /** * Namespaced version of readResource */ readResource( params: ReadResourceRequest["params"] & { serverId: string; }, options: RequestOptions ): Promise<{ [x: string]: unknown; contents: ( | { uri: string; text: string; mimeType?: string | undefined; _meta?: Record | undefined; } | { uri: string; blob: string; mimeType?: string | undefined; _meta?: Record | undefined; } )[]; _meta?: | { [x: string]: unknown; progressToken?: string | number | undefined; "io.modelcontextprotocol/related-task"?: | { taskId: string; } | undefined; } | undefined; }>; /** * Namespaced version of getPrompt */ getPrompt( params: GetPromptRequest["params"] & { serverId: string; }, options: RequestOptions ): Promise<{ [x: string]: unknown; messages: { role: "user" | "assistant"; content: | { type: "text"; text: string; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: Record | undefined; } | { type: "image"; data: string; mimeType: string; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: Record | undefined; } | { type: "audio"; data: string; mimeType: string; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: Record | undefined; } | { type: "resource"; resource: | { uri: string; text: string; mimeType?: string | undefined; _meta?: Record | undefined; } | { uri: string; blob: string; mimeType?: string | undefined; _meta?: Record | undefined; }; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: Record | undefined; } | { uri: string; name: string; type: "resource_link"; description?: string | undefined; mimeType?: string | undefined; size?: number | undefined; annotations?: | { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: | { [x: string]: unknown; } | undefined; icons?: | { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; }; }[]; _meta?: | { [x: string]: unknown; progressToken?: string | number | undefined; "io.modelcontextprotocol/related-task"?: | { taskId: string; } | undefined; } | undefined; description?: string | undefined; }>; } type NamespacedData = { tools: (Tool$1 & { serverId: string; })[]; prompts: (Prompt & { serverId: string; })[]; resources: (Resource & { serverId: string; })[]; resourceTemplates: (ResourceTemplate & { serverId: string; })[]; }; declare function getNamespacedData( mcpClients: Record, type: T ): NamespacedData[T]; //#endregion //#region src/index.d.ts /** * Structural type for Cloudflare's `send_email` binding. * Accepts both raw MIME messages and structured builder objects. */ type EmailSendBinding = { send( message: | EmailMessage | { from: | string | { email: string; name?: string; }; to: string | string[]; subject: string; replyTo?: | string | { email: string; name?: string; }; cc?: string | string[]; bcc?: string | string[]; headers?: Record; text?: string; html?: string; } ): Promise; }; /** * Options for Agent.sendEmail() */ type SendEmailOptions = { binding: EmailSendBinding; to: string | string[]; from: | string | { email: string; name?: string; }; subject: string; text?: string; html?: string; replyTo?: | string | { email: string; name?: string; }; cc?: string | string[]; bcc?: string | string[]; inReplyTo?: string; headers?: Record; secret?: string; }; /** * RPC request message from client */ type RPCRequest = { type: "rpc"; id: string; method: string; args: unknown[]; }; /** * State update message from client */ type StateUpdateMessage = { type: MessageType.CF_AGENT_STATE; state: unknown; }; /** * RPC response message to client */ type RPCResponse = { type: MessageType.RPC; id: string; } & ( | { success: true; result: unknown; done?: false; } | { success: true; result: unknown; done: true; } | { success: false; error: string; } ); /** * Metadata for a callable method */ type CallableMetadata = { /** Optional description of what the method does */ description?: string /** Whether the method supports streaming responses */; streaming?: boolean; }; /** * Error class for SQL execution failures, containing the query that failed */ declare class SqlError extends Error { /** The SQL query that failed */ readonly query: string; constructor(query: string, cause: unknown); } type SubAgentConnectionMeta = { id: string; uri: string | null; tags: string[]; state: unknown; requestHeaders?: [string, string][]; }; type SubAgentConnectionBridgeLike = { send(message: string | ArrayBuffer | ArrayBufferView): void; close(code?: number, reason?: string): void; setState(state: unknown): unknown; broadcast( ownerPath: ReadonlyArray<{ className: string; name: string; }>, message: string | ArrayBuffer | ArrayBufferView, without?: string[] ): void; }; declare class SubAgentConnectionBridge extends RpcTarget implements SubAgentConnectionBridgeLike { #private; constructor( connection: Connection, broadcast?: ( ownerPath: ReadonlyArray<{ className: string; name: string; }>, message: string | ArrayBuffer | ArrayBufferView, without?: string[] ) => void ); send(message: string | ArrayBuffer | ArrayBufferView): void; close(code?: number, reason?: string): void; setState(state: unknown): unknown; broadcast( ownerPath: ReadonlyArray<{ className: string; name: string; }>, message: string | ArrayBuffer | ArrayBufferView, without?: string[] ): void; } /** * Constructor type for a sub-agent class. * Used by {@link Agent.subAgent} to reference the child class * via `ctx.exports`. * * The class name (`cls.name`) must match the export name in the * worker entry point — re-exports under a different name * (e.g. `export { Foo as Bar }`) are not supported. */ type SubAgentClass = { new (ctx: DurableObjectState, env: never): T; }; /** * Wraps `T` in a `Promise` unless it already is one. */ type Promisify = T extends Promise ? T : Promise; /** * A typed RPC stub for a sub-agent. Exposes all public instance methods * as callable RPC methods with Promise-wrapped return types. * * Methods inherited from `Agent` / `Server` / `DurableObject` internals * are excluded — only user-defined methods on the subclass are exposed. */ type SubAgentStub = { [K in keyof T as K extends keyof Agent ? never : T[K] extends (...args: never[]) => unknown ? K : never]: T[K] extends (...args: infer A) => infer R ? (...args: A) => Promisify : never; }; /** * Decorator that marks a method as callable by clients * @param metadata Optional metadata about the callable method */ declare function callable( metadata?: CallableMetadata ): ( target: (this: This, ...args: Args) => Return, _context: ClassMethodDecoratorContext ) => (this: This, ...args: Args) => Return; /** * Decorator that marks a method as callable by clients * @deprecated this has been renamed to callable, and unstable_callable will be removed in the next major version * @param metadata Optional metadata about the callable method */ declare const unstable_callable: ( metadata?: CallableMetadata ) => ( target: (this: This, ...args: Args) => Return, _context: ClassMethodDecoratorContext ) => (this: This, ...args: Args) => Return; type QueueItem = { id: string; payload: T; callback: keyof Agent; created_at: number; retry?: RetryOptions; }; /** * Represents a scheduled task within an Agent * @template T Type of the payload data */ type Schedule = { /** Unique identifier for the schedule */ id: string /** Name of the method to be called */; callback: string /** Data to be passed to the callback */; payload: T /** Retry options for callback execution */; retry?: RetryOptions; } & ( | { /** Type of schedule for one-time execution at a specific time */ type: "scheduled" /** Timestamp when the task should execute */; time: number; } | { /** Type of schedule for delayed execution */ type: "delayed" /** Timestamp when the task should execute */; time: number /** Number of seconds to delay execution */; delayInSeconds: number; } | { /** Type of schedule for recurring execution based on cron expression */ type: "cron" /** Timestamp for the next execution */; time: number /** Cron expression defining the schedule */; cron: string; } | { /** Type of schedule for recurring execution at fixed intervals */ type: "interval" /** Timestamp for the next execution */; time: number /** Number of seconds between executions */; intervalSeconds: number; } ); type AgentPathStep = { className: string; name: string; }; type ScheduleStorageRow = { id: string; callback: string; payload: string; type: "scheduled" | "delayed" | "cron" | "interval"; time: number; delayInSeconds?: number; cron?: string; intervalSeconds?: number; retry?: RetryOptions; running?: number; execution_started_at?: number | null; retry_options?: string | null; owner_path?: string | null; owner_path_key?: string | null; }; type ScheduleCriteria = { id?: string; type?: "scheduled" | "delayed" | "cron" | "interval"; timeRange?: { start?: Date; end?: Date; }; }; /** * Context passed to the `runFiber` callback. Provides checkpoint * and identity for durable execution. */ type FiberContext = { /** Unique identifier for this fiber execution. */ id: string /** Checkpoint data during execution. Synchronous SQLite write. */; stash( data: unknown ): void /** Last checkpoint data (null on first run, populated on recovery re-invocation). */; snapshot: unknown | null; }; /** * Context passed to the `onFiberRecovered` hook when an interrupted * fiber is detected after DO restart. */ type FiberRecoveryContext = { /** Fiber ID. */ id: string /** Name passed to `runFiber`. */; name: string /** Last checkpoint data from `stash()`, or null if never stashed. */; snapshot: unknown | null; /** * Epoch milliseconds when the fiber row was inserted (when `runFiber` * started). Use `Date.now() - createdAt` to gate stale recoveries. */ createdAt: number; [key: string]: unknown; }; /** * MCP Server state update message from server -> Client */ type MCPServerMessage = { type: MessageType.CF_AGENT_MCP_SERVERS; mcp: MCPServersState; }; type MCPServersState = { servers: { [id: string]: MCPServer; }; tools: (Tool$1 & { serverId: string; })[]; prompts: (Prompt & { serverId: string; })[]; resources: (Resource & { serverId: string; })[]; }; type MCPServer = { name: string; server_url: string; auth_url: string | null; state: MCPConnectionState /** May contain untrusted content from external OAuth providers. Escape appropriately for your output context. */; error: string | null; instructions: string | null; capabilities: ServerCapabilities | null; }; /** * Options for adding an MCP server */ type AddMcpServerOptions = { /** OAuth callback host (auto-derived from request if omitted) */ callbackHost?: string; /** * Custom callback URL path — bypasses the default `/agents/{class}/{name}/callback` construction. * Required when `sendIdentityOnConnect` is `false` to prevent leaking the instance name. * When set, the callback URL becomes `{callbackHost}/{callbackPath}`. * The developer must route this path to the agent instance via `getAgentByName`. * Should be a plain path (e.g., `/mcp-callback`) — do not include query strings or fragments. */ callbackPath?: string /** Agents routing prefix (default: "agents") */; agentsPrefix?: string /** MCP client options */; client?: ConstructorParameters[1] /** Transport options */; transport?: { /** Custom headers for authentication (e.g., bearer tokens, CF Access) */ headers?: HeadersInit /** Transport type: "sse", "streamable-http", or "auto" (default) */; type?: TransportType; } /** Retry options for connection and reconnection attempts */; retry?: RetryOptions; }; /** * Options for adding an MCP server via RPC (Durable Object binding) */ type AddRpcMcpServerOptions = { /** Props to pass to the McpAgent instance */ props?: Record; }; /** * Default options for Agent configuration. * Child classes can override specific options without spreading. */ declare const DEFAULT_AGENT_STATIC_OPTIONS: { /** Whether the Agent should hibernate when inactive */ hibernate: boolean /** Whether to send identity (name, agent) to clients on connect */; sendIdentityOnConnect: boolean; /** * Timeout in seconds before a running interval schedule is considered "hung" * and force-reset. Increase this if you have callbacks that legitimately * take longer than 30 seconds. */ hungScheduleTimeoutSeconds: number; /** * Interval in milliseconds for keepAlive() alarm heartbeats. * Lower values mean faster recovery after eviction but more frequent alarms. */ keepAliveIntervalMs: number /** Default retry options for schedule(), queue(), and this.retry() */; retry: { maxAttempts: number; baseDelayMs: number; maxDelayMs: number; }; }; /** * Configuration options for the Agent. * Override in subclasses via `static options`. * All fields are optional - defaults are applied at runtime. * Note: `hibernate` defaults to `true` if not specified. */ interface AgentStaticOptions { hibernate?: boolean; sendIdentityOnConnect?: boolean; hungScheduleTimeoutSeconds?: number; /** * Interval in milliseconds for keepAlive() alarm heartbeats. * Default: 30000 (30 seconds). Lower values mean faster recovery * after eviction but more frequent alarms. */ keepAliveIntervalMs?: number; /** Default retry options for schedule(), queue(), and this.retry(). */ retry?: RetryOptions; } declare function getCurrentAgent< T extends Agent = Agent >(): { agent: T | undefined; connection: Connection | undefined; request: Request | undefined; email: AgentEmail | undefined; }; /** * Extract string keys from Env where the value is a Workflow binding. */ type WorkflowBinding = { [K in keyof E & string]: E[K] extends Workflow ? K : never; }[keyof E & string]; /** * Type for workflow name parameter. * When Env has typed Workflow bindings, provides autocomplete for those keys. * Also accepts any string for dynamic use cases and compatibility. * The `string & {}` trick preserves autocomplete while allowing any string. */ type WorkflowName = WorkflowBinding | (string & {}); /** * Base class for creating Agent implementations * @template Env Environment type containing bindings * @template State State type to store within the Agent */ declare class Agent< Env extends Cloudflare.Env = Cloudflare.Env, State = unknown, Props extends Record = Record > extends Server { private _state; private _disposables; private _destroyed; /** * Stores raw state accessors for wrapped connections. * Used by internal flag methods (readonly, no-protocol) to read/write * _cf_-prefixed keys without going through the user-facing state/setState. */ private _rawStateAccessors; /** * Cached persistence-hook dispatch mode, computed once in the constructor. * - "new" → call onStateChanged * - "old" → call onStateUpdate (deprecated) * - "none" → neither hook is overridden, skip entirely */ private _persistenceHookMode; /** True when this agent runs as a facet (sub-agent) inside a parent. */ private _isFacet; /** * True only while the internal facet bootstrap RPC runs startup. * Startup may happen while the parent is handling a WebSocket * message, so protocol broadcasts must not touch any ambient * parent-owned WebSocket handles during this window. */ private _suppressProtocolBroadcasts; private _cf_currentSubAgentBridge?; private _cf_virtualSubAgentConnections; /** * Ancestor chain, root-first. Empty for top-level DOs; populated at * facet init time from the parent's own `selfPath`. Exposed publicly * via the `parentPath` getter. * @internal */ private _parentPath; /** True while user's onStart() is executing. Used to warn about non-idempotent schedule() calls. */ private _insideOnStart; /** Tracks callbacks already warned about during this onStart() to avoid log spam. */ private _warnedScheduleInOnStart; /** * Number of active keepAlive() callers. When > 0, `_scheduleNextAlarm()` * caps the next alarm at `keepAliveIntervalMs` so the DO stays alive. * Purely in-memory — lost on eviction, which is correct because the * in-memory work keepAlive was protecting is also lost. * @internal */ _keepAliveRefs: number; /** * In-memory tokens for keepAlive leases acquired by facets and held * on the root alarm owner. Lost on eviction, like `_keepAliveRefs`, * because the in-memory work those leases were protecting is also gone. * @internal */ private _facetKeepAliveTokens; /** @internal In-memory set of fiber IDs running in this process. */ private _runFiberActiveFibers; /** @internal Prevents re-entrant recovery from overlapping alarm ticks. */ private _runFiberRecoveryInProgress; private _ParentClass; readonly mcp: MCPClientManager; /** * Initial state for the Agent * Override to provide default state values */ initialState: State; /** * Stable key for Workers AI session affinity (prefix-cache optimization). * * Uses the Durable Object ID, which is globally unique across all agent * classes and stable for the lifetime of the instance. Pass this value as * the `sessionAffinity` option when creating a Workers AI model so that * requests from the same agent instance are routed to the same backend * replica, improving KV-prefix-cache hit rates across conversation turns. * * @example * ```typescript * const workersai = createWorkersAI({ binding: this.env.AI }); * const model = workersai("@cf/meta/llama-3.3-70b-instruct-fp8-fast", { * sessionAffinity: this.sessionAffinity, * }); * ``` */ get sessionAffinity(): string; /** * Current state of the Agent */ get state(): State; /** * Agent configuration options. * Override in subclasses - only specify what you want to change. * @example * class SecureAgent extends Agent { * static options = { sendIdentityOnConnect: false }; * } */ static options: AgentStaticOptions; /** * Resolved options (merges defaults with subclass overrides). * Cached after first access — static options never change during the * lifetime of a Durable Object instance. */ private _cachedOptions?; private get _resolvedOptions(); /** * The observability implementation to use for the Agent */ observability?: Observability; /** * Emit an observability event with auto-generated timestamp. * @internal */ protected _emit( type: ObservabilityEvent["type"], payload?: Record ): void; /** * Execute SQL queries against the Agent's database * @template T Type of the returned rows * @param strings SQL query template strings * @param values Values to be inserted into the query * @returns Array of query results */ sql>( strings: TemplateStringsArray, ...values: (string | number | boolean | null)[] ): T[]; /** * Create all internal tables and run migrations if needed. * Called by the constructor on every wake. Idempotent — skips DDL when * the stored schema version matches CURRENT_SCHEMA_VERSION. * * Protected so that test agents can re-run the real migration path * after manipulating DB state (since ctx.abort() is unavailable in * local dev and the constructor only runs once per DO instance). */ protected _ensureSchema(): void; constructor(ctx: AgentContext, env: Env); /** * Check for workflows referencing unknown bindings and warn with migration suggestion. */ private _checkOrphanedWorkflows; /** * Broadcast a protocol message only to connections that have protocol * messages enabled. Connections where shouldSendProtocolMessages returned * false are excluded automatically. * @param msg The JSON-encoded protocol message * @param excludeIds Additional connection IDs to exclude (e.g. the source) */ private _broadcastProtocol; private _setStateInternal; /** * Update the Agent's state * @param state New state to set * @throws Error if called from a readonly connection context */ setState(state: State): void; /** * Wraps connection.state and connection.setState so that internal * _cf_-prefixed flags (readonly, no-protocol) are hidden from user code * and cannot be accidentally overwritten. * * Idempotent — safe to call multiple times on the same connection. * After hibernation, the _rawStateAccessors WeakMap is empty but the * connection's state getter still reads from the persisted WebSocket * attachment. Calling this method re-captures the raw getter so that * predicate methods (isConnectionReadonly, isConnectionProtocolEnabled) * work correctly post-hibernation. */ private _ensureConnectionWrapped; /** * Mark a connection as readonly or readwrite * @param connection The connection to mark * @param readonly Whether the connection should be readonly (default: true) */ setConnectionReadonly(connection: Connection, readonly?: boolean): void; /** * Check if a connection is marked as readonly. * * Safe to call after hibernation — re-wraps the connection if the * in-memory accessor cache was cleared. * @param connection The connection to check * @returns True if the connection is readonly */ isConnectionReadonly(connection: Connection): boolean; /** * ⚠️ INTERNAL — DO NOT USE IN APPLICATION CODE. ⚠️ * * Read an internal `_cf_`-prefixed flag from the raw connection state, * bypassing the user-facing state wrapper that strips internal keys. * * This exists for framework mixins (e.g. voice) that need to persist * flags in the connection attachment across hibernation. Application * code should use `connection.state` and `connection.setState()` instead. * * @internal */ _unsafe_getConnectionFlag(connection: Connection, key: string): unknown; /** * ⚠️ INTERNAL — DO NOT USE IN APPLICATION CODE. ⚠️ * * Write an internal `_cf_`-prefixed flag to the raw connection state, * bypassing the user-facing state wrapper. The key must be registered * in `CF_INTERNAL_KEYS` so it is preserved across user `setState` calls * and hidden from `connection.state`. * * @internal */ _unsafe_setConnectionFlag( connection: Connection, key: string, value: unknown ): void; /** * Override this method to determine if a connection should be readonly on connect * @param _connection The connection that is being established * @param _ctx Connection context * @returns True if the connection should be readonly */ shouldConnectionBeReadonly( _connection: Connection, _ctx: ConnectionContext ): boolean; /** * Override this method to control whether protocol messages are sent to a * connection. Protocol messages include identity (CF_AGENT_IDENTITY), state * sync (CF_AGENT_STATE), and MCP server lists (CF_AGENT_MCP_SERVERS). * * When this returns `false` for a connection, that connection will not * receive any protocol text frames — neither on connect nor via broadcasts. * This is useful for binary-only clients (e.g. MQTT devices) that cannot * handle JSON text frames. * * The connection can still send and receive regular messages, use RPC, and * participate in all non-protocol communication. * * @param _connection The connection that is being established * @param _ctx Connection context (includes the upgrade request) * @returns True if protocol messages should be sent (default), false to suppress them */ shouldSendProtocolMessages( _connection: Connection, _ctx: ConnectionContext ): boolean; /** * Check if a connection has protocol messages enabled. * Protocol messages include identity, state sync, and MCP server lists. * * Safe to call after hibernation — re-wraps the connection if the * in-memory accessor cache was cleared. * @param connection The connection to check * @returns True if the connection receives protocol messages */ isConnectionProtocolEnabled(connection: Connection): boolean; /** * Mark a connection as having protocol messages disabled. * Called internally when shouldSendProtocolMessages returns false. */ private _setConnectionNoProtocol; /** * Called before the Agent's state is persisted and broadcast. * Override to validate or reject an update by throwing an error. * * IMPORTANT: This hook must be synchronous. */ validateStateChange(nextState: State, source: Connection | "server"): void; /** * Called after the Agent's state has been persisted and broadcast to all clients. * This is a notification hook — errors here are routed to onError and do not * affect state persistence or client broadcasts. * * @param state Updated state * @param source Source of the state update ("server" or a client connection) */ onStateChanged(state: State | undefined, source: Connection | "server"): void; /** * @deprecated Renamed to `onStateChanged` — the behavior is identical. * `onStateUpdate` will be removed in the next major version. * * Called after the Agent's state has been persisted and broadcast to all clients. * This is a server-side notification hook. For the client-side state callback, * see the `onStateUpdate` option in `useAgent` / `AgentClient`. * * @param state Updated state * @param source Source of the state update ("server" or a client connection) */ onStateUpdate(state: State | undefined, source: Connection | "server"): void; /** * Dispatch to the appropriate persistence hook based on the mode * cached in the constructor. No prototype walks at call time. */ private _callStatePersistenceHook; /** * Called when the Agent receives an email via routeAgentEmail() * Override this method to handle incoming emails * @param payload Internal wire format — plain data + RpcTarget bridge */ _onEmail(payload: { from: string; to: string; headers: Headers; rawSize: number; _secureRouted?: boolean; _bridge: EmailBridge; }): Promise; /** * Reply to an email * @param email The email to reply to * @param options Options for the reply * @param options.secret Secret for signing agent headers (enables secure reply routing). * Required if the email was routed via createSecureReplyEmailResolver. * Pass explicit `null` to opt-out of signing (not recommended for secure routing). * @returns void */ replyToEmail( email: AgentEmail, options: { fromName: string; subject?: string | undefined; body: string; contentType?: string; headers?: Record; secret?: string | null; } ): Promise; /** * Send an outbound email via an Email Service binding. * * Automatically injects agent routing headers (X-Agent-Name, X-Agent-ID). * When `secret` is provided, signs headers with HMAC-SHA256 so that replies * can be routed back to this agent instance via createSecureReplyEmailResolver. * * @param options.binding The send_email binding (e.g. this.env.EMAIL) * @param options.to Recipient address(es) * @param options.from Sender address or {email, name} object * @param options.subject Email subject line * @param options.text Plain text body (at least one of text/html required) * @param options.html HTML body (at least one of text/html required) * @param options.replyTo Reply-to address * @param options.cc CC recipient(s) * @param options.bcc BCC recipient(s) * @param options.inReplyTo Message-ID of the email this is replying to (for threading) * @param options.headers Additional custom headers * @param options.secret Secret for signing agent routing headers * @returns The messageId from Email Service */ sendEmail(options: SendEmailOptions): Promise; private _tryCatch; /** * Automatically wrap custom methods with agent context * This ensures getCurrentAgent() works in all custom methods without decorators */ private _autoWrapCustomMethods; onError(connection: Connection, error: unknown): void | Promise; onError(error: unknown): void | Promise; /** * Render content (not implemented in base class) */ render(): void; /** * Retry an async operation with exponential backoff and jitter. * Retries on all errors by default. Use `shouldRetry` to bail early on non-retryable errors. * * @param fn The async function to retry. Receives the current attempt number (1-indexed). * @param options Retry configuration. * @param options.maxAttempts Maximum number of attempts (including the first). Falls back to static options, then 3. * @param options.baseDelayMs Base delay in ms for exponential backoff. Falls back to static options, then 100. * @param options.maxDelayMs Maximum delay cap in ms. Falls back to static options, then 3000. * @param options.shouldRetry Predicate called with the error and next attempt number. Return false to stop retrying immediately. Default: retry all errors. * @returns The result of fn on success. * @throws The last error if all attempts fail or shouldRetry returns false. */ retry( fn: (attempt: number) => Promise, options?: RetryOptions & { /** Return false to stop retrying a specific error. Receives the error and the next attempt number. Default: retry all errors. */ shouldRetry?: ( err: unknown, nextAttempt: number ) => boolean; } ): Promise; /** * Queue a task to be executed in the future * @param callback Name of the method to call * @param payload Payload to pass to the callback * @param options Options for the queued task * @param options.retry Retry options for the callback execution * @returns The ID of the queued task */ queue( callback: keyof this, payload: T, options?: { retry?: RetryOptions; } ): Promise; private _flushingQueue; private _flushQueue; /** * Dequeue a task by ID * @param id ID of the task to dequeue */ dequeue(id: string): void; /** * Dequeue all tasks */ dequeueAll(): void; /** * Dequeue all tasks by callback * @param callback Name of the callback to dequeue */ dequeueAllByCallback(callback: string): void; /** * Get a queued task by ID * @param id ID of the task to get * @returns The task or undefined if not found */ getQueue(id: string): QueueItem | undefined; /** * Get all queues by key and value * @param key Key to filter by * @param value Value to filter by * @returns Array of matching QueueItem objects */ getQueues(key: string, value: string): QueueItem[]; private _scheduleOwnerPathKey; private _facetRunRowsForPrefix; private _deleteFacetRunRowsForPrefix; private _rootAlarmOwner; private _validateScheduleCallback; /** * Insert (or, for idempotent calls, return the existing row for) a * schedule owned by either this top-level agent (`ownerPath === null`) * or a descendant facet. Returns `{ schedule, created }` — `created` * is `false` when an idempotent insert deduplicates onto an existing * row, so callers can suppress the `schedule:create` event in that * case to match historic semantics. * @internal */ private _insertScheduleForOwner; /** * Insert a schedule row owned by a descendant facet. Called via RPC * from the facet's `schedule()`. Returns `{ schedule, created }` * so the originating facet can suppress `schedule:create` on * idempotent dedup. This method does not emit observability * events itself. * @internal */ _cf_scheduleForFacet( ownerPath: ReadonlyArray, when: Date | string | number, callback: string, payload?: T, options?: { retry?: RetryOptions; idempotent?: boolean; } ): Promise<{ schedule: Schedule; created: boolean; }>; /** * Insert (or, for idempotent calls, return the existing row for) an * interval schedule. Mirrors {@link _insertScheduleForOwner} — * returns `{ schedule, created }` so callers can suppress * `schedule:create` on dedup. * @internal */ private _insertIntervalScheduleForOwner; /** * Insert an interval schedule row owned by a descendant facet. * Called via RPC from the facet's `scheduleEvery()`. Returns * `{ schedule, created }` so the originating facet can suppress * `schedule:create` on idempotent dedup. This method does not * emit observability events itself. * @internal */ _cf_scheduleEveryForFacet( ownerPath: ReadonlyArray, intervalSeconds: number, callback: string, payload?: T, options?: { retry?: RetryOptions; _idempotent?: boolean; } ): Promise<{ schedule: Schedule; created: boolean; }>; /** * Cancel a schedule row owned by a descendant facet, scoped by * `owner_path_key` so siblings can't reach each other's rows. * Returns the canceled row's callback name so the originating * facet can emit `schedule:cancel`. This method does not emit * observability events itself. * @internal */ _cf_cancelScheduleForFacet( ownerPath: ReadonlyArray, id: string ): Promise<{ ok: boolean; callback?: string; }>; /** * Clean root-owned bookkeeping for a sub-tree of facets. This * bulk-cancels schedules whose `owner_path` starts with the given * prefix and deletes root-side facet fiber recovery leases for the * same sub-tree. Used by `deleteSubAgent` and recursive facet * destroy. Emits `schedule:cancel` on this agent (the alarm-owning * root) for each schedule row removed — the facets being torn down * may not be alive to receive the events themselves. * @internal */ _cf_cleanupFacetPrefix( ownerPath: ReadonlyArray ): Promise; private _scheduleRowToSchedule; private _getScheduleForOwner; private _listSchedulesForOwner; /** * Read a single schedule row owned by a descendant facet. * @internal */ _cf_getScheduleForFacet( ownerPath: ReadonlyArray, id: string ): Promise | undefined>; /** * List schedule rows owned by a descendant facet, scoped by * `owner_path_key` so siblings remain isolated from each other. * @internal */ _cf_listSchedulesForFacet( ownerPath: ReadonlyArray, criteria?: ScheduleCriteria ): Promise[]>; /** * Acquire a root-owned keepAlive ref on behalf of a descendant facet. * Facets share the root isolate but cannot set their own physical * alarm, so this lets facet work use the root alarm heartbeat. * @internal */ _cf_acquireFacetKeepAlive( ownerPath: ReadonlyArray ): Promise; /** * Release a root-owned keepAlive ref previously acquired for a facet. * Idempotent so disposer calls can safely race or run twice. * @internal */ _cf_releaseFacetKeepAlive(token: string): Promise; /** * Register a facet's durable run row in the root-side index so root * alarm housekeeping can dispatch recovery checks into idle facets. * The facet remains authoritative for snapshots and recovery hooks. * @internal */ _cf_registerFacetRun( ownerPath: ReadonlyArray, runId: string ): Promise; /** * Remove a completed facet fiber from the root-side index. * @internal */ _cf_unregisterFacetRun( ownerPath: ReadonlyArray, runId: string ): Promise; /** * Schedule a task to be executed in the future * * Cron schedules are **idempotent by default** — calling `schedule("0 * * * *", "tick")` * multiple times with the same callback, cron expression, and payload returns * the existing schedule instead of creating a duplicate. Set `idempotent: false` * to override this. * * For delayed and scheduled (Date) types, set `idempotent: true` to opt in * to the same dedup behavior (matched on callback + payload). This is useful * when calling `schedule()` in `onStart()` to avoid accumulating duplicate * rows across Durable Object restarts. * * @template T Type of the payload data * @param when When to execute the task (Date, seconds delay, or cron expression) * @param callback Name of the method to call * @param payload Data to pass to the callback * @param options Options for the scheduled task * @param options.retry Retry options for the callback execution * @param options.idempotent Dedup by callback+payload. Defaults to `true` for cron, `false` otherwise. * @returns Schedule object representing the scheduled task */ schedule( when: Date | string | number, callback: keyof this, payload?: T, options?: { retry?: RetryOptions; idempotent?: boolean; } ): Promise>; /** * Schedule a task to run repeatedly at a fixed interval. * * This method is **idempotent** — calling it multiple times with the same * `callback`, `intervalSeconds`, and `payload` returns the existing schedule * instead of creating a duplicate. A different interval or payload is * treated as a distinct schedule and creates a new row. * * This makes it safe to call in `onStart()`, which runs on every Durable * Object wake: * * ```ts * async onStart() { * // Only one schedule is created, no matter how many times the DO wakes * await this.scheduleEvery(30, "tick"); * } * ``` * * @template T Type of the payload data * @param intervalSeconds Number of seconds between executions * @param callback Name of the method to call * @param payload Data to pass to the callback * @param options Options for the scheduled task * @param options.retry Retry options for the callback execution * @returns Schedule object representing the scheduled task */ scheduleEvery( intervalSeconds: number, callback: keyof this, payload?: T, options?: { retry?: RetryOptions; _idempotent?: boolean; } ): Promise>; /** * Get a scheduled task by ID * @template T Type of the payload data * @param id ID of the scheduled task * @returns The Schedule object or undefined if not found * @deprecated Use {@link getScheduleById}. This synchronous API cannot cross * Durable Object boundaries and throws inside sub-agents. */ getSchedule(id: string): Schedule | undefined; /** * Get a scheduled task by ID. * * Unlike the deprecated synchronous {@link getSchedule}, this works inside * sub-agents by delegating to the top-level parent that owns the alarm. * * @template T Type of the payload data * @param id ID of the scheduled task * @returns The Schedule object or undefined if not found */ getScheduleById(id: string): Promise | undefined>; /** * Get scheduled tasks matching the given criteria * @template T Type of the payload data * @param criteria Criteria to filter schedules * @returns Array of matching Schedule objects * @deprecated Use {@link listSchedules}. This synchronous API cannot cross * Durable Object boundaries and throws inside sub-agents. */ getSchedules(criteria?: ScheduleCriteria): Schedule[]; /** * List scheduled tasks matching the given criteria. * * Unlike the deprecated synchronous {@link getSchedules}, this works inside * sub-agents by delegating to the top-level parent that owns the alarm. * * @template T Type of the payload data * @param criteria Criteria to filter schedules * @returns Array of matching Schedule objects */ listSchedules(criteria?: ScheduleCriteria): Promise[]>; /** * Cancel a scheduled task. * * Schedules are isolated by owner: a top-level agent's * `cancelSchedule(id)` only matches its own schedules, and a * sub-agent's `cancelSchedule(id)` only matches schedules it * created. To clear every schedule under a sub-agent (and its * descendants), call `parent.deleteSubAgent(Cls, name)` from the * parent — that bulk-cleans root-owned bookkeeping via * {@link _cf_cleanupFacetPrefix}. * * @param id ID of the task to cancel * @returns true if the task was cancelled, false if the task was not found */ cancelSchedule(id: string): Promise; /** * Keep the Durable Object alive via alarm heartbeats. * Returns a disposer function that stops the heartbeat when called. * * Use this when you have long-running work and need to prevent the * DO from going idle (eviction after ~70-140s of inactivity). * The heartbeat fires every `keepAliveIntervalMs` (default 30s) via the * alarm system, without creating schedule rows or emitting observability * events. Configure via `static options = { keepAliveIntervalMs: 5000 }`. * * In facets, delegates the physical heartbeat to the root parent * because facets do not have independent alarm slots. * * @example * ```ts * const dispose = await this.keepAlive(); * try { * // ... long-running work ... * } finally { * dispose(); * } * ``` */ keepAlive(): Promise<() => void>; /** * Run an async function while keeping the Durable Object alive. * The heartbeat is automatically stopped when the function completes * (whether it succeeds or throws). * * This is the recommended way to use keepAlive — it guarantees cleanup * so you cannot forget to dispose the heartbeat. * * @example * ```ts * const result = await this.keepAliveWhile(async () => { * const data = await longRunningComputation(); * return data; * }); * ``` */ keepAliveWhile(fn: () => Promise): Promise; /** * Run a function as a durable fiber. The fiber is registered in SQLite * before execution, checkpointable during execution via `ctx.stash()`, * and recoverable after eviction via `onFiberRecovered`. * * - Row created in `cf_agents_runs` at start, deleted on completion * - `keepAlive()` held for the duration — prevents idle eviction * - Inline (await result) or fire-and-forget (`void this.runFiber(...)`) * * @param name Informational name for debugging and recovery filtering * @param fn Async function to execute. Receives a FiberContext with stash/snapshot. * @returns The return value of fn */ runFiber(name: string, fn: (ctx: FiberContext) => Promise): Promise; /** * Checkpoint data for the currently executing fiber. * Uses AsyncLocalStorage to identify the correct fiber, * so it works correctly even with concurrent fibers. * * Throws if called outside a `runFiber` callback. */ stash(data: unknown): void; /** * Called when an interrupted fiber is detected after restart. * Override to implement recovery (re-invoke work, notify clients, etc.). * * Internal framework fibers are filtered by `_handleInternalFiberRecovery` * before this hook runs — users only see their own fibers. * * Default: logs a warning. */ onFiberRecovered(_ctx: FiberRecoveryContext): Promise; /** * Override point for subclasses to handle internal (framework) fibers * before the user's recovery hook fires. Return `true` if handled. * @internal */ protected _handleInternalFiberRecovery( _ctx: FiberRecoveryContext ): Promise; /** @internal Detect fibers left by a dead process (runFiber system). */ private _checkRunFibers; /** @internal */ _onAlarmHousekeeping(): Promise; private _isSameAgentPathPrefix; /** * Root-side scan for durable fibers owned by descendant facets. * `cf_agents_facet_runs` is only an index; actual snapshots and * recovery hooks live in each facet's own `cf_agents_runs` table. * @internal */ private _checkFacetRunFibers; /** * Dispatch a runFiber recovery check into the facet identified by * `ownerPath`. Returns the number of remaining local `cf_agents_runs` * rows on the target facet after recovery. * @internal */ _cf_checkRunFibersForFacet( ownerPath: ReadonlyArray ): Promise; /** * Dispatch a scheduled callback into the facet identified by * `ownerPath`. Walks one step at a time: if `ownerPath` matches * `selfPath`, executes the callback locally; otherwise resolves * the next descendant facet and recurses through its own RPC. * * Called by the root's `alarm()` (which owns the physical alarm * for facet-owned schedules) and by intermediate facets while * walking down the chain. * @internal */ _cf_dispatchScheduledCallback( ownerPath: ReadonlyArray, row: ScheduleStorageRow ): Promise; /** * Recursively destroy a descendant facet identified by * `targetPath`. Walks down from `selfPath` until reaching the * target's immediate parent, where it cancels the target's * parent-owned schedules (and any descendants), removes the * target from the registry, and calls `ctx.facets.delete` to * wipe the target's storage. * * Called by a facet's own `destroy()` (via the root) so that * `this.destroy()` inside a sub-agent results in the same * cleanup as `parent.deleteSubAgent(Cls, name)` from the parent. * @internal */ _cf_destroyDescendantFacet( targetPath: ReadonlyArray ): Promise; private _executeScheduleCallback; private _scheduleNextAlarm; /** * Override PartyServer's onAlarm hook as a no-op. * Agent handles alarm logic directly in the alarm() method override, * but super.alarm() calls onAlarm() after #ensureInitialized(), * so we suppress the default "Implement onAlarm" warning. */ onAlarm(): void; /** * Method called when an alarm fires. * Executes any scheduled tasks that are due. * * Calls super.alarm() first to ensure PartyServer's #ensureInitialized() * runs, which resolves this.name from ctx.id.name (including for * facets, which are spawned with an explicit id so they have their * own ctx.id.name; pre-2026-03-15 alarms fall back to the legacy * __ps_name storage record) and calls onStart() if needed. * * @remarks * To schedule a task, please use the `this.schedule` method instead. * See {@link https://developers.cloudflare.com/agents/api-reference/schedule-tasks/} */ alarm(): Promise; /** * Intercept incoming HTTP/WS requests whose URL contains a * `/sub/{child-class}/{child-name}` marker and forward them to * the facet. The `onBeforeSubAgent` hook fires first (authorize, * mutate, or short-circuit). If the hook doesn't return a * Response, the framework resolves the facet and hands the * request off. * * After a WebSocket upgrade completes, subsequent frames route * directly to the child — the parent is only on the path for the * initial request. * * @experimental The API surface may change before stabilizing. */ fetch(request: Request): Promise; broadcast( msg: string | ArrayBuffer | ArrayBufferView, without?: string[] ): void; getConnection(id: string): Connection | undefined; getConnections(tag?: string): Iterable>; private _cf_broadcastToParentSubAgent; _cf_broadcastToSubAgent( ownerPath: ReadonlyArray, message: string | ArrayBuffer | ArrayBufferView, without?: string[] ): Promise; _cf_subAgentConnectionMetas( ownerPath: ReadonlyArray ): Promise; _cf_sendToSubAgentConnection( connectionId: string, message: string | ArrayBuffer | ArrayBufferView ): Promise; _cf_closeSubAgentConnection( connectionId: string, code?: number, reason?: string ): Promise; _cf_setSubAgentConnectionState( connectionId: string, state: unknown ): Promise; private _cf_subAgentConnectionMetaForPath; private _cf_subAgentTargetPath; private _cf_subAgentPathFromOuterUri; private _isSameAgentPath; private _cf_connectionHasSubAgentTarget; protected _cf_connectionTargetsSubAgent(connection: Connection): boolean; /** * Returns true when the current request is addressed to a child facet of * this agent rather than to this agent itself. * * Chat-style subclasses wrap `onConnect` before the base Agent forwarding * wrapper runs, so they need a request-level check to avoid sending their * own protocol frames on sockets that are about to be forwarded to a child. */ protected _cf_requestTargetsSubAgent(request: Request): boolean; private _cf_forwardSubAgentWebSocketConnect; private _cf_createSubAgentConnectionBridge; private _cf_forwardSubAgentWebSocketMessage; private _cf_forwardSubAgentWebSocketClose; private _cf_resolveSubAgentConnection; _cf_handleSubAgentWebSocketConnect( bridge: SubAgentConnectionBridge, meta: SubAgentConnectionMeta ): Promise; _cf_handleSubAgentWebSocketMessage( message: WSMessage, bridge: SubAgentConnectionBridge, meta: SubAgentConnectionMeta ): Promise; _cf_handleSubAgentWebSocketClose( code: number, reason: string, wasClean: boolean, bridge: SubAgentConnectionBridge, meta: SubAgentConnectionMeta ): Promise; private _cf_runWithSubAgentBridge; private _cf_createSubAgentBridgeConnection; private _cf_storeVirtualSubAgentConnection; protected _cf_hydrateSubAgentConnectionsFromRoot(): Promise; private _cf_getRawConnectionState; private _cf_getForwardedSubAgentState; /** * Parent-side middleware hook. Fires before a request is * forwarded into a facet sub-agent. Mirrors `onBeforeConnect` / * `onBeforeRequest`. * * - return `void` (default) → forward the original request * - return `Request` → forward this (modified) request * - return `Response` → return this response to the * client; do not wake the child * * Default implementation: return void (permissive). * * The hook receives the **original** request with its URL intact — * including the `/sub/{class}/{name}` segment. The routing * decision for which facet to wake is fixed at parse time, so if * you return a modified `Request`, its headers, body, method, and * query string flow through to the child, but the **pathname** * the child sees is always the tail after `/sub/{class}/{name}`. * Customize via headers/body rather than URL-rewriting. * * WebSocket upgrade requests flow through this hook the same way as * plain HTTP. If you return a mutated `Request`, make sure it still * carries the original `Upgrade: websocket` and `Sec-WebSocket-*` * headers — the simplest safe recipe is to clone the incoming * request's headers (via `new Headers(req.headers)`) and only add * or replace entries, rather than constructing a fresh `Headers` * object from scratch. * * @experimental The API surface may change before stabilizing. * * @example * ```ts * class Inbox extends Agent { * override async onBeforeSubAgent(req, { className, name }) { * // Strict registry gate * if (!this.hasSubAgent(className, name)) { * return new Response("Not found", { status: 404 }); * } * } * } * ``` */ onBeforeSubAgent( _request: Request, _child: { className: string; name: string; } ): Promise; /** * Resolve the facet Fetcher for the match and forward the * request to it with `/sub/{class}/{name}` stripped. * * @internal */ private _cf_forwardToFacet; /** * Bridge method used by `getSubAgentByName`. Resolves the facet * on each call (idempotent via `subAgent`) and dispatches one * RPC method. Stateless — no cached references. * * @internal */ _cf_invokeSubAgent( className: string, name: string, method: string, args: unknown[] ): Promise; /** * Initialize this agent as a facet in a single RPC. * * Runs entirely inside the child's isolate, so every storage write * and `onStart()` I/O is owned by the child DO. This replaces the * previous "construct a Request in the parent DO and `stub.fetch()` * it on the child" handshake, whose native I/O was tied to the * parent and triggered "Cannot perform I/O on behalf of a different * Durable Object" on the child. * * We set `_isFacet` eagerly (before `__unsafe_ensureInitialized` * runs `onStart()`) so any code that legitimately branches on it * — e.g. skipping parent-owned alarms in schedule guards — sees * the flag during the first `onStart()` run. Protocol broadcasts are * suppressed only during this bootstrap window; afterward, facets can * broadcast to their own WebSocket clients reached via sub-agent * routing. * * The facet's name (and `this.name` getter) is handled entirely by * partyserver via `ctx.id.name`, which is populated because the * parent passed an explicit `id: parentNs.idFromName(name)` to * `ctx.facets.get()` — see {@link _cf_resolveSubAgent}. No * `setName()` call or `__ps_name` storage write is needed; the * facet's name survives cold wake automatically because the * factory re-runs and `idFromName` is deterministic. * * @internal Called by {@link subAgent}. */ _cf_initAsFacet( name: string, parentPath?: ReadonlyArray<{ className: string; name: string; }> ): Promise; /** * Ancestor chain for this agent, root-first. Empty for top-level * DOs. Populated at facet init time; survives hibernation. * * @example * ```ts * class Chat extends Agent { * onStart() { * console.log("chat started under:", this.parentPath); * // → [{ className: "Tenant", name: "acme" }, { className: "Inbox", name: "alice" }] * } * } * ``` * * @experimental The API surface may change before stabilizing. */ get parentPath(): ReadonlyArray<{ className: string; name: string; }>; /** * Ancestor chain + self, root-first. Convenient for logging. * * @experimental The API surface may change before stabilizing. */ get selfPath(): ReadonlyArray<{ className: string; name: string; }>; /** * Resolve a typed RPC stub for this facet's **immediate** parent * agent. * * Symmetric with `subAgent(Cls, name)`: while `subAgent` opens a * stub from parent to child, `parentAgent` opens one from child * to parent. Pass the direct parent's class reference — the * framework verifies it matches the last entry of * `this.parentPath` at runtime, then looks up `env[Cls.name]` to * find the namespace binding. * * `this.parentPath` is root-first, so the direct parent is the * **last** entry: `this.parentPath.at(-1)`. For grandparents and * further ancestors, iterate `this.parentPath` and use * `getAgentByName(env.X, this.parentPath[i].name)` directly. * * Assumes the standard "binding name matches class name" convention. * If your `wrangler.jsonc` binds the parent under a different name * (e.g. `{ class_name: "Inbox", name: "MY_INBOX" }`), call * `getAgentByName(env.MY_INBOX, this.parentPath.at(-1)!.name)` * directly instead. * * @experimental The API surface may change before stabilizing. * * @throws If this agent is not a facet (no parent). * @throws If `Cls.name` doesn't match the recorded direct-parent * class (guards against accidentally reaching the wrong * DO, especially in nested Root → Mid → Leaf chains). * @throws If no env binding named `Cls.name` is found. * * @example * ```ts * class Chat extends AIChatAgent { * async onChatMessage(...) { * const inbox = await this.parentAgent(Inbox); * const memory = await inbox.getSharedMemory("facts"); * // ... * } * } * ``` */ parentAgent( cls: SubAgentClass ): Promise>; /** * Get or create a named sub-agent — a child Durable Object (facet) * with its own isolated SQLite storage running on the same machine. * * The child class must extend `Agent` and be exported from the worker * entry point. The first call for a given name triggers the child's * `onStart()`. Subsequent calls return the existing instance. * * @experimental The API surface may change before stabilizing. * * @param cls The Agent subclass (must be exported from the worker) * @param name Unique name for this child instance * @returns A typed RPC stub for calling methods on the child * * @example * ```typescript * const searcher = await this.subAgent(SearchAgent, "main-search"); * const results = await searcher.search("cloudflare agents"); * ``` */ subAgent( cls: SubAgentClass, name: string ): Promise>; /** Maximum number of non-terminal agent-tool runs this parent may own at once. */ maxConcurrentAgentTools: number; onAgentToolStart(_run: AgentToolRunInfo): Promise; onAgentToolFinish( _run: AgentToolRunInfo, _result: AgentToolLifecycleResult ): Promise; runAgentTool( cls: ChatCapableAgentClass, options: RunAgentToolOptions ): Promise>; hasAgentToolRun( cls: SubAgentClass, runId: string ): boolean; hasAgentToolRun(agentType: string, runId: string): boolean; clearAgentToolRuns(options?: { olderThan?: number; status?: AgentToolRunStatus[]; }): Promise; private _isAgentToolTerminal; private _activeAgentToolRunCount; private _defaultAgentToolPreview; private _readAgentToolRun; private _resultFromAgentToolRow; private _terminalResultFromInspection; private _updateAgentToolTerminal; private _markAgentToolRunning; private _parseAgentToolJson; private _stringifyAgentToolOutput; private _broadcastAgentToolEvent; private _broadcastAgentToolChunks; private _forwardAgentToolStream; private _broadcastAgentToolTerminal; private _asAgentToolChildAdapter; private _agentToolClassByName; private _replayAndInterruptAgentToolRun; private _replayAgentToolRuns; private _reconcileAgentToolRuns; /** * Shared facet resolution — takes a CamelCase class name string * (matching `ctx.exports`) rather than a class reference. Both * `subAgent(cls, name)` and `_cf_invokeSubAgent(className, ...)` * funnel through here so registry bookkeeping and the * `_cf_initAsFacet` handshake are consistent. * * @internal */ private _cf_resolveSubAgent; /** * Forcefully abort a running sub-agent. The child stops executing * immediately and will be restarted on next {@link subAgent} call. * Pending RPC calls receive the reason as an error. * Transitively aborts the child's own children. * * @experimental The API surface may change before stabilizing. * * @param cls The Agent subclass used when creating the child * @param name Name of the child to abort * @param reason Error thrown to pending/future RPC callers */ abortSubAgent(cls: SubAgentClass, name: string, reason?: unknown): void; /** * Delete a sub-agent: abort it if running, then permanently wipe its * storage. Transitively deletes the child's own children. * * @experimental The API surface may change before stabilizing. * * @param cls The Agent subclass used when creating the child * @param name Name of the child to delete */ deleteSubAgent(cls: SubAgentClass, name: string): Promise; /** @internal */ private _subAgentRegistryReady; /** @internal */ private _ensureSubAgentRegistry; /** @internal */ private _recordSubAgent; /** @internal */ private _forgetSubAgent; /** * Whether this agent has previously spawned (and not deleted) a * sub-agent of the given class and name. Backed by an * auto-maintained SQLite registry in the parent's storage. * * Intended for strict-registry access patterns in * `onBeforeSubAgent` or similar gating logic. * * @experimental The API surface may change before stabilizing. * * @example * ```ts * async onBeforeSubAgent(req, { className, name }) { * if (!this.hasSubAgent(className, name)) { * return new Response("Not found", { status: 404 }); * } * } * ``` */ hasSubAgent(cls: SubAgentClass, name: string): boolean; hasSubAgent(className: string, name: string): boolean; /** * List known sub-agents, optionally filtered by class. Reflects * the registry rows written by {@link subAgent} and removed by * {@link deleteSubAgent}. * * @experimental The API surface may change before stabilizing. */ listSubAgents( cls: SubAgentClass ): Array<{ className: string; name: string; createdAt: number; }>; listSubAgents(className?: string): Array<{ className: string; name: string; createdAt: number; }>; /** * Destroy the Agent, removing all state and scheduled tasks. * * On a top-level agent: drops every table, clears the alarm, and * aborts the isolate. * * On a sub-agent (facet): delegates teardown to the immediate * parent so the parent-owned schedule rows for this sub-agent * (and any of its descendants) are cancelled, the parent's * `cf_agents_sub_agents` registry entry is cleared, and * `ctx.facets.delete` wipes the facet's own storage. The * `ctx.facets.delete` call aborts this isolate, so this method * may not return cleanly when invoked from inside the facet — * callers should treat it as fire-and-forget. */ destroy(): Promise; /** @internal Drop every internal Agents SDK table during top-level destroy. */ protected _dropInternalTablesForDestroy(): void; /** * Check if a method is callable * @param method The method name to check * @returns True if the method is marked as callable */ private _isCallable; /** * Get all methods marked as callable on this Agent * @returns A map of method names to their metadata */ getCallableMethods(): Map; /** * Start a workflow and track it in this Agent's database. * Automatically injects agent identity into the workflow params. * * @template P - Type of params to pass to the workflow * @param workflowName - Name of the workflow binding in env (e.g., 'MY_WORKFLOW') * @param params - Params to pass to the workflow * @param options - Optional workflow options * @returns The workflow instance ID * * @example * ```typescript * const workflowId = await this.runWorkflow( * 'MY_WORKFLOW', * { taskId: '123', data: 'process this' } * ); * ``` */ runWorkflow

( workflowName: WorkflowName, params: P, options?: RunWorkflowOptions ): Promise; /** * Send an event to a running workflow. * The workflow can wait for this event using step.waitForEvent(). * * @param workflowName - Name of the workflow binding in env (e.g., 'MY_WORKFLOW') * @param workflowId - ID of the workflow instance * @param event - Event to send * * @example * ```typescript * await this.sendWorkflowEvent( * 'MY_WORKFLOW', * workflowId, * { type: 'approval', payload: { approved: true } } * ); * ``` */ sendWorkflowEvent( workflowName: WorkflowName, workflowId: string, event: WorkflowEventPayload ): Promise; /** * Approve a waiting workflow. * Sends an approval event to the workflow that can be received by waitForApproval(). * * @param workflowId - ID of the workflow to approve * @param data - Optional approval data (reason, metadata) * * @example * ```typescript * await this.approveWorkflow(workflowId, { * reason: 'Approved by admin', * metadata: { approvedBy: userId } * }); * ``` */ approveWorkflow( workflowId: string, data?: { reason?: string; metadata?: Record; } ): Promise; /** * Reject a waiting workflow. * Sends a rejection event to the workflow that will cause waitForApproval() to throw. * * @param workflowId - ID of the workflow to reject * @param data - Optional rejection data (reason) * * @example * ```typescript * await this.rejectWorkflow(workflowId, { * reason: 'Request denied by admin' * }); * ``` */ rejectWorkflow( workflowId: string, data?: { reason?: string; } ): Promise; /** * Terminate a running workflow. * This immediately stops the workflow and sets its status to "terminated". * * @param workflowId - ID of the workflow to terminate (must be tracked via runWorkflow) * @throws Error if workflow not found in tracking table * @throws Error if workflow binding not found in environment * @throws Error if workflow is already completed/errored/terminated (from Cloudflare) * * @example * ```typescript * await this.terminateWorkflow(workflowId); * ``` */ terminateWorkflow(workflowId: string): Promise; /** * Pause a running workflow. * The workflow can be resumed later with resumeWorkflow(). * * @param workflowId - ID of the workflow to pause (must be tracked via runWorkflow) * @throws Error if workflow not found in tracking table * @throws Error if workflow binding not found in environment * @throws Error if workflow is not running (from Cloudflare) * * @example * ```typescript * await this.pauseWorkflow(workflowId); * ``` */ pauseWorkflow(workflowId: string): Promise; /** * Resume a paused workflow. * * @param workflowId - ID of the workflow to resume (must be tracked via runWorkflow) * @throws Error if workflow not found in tracking table * @throws Error if workflow binding not found in environment * @throws Error if workflow is not paused (from Cloudflare) * * @example * ```typescript * await this.resumeWorkflow(workflowId); * ``` */ resumeWorkflow(workflowId: string): Promise; /** * Restart a workflow instance. * This re-runs the workflow from the beginning with the same ID. * * @param workflowId - ID of the workflow to restart (must be tracked via runWorkflow) * @param options - Optional settings * @param options.resetTracking - If true (default), resets created_at and clears error fields. * If false, preserves original timestamps. * @throws Error if workflow not found in tracking table * @throws Error if workflow binding not found in environment * * @example * ```typescript * // Reset tracking (default) * await this.restartWorkflow(workflowId); * * // Preserve original timestamps * await this.restartWorkflow(workflowId, { resetTracking: false }); * ``` */ restartWorkflow( workflowId: string, options?: { resetTracking?: boolean; } ): Promise; /** * Find a workflow binding by its name. */ private _findWorkflowBindingByName; /** * Get all workflow binding names from the environment. */ private _getWorkflowBindingNames; /** * Get the status of a workflow and update the tracking record. * * @param workflowName - Name of the workflow binding in env (e.g., 'MY_WORKFLOW') * @param workflowId - ID of the workflow instance * @returns The workflow status */ getWorkflowStatus( workflowName: WorkflowName, workflowId: string ): Promise; /** * Get a tracked workflow by ID. * * @param workflowId - Workflow instance ID * @returns Workflow info or undefined if not found */ getWorkflow(workflowId: string): WorkflowInfo | undefined; /** * Query tracked workflows with cursor-based pagination. * * @param criteria - Query criteria including optional cursor for pagination * @returns WorkflowPage with workflows, total count, and next cursor * * @example * ```typescript * // First page * const page1 = this.getWorkflows({ status: 'running', limit: 20 }); * * // Next page * if (page1.nextCursor) { * const page2 = this.getWorkflows({ * status: 'running', * limit: 20, * cursor: page1.nextCursor * }); * } * ``` */ getWorkflows(criteria?: WorkflowQueryCriteria): WorkflowPage; /** * Count workflows matching criteria (for pagination total). */ private _countWorkflows; /** * Encode a cursor from workflow info for pagination. * Stores createdAt as Unix timestamp in seconds (matching DB storage). */ private _encodeCursor; /** * Decode a pagination cursor. * Returns createdAt as Unix timestamp in seconds (matching DB storage). */ private _decodeCursor; /** * Delete a workflow tracking record. * * @param workflowId - ID of the workflow to delete * @returns true if a record was deleted, false if not found */ deleteWorkflow(workflowId: string): boolean; /** * Delete workflow tracking records matching criteria. * Useful for cleaning up old completed/errored workflows. * * @param criteria - Criteria for which workflows to delete * @returns Number of records matching criteria (expected deleted count) * * @example * ```typescript * // Delete all completed workflows created more than 7 days ago * const deleted = this.deleteWorkflows({ * status: 'complete', * createdBefore: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) * }); * * // Delete all errored and terminated workflows * const deleted = this.deleteWorkflows({ * status: ['errored', 'terminated'] * }); * ``` */ deleteWorkflows( criteria?: Omit & { createdBefore?: Date; } ): number; /** * Migrate workflow tracking records from an old binding name to a new one. * Use this after renaming a workflow binding in wrangler.toml. * * @param oldName - Previous workflow binding name * @param newName - New workflow binding name * @returns Number of records migrated * * @example * ```typescript * // After renaming OLD_WORKFLOW to NEW_WORKFLOW in wrangler.toml * async onStart() { * const migrated = this.migrateWorkflowBinding('OLD_WORKFLOW', 'NEW_WORKFLOW'); * } * ``` */ migrateWorkflowBinding(oldName: string, newName: string): number; /** * Update workflow tracking record from InstanceStatus */ private _updateWorkflowTracking; /** * Convert a database row to WorkflowInfo */ private _rowToWorkflowInfo; /** * Find the binding name for this Agent's namespace by matching class name. * Returns undefined if no match found - use options.agentBinding as fallback. */ private _findAgentBindingName; private _findBindingNameForNamespace; private _restoreRpcMcpServers; /** * Handle a callback from a workflow. * Called when the Agent receives a callback at /_workflow/callback. * Override this to handle all callback types in one place. * * @param callback - The callback payload */ onWorkflowCallback(callback: WorkflowCallback): Promise; /** * Called when a workflow reports progress. * Override to handle progress updates. * * @param workflowName - Workflow binding name * @param workflowId - ID of the workflow * @param progress - Typed progress data (default: DefaultProgress) */ onWorkflowProgress( workflowName: string, workflowId: string, progress: unknown ): Promise; /** * Called when a workflow completes successfully. * Override to handle completion. * * @param workflowName - Workflow binding name * @param workflowId - ID of the workflow * @param result - Optional result data */ onWorkflowComplete( workflowName: string, workflowId: string, result?: unknown ): Promise; /** * Called when a workflow encounters an error. * Override to handle errors. * * @param workflowName - Workflow binding name * @param workflowId - ID of the workflow * @param error - Error message */ onWorkflowError( workflowName: string, workflowId: string, error: string ): Promise; /** * Called when a workflow sends a custom event. * Override to handle custom events. * * @param workflowName - Workflow binding name * @param workflowId - ID of the workflow * @param event - Custom event payload */ onWorkflowEvent( workflowName: string, workflowId: string, event: unknown ): Promise; /** * Handle a workflow callback via RPC. * @internal - Called by AgentWorkflow, do not call directly */ _workflow_handleCallback(callback: WorkflowCallback): Promise; /** * Broadcast a message to all connected clients via RPC. * @internal - Called by AgentWorkflow, do not call directly */ _workflow_broadcast(message: unknown): Promise; /** * Update agent state via RPC. * @internal - Called by AgentWorkflow, do not call directly */ _workflow_updateState( action: "set" | "merge" | "reset", state?: unknown ): Promise; /** * Connect to a new MCP Server via RPC (Durable Object binding) * * The binding name and props are persisted to storage so the connection * is automatically restored after Durable Object hibernation. * * @example * await this.addMcpServer("counter", env.MY_MCP); * await this.addMcpServer("counter", env.MY_MCP, { props: { userId: "123" } }); */ addMcpServer( serverName: string, binding: DurableObjectNamespace, options?: AddRpcMcpServerOptions ): Promise<{ id: string; state: typeof MCPConnectionState.READY; }>; /** * Connect to a new MCP Server via HTTP (SSE or Streamable HTTP) * * @example * await this.addMcpServer("github", "https://mcp.github.com"); * await this.addMcpServer("github", "https://mcp.github.com", { transport: { type: "sse" } }); * await this.addMcpServer("github", url, callbackHost, agentsPrefix, options); // legacy */ addMcpServer( serverName: string, url: string, callbackHostOrOptions?: string | AddMcpServerOptions, agentsPrefix?: string, options?: { client?: ConstructorParameters[1]; transport?: { headers?: HeadersInit; type?: TransportType; }; } ): Promise< | { id: string; state: typeof MCPConnectionState.AUTHENTICATING; authUrl: string; } | { id: string; state: typeof MCPConnectionState.READY; } >; removeMcpServer(id: string): Promise; getMcpServers(): MCPServersState; /** * Create the OAuth provider used when connecting to MCP servers that require authentication. * * Override this method in a subclass to supply a custom OAuth provider implementation, * for example to use pre-registered client credentials, mTLS-based authentication, * or any other OAuth flow beyond dynamic client registration. * * @example * // Custom OAuth provider * class MyAgent extends Agent { * createMcpOAuthProvider(callbackUrl: string): AgentMcpOAuthProvider { * return new MyCustomOAuthProvider( * this.ctx.storage, * this.name, * callbackUrl * ); * } * } * * @param callbackUrl The OAuth callback URL for the authorization flow * @returns An {@link AgentMcpOAuthProvider} instance used by {@link addMcpServer} */ createMcpOAuthProvider(callbackUrl: string): AgentMcpOAuthProvider; private broadcastMcpServers; /** * Handle MCP OAuth callback request if it's an OAuth callback. * * This method encapsulates the entire OAuth callback flow: * 1. Checks if the request is an MCP OAuth callback * 2. Processes the OAuth code exchange * 3. Establishes the connection if successful * 4. Broadcasts MCP server state updates * 5. Returns the appropriate HTTP response * * @param request The incoming HTTP request * @returns Response if this was an OAuth callback, null otherwise */ private handleMcpOAuthCallback; /** * Handle OAuth callback response using MCPClientManager configuration * @param result OAuth callback result * @param request The original request (needed for base URL) * @returns Response for the OAuth callback */ private handleOAuthCallbackResponse; } /** * Namespace for creating Agent instances * @template Agentic Type of the Agent class * @deprecated Use DurableObjectNamespace instead */ type AgentNamespace> = DurableObjectNamespace; /** * Agent's durable context */ type AgentContext = DurableObjectState; /** * Configuration options for Agent routing */ type AgentOptions = PartyServerOptions; /** * Route a request to the appropriate Agent * @param request Request to route * @param env Environment containing Agent bindings * @param options Routing options * @returns Response from the Agent or undefined if no route matched */ declare function routeAgentRequest( request: Request, env: Env, options?: AgentOptions ): Promise; type EmailRoutingOptions = AgentOptions & { resolver: EmailResolver; /** * Callback invoked when no routing information is found for an email. * Use this to reject the email or perform custom handling. * If not provided, a warning is logged and the email is dropped. */ onNoRoute?: (email: ForwardableEmailMessage) => void | Promise; }; declare class EmailBridge extends RpcTarget { #private; constructor(email: ForwardableEmailMessage); getRaw(): Promise; setReject(reason: string): void; forward(rcptTo: string, headers?: Headers): Promise; reply(options: { from: string; to: string; raw: string; }): Promise; [Symbol.dispose](): void; } /** * Route an email to the appropriate Agent * @param email The email to route * @param env The environment containing the Agent bindings * @param options The options for routing the email * @returns A promise that resolves when the email has been routed */ declare function routeAgentEmail( email: ForwardableEmailMessage, env: Env, options: EmailRoutingOptions ): Promise; /** * Get or create an Agent by name * @template Env Environment type containing bindings * @template T Type of the Agent class * @param namespace Agent namespace * @param name Name of the Agent instance * @param options Options for Agent creation * @returns Promise resolving to an Agent instance stub */ declare function getAgentByName< Env extends Cloudflare.Env = Cloudflare.Env, T extends Agent = Agent, Props extends Record = Record >( namespace: DurableObjectNamespace, name: string, options?: { jurisdiction?: DurableObjectJurisdiction; locationHint?: DurableObjectLocationHint; props?: Props; } ): Promise>; /** * A wrapper for streaming responses in callable methods */ declare class StreamingResponse { private _connection; private _id; private _closed; constructor(connection: Connection, id: string); /** * Whether the stream has been closed (via end() or error()) */ get isClosed(): boolean; /** * Send a chunk of data to the client * @param chunk The data to send * @returns false if stream is already closed (no-op), true if sent */ send(chunk: unknown): boolean; /** * End the stream and send the final chunk (if any) * @param finalChunk Optional final chunk of data to send * @returns false if stream is already closed (no-op), true if sent */ end(finalChunk?: unknown): boolean; /** * Send an error to the client and close the stream * @param message Error message to send * @returns false if stream is already closed (no-op), true if sent */ error(message: string): boolean; } //#endregion //#region src/agent-tool-types.d.ts type AgentToolRunStatus = | "starting" | "running" | "completed" | "error" | "aborted" | "interrupted"; type AgentToolTerminalStatus = Extract< AgentToolRunStatus, "completed" | "error" | "aborted" | "interrupted" >; type AgentToolDisplayMetadata = { name?: string; icon?: string; } & Record; type AgentToolRunInfo = { runId: string; parentToolCallId?: string; agentType: string; inputPreview?: unknown; status: AgentToolRunStatus; display?: AgentToolDisplayMetadata; displayOrder: number; startedAt: number; completedAt?: number; }; type AgentToolLifecycleResult = { status: AgentToolTerminalStatus; summary?: string; error?: string; }; type RunAgentToolOptions = { input: Input; runId?: string; parentToolCallId?: string; displayOrder?: number; signal?: AbortSignal; inputPreview?: unknown; display?: AgentToolDisplayMetadata; }; type RunAgentToolResult = { runId: string; agentType: string; status: AgentToolTerminalStatus; output?: Output; summary?: string; error?: string; }; type ChatCapableAgentClass = SubAgentClass; type AgentToolRunInspection = { runId: string; status: Exclude; requestId?: string; streamId?: string; output?: Output; summary?: string; error?: string; startedAt: number; completedAt?: number; }; type AgentToolStoredChunk = { sequence: number; body: string; }; type AgentToolChildAdapter = { startAgentToolRun( input: Input, options: { runId: string; signal?: AbortSignal; } ): Promise>; cancelAgentToolRun(runId: string, reason?: unknown): Promise; inspectAgentToolRun( runId: string ): Promise | null>; getAgentToolChunks( runId: string, options?: { afterSequence?: number; } ): Promise; tailAgentToolRun?( runId: string, options?: { afterSequence?: number; signal?: AbortSignal; } ): Promise>; }; type AgentToolEvent = | { kind: "started"; runId: string; agentType: string; inputPreview?: unknown; order: number; display?: AgentToolDisplayMetadata; } | { kind: "chunk"; runId: string; body: string; } | { kind: "finished"; runId: string; summary: string; } | { kind: "error"; runId: string; error: string; } | { kind: "aborted"; runId: string; reason?: string; } | { kind: "interrupted"; runId: string; error: string; }; type AgentToolEventMessage = { type: "agent-tool-event"; parentToolCallId?: string; sequence: number; replay?: true; event: AgentToolEvent; }; type AgentToolRunState = { runId: string; agentType: string; parentToolCallId?: string; inputPreview?: unknown; order: number; display?: AgentToolDisplayMetadata; status: "running" | "completed" | "error" | "aborted" | "interrupted"; parts: UIMessage["parts"]; summary?: string; error?: string; subAgent: { agent: string; name: string; }; }; type AgentToolEventState = { runsById: Record; runsByToolCallId: Record; unboundRuns: AgentToolRunState[]; }; //#endregion export { MCPClientManagerOptions as $, FiberRecoveryContext as A, SUB_PREFIX as At, SqlError as B, CallableMetadata as C, TransportState as Ct, EmailRoutingOptions as D, StreamableHTTPEdgeClientTransport as Dt, DEFAULT_AGENT_STATIC_OPTIONS as E, SSEEdgeClientTransport as Et, RPCRequest as F, WSMessage$1 as G, StreamingResponse as H, RPCResponse as I, getCurrentAgent as J, callable as K, Schedule as L, MCPServerMessage as M, getSubAgentByName as Mt, MCPServersState as N, parseSubAgentPath as Nt, EmailSendBinding as O, McpClientOptions as Ot, QueueItem as P, routeSubAgentRequest as Pt, MCPClientManager as Q, ScheduleCriteria as R, AgentStaticOptions as S, getMcpAuthContext as St, ConnectionContext$1 as T, WorkerTransportOptions as Tt, SubAgentClass as U, StateUpdateMessage as V, SubAgentStub as W, routeAgentRequest as X, routeAgentEmail as Y, unstable_callable as Z, AddRpcMcpServerOptions as _, McpAgent as _t, AgentToolEventState as a, MCPServerFilter as at, AgentNamespace as b, experimental_createMcpHandler as bt, AgentToolRunInspection as c, getNamespacedData as ct, AgentToolStoredChunk as d, RPCServerTransport as dt, MCPClientOAuthCallbackConfig as et, AgentToolTerminalStatus as f, RPCServerTransportOptions as ft, AddMcpServerOptions as g, ElicitResult$1 as gt, RunAgentToolResult as h, ElicitRequestSchema$1 as ht, AgentToolEventMessage as i, MCPOAuthCallbackResult as it, MCPServer as j, SubAgentPathMatch as jt, FiberContext as k, TransportType as kt, AgentToolRunState as l, RPCClientTransport as lt, RunAgentToolOptions as m, ElicitRequest$1 as mt, AgentToolDisplayMetadata as n, MCPConnectionResult as nt, AgentToolLifecycleResult as o, MCPServerOptions as ot, ChatCapableAgentClass as p, RPC_DO_PREFIX as pt, getAgentByName as q, AgentToolEvent as r, MCPDiscoverResult as rt, AgentToolRunInfo as s, RegisterServerOptions as st, AgentToolChildAdapter as t, MCPClientOAuthResult as tt, AgentToolRunStatus as u, RPCClientTransportOptions as ut, Agent as v, CreateMcpHandlerOptions as vt, Connection$1 as w, WorkerTransport as wt, AgentOptions as x, McpAuthContext as xt, AgentContext as y, createMcpHandler as yt, SendEmailOptions as z }; //# sourceMappingURL=agent-tool-types-DSteYkkS.d.ts.map