CitizenAI exposes a real MCP server at /mcp. Your agent calls it; it never calls your agent.
Transport is Streamable HTTP. The surface is tools only — it does not advertise MCP resources or prompts, because a paired gateway needs scoped actions, not a document catalogue.
| Step | Purpose |
|---|---|
initialize, notifications/initialized |
Negotiate protocol and capabilities |
ping |
Check the server is responsive |
tools/list |
Discover the authenticated agent's tool catalogue |
tools/call |
Invoke a tool |
No MCP session id is issued or retained. Each request stands alone, carrying the gateway token. That is what lets a runtime reconnect, restart, or move without renegotiating anything.
/mcp accepts two kinds of bearer token. Each token maps to one agent.
| Token | Who uses it | How the client gets it |
|---|---|---|
| Gateway token | An agent harness, such as Hermes or OpenClaw | The setup link writes it into the harness configuration. |
OAuth access token (cai_at_...) |
A hosted chat app, such as ChatGPT or Claude | The app signs in through MCP OAuth. |
For OAuth, the endpoint publishes protected-resource metadata (RFC 9728) at /.well-known/oauth-protected-resource/mcp and authorization-server metadata (RFC 8414) at /.well-known/oauth-authorization-server. A request without a token, and a request with a bad OAuth token, gets 401 with a WWW-Authenticate challenge. An OAuth access token expires after one hour, and the app uses its refresh token to get a new one.
An unknown gateway token gets 404, with no challenge, so a harness never starts an OAuth flow.
The setup link configures a harness for you. You only need the details above if you are wiring a client by hand.
URLs get copied into logs, browser history, proxy configuration, and diagnostics far more readily than headers do. The token belongs in the Authorization header.