Skip to main content
MCP endpoints are in beta.
Every request to an MCP endpoint must carry a bearer token, and every token must be backed by a grant that your app issued. The token proves who is calling; the grant says what that caller may do through this endpoint. Bijection doesn’t issue tokens or run an OAuth authorization server for MCP endpoints. Clients get tokens from the identity provider you already use for authentication.

Accepting tokens

Configure your identity provider in bijection/auth.config.ts as usual, for example as a custom JWT provider. Then tell the endpoint which resource it is and which authorization servers issue its tokens:
bijection/mcp.ts
  • resource identifies this endpoint. Use your deployment’s .bijection.site URL. Browser requests whose Origin differs from the resource’s origin are refused with 403 origin_refused.
  • authorization_servers lists the issuers your clients get tokens from. At least one is required.
Both must be https:// URLs without credentials, a query string or a fragment. Plain http:// is accepted only for localhost, 127.0.0.1 and [::1], so you can develop locally. Clients send the token in the Authorization header:
A request without a token receives 401 authentication_required with a WWW-Authenticate header that points to the endpoint’s OAuth protected-resource metadata:
The metadata HTTP action you mounted at that path returns:

Grants

A valid token isn’t enough on its own. Your authorize query returns the grant for the calling identity, and the endpoint accepts the request only when:
  • the caller is authenticated,
  • the grant’s principal equals the caller’s tokenIdentifier,
  • the grant’s audience equals the endpoint’s resource,
  • the grant has a non-empty id, and
  • the grant’s expires_at (milliseconds since the epoch) is in the future.
Otherwise it responds with 403 access_refused. The grant’s tools list is an allowlist: tools/list shows only the published tools named in it, and calls to any other tool fail with tool_unavailable. Publishing a new tool grants nothing until you add it to a grant. The full grant shape is the McpGrant type:
The endpoint itself checks id, principal, audience, expires_at and tools. organization, application and customer are yours to define and use, for example in your admission limits or access rules.

Storing grants

Keep grants in a table your app owns:
bijection/schema.ts
Then look up the caller’s grant in an internal query:
bijection/mcp.ts
Protect the grants table with access rules so an identity can read only its own grants, and so only your administrators can write them.

Issuing grants

Issue one principal for each agent interaction you want to authorize, write its grant, and give the agent’s host three things: the endpoint URL, a way to obtain that principal’s token, and the grant id. Clients that call operation tools must send the grant id with each call; a call made under a different grant fails with request_scope_mismatch. To revoke access, delete the grant, shorten its expires_at or remove tools from its allowlist. A token refresh doesn’t change the grant, since the principal stays the same.

When grants are checked

The grant is checked when the request arrives, again inside the transaction that runs each tool call, and once more before the response is released. If a grant is revoked or expires while a request is running, the response is withheld and the client receives 403 request_refused. Revocation fences future work only. An operation that was already accepted stays accepted, and an external call it already made is not undone.

Permissions for tools

Grants decide which tools an agent may call through this endpoint. They don’t replace the permissions of the functions behind those tools. Query tools run as the caller, so your access rules decide which rows it can read. Operation tools need the same permission to invoke the operation that any other client would. See Access and Operations.