ClearComet Cloak for MCP
ClearComet Cloak for MCP

ClearComet Cloak for MCP

0/5 (0 ratings) 20 active installs Updated Nov 11, 2026
Home: one switch, on from the moment you activate. Hidden routes answer 404.

Home: one switch, on from the moment you activate. Hidden routes answer 404.

ClearComet Cloak for MCP is an on/off curtain in front of your site’s MCP and Abilities routes.

WordPress sites now have routes that AI assistants and bots use: the MCP Adapter’s mcp routes, the Abilities API, and MCP servers added by other plugins. Those routes are listed in the public /wp-json index unless something removes them.

A new install starts paused. Cloak saves that explicitly (on is false) and shows a notice, with Turn on and a link to the settings screen, until you turn it on. The switch on that screen shows Paused. Updating from an older version does not change your on/off choice. A site that was already protected stays protected, including one that never saved a settings row (on those versions, no row meant on).

Once Cloak is on, the default door mode is lights out. A stranger who requests a hidden route gets WordPress’s ordinary not-found answer (rest_no_route, 404), and those routes are left off the public /wp-json index. You do not have to create a key. Who gets in:

  • You, in the browser: a logged-in session that sends WordPress’s REST nonce (X-WP-Nonce or _wpnonce). The block editor does this. A cookie with no nonce does not count. An application password does not count unless you turn that rule on.
  • AI assistants and bots WordPress has already logged in: if another plugin has accepted the login (for example a checked OAuth token), the hidden route stays in place. Cloak does not read the Authorization header. A missing, wrong, or expired token is still a 404. Sites that want a Cloak key as well can turn this off with the cloak_allow_authenticated_users filter.
  • Your own scripts: send a secret key in the X-Cloak-Key header (optional, Advanced). The older X-BlindPig-Key header still works.
  • Guest addresses (optional, Advanced): an IP address or range you add. One preset is offered and stays off until you click it.
  • Unlisted mode (optional, per door): the route stays off the public index, and a request to the address itself is answered by the route. Use this when an assistant must see 401 and WWW-Authenticate on its first, still-anonymous request. Anyone who already knows the address can tell the route exists.

    .well-known OAuth files are not hidden. /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server, including path-scoped copies, can name your MCP address. Cloak leaves them up so other OAuth uses on the site keep working. The first anonymous request to the MCP address is still a 404 in the default mode. The follow-up request gets through only after WordPress has accepted the login, or you have allowed a key, an address, or Unlisted mode.

WordPress still checks its own login after Cloak lets a request through. Cloak does not replace application passwords, and an application password alone does not get past Cloak.

Why this matters

People are already scanning the internet for MCP servers:

  • A two-week log study of one small web host (one of its sites runs WordPress) saw MCP initialize handshakes POSTed to /mcp from 49 different IP addresses, on a server that runs no MCP at all. SANS Internet Storm Center, diary 33150
  • GreyNoise put MCP honeypots online, and every one was found within days. GreyNoise
  • Knostic found 1,862 MCP servers exposed to the internet. All 119 it checked by hand listed their tools without any authentication. Knostic
  • Bitsight found roughly 1,000 internet-reachable MCP servers with no authorization at all. Bitsight
  • On WordPress, CVE-2025-11749 (AI Engine 3.1.3 and earlier, with its “No-Auth URL” option on) leaked an MCP bearer token through the public /wp-json route list; it is fixed in 3.1.4. Wordfence
  • A public Metasploit module (also published on Packet Storm) automates that attack against /wp-json/mcp/v1/. Rapid7 Metasploit, Packet Storm via Vulners

To be honest about it: most of these knocks are reconnaissance, not attacks. GreyNoise saw no MCP-specific exploitation attempts in its honeypots. But being listed is how a site ends up on someone’s target list, and Cloak keeps your MCP doors off that list.

New installs start paused

Activate Cloak and it is not protecting yet. An admin notice stays up until you turn it on. It is not dismissible. It has Turn on and Open settings. After you turn it on, a separate notice explains how AI assistants and bots get in, and that one can be dismissed.

An update keeps the on/off state the site already had. Deactivating and activating again does not pause a site that was already set up. CLOAK_DISABLED in wp-config.php still forces Cloak off.

Everyday use

