Run your AI agents on machines you already own, as one private network.
Package an agent as a container, drop it on the mesh, and call it from a desktop app, curl, or any OpenAI SDK.
Peer to peer, end-to-end encrypted, no cloud account, no data leaving your machines.
5-minute quest · How it works · What you can build · Python SDK · Docs · agentfm.net
Why AgentFM
You probably have more compute than you think. The laptop you're reading this on. The desktop with a GPU that sits idle most of the day. A homelab box, a teammate's workstation, the old server in the corner. Meanwhile your agents run on someone else's cloud, billed per token, with your prompts and files leaving the building.
AgentFM turns those machines into one mesh. Install one binary (or the desktop app) on each machine and they find each other: instantly over mDNS on the same Wi-Fi, through a relay lighthouse everywhere else, even behind NAT. Agents run in throwaway Podman sandboxes on whichever machine has room, and you talk to the whole mesh as if it were one OpenAI endpoint.
- Your hardware, pooled. Workers report CPU, GPU, RAM and queue depth every ~2 s, and each task goes to the least-loaded machine that can run it.
- Your data stays on your mesh. Tasks go peer to peer over encrypted libp2p streams. Add a swarm key and only your own machines can even see the network.
- Your code already works. The gateway speaks the OpenAI wire format, so LangChain, LlamaIndex, LiteLLM, Open WebUI and the
openaiSDKs just need a newbase_url. - Trust without a middleman. Every rating is Ed25519-signed and lands in a per-peer, append-only Merkle log. Reputation is computed from that log, and peers caught rewriting history are blocked mesh-wide. No allow-lists, no central server, no blockchain. → How trust works
The 5-minute quest
LVL 1 · Dispatch a task from the desktop app
- Download the app from Releases:
AgentFM-.dmg(macOS, arm64 and x64) orAgentFM-.AppImage(Linux). Windows is in progress. - Launch it. It bundles a full AgentFM node and joins the public mesh on its own.
- Open Mesh Radar, pick an agent, press Dispatch, and watch the output stream back. Rate the result when it's done.
macOS says the app can't be opened?
The v1 installers aren't signed yet. Allow the first launch in System Settings → Privacy & Security → Open Anyway, or clear the quarantine flag before mounting:
xattr -d com.apple.quarantine ~/Downloads/AgentFM-*.dmg
LVL 2 · Call the mesh from your own code
While the app is running, its node serves the AgentFM API on 127.0.0.1:8080. Anything that speaks OpenAI can use the mesh now.
# every agent your node can see, with its hardware and load
curl -s http://127.0.0.1:8080/v1/models
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8080/v1", api_key="unused-on-localhost")
reply = client.chat.completions.create(
model="llama3.2", # a model engine, an agent name, or a peer ID
messages=[{"role": "user", "content": "Draft a sick-leave email for tomorrow."}],
)
print(reply.choices[0].message.content)
model matches a peer ID first, then an agent name, then a model engine; the least-loaded match wins. Use one of the names /v1/models lists. → OpenAI-compatible API
No desktop app? Install the binary withcurl -fsSL https://api.agentfm.net/install.sh | bashand runagentfm -mode apifor the same gateway. → Install
LVL 3 · Put your own machine on the mesh
This level needs Podman (the sandbox) and Ollama (a local model). If you have both, it takes about three minutes.
Install Podman and Ollama (macOS shown; use your package manager on Linux)
brew install podman && podman machine init && podman machine start
curl -fsSL https://ollama.com/install.sh | sh && ollama pull llama3.2
curl -fsSL https://api.agentfm.net/install.sh | bash # skip if you installed it in LVL 2
git clone https://github.com/Agent-FM/agentfm-core && cd agentfm-core
agentfm -mode worker \
-agentdir ./agent-example/sick-leave-generator/agent \
-image agentfm-sick-leave:v1 -model llama3.2 \
-agent "HR Assistant" -maxtasks 10
Your machine now shows up in Mesh Radar and in /v1/models. Every task runs in a fresh podman run --rm container, and any files the agent writes to /tmp/output come back zipped to ./agentfm_artifacts/. Quest complete.
Next: publish your own agent to the public mesh
There's no allow-list. Push your image anywhere, start a worker, and your agent is live. Reputation builds up from honest behaviour over time.
podman build -t ghcr.io/you/myagent:v1 ./my-agent && podman push ghcr.io/you/myagent:v1
agentfm -mode worker -agentdir ./my-agent -image ghcr.io/you/myagent:v1 \
-agent "My Agent" -capability "research-assistant" -model llama3.2
The public lighthouse is built in: /ip4/78.47.21.107/tcp/4001/p2p/12D3KooWQHw8mVQkx17kLTNiRTbYckU2cAGcAwFFLzVJhhmBs5zL. Raise the dispatch gate with --reputation-floor=-0.3, or leave the public mesh entirely with a private swarm. Writing an agent: docs/worker.md.
How it works
One agentfm binary, and -mode picks the role:
| Role | What it does |
|---|---|
| Worker | Runs your agent in a fresh Podman sandbox and broadcasts its live hardware to the mesh. |
| Boss | Finds workers and dispatches tasks: the desktop app, the api gateway, or the boss terminal UI. |
| Relay | A lighthouse that helps peers find each other and punch through NAT, and keeps a copy of the trust ledger so a fresh node can catch up. Tasks go directly between peers; only when NAT can't be punched do they pass through the relay, still end-to-end encrypted. |
Follow one dispatch, step by step
Every dispatch passes the trust gate before a stream opens. Peers caught equivocating are blocked, peers below --reputation-floor get 403, and missing fields fail fast with 400.
sequenceDiagram
participant C as Client (SDK / curl / Desktop)
participant B as Boss (api)
participant W as Worker
participant P as Podman sandbox
C->>B: POST /api/execute {worker_id, prompt}
B->>B: validate fields (400 if missing)
B->>B: trust gate: reputation + equivocation (403 if refused)
B->>W: open task stream (prompt)
W->>P: podman run --rm (mount /tmp/output)
P-->>W: stdout streamed live
W-->>B: stdout + artifact zip
B-->>C: streamed output + trust badge
C->>B: POST /v1/peers/{id}/comments/self (rating -1..+1)
B->>B: sign + append to Merkle log, gossip to mesh
Wire protocols and internals: docs/architecture.md.
What you can build
|
Pool your team's GPUs |
A private, invite-only mesh |
|
Local models behind the OpenAI API |
Fan out batch jobs |
|
Share an agent with the world |
Audit who did what |
Desktop app
A mesh console for macOS and Linux: see every agent, dispatch, chat, rate, and collect artifacts. No terminal needed, and it ships the full backend, so installing it gives you a complete node.
![]() Mesh Radar: every agent, live load, honesty stars, one-click dispatch |
![]() Dispatch: live-streamed output with a trust badge |
More screens: chat, agent profile, artifacts, status
![]() Chat: pin an agent, stream replies, rate each one |
![]() Agent profile: reputation, signed ratings, Merkle-backed history |
![]() Artifacts: every file an agent produced, by project |
![]() Status: node health, relay connectivity, reachability |
Full tour: docs/DESKTOP.md · build it yourself: agentfm-desktop/
Python SDK
pip install agentfm-sdk
from agentfm import AgentFMClient
with AgentFMClient(gateway_url="http://127.0.0.1:8080") as client:
workers = client.workers.list(model="llama3.2", available_only=True)
result = client.tasks.run(worker_id=workers[0].peer_id, prompt="Draft a leave policy.")
print(result.text, result.artifacts) # artifacts: list[Path], auto-extracted
Typed sync and async clients, the full OpenAI-compatible namespace, scatter / scatter_by_model batch dispatch, and signed webhook callbacks. → SDK guide · HTTP API reference
One binary, six modes
Each mode has its own flags (agentfm --help). Add -swarmkey and -bootstrap to put any of them on a private swarm.
| Mode | Role | Example |
|---|---|---|
| worker | Run your agent in a Podman sandbox | agentfm -mode worker -agentdir ./a -image a:v1 -agent "My Agent" -model llama3.2 -maxtasks 4 |
| api | Headless HTTP + OpenAI gateway (what the desktop app runs) | agentfm -mode api -apiport 8080 -reputation-floor -0.3 |
| boss | Interactive terminal dispatcher | agentfm -mode boss |
| relay | Lighthouse: Circuit Relay v2, DHT, archive ledger | agentfm -mode relay -port 4001 -swarmkey ./swarm.key |
| witness | Ledger-only replica that catches equivocation | agentfm -mode witness |
| genkey | Generate a private-swarm key | agentfm -mode genkey |
Every flag: docs/cli.md.
Docs
| Get started | Run it | Under the hood |
|---|---|---|
| Install the binaries
Desktop app guide
Python SDK
OpenAI-compatible API | Run a worker
Private swarms
Authentication
Observability
CLI reference | Architecture & wire protocols
Trust & verification
Security model
HTTP API reference
Changelog |
Contribute
AgentFM is a monorepo: the Go node in agentfm-go/, the Electron app in agentfm-desktop/, the SDK in agentfm-python/, example agents in agent-example/ and the website in agentfm-web/.
- Start with an issue labelled good first issue, or build a new example agent.
- Branch as
feature/…,bugfix/…ordocs/…, and read CONTRIBUTING.md and docs/development.md to build from source. - Found a vulnerability? Follow SECURITY.md instead of opening an issue. Everyone here follows the Code of Conduct.





