Skip to content

Authorization ​

The Flat MCP server follows the MCP authorization specification: OAuth 2.1, authorization code grant with PKCE, discovered from metadata. A client that implements the spec needs no Flat-specific configuration.

Discovery ​

An unauthenticated request to https://mcp.flat.io/mcp answers 401 with a WWW-Authenticate challenge pointing to the protected resource metadata (RFC 9728):

GET https://mcp.flat.io/.well-known/oauth-protected-resource
json
{
  "resource": "https://mcp.flat.io/mcp",
  "authorization_servers": ["https://api.flat.io"],
  "bearer_methods_supported": ["header"],
  "scopes_supported": ["mcp"],
  "resource_name": "Flat",
  "resource_documentation": "https://flat.io/developers/docs/mcp"
}

The authorization server metadata (RFC 8414) is at https://api.flat.io/.well-known/oauth-authorization-server (also served as /.well-known/openid-configuration):

FieldValue
issuerhttps://api.flat.io
authorization_endpointhttps://flat.io/auth/oauth/mcp
token_endpointhttps://api.flat.io/oauth/access_token
revocation_endpointhttps://api.flat.io/oauth/invalidate_token
registration_endpointhttps://api.flat.io/oauth/mcp/register
grant_types_supportedauthorization_code, refresh_token
code_challenge_methods_supportedS256
client_id_metadata_document_supportedtrue
scopes_supportedmcp

Client registration ​

Client ID Metadata Documents (preferred) ​

Use an https:// URL as your client_id. Flat fetches it at authorization time and reads your client metadata from it (CIMD).

  • The URL must be https, have a path (not just a host) and no fragment.
  • The document's client_id must equal the URL exactly.
  • client_name and a non-empty redirect_uris are required.
  • Redirect URIs must be https, or http on localhost / 127.0.0.1, without a fragment.
  • Flat follows at most 3 redirects, reads at most 64 KB and waits at most 5 seconds. It caches the document according to Cache-Control: max-age, between 5 minutes and 24 hours.

There is nothing to register with Flat beforehand.

Dynamic Client Registration ​

For clients that do not support CIMD, Flat accepts RFC 7591 registration:

http
POST https://api.flat.io/oauth/mcp/register
Content-Type: application/json

{
  "client_name": "My MCP client",
  "redirect_uris": ["http://127.0.0.1:33418/callback"]
}

The response (201) contains a client_id, with token_endpoint_auth_method: "none" and scope: "mcp". No client secret is issued: every MCP client is a public client. Registration is limited to 10 clients per IP address per hour (429, Retry-After: 3600).

Clients registered this way cannot prove who they are, so the consent screen marks them as unverified (see below). Prefer CIMD.

Authorization request ​

https://flat.io/auth/oauth/mcp
  ?response_type=code
  &client_id=https://example.com/oauth/client.json
  &redirect_uri=https://example.com/oauth/callback
  &code_challenge=...
  &code_challenge_method=S256
  &scope=mcp
  &resource=https://mcp.flat.io/mcp
  &state=...
  • response_type must be code.
  • PKCE is required, with S256 only. The verifier is 43 to 128 characters.
  • redirect_uri must match a registered URI exactly. For http loopback URIs (localhost, 127.0.0.1), any port matches (RFC 8252); scheme, host, path and query must still match. A mismatch is shown on Flat's page and never redirected.
  • scope defaults to mcp; a request without mcp fails with invalid_scope.
  • resource (RFC 8707) defaults to https://mcp.flat.io/mcp. Unknown values fail with invalid_target.

The redirect back carries code, state and iss (RFC 9207). The code is valid for 10 minutes and can be redeemed once.

The mcp scope is only granted through this flow. It cannot be added to a regular Flat developer app or a personal access token.

Tokens ​

TokenLifetime
Access token24 hours
Refresh token30 days, renewed on every refresh

Every refresh returns a new refresh token with a new 30-day lifetime and invalidates the previous one. A client that does not refresh for 30 days must send the customer through consent again.

Send the access token as a bearer token on every MCP request:

http
Authorization: Bearer <access_token>

The MCP server only accepts tokens issued for its resource (https://mcp.flat.io/mcp).

The customer approves every client on Flat's consent screen, which lists the single permission requested: Read and change the content of your Flat account. How the client is presented depends on what Flat could verify:

ClientShown as
Recognized (ChatGPT, Claude, Visual Studio Code)Product name and logo, "recognized by Flat"
CIMD clientThe domain of its client_id as a proven origin, with the name it declares
DCR client"This app hasn't proven who it is", and the button reads Allow anyway

When the redirect URI is a loopback address, the screen also says the access code goes to a program running on the customer's computer.

Errors ​

SituationResult
Missing, expired or revoked token401, invalid_token
Token issued for another resource401, invalid_token
Account without Flat Power403, MCP_UPGRADE_REQUIRED
Flat for Education account403, MCP_EDUCATION_NOT_AVAILABLE
Disabled account403, MCP_ACCOUNT_DISABLED
Client disabled by FlatMCP_CLIENT_DISABLED

Eligibility is checked at consent and on every request. The error messages are localized to the customer's language and meant to be shown to them as is.

Revocation ​

  • By the customer: removing the client from Link external accounts and apps in their Flat account settings deletes all its tokens for that customer.
  • By the client: POST https://api.flat.io/oauth/invalidate_token (RFC 7009) revokes the token you send.

Copyright © Tutteo Limited