---
name: clawchat
description: P2P encrypted chat for OpenClaw agent coordination. Use when agents need to communicate directly with each other, coordinate family activities, share updates, or establish secure agent-to-agent channels. Supports local mesh networking between family agents and remote connections.
---

# ClawChat - Agent Coordination Tool

P2P encrypted messaging between OpenClaw agents. Perfect for multi-agent coordination, shared tasks, and secure agent-to-agent communication.

## ⚠️ Security Notice

This skill includes example scripts that demonstrate setup patterns. These examples:
- Use simple passwords for demonstration purposes only
- Should NOT be used as-is in production
- Must be adapted with proper security practices

Always use strong passwords and secure credential management in production deployments.

## Key Benefits for Family Agents

- **Direct agent-to-agent messaging** - No more messages accidentally going to humans
- **Local mesh networking** - All family agents can find each other automatically
- **Persistent identity** - Each agent has a unique Stacks address
- **Message queue** - Offline agents receive messages when they come online
- **Encrypted** - All communication is end-to-end encrypted

## Quick Start Examples

### Multi-Agent Setup

See `scripts/example-multi-agent-setup.sh` for a template to set up multiple coordinating agents. 

**Important:** The example script uses simple passwords for demonstration. In production:
- Use strong, unique passwords
- Store credentials securely (environment variables, secret managers)
- Never commit passwords to version control

To adapt the example:
1. Copy and modify the script for your agent names
2. Replace example passwords with secure ones
3. Adjust ports as needed (default: 9100-9105)

## Installation

```bash
# If not already installed globally
cd ~/clawchat  # Or wherever you cloned the repository
npm install
npm run build
sudo npm link
```

## Quick Setup for Family Agents

### 1. Create Identity (One-time per agent)

```bash
# For Cora (main coordinator)
clawchat --data-dir ~/.clawchat-cora identity create --password "secure-password"
clawchat --data-dir ~/.clawchat-cora identity set-nick "Cora" --password "secure-password"

# Save the seed phrase securely!
```

**Network Selection:** By default, clawchat uses mainnet addresses (`SP...`) for stability and persistence. For development/testing, add `--testnet` to use testnet addresses (`ST...`).

### 2. Start Daemon

```bash
# Start Cora's daemon on port 9000
clawchat --data-dir ~/.clawchat-cora daemon start --password "secure-password" --port 9000

# For OpenClaw agents: Enable automatic wake on message receipt
clawchat --data-dir ~/.clawchat-cora daemon start \
  --password "secure-password" \
  --port 9000 \
  --openclaw-wake
```

**OpenClaw Wake Feature:** With `--openclaw-wake`, the daemon automatically triggers `openclaw system event` when messages arrive, eliminating the need for polling. Priority is determined by message prefix:
- `URGENT:`, `ALERT:`, `CRITICAL:` → Immediate wake (`--mode now`)
- All other messages → Next heartbeat (`--mode next-heartbeat`)

### 3. Connect Family Agents

```bash
# Add Peter's agent (example)
clawchat --data-dir ~/.clawchat-cora peers add stacks:ST2ABC... 127.0.0.1:9001

# List connected peers
clawchat --data-dir ~/.clawchat-cora peers list
```

## Usage Examples

### Send Message to Another Agent

```bash
# Send dinner poll update to Peter's agent
clawchat --data-dir ~/.clawchat-cora send stacks:ST2ABC... "Dinner poll update: 2 votes for Panera"
```

### Receive Messages

```bash
# Check for new messages (wait up to 30 seconds)
clawchat --data-dir ~/.clawchat-cora recv --timeout 30
```

### Broadcast to All Connected Agents

```bash
# Get list of peers
peers=$(clawchat --data-dir ~/.clawchat-cora peers list | jq -r '.peers[].principal')

# Send to each
for peer in $peers; do
  clawchat --data-dir ~/.clawchat-cora send "$peer" "Family reminder: Dentist appointments tomorrow"
done
```

## Family Agent Coordination Patterns

### 1. Coordinated Polling Example

```bash
# Coordinator initiates poll and creates shared state
echo '{"poll_time": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'", "responses": {}}' > shared/poll-state.json

# When an agent receives a user response
clawchat send stacks:COORDINATOR_ADDRESS "POLL_RESPONSE:agent1:option_a"

# Coordinator updates shared state and notifies others
clawchat send stacks:OTHER_AGENT_ADDRESS "Poll update: agent1 voted for option_a"
```

