Most guides for connecting AI assistants to a self-hosted WordPress site via MCP suggest using Cloudflare Tunnel or ngrok to expose the site publicly. This works, but it also reintroduces infrastructure layers that can interfere with MCP: WAFs, bot-fight rules, page caches, and host-level rewrites that intercept REST API requests before WordPress ever handles them.
A cleaner alternative, if your machines are already on Tailscale: skip the public internet entirely.
The Problem with Cloudflare and MCP
The @automattic/mcp-wordpress-remote package connects to WordPress via the REST API using HTTP Basic Auth (Application Passwords). Any edge layer that interferes with those REST API calls can silently break the connection. Common culprits when routing through Cloudflare:
- Bot Fight Mode blocking REST API POSTs
- Page caches returning stale or HTML responses on JSON endpoints
- Host WAFs blocking requests based on User-Agent strings
- Security plugins blocking access to the MCP endpoint
The Tailscale Approach
Since Claude Code runs the MCP client locally, it only needs the WordPress server to be reachable from the local machine — not from Anthropic’s servers. If both machines are on the same Tailscale network, you can route traffic directly over Tailscale by pinning the domain in /etc/hosts:
100.x.x.x yourdomain.com
fd7a:xxxx::xxxx yourdomain.com
Both IPv4 and IPv6 entries are needed. Without the IPv6 entry, DNS can still return Cloudflare’s AAAA records and route around the pin.
With this in place, yourdomain.com resolves to the Tailscale IP, traffic goes peer-to-peer, and none of the Cloudflare/WAF/cache layers are involved. The SSL certificate remains valid because the hostname matches.
The Plugin
The active WordPress MCP plugin is WordPress/mcp-adapter (not the older wordpress-mcp repo, which is deprecated). The endpoint lives at:
https://yourdomain.com/wp-json/mcp/mcp-adapter-default-server
Authentication is WordPress Application Passwords (Users → Profile → Application Passwords) via HTTP Basic Auth. XML-RPC is not involved.
MCP Client Configuration
In your Claude Code MCP config (~/.claude.json):
{
"mcpServers": {
"wordpress": {
"command": "npx",
"args": ["@automattic/mcp-wordpress-remote"],
"env": {
"WP_API_URL": "https://yourdomain.com/wp-json/mcp/mcp-adapter-default-server",
"WP_API_USERNAME": "your-wp-username",
"WP_API_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx",
"PATH": "/home/user/.nvm/versions/node/v24.x.x/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
}
}
}
}
Two critical details:
WP_API_URLmust be the full endpoint path, not just the domain. Passing a bare domain puts the package into legacy mode, where it targets/wp-json/wp/v2/wpmcp— the old deprecated plugin’s endpoint — returning a 404.PATHmust be set explicitly if Node is installed via NVM. Claude Code’s environment doesn’t inherit your shell’s NVM paths, so without this thenpxcall fails to find Node.
Result
A successful MCP handshake returns a session ID and server info:
{"protocolVersion":"2024-11-05","serverInfo":{"name":"MCP Adapter Default Server","version":"v1.0.0"}}
No tunnels, no WAF exceptions, no cache exclusion rules — just a direct Tailscale connection to your own server.