Docs
PlatformDeveloper integration

Validate the Xokepoint token

How a customer MCP server checks the token Xokepoint sends and reads the person and the agent.

After it allows a call, Xokepoint calls the customer MCP server with a token made only for that server (Upstream authentication). The server checks the token and, if it wants, uses the person and the agent to decide about its own data.

The server needs three values, shown in the dialog and in the server details (Customer servers): Issuer, JWKS and Audience.

What to check

  1. The signature, with the keys from the JWKS URL. Read the URL and cache it; do not copy the keys, because they rotate.
  2. iss equal to the Issuer.
  3. aud equal to the Audience, which is the endpoint of the server itself in canonical form: lower-case scheme and host, no default port, no query or fragment. A token for another server is refused.
  4. exp in the future. The token lives 60 seconds.

The signature is ES256 and the token header has typ at+jwt.

With a valid token, sub is the person or service and act.sub is the agent. On a tools/call, chokepoint_tool also names the tool (server_id and name).

One kind of token has no agent. When the administrator connects or rediscovers the server, Xokepoint lists its tools with a token whose sub is chokepoint:registry and that has no act. Accept it for tools/list and the protocol messages, and refuse a tools/call without act. Configure the three values before the first discovery: it already sends a token, and a server that rejects it cannot be registered.

Example with FastMCP

The server details in the Admin include this example, with the values filled in:

from fastmcp import FastMCP
from fastmcp.server.auth.providers.jwt import JWTVerifier
from fastmcp.server.dependencies import get_access_token

auth = JWTVerifier(jwks_uri="<JWKS>", issuer="<Issuer>", audience="<Audience>", algorithm="ES256")
mcp = FastMCP("issues", auth=auth)

@mcp.tool
def move_issue(repository: str, issue_number: int, column: str) -> str:
    claims = get_access_token().claims
    person, agent = claims["sub"], claims["act"]["sub"]
    ...

JWTVerifier checks signature, issuer, audience and expiry before the tool runs. Inside the tool, person and agent serve your own filters, such as showing only the person's documents, and logs.

The server does not need to repeat Xokepoint's rules. The call only reaches it after ALLOW.