The same multi-agent shape you came for — WhatsApp, Telegram, browser and email channels, multi-agent routing, memory, LLM tool-use — rebuilt as a single static Rust binary on a NATS event bus. Production-grade by construction.
Coming from OpenClaw? You'll find the channel surface, the agent loop, and the plugin philosophy familiar — see the side-by-side for what changes (everything that runs at 3 AM in production).
Native binaries: Linux x86_64 + aarch64 (musl static), macOS Intel + Apple Silicon, Windows x86_64 (cargo install or zip from Releases). Some optional features (STT) need extra build tools per OS — see Platform support for the per-OS prerequisites + feature matrix.
OpenClaw got the agent shape right — multi-channel, multi-agent, plugin-extensible. We mined it for patterns, then built the operational layer it doesn't try to be: durable message bus, per-agent crash isolation, multi-language plugins, signed plugin distribution, multi-tenant configuration, mobile-first deploys.
If you tried OpenClaw and hit the wall on production ops, this is the next stop.
| nexo-rs | OpenClaw | |
|---|---|---|
| Runtime | Single static Rust binary, ~34 MB | Node + npm + transitive deps |
| Process model | Multi-agent over NATS bus, per-agent crash isolation | Single Node event loop, one crash = all agents down |
| Fault tolerance | NATS broker + disk fallback queue, circuit breakers per external call | In-memory only, no retry guarantees |
| Channels | WhatsApp · Telegram · Browser (CDP) · Email — same surface | WhatsApp · Telegram · Browser (canvas) · Email |
| Plugin languages | Rust, Python, TypeScript, PHP (stdio JSON-RPC contract) | TypeScript only (in-process) |
| Plugin trust | Cosign keyless verification, SBOM per release, signed tarballs | npm registry trust |
| Container image | Multi-arch (amd64 + arm64) on ghcr.io, ~80 MB | No official image |
| Multi-tenant SaaS | Built-in (Phase 82) — per-tenant SQLite + agent isolation | Single-tenant by design |
| LLM providers | MiniMax M2.5 default · Anthropic · OpenAI-compatible · OAuth-PKCE for Claude Code subscriptions | Anthropic + OpenAI |
| Memory | SQLite + sqlite-vec (zero infra) per-tenant short / long / vector tiers | Pluggable — host SDK pattern |
The shape (multi-agent + multi-channel + plugin-extensible) is OpenClaw's contribution. The runtime (durable bus, crash isolation, plugin signing, multi-tenant) is what we add — every operational surface a Node single-process can't reach. Below: the three opinionated trade-offs we made vs the JS reference.
Agents speak WhatsApp, Telegram, email, and browser CDP out of the box. Bring your own channel by writing a plugin — Rust, Python, TypeScript, or PHP.
One static binary, no Node, no npm. Stripped: 29 MB. Gzipped: 13 MB. Runs on a fresh VPS, as a systemd unit, or pull the multi-arch container from ghcr.io.
NATS-backed event bus with disk fallback. Per-agent capability sandboxes. Cosign-verified plugin marketplace. Multi-tenant SaaS-ready.
nexo-rs gives you three layers to extend. Each solves a different problem — pick the layer that matches what you're building.
Bring a new channel (WhatsApp variant, Discord, Slack…) or expose new tools to agents. Subprocess plugin in your favorite language.
Drop bundled tools, advisors, skills, MCP servers as a single tarball. Operator runs nexo ext install.
Build a SaaS product on top of nexo-rs. Multi-tenant, admin RPC over NATS, your own UI. The framework runs out of view.
Ten plugins maintained out-of-tree on their own GitHub repos — five channels (WhatsApp, Telegram, Email, Browser, Google), one tool (Web Search), three pollers (RSS, Gmail, Google Calendar), and the Admin RPC + UI. One command: nexo plugin install <owner>/<repo> grabs the release tarball and drops it under plugins.discovery.search_paths (or build from source with cargo install --git). Pure-Rust + rustls on every cross-compile target (Linux musl, macOS, Windows MSVC, Android NDK / Termux).
nexo-plugin-whatsapp
Signal Protocol via wa-agent upstream. QR pairing, multi-account, recording presence (media="audio"), inbound voice-note hook.
$ nexo plugin install lordmacu/nexo-plugin-whatsapp
nexo-plugin-telegramBot API long-poll + send. Group chat support, multi-bot routing per agent, file uploads, voice notes round-trip.
$ nexo plugin install lordmacu/nexo-plugin-telegram
nexo-plugin-email
IMAP poll + lettre SMTP. Multi-account, Google OAuth, block-based composer, tracking pixels, disposable-domain classifier.
$ nexo plugin install lordmacu/nexo-plugin-email
nexo-plugin-browser
Chrome DevTools Protocol (CDP) via WebSocket. 12 browser_* tools (navigate, click, fill, screenshot, evaluate, snapshot…). Per-agent profile isolation.
$ nexo plugin install lordmacu/nexo-plugin-browser
nexo-rs-plugin-adminAdmin RPC over NATS — tenants CRUD, MCP catalog, plugins doctor, memory query + snapshot create/restore, channels approve, token rotation. Self-hostable web UI included.
$ nexo plugin install lordmacu/nexo-rs-plugin-admin
nexo-plugin-google
Per-agent OAuth client + generic google_call tool: hit any Google API the granted scopes allow. Gmail, Calendar, Drive, Sheets — same wire shape.
$ nexo plugin install lordmacu/nexo-rs-plugin-google
nexo-plugin-web-search
Multi-provider web_search tool: Brave, Tavily, DuckDuckGo, Perplexity. Per-binding policy + multi-instance × multi-agent isolation.
$ nexo plugin install lordmacu/nexo-rs-plugin-web-search
nexo-poller-rssCron-style poller for RSS / Atom feeds. Cursor-driven dedupe, configurable filters, dispatches new items as messages to your agent.
$ nexo plugin install lordmacu/nexo-rs-poller-rss
nexo-poller-gmail
Gmail API poller — sweeps an inbox via OAuth, extracts addresses + body via regex, dispatches matches as agent prompts. Reuses the google plugin's credential store.
$ nexo plugin install lordmacu/nexo-rs-poller-gmail
nexo-poller-google-calendarGoogle Calendar v3 poller — incremental sync, new + updated events as prompts. Lead-time templates, attendee-aware routing, reuses Google OAuth credentials.
$ nexo plugin install lordmacu/nexo-rs-poller-google-calendar
Same JSON-RPC subprocess wire contract every official plugin above speaks. Pick one of the four language SDKs and ship a single noarch tarball.
Single pure-Rust + rustls dep graph cross-compiles to Linux musl × 2, macOS Apple Silicon + Intel, Windows MSVC, and Android NDK / Termux. The table below is what each feature actually does on each desktop OS. Mobile (Termux on Android) shares the Linux row except where noted.
| Feature | 🐧 Linux | 🍎 macOS | 🪟 Windows |
|---|---|---|---|
| Daemon core | |||
| Agent loop — multi-turn, NATS event bus, scheduler, heartbeat | ✅ | ✅ | ✅ |
| LLM clients — MiniMax, Claude, OpenAI, Anthropic, DeepSeek… (rustls) | ✅ | ✅ | ✅ |
| Memory — short-term + long-term SQLite + vector sqlite-vec | ✅ | ✅ | ✅ |
| Skills + MCP — markdown skill loader + MCP client/server | ✅ | ✅ | ✅ |
| Subprocess plugins — JSON-RPC over stdio, multi-instance routing | ✅ | ✅ | ✅ |
| Channels | |||
| WhatsApp — wa-agent Signal Protocol + QR pairing | ✅ | ✅ | ✅ |
| Telegram — Bot API long-poll, multi-bot | ✅ | ✅ | ✅ |
| Email — IMAP poll + lettre SMTP, Google OAuth | ✅ | ✅ | ✅ |
| Browser — Chrome DevTools Protocol, 12 tools, profile isolation | ✅ | ✅ | ✅1 |
| Google — OAuth tokens encrypted at rest | ✅ | ✅ | ✅ |
| SDK features | |||
| voice — Edge TTS + pure-Rust opus encoder | ✅ | ✅ | ✅ |
| stt — voice-note transcription (whisper.cpp) | ✅ | ✅ | ⚠️2 |
| wizard — first-run LLM key probe | ✅ | ✅ | ✅ |
| enrichment — disposable-domain classifier, tenant cache | ✅ | ✅ | ✅ |
| tracking — HMAC-signed message + link tokens | ✅ | ✅ | ✅ |
| email-template — block composer + asset store | ✅ | ✅ | ✅ |
| Operator hardening | |||
POSIX file modes 0600/0700 on secrets/ + token files |
✅ | ✅ | ⚠️3 |
| Symlink-attack defense in plugin config + memory snapshot | ✅ | ✅ | ⚠️4 |
| Auth gauntlet pre-boot perm check — refuses to start on world-readable secrets | ✅ | ✅ | ❌5 |
| Permission-prompt forwarder — daemon ↔ permission-bin over Unix socket | ✅ | ✅ | ❌6 |
| Distribution | |||
Single static binary via install.sh · cargo install nexo-rs · GH Releases (.deb / .rpm / Termux) · Docker (GHCR) |
✅musl × 2 | ✅x86_64 + arm64 | ✅x86_64 MSVC |
| Docker image — ghcr.io multi-arch | ✅ | ✅ | ✅via WSL2 |
Termux (Android) — aarch64-linux-android .deb |
✅cross-compile host | — | — |
1. Browser channel on Windows — auto-detects Chrome / Chromium / Edge at %LOCALAPPDATA%\Google\Chrome\Application\chrome.exe, %ProgramFiles%, %ProgramFiles(x86)%. Set NEXO_PLUGIN_BROWSER_EXECUTABLE for custom install paths.
2. STT on Windows — current whisper-rs binding requires Visual Studio Build Tools 2022 + CMake on the first build (whisper.cpp is vendored C++). Pure-Rust Candle replacement planned (Phase 91) to drop the C++ chain entirely; eliminates the install caveat and unblocks Android NDK / WASM.
3. POSIX file modes on Windows — Windows doesn't honour chmod 0600. Secrets land at the configured path but ACL enforcement is the operator's responsibility (run as a non-admin user; restrict the secrets/ ACL to that user only).
4. Symlink defense on Windows — Windows symlinks require admin or developer mode to create. We skip the symlink-escape probe on Windows because the attack surface is much narrower; the canonicalize-and-starts-with checks still run for non-symlink path traversal.
5. Auth gauntlet on Windows — the pre-boot permission check that refuses to start when token files are world-readable returns an empty diagnostics list on Windows (no POSIX modes to read). Restrict secrets/ ACL manually before exposing the daemon publicly.
6. Permission-prompt forwarder on Windows — the daemon ↔ permission-bin IPC channel uses Unix domain sockets. The Windows orchestrator wires a no-op handle so the daemon boots; decisions fall back to whichever AllowAll / DenyAll / Scripted in-process decider you configured. Named-pipe + TCP-loopback alternative tracked under Phase 27.x in FOLLOWUPS.md.
~95% feature parity across Linux + macOS + Windows. The two real Windows gaps are the permission-prompt forwarder (Unix-socket-only) and the auth gauntlet's pre-boot file-mode check. Everything an operator building a WhatsApp / Telegram / Email / Browser SaaS needs lands on every desktop OS without caveats.
The daemon spawns plugins as subprocesses and talks JSON-RPC 2.0 over stdin/stdout. Same wire contract across all four SDKs — pick the language, vendor your deps, ship a single noarch tarball.
nexo-microapp-sdkuse nexo_microapp_sdk::plugin::{PluginAdapter, Event}; #[tokio::main] async fn main() -> Result<()> { let adapter = PluginAdapter::new(MANIFEST) .on_event(|topic, event, broker| async { broker.publish("plugin.inbound.echo", event).await }); adapter.run().await }
Cargo.toml: nexo-microapp-sdk = { features = ["plugin"] }
nexo_plugin_sdk · stdlib onlyimport asyncio from nexo_plugin_sdk import PluginAdapter, Event async def on_event(topic, event, broker): out = Event.new("plugin.inbound.echo", "my_plugin", {"echoed": event.payload}) await broker.publish("plugin.inbound.echo", out) asyncio.run(PluginAdapter(manifest_toml=MANIFEST, on_event=on_event).run())
requirements.txt: -e ../sdk-python (in-tree path)
nexo-plugin-sdk · Node 18+ ESMimport { PluginAdapter, Event } from "nexo-plugin-sdk"; const adapter = new PluginAdapter({ manifestToml: MANIFEST, onEvent: async (topic, event, broker) => { const out = Event.new("plugin.inbound.echo", "my_plugin", { echoed: event.payload }); await broker.publish("plugin.inbound.echo", out); }, }); await adapter.run();
package.json: "nexo-plugin-sdk": "file:../sdk-typescript"
nexo/plugin-sdk · 8.1+ Fibersuse Nexo\Plugin\Sdk\{PluginAdapter, Event}; $adapter = new PluginAdapter([ 'manifestToml' => $manifest, 'onEvent' => function ($topic, $event, $broker) { $out = Event::new('plugin.inbound.echo', 'my_plugin', ['echoed' => $event->payload]); $broker->publish('plugin.inbound.echo', $out); }, ]); $adapter->run();
composer.json: "nexo/plugin-sdk": "^0.1.0" via path repo
An extension is a self-contained directory with a manifest.toml that declares contributed tools, advisors, skills, MCP servers, channel adapters, and config schemas.
Operators install with one command:
Built for multi-tenant SaaS. Each tenant gets isolated state, scoped capabilities, and per-tenant audit logs. Use it when you have bundled functionality that's not a separate process — just code that ships alongside your daemon.
[extension] id = "my-extension" version = "0.1.0" description = "Custom tools + advisors" [[tools]] name = "summarize" schema_path = "tools/summarize.json" [[advisors]] id = "sales-advisor" prompt_path = "advisors/sales.md" [[skills]] id = "send-quote" yaml_path = "skills/send-quote.yaml" [[mcp_servers]] id = "crm" command = "./bin/crm-mcp" [multi_tenant] isolated_state = true per_tenant_secrets = true
nexo ext install ./my-extension — daemon picks up tools, registers them with the agent runtime, and surfaces them in nexo agent doctor.
A microapp is a complete product that consumes nexo-rs as its agent runtime. The framework runs in the background; your microapp owns the UI, the multi-tenant story, the billing — everything end-users see.
Microapps talk to the framework via admin RPC over NATS — provision tenants, configure agents, manage knowledge bases, rotate API keys. The framework stays agnostic; the microapp drives configuration.
Reference implementation: agent-creator-microapp — a SaaS where end-users create their own WhatsApp agents through a WhatsApp-Web-style React UI.
use nexo_microapp_sdk::admin::{AdminClient, TenantSpec}; let admin = AdminClient::connect("nats://localhost:4222").await?; // Create a tenant for a new SaaS customer admin.create_tenant(TenantSpec { id: "acme-corp".into(), plan: "pro".into(), quotas: Quotas { agents: 10, llm_tokens_month: 5_000_000 }, }).await?; // Provision an agent for that tenant admin.create_agent("acme-corp", AgentSpec { id: "customer-support".into(), persona_path: "./personas/support.md".into(), channels: vec!["whatsapp:acme-prod".into()], llm: "minimax-m2.5".into(), }).await?; // Hot-reload — no daemon restart admin.reload("acme-corp").await?;
Kate handles your personal Telegram. Ana works the WhatsApp sales line. A cron-style poller sweeps Gmail for leads — all sharing one broker, one tool registry, and one memory layer.
┌─────────────┐ ┌──────────────────┐ ┌─────────────────────┐ │ WhatsApp ├──┐ │ │ │ Agent: Ana │ │ Telegram ├──┤ │ NATS broker ├──────┤ Agent: Kate │ │ Email ├──┼──▶│ (event bus) │ │ Agent: ops-bot │ │ Browser ├──┘ │ │ └──────────┬──────────┘ └─────────────┘ └──────────────────┘ │ ▼ ┌─────────────────────┐ │ Memory + LLMs + │ │ Tools + Skills │ └─────────────────────┘
Install the binary, drop a YAML, talk to your agent. The quickstart walks you through the whole thing.