MaiAgent as an OAuth Authorization Server
Connect MCP clients such as Claude to MaiAgent MCP with OAuth 2.1 (authorization code + PKCE) — endpoints, application registration, Redirect URIs, token lifetimes and rotation, and the actual effect
MaiAgent includes a built-in OAuth 2.1 authorization server. MCP clients such as Claude can connect to MaiAgent MCP through OAuth without pasting an API Key into a configuration file. After a member signs in through a browser and grants authorization, the client receives a short-lived access token and operates MaiAgent as that member. This page is for customer IT teams enabling employees to connect to MaiAgent from MCP clients with their own accounts, and developers whose services need to call MaiAgent as a member.
This page describes tokens issued by MaiAgent. For the reverse direction, where MaiAgent connects to third-party OAuth services, see OAuth 2.0 Integration and Automatic Token Refresh.
Choosing OAuth or an API Key
Identity represented
The member who grants authorization
The member associated with the key
Credential delivery
The member signs in through a browser and consents, without handling secrets
Copy the key into client settings
Lifetime
Access token lasts 1 hour; the client refreshes it automatically
Based on the key's expiration setting; can be set to never expire
Permissions
Same as the member's role; scopes impose no additional restrictions (see Actual Effect of Scopes)
Same as the member's role
Members who only sign in through SSO and have no MaiAgent password currently cannot complete OAuth authorization (see Login and Consent). Use an API Key for these members.
Endpoints
The SaaS authorization server is https://api.maiagent.ai. For on-premises and private cloud deployments, replace it with your organization's platform domain. Metadata URLs are generated from the domain used in the request.
Authorization server metadata (RFC 8414)
GET /.well-known/oauth-authorization-server
Authorization
GET /o/authorize/
Token exchange
POST /o/token/
Token revocation (RFC 7009)
POST /o/revoke_token/
The capabilities advertised in the metadata match the actual behavior:
response_types_supported
code
grant_types_supported
authorization_code, refresh_token
code_challenge_methods_supported
S256
token_endpoint_auth_methods_supported
none, client_secret_basic, client_secret_post
scopes_supported
read, write
MaiAgent does not support Dynamic Client Registration; its metadata has no registration_endpoint. MCP clients must support entering a preregistered Client ID. Register an application in your organization as described in the next section first.
Register an OAuth application in your organization
In the admin interface, go to Organization Settings → Organization Overview → Management Actions → OAuth Applications to create an application and obtain its Client ID. The Connection Information card lists the Discovery, Authorize, and Token endpoints. For creation steps, management permissions, and saving or regenerating a Client Secret, see OAuth Applications in the user manual. Keep the following in mind when integrating:
The application type cannot be changed after creation: Public is for MCP clients (such as Claude), uses PKCE, and receives no client secret. Confidential is for server-side integrations and receives a client secret.
Regenerating a Client Secret immediately invalidates the old secret but does not affect issued tokens. Deleting an application immediately invalidates all tokens for every member connected through it.
Each organization can have up to 20 OAuth applications.
The same functionality is available through the API:
/api/v1/oauth/applications/(GET, POST, PATCH, DELETE, plusPOST …/{id}/regenerate-secret/), with the same permission rules as the admin interface.
Redirect URI rules
Exact matching: The scheme, host, port, and path must all match; wildcards are not supported. If the registered URI includes query parameters, the authorization request must include them too.
Only
https://is accepted.http://is allowed only for local callbacks:localhost,127.0.0.1, and::1.Local callback ports: If you register
http://127.0.0.1/…orhttp://[::1]/…, the authorization request can use any port (RFC 8252). If you registerhttp://localhost:<port>/…, the port must match exactly. For local MCP clients that choose a random port each time, register the127.0.0.1form.For web-based MCP clients, use the callback URL specified in the client's documentation. The example in the admin form is
https://claude.ai/api/mcp/auth_callback.
Authorization flow
When an MCP client connects to MaiAgent MCP (https://mcp.maiagent.ai/mcp for SaaS), the flow is:
The client sends no credentials. The MCP server returns
401, with aWWW-Authenticateheader pointing tohttps://mcp.maiagent.ai/.well-known/oauth-protected-resource/mcp.The client reads this resource metadata (RFC 9728), whose
authorization_serverspoints tohttps://api.maiagent.ai, then reads the authorization server metadata.The client opens a browser at
/o/authorize/, where the member signs in and consents.MaiAgent redirects the authorization code to the Redirect URI. The client sends
code_verifierto/o/token/to exchange the code for tokens.Each subsequent call includes
Authorization: Bearer <access_token>. When the access token expires or is revoked, the MCP server returns401, and the client uses its refresh token to obtain a new one.
If you implement your own client, use these authorization and token exchange request formats:
PKCE is always required, for both Public and Confidential applications. Use
S256forcode_challenge_method.Confidential applications must additionally provide their secret through HTTP Basic (
client_secret_basic) or theclient_secretform field (client_secret_post).Authorization codes are valid for 300 seconds.
The token response includes
access_token,token_type(Bearer),expires_in(3600),refresh_token, andscope.
Login and consent
The authorization login page only offers Email and password: a MaiAgent password, or enterprise credentials if the organization has enabled LDAP login. It has no SSO login button, so accounts that only use SSO and have no password cannot complete authorization.
The consent page shows the application name, its organization, and the Email of the currently signed-in member.
If the member already has a valid token for this application, reconnecting skips the consent page.
Token identity and organization
A token represents the member who grants authorization. Its organization is fixed to the organization that owns the application. Calls neither require nor rely on the
X-Organization-Idheader.At the time of each call, the member must be an active member of that organization. If the member is deactivated or removed, or the organization is deleted, the token immediately becomes unusable and the API returns
401.Access tokens can also call the platform REST API directly (
Authorization: Bearer <access_token>), with the same permission checks as API Keys. Exceptions: AI Gateway's OpenAI-compatible endpoints only accept API Keys; high-risk operations such as deleting your own account only accept interactive login.
Token lifetimes and rotation
Authorization code
300 seconds
Access token
3600 seconds (1 hour)
Refresh token
Rotates on every use: the response includes a new refresh token, and the old one is invalidated
Retries after rotation
If the same request is resent because of network issues or concurrency, the just-rotated old refresh token remains usable for 120 seconds
Explicit revocation
Takes effect immediately, without the 120-second grace period
Refresh token lifetime
Do not rely on a fixed lifetime. Revocation, application deletion, or member deactivation invalidates refresh tokens; use an invalid_grant response from the token endpoint as the signal
When your integration receives invalid_grant, stop using that refresh token and prompt the member to authorize again; do not retry in the background. For revocation and rotation details, see When a Refresh Token Is Revoked or Invalidated.
There are three ways to revoke tokens:
Integration
POST /o/revoke_token/ with token (optionally token_type_hint) and client authentication
A single token
Member
List their authorized applications with GET /api/v1/oauth/authorized-applications/, then revoke with DELETE /api/v1/oauth/authorized-applications/{id}/
All tokens this member granted to that application
Organization administrator
Delete the OAuth application
All tokens all members granted to that application
When a refresh token is revoked or invalidated
Once a refresh token is explicitly revoked, it can no longer be exchanged for an access token. If your integration continues sending it to POST /o/token/, the endpoint returns HTTP 400 with the error code invalid_grant. Handle this as follows:
On
invalid_grant, stop using the refresh token and prompt the member to authorize again; do not retry in the background.When a member revokes an entire authorized application, all tokens they granted to that application are revoked, and none of the old refresh tokens can be used.
After normal rotation, the just-rotated old refresh token has a 120-second retry grace period if the same request is resent due to network issues or concurrency. This grace period does not apply to explicit revocation.
Treat invalid_grant as a signal to authorize again. Do not assume a token remains usable for 120 seconds after explicit revocation, and do not schedule reauthorization based on a fixed refresh token lifetime.
Actual effect of scopes
The authorization server accepts the read and write scopes; if an authorization request omits scope, both are granted by default. Scopes currently do not restrict any API: everything a member can do is determined by their role permissions, just as when signing in to the admin interface or using an API Key. To restrict what an MCP client can do, create a dedicated role for its users; see Role Permission Management in the user manual.
Frequently asked questions
Last updated
Was this helpful?