Vibeprod

Your agents, your machine, your keys.

A self-hosted control plane for opencode. One web UI over many sessions — each in its own Docker container — started by hand, by cron, by webhook, or from a chat.

MIT licensed ~6k lines of Python SQLite, no queue Bring your own key Login on the front door

Triggers

manualyou, in the web UI
schedulecron, with a timezone
webhookPOST from CI or anywhere
telegrama message to your bot
broker
FastAPI · SQLite

One container per session

code-reviewer own workspace · own port · own token
nightly-tests history kept on a docker volume
oncall-triage killed after its idle timeout

nothing leaves the machine — not the code, not the keys

The problem

Terminal agents don't schedule themselves

opencode is an excellent coding agent, and it lives in your terminal — one session, in front of you, while you watch it. The moment you want a second one, or a nightly run, or an agent that answers a webhook from CI, you are on your own.

The hosted products solve that, and charge for it: your code goes to their sandbox, your automation lives behind their subscription. Vibeprod solves it on your hardware instead. It is one FastAPI process with a SQLite file next to it — no queue, no Kubernetes, no build step in the frontend.

What you get

A console for agents that keep running

Every session, in one place

Sessions are tagged by what started them, so a nightly cron run and a Telegram question sit in the same list with the same transcript. A worker can be restarted without losing the thread — history lives on a Docker volume, not in the container.

The sessions list, with runs labelled telegram, schedule and webhook alongside their status.
Sessions — labelled by trigger, live status on the right

Watch the agent think

The broker reads the worker's SSE stream and fans it out over a WebSocket. Tool calls, reasoning blocks and todo lists appear as they happen; compact events go to SQLite and the full transcript is kept when the session goes idle.

A session transcript showing collapsed tool calls for a GitHub lookup, a file read and a test run, followed by the agent's written review.
A code-review session — tool calls collapse, the answer stays readable

Agents defined once, reused everywhere

An agent is a row in SQLite — model, mode, temperature, permissions, system prompt — plus the MCP servers and skills attached to it. At session start that becomes a stock opencode.json and a set of markdown files in the worker's workspace. Nothing proprietary: what the worker sees is ordinary opencode configuration.

The agents page listing code-reviewer, general, oncall-triage, release-notes and web-researcher, each with its model, MCP servers and skills.
Agents — model, attached MCP servers and skills on each card

Automation that ships with the box

Cron schedules carry a timezone and record every run. Webhooks give any external system a URL to start an agent, optionally guarded by a secret, optionally blocking until the answer is ready. Telegram runs inside the broker on long polling — no public URL, no extra dependency — and streams the reply by editing the bot's message. Point it at a notification chat and every scheduled or webhook run reports back there, either always or only when it fails.

Three cron schedules with their expressions, timezone, next run time and last result.
Schedules — cron with a timezone, next and last run on every card

Events that go out, not just in

Outgoing webhooks turn the broker into a source of events instead of only a target. Subscribe a URL to session.completed, session.failed, schedule.fired or webhook.received and it gets a POST with the session summary. Set a secret and the raw body is signed with HMAC-SHA256. Failed deliveries retry with backoff — 1s, 5s, 15s, 60s, 300s — and every attempt, successful or not, stays in the per-webhook delivery log with its response code, ready to be replayed by hand.

POST https://ci.example.com/hooks/vibeprod
X-Vibeprod-Event: session.completed
X-Vibeprod-Signature: sha256=…

{"event": "session.completed",
 "timestamp": "2026-08-15T09:00:00Z",
 "data": {"id": "…", "title": "Review PR #482", "result_text": "…"}}

Files that outlive the container

A worker's workspace disappears with the worker. Project files don't: every project gets its own bucket in a MinIO container that comes with the compose file, browsable and uploadable from the Files page. Agents reach the same storage through the files MCP server in the catalog — one click to attach — whose upload_file tool pushes a file out of the worker and returns a link. Together with Playwright and the bundled screenshot-to-files skill that is a complete loop: take a screenshot, put it in the project, answer with the URL.

A browser, a database, an API — one click each

The MCP catalog holds reusable servers: ordinary local and remote ones, and Docker services that Vibeprod starts on demand. The bundled Playwright service gives any agent a real browser in its own container, on a private network the workers share.

The MCP catalog listing a built-in Playwright docker service plus GitHub, Postgres and Sentry servers.
MCP catalog — attach any entry to an agent from its card

Keys you can actually verify

