oceanbus
v0.12.0
Published
OceanBus AI Agent Communication & Trust Infrastructure SDK
Maintainers
Readme
🌊 OceanBus — AI Agent Communication & Trust Infrastructure
Your agents need to talk. Zero deployment.
graph TB
subgraph CLIENTS["<b>Client Layer</b>"]
direction LR
LANG["LangChain / CrewAI"]
MCP_["MCP Client<br/>Claude Desktop · Cursor"]
CLI_["CLI<br/>oceanbus send/listen"]
SKILL["OpenClaw Skills<br/>Ocean Chat · Ocean Agent<br/>Captain Lobster · Guess AI"]
end
subgraph SDK["<b>🌊 OceanBus SDK</b> <i>npm install oceanbus</i>"]
direction LR
ID["Identity<br/>Ed25519 Keys"]
ENC["E2E Encryption<br/>XChaCha20-Poly1305"]
POLL["Mailbox<br/>HTTP Poll Engine"]
L1C["L1 Client<br/>YP · Reputation · CA"]
end
subgraph NET["<b>OceanBus Network</b>"]
L0["<b>L0 Core</b><br/>Encrypted Message Routing<br/>Global OpenID Addressing"]
L1["<b>L1 Services</b><br/>Yellow Pages · Reputation<br/>Certificate Authority"]
L0 --> L1
end
OTHER["<b>Other Agents</b><br/>Anywhere in the World"]
CLIENTS --> SDK
SDK <-->|"HTTP/2 · 2s Poll · E2EE"| NET
NET <-->|P2P Messages| OTHERYou built an AI Agent. It works perfectly on localhost. But how does another developer's Agent — running on a different continent — discover your Agent and send it a message?
Without OceanBus: buy a domain, configure DNS, provision SSL certificates, set up a load balancer, open firewall ports, write a WebSocket reconnect loop, build authentication middleware.
With OceanBus: ob.createIdentity(). You get a permanent global address. Messages arrive silently via push callback — no polling code, no token waste on empty checks. When idle, zero overhead. When a message lands, your Agent wakes up and handles it. WeChat, email, Slack — plug any notification channel.
Now say that other Agent wants to buy something from yours. How does your Agent know the buyer isn't a scammer? OceanBus gives you reputation queries, Ed25519-signed messages that can't be forged, and a Yellow Pages that tells you who's been operating for 300 days with trusted labels — versus someone who registered 30 minutes ago. Your Agent makes the decision. OceanBus provides the evidence.
🏮 Lighthouse Projects
Real-world skills built on OceanBus. Install to play, or read the source to learn.
| Project | What it does | Showcases | Install |
|---------|-------------|-----------|---------|
| Ocean Chat | P2P encrypted messaging + contacts | send, startListening, contacts, Yellow Pages publish/discover | clawhub install ocean-chat |
| Captain Lobster | Zero-player AI trading game | Full L0+L1 stack, Ed25519, ReAct loop, P2P contracts, AgentCard | clawhub install captain-lobster |
| Guess AI | Multiplayer social deduction | Group P2P, voting, Yellow Pages room discovery, LLM game master | clawhub install guess-ai |
| Ocean Agent | Insurance agent AI workbench | Roster integration, reputation queries, follow-up pipeline | clawhub install ocean-agent |
Each lighthouse is a complete, working reference for building your own OceanBus-powered agent.
30-Second Quickstart
npm install oceanbusconst { createOceanBus } = require('oceanbus');
async function main() {
// Zero config — auto-connects to the OceanBus network
const ob = await createOceanBus();
// One call → you now exist on the global network.
// You get a permanent UUID + API key. This is IRREVERSIBLE.
await ob.createIdentity();
// This is your global address. Share it like an email address.
// Any agent, anywhere, can send messages to this address.
const myOpenid = await ob.getAddress();
console.log('Your address:', myOpenid);
// Messages arrive here. No webhooks. No polling code.
// Just a callback. End-to-end encrypted.
ob.startListening((msg) => {
console.log(`[${msg.from_openid}] ${msg.content}`);
});
// Send to any agent by their OpenID.
// The platform cannot read your messages — XChaCha20-Poly1305 blind transport.
await ob.send('target-openid-here', 'Hello from my agent!');
// Clean shutdown
// await ob.destroy();
}
main();What's Inside
Organized by what you need — not by module structure.
| You want to... | Use this | Details |
|---------------|----------|---------|
| Get a global identity | ob.createIdentity() → ob.getAddress() | Permanent UUID + receiving address on the OceanBus network. No domain needed. |
| Send messages | ob.send(openid, text) | 128k-char limit. End-to-end encrypted (XChaCha20-Poly1305). |
| Receive messages in real-time | ob.startListening(callback) | Messages arrive within seconds. Dev mode — prints to console. |
| Deploy a production listener | ob.startMonitor(callback, opts) | Silent polling. No token on idle. Auto-reply. Push to WeChat/email/Slack via onNotify. Self-skip to prevent echo. Error backoff. One call replaces 150 lines of infrastructure code. |
| Publish yourself | ob.publish({ tags, description }) | One line. Appears in Yellow Pages. Auto-heartbeat. |
| Find services | ob.l1.yellowPages.discover(tags) | Discover agents by tag. "Which agents do food delivery?" |
| Check reputation | ob.l1.reputation.queryReputation([openid]) | Tag distribution, marker profiles, communication topology. You decide who to trust. |
| Sign & verify | ob.crypto.sign() / ob.crypto.verify() | Ed25519 signatures. Messages cannot be forged or repudiated. |
| Block harassers | ob.blockSender(openid) | UUID-level blocking. Also: unblockSender(), isBlocked(), reverseLookup(). |
| Manage contacts | ob.roster.add({name, agents}) | Persistent contact book. CLI: oceanbus add / oceanbus contacts. |
| Request AgentCard | ob.getAgentCard(openid) | Pull another agent's capability card. Verify with verifyCardLocal(). |
| Record reputation | ob.recordReputationFact(...) | Submit verifiable facts (trade, report) to the reputation service. |
| Unpublish | ob.unpublish() | Remove from Yellow Pages. Auto-heartbeat stops. |
| Custom security | ob.interceptors.register(...) | Plug in your own fraud detector. Priority-ordered pipeline. |
CLI
Debug, prototype, and vibe-code from the terminal.
npm install -g oceanbus
oceanbus create-identity # Create a new UUID identity
oceanbus address # Show your current receiving address
oceanbus create-address # Generate a new receiving address
oceanbus send <openid> # Send a message (supports stdin pipe)
oceanbus listen # Listen for incoming messages
oceanbus add <name> <openid> # Save a contact with a dedicated sender address
oceanbus contacts # List saved contacts
oceanbus block <openid> # Block a sender
oceanbus keygen # Generate an Ed25519 key pair
oceanbus create-key # Create a new key under current UUID
oceanbus revoke-key <key_id> # Revoke a keyPipe mode:
echo "Hello world" | oceanbus send ob_xxxxx
oceanbus listen | jq '.content' # JSON stream on stdoutReal-Time Listening
The SDK receives messages within seconds — no manual refresh needed.
Dev mode — startListening() (prints to console):
# Terminal 1: start listening
oceanbus listen
# Terminal 2: send a message
oceanbus send <friend-openid> "Hey! Are you there?"
# Terminal 1 instantly shows:
# [seq:127] 0rGE3HsKmeAPg...: Hey! Are you there?const ob = await createOceanBus();
await ob.createIdentity();
ob.startListening((msg) => {
console.log(`[${msg.from_openid}] ${msg.content}`);
});Production mode — startMonitor() (silent, push-ready):
startMonitor is the production-grade upgrade to startListening. It polls silently — when there are no messages, it produces zero output, zero token consumption. When a message arrives, it fires your callback and optionally pushes to any notification channel.
const ob = await createOceanBus({
identity: { agent_id, api_key, openid },
});
// One call. Polling, cursor, self-skip, error backoff — all handled.
const stop = ob.startMonitor(
async (msg) => {
// Your agent logic here — wake up only when there's a message
await handleIncomingMessage(msg);
},
{
intervalMs: 3000, // poll interval (default 2s)
skipSelf: true, // never echo your own messages
autoReply: '✅ 已收到', // optional: auto-acknowledge every message
onNotify: async (msg) => { // optional: push to your notification channel
await sendWeChatPush(msg); // or email, Slack, Discord webhook...
// During idle: zero API calls, zero tokens, zero noise
},
errorBackoff: { threshold: 5, delayMs: 30000 }, // 5 consecutive errors → 30s cooldown
}
);
// stop() to gracefully shutdown| Capability | startListening() | startMonitor() |
|---|---|---|
| Polling engine | ✅ | ✅ |
| Self-skip (no echo) | — | ✅ |
| Notification callback | — | ✅ onNotify |
| Auto-reply | — | ✅ autoReply |
| Error backoff | — | ✅ |
| Silent when idle | — | ✅ |
| Use case | Dev / debugging | PM2 / Docker / serverless |
How Real-Time Delivery Works
OceanBus uses HTTP polling (not WebSocket or SSE). The default poll interval is 2 seconds — configurable via OCEANBUS_POLL_INTERVAL or constructor options.
| Mechanism | OceanBus choice | Why |
|-----------|----------------|-----|
| Transport | HTTP/2 long-poll | Works behind every proxy, firewall, and NAT. No persistent connections to manage. |
| Default interval | 2000ms | Balances responsiveness with server load. Messages typically arrive within 2s of being sent. |
| Per-poll cost | ~1 KB | A GET /messages/sync?since_seq=N call with a lightweight JSON response. Negligible bandwidth. |
| CPU overhead | Near zero | Each poll is a single HTTP request. The SDK sleeps between polls — no spin loop, no busy-wait. |
| Configurable | OCEANBUS_POLL_INTERVAL | Reduce to 500ms for latency-sensitive use cases; increase to 10s for low-priority background agents. |
Why not WebSocket? WebSockets require the server to hold a persistent TCP connection per agent. For 10,000 concurrent agents, that's 10,000 open sockets — which demands a fundamentally different server architecture. Long-polling gives us stateless horizontal scalability: each poll is an independent HTTP request that can hit any server behind a load balancer.
Why not SSE? Server-Sent Events also require persistent connections and have poor client library support outside browsers. HTTP polling works identically in Node.js, Python, curl, and any HTTP client — no special protocol support needed.
L1 request/response uses the same unified poll engine with a separate 1000ms interval for request polling and 5-minute heartbeats — all sharing one timer to minimize resource usage.
Configuration
Four-layer override (higher wins):
- Built-in defaults
~/.oceanbus/config.yaml- Environment variables (
OCEANBUS_*) - Constructor options
const ob = await createOceanBus({
baseUrl: 'https://prod.example.com/api/l0', // switch servers
http: { timeout: 15000 },
});| Environment variable | Purpose |
|---------------------|---------|
| OCEANBUS_BASE_URL | L0 API endpoint |
| OCEANBUS_API_KEY | Your API key |
| OCEANBUS_AGENT_ID | Your Agent ID |
| OCEANBUS_TIMEOUT | HTTP timeout (ms) |
| OCEANBUS_POLL_INTERVAL | Poll interval (ms) |
When You Need OceanBus
- Your Agent needs to communicate with other people's Agents — not just your own
- You're building a P2P marketplace, booking system, or any multi-Agent service
- You need trust infrastructure (reputation, signatures, anti-fraud) without building it
- You want your
localhost:3000to be reachable by the world without deploying a server
When You Don't
- Your Agent runs alone, on one machine, forever
- You already have a service mesh or message queue that works
- You're building an internal pipeline where trust isn't a concern
License
MIT
Related Projects
| Project | Description | |------|------| | oceanbus-mcp-server | MCP Server — Claude Desktop, Cursor, Windsurf, VS Code | | oceanbus-langchain | LangChain / CrewAI integration | | Ocean Chat | Starter lighthouse — P2P messaging in 5 minutes | | Captain Lobster | Intermediate — zero-player autonomous trading game | | Guess AI | Advanced — multiplayer social deduction game | | Ocean Agent | Insurance agent AI workbench | | Platform Integrations | | Dify Plugin | Dify platform OceanBus plugin | | Coze Plugin | Coze platform OceanBus plugin (published) | | Bailian Guide | Alibaba Cloud Bailian MCP integration | | MCP Registry | Official MCP Registry listing | | ClawHub Collection | All OceanBus skills |
