Documentation
Connect Claude / Cursor via MCP
ReliPay hosts two MCP server surfaces, both reachable from Claude Desktop / Claude Code / Cursor:
- Per-Application end-user MCP at
/api/v1/mcp/<slug>— end-users sign into your app via OAuth 2.1 + PKCE and read their own account data through four tools. Full RFC stack: RFC 8414 + RFC 9728 + RFC 7591. Every MCP client that ships generic OAuth discovery connects without custom code. - Operator MCP at
/api/v1/tenant/mcp— the workspace operator's view of their own data: applications, end-users, payments, webhooks, security events. Two auth paths: OAuth 2.1 + PKCE with a workspace picker at consent (the same RFC stack as per-Application MCP), or Bearer with an operator personal-access-token (rp_op_…) for headless automation.
Three-minute quickstart
- Enable MCP on an Application. Go to the operator panel → Applications → pick one → MCP tab → toggle MCP enabled. Copy the displayed MCP URL —
https://api.relipay.dev/api/v1/mcp/your-app. - Add it to your MCP client. Easiest path is Claude Code:
claude mcp add --transport http your-app https://api.relipay.dev/api/v1/mcp/your-app
- Sign in. On first tool call, Claude opens a browser tab pointing at your ReliPay app's login page. The end-user signs in with the credentials they normally use to access the app, approves the consent screen, and the tools become available.
What MCP gives you
An MCP server is a typed-tool surface an AI agent can call. ReliPay's hosted MCP server is per-Application — the same user database, the same auth methods, the same plans + credits + licenses your customers already have. The agent sees a slice scoped to one authenticated end-user.
The four tools are deliberately narrow + read-only — listing balances and entitlements, not modifying them. Writes happen through your normal app surface; MCP is for telling an agent about the user's state.
Per-Application MCP URL
Every Application gets its own MCP endpoint, derived from its slug:
https://api.relipay.dev/api/v1/mcp/your-app
That URL is the only thing you ever hand to a client. It serves both the MCP JSON-RPC endpoint and the OAuth Authorization Server under the same hostname; clients auto-discover everything else.
Connect from Claude Code
The Claude Code CLI registers the server in your global ~/.claude.json and handles the OAuth flow on first use.
claude mcp add --transport http your-app https://api.relipay.dev/api/v1/mcp/your-app
No further config needed — the --transport http flag is the load-bearing part; it tells Claude Code to expect the 401 → OAuth-discovery handshake instead of the stdio process protocol.
Connect from Claude Desktop
Edit your Claude Desktop config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"your-app": {
"type": "http",
"url": "https://api.relipay.dev/api/v1/mcp/your-app",
"oauth": {
"authServerMetadataUrl": "https://api.relipay.dev/api/v1/mcp/your-app/.well-known/oauth-authorization-server"
}
}
}
}Restart Claude Desktop. The OAuth flow opens in your browser; sign in, approve, and the four tools appear in the MCP server's tool list.
The oauth.authServerMetadataUrl field is technically redundant when discovery from the resource works — but pinning it explicitly bypasses the well-known cascade, which helps when your deployment runs the API behind an unusual path or reverse proxy.
Connect from Cursor
Cursor uses the same shape; drop the same block into ~/.cursor/mcp.json and restart Cursor.
Connect a custom Claude connector
In Claude (web/desktop) go to Settings → Connectors → Add custom connector and paste the MCP URL:
https://api.relipay.dev/api/v1/mcp/your-app
Claude reads the protected-resource metadata from the 401 challenge, walks the discovery chain, runs the OAuth flow, and connects.
OAuth flow, step by step
For tooling that doesn't ship a generic OAuth-discovery flow, here's what the supported MCP clients do automatically. All of it is standard OAuth 2.1 + PKCE; no ReliPay-specific quirks.
1. Discover
curl https://api.relipay.dev/api/v1/mcp/your-app/.well-known/oauth-authorization-server
Returns RFC 8414 metadata pointing at the authorize / token / register / introspect endpoints under the same MCP URL.
2. Register dynamically (RFC 7591)
curl -X POST https://api.relipay.dev/api/v1/mcp/your-app/oauth/register \
-H 'Content-Type: application/json' \
-d '{
"client_name": "My Local Tool",
"redirect_uris": ["http://localhost:55123/callback"]
}'You get back { client_id, redirect_uris, token_endpoint_auth_method: "none" }. No client secret — PKCE replaces it.
3. Authorize
Build the authorize URL:
https://api.relipay.dev/api/v1/mcp/your-app/oauth/authorize\n ?response_type=code\n &client_id=<from-register>\n &redirect_uri=http://localhost:55123/callback\n &code_challenge=<sha256-of-verifier>\n &code_challenge_method=S256\n &scope=mcp:account\n &state=<random>
Open it in the user's browser. They sign into your ReliPay Application, approve the consent screen, and the AS redirects to your redirect_uri with ?code=…&state=….
4. Exchange the code for a token
curl -X POST https://api.relipay.dev/api/v1/mcp/your-app/oauth/token \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=authorization_code' \ -d 'code=<from-redirect>' \ -d 'code_verifier=<your-pkce-verifier>' \ -d 'client_id=<from-register>' \ -d 'redirect_uri=http://localhost:55123/callback'
You get back { access_token, refresh_token, token_type: "Bearer", expires_in, scope }. The access token is JWT-signed (you don't need to parse it; the MCP endpoint validates it on every call).
5. Call tools
curl -X POST https://api.relipay.dev/api/v1/mcp/your-app \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'6. Refresh on expiry
Repeat step 4 with grant_type=refresh_token and your refresh_token. The old refresh token is rotated out atomically; replay is rejected.
Tools reference
All four tools are zero-argument; they always operate on the user authenticated by the access token. None require parameters from the agent.
- get_profile
Email, role, verification status, and the metadata your app stored on the user.
Returns:
{ id, email, emailVerified, role, metadata, createdAt } - get_subscription
The user's current subscription (ACTIVE or PAST_DUE) and the linked Plan, or null.
Returns:
{ status, provider, currentPeriodEnd, cancelAt, plan: { slug, name, interval, amount, currency } } | null - get_credits
Prepaid credit balance for the user (unit-less; the app defines what a credit means).
Returns:
{ balance: number } - list_licenses
Issued licenses for the user (PERPETUAL / TIMED / SEATS). License keys are NEVER returned.
Returns:
{ licenses: Array<{ id, kind, status, seatsAllowed, expiresAt, createdAt }> }
Tools never return license keys, password hashes, provider credentials, or any other Application's data. The session is scoped to (applicationId, endUserId) — a token issued for app A can't read app B.
Security model
- PKCE mandatory.
code_challenge_method=S256is the only accepted value; clients without PKCE fail at/authorize. - Public clients only. Dynamic registration returns
token_endpoint_auth_method: "none"; PKCE is the replacement for a client secret. No secret to leak. - Redirect URI allowlist.
https://,http://localhost, and custom schemes (e.g.claude://) are accepted.ftp://,file://, and bare HTTP to a non-localhost host are rejected at registration time. - Audience-bound tokens. Each token is signed with
aud = <mcp-url>; replaying a token issued for app A against app B's MCP endpoint fails verification. - Per-Application kill switch. The operator can bump an Application's
tokenGenerationfrom the panel to invalidate every issued MCP token instantly. Clients see 401 and re-run the flow. - Read-only surface. The four tools never mutate. Writes happen through your normal app surface, where you control authorization end-to-end.
Operator MCP (workspace view)
Per-Application MCP exposes the end-user's data. The operator MCP at https://api.relipay.dev/api/v1/tenant/mcp exposes the operator's workspace — applications, end-users, payments, webhook health, security events.
Two auth paths, pick whichever fits the client:
- OAuth 2.1 + PKCE (recommended for Claude Desktop, Code, Cursor, custom connectors). Operator clicks Connect → browser opens → signs in with panel email + password → picks a workspace at consent → tokens minted. No PAT to paste; full RFC 8414 / 9728 / 7591 discovery.
- PAT-Bearer (for headless automation / non-browser clients). Mint a
rp_op_…token in panel → Account → API tokens and paste it into the client'sheaders.Authorizationfield. The PAT is bound to one workspace at mint time.
OAuth mcp.json snippet
{
"mcpServers": {
"relipay-operator": {
"type": "http",
"url": "https://api.relipay.dev/api/v1/tenant/mcp",
"oauth": {
"authServerMetadataUrl": "https://api.relipay.dev/api/v1/tenant/mcp/.well-known/oauth-authorization-server"
}
}
}
}PAT-Bearer mcp.json snippet
{
"mcpServers": {
"relipay-operator": {
"type": "http",
"url": "https://api.relipay.dev/api/v1/tenant/mcp",
"headers": {
"Authorization": "Bearer rp_op_<paste-your-token-here>"
}
}
}
}Tools the operator can call
get_workspace_overview— counts, MRR per currency.list_applications/list_members.recent_payments/recent_subscriptions(status filter).recent_security_events(actorType filter — operator / end_user / system).recent_webhook_events(provider, onlyFailed) /recent_failed_webhook_deliveries.application_health— per-app payment success rate (30d) + outbound webhook success rate (24h), sorted by failure count.
Read-only. Membership is re-checked on every request; removing the operator from the workspace invalidates the PAT immediately. lastUsedAt on each PAT advances on every successful call.
OAuth endpoints
https://api.relipay.dev/api/v1/tenant/mcp/.well-known/oauth-authorization-server— RFC 8414 metadatahttps://api.relipay.dev/api/v1/tenant/mcp/.well-known/oauth-protected-resource— RFC 9728POST /oauth/register(RFC 7591),GET/POST /oauth/authorize(login + workspace picker + consent),POST /oauth/token(auth-code + refresh),POST /oauth/introspect(RFC 7662)
Scope: mcp:operator:read (the only scope today). Access token: 1h. Refresh token: 30d, hash-only, rotated on redeem.
Self-hosting
The MCP server ships in apps/api — there's no separate process to run. Once your API is reachable on a public URL, set PUBLIC_WEBHOOK_BASE_URL to that origin (the same env var that anchors webhook routes), and the MCP issuer URL is derived automatically. Enable MCP on the Application from the panel and you're done — no extra ports, no extra container, no extra deploy.
Troubleshooting
WWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource" on unauthenticated calls. If your client doesn't honour the hint, paste the discovery URL into oauth.authServerMetadataUrl in your mcp.json.code_challenge_method=S256) or response_type isn't code. Both are mandatory.redirect_uri you intend to use. The AS compares character-for-character.tokenGeneration (per-app kill switch). Re-run the flow.Further reading
- Interactive API reference — the REST surface MCP is built on.
- Back to docs index
- modelcontextprotocol.io — the upstream MCP spec.
- RFC 8414 authorization-server metadata, RFC 9728 protected-resource metadata, RFC 7591 dynamic client registration.