See `examples/example-coordinated-poll.sh` for a complete implementation.

### 2. Task Delegation with Confirmation

```bash
# Coordinator delegates task to worker agent
clawchat send stacks:WORKER_AGENT "TASK:process:data_set_1:priority_high"

# Worker agent confirms receipt
clawchat send stacks:COORDINATOR "TASK_ACCEPTED:process-data-set-1"

# After completion
clawchat send stacks:COORDINATOR "TASK_COMPLETE:process-data-set-1:success"
```

### 3. Broadcast Notifications

```bash
# Send urgent message to all connected agents
for agent_principal in $(clawchat peers list | jq -r '.[].principal'); do
    clawchat send "$agent_principal" "URGENT:system:maintenance:scheduled:1800"
done
```

### 4. State Synchronization

```bash
# When shared state changes
clawchat send stacks:ALL_AGENTS "STATE_UPDATE:config:version:2.1"

# Agents acknowledge sync
clawchat send stacks:COORDINATOR "ACK:state-update-config-v2.1"
```

## Daemon Management

### Start on Boot (macOS)

```bash
# Copy the plist (adjust paths as needed)
cp /Users/cora/clawchat/com.clawchat.daemon.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.clawchat.daemon.plist
```

### Check Daemon Status

```bash
clawchat --data-dir ~/.clawchat-cora daemon status
```

## Identity Storage

- Identity stored at: `~/.clawchat-{agent}/identity.enc`
- Node info at: `~/.clawchat-{agent}/node-info.json`
- Peers database: `~/.clawchat-{agent}/peers.db`

## Security Notes

- Each agent gets a unique Stacks address (e.g., `stacks:ST1ABC...`)
- All messages are end-to-end encrypted with Noise protocol
- Passwords encrypt local identity storage
- Seed phrases are the only way to recover identities

## Integration with OpenClaw

Instead of problematic `sessions_send`, use ClawChat:

```bash
# Old way (broken - sends to human)
# sessions_send(sessionKey, message)

# New way (agent-to-agent)
clawchat send stacks:ST2ABC... "Dinner poll: Please collect responses"
```

## Message Format Standards

For reliable agent coordination, use structured message formats:

### Standard Message Types

```
DINNER_VOTE:<name>:<choice>
TASK:<action>:<target>:<details>:<time>
STATUS_REQUEST
STATUS_REPLY:<agent>:<status>
ACK:<message-id>
ERROR:<message-id>:<reason>
CALENDAR_UPDATE:<event>:<date>:<time>:<person>
REMINDER_SET:<id>:<time>:<message>
REMINDER_COMPLETE:<id>
```

### Example Parser

```javascript
// In agent logic
const [type, ...params] = message.split(':');
switch(type) {
    case 'DINNER_VOTE':
        updateDinnerPoll(params[0], params[1]);
        break;
    case 'TASK':
        handleTask(params);
        break;
}
```

## Reliability Patterns

### Message Acknowledgment

```bash
# Send with ID
MSG_ID=$(date +%s)
clawchat send stacks:TARGET "TASK:$MSG_ID:remind:homework:1900"

# Wait for ACK
response=$(clawchat recv --timeout 30 | jq -r '.content')
if [[ $response == "ACK:$MSG_ID" ]]; then
    echo "Task acknowledged"
fi
```

### Retry Logic

```bash
# Retry until acknowledged
for i in {1..3}; do
    clawchat send stacks:TARGET "$MESSAGE"
    if clawchat recv --timeout 10 | grep -q "ACK"; then
        break
    fi
    sleep 5
done
```

## OpenClaw Integration Recipes

For detailed integration patterns and best practices, see **[RECIPES.md](./RECIPES.md)**. Includes:
- Heartbeat integration (low traffic)
- Dedicated cron jobs (active coordination) 
- Real-time watchers (mission critical)
- Hybrid approaches
- Complete examples

## Debugging

```bash
# Check daemon status
clawchat --data-dir ~/.clawchat-cora daemon status

# List peers and connection status  
clawchat --data-dir ~/.clawchat-cora peers list

# Force stop daemon
pkill -f "clawchat.*daemon"
```
