WordPress Plugins
Free Tools
Pricing Blog Case Studies Switch to Royal Plugin Graveyard Support My Account Cart
Support / Royal MCP / SiteGround Returns 404 for /.well-known/

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.

Try the cache-exclusion fix first

Most SiteGround OAuth failures are resolved by adding the SG Optimizer Dynamic Cache exclusions described in OAuth Fails on Managed Hosts → Option A. If you’ve done that and the Activity Log is still empty, this page is for you. The two issues are separate root causes and you may need both fixes.

Want the simplest fix? Skip OAuth on Claude Desktop entirely.

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.

See: Connect Claude Desktop via API Key (Skip OAuth) →

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 -I against your Royal MCP REST endpoint shows x-cache-enabled: False — cache is confirmed off for that path
  • Hitting https://YOUR-DOMAIN.com/.well-known/oauth-authorization-server returns a tiny 404 from nginx (no X-Httpd header, 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)
Don’t use the Activity Log as a diagnostic for this issue

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.

Why SiteGround support may say “the files don’t exist”

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.

Substitute your actual domain in the JSON below

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.

The resource field MUST be an absolute URL

Replace 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.”

If Claude Desktop still rejects the response (Content-Type issue)

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.

Other hosts where this might apply

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:

  1. Copy your API key from WP Admin → Royal MCP → Settings
  2. 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"
          ]
        }
      }
    }
  3. 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.

Why this works on SiteGround when OAuth doesn’t

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-server and /.well-known/oauth-protected-resource (use curl -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.