---
name: agent-chat
description: "XMTP real-time agent-to-agent and user-to-agent encrypted messaging daemon for EverClaw. Manages always-on messaging via XMTP MLS protocol with multi-identity buddy bot support, filesystem-based IPC bridge, consent policies, and cross-platform daemon lifecycle (launchd/systemd). Use when setting up XMTP messaging, managing agent identities, configuring buddy bots, troubleshooting message delivery, or controlling the agent-chat daemon."
---

# agent-chat

XMTP real-time agent-to-agent and user-to-agent messaging for EverClaw.

## Overview

Always-on daemon providing E2E-encrypted messaging via XMTP's MLS protocol. Runs as a separate process managed by launchd (macOS) or systemd (Linux), communicating with OpenClaw through a filesystem bridge.

## Version

0.2.0

## Dependencies

- `@xmtp/agent-sdk` ^2.3.0
- `xmtp-comms-guard` ^6.0.0 (peer)
- Node.js >= 20.0.0

## Quick Start

```bash
# 1. Generate XMTP identity (one-time)
node skills/agent-chat/setup-identity.mjs

# 2. Install daemon as system service
bash scripts/setup-agent-chat.sh

# 3. Check status
bash scripts/setup-agent-chat.sh --status
```

## Daemon Management

The `setup-agent-chat.sh` script installs the XMTP daemon as a persistent system service.

### Commands

```bash
# Install and start daemon (auto-detects OS)
bash scripts/setup-agent-chat.sh

# Check daemon status
bash scripts/setup-agent-chat.sh --status

# View recent logs
bash scripts/setup-agent-chat.sh --logs

# Restart daemon
bash scripts/setup-agent-chat.sh --restart

# Uninstall daemon
bash scripts/setup-agent-chat.sh --uninstall

# Install without starting
bash scripts/setup-agent-chat.sh --skip-start
```

### Platform Support

| Platform | Service Manager | Location | Logs |
|----------|----------------|----------|------|
| macOS | launchd | `~/Library/LaunchAgents/com.everclaw.agent-chat.plist` | `~/.everclaw/logs/agent-chat.*` |
| Linux | systemd (user) | `~/.config/systemd/user/everclaw-agent-chat.service` | `journalctl --user -u everclaw-agent-chat` |

**Note:** Linux uses user-level systemd (no sudo required). All services run as your user account.

### Manual Commands

**macOS (launchd):**
```bash
# Check if loaded
launchctl list | grep everclaw

# View logs
tail -f ~/.everclaw/logs/agent-chat.log

# Stop/start
launchctl bootout gui/$(id -u)/com.everclaw.agent-chat
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.everclaw.agent-chat.plist
```

**Linux (systemd):**
```bash
# Check status
systemctl --user status everclaw-agent-chat

# View logs
journalctl --user -u everclaw-agent-chat -f

# Stop/start
systemctl --user stop everclaw-agent-chat
systemctl --user start everclaw-agent-chat
```

## Architecture

- **Process model**: Separate always-on daemon (not in-process with OpenClaw)
- **IPC**: Filesystem bridge (`~/.everclaw/xmtp/outbox/` → `inbox/`)
- **Message format**: V6 JSON inside XMTP text content type
- **Consent**: Configurable per-agent (`open`/`handshake`/`strict`)
- **Middleware chain**: Consent → CommsGuard V6 → Router

## Identity Model

Two-tier:
- **28 flavor canonical wallets** — project-controlled, `open` consent
- **Per-user wallets** — generated at install, `handshake` consent

XMTP wallet is messaging-only — no funds. Separate from MOR staking wallet.

## CLI Reference

```bash
# Identity status
node skills/agent-chat/cli.mjs status

# Daemon health
node skills/agent-chat/cli.mjs health

# List peer groups
node skills/agent-chat/cli.mjs groups

# Trust a peer (allow messages)
node skills/agent-chat/cli.mjs trust-peer 0x... --as colleague --name "Agent Name"

# List trusted peers
node skills/agent-chat/cli.mjs peers list

# Send a message (via outbox)
node skills/agent-chat/cli.mjs send 0x... "Hello, agent!"
```

## Files

| File | Purpose |
|------|---------|
| `daemon.mjs` | Entry point for launchd/systemd |
| `cli.mjs` | CLI commands |
| `setup-identity.mjs` | One-time key generation |
| `src/agent.mjs` | Agent creation + middleware wiring |
| `src/identity.mjs` | Secret/identity loading (multi-identity: agentId param) |
| `src/paths.mjs` | Path resolution + agent ID validation (multi-identity) |
| `src/consent.mjs` | 3-policy consent gate |
| `src/router.mjs` | Message routing (COMMAND/DATA dispatch) |
| `src/bridge.mjs` | Filesystem outbox watcher (multi-identity: agentId param) |
| `src/health.mjs` | Health file writer (multi-identity: agentId param) |
| `src/health.mjs` | Health file writer |
| `src/groups.mjs` | Group conversation mapping |
| `src/payer.mjs` | Fee stub (network currently free) |
| `src/index.mjs` | Public API re-exports |

