Openprovider MCP

Openprovider MCP Server

Connect AI assistants like Claude, Cursor, and other MCP-compatible tools to your Openprovider account. Once connected, you can manage domains, DNS, SSL certificates, customers, email, and licenses through natural-language conversation — with policy controls, spend caps, and human approval gates on every billable or destructive action.

The server implements the Model Context Protocol (MCP) over Streamable HTTP. It is multi-tenant: each team connects its own Openprovider reseller credentials and gets isolated data, policies, and audit trails.

Key capabilities

Prerequisites

  1. An account on the dashboard. Sign up at https://mcp.op-staging.net/dashboard/signup. (Reading this on a deployment of your own? The hostname above is rewritten to whichever host you loaded this page from, so the examples are already correct for your environment.)
  2. Openprovider reseller credentials connected. From the dashboard, open Openprovider and enter your Openprovider username and password. The password is encrypted with a per-tenant key and never stored in plaintext.

That is all you need to sign in from a client with your browser. If you are connecting a machine, agent or CI job instead of a person, also issue an API key: from the dashboard open API keys, create one, and store the op_live_… value — it is shown exactly once. Keys can be revoked any time from the same page.

Two ways to connect

Where browser sign-in is available. It is enabled per environment. To check a given server, open https://mcp.op-staging.net/.well-known/oauth-authorization-server: a JSON document means browser sign-in is on; a 404 means that server currently requires an API key. If a client is not offered a browser login, use the API-key form shown alongside each setup below.

Setup: Claude Code

Claude Code connects to remote MCP servers natively. Browser sign-in:

claude mcp add --transport http openprovider https://mcp.op-staging.net/mcp

Run /mcp in a session (or claude mcp login openprovider) and Claude Code opens the browser, you sign in, and the token is stored and refreshed for you.

With an API key (machines, or a server with sign-in off) — add the header, or check a .mcp.json into your project root:

claude mcp add --transport http openprovider https://mcp.op-staging.net/mcp \
  --header "Authorization: Bearer op_live_YOUR_KEY_HERE"
{
  "mcpServers": {
    "openprovider": {
      "type": "http",
      "url": "https://mcp.op-staging.net/mcp",
      "headers": { "Authorization": "Bearer op_live_YOUR_KEY_HERE" }
    }
  }
}

Setup: Claude Desktop

Newer Claude Desktop builds add remote servers directly (Settings → Connectors → Add custom connector): enter the URL https://mcp.op-staging.net/mcp, and it runs the browser sign-in for you.

Older builds reach remote servers through the mcp-remote bridge (Node.js 18+). Browser sign-in — no header. Sign in once from a terminal first, then add the server to Claude Desktop:

npx -p mcp-remote@latest mcp-remote-client https://mcp.op-staging.net/mcp

The browser opens, you sign in and click Allow, and the command prints "Connected successfully!" and exits. Tokens are cached under ~/.mcp-auth, so Claude Desktop connects in a few seconds without a browser. Skipping this step usually ends in a "Couldn't start… Request timed out" error: Claude Desktop gives the bridge about a minute to start, and the bridge holds startup until you finish signing in.

{
  "mcpServers": {
    "openprovider": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.op-staging.net/mcp"]
    }
  }
}

With an API key, add the header as two more arguments:

{
  "mcpServers": {
    "openprovider": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote", "https://mcp.op-staging.net/mcp",
        "--header", "Authorization: Bearer op_live_YOUR_KEY_HERE"
      ]
    }
  }
}

Fully quit Claude Desktop (macOS: Cmd-Q) and relaunch. The Openprovider tools then appear in the message composer or under the connectors icon, depending on your version.

Setup: Cursor

In Settings → MCP → Add new global MCP server, or .cursor/mcp.json. A url alone triggers browser sign-in — Cursor shows a Login action for the server and opens the browser:

{
  "mcpServers": {
    "openprovider": { "url": "https://mcp.op-staging.net/mcp" }
  }
}

With an API key, add a headers block instead:

{
  "mcpServers": {
    "openprovider": {
      "url": "https://mcp.op-staging.net/mcp",
      "headers": { "Authorization": "Bearer op_live_YOUR_KEY_HERE" }
    }
  }
}

Setup: OpenAI Codex

Codex (CLI and IDE) connects to remote Streamable HTTP servers. Browser sign-in:

codex mcp add openprovider --url https://mcp.op-staging.net/mcp
codex mcp login openprovider

With an API key, point config.toml at an environment variable that holds the key:

