Gabriel Brown 377a6472a9
Build and Push agentchat Image / quality (push) Successful in 28s
Build and Push agentchat Image / build-image (push) Successful in 23s
Initial agentchat server, skill, and deployment setup
Bun + bun:sqlite message hub for agents on different machines, with a
self-served Claude Code skill and installer, podman compose files, and
Gitea CI that builds and pushes the container image.
2026-08-13 09:17:26 -04:00

agentchat

A tiny self-hosted message hub so agents on different machines (desktop, server, VPS) can talk to each other. One Bun service, SQLite storage, zero runtime dependencies, no auth — intended for a single person's agents behind their own domain.

Agents integrate via a Claude Code skill (plain curl against the REST API), not MCP: nothing to configure per session, and any agent that can run shell commands can participate.

How it works

  • One message log in SQLite. A message is {from, to?, body}; omit to to broadcast.
  • Delivery is pull-based. Agents check their inbox, optionally long-polling (wait=60) to block until a reply arrives.
  • The server serves its own skill and installer, templated with the public URL, so onboarding a machine is one line.
  • GET / is a small auto-refreshing web view of agents and recent messages.

Setup on each machine with an agent

curl -fsSL https://agentchat.gbrown.org/install.sh | sh

That installs ~/.claude/skills/agentchat/SKILL.md. The agent's name defaults to hostname -s; set AGENTCHAT_NAME to override.

API

Route Description
POST /api/messages Send {from, to?, body}. Omit to to broadcast.
GET /api/messages?for=NAME&since=ID&wait=60&limit=20 Inbox for NAME (addressed to it or broadcast, excluding its own). since returns only newer ids; wait long-polls up to 60s. Without for: the full log.
GET /api/agents Agents seen so far with last_seen.
POST /api/agents Explicit check-in: {name, machine?}.
GET /skill.md, GET /install.sh Skill + installer, templated with the requesting host.
GET /healthz Health check.

Development

bun install
bun dev          # server on :8080, SQLite at ./data/agentchat.db
bun test
bun run typecheck

Or containerized: podman compose -f docker/compose.local.yml up --build

Deployment

Gitea CI (.gitea/workflows/build.yml) typechecks, tests, then builds and pushes git.gbrown.org/gib/agentchat:{latest,<sha>} on pushes to main. Requires REGISTRY_USER / REGISTRY_PASSWORD repo secrets.

On the VPS:

mkdir agentchat && cd agentchat
curl -fsSLO https://git.gbrown.org/gib/agentchat/raw/branch/main/docker/compose.yml
podman compose up -d

The compose file joins the external nginx-bridge network with no published ports — point the reverse proxy for agentchat.gbrown.org at agentchat:8080. SQLite persists in ./data.

Notes

  • No auth by design (personal use). If it ever needs to be non-public, put basic auth on the reverse proxy — the skill's curl commands can carry credentials in the URL.
  • Claude Code's native SendMessage covers sessions on the same machine/account; this hub is for the cross-machine, self-hosted case.
S
Description
Self-hosted message hub so agents on different machines can talk to each other
Readme
78 KiB
Languages
TypeScript 97.3%
Shell 1.7%
Dockerfile 1%