MCP authentication
Connect Claude, ChatGPT, Cursor, VS Code and Claude Code to your Graine workspace by signing in with Graine — no key to paste — or with an API key for clients that send headers.
Graine's MCP server lets an AI app work in your workspace. There are two ways to let it in:
- Sign in with Graine — the app sends you to Graine, you sign in and allow it, and you're done. Nothing to copy, nothing to rotate. Use this whenever your app supports it: claude.ai, Claude Desktop, ChatGPT, Cursor, VS Code and Claude Code all do.
- An API key in a request header — for clients that can't sign in, and for scripts. See Use an API key instead.
| Server URL | https://api.graine.ai/v2/mcp |
| Sign in | OAuth 2.1 with PKCE. The app registers itself; there is no client ID or secret to enter |
| Or a key | Authorization: Bearer gat_… |
How signing in works
- Add
https://api.graine.ai/v2/mcpto your AI app as a remote MCP server. - The app opens Graine in your browser. Sign in if you aren't already.
- Graine shows what is asking — the app's name, the workspace, the role it will act with, and the address it sends you back to. Choose Allow.
- You're returned to the app, which is now connected. It keeps its own access up to date while you use it; you don't sign in again unless it goes unused for 30 days or you revoke it.
What a connected app can do
A connected app acts as you, in the one workspace you allowed it in:
- It can do what you can do, and no more. Your role applies — Admin, Member, View only or a custom role (Keys and workspace roles). If you have View only access, the app can only read.
- If you're limited to some agents, so is the app.
- Changes still follow your workspace's approval rules: a change that would need an admin's approval from you needs it from the app too.
- It can never create or revoke API keys.
- If your role changes, the app follows within the hour. If you leave the workspace, the app stops within the hour.
Check where it sends you
An app names itself. Before you choose Allow, check the address on the
consent screen — claude.ai, chatgpt.com, or an address on your own
computer such as 127.0.0.1 for a desktop app you just started connecting. If
you didn't start connecting an app, choose Deny.
To connect an app to a different workspace, switch to that workspace in Graine first, then connect again.
Connect your AI app
Claude (claude.ai and Claude Desktop)
Connectors you add in Claude work in claude.ai, Claude Desktop and Claude on mobile.
- Open Customize → Connectors, choose + Add, then Add custom connector.
- Name it
Graineand enterhttps://api.graine.ai/v2/mcp. - Keep the sign-in settings Claude detects. Leave the OAuth client ID and secret empty: Claude registers itself.
- Choose Add, then Connect, and allow it in Graine.
On Team and Enterprise plans, an Owner adds the connector once under Organization settings → Connectors; then each person opens Customize → Connectors, finds Graine and chooses Connect. Each person connects as themselves, with their own role.
ChatGPT
Add Graine as a custom MCP server in ChatGPT's settings for apps. Your workspace admin may need to allow custom servers first.
- Enter
Graineas the name andhttps://api.graine.ai/v2/mcpas the server URL. - Choose OAuth for authentication. Leave any client ID and secret empty.
- Create it. ChatGPT opens Graine; sign in and choose Allow.
Cursor
Add Graine to ~/.cursor/mcp.json for every project, or .cursor/mcp.json in
one project:
Open Cursor's MCP settings, where Graine asks you to sign in. Choose to sign in, and allow it in Graine.
VS Code
Add Graine to .vscode/mcp.json in your workspace (or run MCP: Add Server
and choose HTTP):
Start the server. VS Code asks whether Graine may sign you in; allow it, then allow the connection in Graine.
Claude Code
Then run /mcp in Claude Code, choose Graine and choose Authenticate.
Add --scope user to the first command to use Graine in every project.
Other MCP clients
Any client that supports MCP authorization signs in the same way: give it
https://api.graine.ai/v2/mcp and it finds the rest. A client that only runs
local servers can reach Graine through mcp-remote, which signs in for it —
for example in Claude Desktop's claude_desktop_config.json (it needs Node.js):
Manage connected apps
Every app you've connected is listed under API keys → Connected apps, with
the address it signs in from, the role it acts with and when it was last used.
People with View only access, who don't see API keys, find their own at
/api-key/connected-apps in the dashboard.
- Revoke stops the app within seconds: it can't read or change anything until someone connects it again.
- Admins see every person's connected apps and can revoke any of them.
- Connecting the same app again replaces the earlier connection — one per app per person.
- Removing the app in the AI app (or signing out there) also ends the connection, when the app tells Graine.
Every connection and revocation is in the workspace's activity log, with who did it.
Use an API key instead
Use a key for a client that can't sign in, or for a script. The key acts with the role of the person who created it, within its scopes (Mint a key, Scopes). Keep it out of shared files, and revoke it if it leaks.
Cursor:
VS Code, asking for the key once instead of storing it in the file:
Claude Code:
Claude Desktop, through mcp-remote:
For developers of MCP clients
Graine follows the MCP authorization specification. A request to the server
without credentials is answered 401 with a pointer to the server's
protected resource metadata, which names Graine's authorization server.
| Protected resource metadata | https://api.graine.ai/.well-known/oauth-protected-resource/v2/mcp (also at /.well-known/oauth-protected-resource) |
| Authorization server | https://www.graine.ai — metadata at /.well-known/oauth-authorization-server |
| Authorization endpoint | https://www.graine.ai/oauth/authorize |
| Token endpoint | https://www.graine.ai/api/oauth/token |
| Registration endpoint | https://www.graine.ai/api/oauth/register (dynamic client registration) |
| Revocation endpoint | https://www.graine.ai/api/oauth/revoke |
| Resource | https://api.graine.ai/v2/mcp |
| Scope | workspace — act as the person who signs in |
What the authorization server expects:
- Public clients. Register with dynamic client registration; the answer
is a
client_idwithtoken_endpoint_auth_method: "none"and no secret. Unused registrations are removed after a week; an unknownclient_idat the token endpoint is401 invalid_client, which means register again. - Redirect URIs must be
https, or plainhttpto127.0.0.1,[::1]orlocalhost. A loopback address matches on any port; every other address must match exactly. Other schemes are left out of a registration. - Authorization code with PKCE.
code_challenge_method=S256is required. A code is good once, for 60 seconds, and only with theredirect_uri, client and verifier of its request. resourceishttps://api.graine.ai/v2/mcpwhen sent, in both the authorization and the token request.scopeisworkspace;offline_accessis accepted alongside it.- Every authorization response carries
iss— the issuerhttps://www.graine.ai, errors included. - Errors before anyone signs in (a missing
code_challenge, an unknownscope) go straight back to an app on the person's computer — a loopback redirect URI. Any other app's error is shown to the person with a link back to the app, so a link to Graine can never send someone's browser to a site they didn't choose. - Tokens. Access tokens are bearer tokens that last an hour; treat them as opaque. Each refresh returns a new refresh token, and the old one stops working. A refresh token lasts 30 days from when it was issued. Presenting a refresh token that was already used ends the connection — the person has to sign in again.
- Errors are the standard OAuth ones (
invalid_grant,invalid_request,invalid_client,invalid_scope,invalid_target,temporarily_unavailable). Afterinvalid_granton a refresh, start a new sign-in. - Revocation takes the refresh token or the access token; either ends the connection.