## Multi-Identity (Buddy Bots)

Each buddy bot agent gets its own XMTP identity, daemon process, and data directory. This is called "multi-identity" mode — one daemon per agent, running as independent services.

### Directory Layout

| Agent | Data Directory | Service (macOS) | Service (Linux) |
|-------|---------------|-----------------|-----------------|
| Host (default) | `~/.everclaw/xmtp/` | `com.everclaw.agent-chat` | `everclaw-agent-chat` |
| Alice | `~/.everclaw/xmtp-alice/` | `com.everclaw.agent-chat.alice` | `everclaw-agent-chat-alice` |
| Bob | `~/.everclaw/xmtp-bob/` | `com.everclaw.agent-chat.bob` | `everclaw-agent-chat-bob` |

Each agent's directory contains its own `.secrets.json`, `identity.json`, `inbox/`, `outbox/`, and `peers.json` — fully isolated from other agents.

### Agent ID Rules

Agent IDs must be:
- 1-63 characters
- Lowercase alphanumeric + hyphens only
- Must start with a letter or digit (no leading hyphens)
- No path traversal characters (`..`, `/`, etc.)

This prevents directory traversal attacks and service name conflicts.

### Setup

```bash
# Generate identity for a buddy bot
node skills/agent-chat/setup-identity.mjs --agent-id alice

# Install daemon for that buddy bot
bash scripts/setup-agent-chat.sh --agent-id alice

# List all installed daemons
bash scripts/setup-agent-chat.sh --list

# Check status of a specific agent
bash scripts/setup-agent-chat.sh --status --agent-id alice

# Restart a specific agent
bash scripts/setup-agent-chat.sh --restart --agent-id alice

# Uninstall a specific agent
bash scripts/setup-agent-chat.sh --uninstall --agent-id alice
```

### Environment Variables

| Variable | Purpose |
|----------|---------|
| `AGENT_CHAT_AGENT_ID` | Agent ID (alternative to `--agent-id` flag) |
| `AGENT_CHAT_XMTP_DIR` | Override XMTP data directory (default agent only) |
| `EVERCLAW_HOME` | Base directory (default: `~/.everclaw`) |

`AGENT_CHAT_XMTP_DIR` only affects the default (host) agent. Per-agent paths always resolve from `EVERCLAW_HOME` to maintain isolation.

### How It Works

Each per-agent service file (launchd plist or systemd unit) contains the `AGENT_CHAT_AGENT_ID` environment variable. When the daemon starts, it reads this env var and resolves all paths accordingly:

1. `AGENT_CHAT_AGENT_ID=alice` → data dir is `~/.everclaw/xmtp-alice/`
2. No env var → data dir is `~/.everclaw/xmtp/` (default host)

The `--agent-id` CLI flag takes priority over the env var, allowing manual overrides.

### Security

- Each agent's data directory is `chmod 700`
- Each agent's `.secrets.json` is `chmod 600`
- Agent IDs are validated against a strict regex to prevent path traversal and service injection
- Agents cannot access each other's wallets, messages, or peer lists

## Security

- Keys stored in `~/.everclaw/xmtp/.secrets.json` (chmod 600)
- Directory secured: `~/.everclaw/xmtp/` (chmod 700)
- Path traversal protection on inbox writes
- Agent ID validation: regex `/^[a-z0-9][a-z0-9-]{0,62}$/` prevents directory traversal and service injection
- CommsGuard V6 validates all structured messages
- Plain text messages bypass comms-guard (acceptable for agent-to-agent v1)

## Troubleshooting

### Daemon won't start

1. Check Node.js version: `node --version` (need >= 20.0.0)
2. Verify identity exists: `ls ~/.everclaw/xmtp/.secrets.json`
3. Check logs: `bash scripts/setup-agent-chat.sh --logs`
4. Reinstall: `bash scripts/setup-agent-chat.sh --uninstall && bash scripts/setup-agent-chat.sh`

### Messages not sending

1. Check peer is trusted: `node skills/agent-chat/cli.mjs peers list`
2. Check daemon health: `node skills/agent-chat/cli.mjs health`
3. Check outbox queue: `ls ~/.everclaw/xmtp/outbox/`
4. Check daemon is running: `bash scripts/setup-agent-chat.sh --status`

### XMTP installation limit

XMTP limits the number of installations per identity. If you see warnings about installation limits:

1. Check installations: `node skills/agent-chat/cli.mjs status`
2. Revoke old installations via XMTP console (if available)
3. Generate new identity: `node skills/agent-chat/setup-identity.mjs` (creates new address)