workers-mcp-server
by: geelen
Talk to a Cloudflare Worker from Claude Desktop!
📌Overview
Purpose: The framework serves as a proof-of-concept Model Context Protocol (MCP) Server for Cloudflare Workers, extending the functionality of Claude Desktop by enabling RPC communication with server-side functions.
Overview: This MCP Server allows for seamless interaction between Claude Desktop and Cloudflare Workers, utilizing the new RPC syntax to provide responsive and dynamic capabilities. By writing worker code, developers can create functions that Claude Desktop can easily invoke, facilitating various operations via HTTP requests.
Key Features:
-
Easy Function Invocation: The framework allows developers to define functions within a Cloudflare Worker, which can then be invoked from clients like Claude Desktop using the RPC endpoint. This extends the capabilities of MCP clients with server-side functionality.
-
Automated Documentation Generation: The MCP Server includes scripts that automatically generate documentation for the exposed methods, providing a better developer experience by simplifying integration and clear understanding of available functionalities.
Workers MCP Server
Talk to your Cloudflare Workers from Claude Desktop!
Important Note
This project has been superseded by the Workers MCP package. Please use that instead.
Overview
This is a proof-of-concept to write a Model Context Protocol (MCP) Server as a Cloudflare Worker. It allows you to extend Claude Desktop (and other MCP clients) by invoking functions using Cloudflare Worker's new RPC syntax, providing access to any Cloudflare or third-party binding.
You write worker code like this:
export class ExampleWorkerMCP extends WorkerEntrypoint<Env> {
/**
* Generates a random number. This is extra random because it had to travel all the way to
* your nearest Cloudflare PoP to be calculated.
*
* @return {string} A message containing a super duper random number
* */
async getRandomNumber() {
return `Your random number is ${Math.random()}`
}
}
Using the provided MCP proxy, Claude Desktop can see and invoke these messages.
Note:
Math.random()
works the same on a Worker as it does locally, but this is a playful detail.
How to Get Started
- Download Claude Desktop from https://claude.ai/download
- Clone this repository.
- Install dependencies:
pnpm install
- Check
wrangler.json
:
The demo uses the Email Routing API and Browser Rendering. If you don't have access or these are disabled, comment out relevant sections inwrangler.json
to avoid deployment failure. - Deploy the worker:
This generatespnpm deploy:worker
dist/docs.json
fromsrc/index.ts
and deploys using Wrangler. - Generate and upload secret:
This creates a secret innpx workers-mcp secret generate && npx workers-mcp secret upload
.dev.vars
and uploads it withwrangler secret put
. Run this once. - Install the MCP server for Claude Desktop:
npx workers-mcp install <server-alias> <worker-url>
- Restart Claude Desktop:
Restarting is required, particularly after installation or changing methods/documentation.
Iterating on Your Server
- Modify
src/index.ts
- Run:
pnpm deploy:worker
- Usually restart Claude Desktop if you add/remove/change methods or documentation. For code changes within a method, deploying alone is sufficient.
How It Works
This project involves three main components beyond your worker code (src/index.ts
):
1. Docs Generation (scripts/generate-docs.ts
)
The MCP specification separates tools/list
and tools/call
operations. Typically, MCP servers separate schema from implementation, but this combines them for improved developer experience.
We use ts-blank-space and jsdoc-api to parse TypeScript and generate LLM-friendly documentation at build time through JSDoc comments:
Example method with JSDoc:
/**
* Send a text or HTML email to an arbitrary recipient.
*
* @param {string} recipient - The email address of the recipient.
* @param {string} subject - The subject of the email.
* @param {string} contentType - The content type of the email (text/plain or text/html).
* @param {string} body - The body of the email matching the contentType.
* @return {Promise<string>} A success message.
* @throws {Error} If email sending fails or recipient is unverified.
*/
async sendEmail(recipient: string, subject: string, contentType: string, body: string) {
// ...
}
This generates a tools/list
-compatible JSON schema.
To watch and update docs during development, run:
pnpm generate:docs:watch
(Ensure watchexec is installed to use this.)
2. Public HTTP Handler (lib/WorkerMCP.ts
)
Because your worker entrypoint class isn't directly accessible, this file exports a fetch()
handler that exposes a /rpc
endpoint.
The /rpc
endpoint accepts JSON payloads like:
{ "method": "methodName", "args": [ ... ] }
and calls the corresponding method on your WorkerEntrypoint
instance.
3. Local MCP Proxy (scripts/local-proxy.ts
)
This script uses the @modelcontextprotocol/sdk
library to set up a local MCP server that communicates with the remote Cloudflare Worker.
- On
tools/list
, it responds withdocs.json
content. - On
tools/call
, it proxies calls to the remote worker/rpc
, including authentication by sending aBearer
token from a shared secret file.
Installing this proxy for Claude Desktop involves running:
pnpm install:claude <server-alias> <worker-url>
This adds an entry in your claude_desktop_config.json
to launch the local proxy command, enabling multiple server aliases.
Limitations
This project is experimental and has several known limitations:
- Documentation generation only covers
src/index.ts
and does not crawl imports. - Only class exports are supported for docs generation.
- The proxy communication does not follow a formal RPC specification.
- Limited error handling, non-text return values, and streaming responses support.
- No support yet for
wrangler dev
;wrangler dev --remote
may work in future. - Missing implementation of
notifications/tools/list_changed
spec to allow refreshing without restarting Claude Desktop. - Doc parsing does not yet integrate TypeScript type information (only JSDoc).
- Doc generation may be redundant if using schema validators like zod or typebox but currently provides static extraction.
Future Directions
- Enable Claude Desktop to communicate directly with the Worker without the proxy.
- Add support for
wrangler dev --remote
for faster development cycles. - Extract and improve the docs generator into a standalone library, potentially incorporating type info and schema validation.
Feedback & Contributions
Try the project and provide feedback! Issues and pull requests are welcome to improve this evolving project.