Log in with Didit
The hosted server (https://mcp.didit.me/mcp) is an OAuth 2.1 resource server. The Didit Business Console (business.didit.me) is the authorization server that hosts the consent screen and issues tokens. Your MCP client drives the standard flow automatically:
1
Discover
The client posts to That document names the resource (
/mcp without a token and gets 401 with a WWW-Authenticate: Bearer header whose resource_metadata points at the protected-resource metadata (RFC 9728):https://mcp.didit.me/mcp), the authorization server (https://business.didit.me) and the supported scopes. The same document is also served at the origin root, https://mcp.didit.me/.well-known/oauth-protected-resource, for clients that probe there first.2
Register (dynamic client registration)
The client reads the authorization server’s metadata at
https://business.didit.me/.well-known/oauth-authorization-server and, if it has no client id yet, registers itself at the registration_endpoint (RFC 7591). There is nothing to pre-provision on your side: local clients with a loopback or native callback (Claude Code, Cursor, MCP Inspector) and cloud-hosted clients with a reviewed callback (Claude) both register this way. A remote callback URL Didit has not reviewed is refused with invalid_redirect_uri; that client needs an operator to register it first.3
Authorize (PKCE)
The client opens
https://business.didit.me/authorize with an S256 PKCE challenge. You sign in (or register) and see exactly which permissions are requested. Clients are public: the token endpoint accepts no client secret (token_endpoint_auth_methods_supported is none), so PKCE is what binds the code to the client.4
Consent
You approve. The console mints a session for that app, bound to the scopes you approved, and returns an authorization code, which the client exchanges at the
token_endpoint for an access token and a refresh token.5
Call tools
The client sends the access token with every request. The MCP validates it with RFC 7662 token introspection against the Didit auth service (the tokens are opaque, not JWTs), reads your organization permissions from the introspection response, and acts as you for the duration of that request.
Scopes
The resource metadata advertises three scopes. The consent screen shows the ones a client asks for in plain language:
Both scopes include
analytics. Managing lists requires didit:management; accessing blocklist requires didit:verification.
The tools reference lists the scope each tool falls under. The scopes you approve are carried on the token and enforced server-side, so an app connected with didit:verification alone is refused on the management surface even when your own role would allow it. The authorization server also knows the OpenID scopes (openid profile email); a connection that requests only those can tell who you are and nothing else.
An app’s effective permissions are the intersection of the approved scopes and your console role — never the wider of the two.
To create a verification session with didit_session_create, you need the didit:verification scope and a role with create:sessions or write:sessions. The Developer role includes create:sessions. Approving didit:management alone does not allow session creation, even if your role has the required permission.
Roles and permissions
The hosted token represents you, so the agent can work across every organization you belong to in a single connection — the cross-app tools (didit_session_search, didit_analytics, didit_context_get, and the other *_search tools) aggregate over all of them automatically.
Your role is always enforced by the Didit backend, per organization. Each tool maps to one backend permission string (for example write:sessions for didit_session_update_status, delete:sessions for didit_session_delete); the tools reference shows it per tool. The server also checks that permission before it sends the request, using the permissions the introspection response carries for your organization:
- In
enforcemode a tool your role cannot run is left out oftools/list, and calling it anyway returns amissing_scopeerror that names the permission ("Your role in this organization does not include the permission 'delete:sessions' that didit_session_delete requires."). - In
shadowmode (the server default) every tool is listed and the call goes through to the backend, which answers403when the role lacks the permission; the verdict is only recorded in the server’s audit log.
READER can list and read; an OWNER or ADMIN can write and delete.
Token lifetime
An approved app gets its own session, separate from the browser session you approved it from. Access tokens are short-lived; the client refreshes them silently with the refresh token (grant_types_supported includes refresh_token), and a refresh keeps the app’s scopes and stays bound to that app. If a refresh fails (for example after you disconnect the app), the client re-runs Log in with Didit on the next call.
Signing out of the console does not sign out connected apps, and disconnecting an app never signs you out anywhere.
Disconnecting an app
1
From the console
Settings → Authentication → Connected apps lists every app you have approved, with its registered name and the permissions it was granted. Disconnect ends that app’s access immediately: both its access token and its refresh token stop working, and nothing else is affected.
2
From the app (RFC 7009)
A client can hand its own access back by posting the token to the authorization server’s
revocation_endpoint, advertised in the metadata at https://business.didit.me/.well-known/oauth-authorization-server. As RFC 7009 requires, a successful call answers 200 whether or not the token was still live, so the response never tells you whether a token was valid. A 503 means the revocation could not be applied: treat the token as still valid and retry.Why no API key? Every MCP tool calls the user-scoped console endpoints (
/organization/{org}/application/{app}/…), which authorize a Bearer token with per-role privileges and reject x-api-key. An application API key is for calling the REST API directly from your own backend (e.g. creating sessions) — not for this MCP. didit_org_list_api_keys shows key metadata with the values redacted; the tool that reveals a raw key is hidden on the hosted connector.Connecting from each client
Every client runs the same flow; only the way you give it the URL differs.- Claude
- Claude Code
- Cursor
- Generic client
Use the deep link the Business Console shows on its integrate page. It opens claude.ai with the Add custom connector dialog pre-filled:Confirm, then complete Log in with Didit. Claude Desktop uses the same URL under Settings → Connectors → Add custom connector. Details on Connect Claude.
Auth failures
401 from /mcp means the token is missing, expired or was revoked — the client should refresh or re-run Log in with Didit.
A 403 or a missing_scope error on a specific tool usually means either your role lacks that permission (e.g. a READER attempting a write) or the connection was approved without the scope that tool needs — not that the whole connection is broken. Reconnecting and approving both scopes fixes the second case; the first needs a role change.
If every tool fails, check Settings → Authentication → Connected apps in the console: an app that was disconnected there has to be approved again.
Tools reference
What each tool does, its scope and its role permission.
Advanced
Roles, cross-app behavior, and self-hosting.