Connect an AI client
An AI client connects to a Cahut with its address alone: https://cahut.example.com/mcp. The client sends you to the console of the Cahut, where you sign in and choose what it may do. Then it acts for you, within what you granted, and every call it makes goes to the Logbook.
This works with the MCP clients that sign in with OAuth: claude.ai, Claude Desktop, Claude Code, ChatGPT, Le Chat and others. For a client that cannot, such as a script, use a personal token.
Add the Cahut to your client
Section titled “Add the Cahut to your client”The address to give is on the AIs and access screen of the console, ready to copy.
| Client | Where |
|---|---|
| claude.ai, Claude Desktop | Settings, Connectors, Add custom connector: the address of the Cahut, nothing else |
| Claude Code | claude mcp add --transport http cahut https://cahut.example.com/mcp, then /mcp and Authenticate. See Connect Claude Code |
| ChatGPT | On the web, Plugins, the plus button, Add custom MCP server: the address of the Cahut, and OAuth as its authentication. Custom MCP servers need a Business, Enterprise or Edu plan |
| Le Chat | Connectors, add a custom MCP connector with the address of the Cahut. Le Chat finds OAuth by itself |
| Others | The address of the Cahut. The client finds the rest by itself |
A Cahut on my.cahut.cloud needs no address in claude.ai and Claude Desktop: My Cahut is in the directory of connectors of Claude. Search for it, then select Connect. See Try Cahut on My Cahut.
The client opens a page of the console in your browser, at https://<domain>/console/oauth/authorize. The servers of the client, and your browser, reach the Cahut on port 443 only.
ChatGPT does not connect to a Cahut at the IP address of its server: its servers never call the Cahut, and ChatGPT says that it cannot find the OAuth settings. Move the Cahut to a domain first, then add it to ChatGPT at its new address.
Every client gets the same tools. Each tool has a title, such as Publish a Window, and says whether it only reads: ChatGPT shows the title when it asks you to confirm a call that changes something, and Le Chat lets you allow each tool always or ask each time. That confirmation comes on top of Knock first, which no client can skip.
Consent
Section titled “Consent”If you are not signed in to the console, you sign in first. Then the console shows:
- Who asks: the name of the AI client, as it gives it, and the host the browser goes back to once you answer, such as
claude.ai. Some clients, such as Claude Code, describe themselves in a document on their own site, and the console names that site. A client that registered by itself could have chosen any name: connect it only if you started from it. - What it may do: read and publish, which is everything you can do in your Rooms, or read only, which is your Rooms, their Windows and the Logbook. A client that asks for read access cannot get more.
- Where: all your Rooms, including those you join later, or a list of them.
Connect sends the browser back to the client, which receives its tokens. Refuse sends it back with nothing.
An AI never gets more than its person: if you leave a Room, or an administrator disables you, it loses that too. An AI limited to some Rooms does not see the others, cannot publish in them and cannot create a Room. An AI that may only read sees only the tools that read.
Connected AIs
Section titled “Connected AIs”AIs and access lists your connected AIs: the client, what it may do, its Rooms, when it last acted and its state. Change sets what it may do and where, as on the consent screen. Disconnect cuts one off: its next call is refused.
An AI can ask for more itself, such as write access or another Room, with set_ai_reach: it knocks first, and gets it once you approve. An AI that may only read is offered this tool too, for that. Narrowing what it reaches, it does at once.
| State | What it means |
|---|---|
| Active | The AI can act |
| Expired | The AI has not been used for 30 days: connect it again |
| Disconnected | You, an administrator, or the client itself ended the connection |
An administrator of the Cahut sees the connected AIs of others too, and can disconnect them.
Each connection is in the Logbook: your consent, every call the AI makes, under its name and the person it acts for, such as Claude Code (claude-code 2.1.307) for you, and the end of the connection.
For the developers of clients
Section titled “For the developers of clients”Each Cahut is its own OAuth 2.1 authorization server, as the MCP authorization specification asks:
| What | Where |
|---|---|
| Protected resource metadata (RFC 9728) | https://cahut.example.com/.well-known/oauth-protected-resource/mcp |
| Issuer | https://cahut.example.com |
| Authorization server metadata (RFC 8414) | https://cahut.example.com/.well-known/oauth-authorization-server |
| Token, registration, revocation | https://cahut.example.com/oauth/token, /oauth/register, /oauth/revoke |
| Authorization | https://cahut.example.com/console/oauth/authorize, a page of the console |
Everything is on port 443. The servers of a client call the endpoints of the protocol, and the person’s browser opens the authorization page, in the console.
- Clients register with a Client ID Metadata Document or by dynamic registration (RFC 7591). Both make public clients, which authenticate with
none: there is no client secret. A metadata document may prefer another method, such asprivate_key_jwtfor ChatGPT, as long as it listsnoneintoken_endpoint_auth_methods_supported. - Cahut fetches a metadata document as
Cahut/<version>, from public addresses only, and keeps it in memory for an hour. It also keeps the last valid copy of each document a person connected: when the document no longer answers, the copy stands in for 30 days. A document that answers but is invalid is refused. - Authorization codes need PKCE with S256, live 5 minutes and are used once.
- Access tokens start with
cahut_oat_and live one hour. Refresh tokens start withcahut_ort_and live 30 days; each refresh replaces the refresh token. A refresh token used twice ends the connection. - The scopes are
readandwrite, andoffline_accessfor the refresh token, which every connection has. A token grantedwritestatesread write offline_access, and one grantedreadstatesread offline_access. The resource ishttps://cahut.example.com/mcp; a token of one Cahut opens nothing in another. - Redirect URIs match exactly, except loopback addresses in
http, whose port may change.
ADR 16 and ADR 17 give the details. The service logs each request to these endpoints, with its status and the error of a refused one: journalctl -u cahut shows them while a client connects.