Skip to content
DocsAll docs
Console

OAuth and connected apps API

Lists the endpoints that sign an MCP client in with OAuth, and the routes that list and revoke connected apps.

Last updated

On this page

OAuth endpoints

These routes are not under /v1. They take no desk.

PathMethodMeaning
/mcpPOSTThe MCP server. One JSON-RPC message in (a batch is 400); application/json out. A notification gets 202. GET and DELETE get 405. No token gets 401 with WWW-Authenticate: Bearer resource_metadata="https://dev.kloudlite.io/.well-known/oauth-protected-resource", scope="kode"; a token that is not valid for this server gets the same with error="invalid_token" added. An Origin other than this server, claude.ai, claude.com or chatgpt.com gets 403, and an unknown MCP-Protocol-Version gets 400. A tool call waits at most 95 seconds in all
/.well-known/oauth-protected-resourceGETRFC 9728 document. resource is the /mcp URL
/.well-known/oauth-authorization-serverGETRFC 8414 document. code_challenge_methods_supported is ["S256"], and authorization_response_iss_parameter_supported is true
/oauth/authorizeGETThe consent page in the console. response_type=code, client_id, redirect_uri, code_challenge, code_challenge_method=S256, state, scope and resource (the /mcp URL) are required. Every redirect back to the client carries iss
/oauth/registerPOSTRFC 7591 registration, JSON. Stores nothing. At most 5 redirect_uris
/oauth/tokenPOSTauthorization_code and refresh_token. The body is application/x-www-form-urlencoded; a JSON body is 400 invalid_request
/oauth/revokePOSTRFC 7009. Form field token. Always 200

A client is identified by a client ID metadata document (client_id is an https:// URL on claude.ai, claude.com, or chatgpt.com), or by the client_id that /oauth/register returns. A redirect_uri is one of these, compared exactly:

  • https://claude.ai/api/mcp/auth_callback
  • https://claude.com/api/mcp/auth_callback
  • https://chatgpt.com/connector_platform_oauth_redirect
  • https://chatgpt.com/connector/oauth/{id}
  • http://localhost or http://127.0.0.1 with any port, for a program on the same computer

Lifetimes:

ItemLifetime
Code60 seconds, and it works once
Access token1 hour
Refresh tokenReplaced at every use. The replaced token still works for 30 seconds, so a retry does not lose the connection
ApprovalDeleted when it is not finished within 10 minutes
Connection30 days, and at most 20 at once

A replaced refresh token that is presented after the 30 seconds deletes the connection. The same happens for a code that is used twice. The check covers the last three replacements.

POST /v1/oauth/client

Checks an authorize request for the consent page. Takes a desk. The body has the authorize parameters.

Response: 200, one of these.

json
{ "client_name": "Claude", "redirect_host": "claude.ai", "loopback_only": false }
json
{ "page_error": "This sign-in link names a return address that this app is not registered for." }
json
{ "redirect": "https://claude.ai/api/mcp/auth_callback?error=invalid_target&state=...&iss=https%3A%2F%2Fdev.kloudlite.io" }

page_error is shown to the person and is never redirected to. redirect is an OAuth error for the client.

Errors:

  • 401 — a CLI login, an API token, or a connector token. Only a console session is accepted.

POST /v1/oauth/approve

Approves or denies a connection. Takes a desk. The body is the authorize parameters and these fields.

FieldTypeRequiredRule
teamsstring arrayyesOne or more of your handle and the teams that you are an active member of. Your handle is stored first. No desk is asked or made: the app picks and makes desks itself
allowbooleanyesfalse writes nothing and redirects with error=access_denied

Response: 200 with {"redirect": "..."}, the return address with code, state, and iss.

Errors:

  • 400 — a page_error, as above.
  • 401 — not a console session.
  • 403 — you are not a member of that team, or your access to acme is paused.
  • 422 — a page_error when teams is empty or holds more than 50 teams, or when you already hold 20 connections.

GET /v1/oauth/grants

Lists the apps that you connected. Takes a desk or a CLI login.

Response: 200.

json
[  {    "id": "5f2d8a0b9c3e4d1f7a6b5c4d3e2f1a0b",    "client_name": "Claude",    "redirect_host": "claude.ai",    "teams": ["ada", "acme"],    "created_at": "2026-11-03T08:00:00+00:00",    "last_used_at": "2026-11-03T09:30:00+00:00",    "expires_at": "2026-12-03T08:00:00+00:00"  }]

DELETE /v1/oauth/grants/{id}

Disconnects an app. The next call from the app is 401, and its refresh token stops working. Takes a desk or a CLI login and no body.

Response: 204.

Errors:

  • 404 — no such connected app. Also the answer for a connection that another person made.