WordPress Plugins
Free Tools
Pricing Blog Case Studies Switch to Royal Plugin Graveyard Support My Account Cart
Support / Royal MCP / Direct-Connect Threat Model

Royal MCP Direct-Connect Threat Model

Royal MCP is a direct-connect MCP server: AI clients authenticate against your WordPress install, not a third-party relay. This document explains the authentication boundary on each of Royal MCP’s three transports (MCP OAuth 2.1, WordPress Abilities API adapter, WP REST API), lists the threat scenarios covered and the mitigations in place, and gives your security or agency team a production-readiness checklist to run before enabling AI access on a customer-facing site.

TL;DR — the 60-second version

Royal MCP authenticates AI clients on your WordPress install — no third party sits between the client and your site. The MCP transport uses OAuth 2.1 with Dynamic Client Registration and PKCE-S256; access tokens live 1 hour, refresh tokens rotate on use and live 30 days, and every authorized client is bounded by the WordPress capabilities of the user who authorized it. As of 1.4.38 the same tools are also exposed via the WordPress REST API using WP-native authentication (Application Passwords or cookie+nonce); every REST call still passes through the same per-tool capability check that gates the MCP transport. Before enabling AI access on a production site: enforce HTTPS, decide which WordPress users you allow to authorize AI clients, decide your Application Password policy, put a backup and error-log monitoring plan in place, and call the royal_mcp_connection_health tool from your AI client to confirm live configuration. The detailed threat scenarios and mitigations follow below.

What “direct-connect” means for your site

An MCP server can be reached in one of two shapes. Some products run a relay-based architecture: the AI client talks to the vendor’s relay service, and the relay talks to your WordPress site on your behalf. Auth happens on the relay, not on your site. Convenient to set up, but every call in and out passes through a third-party trust boundary you don’t operate. Others — Royal MCP included — run direct-connect: the AI client authenticates against your WordPress install itself, and every subsequent call reaches WordPress with no intermediary.

The direct-connect trade-off is straightforward. You keep every request inside a trust boundary you already own. Your capability model, your audit trail, your rate limits, your incident response. Nothing is metered by anyone else. In exchange, you accept full responsibility for the auth surface on your own site — the same responsibility you already carry for the WordPress admin panel and the WP REST API. This document describes what that surface looks like on Royal MCP so your team can evaluate it against your existing security posture.

The three transports Royal MCP exposes

Post-1.4.38 there are three distinct paths a caller can use to reach a Royal MCP tool. All three routes converge on the same set of tool handlers and the same per-tool capability checks. Only the transport-level authentication differs.

TransportAuth mechanismTypical caller
MCP server
/wp-json/royal-mcp/v1/mcp
OAuth 2.1 with Dynamic Client Registration + PKCE-S256, or long-lived API key Claude Desktop, Claude Code, Claude.ai web, ChatGPT MCP connector, any MCP-compatible client
WordPress Abilities API
(via WP MCP Adapter)
Delegated to the adapter’s auth (typically the adapter’s own OAuth flow) Sites running the WP MCP Adapter plugin alongside Royal MCP; ecosystem clients that speak to the adapter
WordPress REST API
/wp-json/wp-abilities/v1/abilities/royal-mcp/{name}/run
WP-native: Application Passwords, cookie + nonce for logged-in browsers Custom scripts, WP-CLI, automation platforms, existing REST clients

The same tool (say, wp_get_posts) is reachable via all three transports as of 1.4.38. What changes between them is who authenticates and how — not what the tool does or which WordPress capabilities are required to run it. A caller who reaches wp_create_post via the REST endpoint still needs the edit_posts capability on the WordPress user attached to their Application Password, exactly as an MCP-transport caller would.

Why we expose all three

The MCP transport is the primary path for AI clients. The Abilities API path lets Royal MCP co-exist with the emerging WordPress MCP Adapter ecosystem so buyers who standardize on the adapter can use our tools without changing tooling. The REST path lets existing automation (WP-CLI, custom scripts, third-party workflow tools) call the same tools without needing to speak MCP. Same authorization gate on all three — three transports, one capability model.

The OAuth 2.1 model on the MCP transport

