Acorn is a self-hosted AI agent backend for one owner and their devices.
Run Acorn on your own server, pair your phone, and use the mobile app to start work, inspect runs, review pending approvals, and keep the agent's durable state under your control.
- Single-owner self-hosted backend for personal deployments.
- Authenticated
/v1API with one-time device pairing. - Android mobile control surface for inbox, threads, runs, approvals, and settings.
- Persistent runs, run events, pending actions, tool results, workspace checkpoints, memory, and skills.
- File-backed long-term memory with hybrid semantic + keyword retrieval (sqlite-vec, opt-in).
- Linux
amd64andarm64release tarballs (pure Go cross-compilation, no CGO). - Signed Android APK published with each GitHub Release.
Acorn's supported deployment path is a Linux release tarball managed by systemd. Docker is not required, and the server does not need to build from source.
Install the latest release on Debian or Ubuntu:
curl -fsSL https://github.com/ycvk/acorn/releases/latest/download/install-release.sh | shThe installer installs Acorn's host dependencies and creates the systemd service.
Install and start the service in one step:
curl -fsSL https://github.com/ycvk/acorn/releases/latest/download/install-release.sh | OPENAI_API_KEY=your-provider-key shThe installer creates:
| Path | Purpose |
|---|---|
/opt/acorn/acorn |
Release binary |
/usr/local/bin/acorn |
Global command wrapper |
~/.acorn/acorn.yaml |
Backend configuration |
~/.acorn/acorn.env |
Provider secrets |
/srv/acorn/workspace |
Operator workspace |
/etc/systemd/system/acorn.service |
systemd service |
The installer uses the user that runs the script. On a typical root VPS install, Acorn reads /root/.acorn/acorn.yaml and /root/.acorn/acorn.env. Commands such as acorn pair and acorn doctor use the same config unless you pass -c.
If you did not pass OPENAI_API_KEY, edit the environment file and start the service:
sudoedit ~/.acorn/acorn.env
sudo systemctl enable --now acornVerify the backend:
curl http://127.0.0.1:8080/healthz
acorn doctorCreate a pairing QR for the mobile app:
acorn pair --server-url https://acorn.example.com --qrPrint the same mobile connection details for manual entry:
acorn pair --server-url https://acorn.example.comFor remote access, keep Acorn bound to 127.0.0.1:8080 and expose it through Tailscale, a reverse proxy, or a tunnel. See Self-hosted Onboarding for the full deployment guide.
Each GitHub Release includes a signed Android APK:
VERSION_URL=$(curl -fsSLo /dev/null -w '%{url_effective}' https://github.com/ycvk/acorn/releases/latest)
VERSION=${VERSION_URL##*/}
curl -fL -O "https://github.com/ycvk/acorn/releases/download/${VERSION}/acorn_mobile_${VERSION}_android.apk"
curl -fL -O "https://github.com/ycvk/acorn/releases/download/${VERSION}/acorn_mobile_${VERSION}_android.apk.sha256"
sha256sum -c "acorn_mobile_${VERSION}_android.apk.sha256"Open the app, scan or enter the pairing payload, and the device receives a bearer token. The token is shown once; the server stores only token hashes.
Local configuration starts from the example file:
cp configs/acorn.example.yaml configs/acorn.local.yaml
$EDITOR configs/acorn.local.yamlMinimal provider configuration:
providers:
- name: primary
model: gpt-4o
base_url: https://api.openai.com/v1
api_key: ${OPENAI_API_KEY}
enabled: trueProvider keys can reference environment variables. Missing provider credentials are reported by readiness checks instead of being silently ignored.
Remote clients use the authenticated /v1 API. Common endpoints include:
| Endpoint | Purpose |
|---|---|
GET /healthz |
Process health |
POST /v1/devices:pair |
Exchange a pairing code for a device token |
GET /v1/inbox |
Mobile-friendly aggregate of active work and pending approvals |
GET /v1/threads |
List threads |
POST /v1/threads |
Create a thread |
POST /v1/threads/{thread_id}/messages |
Append a user message |
POST /v1/threads/{thread_id}/runs |
Start a run |
GET /v1/runs/{run_id}/events?follow=true |
Replay and follow mobile live run events |
GET /v1/runs/{run_id}/detail |
Fetch a full run detail view |
GET /v1/pending-actions |
List pending approvals |
POST /v1/pending-actions/{action_id}:decide |
Accept or decline a pending action |
The full client contract is defined in docs/openapi.yaml. The Kotlin + Jetpack Compose mobile client is generated from that file.
Prerequisites:
- Go 1.26
golangci-lintgoimports- Kotlin + Jetpack Compose, if you work on the mobile app
Run the backend locally:
make doctor
make servePair a local mobile client or API client:
go run ./cmd/acorn pair -c configs/acorn.local.yaml --server-url http://127.0.0.1:8080 --qrRun checks before sending changes:
make test
make format-check
make lint
python3 mobile-kotlin/tool/generate_openapi_client.sh --check
git diff --checkMobile checks run from mobile-kotlin/:
./gradlew test
./gradlew lint
./gradlew assembleDebug| Path | Purpose |
|---|---|
cmd/acorn/ |
CLI entrypoint |
internal/wire/ |
Composition root — container wiring, the only place concrete implementations are instantiated |
internal/core/ |
Layer 0 domain types, store interfaces, tool contracts, plugin registry — zero internal imports |
internal/runtime/ |
Executor, RunnerFactory, direct_response, context session, masking, auto-compact, StreamItem projection |
internal/tools/ |
Tool implementations (file/git/browser/web/command/artifact), dispatch scheduler, ToolRegistry |
internal/store/ |
SQLite persisted state (modernc.org/sqlite, single-connection serialized) |
internal/memory/ |
File-backed memory records, hybrid semantic + keyword retrieval (sqlite-vec) |
internal/mcp/ |
MCP provider manager |
internal/workspace/ |
Mutation checkpoint and worktree |
internal/webaccess/ |
web_search / web_fetch / browser tools and shared URL policy |
internal/skills/ |
File-backed skill loader |
internal/config/ |
Config struct, defaults, validation |
internal/cli/ |
CLI command dispatch |
internal/api/ |
HTTP server, /healthz, /v1 |
mobile-kotlin/ |
Kotlin + Jetpack Compose mobile app |
skills/ |
Built-in Acorn skill seed pack |
docs/ |
User guides, developer guides, OpenAPI, and architecture notes |
Acorn is released under the Apache License 2.0.
