wp-mcp-gateway
wp-mcp-gateway (Cloudflare Workers version)
Same idea as the Node version: one MCP endpoint, every tool call takes a
site_id, so one Claude connector covers your whole WordPress fleet. This
version runs on Cloudflare Workers instead of a VPS — no server to patch,
free tier covers this comfortably, and it's live at a workers.dev URL
within a couple minutes of running wrangler deploy.
It's built on Cloudflare's current recommended approach: a stateless
createMcpHandler from the agents SDK (the older stateful McpAgent /
Durable Objects approach is deprecated for new servers — this gateway
doesn't need session state anyway, since every tool call is independent).
Verified locally end-to-end before hand-off: Worker boots, /health
responds, the MCP initialize handshake works, bearer-token auth correctly
rejects missing/wrong tokens and allows the right one, and list_sites
returns real data from a test SITES_JSON.
1. Prerequisites
npm install -g wrangler # or just use npx wrangler as shown below
wrangler login # opens a browser to authenticate with your Cloudflare accountIf you don't have a Cloudflare account yet, sign up free at https://dash.cloudflare.com/sign-up — the free tier (100,000 requests/day) is more than enough for this.
2. Install dependencies
cd wp-mcp-gateway-cf
npm install3. Configure your sites
Unlike the Node version, Workers have no filesystem, so the site registry
lives in a secret (SITES_JSON) instead of a file. Same shape as before
— one entry per site:
{
"town-green": {
"label": "Town Green",
"baseUrl": "https://town-green.org",
"username": "mcp-agent",
"appPassword": "xxxx xxxx xxxx xxxx xxxx xxxx",
"host": "wpengine"
},
"cra": {
"label": "CRA",
"baseUrl": "https://cra.com",
"username": "mcp-agent",
"appPassword": "xxxx xxxx xxxx xxxx xxxx xxxx",
"host": "gridpane"
}
}Build that JSON for all your sites (a spreadsheet-to-JSON script is easy to throw together once you've generated Application Passwords for each site — ask if you want one), then set it as a secret:
npx wrangler secret put SITES_JSON
# paste the whole JSON blob when prompted, then press Ctrl+DApplication Passwords: in wp-admin, Users → your user → Application Passwords. Same recommendation as before — use a dedicated
low-privilege WP user per site rather than your personal admin account, so a
leaked token can't do more than that role allows.
4. Set your gateway auth token
npx wrangler secret put GATEWAY_TOKEN
# paste a long random value, e.g. output of: openssl rand -hex 32Without this set, the endpoint runs with no auth — fine for a first local test, never for the deployed version.
5. Test locally
npx wrangler devThis starts a local dev server (default http://localhost:8787). For local
testing, put your secrets in a .dev.vars file instead (never commit it):
GATEWAY_TOKEN=some-local-test-token
SITES_JSON={"town-green":{"label":"Town Green","baseUrl":"https://town-green.org","username":"mcp-agent","appPassword":"xxxx"}}Check it's alive:
curl http://localhost:8787/health6. Deploy
npx wrangler deployWrangler prints your live URL, something like:
https://wp-mcp-gateway.<your-subdomain>.workers.devYour MCP endpoint is https://wp-mcp-gateway.<your-subdomain>.workers.dev/mcp.
7. Add it as a connector in Claude
Add a custom connector pointing at that /mcp URL, with header
Authorization: Bearer <GATEWAY_TOKEN> (the same value you set in step 4).
From then on, "list draft posts on cra.com" only needs Claude to call
list_sites (or already know the id) and then list_posts with
site_id: "cra" — same behavior as the Node version, just edge-hosted.
Updating sites later
Add a new site, or change credentials, by re-running:
npx wrangler secret put SITES_JSONNo redeploy needed — secrets update independently of the Worker code.
Notes specific to this deployment
No filesystem, no long-running process — the whole registry lives in the
SITES_JSONsecret, parsed fresh on each request. Trivial cost even at ~80 sites.Stateless by design — each MCP request creates a fresh server instance (per Cloudflare's current guidance); there's no cross-request session to worry about losing.
WAF flags on managed hosts — same caveat as the Node version: WP Engine in particular may flag traffic from an unfamiliar IP range calling the REST API. If a site 403s only when hit via this gateway, that's the first thing to check with WP Engine support — worth allowlisting Cloudflare's egress ranges if needed.
Scope of tools — this only talks to the core WP REST API (
/wp/v2/...). No WP-CLI, SSH, or database-level operations — Workers can't SSH out anyway, so that would need a different piece entirely if you need it later.
Security checklist before connecting Claude to the deployed URL
GATEWAY_TOKENset viawrangler secret put, long and randomSITES_JSONuses a dedicated low-privilege WP user per site.dev.vars(if you used one locally) is in.gitignoreand never committedYou've tested against 2–3 sites before scaling the secret up to all ~80