Other clients

Claude is the supported client and the one the quickstart covers. Any MCP client that speaks Streamable HTTP with OAuth can connect to the same endpoint, and broader first-class support is on the way.

What every client needs

All of them point at the same URL and let OAuth do the rest:

MCP endpoint
https://opzero.sh/mcp

Transport is Streamable HTTP. Clients discover the authorization server from /.well-known/oauth-protected-resource, register themselves dynamically, and run OAuth 2.1 with PKCE. There is no client ID to obtain and nothing to configure by hand.

Claude Code

Add it once from the terminal, then complete the browser flow from the /mcp command inside Claude Code:

Terminal
claude mcp add --transport http opzero https://opzero.sh/mcp

Claude Code re-lists tools every session, so it sees changes to your gateways and hosted servers immediately — unlike hosts that cache a tool snapshot.

Claude Desktop

Use the same Settings → Connectors → Add custom connector flow as claude.ai, with the endpoint above. Desktop and web share your connector list, so connecting in one usually means it is already there in the other.

Cursor

In Settings → MCP → Add new server, add an HTTP server pointing at the endpoint. Cursor opens the OAuth flow on first use:

~/.cursor/mcp.json
{
  "mcpServers": {
    "opzero": {
      "url": "https://opzero.sh/mcp"
    }
  }
}

OpenAI Codex

Codex supports remote MCP servers over Streamable HTTP:

~/.codex/config.toml
[mcp_servers.opzero]
url = "https://opzero.sh/mcp"

Then authorize with codex mcp login opzero and confirm with codex mcp list. See the Codex MCP docs for the current syntax.

Raw HTTP

The endpoint is plain JSON-RPC 2.0 over HTTPS, so anything that can POST can drive it. Discovery and listing work like this:

List the available tools
curl -X POST https://opzero.sh/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPZERO_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list"
  }'
Call one
curl -X POST https://opzero.sh/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPZERO_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "deploy_markdown",
      "arguments": { "markdown": "# Hello\n\nShipped from curl." }
    }
  }'

The bearer token is whatever OAuth issued you. Access tokens are short-lived — one hour — so a script that runs unattended needs either the refresh token or the API key below.

Discovery endpoints

Useful when you are debugging a client that will not connect:

EndpointReturns
/.well-known/oauth-protected-resourceRFC 9728 metadata — the resource URL, the authorization server, supported scopes.
/.well-known/mcp.jsonThe server card: endpoint, transport, protocol version, auth config.
/.well-known/oauth-authorization-serverAuthorization server metadata for the OAuth flow.

API keys (secondary)

OAuth is the way OpZero is meant to be used, and every interactive client supports it. API keys exist for the narrower case where no browser is available to complete a flow — a CI job, a cron script, a server-side integration.

Create one in your dashboard. It is shown once, at creation. Present it exactly like an OAuth token:

Authorization header
Authorization: Bearer YOUR_API_KEY
Prefer OAuth wherever it fits
An API key is a long-lived credential with full access to your account, and it does not expire on its own. OAuth tokens last an hour and refresh automatically, and you can revoke a single client’s grant without disturbing the others. If a browser can complete the flow, use OAuth.
Next
Troubleshooting

When tools do not appear, calls fail, or auth goes sideways.