Cloudflare Worker MCP Server¶
Status: Authored as Cloudflare Worker MCP Server v1
A remote Model Context Protocol server deployed on Cloudflare Workers, with authorization at the HTTP boundary, narrow tool schemas, runtime validation, explicit permission checks, optional Durable Object-backed state, and deployment evidence.
This stack is valuable when the problem is not "how do I write an MCP server?" but "how do I expose remote tools to AI clients without turning the Worker into an unaudited remote-control endpoint?"
Full rubric¶
Cloudflare Worker MCP Server v1 is the judgeable rubric. Use it when a repository exposes MCP over HTTP from Cloudflare Workers or Cloudflare Agents.
Reference implementation¶
vibecodeqa/ref-cloudflare-worker-mcp. This repo is a product-neutral template. It shows a Worker entrypoint, MCP Streamable HTTP handling, protected resource metadata, authorization before tool dispatch, scoped tool permissions, Zod validation, audit events, CI gates, and a tracked VCQA report.
| Score evidence | Value |
|---|---|
| Repository | vibecodeqa/ref-cloudflare-worker-mcp (published) |
| VCQA report | A 92/100 |
| Verification | self-reported |
| Assessed commit | 2242765 |
| Assessed on | 2026-07-24 |
| CI run | success (2026-07-24) |
| Independent assessment | None published yet. The score above is the reference repo's own claim, not third-party proof. |
| Catalog entry last verified | 2026-08-08 |
Reference template map¶
The reference repo is meant to be inspected, not treated as a black box. These files show the stack contract in code:
| Evidence | Where to look | What it proves |
|---|---|---|
| Worker MCP boundary | src/index.ts |
The Worker owns metadata and MCP routes, authorizes before dispatch, registers tools, checks scopes, validates inputs, and emits audit-ready mutation evidence. |
| Protocol and auth tests | src/index.test.ts |
CI exercises unauthorized rejection, scope checks, SDK transport initialization, and representative tool calls. |
| Cloudflare deployment shape | wrangler.toml |
Worker name, compatibility date, environment config, and binding shape are explicit. |
| Quality gates | .github/workflows/ci.yml |
Lint, typecheck, tests, build, and VCQA run before changes are trusted. |
| Deployment operations | docs/runbooks/deploy.md |
Production deploys require protected environment evidence and protocol smoke tests. |
| Incident operations | docs/runbooks/incident-response.md |
A bad tool call can be investigated with actor, tenant, tool, outcome, and request correlation. |
| Score evidence | docs/vcqa-report.md |
The template carries a tracked VCQA score and visible gaps. |
What this teaches¶
Choose this stack when you need a remote MCP server that can be reached by hosted clients, IDE agents, internal automation, or product agents without installing a local process on every machine. It fits tool surfaces such as account operations, tenant administration, content workflows, deploy automation, support tooling, and product-specific data access.
Do not choose this stack just because MCP is fashionable. If the tools only run on a developer laptop, use a local MCP server. If the server is just a normal HTTP API, use API and web-security standards. If the tool can mutate customer or production data and you cannot fund authorization, audit, rate limiting, and operational review, do not expose it as a remote MCP tool yet.
The stack is strongest when the Worker remains a narrow protocol and policy boundary:
- MCP transport and discovery live at explicit routes such as
/mcpand/.well-known/oauth-protected-resource. - Authentication and authorization happen before MCP tool dispatch.
- Every tool has a bounded input schema, a permission mapping, and a declared side-effect profile.
- Durable Objects, KV, R2, or D1 are used only behind scoped storage keys and documented state ownership.
- CI proves unauthorized rejection, tool listing, schema validation, and at least one representative read and mutation path.
Architecture flow¶
| Step | Boundary | What VCQA expects |
|---|---|---|
| 1 | Remote MCP client | Client sends Streamable HTTP requests and follows protected-resource discovery. |
| 2 | Cloudflare Worker route | Worker owns /mcp and metadata routes explicitly. |
| 3 | Auth and protected metadata | Unauthorized requests fail before MCP dispatch. |
| 4 | MCP server transport | SDK or Cloudflare Agent receives only authorized request context. |
| 5 | Tool permission check | Tool name maps to a narrow read or mutate grant. |
| 6 | Zod argument validation | Parsed input, not raw JSON, drives authorization-sensitive work. |
| 7 | Tool handler | Side effects are scoped and intentionally named. |
| 8 | Scoped binding or Durable Object | State keys and object IDs match tenant, user, session, or resource boundaries. |
| 9 | Audit event | Mutations produce actor, tool, target, outcome, and request correlation evidence. |
The important boundary is between worker and mcp: unauthenticated or
unauthorized requests should fail before the MCP server dispatches tools.
Decision matrix¶
| Need | Better fit |
|---|---|
| Local tools for one developer machine | Local stdio MCP server. |
| Public product API consumed by normal web/mobile clients | HTTP API standard plus OpenAPI, auth, and web-security standards. |
| Remote tools for agents with organization/product permissions | Cloudflare Worker MCP Server. |
| Remote tools plus tenant-specific deployable Cloudflare surfaces | Cloudflare Worker MCP Server plus Tenant-Deployed Cloudflare SaaS. |
| Long-running jobs, fan-out work, or delayed side effects | Worker MCP gateway plus queue/workflow/job boundary; do not hide long work inside one tool request. |
| Unrestricted shell, database, or cloud admin access | Do not expose as a remote MCP tool without redesigning into narrow, auditable capabilities. |
When this stack is a good fit¶
- The server must be reachable over HTTP by remote MCP clients.
- The tool surface is product-specific or organization-specific, not a generic public API.
- The Worker can enforce auth, permissions, validation, and audit before any side effect.
- Tool latency and runtime behavior fit Cloudflare Workers constraints.
- Stateful coordination, if needed, can be represented through Durable Objects or other Cloudflare bindings with clear ownership boundaries.
- You need repeatable CI/deployment evidence rather than a hand-run local server.
When not to use it¶
- The server only needs stdio for local developer workflows.
- Tool calls require long-running jobs that exceed Worker request/runtime expectations without a queue, workflow, or async job boundary.
- Tools need unrestricted shell, database, or cloud-account access.
- The auth model is "the client promised it is allowed."
- Multiple tenants, users, or sessions would share the same Durable Object ID, cache key, or audit stream by accident.
- You cannot explain what each mutating tool is allowed to change.
Architecture contract¶
| Layer | Standard expectation |
|---|---|
| Worker entrypoint | Owns MCP routes explicitly; non-MCP routes do not fall through into protocol handling. |
| Transport | Uses current MCP Streamable HTTP semantics for remote clients; legacy SSE is treated as compatibility, not the default. |
| Discovery | Protected resource metadata or equivalent authorization challenge is discoverable by clients. |
| Authorization | Request auth is checked at the Worker boundary before any tool list, resource read, or tool call. |
| Permissions | Each tool maps to narrow scopes or grants; read and mutate capabilities are separated. |
| Validation | Tool arguments are parsed with Zod or equivalent runtime validation before permission-sensitive work. |
| State | Durable Object IDs and storage keys include the tenant, user, session, resource, or coordination boundary they represent. |
| Audit | Mutating calls emit actor, tool, target, scope, outcome, timestamp, and request correlation. |
| Output safety | Tool output is data returned to a client, not instructions trusted by later tool calls. |
| Deployment | CI proves auth rejection, server initialization, tool listing, schema validation, and representative calls. |
Scope¶
Remote Model Context Protocol servers exposed over HTTP from Cloudflare Workers or Cloudflare Agents, where the Worker owns authorization, tool schemas, validation, scoped state, and deployment evidence.
Not in scope¶
- Local stdio MCP servers running on a developer machine.
- Ordinary HTTP product APIs that happen to be on Workers.
- MCP client behaviour, prompt design, or agent orchestration.
- Generic Cloudflare Workers doctrine already owned upstream.
Upstream references¶
- Cloudflare Agents MCP
- Cloudflare
McpAgentAPI - Cloudflare Workers documentation
- Cloudflare Workers bindings
- Durable Objects
- MCP specification
- MCP Streamable HTTP transport
- MCP authorization
- MCP security best practices
- MCP TypeScript SDK
- Zod documentation
- OWASP Authorization Cheat Sheet
- OWASP Logging Cheat Sheet
- GitHub Actions secure use
Composes¶
- Cloudflare Workers
- Durable Objects
- Model Context Protocol
- Zod
- TypeScript
- Web Security
- GitHub Actions
VCQA-owned rule surface¶
- Worker routing and MCP endpoint ownership.
- Remote MCP authorization and protected resource discovery.
- Tool schema quality, runtime validation, and parsed-argument use.
- Tool-level permission boundaries and read/write separation.
- Durable Object, KV, R2, or D1 state ownership.
- Tenant/user/session/resource scoping for state keys and object IDs.
- Mutating tool audit evidence.
- Safe output handling for untrusted tool results.
- CI and deployment evidence for protocol, auth, validation, and representative tool behavior.
Detection signals¶
wrangler.toml,wrangler.json, orwrangler.jsonc.- Worker entrypoint exporting a
fetchhandler or Cloudflare Agent/McpAgent server. @modelcontextprotocol/sdkor Cloudflare Agents MCP dependencies.- MCP route names such as
/mcp,/sse, or protected-resource metadata paths. - Tool registration calls, tool/resource schemas, or Zod object schemas.
- OAuth, bearer-token, service-token, Access, or protected resource metadata handling.
- Durable Object, KV, R2, D1, or service bindings used by tool handlers.
- Audit/log calls that name actor, tool, target, request ID, outcome, and environment.
- CI smoke tests for unauthorized requests, tool listing, validation failure, and representative tool invocation.
Combination-born guidelines¶
- Remote MCP plus Workers makes auth a routing concern. The Worker must reject unauthorized requests before the MCP server dispatches tools.
- MCP schemas plus Zod must converge. The schema advertised to clients and the schema enforced at runtime should describe the same boundary.
- Tools are permissions, not just functions. Every exposed tool is a capability. Mutating tools require narrower grants than read-only discovery.
- Durable Objects are coordination boundaries. Object IDs must be scoped to the tenant, user, session, or resource being coordinated.
- OAuth discovery is part of interoperability. Protected remote servers need metadata or challenge behavior clients can discover.
- Tool output is untrusted. Returned text, fetched documents, and model-facing content must not become policy for later tool calls.
- CI has to exercise the protocol. Unit tests are not enough; the deployed Worker shape must prove initialization, auth rejection, schema errors, and a representative call path.
Implementation checklist¶
- Define the MCP route and any metadata routes explicitly.
- Decide whether the implementation uses raw Workers plus the MCP TypeScript SDK,
Cloudflare Agents
McpAgent, or a thin wrapper around either. - Add a typed binding contract for Durable Objects, KV, R2, D1, secrets, and service bindings.
- Put auth verification before tool listing, resource access, and tool calls.
- Give every tool a name, description, Zod input schema, permission requirement, and side-effect classification.
- Parse tool inputs once and pass parsed values into authorization and side effects.
- Add audit events for every mutation and every denied mutation attempt.
- Redact tokens, prompts, tool arguments, and fetched content where logs could expose secrets or customer data.
- Add CI tests for unauthorized requests, invalid input, tool listing, read-only calls, mutating calls, and deployment config.
- Document how to rotate credentials, revoke access, and investigate a bad tool call.
Rule highlights¶
- R-SHAPE-1: Worker entrypoint owns the MCP endpoint. Remote MCP routing is explicit and non-MCP routes do not fall through into the protocol handler.
- R-AUTH-1: Worker boundary enforces authorization. Protected MCP endpoints reject unauthenticated or unauthorized requests before tool dispatch.
- R-AUTH-2: Protected resource metadata is published. OAuth-protected MCP servers expose protected resource metadata or a challenge path clients can discover.
- R-PERM-1: Tools map to narrow permissions. Each tool has an enforceable permission or scope, and mutating tools require write-capable grants.
- R-TOOL-1: Tool input schemas are narrow. Tool parameters are concrete, bounded, and advertised to clients instead of hidden in prose.
- R-VAL-1: Tool arguments are parsed before side effects. Zod or equivalent runtime validation happens before authorization-sensitive work or mutations.
- R-STATE-1: Durable Object IDs are scoped to the coordination boundary. Tenant, user, session, or resource state is not mixed through shared object IDs.
- R-AUDIT-1: Mutating tool calls leave an audit trail. Actor, tool, target, scope, outcome, timestamp, and request correlation are captured.
- R-OUT-1: Tool output is untrusted data. External or user-controlled content returned by tools is not treated as policy or instructions for further tool calls.
- R-DEPLOY-3: CI runs protocol and auth smoke tests before production. Deploys prove initialization, tool listing, representative calls, and unauthorized rejection.
Limitations¶
- Authorization is judged at the boundary, not end to end. The rubric can require that an unauthenticated request fails before tool dispatch; it cannot prove that every tool's scope mapping matches your product's permission model.
- Tool side effects are declared, not verified. A tool that claims to be read-only and writes is a defect this standard asks you to test for, not one a scan can detect.
- Protocol conformance is checked against a pinned specification date. A client on a different revision may still fail against a compliant server.
- Durable Object and binding scoping is judged from key construction in source. Runtime key collisions across tenants are only provable with a runtime transcript.
- Rate limiting and abuse control are not rules in v1. They are named as adjacent concerns; a repo can score well and still be trivially abusable.
Anti-patterns¶
- Exposing generic
runCommand,queryDatabase,fetchUrl, oradminActiontools without narrow schemas and tool-specific authorization. - Letting the MCP SDK receive a request before the Worker has established actor, environment, and permission context.
- Using one Durable Object ID, KV prefix, or audit stream for multiple tenants or unrelated resources.
- Treating local dev tokens, preview tokens, and production OAuth credentials as interchangeable.
- Allowing tool descriptions or fetched content to instruct the server to ignore authorization, validation, or audit rules.
- Logging full prompts, bearer tokens, OAuth responses, tool arguments, or fetched customer data while trying to create observability.
- Shipping only unit tests and no HTTP smoke test for the deployed MCP route.
Benefits¶
- Gives teams a concrete way to decide when remote MCP on Workers is worth the operational surface area.
- Converts generic MCP and Cloudflare documentation into checkable production expectations.
- Makes tool schemas, permissions, state ownership, and auditability visible in code review.
- Helps reference templates and product repos prove their quality with the same rubric instead of relying on a demo-only starter.
Maintenance¶
| Maintenance | Value |
|---|---|
| Latest edition | Cloudflare Worker MCP Server v1 |
| Pin reports and scans to | /standards/cloudflare-worker-mcp-server/v1/ |
| Last reviewed | 2026-07 |
| Next review due | 2027-07 |
| Edition targets | cloudflareWorkers latest, mcp 2025-11-25, typescript 6 |
| Lifecycle | active |
| Errata | none |
| Composes | cloudflare-workers, durable-objects, mcp, zod, typescript, web-security, github-actions |
Editions are cut on material change, not on a calendar. A review that finds the edition
still correct moves Last reviewed forward without a new edition. Metadata lives in
standards/registry.json.