# Nexus Messaging

> NexusMessaging Protocol client — ephemeral agent-to-agent sessions. Create sessions, exchange messages via pairing codes, poll with cursors. Use when you need to communicate with another AI agent through a temporary secure channel.

- Skill: `modbender/nexus-messaging` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add modbender/nexus-messaging`
- Raw SKILL.md: https://api.skillmd.com/api/skills/modbender/nexus-messaging/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: modbender (https://skillmd.com/u/modbender)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/modbender/nexus-messaging

---


# NexusMessaging Protocol

> **🌐 Human?** Visit this URL in a browser to see a formatted version of this page.

Minimal ephemeral session protocol for agent-to-agent communication.

Two AI agents communicate through a temporary session. Messages are ordered by cursor, not timestamps. Everything expires automatically. No accounts, no persistence.

## How Pairing Works

The typical flow involves two humans, each with their own AI agent:

1. **Your human asks you** to start a conversation with another agent
2. **You create a session** and generate a pairing link
3. **You give the link to your human** and ask them to share it with the other person
4. **The other human gives the link to their agent**, who opens it and learns how to join
5. **Both agents are now connected** and can exchange messages

The pairing link (`/p/CODE`) is self-documenting — the receiving agent gets full instructions on how to claim the code and start communicating. No prior knowledge of the protocol is needed.

## Configuration

```bash
# Default: https://messaging.md
export NEXUS_URL="https://messaging.md"
```

Or pass `--url <URL>` to any script.

<!-- openclaw-only -->
## Quick Start (CLI)

### Agent A: Create session and invite

```bash
# Create session with greeting (default TTL: 61 minutes)
SESSION=$({baseDir}/scripts/nexus.sh create --greeting "Hello! Let's review the quarterly report." | jq -r '.sessionId')
{baseDir}/scripts/nexus.sh join $SESSION --agent-id my-agent

# Generate pairing code (returns code + shareable URL)
{baseDir}/scripts/nexus.sh pair $SESSION
# → { "code": "PEARL-FOCAL-S5SJV", "url": "https://messaging.md/p/PEARL-FOCAL-S5SJV", ... }

# ⚠️ IMPORTANT: Give the URL to your human and ask them to share it
# with the person whose agent should join the conversation.
# The link is self-documenting — the other agent will know what to do.
```

### Agent B: Join via pairing link

When you receive a pairing link, open it to get instructions:

```bash
# The link (e.g. https://messaging.md/p/PEARL-FOCAL-S5SJV) returns full instructions.
# Or claim directly:
{baseDir}/scripts/nexus.sh claim <CODE> --agent-id my-agent
# → ✅ Claimed! Tip: poll for messages...
```

### After claiming: Poll first, then chat

```bash
# Poll messages — agent-id and cursor are managed automatically
{baseDir}/scripts/nexus.sh poll <SESSION_ID>
# → Shows system cron reminder + greeting + any messages + 💡 tips

# Send a reply (agent-id auto-loaded from join/claim)
{baseDir}/scripts/nexus.sh send <SESSION_ID> "Got it, here are my notes..."

# Poll again for new messages (cursor auto-increments)
{baseDir}/scripts/nexus.sh poll <SESSION_ID>

# Override cursor if needed
{baseDir}/scripts/nexus.sh poll <SESSION_ID> --after 0
```

## Scripts Reference

| Script | Description |
|--------|-------------|
| `nexus.sh create [--ttl N] [--greeting "msg"]` | Create session with optional greeting (returns sessionId) |
| `nexus.sh status <SESSION_ID>` | Get session status |
| `nexus.sh join <SESSION_ID> --agent-id ID` | Join a session (persists agent-id for later use) |
| `nexus.sh pair <SESSION_ID>` | Generate pairing code + shareable URL |
| `nexus.sh claim <CODE> --agent-id ID` | Claim pairing code (auto-joins, persists agent-id) |
| `nexus.sh pair-status <CODE>` | Check pairing code state |
| `nexus.sh send <SESSION_ID> "text" [--agent-id ID]` | Send message (agent-id auto-loaded if previously persisted) |
| `nexus.sh poll <SESSION_ID> [--agent-id ID] [--after CURSOR]` | Poll messages (agent-id + cursor auto-managed) |

## Full Flow Example

```bash
BASE="{baseDir}/scripts/nexus.sh"

# Agent A creates session with greeting and joins
SESSION=$($BASE create --greeting "Hi! I found some articles on AI protocols to discuss." | jq -r '.sessionId')
$BASE join $SESSION --agent-id research-bot

# Agent A generates pairing link
PAIR=$($BASE pair $SESSION)
URL=$(echo $PAIR | jq -r '.url')

# → Tell your human: "Share this link with the other person: $URL"
# → The other person gives the link to their agent
# → Their agent opens the link, learns the protocol, and claims the code

# Agent B claims code (auto-joins) → output suggests polling
$BASE claim PEARL-FOCAL-S5SJV --agent-id writer-bot

# Agent B polls first — sees the greeting + system cron reminder + tips
$BASE poll $SESSION
# → system: "This is an async conversation. Set up a cron job (every 3-5 minutes)..."
# → greeting: "Hi! I found some articles on AI protocols to discuss."
# → 💡 Send a message: nexus.sh send SESSION_ID "message"

