SiteGround Returns 404 for /.well-known/ — Royal MCP OAuth Fix
If you’ve already added SG Optimizer cache exclusions and Claude.ai still returns “Authorization with the MCP server failed” with an empty Royal MCP Activity Log, you’re hitting a separate, deeper issue: SiteGround’s nginx layer reserves /.well-known/ for its own use (ACME SSL renewals) and serves a static 404 for any other path under it — before WordPress ever sees the request. Drop two static JSON files in your webroot and the OAuth handshake completes immediately.
If you only need to connect Claude Desktop (not Claude.ai web), you can bypass OAuth completely with a two-line change to your Claude Desktop config — no /.well-known/ files, no static-file workaround, no SiteGround tickets. Confirmed working on SiteGround GrowBig.
Symptoms
You’re hitting this specific issue if all of the following are true:
The Telltale Signs
- You’ve already added SG Optimizer Dynamic Cache exclusions for the OAuth paths and purged the cache
- A
curl -Iagainst your Royal MCP REST endpoint showsx-cache-enabled: False— cache is confirmed off for that path - Hitting
https://YOUR-DOMAIN.com/.well-known/oauth-authorization-serverreturns a tiny 404 from nginx (noX-Httpdheader, no CORS headers, no WordPress branding) — the request died at the web server, not at WordPress - Royal MCP is on version 1.4.13 or newer (verifiable in WP Admin → Plugins)
An empty WP Admin → Royal MCP → Activity Log is expected behavior for OAuth-connected MCP sessions and is not a sign of failure. The Activity Log captures requests to the legacy REST endpoints (/posts, /pages, /media, etc.) but does not currently log requests to the modern MCP JSON-RPC endpoint at /wp-json/royal-mcp/v1/mcp, which is what Claude.ai actually uses. We’re closing this gap in a future release. For diagnosing this /.well-known/ 404 issue, use the curl tests in the next section instead — they’re definitive.
How to Confirm It’s the nginx /.well-known/ Intercept
Three quick curl tests will leave no doubt about the diagnosis. Run them from any terminal — replace YOUR-DOMAIN.com with your actual domain.
Test the OAuth discovery URL Claude.ai uses
This is the URL the MCP client probes during connection setup:
curl -I https://YOUR-DOMAIN.com/.well-known/oauth-authorization-server
If you see HTTP/1.1 404 Not Found with Content-Length: 93 (or some other tiny number) and no X-Httpd header, that’s nginx serving its default 404 page directly. The request never reached WordPress.
Confirm with any other /.well-known/ path
This proves the intercept is on the entire /.well-known/ namespace, not specific to OAuth:
curl -I https://YOUR-DOMAIN.com/.well-known/security.txt curl -I https://YOUR-DOMAIN.com/.well-known/anything-random
Identical 404 fingerprint confirms SiteGround’s nginx is shadowing the entire path prefix.
Compare against a normal WordPress 404 to see the difference
curl -s https://YOUR-DOMAIN.com/this-does-not-exist/ | head -20
This returns a full WordPress 404 page (HTML, your site’s language, theme styling), confirming WordPress does handle other unknown paths correctly. The /.well-known/ behavior is unique — that’s the smoking gun.
If you opened a SiteGround support ticket and they replied that the /.well-known/ files don’t exist on your server, that’s actually the correct behavior — and the perfect setup for this fix. SiteGround’s nginx will serve files from /.well-known/ if they physically exist in your webroot. It just won’t fall through to WordPress when they don’t. So we’re going to put two real files there.
The Fix — Two Static Files in Your Webroot
You’ll create two text files in public_html/.well-known/ with no file extension. nginx will serve them directly, Claude.ai will read the OAuth metadata it needs, and the authorization handshake will complete normally.
Both files contain absolute URLs that must match your site. Replace every instance of https://YOUR-DOMAIN.com with your real site URL (including the protocol and no trailing slash). If your site uses www., include it.
Open SiteGround File Manager (or SFTP)
In Site Tools → Site → File Manager, navigate to your WordPress webroot — the folder containing wp-config.php and wp-content/. (For the primary domain on a SiteGround account, this is typically public_html/.)
Create the .well-known folder if it doesn’t exist
The folder name starts with a dot. Some file managers hide dot-prefixed entries by default — if you don’t see it, enable “Show hidden files” or just try to create it; the file manager will tell you if it already exists.
Create the first file: oauth-authorization-server
Inside .well-known/, create a new file named exactly oauth-authorization-server (no extension, no .txt or .json). Paste this JSON, substituting your domain:
{
"issuer": "https://YOUR-DOMAIN.com",
"authorization_endpoint": "https://YOUR-DOMAIN.com/authorize",
"token_endpoint": "https://YOUR-DOMAIN.com/token",
"registration_endpoint": "https://YOUR-DOMAIN.com/register",
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"token_endpoint_auth_methods_supported": ["none", "client_secret_post"],
"code_challenge_methods_supported": ["S256"],
"scopes_supported": ["mcp:full"],
"service_documentation": "https://royalplugins.com/support/royal-mcp/"
}Save the file.
Create the second file: oauth-protected-resource
Same folder, named exactly oauth-protected-resource (no extension). Paste:
{
"resource": "https://YOUR-DOMAIN.com/wp-json/royal-mcp/v1",
"authorization_servers": ["https://YOUR-DOMAIN.com"],
"bearer_methods_supported": ["header"],
"scopes_supported": ["mcp:full"]
}Save the file.
resource field MUST be an absolute URLReplace https://YOUR-DOMAIN.com with your real domain — do not leave it as a relative path like /wp-json/royal-mcp/v1 or wp-json/royal-mcp/v1. RFC 9728 requires this field to be a fully-qualified absolute URL, and Claude.ai/Claude Desktop will resolve a relative path against the metadata URL itself, producing a malformed nginx request like .well-known/oauth-protected-resource/wp-json/royal-mcp/v1/mcp that returns 404. The connection will fail silently. Same rule applies to authorization_servers — absolute URLs only.
Verify both files are now reachable
From any terminal:
curl -i https://YOUR-DOMAIN.com/.well-known/oauth-authorization-server curl -i https://YOUR-DOMAIN.com/.well-known/oauth-protected-resource
You should now see HTTP/2 200 and your JSON body. If you still see 404, double-check the folder name starts with a dot and the file names have no extension.
Retry the Claude.ai connection
Open Claude.ai → Connectors → Royal MCP and click Connect (or Reconnect) again. The authorize flow should complete and Royal MCP’s Activity Log will now show entries the moment you click “Authorize.”
Strict MCP clients — Claude Desktop’s mcp-remote bridge in particular — require these metadata responses to be served as application/json. SiteGround’s nginx serves the static files as text/plain, and .htaccess ForceType directives are silently ignored on these paths because nginx never falls through to Apache for /.well-known/*. SiteGround also confirmed in May 2026 that they no longer make per-customer nginx config changes since their move to Google Cloud, so the host-side fix is closed.
The reliable answer is a free Cloudflare Transform Rule that overrides the response Content-Type at the edge. Two-minute setup, walkthrough at Fix /.well-known/ Content-Type with a Cloudflare Transform Rule →
Why Does SiteGround Block /.well-known/?
The /.well-known/ URL prefix is reserved by RFC 5785 for “well-known” URIs that need a predictable, host-level location — things like ACME SSL certificate challenges (/.well-known/acme-challenge/), security.txt, and OAuth 2.0 / OpenID Connect discovery metadata (RFC 8414).
SiteGround’s nginx layer is configured to serve /.well-known/acme-challenge/* directly so their automated Let’s Encrypt renewals can complete without going through WordPress (which might redirect, return a wrong content type, or be slow). To keep that mechanism reliable, nginx claims the entire /.well-known/ path prefix at the host level: it serves files that physically exist there, and returns a 404 for anything that doesn’t — without falling through to PHP.
That’s great for ACME, but it means RFC 8414 OAuth discovery URLs (which Claude.ai and every other MCP client are required to probe) never reach WordPress. The Royal MCP rewrite rule that maps /.well-known/oauth-authorization-server to a WordPress query var works on every other host we’ve tested — just not on SiteGround, because nginx never lets the request get that far.
SiteGround is the most common case but the same pattern can appear on any host that uses nginx to claim /.well-known/* for ACME or other system-level uses — some o2switch, Hostinger, and Pressable configurations have shown the same fingerprint. If your curl shows the same tiny nginx 404 for /.well-known/anything, this fix applies to you too.
What Royal MCP 1.4.14 Already Does for You
Royal MCP 1.4.14 (shipped May 2026) detects this exact failure mode automatically. When the plugin loads on a site where /.well-known/oauth-authorization-server isn’t reachable, it surfaces a dismissible admin notice on the Plugins screen and Royal MCP settings linking back to this page. So future SiteGround customers will land here from inside their own WordPress admin instead of having to search for “Royal MCP couldn’t reach OAuth” first.
The plugin can’t auto-create the static files for you, though — SiteGround’s nginx layer that blocks /.well-known/ reads from the same WordPress installation, so files written via PHP would be served the same way. The static-file step still has to be done manually via File Manager / SFTP.
Faster Alternative for Claude Desktop: Skip OAuth Entirely
If your only goal is to get Claude Desktop connected, the static-file workaround above is more work than you need. You can bypass OAuth completely by passing a Royal MCP API key as a header through mcp-remote, the bridge Claude Desktop uses to talk to remote MCP servers. No /.well-known/, no consent screen, no SiteGround support ticket.
Quick version — full step-by-step at Connect Claude Desktop via API Key:
- Copy your API key from WP Admin → Royal MCP → Settings
- Add this entry to your
claude_desktop_config.json(substitute your domain and key):{ "mcpServers": { "my-site": { "command": "npx", "args": [ "-y", "mcp-remote", "https://YOUR-SITE.com/wp-json/royal-mcp/v1/mcp", "--header", "X-Royal-MCP-API-Key: YOUR_API_KEY_HERE" ] } } } - Quit and relaunch Claude Desktop.
This works regardless of whether the /.well-known/ files are in place. It also works regardless of Content-Type, WAF rules, or any other front-end web server quirk — the only thing it needs is the /wp-json/royal-mcp/v1/mcp endpoint reachable, which your curl test in the verification step above already confirmed.
OAuth discovery (RFC 8414) requires reaching /.well-known/* — that’s the path SiteGround intercepts. The API key path uses only /wp-json/royal-mcp/v1/mcp, which SiteGround routes through to WordPress normally. The static-file workaround is the only way to make Claude.ai web (browser-based) work; for Claude Desktop, the API-key bypass sidesteps the entire problem.
Still Stuck After Creating the Files?
If you’ve verified both files return HTTP/2 200 via curl but Claude.ai still fails, contact support@royalplugins.com with:
Information We’ll Need
- Full curl output for both
/.well-known/oauth-authorization-serverand/.well-known/oauth-protected-resource(usecurl -i, not just-I, so we see the body too) - Royal MCP version from WP Admin → Plugins
- Your domain (so we can compare your JSON against what we’d expect)
- The exact error message Claude.ai shows after clicking Authorize
- Whether the Activity Log now shows any entries during the failed attempt (even one entry tells us the request reached WordPress)
We respond within one business day and have resolved this on every SiteGround site we’ve seen so far.