Cursor
.cursor/mcp.json, OAuth Connect, API key, and the install deeplink
Project file: .cursor/mcp.json. Global file: ~/.cursor/mcp.json. Both use a top-level mcpServers object. Project wins on name clash.
Org must be Pro (or trial). The connecting user must be an active admin with TOTP enrolled.
OAuth (recommended)
URL-only config. Cursor runs dynamic client registration (DCR) + PKCE on first Connect:
{
"mcpServers": {
"servicebay": {
"url": "https://oauth.servicebay.io/mcp"
}
}
}- Save the file (project or global).
- In Cursor → Settings → MCP, click Connect / Authenticate on
servicebay. - Complete the Servicebay consent screen in the browser.
Cursor's desktop DCR registers one or more of these redirect URIs (Servicebay accepts all of them):
| Redirect | When |
|---|---|
http://localhost:8787/callback | Preferred loopback when port 8787 is free |
cursor://anysphere.cursor-mcp/oauth/callback | Fallback when 8787 is busy (e.g. wrangler dev) |
https://www.cursor.com/agents/mcp/oauth/callback | Cursor Agents / web |
You do not put redirect URIs in mcp.json. Cursor sends them during DCR.
If Connect fails with redirect_uris must be… / invalid_client_metadata, the OAuth Worker is still on a build that required application_type: native for custom schemes — Cursor omits that field. Deploy the Worker that allows non-reserved custom schemes (still rejects http:// non-loopback). Until then, use a static API key below.
Static confidential client (optional)
Pin a pre-registered client from the developer portal. Allowlist at least http://localhost:8787/callback and https://www.cursor.com/agents/mcp/oauth/callback (and cursor://anysphere.cursor-mcp/oauth/callback if your client tool accepts custom schemes):
{
"mcpServers": {
"servicebay": {
"url": "https://oauth.servicebay.io/mcp",
"auth": {
"CLIENT_ID": "your-client-id",
"CLIENT_SECRET": "your-client-secret"
}
}
}
}Static key
Skip OAuth entirely. Create a key in the portal with allowedUses including mcp, then:
{
"mcpServers": {
"servicebay": {
"url": "https://oauth.servicebay.io/mcp",
"headers": {
"Authorization": "Bearer ${env:SERVICEBAY_KEY}"
}
}
}
}${env:NAME} interpolates in url and headers. The variable must be visible to the Cursor desktop process (not only your shell rc).
Deeplink
Same shape the portal emits (src/lib/mcp/client-snippets.ts):
cursor://anysphere.cursor-deeplink/mcp/install?name=servicebay&config=BASE64config is Base64 of {"url":"https://oauth.servicebay.io/mcp"}.