MCP Router
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Routersearch the web for latest AI news"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Router
Extensible MCP server that aggregates multiple backends behind a single endpoint.
Architecture
Claude → CF Worker (OAuth) → Workers VPC → CF Tunnel → MCP Router → [Backends]
│ ↓
(private backbone) email backend → ProtonMail Bridge
(add more backends here)Security: No public DNS exposure. Traffic flows through Cloudflare's private network via Workers VPC binding to a Cloudflare Tunnel with no public hostname.
Related MCP server: todoist-v1-mcp-server
Quick Start
1. Clone and install
curl -LsSf https://astral.sh/uv/install.sh | sh
git clone https://github.com/marklubin/mcp-email-server.git mcp-infrastructure
cd mcp-infrastructure2. Configure
cp .env.example .env
# Edit .env with your credentials3. ProtonMail Bridge (one-time)
protonmail-bridge --cli
# > login
# > info (note the bridge password)4. Run
uv run python router/server.pyOr with systemd:
./setup.sh
sudo systemctl enable --now mcp-router@$USER5. Set up Cloudflare Tunnel (for private backend)
cloudflared tunnel login
cloudflared tunnel create mcp-router
# Configure ~/.cloudflared/config.yml (see cloudflare/tunnel-config.yml.example)
sudo systemctl enable --now cloudflared6. Create Workers VPC Service
In Cloudflare Dashboard → Workers & Pages → Workers VPC:
Create service:
mcp-router-vpcSelect tunnel:
mcp-routerTarget:
http://127.0.0.1:8080
7. Deploy Worker
cd cloudflare/worker && npx wrangler deployDeployment
The canonical deployed instance runs on oxnard as the systemd unit mcp-router@mark.service.
Steady-state flow:
Edit code locally on a dev machine (clone of this repo).
Commit and push to
origin/master.From the local clone, run
./scripts/deploy.sh— pushes (if needed), SSHes to the remote, runsgit pull, and restarts the service.If dependencies changed (
pyproject.toml/uv.lock), deploy.sh'suv synckeeps the venv in sync. If it doesn't, restart will still pick up the new deps on nextuv run.
Do not edit code directly on oxnard. The repo is the source of truth — changes made only on the box will drift and get lost. If you must hotpatch in an emergency, copy the fix back into the repo and commit it before doing anything else.
Override the deploy target with MCP_REMOTE=hostname ./scripts/deploy.sh.
Backends
Each backend lives in router/backends/ and exposes tools under its mount prefix.
Backend | Prefix | Purpose |
|
| ProtonMail Bridge — list/search/get/send |
|
| Playwright-over-CDP browser automation |
|
| Todoist tasks/projects |
|
| Push notifications + inbox |
|
| Discord (via user token) |
|
| Agent memory store |
|
| Twitter read via twitterapi.io |
|
| Web search + contents via Exa |
Also available but not currently mounted in server.py:
unified_memory.py— proxies all synix MCP tools from the agent-mesh server on salinas. Wire it up by importing + mounting if you want to replace or augmentmemory.
Email Backend (prefix: email_)
Tool | Description |
| List recent emails |
| Search by subject, sender, or body |
| Get full email content |
| Send email |
Web Backend (prefix: web_)
Uses Exa under the hood. Free tier: 1,000 searches/month.
Tool | Description |
| Web search; optional inline text excerpts |
| Fetch clean text for one or more URLs |
For detailed signatures of other backends, read the source — each tool's docstring is its contract.
Router
Tool | Description |
| Health check with backend status |
| Tail service logs ( |
Adding New Backends
Create
router/backends/yourbackend.py:
from fastmcp import FastMCP
mcp = FastMCP('yourbackend')
@mcp.tool()
async def your_tool(arg: str) -> dict:
"""Your tool description."""
return {'result': 'value'}Mount in
router/server.py:
from backends import yourbackend
router.mount(yourbackend.mcp, prefix='yourbackend')Also append the prefix to the health() backend list.
If the backend needs secrets, add them to
.env.exampleand.env.Commit and run
./scripts/deploy.sh. Tools appear asyourbackend_your_tool.
Claude Config
{
"mcpServers": {
"router": {
"url": "https://mcp-router-proxy.melubin.workers.dev/mcp",
"transport": "sse"
}
}
}Environment Variables
See .env.example for the full list. Required for core operation:
MCP_SECRET= # API key for auth from CF Worker
ROUTER_HOST=127.0.0.1
ROUTER_PORT=8080
PROTON_BRIDGE_HOST=127.0.0.1
PROTON_BRIDGE_IMAP_PORT=1143
PROTON_BRIDGE_SMTP_PORT=1025
PROTON_BRIDGE_USER=you@proton.me
PROTON_BRIDGE_PASSWORD=bridge-passwordBackend-specific keys (only required if the backend is mounted):
EXA_API_KEY= # web search
TODOIST_API_TOKEN= # todoist
TWITTERAPI_IO_KEY= # twitter
DISCORD_TOKEN= # discord
MESH_SERVER_URL= # memory
MESH_TOKEN= # memory
AGENT_MESH_MCP_URL= # unified_memory (if mounted)Project Structure
mcp-infrastructure/
├── router/
│ ├── server.py # Main router, mounts backends
│ └── backends/
│ ├── __init__.py
│ ├── email.py # ProtonMail
│ ├── browser.py # Playwright over CDP
│ ├── todoist.py # Todoist
│ ├── notifications.py # Push/inbox
│ ├── discord.py # Discord user-token
│ ├── memory.py # Agent memory
│ ├── twitter.py # Twitter (twitterapi.io)
│ ├── web.py # Web search (Exa)
│ └── unified_memory.py # Synix proxy (not mounted by default)
├── services/
│ ├── mcp-router.service # systemd template for router
│ ├── cloudflared.service # systemd service for tunnel
│ ├── headless-brave.service # headless browser
│ └── protonmail-bridge.service # ProtonMail Bridge
├── cloudflare/
│ ├── tunnel-config.yml.example # Tunnel config template
│ └── worker/ # CF Worker for OAuth + VPC proxy
├── scripts/
│ ├── deploy.sh # Push and deploy to remote
│ ├── logs.sh # View service logs
│ ├── status.sh # Check service status
│ ├── tunnel.sh # Manage Cloudflare Tunnel
│ ├── test-email.sh # Test email tools
│ ├── test.sh # Run tests
│ ├── browser-connect.sh # Connect to CDP browser
│ ├── run-headless-brave.sh # Launch headless Brave
│ ├── run-headless-firefox.sh # Launch headless Firefox + VNC
│ └── notify-check.sh # Notification health check
├── setup.sh # One-shot setup script
├── pyproject.toml # Python dependencies
└── .env.example # Config templateManagement Scripts
Script | Purpose |
| Push and deploy to remote (respects |
| View last n log lines |
| Check service status |
| Manage tunnel |
| Test email tools |
| Run tests |
| Connect to the CDP-exposed browser |
| Launch headless Brave with CDP |
| Launch headless Firefox + VNC on :99 |
| Notification backend health check |
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityCmaintenanceA Model Context Protocol server implementation designed to run on Cloudflare Workers with integrated OAuth authentication. It enables hosting and securely accessing MCP tools remotely via SSE transport from clients like Claude Desktop.Last updated
- AlicenseAqualityCmaintenanceA clean, reliable MCP (Model Context Protocol) server for Todoist — built on the Todoist unified API v1.Last updated201MIT
- Alicense-qualityDmaintenanceA proof-of-concept MCP server that interacts with Todoist using OAuth-based authorization and is deployed on Cloudflare Workers.Last updated4MIT
- Alicense-qualityCmaintenanceA Cloudflare Worker-based MCP server that enables AI assistants to read and manage Todoist tasks through tools like get_tasks, add_task, update_task, complete_task, delete_task, and move_task.Last updated327MIT
Related MCP Connectors
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
User-owned memory for AI agents, Copilot, Claude, IDEs, CLIs, and chat apps over remote MCP.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/marklubin/mcp-email-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server