The project's README from github.com/allenpeng0705/EnvoyMesh. As one markdown file: README.md.
EnvoyMesh — Secure P2P Agentic Mesh
🌐 Website · ⬇ Download · English · 简体中文
A decentralized, peer-to-peer mesh for autonomous AI agents.
EnvoyMesh is a private social network that you — and your AI agent — actually own. Unlike most social apps and AI assistants that live on someone else's server, EnvoyMesh flips the script:
Install EnvoyMesh on your computer (home node) and EnvoyGo on your phone, chat with friends directly, and let your AI agents negotiate tasks on your behalf — all without any platform in the middle.
The default home node is the standalone desktop app (macOS / Windows). A headless home node (LaunchAgent / logon task) is optional, for advanced operators only.
📖 QuickStart.md — Get up and running in minutes.
📘 EnvoyMesh Guidebook 0.4.0 (中文版 · HTML)
Install the desktop app to run your private mesh (Social UI + node). Prefer the mirror if GitHub is slow.
| Platform | Download |
|---|---|
| macOS (Apple Silicon · DMG) | GitHub Releases · Mirror DMG |
| Windows (EXE) | GitHub Releases · Mirror EXE |
| Linux | Build from source (see QuickStart.md) |
More options and screenshots: Website downloads.
Pair EnvoyGo to your home node via QR. Requires a running EnvoyMesh desktop install.
| Platform | Download |
|---|---|
| iOS (App Store · iOS 18.6+) | App Store |
| Android (Google Play) | Google Play · APK mirror · GitHub Releases |
Scan · App Store Scan · Google Play
:18789. Mesh-aware (contacts, knowledge, chat).public / friends / private), folder navigation, automatic RAG re-index on save.kb-obsidian provider: frontmatter YAML, [[wiki-links]] graph, published: true/false auto-sync to sensitivity labels. Open your vault in Obsidian for rich editing while EnvoyMesh handles networking.KnowledgeBasePlugin interface.envoy:// pages and syncs to bonded peers.manual / auto / never).End users: download a desktop build or EnvoyGo from Download — you do not need source or envoy-harness.
Developers: clone EnvoyMesh and run setup. Setup clones/builds the sibling envoy-harness repo next to EnvoyMesh when missing (requires Node.js, npm, and pnpm).
parent/
EnvoyMesh/ ← this repo
envoy-harness/ ← auto-cloned by setup (coding-agent runtime)
macOS / Linux:
git clone https://github.com/allenpeng0705/EnvoyMesh.git
cd EnvoyMesh
./scripts/setup.sh
# Run
npm run node:dev # Start the P2P node
npm run social:dev # Open http://localhost:5173
Windows (PowerShell 5.1+):
git clone https://github.com/allenpeng0705/EnvoyMesh.git
cd EnvoyMesh
.\scripts\setup.ps1
# Run
npm run node:dev # Start the P2P node
npm run social:dev # Open http://localhost:5173
Optional: clone harness yourself first, or point at an existing tree:
./scripts/setup.sh --local-envoy-harness /path/to/envoy-harness
# Windows: .\scripts\setup.ps1 -LocalEnvoyHarnessPath D:\path\to\envoy-harness
# Or: export ENVOY_HARNESS_DIR=/path/to/envoy-harness
Desktop packaging (./scripts/build-desktop.sh / .\scripts\build-desktop.ps1) stages harness from that sibling into the Tauri bundle. Details: docs/envoy-harness-integration-EnvoyMesh.md · QuickStart.md.
setup.sh and setup.ps1 are kept in sync step-for-step — if you change one, change the other in the same commit. Setup also bootstraps OpenClaw, copies the envoymesh channel extension, builds the OpenClaw gateway, and smoke-tests the webhook.
First launch. A desktop install (DMG / .exe / .AppImage) auto-bonds to the project's author (Allen Peng) on first launch via the bundled bundled-sponsor-friend.json, so you start with one working contact out of the box. Remove it any time from Settings → Contacts. To opt out before launch, delete the file from the bundle (or set bundled-sponsor-friend.json to {"enabled": false} in your installer profile).
Most people should keep using the desktop download. The Tauri app already starts the home node and respawns it when it wedges.
If you need the home node always on without a UI (EnvoyGo to a mini-PC, overnight checkout), install an OS supervisor. Quit the desktop app first — one process owns a profile.
# macOS / Linux — portable bundle, or this git checkout if you omit --bundle
./scripts/home-node-service.sh install --bundle /path/to/envoymesh-bundle
./scripts/home-node-service.sh status
./scripts/home-node-service.sh uninstall
# Windows — Scheduled Task at logon (not a Windows Service)
.\scripts\home-node-service.ps1 install -Bundle C:\path\to\envoymesh-bundle
.\scripts\home-node-service.ps1 status
.\scripts\home-node-service.ps1 uninstall
Details: docs/headless-home-node.md · QuickStart.md.
For detailed setup, configuration, Docker, mobile, and packaging: QuickStart.md · packaging.md
Every home node is a full peer. EnvoyGo is a thin client to your home; friends connect over signed mesh envelopes (optionally via relay).
Primary Envoy (desktop) · EnvoyGo (phone) · Friend Envoy · External agents · Obsidian vault
Interactive version on the website.
You don't need to understand this to use EnvoyMesh — but here's the short version:
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Your Mac │ signed msg │ Relay │ signed msg │ Friend's │
│ (Envoy) │ ─────────────▶ │ (helps the │ ─────────────▶ │ Mac │
│ │ │ two find │ │ (Envoy) │
│ │ │ each other│ │ │
└────────────┘ └────────────┘ └────────────┘
▲ │
│ │
signed signed │
reply ◀────────────────────────────────────── reply ◀─────┘
- The relay never reads your message. It only helps you find each other.
- Your friend's Mac checks the signature, checks that it trusts you, then delivers it.
- If the relay is offline, the two Macs can still talk directly.
Every message goes through four checks before delivery:
Wire ──▶ 1. Is it really from you? (signed with your key)
│
▼
2. Do I trust you? (your trust list — public / referred / direct)
│
▼
3. Is this message allowed? (policy engine — what can this sender do?)
│
▼
4. Has it been seen before? (no replays, no duplicates)
│
▼
Delivered
Your AI agent doesn't speak the P2P language directly — that would be risky. EnvoyMesh runs a secure bridge that translates between the mesh and your agent. The agent never holds your identity keys — EnvoyMesh signs everything, applies your policy, and the agent just answers plain HTTP requests.
→ Full guide: AI Agent & External Agents
EnvoyMesh supports a two-engine agent network — a built-in AI (EnvoyAI/OpenClaw) and an optional external agent connected over HTTP. Both engines share the same mesh tools, chat interface, and policy controls. Only one external agent can be active at a time.
EnvoyAI is the built-in AI assistant that ships with every EnvoyMesh node:
:18789 — no separate install or config needed.openclawEnabled: false in node-config.json to disable.For OpenClaw setup and extension details, see docs/openclaw-extension.md.
For users who prefer a different AI engine, EnvoyMesh provides a secure bridge — a bidirectional HTTP-to-P2P gateway. External agents never get direct mesh access or your identity keys.
Three external agent presets are built in:
| Agent | Default URL | Status | Description |
|---|---|---|---|
| HomeClaw | http://127.0.0.1:8010/message |
Enabled | The original external agent. Python/FastAPI-based. |
| Hermes | http://127.0.0.1:8020/message |
Enabled | Alternative external agent. Migration tool available to import into OpenClaw. |
| OpenHuman | http://127.0.0.1:8021/message |
Disabled by default | Community external agent. |
All three use the same envoymesh-message adapter — the same wire protocol, the same HTTP endpoints, no agent-specific code in EnvoyMesh.
Friend's Envoy Your Envoy External Agent
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ Mesh │ ──chat.msg─▶│ Bridge │──POST /msg──▶│ HomeClaw │
│ (P2P) │◀─chat.msg──│ (HTTP:3031) │◀─POST /send──│ / Hermes │
│ │ │ │ │ / OpenHuman │
└──────────┘ └──────────────┘ └──────────────┘
│
The agent never holds
your identity keys or
speaks P2P directly
Key rules:
POST /bridge/send, not the sync HTTP responseStep 1: Start Hermes
# Hermes listens on port 8020 by default
hermes serve --port 8020
Step 2: Configure the EnvoyMesh bridge
Open the Social UI → Settings → AI → AI Engine:
http://127.0.0.1:8020/message3031) — this is where Hermes sends replies backOr via WebSocket RPC:
{
"method": "applyExtAgentSettings",
"params": {
"activeExtAgentId": "hermes",
"bridgeEnabled": true,
"bridgeListenPort": 3031,
"extAgents": [
{
"id": "hermes",
"name": "Hermes",
"adapter": "envoymesh-message",
"url": "http://127.0.0.1:8020/message",
"enabled": true
}
]
}
}
Step 3: Configure Hermes to send replies to EnvoyMesh
In your Hermes configuration, point the reply endpoint at the EnvoyMesh bridge:
{
"bridgeUrl": "http://127.0.0.1:3031/bridge/send",
"bridgeSecret": "your-shared-secret"
}
Step 4: Verify
After saving, the AI Engine mode chip should show "Built-in + Ext" (if EnvoyAI is running) or "Ext only" (if EnvoyAI is disabled). Messages sent to your agent peer ID will be forwarded to Hermes, and Hermes's replies will appear in chat.
Step 1: Start OpenHuman
# OpenHuman listens on port 8021 by default
openhuman serve --port 8021
Step 2: Enable OpenHuman in EnvoyMesh
Open the Social UI → Settings → AI → AI Engine:
http://127.0.0.1:8021/message3031)Or via RPC:
{
"method": "applyExtAgentSettings",
"params": {
"activeExtAgentId": "openhuman",
"bridgeEnabled": true,
"bridgeListenPort": 3031,
"extAgents": [
{
"id": "openhuman",
"name": "OpenHuman",
"adapter": "envoymesh-message",
"url": "http://127.0.0.1:8021/message",
"enabled": true
}
]
}
}
Step 3: Configure OpenHuman's reply endpoint
{
"bridgeUrl": "http://127.0.0.1:3031/bridge/send",
"bridgeSecret": "your-shared-secret"
}
EnvoyMesh supports four engine modes:
| Mode | EnvoyAI (Built-in) | Ext Agent | Use Case |
|---|---|---|---|
| Built-in only | ✅ On | ❌ Off | Default — OpenClaw runs in-process, no external agent |
| Built-in + Ext | ✅ On | ✅ On | Both engines active — EnvoyAI handles assistant turns, ext handles agent tasks |
| Ext only | ❌ Off | ✅ On | Replace the built-in agent entirely with your preferred external agent |
| None | ❌ Off | ❌ Off | No AI — just P2P messaging |
Note: EnvoyAI (OpenClaw) is read-only in the Settings UI — it's toggled at node startup via node-config.json (openclawEnabled: true/false). The Ext Agent bridge can be enabled/disabled at runtime.
The bridge listens on 127.0.0.1:<listenPort> and exposes these endpoints for the external agent:
| Method | Path | Purpose | Auth |
|---|---|---|---|
POST |
/bridge/send |
Agent sends a chat reply to a mesh peer | Bearer token (if configured) |
POST |
/bridge/execute-tool |
Agent invokes a mesh tool | Bearer token |
POST |
/bridge/agent-share-proposal |
Agent proposes sharing a vault file | Bearer token |
GET |
/bridge/list-tools |
List available mesh tools | Bearer token |
EnvoyMesh → External Agent (POST agentUrl):
{
"from": "envoy_abc123",
"fromOwnerId": "envoy:owner:def456",
"fromName": "Alice",
"text": "What is EnvoyMesh?",
"messageId": "msg-unique-id"
}
External Agent → EnvoyMesh (POST /bridge/send):
{
"to": "envoy_abc123",
"text": "EnvoyMesh is a decentralized P2P mesh for AI agents."
}
External agents can call EnvoyMesh mesh tools through the bridge:
| Tool | Description |
|---|---|
mesh.findKnowledge |
Search the local vault knowledge base |
mesh.findContact |
Look up a bonded contact's profile |
mesh.sendMessage |
Send a chat message to a contact |
mesh.listContacts |
List all bonded contacts |
mesh.getProfile |
Get the owner's profile |
If you're moving from Hermes to the built-in OpenClaw (EnvoyAI), a migration plugin is available:
packages/openclaw/extensions/migrate-hermes/For details, see docs/openclaw-extension.md.
You can register any HTTP agent that implements the envoymesh-message wire contract:
Or configure programmatically:
{
"method": "applyExtAgentSettings",
"params": {
"activeExtAgentId": "my-custom-agent",
"bridgeEnabled": true,
"bridgeListenPort": 3031,
"extAgents": [
{
"id": "my-custom-agent",
"name": "My Agent",
"adapter": "envoymesh-message",
"url": "http://127.0.0.1:9090/webhook",
"enabled": true
}
]
}
}
For the bridge developer guide, see docs/agent_bridge_guide.md. For OpenClaw setup, see docs/openclaw-extension.md.
The Agent Network is EnvoyMesh's system for multi-device teams and multi-agent collaboration — from bringing a team online to decomposing complex tasks across AI agents.
Read first: docs/agent-network-guide.md (中文) — membership (opt-in + bonds), Team jobs, settings map, and FAQ.
EnvoyMesh ships four paths for bringing teams online, from simple invite links to enterprise-scale manifests (all under Settings → Agent Network):
| Path | Description | Best For |
|---|---|---|
| Company Invite | Issue a shareable link; joiner pastes it in their UI | Small teams (1–20) |
| Fleet Manifest | Import a signed JSON roster; pre-stage trust records | Medium-large teams (20+) |
| LAN Auto-bond | Auto-bond nodes sharing the same fleet token on LAN | Office networks |
| Pairing Kiosk | One-button HTTP server for on-demand invites | Office visitors |
All paths are opt-in, auditable, and owner-controlled. Bonds alone do not recruit an agent — each owner also enables Join Agent Network to accept Team jobs. See docs/fleet-onboarding.md and docs/agent-network-fleet.md.
EnvoyMesh Team jobs (protocol name: chains) let your agent decompose complex work and orchestrate across bonded, opted-in peers:
Owner asks: "Translate this document, then have someone review it"
│
▼
Orchestrator agent decomposes into subtasks:
├─ Translate (Worker A)
└─ Review (Worker B)
│
▼
Worker selection (direct assign by default, or competitive bidding):
├─ Workers must have Join Agent Network enabled
├─ Optional multi-round bids (up to 3 rounds)
├─ Orchestrator awards using score / cost / policy
│
▼
Partial results flow back, then merge into a composite deliverable
│
▼
Final Team job report with citations, audit trail, and optional cost breakdown
Key features:
ChainBudgetLedger (when cost UI is enabled)manual / auto / never)chain.* audit eventsSee docs/agent_network.md for the protocol design.
EnvoyMesh includes a built-in knowledge base with in-app note creation and optional plugins for Obsidian-style enrichment and MCP write-back.
The Social app's Library tab is your in-app knowledge UI:
public / friends / private). Persisted to .envoy/sensitivity.json so it survives restarts and re-indexes.knowledge.query, not just bonded contacts. Strangers are rate-limited (5/min, 50/hour).Vault layout (auto-created on first run):
shared_vault/
├── .envoy/ ← Internal metadata (never shared)
│ ├── sensitivity.json ← Per-item sensitivity overrides
│ └── plugins/
│ └── obsidian/ ← Link graph + frontmatter cache
├── notes/ ← User-created Markdown notes
│ ├── research/ tutorials/ personal/ work/
├── documents/ ← Imported files (PDF, Word, images, etc.)
├── inbox/ ← Received files from peers
└── temp/ ← Staging for imports
Programmatic access: createNote / listKbPlugins / enableKbPlugin / disableKbPlugin JSON-RPC methods on NodeService.
EnvoyMesh includes a built-in Obsidian-compatible knowledge base plugin (@envoymesh/kb-obsidian) that turns your vault into an Obsidian-style second brain — with YAML frontmatter, [[wiki-links]], bidirectional backlinks, and automatic sensitivity sync — all without any external Obsidian dependency.
Your vault directory doubles as an Obsidian vault. Open the same folder in Obsidian for a rich editing experience while EnvoyMesh handles the mesh networking and sensitivity.
When activated, the plugin scans every .md file in your vault and:
| Feature | Description |
|---|---|
| Frontmatter parsing | Extracts tags, aliases, date, category, published from YAML headers |
| Wiki-link graph | Builds a bidirectional link graph from [[Note]] and [[Note|Display Text]] syntax |
| Sensitivity sync | published: true → note becomes public; published: false → override removed |
| Embed-aware parsing | ![[image]] embeds are preserved (not treated as links) |
| Heading anchors | [[Note#Section]] and [[Note#^block-id]] normalize to "Note" in the graph |
| Path normalization | [[folder/Note]] resolves to "Note" (folder prefix stripped) |
| Sensitivity-aware resolution | Strangers see only public wiki-links; private links become plain text |
Step 1: Find your vault directory
By default, your vault lives inside your profile directory:
~/.local/share/envoymesh/default/vault/
You can also check the vault path in the Social UI under Settings → Knowledge Base.
Step 2: Create notes with Obsidian-style frontmatter
Create .md files in your vault with YAML frontmatter:
---
title: My Project
tags: [project, research]
aliases: [Project Alpha, Alpha]
date: "2026-07-13"
category: engineering
published: true
---
# My Project
This is a public note about my project.
See [[Meeting Notes]] for related discussions.
Also check [[ideas/Brainstorm|the brainstorm session]].
Step 3: Activate the Obsidian plugin
The plugin is registered automatically when your node starts, but must be activated before it enriches your metadata. Via the Social UI:
Or via WebSocket RPC:
{
"method": "activateKbPlugin",
"params": {
"pluginId": "obsidian"
}
}
Once active, the plugin enriches every vault document with metadata (tags, aliases, backlinks, outgoing links) that appears in search results and the Library view.
You have two options for creating notes:
Option A: Create in Obsidian, indexed by EnvoyMesh
~/.local/share/envoymesh/default/vault/) in Obsidian.md files with frontmatter and wiki-linkspublished: true/false in frontmatterOption B: Create via the Social UI Library
public / friends / private){vault}/notes/{filename}.md and indexed immediatelyThe sensitivity of each note controls who can see it in the mesh:
┌─────────────────────────────────────────────────────┐
│ Sensitivity Tiers │
├──────────┬────────────────────────────────────────────┤
│ public │ Anyone on the mesh can discover & query │
│ friends │ Bonded contacts (direct + referred) only │
│ private │ Only you and your AI agent │
└──────────┴────────────────────────────────────────────┘
When a stranger queries your knowledge base, wiki-links are filtered based on the target note's sensitivity:
| Link target sensitivity | Who sees the link |
|---|---|
public |
Everyone — rendered as [[Note]] |
friends |
Bonded contacts only — strangers see plain text |
private |
Only you — others see plain text (alias or note name) |
| Field | Type | Description |
|---|---|---|
tags |
[tag1, tag2] or multiline list |
Note tags — used in search and Library view |
aliases |
[alias1, alias2] or multiline list |
Alternative names for the note |
date |
"YYYY-MM-DD" or "YYYY-MM-DDTHH:mm:ss" |
Note date |
category |
string |
Note category (e.g., engineering, research) |
published |
true or false |
Controls sensitivity: true → public, false → revert to default |
Published sync behavior:
published: true → EnvoyMesh writes a per-item sensitivity override of "public"published: false → Override is removed, reverts to path-heuristic defaultpublished field → No override, path heuristic determines sensitivity| Syntax | Description | Normalized Target |
|---|---|---|
[[Note]] |
Basic link | Note |
[[Note|Display Text]] |
Link with display alias | Note |
[[folder/Note]] |
Path-qualified link | Note |
[[Note#Section]] |
Link to heading | Note |
[[Note#^block-id]] |
Link to block reference | Note |
![[Image]] |
Embed (image, text, etc.) | Excluded from link graph |
If you already have an Obsidian vault, you can point EnvoyMesh to use it:
Important: EnvoyMesh never modifies your notes. It only reads frontmatter and wiki-links for enrichment. All writes go through the Social UI or the createNote RPC.
When your AI agent discovers knowledge from an external MCP server, it can save the results as vault notes:
---
source: mcp
mcp-server: "http://127.0.0.1:9999/mcp"
mcp-tool: "memex_search"
mcp-query: "deployment guide"
mcp-queried-at: "2026-07-13T10:30:00Z"
published: false
tags: [mcp, knowledge]
---
# MCP deployment-guide
> Sourced from memex_search on 2026-07-13T10:30:00Z
## Results
### 1. EnvoyMesh Deployment Guide
Deployment notes...
### 2. Network Configuration
Networking config...
MCP-sourced notes default to friends sensitivity (not public). You can toggle them to published: true in the Library UI to make them discoverable on the mesh.
All KB plugins can be managed via the Social UI or RPC:
| Action | RPC Method | Description |
|---|---|---|
| List plugins | listKbPlugins({ activeOnly: true }) |
See all registered plugins and their status |
| Activate | activateKbPlugin({ pluginId: "obsidian" }) |
Start a plugin |
| Deactivate | deactivateKbPlugin({ pluginId: "obsidian" }) |
Stop a plugin (link graph deleted) |
| Get config | getKbPluginConfig("obsidian") |
Read plugin settings |
| Update config | updateKbPluginConfig({ pluginId: "obsidian", config: { ... } }) |
Update settings |
Plugin status values: registered → active → disabled / error
You write a .md file with frontmatter and wiki-links
│
▼
Obsidian plugin reads all .md files from vault
│
├─ Parse YAML frontmatter (tags, aliases, date, published)
│
├─ Sync published: true/false → per-item sensitivity overrides
│ ├── published: true → sensitivity override = "public"
│ └─ published: false → override removed
│
├─ Build wiki-link graph from [[links]] in content
│ ├── Normalize targets (strip paths, anchors, .md)
│ ├── Deduplicate outgoing links
│ └─ Compute bidirectional backlinks
│
└─ Enrich vault documents with metadata
├── frontmatter:tags → ["tag1", "tag2"]
├── frontmatter:aliases → ["alias1"]
├── links:outgoing → ["NoteB", "NoteC"]
└── links:backlinks → ["NoteA"]
When a peer queries your knowledge:
│
▼
Sensitivity-aware resolution
├── Owner (you): sees all links and notes
├── Bonded contact: sees public + friends links
└── Stranger: sees only public links (private → plain text)
For the full design, see docs/knowledge-base-and-rag.md.
Product mobile app: EnvoyGo (apps/envoygo/) — Flutter thin client. This is what “mobile / phone / iOS / Android” means in this repo.
A lightweight app that acts as a remote client to your home node:
Install: Download EnvoyGo (App Store / Google Play + QR codes).
Pairing: Scan a QR code from your desktop Social UI → instant connection.
Design: docs/flutter-thin-client-design.md.
The old Capacitor full-node stack (
apps/mobile/) was removed. Do not recreate it unless explicitly requested.
EnvoyMesh/
├── apps/
│ ├── node/ # Home node runtime (CLI, mesh, WebSocket API)
│ ├── relay/ # Relay binary (lean: connectivity + lookup, no LLMs)
│ ├── tauri/ # Native desktop wrapper (Social + node → DMG/EXE)
│ ├── social/ # Social/chat UI (Vite + React) — desktop
│ └── envoygo/ # ★ PRODUCT mobile app (Flutter thin client)
├── packages/ # protocol, identity, bonds, network, vault, models, local-store, mobile-identity (browser), …
├── sites/ # Public website + download QR assets
├── docs/ # Design docs, security model, implementation plan
├── QuickStart.md # Step-by-step guide
└── AGENTS.md # Architecture reference
Active product surfaces: Social (desktop) + EnvoyGo (mobile), with Envoy Harness for coding chat / Terminal and Pi for Terminal + Ext Agent. Dynamic relay roster (CN + US community hubs) ships in the desktop package seed.
Recent milestones (see docs/implementation-plan.md for the full list):
Earlier phases (trust modes, Agent Network / Team jobs, fleet onboarding, terminals, audio messages, family network, …) are also shipped — details in the roadmap.
QuickStart.md — install, run, mobile, multi-machine, bridgeMIT