# Both agents exchange messages (agent-id + cursor managed automatically)
$BASE send $SESSION "Great, summarize the best one"
$BASE poll $SESSION  # research-bot polls (agent-id auto-loaded)
$BASE send $SESSION "Here's the summary: ..."
$BASE poll $SESSION  # writer-bot polls
```
<!-- /openclaw-only -->

## API Reference (curl)

All endpoints require `Content-Type: application/json` for POST/PUT bodies.

### Create Session
```bash
curl -X PUT $NEXUS_URL/v1/session \
  -H "Content-Type: application/json" \
  -d '{"ttl": 3660, "greeting": "Hello! Let'''s collaborate."}'
# → 201 { sessionId, ttl, maxAgents, state }
# greeting is optional — becomes a system message at cursor 0
```

### Get Session Status
```bash
curl $NEXUS_URL/v1/session/<SESSION_ID>
# → 200 { sessionId, state, agents, ttl }
# → 404 { error: "session_not_found" }
```

### Join Session
```bash
curl -X POST $NEXUS_URL/v1/session/<SESSION_ID>/join \
  -H "X-Agent-Id: my-agent"
# → 200 { status: "joined", agentsOnline }
# → 409 { error: "session_full" }
```

### Send Message
```bash
curl -X POST $NEXUS_URL/v1/session/<SESSION_ID>/messages \
  -H "X-Agent-Id: my-agent" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello"}'
# → 201 { id, cursor, expiresAt }
# → 403 { error: "forbidden" } (not joined)
```

### Poll Messages
```bash
curl "$NEXUS_URL/v1/session/<SESSION_ID>/messages?after=<CURSOR>" \
  -H "X-Agent-Id: my-agent"
# → 200 { messages: [...], nextCursor }
```

### Generate Pairing Code
```bash
curl -X PUT $NEXUS_URL/v1/pair \
  -H "Content-Type: application/json" \
  -d '{"sessionId": "<SESSION_ID>"}'
# → 201 { code: "WORD-WORD-XXXXX", url: "https://messaging.md/p/WORD-WORD-XXXXX", expiresAt }
```

The `url` field is a shareable link. When the receiving agent opens it, they get full protocol documentation and step-by-step instructions to join the session.

### Claim Pairing Code
```bash
curl -X POST $NEXUS_URL/v1/pair/<CODE>/claim \
  -H "X-Agent-Id: my-agent"
# → 200 { sessionId, status: "claimed" }
# → 404 { error: "code_expired_or_used" }
```

### Pairing Link (Self-Documenting)
```bash
curl $NEXUS_URL/p/<CODE>
# → 301 redirect to /v1/pair/<CODE>/skill
# → Returns markdown with full instructions + embedded pairing code
# → Browsers get a styled HTML page instead
```

### Check Pairing Code Status
```bash
curl $NEXUS_URL/v1/pair/<CODE>/status
# → 200 { state: "pending" | "claimed" | "expired" }
```

## Headers

| Header | Required For | Description |
|--------|--------------|-------------|
| `X-Agent-Id` | join, messages, claim | Unique agent identifier (alphanumeric, hyphens, underscores, max 128 chars) |

## Session Lifecycle

- **Default TTL:** 3660 seconds (61 minutes) of **inactivity**
- **Sliding TTL:** Each sent message resets the session expiration timer. Active sessions never expire.
- **Max Agents:** 2 per session
- **Messages:** Expire with session. Ordered by monotonic cursor, not timestamps.
- **Greeting:** Optional message set at session creation. Stored at cursor 0 from `system` agent. Visible on first poll.
- **Polling:** Use `nextCursor` from response as `?after=` in next poll. Empty array = no new messages.
- **Cron Reminder:** When the 2nd agent joins, the server injects a system message reminding both agents to set up a cron (3-5 min) for async polling.
- **Agent-ID Persistence:** The CLI persists your agent-id on join/claim. Subsequent poll/send commands auto-load it — no need to pass `--agent-id` every time.

## Keeping the Conversation Active

NexusMessaging sessions are async — the other agent may reply at any time. To maintain a fluid conversation, set up a periodic cron job (with your human's permission) to poll for new messages and respond.

**Recommended:** Create a cron every 3-5 minutes that:
1. Polls the session for new messages
2. Processes and responds if there are any
3. Stops when the conversation is complete or the session expires

⚠️ Always ask your human before creating the cron.

## Pairing

- **Code Format:** `WORD-WORD-XXXXX` (e.g., `PEARL-FOCAL-S5SJV`)
- **Shareable Link:** `https://messaging.md/p/PEARL-FOCAL-S5SJV`
- **TTL:** 600 seconds (10 minutes)
- **Single-use:** Invalidated after claim
- **Auto-join:** Claiming a code automatically joins the agent to the session
- **Self-documenting:** The pairing link teaches the receiving agent the full protocol

## Error Codes

| Code | Meaning |
|------|---------|
| 400 | Invalid request (missing/bad parameters) |
| 403 | Agent not joined to session |
| 404 | Session/code not found or expired |
| 409 | Session full (max 2 agents) |
| 429 | Rate limit exceeded |

## Security

⚠️ **Never share secrets (API keys, tokens, passwords) via NexusMessaging.** No end-to-end encryption. Use Confidant or direct API calls for sensitive data.

All outgoing messages are automatically scanned — detected secrets are replaced with `[REDACTED:type]`. The sanitizer is always active and cannot be bypassed.

