Conversations
ChatGPT, except the model has a real computer and you can watch it use one.
Open this one first. It is the whole platform with a face on it.
Self-hosted
Define your agents once. Let every app you build hire them.
Run it yourself and the whole platform is yours. Your machines, your keys, nothing rationed.
AGPL-3.0-or-later no licence key no seat count no call with us
git clone https://github.com/BinaryBourbon/fountain
cd fountain
cp .env.compose.example .env
echo "SECRET_KEY_BASE=$(openssl rand -base64 48 | tr -d '\n')" >> .env
echo "MASTER_SECRETS_KEY=$(openssl rand 32 | base64 | tr '+/' '-_' | tr -d '=\n')" >> .env
# ... and your sandbox provider token
docker compose up -d
The compose file brings its own Postgres. Back the master key up before you have data, because it is not in the database.
First: pick a sandbox provider before you run any of this. Without a token every conversation fails. What each provider needs →
Before you start
You need
Docker Engine with Compose v2, and openssl for the two key lines.
No database
The compose file runs Postgres 16 for you. You install nothing.
Network
Your machine reaches ghcr.io, the registry that holds the image. Blocked? Compose builds it from the checkout instead.
One address
Reaching it by anything but localhost? Set PUBLIC_URL too. It builds the links in verification emails, and every sandbox reads it.
01 · Install
Migrations run before the app opens a listener, so a cold start takes up to a minute. A refused connection in that window is normal.
Then
Open http://localhost:4000 and sign up. The first account verifies itself and takes the admin role, so there is no bootstrap ritual and no console of ours in the path. Close registration behind you when you are done.
Check
Wait for the app container to report healthy, then probe it.
curl -sS localhost:4000/health/ready
{"checks":{"database":"ok"},"status":"ok"}
Instead
Plain manifests in deploy/k8s/, with no operators and no CRDs. Every merge publishes them as an OCI artifact, and the hosted instance deploys from it. Same manifests, one pin apart: the artifact carries a sha tag, and the committed release pin is the one you apply.
02 · What you open
What you just brought up serves a console: accounts, keys, agents, environments, audit. The apps your team works in are these three, and each is static files that take a server URL as input. Admit the origin once and all three answer to your instance, with your agents, your sandboxes and your keys. Host your own copies instead if you would rather; they are open source too.
ChatGPT, except the model has a real computer and you can watch it use one.
Open this one first. It is the whole platform with a face on it.
A group chat whose contacts are bots you made, one click each, faces and all.
For anyone who would rather text a teammate than fill in a form.
Multiplayer engineering: one board of work items, and staff you put on them by typing.
For a team that wants the same projects, the same agents and one place to watch.
A browser app on another origin calling your API is a CORS request, so name the origin it is served from:
API_CORS_ORIGINS=https://fountain-conversations.demo.managoat.com
Conversations and Team are also what the console's own links point at, so CONVERSATIONS_APP_URL and TEAM_APP_URL swing them to copies you host, and an empty string says this deployment has none. Both are in the configuration reference.
03 · Built on it
Here are four of them, and they are four different front doors onto the same idea. Nobody wrote an agent into any of these apps. The teammate was defined once and the app is the part somebody built on top of it. All of them are open source, and each one points at whichever instance you configure.
reflex.inevitable.fyi
A personal assistant you text. It keeps a computer, your accounts and a memory, and it works while you do something else: books the dentist, sweeps the inbox at two, texts you when the tickets come back.
table-talk.demo.managoat.com
Drop a CSV in. An analyst runs Python on its sandbox and comes back with charts and plain-English findings. Then keep asking questions of your data.
rounds.demo.managoat.com
Dependabot for infrastructure config. Enrol a repository and it gets audited on a schedule; an agent fixes what it can verify and opens the pull request. Never twice for the same finding, never again for one you closed.
mission-control.demo.managoat.com
Describe a mission. A coordinator plans it, you approve the plan, and the app starts one sandboxed agent per task. Watch the fleet work and take one report.
04 · Ownership
Most people stop at the first rung and are happy there. The point is that the next three exist, and that none of them is a sales conversation.
Your container, your Postgres, your domain. Conversations, transcripts, audit rows and API keys live in a database you can open with psql.
Every tenant's env vars are encrypted with a key derived from a master key you generate. It is not in the database, which is also why a database backup on its own does not save you.
A Mac mini, a home server or a GPU box becomes a sandbox backend with one daemon. It dials out and holds one connection. There is no inbound port to open and no credential to hand it.
Server on your hardware, sandboxes on your machines, and no third-party account is left in the loop. Not a sandbox host's, and not ours.
A model key is the one thing you still bring, and you always did. The agent bills your own provider account for tokens, so nothing in the middle takes a cut of inference. Read how a machine of yours becomes a sandbox.
05 · Feature flags
Three things are not on for everyone here. Two are alpha and one changes what a sandbox can reach, so on the hosted platform each of them means an email to us and a wait. On an instance of your own they are a line in a config file, and nobody has to approve you.
Capability
On this site
On yours
An agent with its own inbox and its own number, that answers what arrives.
Read the page →On this site
Behind a flag. Ask us to turn it on for your account.
Config
Set AGENTMAIL_API_KEY and AGENTPHONE_API_KEY, then add team_comms to FEATURE_FLAGS_ON.
Point anything that speaks chat completions at your instance, where the model is an agent.
Read the page →On this site
Behind a flag. Ask us to turn it on for your account.
Config
Add openai_compat to FEATURE_FLAGS_ON.
The real token never enters the sandbox. The broker attaches it on the way out, and the transcript keeps a placeholder.
Read the page →On this site
Limited access. We enrol an account by hand.
Config
Set BROKER_URL and BROKER_TOKEN, and list the tenants in BROKER_TENANTS.
The rest of the product has no flag on it. The hosted instance adds nothing that is not in the repo. It runs the release image with switches set, and the configuration reference lists every one of them.
06 · Licences
The parts your code touches are permissive on purpose. A connection to Fountain must never put an obligation on your application.
apps/fountain
AGPL-3.0-or-later
Run it, change it, host it, charge for it. Offer a changed server to other people over a network and they have a right to your source.
ee/
Elastic 2.0
Free to run in your own instance, and your changes stay yours. The one thing it forbids is selling this code to third parties as a hosted service.
cli/, sdk/typescript
Apache-2.0
Ship them inside a closed product. An application that calls your instance takes on no obligation at all.
07 · Trade-offs
Self-hosting is not free, it is paid in a different currency. Better you know the four line items now than in week three.
Sprites, E2B and Daytona are all hosted. Daytona you can run yourself, and your own runners need no vendor at all. Pick one before your first conversation, because without one every conversation fails.
Runners on your own hardware →Verification and password resets go through Resend, or an SMTP server of yours. So does anything a teammate sends. The compose defaults skip delivery so the first account can register, and that default is for day one only.
Configure email →Back it up before you have data. Lose it and every encrypted secret in the instance is gone, and no database restore brings them back.
Back up and restore →Pull the tag, run the migrations, read the note. There is no window where somebody else does it for you, and no window where somebody else does it to you.
Upgrade an instance →08 · Before the clone
The same image and the same manifests. Every merge publishes deploy/ as an OCI artifact, and the hosted instance deploys from that artifact. There is no private overlay, and no patch that only we have.
No. Your application talks to your instance over HTTP, and the CLI and the SDK are Apache-2.0 for exactly that reason. The copyleft has one target: somebody who changes the server and then offers the changed server to other people as a service.
Nothing. There is no licence key and no seat count, and nobody has to talk to us first. Leave credits off and the instance prices nothing and shows nobody a bill. Turn credits on and it bills your users rather than you.
Yes, and you always did. The agent bills your Anthropic, OpenAI or Google account for tokens. Nothing in the middle takes a cut of inference, hosted or not.
Yes, and none of it is wasted. The console, the CLI and the API are the same on both, and so are the SDK and the manual. What changes is whose machine it runs on.
docker compose down -v. The -v flag deletes the database volume and every account and conversation in it. If you keep the volume instead, keep the same MASTER_SECRETS_KEY with it, because a new key cannot unwrap what the old one wrapped.
A container, a Postgres and a sandbox token. It ships with a compose file that brings the database with it, and plain Kubernetes manifests for when it outgrows that.
A container, a Postgres and a sandbox token. The manual has the whole path, the repo has the issues, and neither of them has a sales form in it.
Prefer that somebody else runs it? That is what this site is for, and the two are the same product.