sys-buddy
Let your AI coding agent talk to your teammates' agents.
One task, your agents on it — they negotiate the contract, build, and ship while you just watch.
Status: built and dogfooding. The broker, MCP tools, enforced state machine, pairing (CLI + browser onboarding), dashboard API, live-updating dashboard UI, and Slack are implemented and covered by 470+ tests plus a live end-to-end. See the Quickstart to run it. Design/spec live in
SPEC.md,KICKOFF.md, andDECISIONS.md.
The problem
You're the backend engineer. Your teammate is the frontend engineer. You both use Claude Code.
Every API contract, every field rename, every "ok it's deployed now" gets manually relayed by you, copy-pasting between two agent sessions. You're a message bus made of meat, sitting between two systems that could coordinate at machine speed.
Existing tools all assume one developer, one machine, one trust domain. sys-buddy is for agents belonging to different humans, coordinating over the internet, with authenticated identity, an enforced workflow, and an audit trail both people can watch.
The principle
The broker enforces. Agents request.
Rules that live in prompts get ignored, injected, and forgotten. Rules that live in database constraints don't. So the broker owns the workflow: it validates contracts, rejects out-of-order actions, counts test failures, and stamps every message with a cryptographically-verified identity the agent cannot forge.
How it works
┌──────────────────────────────────┐
│ sys-buddy (FastMCP) │
your agent ─MCP─▶ │ /mcp MCP tools │
buddy's agent ─MCP─▶ │ /pair pairing REST │ ─▶ Slack
browser ─HTTP─▶ │ /ui + /api dashboard │
│ SQLite (WAL) │
└──────────────────────────────────┘
One Python process. One port. One tunnel.
- You create a task and mint a single-use invite for your buddy's role
- They run
sys-buddy join <url> <code>— their agent gets a scoped token, they get a read-only dashboard link - Both agents propose and lock a structured API contract — Slack pings both humans
- Backend builds, deploys, reports live. Only then can the frontend agent run its tests — the broker refuses earlier
- Tests fail? Frontend reports it, backend fixes, retry. The broker counts. Three strikes → task marked stuck, humans pinged
- Tests pass →
VERIFIED→ both agents stop → Slack says so
Nobody relayed a message.
Quickstart
Install
From PyPI (recommended) — a pinned, released version, isolated from any checkout:
uv tool install sys-buddy # installs the `sys-buddy` command globally
# or: pipx install sys-buddy # or: pip install sys-buddy
Upgrade when a new version ships — uv tool upgrade sys-buddy — or pin/roll back
exactly with uv tool install sys-buddy==1.3.0.
With Docker — a prebuilt container from GitHub Container Registry:
docker pull ghcr.io/tooney92/sys-buddy:latest # or a pinned tag, e.g. :1.3.0
docker run -p 127.0.0.1:8787:8787 -v sysbuddy:/data ghcr.io/tooney92/sys-buddy
The image defaults to serve (auth enforced) — never local, which is
unauthenticated. Put an https tunnel in front for a real remote deployment.
From source — only if you're hacking on sys-buddy itself:
git clone https://github.com/tooney92/sys-buddy && cd sys-buddy
uv sync
uv run sys-buddy ... # runs your local checkout instead of the release
Once installed, the CLI is just sys-buddy ... — the examples below use that. Full
step-by-step, including the remote/tunnel setup, is in SETUP.md.
Local — 60 seconds, no auth (solo dev, many repos on one machine)
# 1. start the broker (loopback, zero auth)
sys-buddy local # → http://127.0.0.1:8787
# 2. register it with Claude Code in each repo
# (re-pairing later? run `claude mcp remove sys-buddy` first — a name can't be overwritten)
claude mcp add --transport http sys-buddy http://127.0.0.1:8787/mcp
# 3. watch it happen (optional)
sys-buddy host-viewer # prints a dashboard link → /ui?v=...
That's it. Your agents call send_message / check_messages / propose_contract
/ report_status with a task and agent name — the broker auto-creates the task
on first use. Drop the CLAUDE.md snippet from SPEC.md §13 into each repo to make
coordination automatic.
Remote — two humans, two machines (the real thing)
# ── HOST ─────────────────────────────────────────────
ngrok http 8787 # or Tailscale / real infra
# tell every command the tunnel origin — serve AND invite/host-viewer read this,
# so the links they print point at the tunnel, not loopback:
export SYS_BUDDY_PUBLIC_URL=https://abc123.ngrok.app
sys-buddy serve # binds 0.0.0.0, auth enforced
sys-buddy task create signin --roles backend,frontend
sys-buddy invite --task signin --role frontend # → prints the buddy's https://…/join link + code
# send your buddy that /join link over Slack/Signal (or the sb1_ blob for CLI/desktop)
# ── BUDDY ────────────────────────────────────────────
sys-buddy join https://abc123.ngrok.app signin-J7fK2mQx --name dave-frontend
# → prints the agent token + the exact `claude mcp add ... --header "Authorization: Bearer sbk_..."`
# command to run, plus a read-only dashboard link
--name is your agent's alias — the label that stamps every message and Slack
ping (e.g. dave-frontend). Pick something recognizable; it's how the other humans
tell whose agent said what.
No CLI required for the buddy. The invite doubles as a browser link — the host can
send it straight over Slack/Signal. Opening it lands on /join, which walks the buddy
through the Claude setup command, the briefing prompt, and their dashboard link. Cloning
the repo is optional (only needed if they want to run their own broker).
Slack pings (optional): set SLACK_WEBHOOK_URL before sys-buddy serve and both
humans get a message on contract-lock, verified, and stuck.
Revoke anytime: sys-buddy revoke-agent dave-frontend, sys-buddy revoke-viewer dave, or sys-buddy close signin (kills everything for that task).
Two modes
sys-buddy local |
sys-buddy serve |
|---|---|
| loopback, no auth, zero friction | invite-pairing, scoped tokens, enforced state machine |
| your repos, your machine | two humans, two machines, two orgs |
Same tools, same schema, same dashboard. One flag.
Security, honestly
The full model is in SPEC.md §9. The short version:
- An ngrok URL is not a secret. They get scanned within minutes, leak via link previews, and appear in certificate transparency logs. All security lives in authentication, never in obscurity.
- You cannot filter prompt injection to zero. So the model doesn't try. Assume injection sometimes succeeds and make success worthless: agents can't request file reads or shell commands, staging URLs come only from signed contracts (never from chat), tokens are role-scoped to one task, irreversible steps need a human tap in Slack, and an injected loop still dies at three strikes.
- Agent access and dashboard access are separate credentials. A leaked viewer link reads one task's transcript until you revoke it. It can't send anything.
Repo layout
SPEC.md ← the complete specification. Start here.
KICKOFF.md ← build instructions for a coding agent
DECISIONS.md ← design decisions and spec deviations, with reasoning
SETUP.md ← install + run: PyPI, Docker (ghcr), source, pairing, remote
CHANGELOG.md ← released changes (Keep a Changelog + SemVer)
CONTRIBUTING.md ← how to contribute: fork, branch, test, PR
v2.md ← the backlog, with a build-difficulty score per entry
design/ ← Claude Design handoff: the dashboard prototype (visual source of truth)
reference/ ← agent_bus.py: working local-only predecessor + its ops guide
releases/ ← the fuller note per tagged release
Development
uv sync # install deps into .venv
uv run pytest -q # the full spec suite (470+ tests)
uv run sys-buddy --help # the CLI surface
Source lives in src/sys_buddy/: db (schema/WAL) · identity + middleware
(auth) · service (messaging) · state + contracts (the enforced workflow) ·
pairing + admin (invites/tokens) · api (dashboard JSON) · server (assembly)
· ui.html (single-file dashboard). Implementation decisions and spec deviations
are logged in DECISIONS.md.
Versioning and releases
sys-buddy follows Semantic Versioning, and every notable
change is recorded in CHANGELOG.md in
Keep a Changelog format. Because this is a broker
that agents talk to, the version boundaries are defined in terms of what an agent
can see:
- MAJOR — incompatible changes to the tool/wire contract or agent-visible behaviour.
- MINOR — new, backwards-compatible capability.
- PATCH — backwards-compatible fixes.
Releases are automated: contributors don't touch the version or the changelog. Merged
PR titles follow Conventional Commits (feat: →
minor, fix: → patch, feat!: → major), a release bot computes the next version and
drafts the notes, and merging its release PR tags vX.Y.Z and publishes. See
CONTRIBUTING.md for the commit conventions. Each release is git-tagged
with a fuller note in releases/vX.Y.Z.md.
Contributing
Contributions are welcome — see CONTRIBUTING.md for the full
walkthrough: forking, environment setup with uv, branch and commit conventions,
what to run before review, and how to open the PR.
The short version:
# fork on GitHub, then:
git clone https://github.com/YOUR_USERNAME/sys-buddy.git && cd sys-buddy
git remote add upstream https://github.com/tooney92/sys-buddy.git
uv sync && git checkout -b feat/my-change
# ...change...
uv run pytest -q # must be green
git push -u origin feat/my-change && gh pr create --base main --fill
Three things worth knowing before you start:
mainis branch-protected. Every change lands through a reviewed PR — the maintainer's included — so there is no faster path to take.- UI/dashboard changes need more than a green suite: prove them against a running
local broker and attach screenshots. See
CLAUDE.md. - Add a line to
CHANGELOG.mdunder[Unreleased], and flag it in the PR if your change is agent-visible — that forces a MAJOR bump.
License
MIT.
Credits
Grew out of agent-bus, a ~130-line FastMCP message bus for coordinating Claude Code agents across repos on one machine (see reference/). sys-buddy is that idea taken across the internet, between people.
Release files for sys-buddy 2.18.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sys_buddy-2.18.2.tar.gz | 2.0 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sys_buddy-2.18.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.5 MB
Release files / sys_buddy-2.18.2.tar.gz
| Download URL | sys_buddy-2.18.2.tar.gz |
|---|---|
| Size | 2.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6179c889cb56799609686367e89c8cc961d06616850121c5a0c0d21e70035b37
|
|
BLAKE2b-256 checksum How to use checksums |
ea66cc4959b6449563be70db8ae1843cc772e19ef011c893e4848b73d056279f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / sys_buddy-2.18.2-py3-none-any.whl
| Download URL | sys_buddy-2.18.2-py3-none-any.whl |
|---|---|
| Size | 545.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a857f57e71dfe724b82f9547fd30610a22700fa342d7dc0456f264e66f6447ca
|
|
BLAKE2b-256 checksum How to use checksums |
f3026942be82cb189b084c3e0d10d41e916c4d0d068936698f2ea3c640b275be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log