Forum Replies Created

Viewing 11 replies - 1 through 11 (of 11 total)
  • Plugin Support rpteam

    (@rpteam)

    Hi @alexandregenesis — circling back. The fix shipped in 1.4.13 as promised,
    plus follow-on fixes in 1.4.14 and 1.4.15 worth noting.

    1.4.13 (your specific fix): /register, /token, /authorize now send
    Cache-Control: no-store, no-cache, must-revalidate, private and
    Pragma: no-cache on every response. Should make the PowerBoost
    cache-poisoning behavior you diagnosed structurally impossible.

    1.4.14: GET /wp-json/royal-mcp/v1/mcp (without auth) now returns
    401 + WWW-Authenticate: Bearer instead of 405 — restores Claude.ai web’s
    RFC 9728 OAuth discovery probe.

    1.4.15: Same no-store headers extended to the /mcp endpoint and every response
    under /wp-json/royal-mcp/* — 1.4.13 was a partial fix, /mcp itself was still
    vulnerable to the same edge-cache poisoning pattern. Also flipped 403→401 for
    invalid API key (RFC 7235 alignment, helps strict MCP clients fall back to
    OAuth correctly).

    To verify after updating to 1.4.15:

    curl -v -X POST "https://yoursite.com/register?_=$(date +%s)" \
    -H "Content-Type: application/json" \
    -d '{"client_name":"Test","redirect_uris":["https://claude.ai/api/mcp/auth_callback"],"grant_types":["authorization_code"],"response_types":["code"],"token_endpoint_auth_method":"none"}'

    Response headers should now include Cache-Control: no-store, ... and the body
    should be a 201 with client_id. Then try the Claude.ai connector directly —
    should complete OAuth without the cache excludes you configured as a workaround.

    If you still get a cached 405 even with the fresh query string, that means
    PowerBoost is overriding Cache-Control: no-store on its own response
    interception — a host-side bug worth escalating to o2switch. The
    /register, /token, /authorize cache excludes would remain the permanent
    solution in that case.

    Mind giving 1.4.15 a try and letting us know? If it works without the manual
    cache excludes, please mark the topic as resolved — helps the next person on
    a LiteSpeed/PowerBoost setup land on the right answer faster.

    — Royal Plugins team

    Plugin Support rpteam

    (@rpteam)

    Hi @michealdupont — thanks for the request, good thing to surface so we can
    explain where we draw the line.

    Short answer: PHP file editing isn’t on the roadmap and probably never will be,
    and I want to give you the why so it doesn’t feel arbitrary.

    The threat model. Every Royal MCP tool today operates on content that lives in
    the database — posts, pages, products, taxonomy, comments, settings. All of
    that is recoverable from a backup, and the worst-case scenario for a leaked API
    key is “someone messes with your content.” Adding PHP file write turns that
    into “someone plants a backdoor in functions.php and hides their tracks.” Same
    credential, completely different blast radius. We’d need to assume every
    install was one phished API key away from full code execution, and that’s not a
    trade we want to make for a free WP.org plugin.

    WP-side constraints. A meaningful percentage of production installs define
    DISALLOW_FILE_EDIT or DISALLOW_FILE_MODS in wp-config.php specifically to
    prevent any plugin (or admin user) from editing PHP files. Honoring those
    constants means the tool silently no-ops on those sites. Not honoring them
    breaks WordPress best practice. Either way the feature is unreliable by design.

    Existing paths that already do this safely. WP-CLI over SSH (wp eval-file,
    wp shell), an IDE with SFTP/SSH access, or a “Code Snippets”-style plugin
    that stores PHP in a DB row with syntax validation and an instant kill switch.
    Each of those has guardrails (atomic write, lint, rollback) that an MCP
    file_put_contents tool would lack without a substantial engineering investment
    that doesn’t fit our scope.

    For your specific case — hiding sidebars and going full-width — the CSS via
    Customizer route the AI suggested is actually the cleanest answer regardless
    of capabilities. It’s theme-update-safe, doesn’t need a child theme, and
    reverts with one click if it ever causes layout issues.

    Hope that explains the stance, assuming since haven’t heard anything more on
    this in over a week that the CSS approach worked, so marking as resolved for now.

    Plugin Support rpteam

    (@rpteam)

    Hi @beerloft — circling back. Since 1.4.3 we’ve shipped 1.4.13, 1.4.14, and 1.4.15
    with several fixes that line up with what you reported:

    • 1.4.13 — Added Cache-Control: no-store to OAuth endpoints (/register, /token,
    /authorize). Pre-1.4.13, host-level edge caches (LiteSpeed, Cloudflare APO,
    fastcgi cache) could pin an auth-error response and serve it back indefinitely
    to every subsequent request.

    • 1.4.14 — GET /wp-json/royal-mcp/v1/mcp without auth now returns
    401 + WWW-Authenticate: Bearer instead of 405. This is what claude.ai’s web
    connector probes for to start its OAuth flow — pre-1.4.14 it would silently
    fail with exactly the “Couldn’t reach the MCP server” message you saw, with
    no authorization window ever appearing.

    • 1.4.15 — Same no-store headers extended to the /mcp endpoint itself and to
    every response in the namespace (1.4.13 was a partial fix). Also flipped
    invalid-API-key responses from 403 to 401 with a WWW-Authenticate header,
    which is what RFC 9728 strict MCP clients need to fall back to OAuth
    correctly.

    If you’re up for retesting:

    1. Update both sites to 1.4.15.
    2. Settings → Permalinks → Save Changes on each (forces a rewrite flush in
       case any /authorize routes weren't registered cleanly during prior upgrades).
    3. If either site is behind Cloudflare, double-check that "Block AI Bots" /
       "Verified Bots" is OFF — Anthropic's backend (AS 399358) makes the
       server-to-server /register and /token calls, and Cloudflare blocks that
       ASN by default on new zones. This was the most likely cause of your
       original symptoms and we still see it bite people regularly.
    4. Try connecting from claude.ai web again (since that was the failing path).

    If it works, would you mind marking the topic as resolved or comment back as resolved so I can? That helps the next person Googling the same symptoms land on the answer faster. If it still doesn’t, please share which scenario applies (A/B/C from my earlier reply) and any new error message and we’ll dig back in.

    — Royal Plugins

    Plugin Support rpteam

    (@rpteam)

    Hi René,

    Owe you an apology before anything else — I made a mistake in my very first reply that’s been quietly compounding through this entire thread. The SG Optimizer cache exclusion list I gave you was both wrong in one place and missing the most important endpoints. That alone could explain why nothing has stuck. Let me correct it and give you a definitive next step.

    The exclusion list I gave you originally:
    /wp-json/royal-mcp/*
    /wp-json/royal-mcp/v1/oauth/* ← MISTAKE: this path has never existed in
    Royal MCP
    /.well-known/oauth-authorization-server
    /.well-known/oauth-protected-resource

    The /wp-json/royal-mcp/v1/oauth/* line does nothing. There’s no such REST namespace in the plugin — Royal MCP’s OAuth endpoints are root-level rewrite rules at /authorize, /token, and /register — and those three paths were never in your exclusion list. They’re the actual OAuth handshake endpoints, and they’re the ones SG’s edge cache is most likely poisoning. Anyone who got “Authorization with the MCP server failed” on SG without those exclusions was probably hitting a cached response from a stale GET
    probe.

    Step 1 — fix the SG Optimizer exclusion list

    WP Admin → SG Optimizer → Caching → Dynamic Cache → Exclude URLs. Replace the list with:

    /wp-json/royal-mcp/*
    /.well-known/oauth-authorization-server
    /.well-known/oauth-protected-resource
    /authorize
    /token
    /register

    Save, then click Purge SG Cache in the SG Optimizer toolbar. The purge is critical — without it any cached 4xx responses from your earlier test attempts (when GET /mcp was still returning 405 pre-1.4.14) will keep getting served regardless of the new exclusions.

    Step 2 — two diagnostic curls (run AFTER the cache purge)

    These will tell us if anything else is in the way:

    (A) Content-Type on the metadata files — should be application/json
    curl -sI https://terraexperty.com/.well-known/oauth-authorization-server | grep -i content-type
    curl -sI https://terraexperty.com/.well-known/oauth-protected-resource | grep -i content-type

    (B) Force a cache-busted POST to /register — should return 201 with a client_id
    curl -v -X POST “https://terraexperty.com/register?=$(date +%s)” \ -H “Content-Type: application/json” \ -H “Cache-Control: no-cache” \ -d ‘{“client_name”:”Test”,”redirect_uris”:[“https://claude.ai/api/mcp/auth_callback” ],”grant_types”:[“authorization_code”],”response_types”:[“code”],”token_endpoint_auth
    method”:”none”}’

    Send back the output of both. If (A) shows text/plain, that’s a separate Content-Type
    blocker (covered in step 3). If (B) returns 201 Created with a client_id, the OAuth
    registration plumbing is working and you can retry the Claude.ai connection right
    then.

    Step 3 — retract my “Path A” SiteGround support ticket recommendation

    In my last reply I told you to open a SiteGround ticket asking for an nginx MIME-type override on the /.well-known/ paths. Don’t bother — that path is now closed. SiteGround confirmed to another Royal MCP customer yesterday that they no longer make per-customer nginx changes since their migration to Google Cloud infrastructure. The escalation route I pointed you at has been removed.

    If diagnostic (A) above shows text/plain, the working alternative is a free Cloudflare Transform Rule that overrides the response Content-Type at the edge — works around SG entirely:
    https://royalplugins.com/support/royal-mcp/siteground-cloudflare-content-type-fix.html

    Two-minute setup on Cloudflare’s free plan, no SG involvement needed. Walkthrough on
    that page.

    The .htaccess ForceType application/json advice I gave you earlier in the thread also doesn’t work on these paths — nginx serves /.well-known/ files directly without falling through to Apache, so .htaccess is silently ignored. Apologies for sending you down that road.

    Step 4 — fallback if you just need it working today

    If the goal is simply “get Royal MCP usable with Claude” and Claude Desktop is acceptable, you can sidestep OAuth entirely with the API-key bypass — works in two minutes, no /.well-known/, no consent screen, no Cloudflare:
    https://royalplugins.com/support/royal-mcp/connect-claude-desktop-api-key.html

    Quick version: paste this into your Claude Desktop config, substituting your API key from WP Admin → Royal MCP → Settings:

     {
    "mcpServers": {
    "terra-experty": {
    "command": "npx",
    "args": [
    "-y",
    "mcp-remote",
    "https://terraexperty.com/wp-json/royal-mcp/v1/mcp",
    "--header",
    "X-Royal-MCP-API-Key: YOUR_KEY_HERE"
    ]
    }
    }
    }

    Restart Claude Desktop. Connected.

    Send back the curl output from step 2 once you’ve done step 1 and we’ll either be done or know exactly which layer to tackle next. Sorry again for the runaround on the wrong cache list — that should have been right from the start.

    Best,
    Jameson

    -Royal Plugins

    Plugin Support rpteam

    (@rpteam)

    Hi René,

    I tested every endpoint on terraexperty.com from our side just now, and have a definitive picture for you. The good news: Royal MCP on your site is fully functional. Every OAuth endpoint reaches PHP correctly:

    GET /.well-known/oauth-authorization-server → 200 ✅
    GET /.well-known/oauth-protected-resource → 200 ✅
    GET /wp-json/royal-mcp/v1/mcp → 401 ✅ (with WWW-Authenticate:
    Bearer resource_metadata=”…”)
    POST /register → 201 ✅ (dynamic client registration confirmed working — I just registered a test client and it succeeded)
    GET /authorize → reaches PHP (X-Httpd: 1)

    The 1.4.14 fix is verified live. DCR works. The plugin is doing its job.

    Two important corrections on what you’re seeing:

    1. Empty debug.log is GOOD news, not bad. WordPress’s debug.log only captures PHP
      errors and notices, not request traffic. An empty debug.log during OAuth attempts
      means no PHP errors were thrown — which is exactly what you want. It does NOT mean
      Claude.ai’s requests aren’t reaching your server. Royal MCP also doesn’t write
      OAuth handshake events to its own Activity Log (that log is for post-auth MCP tool
      calls). To see actual request traffic during OAuth attempts, pull your nginx
      access log from SiteGround Site Tools → Statistics → Access Log.
    2. The most likely remaining blocker is Content-Type on your static files. Both
      .well-known/ files are returning: Content-Type: text/plain RFC 8414 §3.2 requires OAuth discovery responses to be served as application/json (“a successful response MUST use the 200 OK HTTP status code and return a JSON object using the application/json content type”). Most clients are lenient and parse JSON regardless of Content-Type. Strict clients reject the metadata even
      though the body is valid JSON. Another customer on SiteGround GrowBig hit this
      same fingerprint recently — same host configuration, same text/plain, same OAuth
      failure. That’s two production data points pointing at the same root cause. Two paths forward, depending on your use case:

    Path A — Fix the Content-Type properly (works for Claude.ai web AND Claude Desktop) Open a SiteGround support ticket with this exact wording:

    “We have two static files at /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource that are required by RFC 8414 (OAuth 2.0 Authorization Server Metadata). They are currently being served with Content-Type: text/plain because they have no file extension, but RFC 8414 §3.2 mandates Content-Type: application/json. .htaccess ForceType doesn’t apply since nginx serves these files directly without falling through to Apache. Could you please add an nginx-level MIME type override so files at these two specific paths are served as application/json? They contain valid JSON; only the Content-Type header needs correction.”

    SiteGround has granted similar exceptions for other customers’ OAuth needs.

    Path B — Skip OAuth entirely on Claude Desktop (works in 2 minutes, today)

    If your goal is to get Royal MCP working with an AI assistant and Claude Desktop
    is acceptable for your workflow, you can bypass the OAuth flow entirely. Royal MCP
    supports API-key authentication via mcp-remote’s –header flag — no
    /.well-known/, no discovery, no consent screen. Confirmed working on SiteGround
    GrowBig.

    Full walkthrough:
    https://royalplugins.com/support/royal-mcp/connect-claude-desktop-api-key.html

    Quick version — paste this into your Claude Desktop config
    (claude_desktop_config.json), substituting your API key from WP Admin → Royal MCP
    → Settings:

    {
    "mcpServers": {
    "terra-experty": {
    "command": "npx",
    "args": [
    "-y",
    "mcp-remote",
    "https://terraexperty.com/wp-json/royal-mcp/v1/mcp",
    "--header",
    "X-Royal-MCP-API-Key: YOUR_KEY_HERE"
    ]
    }
    }
    }

    Restart Claude Desktop and you’re connected.

    Path A is the proper fix and unblocks Claude.ai web. Path B works around the issue
    today if waiting on SiteGround isn’t workable.

    Best,
    Jameson

    – Royal Plugins

    Plugin Support rpteam

    (@rpteam)

    V.1.4.14 is live, test it and let me know

    Plugin Support rpteam

    (@rpteam)

    Hi René,

    I see the issue now, will have update addressing this in next 24hrs V1.4.14 – be on the lookout

    Plugin Support rpteam

    (@rpteam)

    Hi René,

    That diagnostic is gold — those green checkmarks prove the static-file workaround unblocked the host-level OAuth handshake. The “Unknown client_id” is the next layer down, and it points at Claude.ai’s
    connector configuration on your side, not a Royal MCP bug.

    What’s happening:

    Claude.ai’s MCP connector supports two modes:

    1. Automatic OAuth (the standard flow Royal MCP expects) — you give Claude only your MCP URL. Claude auto-discovers your OAuth metadata at /.well-known/oauth-authorization-server, calls /register to
      dynamically register itself per RFC 7591, receives a fresh client_id, then sends the user to /authorize. Royal MCP recognizes the freshly-registered client_id and the handshake completes.
    2. Custom OAuth credentials / Bearer Token — you pre-register a client and paste a client_id (or token) into Claude’s connector form manually. Claude skips /register entirely and sends whatever client_id you
      entered straight to /authorize. If that ID doesn’t exist in Royal MCP’s clients table, you get exactly the error you’re seeing. Your first message mentioned “creating a custom connector with a Bearer Token” — that’s mode 2, and Claude.ai may still be using that cached configuration even if you’ve since pasted the URL alone. That
      perfectly matches your observation that /register is never called and /authorize arrives with an unknown ID. The fix:
    3. In Claude.ai → Settings → Connectors, fully remove the existing Royal MCP / Terra Experty connector. Don’t just edit it — remove it completely so Claude purges its cached config.
    4. Wait ~10 seconds.
    5. Click Add connector and select the standard “Add MCP server by URL” option (not the “Custom OAuth” / “Bearer Token” option).
    6. Paste only the MCP URL: https://terraexperty.com/wp-json/royal-mcp/v1/mcp — no client_id, no secret, nothing else.
    7. Click through the OAuth flow. Verify it’s now using DCR: While you click “Add connector”, tail your access log: tail -f /var/log/nginx/access.log | grep -E ‘(register|authorize|token)’ You should see POST /register HTTP/2 201, then GET /authorize …, then POST /token …. If /register does not appear, Claude is still running in the custom-credentials mode — back to step 1. About the empty Activity Log: Royal MCP’s Activity Log records MCP tool calls (post-auth), not the OAuth handshake itself. So an empty log during the connection attempt is expected behavior, not a separate signal of trouble — once you’re
      connected and Claude makes its first tool call, you’ll see it land in the log. Try the remove-and-re-add and send back the access-log lines. We’re one click away from a working connector.

    Best
    Jameson

    Plugin Support rpteam

    (@rpteam)

    Hi René,

    Perfect — that confirms exactly what we suspected. SiteGround’s nginx will serve files
    from /.well-known/ if they physically exist; it just refuses to fall through to
    WordPress when they don’t. So the workaround is to drop two static files in your
    webroot.

    File 1: /.well-known/oauth-authorization-server (no file extension)

    {
    “issuer”: “https://terraexperty.com”,
    “authorization_endpoint”: “https://terraexperty.com/authorize”,
    “token_endpoint”: “https://terraexperty.com/token”,
    “registration_endpoint”: “https://terraexperty.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/”
    }

    File 2: /.well-known/oauth-protected-resource (no file extension)

    {
    “resource”: “https://terraexperty.com/wp-json/royal-mcp/v1”,
    “authorization_servers”: [“https://terraexperty.com”%5D,
    “bearer_methods_supported”: [“header”],
    “scopes_supported”: [“mcp:full”]
    }

    Steps:

    1. Via SiteGround File Manager (Site Tools → Site → File Manager) or SFTP, navigate to
      your WordPress root (the folder containing wp-config.php).
    2. Create a folder named .well-known if it doesn’t exist.
    3. Inside it, create two files with no extension — name them exactly
      oauth-authorization-server and oauth-protected-resource.
    4. Paste the JSON content above into each, save. Verify with curl: curl -i https://terraexperty.com/.well-known/oauth-authorization-server
      curl -i https://terraexperty.com/.well-known/oauth-protected-resource You should see HTTP/2 200 and the JSON body. If you see a 404, the file path is off —
      double-check the folder name starts with a dot. If the Content-Type header comes back as application/octet-stream rather than
      application/json, that’s fine — Claude.ai parses these endpoints as JSON regardless.
      If for any reason Claude still rejects, drop a .htaccess next to the files with: ForceType application/json
      ForceType application/json Once the files are live, retry the Claude.ai connection. We’re scoping a 1.4.14
      release that will auto-create these for SiteGround/managed-host users so this isn’t a
      manual step going forward — thanks for the patience and for helping us pin this down.

    Best
    Jameson

    Plugin Support rpteam

    (@rpteam)

    Hi René!
    Quick follow-up, I just tested your endpoint from my end and we have a
    definitive answer.

    The good news: Royal MCP is working correctly on your site. Your MCP endpoint,
    /authorize, /register, and /token all reach WordPress and respond properly with our
    1.4.13 cache-control headers.

    The actual issue: SiteGround’s nginx is intercepting /.well-known/* requests at the
    host level and returning its own static 404 — the requests never reach WordPress.
    Here’s the proof:

    Your MCP endpoint — works fine, served by PHP/WordPress:
    $ curl -I https://terraexperty.com/wp-json/royal-mcp/v1/
    HTTP/1.1 200 OK
    X-Httpd: 1 ← PHP processed this

    OAuth discovery — nginx 404, never reached WordPress:
    $ curl -I https://terraexperty.com/.well-known/oauth-authorization-server
    HTTP/1.1 404 Not Found
    Content-Length: 93 ← tiny nginx static page, not WP
    (no X-Httpd header, no CORS headers — request died at nginx)

    Same behavior on any other .well-known path:
    $ curl -I https://terraexperty.com/.well-known/security.txt
    HTTP/1.1 404 Not Found
    Content-Length: 93 ← identical fingerprint

    Compare to a WP-handled 404:
    $ curl -s https://terraexperty.com/this-does-not-exist/
    <html lang=”es” … ← full WP page in your site’s language

    SiteGround reserves /.well-known/ for their own use (ACME SSL certificate renewals,
    security.txt). Anything else under that path returns nginx’s default 404 before
    WordPress can register a route there. This is why Claude.ai fails the connection: it
    tries to discover the OAuth metadata at /.well-known/oauth-authorization-server, gets
    a 404, and can’t continue the flow.

    What you need to do: open a support ticket with SiteGround and ask them to allow these
    two paths through to PHP/WordPress:

    /.well-known/oauth-authorization-server
    /.well-known/oauth-protected-resource

    Suggested wording for the ticket:

    “We use a WordPress plugin (Royal MCP) that needs to serve OAuth 2.0 discovery
    metadata at the standard RFC 8414 paths (/.well-known/oauth-authorization-server and
    /.well-known/oauth-protected-resource). These requests are currently returning a 404
    from your nginx layer instead of reaching WordPress. Could you please add an exception
    to allow these specific paths to pass through to PHP? They’re standard OAuth
    discovery endpoints required by client applications like Claude.ai.”

    If SiteGround declines or this is a hard blocker for you, let us know — we’re scoping
    a workaround on our end (writing the metadata as a static file in the webroot) for the
    next Royal MCP release that could route around this.

    Best,
    Jameson
    -Royal Plugins

    Plugin Support rpteam

    (@rpteam)

    Hi René,

    Thanks for the detailed write-up — you’ve already ruled out most of the usual suspects, which actually helps a lot. We’ve seen this exact failure mode on managed-WordPress hosts that run NGINX-level dynamic caching (SiteGround, o2switch, LiteSpeed). Even with Cloudflare removed, SiteGround’s own Speed Optimizer cache layer is still in front of WordPress, and it sometimes ignores the cache-bypass headers we send on the OAuth endpoints.

    Before we dig deeper, two quick checks will tell us exactly what’s happening:

    1. Confirm your Royal MCP version WP Admin → Plugins → Royal MCP. We need 1.4.13 or newer — earlier versions had a known cache-poisoning bug we fixed in 1.4.13. If you’re on an older build, please update first and retry the connection.
    2. Check the Activity Log WP Admin → Royal MCP → Activity Log, then attempt the Claude.ai authorization again. Look for entries timestamped at the moment you clicked “Authorize.”
    • Entries appear: OAuth is reaching WordPress — the issue is in the flow itself, and we’ll dig into the specific log lines.
    • Log stays empty: The request never reached PHP, which confirms an upstream cache or WAF is short-circuiting it. This is the more likely scenario on SiteGround.
    1. Inspect the cache headers (1 minute) Run this from any terminal — it tells us whether SiteGround is serving cached responses for our OAuth endpoints: curl -I https://terraexperty.com/wp-json/royal-mcp/v1/oauth/.well-known/oauth-authorization-server Send us the full response headers. We’re looking specifically for x-cache, x-proxy-cache, or x-sg-cache — if any of those show HIT, we’ve found the problem. If the Activity Log is empty (most likely): The fix is to exclude the OAuth and MCP endpoints from SiteGround’s Dynamic Cache. In WP Admin → SG Optimizer → Caching → Dynamic Cache → Exclude URLs, add these patterns: /wp-json/royal-mcp/*
      /wp-json/royal-mcp/v1/oauth/*
      /.well-known/oauth-authorization-server
      /.well-known/oauth-protected-resource

    Then click Purge Cache in the SG Optimizer toolbar and retry the Claude.ai connection. This has resolved the same symptom for us on other NGINX-cached hosts.

    If that doesn’t clear it, also worth checking SiteGround → Site Tools → Security → Site Scanner / Web Application Firewall — some custom WAF rules block JSON POSTs to non-standard REST namespaces, which would also produce the silent failure you’re describing.

    Reply with the Activity Log findings and curl headers and we’ll take it from there. We’ll get this connected!

    Best,
    Jameson
    Royal Plugins

Viewing 11 replies - 1 through 11 (of 11 total)