[mcp_servers.openprovider]
url = "https://mcp.op-staging.net/mcp"
bearer_token_env_var = "OPENPROVIDER_MCP_KEY"

Authentication

The server accepts two kinds of caller, and both resolve to the same tenant with the same data isolation, policy and audit trail.

Browser sign-in (OAuth 2.1). The server is an OAuth 2.1 resource server with an embedded authorization server: metadata at /.well-known/oauth-authorization-server, Dynamic Client Registration, Client ID Metadata Documents, PKCE (S256) and resource indicators, so a token issued for this server cannot be replayed against any other. A token carries the scopes you approved — mcp:read for read-only tools, mcp:read mcp:write for the rest — and the tools a client sees narrow to what its token allows. Tokens are short-lived and refresh automatically; an owner or admin can revoke any app from the dashboard Connected apps page. Your Openprovider reseller credentials are never shared with the connecting application — only your dashboard identity is.

API key. Pass a tenant key as a Bearer token:

Authorization: Bearer op_live_…

In both cases the server calls Openprovider with your tenant's own stored reseller credentials; the token or key you present is never forwarded upstream.

Usage examples

Ask your assistant things like:

"Check if acme-rockets.com and acme-rockets.io are available, with prices."

"List my DNS zones and show the records for example.com."

"Suggest 10 domain names for a coffee subscription startup."

"Renew example.com for 1 year." — this one is billable, so read on.

The approval flow (billable / destructive operations)

Operations that cost money or destroy data (register, renew, transfer, delete domain, SSL orders, Plesk licenses, …) do not execute immediately. Instead the tool returns a confirmation request:

{
  "confirmationId": "1f0c5e2e-…",
  "summary": "renew_domain (est. €12.50)",
  "estimatedCostEur": 12.5,
  "requiredApproverRoles": ["owner", "admin"],
  "expiresAt": "2026-06-11T10:30:00.000Z"
}

An owner or admin then approves it, either:

Confirmations expire after 5 minutes, are single-use, are bound to the exact arguments that were proposed, and re-check the live price at approval time — if the price drifted upward beyond tolerance, the confirmation is rejected and must be re-proposed.

Spend caps

Each tenant has a monthly spend cap in EUR (default €0 — all billable operations blocked until an owner raises it). Set it from the dashboard Policy page. Approved operations reserve against the cap atomically, so concurrent approvals cannot overshoot it.

Limits to know

Limit Value
check_domain batch size 15 domains per call (Openprovider rejects more)
Confirmation TTL 5 minutes
Default spend cap €0 (raise it before billable operations)
Request timeout to Openprovider 30 s with automatic retry on 5xx/429

Troubleshooting

401 Unauthorized / tools don't load If you signed in with your browser, the token expired or was revoked — re-run the client's login (in Claude Code, /mcp) to sign in again. If you use an API key, it is missing, revoked, expired, or mistyped; issue a fresh one from the dashboard and update your client config (the plaintext is shown only once).

policy_denied / tool_not_permitted Tenant policy denies this tool for your role, or you're a viewer/auditor attempting a write. An owner can adjust tool modes on the Policy page.

spend_cap_exceeded The estimated cost would exceed the monthly cap. Raise the cap on the Policy page or wait for the window to reset.

confirmation_expired / confirmation_not_found Confirmations are single-use and expire after 5 minutes. Re-run the original request to get a fresh confirmation.

openprovider_not_connected The tenant has no Openprovider credentials onboarded. Connect them from the dashboard Openprovider page.

upstream 500: {"desc":"Access denied.","code":10005} Openprovider rejected the call at their edge — typically an IP allowlist on the Openprovider account that doesn't include the server's egress IP, or account-level API restrictions. Verify the Openprovider account's API settings.

Claude Desktop shows no tools after config change Fully quit the app (macOS: Cmd-Q) and relaunch — the config is read only at startup. Then check ~/Library/Logs/Claude/mcp*.log for connection errors.

Claude Desktop shows "Couldn't start… Request timed out" during browser sign-in Claude Desktop gives a bridge process about a minute to start, and mcp-remote holds startup until the browser sign-in and consent are done. A normal sign-in takes longer than that, so Desktop marks the server failed and restarts the bridge — which also bounces the browser tab back to the sign-in page. The sign-in itself is fine; the badge is just stale. Avoid it by signing in once from a terminal before launching Desktop (see Setup: Claude Desktop), or by using the built-in Add custom connector instead of the bridge.

SSE disconnect / reconnect noise in mcp-remote logs Long-idle SSE streams may be dropped by intermediate proxies and re-established automatically. Harmless as long as tool calls succeed.

Resources