Royal MCP implements the OAuth 2.1 draft profile (draft-ietf-oauth-v2-1) with the extensions the MCP specification requires. The relevant properties for a security review:

A separate long-lived API key path is available for callers that can’t complete an interactive OAuth flow (headless CI, scheduled scripts). API keys are generated in Royal MCP → Settings, tied to a WordPress user, and can be revoked from the same screen. They carry the same capability boundary as OAuth-issued tokens — they don’t bypass any check.

The REST-transport authentication model

The REST endpoints Royal MCP registers as of 1.4.38 use the WordPress-native REST authentication stack. This is deliberate: WordPress’ REST auth is well-understood by the WordPress security ecosystem, has been reviewed for over a decade, and any Application Password or cookie-auth issue is already handled by every WordPress security plugin your customers may already run.

The OAuth 2.1 flow stays MCP-scoped

Royal MCP’s OAuth 2.1 layer authenticates MCP-transport callers only. It does not participate in REST-transport auth. This is by design — keeping the two auth stacks separate means each transport uses the mechanism the WordPress ecosystem already expects, and neither becomes a bypass path around the other. If your organization’s policy prohibits Application Passwords, disable them site-wide via the wp_is_application_passwords_available filter; Royal MCP’s MCP transport will continue to work unaffected.

Threat scenarios and mitigations

The scenarios below cover the classes of attack a security team commonly asks about when evaluating a direct-connect MCP server. For each scenario we describe the attack shape, the mitigation Royal MCP already applies, and the residual risk you should be aware of.

1. AI client compromised, live tokens stolen

An attacker gains access to the AI client (compromised laptop, malware, insider) and extracts live access + refresh tokens from the client’s storage.

Mitigation

Access tokens are 1-hour TTL, so a stolen access token expires within the hour. Refresh tokens rotate on every use — if the attacker uses the refresh token, the legitimate client’s next refresh fails, alerting the user. Every tool call still runs the WordPress capability check on the owning user, so the blast radius is bounded by that user’s capabilities. A stolen editor-scoped token cannot escalate to admin actions.

Residual risk

Within the 1-hour window before the access token expires, the attacker can invoke any tool the token’s user is authorized to invoke. Standard WordPress incident response applies: revoke the OAuth client from Royal MCP → Settings → Connected Clients, rotate the user’s password if the compromise was broader, review the WordPress audit log.

2. Token leaked via debug log, bug report, or screenshot

A token ends up in a text log, a support conversation, a screenshot posted publicly, or a copy-pasted terminal transcript. An attacker discovers it before the user does.

Mitigation

Same short-TTL and rotating-refresh properties as scenario 1. Additionally: Royal MCP does not log tokens or authorization codes to the WordPress error log or Activity Log — token values are redacted before any log write. If a token leaks it’s from the client side or an operator’s environment, not from Royal MCP’s own outputs.

Residual risk

Same 1-hour window. Recommend the operator revoke the affected OAuth client immediately upon discovery rather than waiting for TTL expiry.

3. Token replayed from a different origin

An attacker captures a token and attempts to use it from a different network / device / geographic location than the legitimate client.

Mitigation

