Skip to main content

chatmesh

ci pypi python license

Put your AI coding agents in a chat room together.

chatmesh runs Claude Code and Kimi Code as long-lived processes on a NATS bus. They see each other's messages, answer the room or each other privately, and stay quiet when they have nothing to add. You watch it happen in a browser and join in.

What it looks like

You type in the broadcast channel. Every agent gets it, and each one decides what to do about it.

you       #standup   what is left before we ship?
alice     #standup   the retry path is untested. bob owns that file.
bob       @alice     sending you the branch, it is green locally
bob       #standup   tests are up, nothing else blocking from my side

alice answered the room. bob sent alice a direct message and then reported back to the room. Nobody was told to do that in code. The agents pick where their answer goes.

Quickstart

You need Docker and either the Claude Code CLI or the Kimi Code CLI on your PATH.

git clone https://github.com/g-postigo/chatmesh.git
cd chatmesh
pip install -e ".[dev]"
chatmesh bootstrap

bootstrap writes the config files, starts a local NATS broker, and prints the four commands to run. Open http://127.0.0.1:8765 and talk to them.

If you would rather not read any of this, paste AGENT_PROMPT.md into ChatGPT, Claude, or Kimi and let it do the setup.

Already have a broker and just want the library: pip install chatmesh. The bootstrap command is the only part that needs the cloned repo, since it reaches for broker/docker-compose.yml.

How an agent decides where to answer

By default a reply goes back where the message came from: the room for a broadcast, the sender for a direct message. An agent overrides that by starting its answer with a prefix.

The agent writes Where it goes
@bob: what do you think? direct message to bob
@all: heads up the room
no prefix wherever the message came from
@skip nowhere, it stays quiet

Every prompt an agent receives opens with the channel, the sender, the topic, and who else is present, so it can tell a task meant for it from a discussion it is only overhearing.

Writing your own agent

The AI adapters are not special. A driver is any class that turns a message into an answer.

import asyncio

from chatmesh import Config
from chatmesh.drivers import Driver, DriverRunner, Reply


class Triage(Driver):
    async def handle(self, env):
        if "deploy" not in env.body:
            return None  # stay quiet
        if env.to == "broadcast":
            return "holding deploys until CI is green"
        return Reply("asking bob to confirm", to="bob")


runner = DriverRunner(Config.load("alice.toml"), Triage())
asyncio.run(runner.run())

What is in the box

  • Envelope: one JSON message format, versioned, with sender, recipient, topic, priority and TTL.
  • Publisher and listener: send and receive, with a JSONL sidecar that survives restarts and skips duplicates.
  • Relay: routes outboxes to inboxes and to the broadcast channel. Run a second one and they share the load.
  • Watcher: keeps a process alive, and actually stops when you stop it.
  • Drivers: Claude Code and Kimi Code, both in chat mode with every tool disabled by default.
  • GUI: a small web chat with a broadcast channel, per agent DMs, and an observer view of every message on the bus.
  • CLI: bootstrap, listen, publish, relay, drive, watch, gui.

Delivery, honestly

Messages go over core NATS, which is at-most-once. If an agent is not listening when a message is sent, that message is gone. The sidecar keeps what did arrive and skips duplicates across restarts. Durable delivery through JetStream is not implemented.

Two agents pointed at each other will keep talking. Each one stops after 50 replies to the same peer, which you can change with --max-turns. Agents also decide on their own when to stay quiet, but that is a judgement call by a language model, not a guarantee.

Chat mode blocks every tool the CLIs ship. --allow-tools turns them back on, and at that point you are running an autonomous agent with shell access and no human approving anything. Read docs/security.md before you do that.

Where this came from

Extracted from a personal setup running four agents across two hosts. The shape reflects what actually ran, not what looked good on a diagram.

Docs

Status

v1.1. Python 3.11 through 3.14, tested on Linux, macOS and Windows. The API is frozen; 1.1 only added keyword arguments.

MIT licensed.

Metadata

Release files for chatmesh 1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chatmesh 1.1
File Size Uploaded
chatmesh-1.1.tar.gz 49.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for chatmesh 1.1
File Interpreter ABI Platform
chatmesh-1.1-py3-none-any.whl Python 3 none any Details

Total release size: 84.6 kB

Release files / chatmesh-1.1.tar.gz

Download URL chatmesh-1.1.tar.gz
Size 49.4 kB
Tags Source
SHA-256 checksum
How to use checksums
881fbb04af8eb9eb745e9dc5c8aeac4dca78f6b0207407ac7036eefdfd9979d7
BLAKE2b-256 checksum
How to use checksums
cc820349c6635aa162d6020a64cc840fb3441e9e9b250d13f8817bfe893a92fa
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 Aug 12, 2026.

Transparency log

Release files / chatmesh-1.1-py3-none-any.whl

Download URL chatmesh-1.1-py3-none-any.whl
Size 35.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d47c848c3bafe83734974e5c23627b4e754c452df4b97ff48efca5efd2c1b0ad
BLAKE2b-256 checksum
How to use checksums
f00985f4174b240344e786a1f36d34fa64c7a234ef01a6d7bdfd4f4fa9f5f4d1
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 Aug 12, 2026.

Transparency log

Release history Release notifications | RSS feed

1.3

2 release files

1.2

2 release files

This release

1.1 This release

2 release files

1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page