Auth model
Every tool call to the Lev MCP server is validated against an Auth0-issued RS256 JWT. When you install the server via Claude Code, Claude Desktop, or Cursor, OAuth is already wired up — you sign in once and the client handles tokens from there.
The OAuth flow
The first tool call triggers a standards-compliant OAuth 2.0 authorization-code flow. Clients discover the server's authorization metadata — you never configure it by hand.
- Discover the authorization server
The client fetches
<mcp-server-url>/.well-known/oauth-authorization-serverto learn the authorize, token, and JWKS endpoints.The client knows the authorize, token, and JWKS endpoints. - Start the authorize request
The client opens the browser to Auth0's hosted login page with a PKCE challenge and a redirect URI that points back at the client.
Auth0's login page opens for the user. - Handle the callback
After the user signs in, Auth0 redirects back to the client with an authorization code.
The client receives an authorization code. - Exchange the code for tokens
The client trades the code for an RS256-signed access token and a refresh token.
The client holds an access token (JWT) and a refresh token. - Call tools with the JWT
Every subsequent MCP request includes
Authorization: Bearer <jwt>— the server validates the signature, expiry, audience, and issuer against the JWKS it discovered from Auth0.Every request is authenticated against the JWT discovered from Auth0. - Refresh silently
When the access token expires, the client uses the refresh token to get a new one. No user action required.
The session continues without prompting the user.
You should now have a client that can call Lev MCP tools without ever prompting you for credentials again.
Your MCP client handles discovery, code exchange, storage, and refresh. Do not set Authorization headers manually.
Programmatic session provisioning
Some trusted service integrations can provision MCP access server-side without sending a user through the interactive OAuth prompt. This flow is not part of the public API surface and is not available with standard user API keys or JWTs.
Contact Lev if your integration needs server-side MCP provisioning. We will review the deployment model, account scoping, permissions, audit requirements, and key rotation plan before enabling access.
Scopes and permissions
The OAuth flow requests two scopes from Auth0:
The scopes above are what the server asks Auth0 for. What tools you can actually call depends on your Lev account permissions. The MCP server never elevates privileges — every call downstream to lev-backend is scoped to your live role.
That means:
- A
403on a tool means your Lev user does not have access to the resource, not that the MCP server misrouted the call. - A role change in Lev takes effect on the next tool call. The server does not cache authorization decisions.
To see what a given session actually has access to, call get_my_profile. It returns your user record, active account, available accounts, subscription status, and any platform-level scopes granted to the session.
Headers sent to Lev
Every call the MCP server makes to lev-backend carries a predictable header set. You do not need to set these — they are listed so you can spot them in traces and logs.
The MCP server does not pass an X-Active-Account header. When you call switch_account, the server issues a PATCH /me/active-account to lev-backend, which persists your active-account preference. Every subsequent request (from any client using the same credentials) is automatically scoped to that account until you switch again.
Switching accounts
Some Lev users belong to more than one account — a brokerage and a lender, for example. The MCP server supports switching between them without ending the session.
How to switch
Ask the client in plain language, for example: "Switch my Lev account to Broker Magicians." The client calls the switch_account tool with the name or slug, which persists your active-account preference server-side via PATCH /me/active-account. Subsequent tool calls scope to that account automatically.
List available accounts
Call list_available_accounts to return every account you can switch to. Use this when you are not sure of the exact slug to pass to switch_account.
Next: MCP Errors & Limits — error codes, rate limits, and known gaps at the tool layer.