Cloudflare OS is a monorepo of Cloudflare Workers packages that together form a coherent “operating system” for AI-driven productivity. At its core, a public-facing router dispatches requests to a stateful backend Durable Object (the “kernel”), which manages user sessions, workspaces, Gadget lifecycles, and security policy. Gatekeepers run as separate Workers and act as sandboxed bridges to external services. The frontend is a pure SPA that communicates with the backend exclusively over a Cap’n Web RPC session on a persistent WebSocket.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/cloudflare/cloudflare-os/llms.txt
Use this file to discover all available pages before exploring further.
workerd — the Cloudflare Workers runtime that powers this stack — is fully open source. Cloudflare OS can run entirely on a self-hosted workerd instance on your own servers. The pnpm run-local command already uses workerd under the hood via wrangler.The OS Analogy
Cloudflare OS is genuinely analogous to a traditional operating system at the technical level, not just in marketing language.| Traditional OS | Cloudflare OS | Notes |
|---|---|---|
| Kernel | packages/workshop-backend | Manages users, workspaces, Gadgets, Gatekeepers, and enforces capability-based security |
| Device drivers | packages/gatekeeper-* | Each Gatekeeper bridges one external service (GitHub, Google, Slack, etc.) |
| Shell | packages/workshop-frontend | Pure SPA; communicates with the kernel only via the RPC API |
| Processes | Gadgets | User-specific app instances, each sandboxed in a Dynamic Worker Facet |
| Executables | Blueprints | Reusable code templates that any user can instantiate into their own Gadget |
| Users | Users | Authenticated humans with their own Durable Object storing sessions and connected accounts |
| ACLs | Shared permissions | Capability-based access; each Gadget is introduced to resources explicitly |
| ??? | Agents | First-class concept distinct from users; accountable to a human, with restricted permissions |
Package Structure
The monorepo is organized into focused packages, each with a clearly bounded role.- Core
- Gatekeepers
- Libraries
packages/workshop-backend — The kernel. Runs on Cloudflare Workers with multiple Durable Object classes (UserDurableObject, OverseerDurableObject, AdminSettings, PendingLogin). Responsible for authentication, workspace lifecycle, Gadget sandboxing, Gatekeeper capability management, and the AI agent loop. Every line of this package is held to a high review bar — keep diffs small and changes elegant.packages/workshop-frontend — The shell. A pure client-side SPA built with React, Kumo UI, Phosphor icons, and Vite. Connects to the backend over a persistent WebSocket and speaks the Cap’n Web RPC API defined in workshop-shared. Contains no server-side rendering — all Gadget sandboxing happens in the browser.packages/workshop-shared — Shared API definitions used by both the frontend and backend. Defines every RPC interface (PublicApi, AuthenticatedApi, Overseer, GadgetClient, AdminApi, and more) using Cap’n Web’s RpcTarget / RpcStub types. Changing this package changes the contract between client and server — treat it with the same care as the backend.packages/router — The public-facing origin Worker. Routes incoming requests by path prefix: /api/* and /blueprint-screenshot/* go to the workshop-backend service binding, and /gatekeeper/<name>/* goes to the matching GATEKEEPER_* service binding. Gatekeeper bindings are discovered at runtime by scanning the router’s own environment for GATEKEEPER_ prefixed bindings — installing a new Gatekeeper is purely a binding change, not a code change. In development mode (no ASSETS binding), the router proxies frontend requests to the Vite dev server instead.Request Flow
A request from the browser travels through several layers before reaching its destination.workshop-backend. Each workspace has its own OverseerDurableObject instance, which manages the Gadgets, chat threads, code history, and Gatekeeper bindings for that workspace.
Service Binding Structure
The rootwrangler.jsonc (used for local development via pnpm run-local) defines the router as the entry point with a single static service binding to the backend. Gatekeeper bindings are added dynamically at dev and deploy time:
wrangler.jsonc is augmented with one GATEKEEPER_<NAME> service binding per installed Gatekeeper — for example, GATEKEEPER_GITHUB, GATEKEEPER_GOOGLE, GATEKEEPER_SLACK. The router discovers them at runtime by scanning its own environment, so no router code changes are needed to add or remove a Gatekeeper.
RPC Protocol: Cap’n Web
All communication between the frontend and backend — and between the backend and Gatekeeper Workers — uses Cap’n Web, a JavaScript/TypeScript RPC system with semantics similar to Cloudflare’s Worker-to-Worker RPC, adapted to run in a browser over WebSocket. Cap’n Web is the right choice here for two reasons:-
Promise pipelining — If an RPC call returns a stub, you can immediately call methods on that stub without waiting for the first round trip to complete. The server resolves the pipeline server-side before delivering the downstream call. This eliminates unnecessary round trips and makes the API feel like local function calls. The
api.tsfile is built entirely around this pattern — for example,openGadget()returns anOverseerstub, and you can pipelinegetMetadata(),listChats(), andsubscribeToCode()on it before the first call even resolves. -
Low boilerplate — You define a TypeScript interface extending
RpcTarget, implement it on the server, and call it from the client as if it were local. There is no schema file, no code generation step, and no manual serialization. This also means Gadget APIs are automatically agent-accessible: because every Gadget’s client and server communicate through Cap’n Web, an AI agent using Code Mode can call any Gadget method directly.
postMessage() into its sandboxed iframe.
Sandbox Model
Cloudflare OS enforces two layers of sandboxing for every Gadget. Server-side sandbox (Dynamic Worker Facets): Each Gadget’s server code runs in a Dynamic Worker instantiated as a Facet of the workspace’sOverseerDurableObject. The Dynamic Worker has all outbound network access disabled by default. It can only communicate with external resources that have been explicitly bound into its environment via Workers Bindings — meaning a Gatekeeper that the user has explicitly introduced to that workspace.
Client-side sandbox (sandboxed iframes):
Each Gadget’s UI code runs inside a sandboxed <iframe> with Content-Security-Policy and iframe sandbox attributes that block it from accessing the internet directly. The only channel available to the Gadget’s client code is a Cap’n Web RPC session provided over postMessage() by the parent Workshop frame. Through this session, the Gadget can call its own server-side Durable Object and interact with the Workshop shell — and nothing else.
This two-layer model means that even if an agent writes buggy or malicious Gadget code, the sandbox prevents it from leaking data or calling arbitrary services. Security is structural, not policy-based.
Quickstart
Run the full stack locally in minutes or deploy to your Cloudflare account.
Gatekeeper Overview
Learn how to connect external services to agents and Gadgets through the Gatekeeper security layer.