# Perfmatters “Disable REST API” Blocks Royal MCP

> Perfmatters' Disable REST API option, set to block everyone, rejects the Royal MCP endpoint so Claude cannot connect. Set it to 'Disable when logged out'.

- Canonical: <https://royalplugins.com/support/royal-mcp/perfmatters-disable-rest-api-blocks-mcp/>
- HTML version: <https://royalplugins.com/support/royal-mcp/perfmatters-disable-rest-api-blocks-mcp/>

---

Perfmatters ships a “Disable REST API” option that, when set to block everyone, rejects requests to the entire `/wp-json/*` path prefix with HTTP 401, including Royal MCP’s own `/wp-json/royal-mcp/v1/mcp` endpoint. External AI clients like Claude, ChatGPT, and Claude Code can’t connect. This page walks through the three configuration changes that fix it, and explains the safe middle-ground setting that keeps anonymous-scraper hardening in place without breaking MCP.

Before applying this fix

Royal MCP connection issues can look host-specific but usually resolve in our [**4-step basic checklist**](https://royalplugins.com/support/royal-mcp/troubleshooting-start-here/). If you haven’t worked through that yet, do it first. This article assumes the basics are already ruled out.

### On Royal MCP 1.5.1 or later? Read this first.

The warning on your Royal MCP settings page only fires when Perfmatters’ `Disable REST API` is set to a full-block value (blocks every visitor). If it’s set to `Disable when logged out`, MCP is not affected on 1.5.1+ and you don’t need to change anything. The plugin’s OAuth Bearer authentication resolves to a real user before Perfmatters’ logged-out gate fires.

## Symptoms

You’re hitting this specific issue if all of the following are true:

#### The Telltale Signs

- Claude, ChatGPT, or Claude Code fails to connect to your Royal MCP endpoint with a generic “couldn’t connect” error
- Perfmatters is installed and active on the site (WP Admin → Plugins shows it enabled)
- Perfmatters’ `Assets → Disable REST API` option is set to a full-block value (typically labeled “Everywhere” or the equivalent full-disable toggle)
- A `curl` against your Royal MCP endpoint from outside the site returns HTTP 401 with WordPress’ standard REST authentication error body, not a plain 404 or a security-plugin denial message
- Royal MCP’s Activity Log (WP Admin → Royal MCP → Activity Log) may stay empty because Perfmatters short-circuits the request before Royal MCP’s handler runs

Why the failure mode looks generic

Perfmatters’ block runs during `rest_authentication_errors`, which is a WordPress core filter, so the 401 comes back in the standard REST envelope. There’s no branded “blocked by Perfmatters” message in the response body, unlike host-side WAF blocks (Imunify360, BitNinja, Sucuri) which fingerprint themselves. That makes this failure harder to diagnose from the client side alone.

## How to Confirm It’s Perfmatters

A quick 60-second check will confirm whether Perfmatters is the block. Run these two steps in order:

#### Check the Perfmatters setting

In WP Admin, go to `Perfmatters → Assets`. Scroll to the `Disable REST API` option.

- If it’s **off** or **empty**, Perfmatters is not the cause. Investigate elsewhere.
- If it’s set to **“Disable when logged out”** on Royal MCP 1.5.1 or later, this is safe and you can ignore the warning. On earlier versions, upgrade to 1.5.1 to resolve.
- If it’s set to **“Everywhere”** or a full-block equivalent, that’s the block. Continue to the fix section below.

#### Confirm via curl from outside the site

Replace `example.com` with your actual domain. This should return WordPress’ standard REST 401 response, not a WAF-branded denial:

```
curl -i https://example.com/wp-json/royal-mcp/v1/mcp \
  -X POST \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize"}'
```

If the response is HTTP 401 with a body containing `"code":"rest_forbidden"` or similar core-REST error language, that’s Perfmatters’ block coming through WordPress’ standard authentication filter. A WAF block would instead return a branded HTML page or a JSON body naming the security vendor.

## Three Ways to Fix It

Pick the option that matches how you want Perfmatters to protect the rest of your REST API. All three take under a minute to apply.

### Option A — Switch to “Disable when logged out” (recommended)

This is the safest configuration for most sites. Perfmatters still blocks anonymous REST scrapers and user-enumeration attacks, but external MCP clients pass through because their OAuth Bearer authentication resolves to a real user before Perfmatters’ logged-out check runs.

#### Change the setting

In WP Admin, go to `Perfmatters → Assets → Disable REST API`. Change the value from “Everywhere” to “Disable when logged out.” Save.

#### Confirm MCP is reachable

Re-run the curl command from the “How to Confirm” section. You should now get a proper Royal MCP JSON-RPC response, not a 401. Then reconnect from Claude, ChatGPT, or Claude Code.

Why this works on Royal MCP 1.5.1 and later

Royal MCP’s OAuth Bearer authentication sets the current WordPress user during `rest_authentication_errors`. By the time Perfmatters’ logged-out gate fires, `is_user_logged_in()` returns true and the request passes through. Anonymous scrapers (the ones you actually want to block) still get the 401.

### Option B — Turn off “Disable REST API” entirely

If you don’t need Perfmatters’ REST protection at all (perhaps because you already have a firewall plugin or WAF handling anonymous requests), you can just toggle the setting off.

#### Turn it off

In WP Admin, go to `Perfmatters → Assets → Disable REST API`. Switch it to off or empty. Save.

Trade-off

Turning this off removes Perfmatters’ anonymous-REST protection. If nothing else on your site is blocking anonymous `/wp-json/*` access, user-enumeration attacks (`/wp-json/wp/v2/users`) become possible again. Option A is safer for most sites.

### Option C — Whitelist `royal-mcp` via the Perfmatters filter

If you want to keep Perfmatters’ full-disable behavior for everything else but explicitly allow the Royal MCP endpoint through, add a small filter to your site. This preserves the strictest REST-hardening posture while giving Royal MCP a targeted exception.

Add this to your theme’s `functions.php` or a site-specific plugin:

```
add_filter( 'perfmatters_rest_api_exceptions', function ( $exceptions ) {
    $exceptions[] = 'royal-mcp';
    return $exceptions;
} );
```

Perfmatters exposes `perfmatters_rest_api_exceptions` as a documented filter for exactly this scenario. Any REST route whose namespace matches an entry in the exceptions array bypasses the block.

## What Royal MCP Does for You

Royal MCP 1.5.1 detects when Perfmatters’ `Disable REST API` is set to a full-block value and surfaces a dismissible admin notice on the Royal MCP settings page linking back to this doc. The notice fires only when the setting is a genuine block for MCP. The safe `Disable when logged out` value does not trigger it.

If you see the warning, the fix is one of the three options above. Once Perfmatters is reconfigured, dismiss the notice and reconnect your MCP client.

If you’re on an earlier Royal MCP version

On Royal MCP 1.5.0 or earlier, the warning also fires when Perfmatters is set to `Disable when logged out`, which is a false positive on 1.5.0+ where OAuth Bearer authentication already handles the logged-out gate. Update to Royal MCP 1.5.1 or later to remove that false positive.

## Related Issues You Might Also Be Hitting

Other REST-API-blocking scenarios that produce a similar “client can’t connect” symptom:

#### Plain permalinks blocking OAuth discovery

Your WordPress permalink structure is set to “Plain” in Settings → Permalinks. This alone breaks OAuth discovery because the root-level rewrite rules don’t fire.

[**See: Plain Permalinks Break OAuth Discovery →**](https://royalplugins.com/support/royal-mcp/plain-permalinks-blocks-discovery/)

#### Imunify360 blocking Royal MCP

Host-layer bot-protection (CloudLinux Imunify360, common on shared cPanel hosts) intercepts `/wp-json/*` and `/.well-known/*` before WordPress sees the request.

[**See: Imunify360 Blocks Royal MCP →**](https://royalplugins.com/support/royal-mcp/imunify360-blocks-mcp/)

#### ModSecurity 406 bot-fingerprint

cPanel ModSecurity returns HTTP 406 for the User-Agent Anthropic’s OAuth backend uses, with “Mod Security” visible in the response body.

[**See: ModSecurity 406 fix →**](https://royalplugins.com/support/royal-mcp/modsecurity-406-bot-fingerprint/)

## Still Stuck? Two Support Paths

If you’ve applied one of the three options above and Royal MCP still can’t reach your endpoint:

### Community Support (free) — wp.org Plugin Forum

Post a new thread at [wordpress.org/support/plugin/royal-mcp/](https://wordpress.org/support/plugin/royal-mcp/). Include the diagnostic info listed below in your post.

### Premium Support (paid) — direct one-on-one help

For priority response (24-hour SLA) and hands-on diagnostic help, our [Premium Support tier](https://royalplugins.com/premium-support/) is $149/year.

#### Information to include in your post or ticket

- **Full curl output** from the “How to Confirm” section (use `-i`, not just `-I`, so we see the body)
- **Your Perfmatters version** from WP Admin → Plugins
- **The exact value** of `Perfmatters → Assets → Disable REST API` before and after your fix
- **Which of the three options** you applied (A, B, or C)
- **Whether the Activity Log** now shows entries during a failed attempt (any entry means the request reached WordPress, which is a different diagnosis)
- **Royal MCP version** from WP Admin → Plugins

[Back to Troubleshooting Start Here](https://royalplugins.com/support/royal-mcp/troubleshooting-start-here/)
[Back to Royal MCP Support](https://royalplugins.com/support/royal-mcp/)