Tokens are bearer tokens by design in the OAuth 2.1 profile — they don’t carry origin binding today. Every call still runs the capability check. If your site is behind Cloudflare or a WAF, IP-based or geo-based rules on /wp-json/royal-mcp/v1/* add a layer here at the operator’s discretion.

Residual risk

A leaked token can be used from any origin. Origin-binding is an area of active OAuth extension work (DPoP, mTLS) that Royal MCP will evaluate for future releases; not shipped today.

4. Man-in-the-middle on the token exchange

An attacker positioned on the network path between the AI client and your WordPress site intercepts the OAuth authorization code or the token exchange request.

Mitigation

Every OAuth endpoint requires HTTPS. Royal MCP refuses to complete an OAuth flow over plain HTTP. PKCE-S256 mitigates the code-interception class specifically — an attacker who captures the authorization code cannot exchange it for a token without also having captured the client’s PKCE code-verifier, which never traverses the network in cleartext.

Residual risk

A TLS-terminating MITM (compromised CA, corporate SSL-inspection proxy) can still see the exchange. This is a network-layer concern outside Royal MCP’s trust boundary; addressed by your certificate management practices.

5. Encrypted-traffic sniff / passive network capture

An attacker records encrypted traffic between AI client and site with the intent of decrypting it later.

Mitigation

HTTPS-only enforcement means everything is TLS-encrypted in transit. Royal MCP does not require or accept any downgrade to plain HTTP. Ensure your site’s TLS configuration is 1.2+ with modern cipher suites — use the SSL Checker linked at the bottom of this page to verify.

Residual risk

Standard TLS-lifecycle concerns (private key compromise, retroactive decryption if a weak cipher was in use). Not Royal MCP-specific.

6. Application Password stolen or leaked

A WordPress Application Password (used for REST-transport calls) is disclosed to an attacker.

Mitigation

Application Passwords are per-user and per-name — the compromised password can be revoked in Users → Profile → Application Passwords without disturbing other passwords the same user has issued. The password’s reach is bounded by the owning user’s WordPress capabilities. All standard WordPress security-plugin monitoring (failed-login alerts, geographic anomalies) applies to Application Password auth.

Residual risk

Application Passwords transmit on every request as a bearer credential. Sites that consider this shape unacceptable can disable the feature site-wide via the wp_is_application_passwords_available filter and rely exclusively on the MCP OAuth 2.1 path.

7. Malicious plugin attempts to register a colliding ability namespace

Another plugin on the site registers an ability with a name in the royal-mcp/ namespace, attempting to intercept calls meant for a Royal MCP tool.

Mitigation

WordPress core’s wp_register_ability() refuses to register duplicates — the first registration wins. Royal MCP registers its abilities on wp_abilities_api_init priority 10, and pre-registers its 10 categories on priority 5. A later plugin cannot displace an already-registered ability. Namespace collision as an attack shape is closed by WP core’s registration model, not by anything Royal MCP does specially.

Residual risk

None on this shape. A malicious plugin can still register abilities in its own namespace and register handlers there — the same trust-your-installed-plugins concern that already applies to WordPress generally.

8. Bulk-scan for open MCP endpoints on the public internet

An attacker sweeps IP ranges or WordPress sites looking for exposed /wp-json/royal-mcp/v1/* endpoints they can call without authentication.

Mitigation

Every MCP endpoint requires an authenticated session from the first call. There is no anonymous read path, no unauthenticated tool listing that leaks tool names, and no default-open configuration. A scanner sees the OAuth discovery document (which is intentionally public per RFC 8414) but cannot invoke any tool without completing DCR + admin authorization + PKCE flow.

Residual risk

The public discovery document reveals that Royal MCP is installed. This is a fingerprinting concern, not an authorization bypass. Sites that want to hide the plugin’s presence can add path-blocking rules at their edge (Cloudflare WAF, nginx rewrite) to require an additional header on /.well-known/oauth-authorization-server.

9. Insider abuse: legitimate admin uses AI to exfiltrate data

A user who is legitimately authorized to use Royal MCP uses their access to exfiltrate content the site owner didn’t intend to share (bulk-download all draft posts, export all user emails, etc.).

Mitigation

This is outside the authentication model — the user is who they say they are, and they hold the capabilities the exfiltration requires. The mitigation is monitoring, not prevention. Royal MCP writes every tool invocation to the plugin’s Activity Log with the invoking user, tool name, and timestamp. A future Pro-tier release will add a universal cross-tool audit log with export and 90-day retention; see the Royal MCP Pro pages for the current status of that feature.

Residual risk

Real. Insider abuse is a monitoring and human-controls problem, not an authentication one. Standard mitigations: least-privilege WordPress roles for AI-connected users, review of the Activity Log on a routine cadence, alerting on unusual bulk-read patterns via a security plugin.

Direct-connect vs relay-based architectures

Direct-connect and relay-based MCP servers make different trade-offs. Neither shape is universally better — each fits different customer profiles. The comparison below is architectural, not product-vs-product.

PropertyDirect-connect (Royal MCP)Relay-based
Auth boundaryYour WordPress installVendor’s relay service
Third-party trust boundary in the call pathNone — client talks straight to your siteVendor’s relay sees every request and response
Rate-limit ownershipYour site’s server + WAF settingsVendor’s tier limits (typically per-day action caps)
Incident responseYou + your hosting providerYou + vendor + your hosting provider
LatencyOne network hop: client → siteTwo hops: client → relay → site
Setup frictionOAuth flow with DCR, admin approval per clientTypically vendor account + connector configuration
Auth surface exposed to public internetYes — your WordPress install is the OAuth serverNo — relay handles the public-facing auth
Data residencyEverything stays within your site + client boundaryData traverses the relay, subject to their region + retention policies

Direct-connect fits organizations that already own their WordPress security posture and prefer to keep the AI-agent trust boundary on infrastructure they operate. Relay-based fits organizations that want to offload the auth surface to a vendor and accept the third-party trust and rate-limit trade-offs that come with it. If your compliance framework mandates that authentication for a specific data class must terminate on your infrastructure, direct-connect is likely the required shape.

Before enabling Royal MCP on a production site

Run through this checklist before authorizing an AI client against a customer-facing site for the first time. Everything here is achievable in about 30 minutes on a site that already follows standard WordPress security practice.

Enforce HTTPS site-wide, TLS 1.2+

Every Royal MCP transport (MCP OAuth, Abilities API, REST) requires HTTPS. Use the SSL Checker to confirm your site accepts TLS 1.2 or 1.3 and rejects lower versions. If your host still permits TLS 1.0 or 1.1, upgrade before enabling MCP.

Verify the authorizing-user capability boundary

Any logged-in WordPress user can complete an OAuth consent for a new MCP client — the resulting client inherits the capabilities of the user who authorized it. Verify this bound holds: authorize a client while logged in as a low-privilege user (Subscriber or Contributor), then try to invoke an Administrator-scoped tool (royal_mcp_connection_health, a settings-write tool) from that client — the call should return a rest_forbidden / capability-denied error. If your policy is that only Administrators may authorize AI clients, restrict which users can log into your site or use a role-management plugin to constrain non-admin roles before enabling MCP.

Decide your Application Password policy

WordPress ships Application Passwords enabled by default. If your organization’s policy is to disable them, apply the wp_is_application_passwords_available filter in a must-use plugin. Royal MCP’s MCP transport works with or without Application Passwords — the choice is about which REST-transport callers you want to permit.

Put a backup + restore plan in place

MCP-connected AI can create, update, or delete content within the connected user’s capabilities. Ensure you have a recent backup and a tested restore procedure before enabling write-capable tools on a production site. SiteVault or any WordPress backup plugin your team already uses works.

Enable WordPress error-log monitoring

Set WP_DEBUG_LOG or an equivalent logging plugin so that authorization failures, capability errors, and unexpected tool errors are recorded and reviewable. Royal MCP’s built-in Activity Log covers plugin-side events; site-wide logging catches everything else.

Consider WAF rules on the MCP paths

If you run Cloudflare or a WordPress WAF plugin, decide whether you want rate-limit or geo-fencing rules on /wp-json/royal-mcp/v1/* and /wp-json/wp-abilities/v1/abilities/royal-mcp/*. This is optional but useful for sites that expect connections from a known set of geographies or IP ranges.

Call royal_mcp_connection_health from your AI client

Once your first AI client is connected, invoke the royal_mcp_connection_health tool. It returns your site’s current auth model, active OAuth session TTLs, negotiated MCP capabilities, and Royal MCP + WordPress version strings. Screenshot the response for your security review file — it’s the plugin’s own confirmation of what’s live.

Independent security review invitation

If your team runs an internal security review, penetration test, or vendor risk assessment on WordPress plugins, we welcome the report. Reach out via the support form and note that you’re requesting a security-review contact. We’ll route the conversation to someone who can answer follow-up questions on specifics that aren’t covered in this document.

Responsible-disclosure reports are appreciated. Royal Plugins does not currently operate a paid bug-bounty program, but we credit contributors publicly (with your permission) and prioritize confirmed vulnerabilities on the fastest-possible release cadence.

What this document does not cover

The scope of this threat model is the authentication and authorization boundary between an AI client and your WordPress site. Related concerns that sit outside that boundary are called out here so your team knows where to look for them.

See also