This example exposes Computer through MCP. It gives an MCP client one durable workspace, a fast Worker shell, and a full Linux container behind a single Code Mode code tool.
To copy the example into a standalone project, start Docker and run:
npm create cloudflare@latest computer-mcp -- \
--template=cloudflare/computer/examples/mcpC3 installs the dependencies and offers to deploy the project. You can then edit and redeploy it from the new computer-mcp directory.
To build and deploy from a clone of this repository instead, run:
npm install
npm run build --workspace @cloudflare/computer
npm run deploy --workspace @example/computer-mcpThe endpoint fails closed until you set MCP_TOKEN. Generate a random token rather than reusing a password:
openssl rand -hex 32After deployment, add the result as an encrypted Worker secret in the Cloudflare dashboard. From a standalone project, you can set it with:
npx wrangler secret put MCP_TOKENFrom a clone of this repository, specify the example configuration:
npx wrangler secret put MCP_TOKEN --config examples/mcp/wrangler.jsoncConfigure your MCP client to use the remote HTTP endpoint:
https://<your-worker>.workers.dev/mcp
Send the token on every MCP request:
Authorization: Bearer <MCP_TOKEN>
For clients that accept MCP server configuration as JSON, the entry typically looks like this:
{
"mcpServers": {
"computer": {
"type": "http",
"url": "https://<your-worker>.workers.dev/mcp",
"headers": {
"Authorization": "Bearer <MCP_TOKEN>"
}
}
}
}The exact configuration filename and format depend on the client. Keep the token in the client's secret storage when it provides one rather than committing it to a configuration file.
The Worker's root URL prints its MCP endpoint and available backends. GET /health returns ok without authentication.
Once connected, ask your MCP client to work in the Computer workspace. For example:
Create /workspace/hello.txt, read it back, and list the workspace files.
Commands use worker-shell by default. Select the container when the task needs a full Linux environment:
Use container-shell to create a small Node.js project in /workspace, install its dependencies, and run its tests.
The client sees one public MCP tool named code. The model uses that tool to write a small JavaScript function that combines Computer's durable filesystem and command tools:
async () => {
await codemode.write({
path: "/workspace/package.json",
content: JSON.stringify({ scripts: { test: "node --test" } }),
});
const result = await codemode.exec({
command: "npm test",
backend: "container-shell",
});
return { exitCode: result.exitCode, stdout: result.stdout };
}You do not need to call the underlying Computer tools individually. The code tool describes these functions and backends to the model:
| Function | Purpose |
|---|---|
codemode.read({ path, offset?, byteOffset?, limit? }) |
Read bounded text or model-supported media. |
codemode.ls({ path, limit?, offset? }) |
List one page of a directory. |
codemode.find({ path, pattern, limit?, offset? }) |
Find paths matching a glob. |
codemode.grep({ path, query, ... }) |
Search workspace text. |
codemode.write({ path, content }) |
Create or replace a file. |
codemode.edit({ path, edits }) |
Apply exact text replacements to a file. |
codemode.delete_({ path, recursive? }) |
Delete a file or directory. |
codemode.exec({ command, cwd?, backend?, env? }) |
Run a command, using worker-shell unless another backend is selected. |
@cloudflare/codemode runs Code Mode orchestration code in an isolated Dynamic Worker with outbound networking disabled. Tool calls return to the Durable Object and operate on its Computer workspace.
| Backend | Use it for |
|---|---|
worker-shell |
The fast default for common commands. It has no ambient network access; its built-in Git command supports HTTPS remotes. |
container-shell |
Full Debian Linux with Node.js, npm, git, native binaries, and outbound networking. |
The model can select a backend in codemode.exec(). The example does not retry automatically, so backend choice, cost, and failures remain visible.
The container starts only when container-shell is selected. Computer synchronizes /workspace between the Durable Object and the container's FUSE mount before and after each command.
Local development requires a running Docker daemon for the Linux container. From the repository root:
npm install
npm run build --workspace @cloudflare/computer
printf 'MCP_TOKEN=development-token\n' > examples/mcp/.dev.vars
npm run dev --workspace @example/computer-mcpThe explicit build step is needed only when working from this repository; a standalone C3 project installs the published Computer package. On the first run, Wrangler also builds the container image. Connect to http://127.0.0.1:8787/mcp with the same bearer token.
npm run typecheck --workspace @example/computer-mcp
npm test --workspace @example/computer-mcpThe workerd integration test authenticates a real MCP client, verifies that only code is public, runs filesystem and Worker-shell operations, and confirms that files persist across calls. It does not start the Linux container.
Check the public routes first:
curl https://<your-worker>.workers.dev/health
curl https://<your-worker>.workers.dev/Then stream Worker and Durable Object logs:
npx wrangler tail --config examples/mcp/wrangler.jsoncA 401 means the bearer token is missing or incorrect. A 503 means MCP_TOKEN has not been configured. Backend failures are returned in the codemode.exec() result with the selected backend name.
This example is intentionally single-user. Every authenticated request reaches the same Durable Object and workspace. Keep MCP_TOKEN private and deploy a separate copy for each trust boundary.
Code Mode's orchestration Worker and the Worker shell cannot make arbitrary outbound requests. The Worker shell's built-in Git command can use HTTPS remotes. The Linux container has outbound access so package managers and development tools work.
For a multi-user service, replace the bearer-token check with OAuth, derive the Durable Object name from the authenticated subject, and add per-user execution and storage limits.