An MCP server giving Claude (or any MCP client) direct tool access to GitHub, Cloudflare, Notion, Mem0, and the web — one connector, five real backends.
madmcp is a single MCP server that gives an AI agent tool-level access to
real infrastructure — GitHub, Cloudflare, Notion, Mem0, and arbitrary web
pages — so agent workflows can read and write directly instead of relying on
manual copy/paste between tabs.
An illustrative six-step walkthrough of a mock incident response — finding a
slow endpoint, checking latency metrics, shipping and reviewing a fix, and
logging it to memory — touching all five connectors in one flow (including a
deeper look at Mem0's semantic dedup and relation-graph tools), with a synced
status panel and live call/latency stats alongside the trace. Sample data
throughout, not a live call. (If GitHub Pages isn't enabled for this repo
yet, open demo.html directly.)
Get tokens, deploy, connect to Claude — in that order.
1. Deploy it — pick a host. Both buttons above deploy this repo as-is, no Dockerfile or CLI needed, but they're not identical:
-
Render reads
render.yamland generatesMCP_SHARED_KEYfor you automatically — one less thing to get wrong. Trade-off: the free plan spins down after 15 minutes idle, so the first request after a quiet period is slow (~30s cold start). Fine for testing; upgrade to a paid plan if you want Claude's calls to stay consistently fast. -
Vercel deploys with zero config (this repo's
server.jsalready matches what Vercel expects) and its Fluid compute avoids Render's cold-start spin-down. Trade-off: you have to generateMCP_SHARED_KEYyourself — any long random string, e.g. via a password generator oropenssl rand -hex 32— and paste it into the form; Vercel's button can't auto-fill it the way Render's blueprint does. -
Manufact Cloud is purpose-built for hosting MCP servers (this one included — the default IP allowlist already carries a comment about Manufact's own deploy-time health check). It doesn't have a one-click button with a public URL scheme the way Render/Vercel do; instead sign in, New Server → Import from GitHub → pick this repo, add your env vars on the Configure Deployment screen (or paste a
.env), then Deploy. Node.js is auto-detected frompackage.json, no Dockerfile needed. Free tier scales to zero like Render's free tier (cold starts); paid plans offer "Prevent Scale to Zero." Manufact's gateway URL pattern ishttps://<slug>.run.mcp-use.com/mcp— the/mcp/<key>path-auth variant this repo uses does survive that gateway routing (confirmed: it's the exact pattern in use), so the samehttps://<slug>.run.mcp-use.com/mcp/<your MCP_SHARED_KEY>URL from step 5 below works here too.
Prefer another host, or running it yourself? It's a plain Node/Express app —
npm install && npm start, listens on $PORT (default 8080) — so any
Node-friendly host (Railway, Fly.io, etc.) or your own server works too,
just without any platform's auto-fill.
A note on IP allowlisting across hosts: the allowlist trusts one
reverse-proxy hop by default (TRUST_PROXY_HOPS, default 1), which
matches Render and most single-CDN-hop platforms. If Claude's calls get
unexpectedly 403'd on a different platform, that hop count is the first
thing to check — adjust TRUST_PROXY_HOPS, or temporarily set
IP_ALLOWLIST_ENABLED=false to confirm that's the cause before tightening
it back up.
2. Collect tokens for the connectors you want. Each is independent — skip any you don't need, its tools just fail at call time instead of blocking the rest.
| Connector | Where to get it |
|---|---|
| GitHub | github.com/settings/tokens → fine-grained PAT, scoped to specific repos |
| Notion | notion.so/my-integrations → create an integration, then share the relevant pages/databases with it |
| Mem0 | app.mem0.ai → API keys |
| Cloudflare | dash.cloudflare.com → My Profile → API Tokens, plus your Account ID from the dashboard sidebar |
3. Set two security env vars — don't skip these.
MCP_SHARED_KEY— any long random string. Unset =/mcpis open to anyone who has your server's URL, tokens and all.IP_ALLOWLIST_ENABLED— on by default, pre-set to Claude's published connector IP range, so leave it alone if you're only ever connecting from Claude.ai. Set it tofalsetemporarily to test with curl/Postman from your own machine first.
4. Deploy, then verify. GET /health returns {"status":"ok"}, no auth
needed. GET / (needs your x-manufact-key header — this endpoint doesn't
support the path-key variant) reports which connectors are configured, so
you can confirm your tokens landed.
5. Add it to Claude. Settings → Connectors → Add custom connector, using:
https://<your-host>/mcp/<your MCP_SHARED_KEY>
(Path-based, since Claude.ai's connector UI doesn't currently support header-based auth for MCP servers.)
See Configuration below for the full variable reference.
File/repo ops: read_file, read_file_chunked, get_file_at_commit, list_directory,
get_file_tree, create_or_update_file, push_files, str_replace_file, rename_file,
delete_file, diff_files, download_repo
Branches & commits: list_branches, create_branch, list_commits, get_commit, list_contributors
Issues & PRs: list_issues, create_issue, update_issue, add_issue_comment,
get_pull_requests, create_pull_request, review_pull_request, merge_pull_request
Releases & tags: list_releases, create_release, list_tags
Repo management: list_repos, get_repo, create_repo, delete_repo, get_repo_topics
Actions & search: list_workflow_runs, get_workflow_run_logs, search_code
D1: cf_d1_databases_list, cf_d1_database_get, cf_d1_database_create, cf_d1_database_delete, cf_d1_database_query
KV: cf_kv_namespaces_list, cf_kv_namespace_get/create/update/delete
R2: cf_r2_buckets_list, cf_r2_bucket_get/create/delete
Hyperdrive: cf_hyperdrive_configs_list, cf_hyperdrive_config_get/edit/delete
Workers: cf_workers_list, cf_workers_get_worker, cf_workers_get_worker_code
Observability: cf_workers_observability_query/keys/values/compare
notion_search, notion_get_page, notion_create_page, notion_update_page
mem0_add, mem0_add_batch, mem0_get, mem0_get_history, mem0_list, mem0_search,
mem0_update, mem0_delete, mem0_delete_batch, mem0_delete_all
web_fetch — fetch a public URL and return text/JSON/stripped HTML
All tokens are optional independently — a connector's tools fail at call time (not startup) if its token is missing.
| Variable | Required for |
|---|---|
GITHUB_TOKEN |
GitHub tools |
NOTION_TOKEN |
Notion tools |
MEM0_API_KEY |
Mem0 tools (MEM0_USER_ID optional, defaults to default) |
CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID |
Cloudflare tools |
DEFAULT_OWNER |
Default GitHub owner when omitted from a call (defaults to allocsys) |
MCP_SHARED_KEY |
Shared-secret auth for /mcp. Unset = endpoint is open to anyone with the URL — set this in any real deployment. |
IP_ALLOWLIST_ENABLED |
Set false to disable the IP allowlist (default: enabled) |
ALLOWED_IP_RANGES |
Comma-separated CIDR ranges allowed to call /mcp (defaults to Anthropic's published connector range) |
TRUST_PROXY_HOPS |
Number of reverse-proxy hops to trust for client-IP detection (default 1, matches Render). Adjust if deploying behind a different proxy chain. |
- Requests to
/mcpare restricted by IP allowlist and rate-limited (30 requests/min). - Scope
GITHUB_TOKENas narrowly as possible (ideally fine-grained, limited to specific repos). This server can create/delete repos and files, merge PRs, and delete Cloudflare resources — treat every configured token as live write access. GET /reports which connectors are configured;GET /healthstays open and info-free for uptime checks.- Rotate any token if you ever suspect it's been exposed.
Licensed under AGPL-3.0 with the Commons Clause. In plain terms:
- You can use, run, modify, and self-host this server, including for internal business use — for free.
- If you modify it and let others interact with your version over a network (e.g. host it as a service), you must publish the source of your changes (AGPL-3.0's network-copyleft requirement).
- You may not sell it — the Commons Clause blocks offering a paid product or service whose value comes substantially from this software's functionality, including paid hosting of it, without a separate agreement with the licensor.
See LICENSE for the full, binding text. This summary is for
convenience only and isn't a substitute for reading it (and isn't legal
advice).
export GITHUB_TOKEN=ghp_yourtokenhere
npm install
npm startServer listens on PORT (default 8080). MCP endpoint: POST /mcp.
Health check: GET /health.