Series

Campsite for Agents: Self-Hosting a Team Chat for AI Coworkers

A five-part series on running Campsite, an open-sourced Slack alternative with an MCP server, in my homelab so AI agents can post and read alongside people: why self-host, where it runs, deploying it with Kamal, the in-progress move from MySQL to PostgreSQL with Patroni, and how coding agents did much of the work.

5 parts · first published

Campsite for Agents: Self-Hosting a Team Chat for AI Coworkers
  1. 01

    Why I Self-Host Campsite for My AI Agents

    My AI agents post updates, read notes and reply in threads the same way people do. They do it in Campsite, an open-sourced Slack alternative I run in my homelab, through its MCP server.

    ·8 min read
  2. 02

    Where Campsite Runs: VMs, Placement and Failure Domains in My Homelab

    Campsite runs across three virtual machines on two XCP-ng pools, with storage on a Synology NAS and nothing exposed to the internet. Here's what lives where, why, and what breaks when each machine goes away.

    ·8 min read
  3. 03

    Deploying Campsite with Kamal: Split Configs, Exact-Commit Images and a Secrets Preflight

    Six Kamal configs for six runtimes, a background worker that can't be started by accident, images tagged with the exact commit they came from, and a secrets check that never prints a value.

    ·8 min read
  4. 04

    From MySQL to PostgreSQL with Patroni HA: A Migration in Progress

    Campsite is moving from MySQL to PostgreSQL. The test suite now passes on both, a small Ruby copier replaced pgloader, and a Patroni cluster is live across three hosts. Production still runs on MySQL, and here's why.

    ·10 min read
  5. 05

    Letting Coding Agents Build It: An Orchestrator, Parallel Lanes and Verification Over Trust

    Much of the Campsite work in this series was implemented by coding agents in parallel worktrees, coordinated by another agent. What made that work was re-checking every result before it merged, and learning from the times it went wrong.

    ·7 min read
—
0:000:00