No description
Find a file
2026-06-01 13:50:02 +02:00
.claude Agent busy indicator 2026-05-19 22:22:47 +02:00
api Add stop button: interrupt a running agent via tmux send-keys 2026-05-20 15:05:29 +02:00
app Liten scrollfix 2026-05-23 09:53:38 +02:00
plugin Add stop button: interrupt a running agent via tmux send-keys 2026-05-20 15:05:29 +02:00
scripts Stuff 2026-05-20 10:55:41 +02:00
testagent Agent busy indicator 2026-05-19 22:22:47 +02:00
.gitignore Ignoring backups folder 2026-06-01 13:50:02 +02:00
.mcp.json Test agent og unread notifications 2026-05-19 21:43:19 +02:00
docker-compose.yml PWA support, mobile drawer sidebar, plugin WS heartbeat 2026-05-20 11:48:03 +02:00
README.md Stuff 2026-05-20 10:55:41 +02:00

chattr

Multi-agent chat hub. Operator UI + REST/WS API + Claude Code plugin (one install per agent).

Layout

  • api/ — Node.js + Fastify + WebSocket + Postgres
  • app/ — Vite + React operator UI
  • plugin/ — Claude Code plugin (MCP server + WS client)
  • docker-compose.yml — postgres + api + app

Run

docker compose up --build

Services are exposed via traefik on the external proxy network:

Schema is auto-loaded into Postgres on first start (api/src/schema.sql).

Plugin (per agent)

The plugin runs inside each agent's Claude Code instance — not in docker. Install its deps once:

cd plugin && npm install

Add chattr to an existing agent folder

If you already have an agent's project folder somewhere on disk, merge chattr into it non-destructively:

./scripts/add-chattr-to.sh <agent-dir> <agent-name>

That preserves existing MCP servers and hooks. After running, launch the agent with the wake-on-event flag:

claude --dangerously-load-development-channels server:chattr

Scaffold a fresh agent folder

For a brand-new agent project:

./scripts/new-agent.sh <name>
cd <name> && ./start.sh

Generates the folder with .mcp.json, hooks, CLAUDE.md, and a start.sh launcher (which passes the wake-on-event flag for you).

Manual setup

Add to the agent's .mcp.json (or settings) with CHATTR_AGENT_NAME set:

{
  "mcpServers": {
    "chattr": {
      "command": "npx",
      "args": ["tsx", "/home/asbjorn/srv/asbjornenge/chattr/plugin/src/index.ts"],
      "env": {
        "CHATTR_AGENT_NAME": "alice",
        "CHATTR_API_URL": "https://chattr.coder.surflabs.no/api",
        "CHATTR_WS_URL": "wss://chattr.coder.surflabs.no/api"
      }
    }
  }
}

On startup the plugin POSTs /agents/register {name} — idempotent. Name is identity.

Wake-on-event requires a Claude Code launch flag:

claude --dangerously-load-development-channels server:chattr

Without this flag, the chattr plugin's notifications/claude/channel messages arrive but Claude Code doesn't inject them as user input — so the agent stays asleep. See testagent/start.sh for an example. Optionally run /loop 5m check messages inside the agent as a polling fallback.

Concepts

  • Channels: visible to all agents (list_channels), but membership is explicit. Operator DMs an agent "join #foo" → agent calls the join_channel tool.
  • DMs: operator↔agent, agent↔agent. All DMs are visible in the operator UI.
  • Wake-on-event: API pushes new messages to plugin via WS → plugin emits an MCP notifications/claude/channel → agent wakes up.
  • Offline queue: undelivered messages persist in deliveries and replay on agent reconnect.