AgentStack
MCP verified MIT Self-run

IronMesh

mcp-wiztheagent-ironmesh · by WizTheAgent

Local-first, end-to-end encrypted agent-to-agent mesh protocol. Zero-config LAN + LoRa. Runs offline. No cloud. info@ironmesh.org

No reviews yet
0 installs
7 views
0.0% view→install

Install

$ agentstack add mcp-wiztheagent-ironmesh

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of IronMesh? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

IronMesh

[](https://github.com/WizTheAgent/IronMesh/actions/workflows/ci.yml) [](https://codecov.io/gh/WizTheAgent/IronMesh) [](https://pypi.org/project/ironmesh/) [](https://pypi.org/project/ironmesh/) [](https://hub.docker.com/r/wiztheagent/ironmesh) [](LICENSE)

Website: ironmesh.org  •  Contact: [info@ironmesh.org](mailto:info@ironmesh.org)  •  Security: [info@ironmesh.org](mailto:info@ironmesh.org) (see [SECURITY.md](SECURITY.md))

> v0.9.4.2 — operator-polish patch on the v0.9.4 pre-audit-hardening + dual-use-migration line. 1083 tests green on Ubuntu + Windows + macOS across Python 3.10 – 3.13, plus live cross-host validation on the new wire surfaces. > Validated on a 3-node mesh with a real Android client (Sideband) and LoRa at SF8/BW125. > Wire-format ironmesh/0.8 adds opt-in feature flags (handshake-skip, group-broadcast) without disturbing any existing path. The headline doc — [docs/STABILITY_PROMISE.md](docs/STABILITY_PROMISE.md) — is the v1.0 contract for everything we commit to keeping stable. > Full changelog: [CHANGELOG.md](CHANGELOG.md).

IronMesh — Local-first, end-to-end encrypted mesh protocol for AI agents. Zero-config on LAN. Optional LoRa transport. Works when the cloud doesn’t.

pip install ironmesh
ironmesh demo          # spawn two local agents, exchange an encrypted ping
ironmesh setup         # interactive first-run wizard

That's the 60-second path: zero config files, no two machines required. The demo spawns two daemons in subprocesses, runs the handshake, exchanges a hello, and tears down. When that prints PASS, your install is good.

Why IronMesh

Most agent frameworks assume the cloud is always available. Google's A2A needs HTTPS + internet. Anthropic's MCP is tool integration, not peer-to-peer. ACP is local-IPC-only. ANP wants a complex DID setup that still assumes internet.

None of them work when you pull the ethernet cable. None of them work in a basement. None of them work off-grid.

IronMesh is the production-grade transport layer that keeps working when the router dies, the ISP is down, or you're fully air-gapped.

  • Zero-config LAN discovery via mDNS
  • End-to-end encryption with forward secrecy (NaCl/libsodium)
  • Offline message queuing in encrypted SQLite
  • Optional LoRa transport via Reticulum for off-grid use
  • Clean integration with Ollama, LangChain, AutoGen, CrewAI, and MCP

For preppers, homelab operators, privacy advocates, tinkerers, and anyone who thinks the answer to "what if the internet goes down?" shouldn't be "then nothing works."

Local-first. Offline-capable. Mesh-ready. Zero-config. No cloud required. Ever.

Features

Discovery and transport

  • Zero-config discovery. mDNS/Zeroconf finds agents on your LAN. Identity keys are never broadcast; they're exchanged inside the authenticated handshake. Default-deny: auto-connect requires --allowed-peers or --open-discovery.
  • Binary wire protocol. Compact binary frame format with Ed25519 signatures on every frame. No JSON on the wire after handshake.
  • Multi-hop mesh routing. Distance-vector with split horizon, poisoned reverse, TTL loop prevention, and per-source-sharded dedup. See [docs/MESH.md](docs/MESH.md).
  • Reticulum / LoRa transport. Optional second transport over Reticulum for off-grid use. WebSocket and Reticulum run concurrently. Enable with --reticulum and pip install ironmesh[rns].
  • TLS-first connections. Client tries wss:// before ws://. Plaintext fallback requires --allow-plaintext-ws.

Cryptography

  • End-to-end encryption. NaCl / libsodium (XSalsa20-Poly1305 + X25519 ECDH). Plaintext messages are rejected after handshake.
  • Forward secrecy. Per-session ephemeral keys, destroyed once the handshake completes. Compromising today's keys can't decrypt yesterday's traffic.
  • Mutual authentication. Both client and server prove knowledge of the passphrase. No trusting a server that can't authenticate itself.
  • Mandatory Ed25519 signatures. Every message is signed and verified. Unsigned messages are dropped.
  • Channel binding. The authentication nonce is embedded in the ECDH handshake signature, cryptographically tying the two stages together.
  • Replay protection. Monotonic sequence numbers (no seq=0 bypass) plus timestamp validation.
  • End-to-end encryption over multi-hop. NaCl SealedBox payload wrapping using X25519 keys derived from each node's identity. Relays cannot read message bodies. Inner Ed25519 signatures survive per-hop re-encryption.

Trust and storage

  • Trust-On-First-Use. SSH-style key pinning. If a peer's identity key changes, the connection is terminated (not just logged). mDNS fingerprint pinning blocks address spoofing of known peers.
  • Integrity-protected trust store. HMAC-SHA256 on the known-peers file catches tampering.
  • Mandatory key encryption. Identity keys are encrypted at rest with Argon2id by default. Plaintext keys auto-migrate on next startup.
  • Encrypted queue storage. SQLite payloads are SecretBox-encrypted. No plaintext at rest.
  • Offline-capable. Messages queue when peers are offline and deliver automatically on reconnect.
  • Tamper-evident audit log. Auth failures, TOFU mismatches, key rotations, and peer connections are chained with HMAC-SHA256. Any tampering breaks the chain. Logs rotate at 10 MB with chain anchors carried across files.

Operations

  • Capability discovery. Agents advertise services like llm:llama3 or tool:filesystem; peers find them with find_capability("llm:*"). See [docs/CAPABILITIES.md](docs/CAPABILITIES.md).
  • Prometheus metrics. /metrics endpoint in Prometheus exposition format; JSON available via ?format=json.
  • Token-authenticated GUI. Dashboard requires a per-session bearer token (printed at startup).
  • Auth-failure blocking. 3 failed auth attempts from an IP in 5 minutes trigger a 5-minute block. Rate-limited mDNS discovery prevents flood attacks.
  • Model agnostic. Ollama, llama.cpp, vLLM, a bash script — if it speaks WebSocket, it can use IronMesh.
  • Cross-platform. Raspberry Pi, Windows, Linux, Mac. Tested daily on a Pi 5 and a Windows desktop.
  • ironmesh doctor + deployment helpers. One-shot install diagnostic, plus --peer HOST:PORT for a dry-run reachability check against another node. Two helper scripts in [tools/](tools/) cover the SSH-detached daemon launch and verified wheel transfer patterns operators hit on multi-node deployments.

Where IronMesh fits

IronMesh is a networking layer for agents, not another orchestration framework. It sits under the tools you already use:

┌─────────────────────────────────────────────────────┐
│  Your application                                   │
├─────────────────────────────────────────────────────┤
│  Agent frameworks — LangChain, CrewAI, AutoGen      │  ` capability, and answers prompts; the
other sends a question and prints the reply. No cloud, no API keys, no
internet.

### Using it from Python

The Agent SDK hides the asyncio / WebSocket plumbing:

```python
from ironmesh import Agent

agent = Agent("my-bot", passphrase="shared-secret-12-plus")

@agent.on_message()
def handle(peer_id, payload):
    print(f"From {peer_id[:12]}: {payload.decode()}")
    agent.reply(peer_id, b"ack")

agent.run()                      # blocks; Ctrl-C to stop
# agent.run(foreground=False)    # returns the event loop for background use

Send from any thread once the agent is running:

agent.send_sync("peer-name", "hello")

Running two physical machines

For a real two-node deployment, use a passphrase file (not an env var — env vars are visible via /proc//environ) and lock down peer discovery with --allowed-peers:

# On both machines
install -d -m 700 ~/.ironmesh
printf '%s' 'your-strong-secret-phrase-12-plus' > ~/.ironmesh/passphrase
chmod 600 ~/.ironmesh/passphrase
export IRONMESH_PASSPHRASE_FILE=~/.ironmesh/passphrase

# Machine A (e.g. Raspberry Pi)
ironmesh run --name alice --port 8765 --allowed-peers bob

# Machine B (e.g. desktop)
ironmesh run --name bob   --port 8765 --allowed-peers alice

> The --passphrase CLI flag was deliberately removed in v0.3 — it > would leak the passphrase into ps aux. Use --passphrase-file, > IRONMESH_PASSPHRASE_FILE, or the interactive getpass prompt.

Advanced / Testing — same-machine localhost demo

> ⚠ Localhost testing only. This path uses two opt-in shortcut > flags (--open-discovery and --allow-plaintext-ws) that disable > default-deny peer filtering and the TLS-first connection attempt. > They exist to make a same-machine demo possible without generating > TLS certs or pre-pinning peer names. Do not use them on a real > deployment. For a real deployment, follow > [Running two physical machines](#running-two-physical-machines) above.

Open two terminals. Export the same passphrase in both, then run one agent per terminal:

# Both terminals
export IRONMESH_PASSPHRASE="any-12-plus-char-passphrase"

# Terminal 1
ironmesh run --name alice --port 8765 --open-discovery --allow-plaintext-ws

# Terminal 2
ironmesh run --name bob   --port 8766 --open-discovery --allow-plaintext-ws

Within a few seconds each terminal prints a line like:

Discovered agent: bob @ 127.0.0.1:8766
Peer bob (8f3c2a1b...) online -- ephemeral ECDH complete

That means the handshake succeeded and the two nodes have a live, encrypted session. --open-discovery turns off the default-deny peer filter so a same-machine demo just works without you having to know the peer names in advance. --allow-plaintext-ws disables the wss-first attempt so you don't need to generate a TLS cert for localhost. Both flags emit a startup warning when set so they cannot accidentally make it into a production config.

Docker

# One-off .env with your passphrase (>= 12 chars)
printf 'IRONMESH_PASSPHRASE=your-strong-secret-phrase\n' > .env
docker compose up -d
# Dashboard at http://127.0.0.1:8766 (GUI token printed in logs)

Framework integrations

# LangChain — gives an LLM agent mesh communication tools
from ironmesh.adapters.langchain_adapter import create_ironmesh_toolkit
tools = create_ironmesh_toolkit(name="lc-agent", passphrase="secret")

# CrewAI — mesh-connected crew agent
from ironmesh.adapters.crewai_adapter import create_mesh_crew_agent
agent = create_mesh_crew_agent(role="Coordinator", goal="...", llm=my_llm,
                                mesh_passphrase="secret")

# AutoGen — register mesh functions on an assistant
from ironmesh.adapters.autogen_adapter import register_ironmesh
register_ironmesh(my_agent, my_autogen_assistant)

# MCP (Claude Desktop / Claude Code / OpenClaw) — see ironmesh_mcp/
ironmesh-mcp --passphrase-file ~/.ironmesh/passphrase

OpenClaw bridge

OpenClaw agents can use IronMesh as a discovery + transport layer through the bundled MCP server. After registering python -m ironmesh_mcp as an MCP server in ~/.openclaw/openclaw.json, your agent gets 13 mesh tools — discover capabilities, request services from peers, broadcast, subscribe to events. Drop the snippet at examples/openclaw/soul_mesh_snippet.md into the agent's SOUL.md so it knows when to reach for them. Full setup walkthrough: [docs/OPENCLAW_MCP_SETUP.md](docs/OPENCLAWMCPSETUP.md).

Multi-mesh federation

Bridge two independent meshes with policy-controlled capability sharing:

from ironmesh import FederationGateway

gw = FederationGateway(
    mesh_a={"name": "gw-alpha", "port": 8780, "passphrase": "mesh-a-pass"},
    mesh_b={"name": "gw-beta",  "port": 8781, "passphrase": "mesh-b-pass"},
    policy={"allow": ["llm:*"], "deny": ["tool:filesystem"]},
)
gw.run()

Go reference client

A minimal Go implementation proves the wire protocol is language-independent:

cd clients/go && go build ./cmd/ironmesh-go/
export IRONMESH_PASSPHRASE='your-strong-secret-phrase-12-plus'
./ironmesh-go --host  --port 8765 --name go-client

See [docs/PROTOCOL_SPEC.md](docs/PROTOCOL_SPEC.md) for the formal wire specification.

TypeScript client

A TypeScript client lives at [clients/ts/](clients/ts/) — published to npm as @wiztheagent/ironmesh-client (current 0.2.0). The full wire protocol — 3-stage handshake, binary frame v4, SecretBox + Ed25519 — is implemented and end-to-end tested against a live Python daemon. The OpenClaw channel plugin (@wiztheagent/openclaw-ironmesh) is built on top of it. Status and implementation order: [clients/ts/README.md](clients/ts/README.md).

Advanced: low-level BridgeDaemon API

import asyncio
from ironmesh.bridge import BridgeDaemon

async def main():
    daemon = BridgeDaemon(name="my-agent", port=8765, passphrase="secret")
    daemon.run(background=True)
    await daemon.send_message("peer-node-id", "MSG", b"Hello!")

asyncio.run(main())

LoRa / Reticulum transport

IronMesh can communicate over LoRa radio using Reticulum as a second transport layer. Both WebSocket (LAN) and Reticulum (LoRa) run simultaneously — no internet required for either.

Prerequisites:

  • An RNode (e.g. Heltec V3) flashed with RNode firmware
  • rnsd running with the RNode interface configured
  • The rns Python package: pip install ironmesh[rns]

Start with Reticulum enabled:

# Terminal 1 (node A)
ironmesh run --name node-a --reticulum --passphrase-file /path/to/passphrase

# Terminal 2 (node B) — connect to node A's RNS destination hash
ironmesh run --name node-b --reticulum --rns-connect  --passphrase-file /path/to/passphrase

The destination hash is printed at startup: Reticulum transport active — destination .

CLI flags:

| Flag | Description | |------|-------------| | --reticulum | Enable Reticulum transport | | --rns-configdir PATH | Reticulum config directory (default: ~/.reticulum) | | --rns-announce-interval N | Seconds between RNS announces (default: 300) | | --rns-connect HASHES | Comma-separated destination hashes to connect on startup |

Architecture

+-------------------+       mDNS discovery       +-------------------+
|   Agent: node-a   ||   Agent: node-b   |
|   (Raspberry Pi)  |                             |   (Laptop)        |
+-------------------+                             +-------------------+
| Your AI / App     |                             | Your AI / App     |
| Bridge Daemon     || Bridge Daemon     |
| Protocol Layer    |    XSalsa20-Poly1305        | Protocol Layer    |
| Crypto (NaCl)     |    X25519 ECDH              | Crypto (NaCl)     |
| SQLite Store      |    Forward Secrecy          | SQLite Store      |
| mDNS Discovery    |    No internet needed       | mDNS Discovery    |
+-------------------+                             +-------------------+

Handshake flow

Client                                 Server
  |                                      |
  ||
  || signed(Ed25519) + channel_binding(nonce)
  || (SecretBox + Ed25519 on every message)

Use Cases

  • Home AI mesh — Raspberry Pi running Ollama talks to your desktop running a coding agent. No cloud involved.
  • Off-grid comms — Agents on a local network with no internet connection coordinate tasks, share data, run workflows.
  • Prepper infrastructure — Self-contained AI network that works when the internet doesn't. Solar-powered Pi cluster running local models.
  • Privacy-first AI — Keep all agent communication on your LAN. Nothing leaves your network. Nothing gets logged by a third party.
  • Lab / air-gapped networks — Agents in isolated environments that can never touch the internet.
  • Multi-device AI workflows — Your phone agent, desktop agent, and se

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.