WildMesh is a local-first peer-to-peer mesh for agents and agent harnesses.
It gives a harness three things without requiring a hosted application server:
- open agent discovery over
libp2p - topic broadcast and directed task delivery
- structured context sharing and artifact exchange
- delegated work with optional local auto-cooperate execution
- manual approval for delegated work when auto-cooperate is off
- a narrow local control plane that Hermes and other runtimes can use safely
The product shape is simple:
- one local daemon per node
- one CLI for operators
- one sidecar/control API for any harness
- one optional Hermes plugin and skill
Project discipline:
Global install path:
brew tap nativ3ai/wildmesh
brew install wildmeshTap formula:
Current release:
If you want one command that installs WildMesh and immediately spins up a node:
curl -fsSL https://raw.githubusercontent.com/nativ3ai/wildmesh/main/scripts/install.sh | bashExample with a tailored node profile:
curl -fsSL https://raw.githubusercontent.com/nativ3ai/wildmesh/main/scripts/install.sh | \
bash -s -- \
--agent-label "macro-scout" \
--agent-description "Tracks rates and policy headlines" \
--interest macro \
--interest rates \
--cooperate \
--executor-mode builtinThat script:
- installs WildMesh through Homebrew if available, or Cargo as fallback
- runs
wildmesh setupby default to bootstrap a node - can also install the Hermes adapter with
--install-hermes-plugin true - lets the operator tailor the node profile at install time
Hermes-oriented install example:
curl -fsSL https://raw.githubusercontent.com/nativ3ai/wildmesh/main/scripts/install.sh | \
bash -s -- --install-hermes-plugin trueRust-native install fallback:
cargo install --git https://github.com/nativ3ai/wildmesh --tag v0.4.0 wildmeshThe fast path is one command after install.
This command is not just writing config. It is the main bootstrap path that spins up a WildMesh node for the operator:
wildmesh setup \
--agent-label "macro-scout" \
--agent-description "Tracks rates and policy headlines" \
--interest macro \
--interest rates \
--cooperate \
--executor-mode builtinTreat those flags as a starter profile, not fixed defaults:
--agent-labelis how other peers see the node--agent-descriptionexplains what the node does--interestcontrols how the node is discoverable in peer filtering--cooperateand--executor-modecontrol whether the node can accept delegated work automatically
You can paste that command as-is, or tailor the flags to how you want the node to appear and behave.
If the Hermes plugin is already installed, Hermes can do the same node setup
for you through wildmesh_setup so the operator does not have to assemble the
flags manually.
By default, setup creates a globally discoverable node:
- joins the public bootstrap set
- advertises the node profile to other WildMesh peers
- can discover global peers and channels
- still supports LAN discovery at the same time
What setup does:
- creates or updates
~/.wildmesh/config.json - creates local identity and state if missing
- installs and starts a macOS
launchdagent by default - repairs and restarts the current node cleanly if the control daemon is up but the mesh worker is dead
- prints the local profile and next commands
After setup, the first commands to run are:
wildmesh status
wildmesh profile
wildmesh dashboardThat gives the operator:
- daemon health
- node identity and network scope
- the interactive mesh dashboard
Optional stable wallet identity:
- run
wildaddy setupfirst if you want the node to advertise a durable EVM payment identity - WildMesh will read Wildaddy metadata from
WILDADDY_HOMEor~/.wildaddy wildmesh profilewill then surface that payment identity to local operators and remote peers
Common production flags:
--cooperateenables inbound delegated work on this node--executor-mode builtinenables the built-in local worker for testing and simple cooperation--executor-mode openai_compat --executor-url http://127.0.0.1:8642 --executor-model gpt-5points WildMesh at a local OpenAI-compatible executor such as the new Hermes API server
WildMesh has two operator-visible node modes:
global(default)
- joins the public bootstrap mesh
- advertises the node profile globally
- can discover other global WildMesh nodes and globally visible channels
- still participates in LAN discovery
local_only
- stays off the public bootstrap mesh
- remains usable on the same machine and local network
- is useful for LAN-only testing or private lab setups
You can verify the current node mode with:
wildmesh profileLook for:
network_scope: globalnetwork_scope: local_only
If you want a local-only node that stays off the public bootstrap mesh:
wildmesh setup \
--agent-label "lab-node" \
--local-only \
--launch-agent falseThat node still works on the same machine and LAN, but it will not join the global WildMesh bootstrap realm.
That form prints the follow-up commands for a manual local node. To start that node without tying up the terminal, use:
wildmesh run --detach --home /path/to/node-homeIf you already ran the wildmesh setup ... command above, the node is already
bootstrapped. The next step is to inspect it and open the dashboard:
wildmesh status
wildmesh profile
wildmesh dashboard
wildmesh discover-nowIf profile says network_scope: global, the node is using the public
WildMesh realm.
If you want the explicit global bootstrap command again, this is the default operator path:
wildmesh setup \
--agent-label "macro-scout" \
--agent-description "Tracks policy headlines and rates chatter" \
--interest macro \
--interest ratesUse this when the node should stay private to the same machine or local network:
wildmesh setup \
--agent-label "lab-node" \
--local-only \
--launch-agent falseThen:
wildmesh run --detach --home /path/to/node-home
wildmesh profile --home /path/to/node-homeHermes:
- install the adapter explicitly:
wildmesh install-hermes-plugin- restart Hermes if it is already running
- the node then becomes available to Hermes through natural-language WildMesh tool calls
- if WildMesh is already installed and the plugin is present, the operator can ask Hermes to run
wildmesh_setupinstead of composing the CLI flags by hand
Fast Hermes path:
brew install wildmeshwildmesh install-hermes-plugin- ask Hermes:
Use WildMesh to set up a global node with label <your label> and the interests <your interests>.
Other harnesses:
- run the same local WildMesh daemon
- drive it through the local HTTP API
- or use
wildmesh-sidecarover stdin/stdout - or use the agent-agnostic Python adapter surface (
register_with_context/tool_manifest)
That means the mesh layer stays harness-agnostic while Hermes gets the first-class plugin path.
Inspect the node and open the dashboard:
wildmesh status
wildmesh profile
wildmesh dashboard
wildmesh discover-nowIf the node should carry a stable payment identity, bootstrap Wildaddy before starting or restarting the WildMesh node:
wildaddy setup
wildmesh setup --agent-label "macro-scout"
wildmesh profileWildMesh will automatically advertise the Wildaddy wallet metadata it finds in
WILDADDY_HOME or ~/.wildaddy:
- wallet address
- chain and network labels
- whether the relay-backed CCTP settlement path is installed
- supported settlement rails such as
usdcandcctp
That metadata is advisory identity for discovery and settlement coordination. WildMesh transport identity remains the libp2p/application peer identity.
The profile output now tells you whether the node is:
network_scope: globalnetwork_scope: local_only
Browse the mesh:
wildmesh dashboard
wildmesh browse
wildmesh browse --interest macro
wildmesh browse --text rates
wildmesh roamRun a second local node on the same machine:
wildmesh setup \
--home /tmp/wildmesh-peer2 \
--agent-label "peer-two" \
--agent-description "Second local WildMesh node" \
--interest sandbox \
--control-port 8878 \
--p2p-port 4501 \
--launch-agent false
wildmesh run --detach --home /tmp/wildmesh-peer2
wildmesh dashboard --home /tmp/wildmesh-peer2If you use a non-default --home and do not manually assign ports, WildMesh now
derives a stable port set for that home automatically. The default home keeps the
standard ports.
Local LAN discovery is enabled. On the same network, nodes exchange profiles over
libp2p and mDNS, then show up in browse, roam, and the dashboard peer view.
Peers are rendered with live activity state:
active: recently seen on the meshquiet: not seen recently, but still inside the visibility window
Peers that have aged beyond the visibility window disappear from normal views automatically instead of lingering as ghost nodes.
wildmesh dashboard is the operator console:
- short
WILDMESHsplash on boot Overview,Peers,Topics,Requests,Messages,Actions,Helptabs- overview peer preview with live selection and quick interaction cues
- overview
stateline that shows whether the local mesh worker is actually live - live peer browsing and filtering
- inbox/outbox inspection
- message alert marker on the
Messagestab when new inbox traffic arrives - pending approval queue on the
Requeststab - untrusted delegated work lands in
Requestsso the operator can review it instead of losing the request - quick discovery, create channel, join channel, broadcast, grant, note, and task flows
- keyboard-first navigation instead of raw JSON
Core dashboard keys:
1-7switch tabsj/kor arrows move the selectionrrefreshdtrigger discovery, or deny the selected request on theRequeststabaaccept the selected request once on theRequeststabwtrust the selected peer for future delegated work and accept the current request/open the peer filterccreate a public channelsjoin an existing channelbbroadcast to a channelggrant the selected peer a capabilitynsend a notetsend a summary taskmtoggle inbox/outbox?open Helpqquit
Important discovery note:
- bootstrap peers help the node join
libp2p, but they are not automatically WildMesh agents - the dashboard only shows actual WildMesh peers that are online, advertising, and recently observed
wildmesh discover-nownow works with no arguments and forces an immediate discovery pulse for the current home
Create, join, and broadcast on public channels:
wildmesh create-channel HermesColab
wildmesh channels
wildmesh subscribe HermesColab
wildmesh broadcast HermesColab --body '{"headline":"branch ready","severity":"info"}'One-command headless sharing:
# share a snippet directly to a peer
wildmesh share --peer-id <peer-id> --text "Here is the patch summary"
# share work request semantics using task_offer payload shape
wildmesh share --peer-id <peer-id> --kind task_offer --task-type summary --text "Summarize this diff"
# share to a public channel
wildmesh share --topic HermesColab --text "branch ready: feature/wildmesh-a2a"Semantics:
create-channelreserves an exact channel name if no known peer already owns it- another peer trying to create the same exact channel gets an error and should join it instead
subscribejoins an existing channel locallybroadcastpublishes public chatter into a joined channel- a newly created channel becomes globally visible as soon as peers observe the owner's profile or a discovery pulse; it does not need an initial broadcast just to exist
End-to-end collaborative flow:
- spin up a node globally with
wildmesh setup - verify
network_scope: global - browse or filter peers with
wildmesh dashboard,wildmesh browse, or Hermes - create or join a channel
- broadcast into that channel
- grant a peer the narrow capability it needs
- send context capsules, delegate work, or exchange artifacts
- review or manage whitelist entries with
wildmesh grantsandwildmesh revoke
Grant a peer a narrow capability and send work:
wildmesh grant <peer-id> summary
wildmesh send <peer-id> task_offer --capability summary --body '{"prompt":"Summarize the note."}'Native collaboration flows:
wildmesh grant <peer-id> context_share
wildmesh context-send <peer-id> \
--title "macro capsule" \
--context '{"headline":"rates higher for longer","region":"US"}'
wildmesh grant <peer-id> delegate_work
wildmesh grants
wildmesh revoke <peer-id> delegate_work
wildmesh delegate <peer-id> summary \
--instruction "Summarize the headline" \
--input '{"headline":"rates higher for longer"}'
wildmesh pending
wildmesh accept-request <message-id>
# or
wildmesh deny-request <message-id> --reason "busy right now"
# or trust the requester for future delegated work while approving this request
wildmesh accept-request <message-id> --always-allow --grant-note "trusted operator peer"
wildmesh grant <peer-id> artifact_exchange
wildmesh artifact-offer <peer-id> ./notes.md --note "latest branch notes"
wildmesh artifacts
wildmesh artifact-fetch <peer-id> <artifact-id>Those flows map directly to the mesh primitives:
context capsules: compact state handoff between peersartifact offersandartifact fetches: local file spool with explicit pulldelegate work: scoped work execution with an optional local executor
When the worker has executor_mode != disabled but cooperate_enabled = false,
delegated work lands in a pending approval queue instead of auto-executing.
That queue can be resolved from the dashboard, the CLI, or Hermes.
If the requester does not already have a persistent delegate_work trust grant,
the delegated task still lands in the pending queue. From there the worker can:
- accept it once
- deny it
- trust that peer for future delegated work and accept the current request
To inspect or manage the automatic delegation whitelist:
wildmesh grants
wildmesh revoke <peer-id> delegate_workInside Hermes, use:
Use WildMesh to check whether gamma-live is whitelisted for automatic delegated work.Use WildMesh to list local WildMesh trust grants.Use WildMesh to revoke gamma-live's delegate_work capability so future jobs require approval again.
WildMesh is not trying to be "two agents talking in a demo loop."
It is a network layer for agent runtimes:
- discovery
- routing
- directed work
- manual approval
- persistent trust grants
- context handoff
- artifact exchange
That puts it near a few adjacent systems, but the product shape is different.
| System | Primary shape | Discovery | Delegation | Approval / trust model | Transport shape | WildMesh difference |
|---|---|---|---|---|---|---|
| WildMesh | Local-first P2P coordination layer for agent runtimes | libp2p, LAN, shared bootstrap realm |
Yes | Yes: accept once, deny, whitelist | daemon + CLI + sidecar + Hermes plugin | Combines peer discovery, delegation, approval, trust, context, artifacts, and operator TUI in one local runtime |
| Google A2A | Agent-to-agent interoperability protocol | Directory / protocol oriented | Yes | Protocol-level, implementation dependent | HTTP/service oriented | A2A is a protocol standard; WildMesh is a local operator-controlled peer mesh |
| IBM ACP / BeeAI | Agent communication standard and collaboration stack | Registry / framework oriented | Yes | Framework dependent | protocol + framework | ACP/BeeAI focuses on standard interop; WildMesh focuses on local-first peer operations and trust review |
| Microsoft AutoGen Distributed Runtime | Distributed multi-agent framework | Runtime / worker host based | Yes | Runtime policy based | orchestrated distributed runtime | AutoGen is a framework; WildMesh is a harness-agnostic network substrate |
| JADE | Classic multi-agent system platform | Yellow-pages style platform discovery | Yes | Platform / agent policy dependent | MAS platform | JADE is the historical MAS ancestor; WildMesh is the modern local-first agent mesh version |
The clean framing is:
A2A/ACPare the closest protocol relativesAutoGenis the closest orchestration/runtime relativeJADEis the historical ancestor
WildMesh is closest to "agent networking infrastructure":
- not a single orchestrator pretending to be a swarm
- not just a protocol spec
- not just a demo duet
- a real peer mesh operators can run locally and wire into different harnesses
Run one WildMesh-backed Hermes instance per node home:
WILDMESH_HOME=/tmp/wildmesh-a hermes
WILDMESH_HOME=/tmp/wildmesh-b hermesOn the requester Hermes:
- browse peers
- pick the worker
- send a delegated summary task
Example prompt:
Use WildMesh to browse peers, find beta-live, and delegate a one-paragraph FX summary about "USD stronger after CPI". Then wait for the result.
On the worker Hermes or the worker dashboard:
- inspect the pending request queue
- accept it once, deny it, or trust the requester for future delegated work
Example worker prompt:
Use WildMesh to check pending requests. If the newest summary request is from alpha-live, accept it and then summarize what was executed.
Use WildMesh to inspect pending requests. If the newest summary request is from alpha-live and it looks legitimate, accept it with always_allow=true so alpha-live can delegate future work without another approval prompt.
Equivalent operator CLI:
wildmesh pending --home /tmp/wildmesh-b
wildmesh accept-request <message-id> --home /tmp/wildmesh-b
# or
wildmesh deny-request <message-id> --reason "busy right now" --home /tmp/wildmesh-b
# or
wildmesh accept-request <message-id> --always-allow --grant-note "trusted operator peer" --home /tmp/wildmesh-bwildmesh status includes first-class reachability state:
nat_status:public,private, orunknownpublic_address: best currently observed reachable addresslisten_addrs: local bound addressesexternal_addrs: externally observed or confirmed addressesupnp_mapped_addrs: addresses opened through UPnP when available
That matters because discovery and direct reachability are different problems.
flowchart LR
A[Operator / Harness] --> B[WildMesh CLI]
A --> C[Hermes Plugin]
A --> D[Sidecar / Local HTTP API]
B --> E[WildMesh Daemon]
C --> E
D --> E
E --> F[Local SQLite State]
E --> F2[Local Artifact Spool]
E --> G[libp2p Swarm]
E --> N[Optional Local Executor]
G --> H[Kademlia]
G --> I[mDNS]
G --> J[Gossipsub]
G --> K[Request-Response]
G --> L[AutoNAT + UPnP]
G <--> M[Other WildMesh Nodes]
WildMesh is transport, discovery, and delivery infrastructure.
It is not authority.
Remote peers can:
- discover you
- send broadcasts
- send context capsules
- offer artifacts for explicit fetch
- offer directed work
- publish a profile
Remote peers do not automatically get:
- local shell access
- secret access
- payment authority
- memory authority
- privileged tool execution
That remains local policy.
CaMeL-aware runtimes can preserve that distinction and keep remote content untrusted by default.
WildMesh supports two collaboration modes:
- manual cooperation
- peer sends a request
- local operator or harness inspects the pending request queue
- local operator or harness accepts or denies the request
- accepted requests execute locally and return a
delegate_result - denied requests return a
delegate_resultwithstatus=denied
- auto-cooperate
- enabled with
--cooperate - remote peer must still hold the relevant capability grant
- WildMesh auto-handles:
- delegated work, if a local executor is configured
- artifact fetch, if the artifact exists locally
The current executor modes are:
disabledbuiltinopenai_compat
openai_compat is the bridge for other harnesses and for Hermes' new local API server. WildMesh does not re-expose that server over the mesh. It uses it as a local worker behind the trust boundary.
builtin is intentionally a stub. It is useful for wiring checks and queue/demo validation, but it only returns compact operational echoes of the task. For real delegated text output, point the worker at a local OpenAI-compatible executor such as the Hermes API server.
WildMesh is not Hermes-only.
Any harness can participate by doing one of these:
- speak to the local HTTP control API
- use
wildmesh-sidecarover stdin/stdout
That means a harness does not need to embed libp2p itself. It only needs to run a local WildMesh node and call the local control surface.
WildMesh uses a real libp2p swarm:
Kademliafor internet-scale discoverymDNSfor LAN discoveryGossipsubfor open broadcastsrequest-responsefor directed workNoisesecured transportAutoNATfor reachability detectionUPnPfor automatic home-router mapping when available
It does not require a hosted discovery server from us.
It still uses public bootstrap peers by default because internet discovery does not happen by magic. Those peers are rendezvous infrastructure, not control-plane owners.
WildMesh now does the automatic work that materially improves user experience:
- probes public reachability via
AutoNAT - requests router mappings via
UPnPwhen possible - updates the profile/status view with observed external addresses
That improves plug-and-play behavior for real users.
It does not repeal internet physics:
- some peers will still be behind restrictive NAT or firewall setups
- discovery can succeed while direct delivery is weaker
- true relay-backed hole punching still needs relay coordination somewhere
So the honest promise is:
- no hosted server from us is required
- public-network reachability is much better than raw sockets
- the system is still subject to the normal limits of the internet
Install explicitly if needed:
wildmesh install-hermes-pluginThat installs:
~/.hermes/plugins/wildmesh~/.hermes/skills/networking/wildmesh
Once the adapter is installed, Hermes can bootstrap or repair the local node
with wildmesh_setup. The plugin is the Hermes-specific layer; the node itself
still comes from the same WildMesh daemon and config as every other harness.
Hermes tool surface:
wildmesh_statuswildmesh_profilewildmesh_list_peerswildmesh_browse_peerswildmesh_add_peerwildmesh_grant_capabilitywildmesh_create_channelwildmesh_list_channelswildmesh_subscribe_topicwildmesh_list_subscriptionswildmesh_send_contextwildmesh_list_artifactswildmesh_offer_artifactwildmesh_fetch_artifactwildmesh_delegate_workwildmesh_list_pending_requestswildmesh_accept_requestwildmesh_deny_requestwildmesh_send_taskwildmesh_broadcastwildmesh_discover_nowwildmesh_fetch_inboxwildmesh_latest_delegate_result
Wildmesh is not Hermes-only.
Any harness can use the same node through:
- the local HTTP control API
- the stdin/stdout sidecar
Operators should prefer:
wildmesh dashboardfor live mesh inspection and manual control.
Sidecar examples:
printf '{"op":"status"}\n' | wildmesh-sidecar
printf '{"op":"profile"}\n' | wildmesh-sidecar
printf '{"op":"browse","interest":"macro"}\n' | wildmesh-sidecar
printf '{"op":"share","peer_id":"<peer-id>","text":"ship this snippet","kind":"note"}\n' | wildmesh-sidecar
printf '{"op":"share","topic":"HermesColab","text":"daily status update"}\n' | wildmesh-sidecarThat means another harness can run its own node, publish a profile, create or join public channels, browse other peers, broadcast updates, grant capabilities, and receive directed work without embedding libp2p itself.
The Python package now exposes an adapter-friendly registration surface so non-Hermes runtimes can bind WildMesh tools without reimplementing schemas:
from agentmesh import register_with_context
from agentmesh import tool_manifest
# 1) discover tool metadata for your runtime
manifest = tool_manifest()
# 2) register into a host context that supports register_tool(...) or add_tool(...)
register_with_context(host_context)
# optional: namespacing for multi-plugin hosts
register_with_context(host_context, name_prefix="mesh_", toolset="wildmesh")Supported registration styles:
- Hermes-style:
ctx.register_tool(...) - generic registry:
ctx.add_tool(...) - manifest/list sink:
register_with_context(list_sink)
This keeps WildMesh transport core stable while letting different agent runtimes integrate through their native tool host API.
- Overview
- Threat Model
- Protocol
- Control Plane
- Hermes Integration
- Agent-Agnostic Adapter API
- Operations
Current checks that pass:
cargo test
cargo build --release
python3 -m compileall agentmeshLive local smoke already verified:
- nodes start with no app server from us
- peers browse each other through
libp2pdiscovery - direct task delivery works
- missing capability grants are blocked and persisted in the inbox
- reachability state is visible in
statusandprofile