Provider keys live in your database and are injected into workers as environment variables. Check spins up a throwaway container with the same opencode image and your key, confirms the provider registers, lists the models it offers and makes a real generation call — the exact path a worker will take, so a bad key fails here instead of halfway through a scheduled run.

The providers page showing Anthropic, DeepSeek and OpenAI, each with a masked key, available models and a successful test call.
Providers — verified against a real container, not a regex

A lock on the front door

Put a login and password in .env and the UI asks for them: pages and the whole API move behind a signed cookie that lasts a week. Webhook endpoints keep their own secret and the operator's MCP endpoint keeps its bearer token, so automation carries on working. Leave both variables empty and nothing changes — no login at all, the way it was. This is one shared account, not user management: there is no user list, no roles, and no audit trail.

The unusual part

The agent configures the platform

Vibeprod ships with an operator agent that reaches back into Vibeprod itself through a private MCP server living inside the broker. Describe what you want on the home screen — “review agent for pull requests, give it GitHub, run it from a webhook” — and it creates the agents, attaches the MCP servers and skills, adds the providers, checks the keys, wires up the webhook and the schedule, and can put files into the project's storage on the way. You watch it happen in a normal session transcript, and nothing gets deleted without your say-so.

The operator's MCP endpoint is not in the catalog and cannot be attached to other agents: its URL and bearer secret are injected only into operator sessions.

Comparison

Where Vibeprod wins, and where it doesn't

This is a small project, not a competitor to funded platforms on breadth or maturity. It wins on one axis — self-hosted automation with no cloud tier — and loses on another: the login it now has is a single shared account, with no users, roles or audit trail behind it.

  Vibeprod OpenHands opencode Goose Devin · Jules · Codex cloud · Cursor agents
License MITMITMITApache-2.0Proprietary
Self-hosted Only optionYes, plus a managed cloudYesYesNo
Web UI over many sessions YesYesNo — TUI and serve APINo — desktop and CLIYes, vendor-hosted
Container per session YesYesRuns on the hostRuns on the hostVendor sandbox
Cron schedules Built inCloud tierNoNoVaries
Inbound webhooks Built inCloud tierNoNoVaries
Outbound webhooks Built inVariesNoNoVaries
Chat channel (Telegram) YesNoNoNoNo
MCP support Yes, shared catalogYesYesYesVaries
Agent that configures the platform YesNoNoNoNo
Bring your own key YesYesYesYesSubscription
Git and pull-request workflow Via the agent and gitFirst-classFirst-classYesFirst-class
Auth, multi-user, RBAC One shared login, no rolesEnterprise tiern/an/aYes
Maturity EarlyLarge, fundedVery largeLinux FoundationCommercial

Compiled August 2026 from public documentation. Hosted products move quickly — check the vendor's own pages before making a decision on this table alone.

Pick Vibeprod if

You want agents on your own hardware, started by cron, webhooks and chat, reporting back over webhooks and Telegram, with per-session isolation and API keys that never leave the box.

Pick something else if

You need per-user access control for a team, a hosted service with an SLA, or a mature pull-request review workflow out of the box.

Quick start

Running in about a minute

You need Docker and Python 3.11+ — or just Docker. The first start pulls the opencode image and builds a worker image on top of it, with git and openssh so agents can work with repositories.

On the host

# clone, configure, run
git clone https://github.com/katskov-dev/vibeprod.git
cd vibeprod
cp .env.example .env   # add one provider key
./run.sh               # → localhost:8000

In a container

# same thing, dockerised
git clone https://github.com/katskov-dev/vibeprod.git
cd vibeprod
cp .env.example .env
docker compose up --build

Ask for a login, and for file storage

# .env — both empty means no login at all
VIBEPROD_LOGIN=admin
VIBEPROD_PASSWORD=change-me

# project files live in MinIO; compose brings it up on loopback
docker compose up -d minio   # API 9000 · console 9001

Start an agent from anywhere

curl -X POST http://localhost:8000/api/webhooks/pr-review/run \
     -H 'X-Webhook-Secret: …' \
     -H 'Content-Type: application/json' \
     -d '{"prompt": "Review the diff in PR #482"}'

Before you put this on a server

The login is a single shared password, and the broker drives the Docker daemon — so anyone who gets past it can run code as root on the host. Compose binds the port to 127.0.0.1 for that reason, and leaving VIBEPROD_LOGIN unset means no login at all. Treat the login as a lock on an internal door, not as a reason to expose the port: to reach it remotely, still put it behind a reverse proxy with TLS, or a VPN. The details are in SECURITY.md.