API reference
Choose what you want to build. Each example shows the token and request you need.
Choose an API task
Jump to an API step
Base URL: https://closedmcp.com. Use your company’s address if it differs.
An access token lets an AI app call ClosedMCP. A tool identity token tells a connected server who is calling. Use the access token when calling ClosedMCP. Your tool receives a separate identity token to identify the person.
Sign-in steps
- Register your app. Save the client_id and use your registered return URL.
- Sign in the user. Make a random PKCE verifier. Send its SHA-256 base64url hash as code_challenge. Keep the verifier private. Make a random state value and check it on return.
- Get a token. Exchange the returned code with the original verifier. Save the access token securely. Use the refresh token to renew it.
Follow the endpoints below in order. ClosedMCP handles the permission form; your app opens its URL.
Discover the sign-in server
GET/.well-known/oauth-protected-resource
Tells an AI app where to sign in. Also at /.well-known/oauth-protected-resource/mcp.
Authentication: None.
Copy request
curl "$BASE/.well-known/oauth-protected-resource"View response
{
"resource": "https://closedmcp.com/mcp",
"authorization_servers": [
"https://closedmcp.com"
],
"scopes_supported": [
"mcp:tools",
"mcp:list"
],
"bearer_methods_supported": [
"header"
]
}Notes and errors
Errors: No endpoint-specific error response.
Read sign-in settings
GET/.well-known/oauth-authorization-server
Lists the sign-in, registration and token URLs, supported settings and the public key URL. Also at /.well-known/oauth-authorization-server/mcp and /.well-known/openid-configuration.
Authentication: None.
Copy request
curl "$BASE/.well-known/oauth-authorization-server"View response
{
"issuer": "https://closedmcp.com",
"authorization_endpoint": "https://closedmcp.com/oauth/authorize",
"token_endpoint": "https://closedmcp.com/oauth/token",
"registration_endpoint": "https://closedmcp.com/oauth/register",
"code_challenge_methods_supported": [
"S256"
],
"jwks_uri": "https://closedmcp.com/.well-known/jwks.json"
}Notes and errors
Excerpt. The response also lists supported grants, scopes and response types.
Errors: No endpoint-specific error response.
Register an AI app
POST/oauth/register
Registers an AI app and its return URLs. Send JSON. The answer includes a client_id. No client secret is needed.
Authentication: None.
Copy request
curl "$BASE/oauth/register" \
-H 'Content-Type: application/json' \
-d '{"client_name":"My app",
"redirect_uris":["https://my-app.example/callback"]}'View response
{
"client_name": "My app",
"redirect_uris": [
"https://my-app.example/callback"
],
"client_id": "cm_example",
"client_id_issued_at": 1791504000,
"token_endpoint_auth_method": "none"
}Notes and errors
Errors: HTTP 400, invalid_redirect_uri: missing or unsupported return URL.
Open the sign-in and permission page
GET/oauth/authorize
Opens the sign-in and permission page in a browser. Use the registered client_id and return URL with a PKCE S256 challenge. To ask for a tool identity token for your own MCP server, add its exact URL as resource. Replace the placeholder values, then open this URL in a browser.
Authentication: Google sign-in in the browser.
Copy request
https://closedmcp.com/oauth/authorize
?response_type=code
&client_id=<client_id>
&redirect_uri=https%3A%2F%2Fmy-app.example%2Fcallback
&code_challenge=<S256_challenge>
&code_challenge_method=S256
&state=<random_state>View response
HTTP 200: sign-in or permission page.
After approval: HTTP 302 to your return URL.
https://my-app.example/callback?code=example&state=exampleNotes and errors
Errors: HTTP 400: invalid authorization parameters. User denial returns access_denied to a validated return URL.
Submit the permission decision
POST/oauth/authorize
Sends the person’s choice from the permission page. Needs the signed-in browser session and a request from the same site.
Authentication: Signed-in browser session. Same-origin request.
Copy request
rid=<request_id>&decision=allowView response
HTTP 302
Location: https://my-app.example/callback?code=example&state=exampleNotes and errors
The Location header is a single-line URL. This endpoint serves the permission form; apps should open GET /oauth/authorize.
Errors: HTTP 403: cross-site request. HTTP 400: invalid or expired request.
Get an access token
POST/oauth/token
Swaps a sign-in code and its PKCE verifier for a bearer token. Send form data. To renew a token, send grant_type=refresh_token and refresh_token instead. Keep client_id when renewing an access token.
Authentication: Registered client_id and PKCE verifier. No client secret.
Copy request
curl "$BASE/oauth/token" \
-d grant_type=authorization_code \
-d 'code=<code>' \
-d 'code_verifier=<verifier>' \
-d 'client_id=<client_id>' \
-d redirect_uri=https%3A%2F%2Fmy-app.example%2FcallbackView response
{
"access_token": "cmcp_at_example",
"refresh_token": "cmcp_rt_example",
"token_type": "Bearer",
"expires_in": 2592000,
"scope": "mcp:tools mcp:list"
}Notes and errors
Errors: HTTP 400: invalid_grant for a bad, expired or reused code, mismatched client, or invalid verifier. invalid_target for an unsupported resource. invalid_request for repeated parameters.