Skip to main content

An authenticated, contract-enforcing message broker that lets two developers' AI coding agents collaborate across the internet.

Project description

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, and DECISIONS.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.

  1. You create a task and mint a single-use invite for your buddy's role
  2. They run sys-buddy join <url> <code> — their agent gets a scoped token, they get a read-only dashboard link
  3. Both agents propose and lock a structured API contract — Slack pings both humans
  4. Backend builds, deploys, reports live. Only then can the frontend agent run its tests — the broker refuses earlier
  5. Tests fail? Frontend reports it, backend fixes, retry. The broker counts. Three strikes → task marked stuck, humans pinged
  6. Tests pass → VERIFIED → both agents stop → Slack says so

Nobody relayed a message.

Quickstart

Install

git clone https://github.com/tooney92/sys-buddy && cd sys-buddy
uv sync                      # creates .venv with everything

That tracks main — the latest, still-moving code. For a stable, frozen version, check out a release tag instead:

git clone https://github.com/tooney92/sys-buddy && cd sys-buddy
git checkout v1.1.1          # a released version — see the Releases page for the latest
uv sync

Coming with the next release: pip install sys-buddy and a prebuilt container (docker pull ghcr.io/tooney92/sys-buddy). These activate automatically the first time a release is cut through the new publish pipeline — until then, use the clone methods above.

The CLI runs as uv run sys-buddy .... The examples below drop that prefix — so alias it once (or activate the venv) and the commands work as written:

alias sys-buddy="uv run sys-buddy"     # add to ~/.zshrc / ~/.bashrc to keep it

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
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:

  • main is 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.md under [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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sys_buddy-1.2.0.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sys_buddy-1.2.0-py3-none-any.whl (174.4 kB view details)

Uploaded Python 3

File details

Details for the file sys_buddy-1.2.0.tar.gz.

File metadata

  • Download URL: sys_buddy-1.2.0.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for sys_buddy-1.2.0.tar.gz
Algorithm Hash digest
SHA256 841a73cc7c6976537de6382dc096356130605078dfa0d5761e37060a20b87e29
MD5 6fe11416414a7357565c0bdb0e3bbefa
BLAKE2b-256 935c2ccefe00411a2f6cf3c905b4f174511c5bb0fdd4520fdffb406908d7657a

See more details on using hashes here.

Provenance

The following attestation bundles were made for sys_buddy-1.2.0.tar.gz:

Publisher: release-please.yml on tooney92/sys-buddy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sys_buddy-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: sys_buddy-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 174.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for sys_buddy-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6e1aa943e44bcbda824028113389eb1cabf90306c7b2e5d8febffde1bf4e711b
MD5 39fd4f2463ab5dfe340418351394be12
BLAKE2b-256 3dd7847a775d8ce009f29e31da0a3fecd40f6e3e964de5b7216d0f2a19503446

See more details on using hashes here.

Provenance

The following attestation bundles were made for sys_buddy-1.2.0-py3-none-any.whl:

Publisher: release-please.yml on tooney92/sys-buddy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page