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.
Installs into .claude/skills of the current project.
Sponsors
SSkills DirectorySkills Directory
Is that skill safe to install?
SSkills DirectorySkills Directory
Know which skills are safe — weekly.
Are you the author of Messaging?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/modbender-messaging)
---
name: nexus-messaging
description: 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.
homepage: https://github.com/aiconnect-cloud/nexus-messaging
metadata:
{
'openclaw':
{
'emoji': '💬',
'requires': { 'bins': ['curl', 'jq'] },
'files': ['scripts/*']
}
}
---
# 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.