Managoat is the hosted Fountain. Fountain is the open-source engine, and its name is on the CLI, the API, the SDK and this manual. Everything here applies to Managoat unless a page says it is for a self-hosted server.
Connections
A connection is a provider account you signed in to once, whose tokens Fountain holds. Fountain encrypts the refresh token with your tenant key, like a vault secret. An agent gets the capability, and never the credential.
A connection provider says where a connection's tokens come from. It holds the OAuth client, the endpoints, the scopes, and the hosts the token goes to.
Limited access
Connections exist only for accounts the egress broker is on for (ADR 0019). Without the broker, a token would have to enter the sandbox in the clear, so the page and the routes are absent. Read Feature status.
Platform and tenant providers
| Platform | Tenant | |
|---|---|---|
| Who owns the OAuth client. | The operator of the instance. | You. |
| Where you define it. | Instance configuration. | The Connections page, or POST /api/connection-providers. |
| Which exist. | Google, Microsoft and Slack, with their slugs as ids. | As many as you define. |
Fountain owns an OAuth client for each platform provider. It cannot own an app at every service, and a restricted scope needs verification of each app anyway. So every other service is a tenant provider.
One platform connection covers several products. The Google account carries Gmail and Calendar. The Microsoft account carries Outlook mail, calendar and Teams chat. The granted scopes on a connection say which products you consented to.
The two kinds of tenant provider
| Kind | You give Fountain | Fountain learns the endpoints from | Guide |
|---|---|---|---|
oauth2 |
Your app registration at the service. The client id and secret, the scopes, and the token hosts. | You. The console has presets for GitHub, Slack, Notion and Linear. | Connect a service with your own OAuth app. |
mcp |
The URL of a remote MCP server. | Discovery, from the server's metadata. Fountain registers a client there when it can. | Connect a remote MCP server. |
Both kinds share one connection model. Each provider has an env key, such
as GITHUB_ACCESS_TOKEN, and a list of token hosts. Fountain derives the
env key from the slug. A second account on the same provider takes the next
numbered key, GITHUB_ACCESS_TOKEN_2.
How an agent uses a connection
The sandbox holds a placeholder for the env key, __github_access_token__
for GITHUB_ACCESS_TOKEN. The broker replaces it with the real token on a
request to a token host. Three shapes use that.
A stdio server in the sandbox. The server reads the env key from its environment, as it would read a personal access token. The value it reads is the placeholder.
{ "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_ACCESS_TOKEN}" } } }
A remote MCP server. The entry names a URL and a connection. At spawn it gets a placeholder bearer, and the broker attaches the token to that host.
{ "linear": { "type": "http", "url": "https://mcp.linear.app/mcp", "connection": "<id>" } }
A server Fountain hosts. Only for Google today. The entry names the connection alone, and the token stays on the server. Read fountain-gmail.
Status
| Status | Meaning |
|---|---|
active |
Fountain can get an access token. |
revoked |
The provider refused the refresh, or you revoked. Connect again to replace it. |
expired |
The provider gave no refresh token, and the access token lapsed. Reconnect to replace it. |
Fountain refreshes a token on the server before it expires. A response with
no expires_in means the token does not expire. A response with a new
refresh token replaces the stored one.