Self-hosting
Develop Oatmilk locally
Run Oatmilk from source with hot reload, local data services and, if you like, local AI models.
To change Oatmilk itself, run it from source with bun run dev. One command starts the data services it needs in Docker, so you don't need any cloud accounts to begin.
1. Install what it needs
- Node.js 24 and Bun 1.3.14, the versions
package.jsonpins. - Docker with Compose 2.20 or newer, for the data services.
2. Start the data services
git clone https://github.com/AGI-Ventures-Canada/oatmilk.git && cd oatmilk
bun install
bun run self-host devself-host dev starts PostgreSQL, Redis, the database API and file storage in Docker, applies every migration, and writes .env.development.local so bun run dev uses them and keeps accounts locally.
- Anyone can make an account on this install.
- Your own
.env.localis left alone, but.env.development.localwins over it. Delete.env.development.localto go back to your own settings.
3. Add AI models
Add one of these to .env.local:
OATMILK_MODEL_PROVIDER=ollama
OATMILK_LOCAL_MODEL=qwen3.5:9b
OATMILK_LOCAL_CLASSIFIER_MODEL=tev1
OATMILK_LOCAL_CLASSIFIER_API=systemoneAI_GATEWAY_API_KEY=…Use local AI models covers LM Studio and other servers. Here Oatmilk runs on your computer itself, so the default addresses, http://localhost:11434/v1 and http://localhost:1234/v1, work as they are.
4. Start Oatmilk
bun run devOpen <http://localhost:3000>, make an account and create your company. Changes to the code reload as you save.
5. Use your tools against it
- API: create a key in Developers › API keys (it starts with
oat_test_), and send requests tohttp://localhost:3000/api/v1/accounting/<action>. - Docs:
http://localhost:3000/docsuses your local address in every example. - MCP:
http://localhost:3000/api/mcp. - CLI:
oatmilk login --host localhost:3000, or from source:bun packages/cli/src/main.ts --host localhost:3000.
Stop
bun run self-host dev down # stops the data services; their data staysbun run dev keeps using them until you delete .env.development.local.
Before you send a change
bun run test
bun run typecheck
bun run lintCONTRIBUTING.md in the repository lists the full checks.