Self-hosted MCP control plane

Run AI coding agents like a small, observable fleet.

Chetter gives Claude, OpenCode, ChatGPT, curl, or your own agent stack a simple MCP tool surface for submitting development work to remote containerized runners.

20MCP tools
1durable queue
1database
manyinterchangeable runners

How it works

One Go service coordinates the work. Runners do the execution.

Chetter stays deliberately small: the MCP server accepts tool calls, stores task state, publishes work to NATS JetStream, and ingests runner events. Runners clone repositories, start coding agents, stream progress, and report results.

1. SubmitMCP tool call creates a task row and publishes to JetStream.
2. QueueWorkQueue retention delivers each task to one runner.
3. RunA containerized runner executes OpenCode against the repository.
4. ObserveEvents are persisted for status, progress, and audit trails.

Architecture

A boring stack on purpose.

client

Any MCP-capable caller

Use Claude, OpenCode, Cursor-style clients, curl, or custom automation. The interface is tools plus JSON, not a custom dashboard.

control plane

Stateless HTTP MCP server

A small Go process exposes /mcp and /healthz, registers schema-driven tools, schedules cron jobs, and records events.

transport

NATS JetStream

One stream for durable tasks, one stream for replayable events. Add runners without teaching the server how many exist.

state

MySQL or TiDB

Five straightforward tables hold tasks, raw events, schedules, schedule runs, and runner metadata. Secrets are redacted.

Why developers use it

Useful automation without a giant platform.

Remote, isolated execution

Keep agent work off your laptop. Runners execute inside containers with explicit CPU, memory, timeout, image, model, and provider settings.

Durable by default

Tasks survive runner restarts. Events are written before ack. Terminal task states are updated idempotently to make replays safe.

GitOps schedules

Recurring jobs live in schedules/*.yaml, sync into MySQL, and re-activate on restart. Nightly docs, changelogs, audits, and scans fit naturally.

Readable codebase

The main surface is a few focused Go packages: service orchestration, MCP tools, store, bus, config, and optional Arcane vulnerability scanning.

Standard protocols

Streamable HTTP MCP, JSON-RPC semantics, NATS, MySQL wire compatibility, Docker Compose, and cron. No proprietary agent protocol required.

Built for operators

Inspect status, logs, latest events, progress summaries, fleet health, runner image digests, model IDs, and OpenCode session IDs from MCP.

Tool surface

Everything is exposed as MCP tools.

Chetter is designed for AI clients first. Tool schemas are generated from Go structs, so the implementation and JSON contracts stay aligned.

Taskssubmit, status, list, cancel, clear queue
Eventsfull history, progress, latest event
Schedulescreate, update, run now, list, sync, delete
Fleetrunner health inferred from task activity
Arcaneoptional Trivy-backed image vulnerability tools

Quick start

Bring up the control plane and two runners with Compose.

Clone the repo, configure tokens, start the stack, then point your MCP client at /mcp. Use a GITHUB_TOKEN when runners need private repo access or pull request permissions.

Deployment shape

Small enough to understand, useful enough to automate real work.

NATSJetStream enabled, token auth
chetter-mcpGo MCP server on port 18088
MySQL / TiDBtask state, schedules, event log
runnersone image, many workers

Production can use an external MySQL or TiDB by setting DATABASE_DSN. The bundled local compose override is there for fast evaluation.