Settings > Cloak for MCP shows one door-slot switch and one line telling you whether you’re protected. Click the slot to pause or resume. Everything else is optional and lives on the Advanced pages: doors, the guest list, a secret key for your own apps, Cloudflare, access rules, an activity log and tools (export/import).

Secret key (optional)

You don’t need a key. It’s only for your own apps or scripts that connect from changing addresses. Generate a key, or paste your own (20+ characters: letters, digits, _ and -). Apps send it in the X-Cloak-Key header. Rotate keeps the old key working for 24 hours so you can update your apps; Turn off stops it. The key page has ready-made snippets for a desktop AI assistant, curl and n8n.

Cloak stores only a fingerprint of the key (a salted HMAC-SHA256), never the key itself, so a new key is shown once, right after it is made. Lost it? Make a new one. Keys are never exported and are compared in constant time.

Cloudflare

Cloak trusts the CF-Connecting-IP header only when the request really comes from one of Cloudflare’s published ranges. X-Forwarded-For is never used. The plugin ships with Cloudflare’s list (checked 2026-10-06); Refresh from Cloudflare on the Guest list page downloads the current official list from Cloudflare’s public API over a checked HTTPS connection, and keeps the old list if anything looks wrong.

Advanced: wp-config.php overrides

These optional constants pin a setting in code. The matching field shows as locked on the settings screen. They apply once protection is on, except CLOAK_DISABLED, which always switches protection off.

define( 'CLOAK_KEY', 'your-long-random-key' ); (20+ characters; works alongside a key made on the screen)
define( 'CLOAK_GUESTS', array( '203.0.113.7', '198.51.100.0/24' ) );
define( 'CLOAK_MODES', array( '/acme/v1' => 'lights_out' ) ); (modes: `open`, `unlisted`, `lights_out`)

lights_out (the default) answers 404 and hides the route from the index. `unlisted` hides the route from the index and lets the address itself answer, which is what an OAuth client needs in order to see 401. `open` leaves the route unchanged.
define( 'CLOAK_DISABLED', true ); (emergency off switch)

Advanced: filters for developers

  • cloak_presets: change or add guest presets. Each preset is id => array( 'label' => ..., 'cidrs' => array( ... ) ). A single cidr string is still accepted. Presets stay off until an administrator adds them. The older blindpig_presets filter still runs first.
  • cloak_cf_ranges: change the Cloudflare ranges used to trust CF-Connecting-IP.
  • cloak_client_ip: supply the visitor address yourself if your site sits behind another trusted proxy. It must return a valid IP.
  • cloak_allow_authenticated_users: default true. When true, a user WordPress has already logged in for this REST request may use a hidden route, unless that login is an application password or a cookie session (those keep their own rules). Return false to require a Cloak key, a guest address, or a browser nonce as well. Cloak never treats the Authorization header, by itself, as a login. The older blindpig_allow_authenticated_users filter still runs first.

Privacy

Cloak never phones home: no tracking, no analytics, no account, no ads. It makes no outside requests except two optional ones that only run when an administrator clicks a button: the quick check, which asks your own site for one hidden door, and Refresh from Cloudflare (see “External services” below). The activity log keeps the last 200 visits to hidden doors (time, IP address, door, result) on your site only and never records headers or keys. Deleting the plugin deletes all of its data.

Disclaimer

Cloak is one layer of protection, not a guarantee. Keep WordPress, your plugins and your passwords up to date. Cloak is provided as-is, without warranty of any kind, under the GPL (see license.txt).

External services

Cloak connects to one outside service, and only when an administrator asks it to.

Cloudflare IP list (optional, manual). When you click Refresh from Cloudflare on Settings > Cloak for MCP > Guest list, the plugin sends one HTTPS GET request to https://api.cloudflare.com/client/v4/ips to download Cloudflare’s public list of its own server address ranges. The list is used only to decide when the CF-Connecting-IP header can be trusted.

  • What is sent: a plain request with no data from your site, no API key and no account. Like any web request, it reveals your server’s IP address and WordPress’s standard user agent (which includes your site address) to Cloudflare.
  • When: only when an administrator clicks the button. Never automatically, on a schedule, or on visitor requests.
  • If you never click it, the plugin uses the list bundled with it and makes no request.
  • Service provider: Cloudflare, Inc. Terms of use and Privacy policy.

The optional quick check sends one request from your site to your own site’s address; nothing goes to a third party.