Web Server 301-Redirects /register to /register/
Royal MCP’s admin self-check flagged that your web server is responding to POST /register with a 301 redirect to /register/ (with a trailing slash). OAuth clients don’t follow 301 on POST, so claude.ai’s registration request dies before it reaches WordPress — the connector silently fails with a generic “couldn’t reach the MCP server” error. This is a web-server canonicalization rule (Nginx, Apache, or .htaccess), not a Royal MCP setting. Here are the fixes for each common server.
Confirm What’s Happening
From any terminal:
curl -i -X POST -H "Content-Type: application/json" -d '{}' https://YOUR-DOMAIN.com/registerYou’re hitting this issue if you see:
The Telltale Signature
- Status:
HTTP/2 301(sometimes301 Moved Permanently) - Header:
Location: https://YOUR-DOMAIN.com/register/(trailing slash added) - If you re-run with
-L(follow redirects), curl will follow the 301 as a GET (per RFC 7231 it would, but real OAuth clients don’t) — this confirms the redirect target works fine and the issue is just that OAuth POSTs don’t follow 301
If the response is a 4xx, 5xx, or 200, you’re looking at a different issue and this guide doesn’t apply.
Why This Happens
Nginx, Apache, and many .htaccess-based hosts emit a 301 redirect on any non-file URL path that lacks a trailing slash. The behavior is built into:
- Nginx: when a request path matches a directory location (or could match one), Nginx adds the slash via an internal redirect
- Apache
mod_dir: theDirectorySlashdirective (defaultOn) does the same thing - Apache
mod_rewrite/.htaccess: many cPanel and shared-host default configs include a canonicalization rule that forces trailing slashes
For browser-facing pages this is fine — browsers follow 301 on GET. For OAuth, RFC 7231 specifically says clients SHOULD NOT auto-follow 301 redirects on POST (the response method-change behavior is undefined and unsafe). Real-world OAuth clients including claude.ai, mcp-remote, and Anthropic’s backend treat a 301 on a POST as a failure.
Royal MCP’s rewrite rules in 1.4.22+ match both bare and trailing-slash variants of /register, /authorize, and /token — so when WordPress handles the request internally, both forms work. But this web-server 301 happens before WordPress even sees the request, so the plugin can’t fix it from PHP. It has to be fixed in your web-server config.
Fix: Nginx
Add a location block above your main location / block in your server config (usually /etc/nginx/sites-available/your-site.conf on Debian/Ubuntu, or /etc/nginx/conf.d/your-site.conf):
location = /register {
try_files $uri $uri/ /index.php?$args;
}
location = /authorize {
try_files $uri $uri/ /index.php?$args;
}
location = /token {
try_files $uri $uri/ /index.php?$args;
}The = prefix means “exact match” — Nginx evaluates these before any prefix or regex location, so the request goes straight to PHP without canonicalization. After saving, reload Nginx:
sudo nginx -t && sudo systemctl reload nginx
Re-run the curl test from the top — you should now see HTTP/2 200 or a JSON error response instead of HTTP/2 301.
Cloudflare can also produce a 301 trailing-slash redirect via the “Always Use HTTPS” or a Page Rule with the “Forwarding URL” action. Check Cloudflare Dashboard → Rules → Page Rules and Bulk Redirects for any pattern matching /register, /authorize, or /token. Disable or refine the rule to exclude these paths.
Fix: Apache (with mod_dir)
In your virtual host config or in your site’s root .htaccess, add before the WordPress block:
<IfModule mod_dir.c>
<LocationMatch "^/(register|authorize|token)$">
DirectorySlash Off
</LocationMatch>
</IfModule>If you don’t have <LocationMatch> available (it requires server-config or virtual-host-level access), use the .htaccess-only version instead:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(register|authorize|token)$ index.php?$0 [L]
</IfModule>Add this above the existing WordPress # BEGIN WordPress block in .htaccess. Reload Apache (sudo systemctl reload apache2) or just save the .htaccess file (Apache re-reads it per-request).
Re-run the curl test — you should no longer see a 301.
Fix: LiteSpeed
LiteSpeed reads .htaccess files like Apache does, so the mod_rewrite snippet from the Apache section above works identically. After saving, you may need to clear the LiteSpeed cache:
WP Admin → LiteSpeed Cache → Toolbox → Purge All
Re-run the curl test to confirm.
Verify the Fix Worked
- Run the
curlPOST command from the top of this page again — you should now see a JSON response or a 4xx/5xx (Royal MCP responding), not a 301 - In WordPress admin, go to WP Admin → Royal MCP → Settings and save the form to invalidate the 12-hour self-check transient
- Reload any Royal MCP admin page — the “OAuth registration may be blocked” notice should no longer appear
- Reconnect Claude.ai (or whichever MCP client was failing) — the OAuth handshake should now complete
Still Stuck?
If you’ve applied the appropriate fix and the curl test still returns 301, contact support@royalplugins.com with:
Information We’ll Need
- Full
curl -i -X POSToutput (headers + body) - Your web server (Nginx / Apache / LiteSpeed) and the host (DigitalOcean, AWS, cPanel, Cloudways, etc.)
- Whether you’re behind Cloudflare, BunnyCDN, or another CDN/WAF
- Royal MCP version (must be 1.4.22 or newer for the self-check)
- What you tried from this article and what changed (or didn’t)
We respond within one business day.