A federated AI agent orchestration system built on AT Protocol primitives — agents with self-sovereign identity, capability discovery, decentralised task coordination, and portable reputation.
Status: MVP — 481 tests passing · persistent identities · real LLM inference · AT Protocol PDS bridge · Jetstream federation · knowledge + tool providers · composable multi-attestor trust · proof-chain dashboard
Mycelium is a protocol layer that fills the gap between centralised agent platforms (which lock in your data) and local-first runtimes (which offer no coordination). Agents own their identity and work history; orchestrators coordinate without controlling.
The MVP demonstrates the full lifecycle:
Bootstrap agents → Declare capabilities → Post tasks to Wanted Board →
Agents discover & claim tasks via Firehose → Execute (real or simulated) →
Mayor recommends, assigns, verifies completions → Reputation stamps link to evidence →
WorkTrace explains who did what, why it counted, and what changes next
Most agent frameworks (LangGraph, CrewAI, AutoGen) are single-process orchestrators — agents share a central database, coordination dies with the process, and reputation doesn't travel between platforms.
Mycelium follows AT Protocol's social architecture instead:
| Centralised (LangGraph / CrewAI) | Mycelium | |
|---|---|---|
| Identity | Assigned by framework | did:key / did:plc — cryptographic, self-sovereign, portable |
| Data | Central database | Agent-owned repos with signed commits |
| Coordination | Single process | AT Protocol relay — agents on different machines see each other |
| Reputation | Vendor-locked | Signed stamps, verifiable by any observer |
| Portability | Tied to the platform | Records live on any AT Protocol PDS |
Requirements: Node.js ≥ 20
npm install
# Level 0 — Pure simulation (zero config, ~50 seconds)
npm run demo
# Web dashboard (http://localhost:3000)
npm run dashboard
# Inspect the DuckDB database directly
npm run query "SELECT * FROM agent_identities"
npm run query "SELECT collection, COUNT(*) FROM firehose_events GROUP BY 1 ORDER BY 2 DESC"
# Clear all data for a fresh start
npm run reset
# Run tests
npm testEach level builds on the previous. Level 0 works out of the box.
| Level | Command | What you need |
|---|---|---|
| 0 — Simulation | npm run demo |
Nothing — pure simulation |
| 1 — Real LLM | MYCELIUM_ENABLE_INFERENCE=true GITHUB_TOKEN=ghp_... npm run demo |
Free GitHub token |
| 1b — Local LLM | MYCELIUM_ENABLE_INFERENCE=true LOCAL_ONLY_MODEL=qwen2.5:7b npm run demo |
Ollama installed |
| 2 — Persistent | npm run demo (after first run) |
Nothing extra — DIDs persist via DuckDB |
| 3 — Docker | docker compose up |
Docker |
Copy .env.example to .env and uncomment variables as needed.
npm run demo bootstraps a 6-agent team and runs an 8-task project end-to-end:
🍄 MYCELIUM MVP — Federated Agent Orchestration Demo
🤖 atlas ← Frontend specialist (claude-sonnet-4 via GitHub Models)
🤖 beacon ← Backend architect (claude-sonnet-4 via GitHub Models)
🤖 cipher ← Security analyst (gpt-4 via GitHub Models)
🤖 delta ← DevOps engineer (claude-haiku-4 via GitHub Models)
🤖 echo ← QA specialist (claude-sonnet-4 via GitHub Models)
🤖 forge ← Generalist (llama-3-70b via Ollama)
📋 PROJECT: Build the Mycelium Dashboard
8 tasks · dependency-gated posting · competing claims · reputation stamps
[████████] 8/8 accepted ✅
Agent Tasks Score Trust Rejected Model
atlas 3 85 🔵 established 0 claude-sonnet-4
beacon 1 86 ⬜ newcomer 0 claude-sonnet-4
cipher 1 83 ⬜ newcomer 0 gpt-4
...
All 6 agents use a local Ollama model (no API token required):
# Install Ollama: https://ollama.ai
ollama pull qwen2.5:7b
MYCELIUM_ENABLE_INFERENCE=true LOCAL_ONLY_MODEL=qwen2.5:7b DEMO_TIMEOUT_MS=600000 npm run demoOr use GitHub Models (free token at github.com/settings/tokens):
MYCELIUM_ENABLE_INFERENCE=true GITHUB_TOKEN=ghp_... npm run demoAgent DIDs persist in data/mycelium.duckdb across runs. Run the demo twice — reputation accumulates, the same agents return, their work history grows.
npm run demo # first run: generates identities
npm run demo # second run: reuses same DIDs, adds more stamps
npm run query "SELECT handle, did FROM agent_identities"
npm run reset # clear everything for a fresh startNo Node.js required — run the entire simulation in a container:
docker compose up
# open http://localhost:3000To also spin up a local AT Protocol PDS (agents mirror records to real XRPC repos, browseable via any AT Proto tool):
npm run pds-init # generates .env.docker with PDS secrets (run once)
docker compose --profile pds up # mycelium dashboard + local AT Proto PDS
# Dashboard: http://localhost:3000
# PDS: http://localhost:2583To add Jetstream federation (multiple Mycelium nodes see each other's agent activity):
docker compose --profile pds --profile jetstream upAfter running with --profile pds, you can inspect agent records directly:
# List records for an agent
curl "http://localhost:2583/xrpc/com.atproto.repo.listRecords?repo=<did>&collection=network.mycelium.task.posting"| Layer | Component | MVP Implementation |
|---|---|---|
| L0 | Agent Identity | did:key (Ed25519) — unique, cryptographically verifiable, persisted |
| L1 | Data Ownership | Per-agent in-memory stores (DuckDB-persisted) — agents own their records |
| L2 | Schemas | Zod-validated Lexicon-like records (19 types) |
| L3 | Federation | In-memory Firehose + AT Protocol PDS bridge (real XRPC) + Jetstream federation |
| L3 | Coordination | Wanted Board — task state machine (open→claimed→assigned→in_progress→completed→accepted/rejected→open) |
| L4 | Orchestration | Mayor — decomposes projects, ranks claims, quality-gates completions |
| L5 | Governance | Reputation — signed stamps, multi-dimensional scores, trust levels |
| L6 | Explanation | WorkTrace — derived proof chain for task lifecycle, evidence, and consequences |
Models are first-class entities with DIDs, enabling verifiable attribution:
GitHub Models (cloud) Ollama (local)
├── claude-sonnet-4 ├── llama-3-70b
├── claude-haiku-4 └── codellama
├── gpt-4
└── phi-4
src/
identity/ Ed25519 key generation, DID:key, signing/verification
repository/ In-memory record store (one store per agent)
storage/ DuckDB connection factory + async persistence layer
firehose/ In-memory pub/sub event bus
atproto/ AT Protocol bridge (PDS XRPC mirror + Jetstream federation consumer)
audit/ WorkTrace builder that derives human-readable proof chains from firehose events
schemas/ Zod schemas for all 19 record types
intelligence/ Provider/model bootstrap (GitHub Models + Ollama)
knowledge/ Knowledge provider bootstrap, seed documents, query with graceful degradation
tools/ Tool provider bootstrap, definition records, invocation with graceful degradation
agents/ Engine (bootstrap + createAgentRunner) + 6-agent roster
orchestrator/ Mayor + Wanted Board (recommendation, assignment, verification, quality gate)
reputation/ Stamp creation, aggregation, trust levels, rankClaims
constants.ts All magic numbers centralised
demo/
run.ts Full E2E CLI demo (DuckDB-backed, persistent identities)
dashboard/ Fastify SSE/REST server + HTML/CSS/JS dashboard
scripts/
reset.ts Clears data/ for a fresh start
query.ts DuckDB SQL inspector (npm run query "<SQL>")
Agent Sovereignty — Each agent has its own data store, persisted to DuckDB. The Mayor coordinates but never owns agent data. Agent identities (DIDs + keypairs) persist across runs.
Wanted Board — Tasks posted as task.posting records in the Mayor's repo. Agents subscribe to the Firehose, evaluate tasks via shouldClaim() (domain + proficiency + tag matching), file task.claim records in their own repos. The Mayor Bundle ranks competing claims by capability fit, reputation, and load, writes a match.recommendation record, then writes a task.assignment record for the selected worker. The matcher and coordinator roles are bundled in this demo, but their typed records make the boundary explicit.
Quality Gate — The Mayor Bundle evaluates completions against quality thresholds (pass rate, coverage, summary depth), writes a verification.result, and then stamps accepted or rejected work. Poor-quality work is rejected: the task reopens, the agent earns a negative stamp linked to the verification evidence, and another agent can claim it. After 3 attempts, the task is force-accepted.
Reputation — After verification, an attestor issues a reputation.stamp (multi-dimensional: code quality, reliability, communication, creativity, efficiency). Stamps are typed by attestorType (mayor, requester, peer, verifier) and weighted during aggregation — Mayor stamps carry 40%, requester feedback 35%, peer review 20%. Stamps live in the attestor's repo, signed and attributable, and can carry evidenceUris pointing to verification records. Any observer can aggregate them into a trust level (newcomer → established → trusted → expert). A stamp is evidence, not a global score.
Network Participants — The dashboard shows all entity types in a unified "Network Participants" view: 👤 human task requesters (with their own DID and AT Protocol identity), 🏛️ the Mayor Bundle (matcher, coordinator, verifier, and attestor roles bundled in this demo), 🤖 worker agents, 🔧 tool providers, and 📚 knowledge providers. Customer task.posting and task.review events are labeled by handle in the firehose.
Proof Chain / WorkTrace — Open a completed task in the dashboard to see a role-by-role proof chain: requester posted work, agents claimed it, matcher recommended a worker, coordinator assigned it, worker completed it, verifier checked it, and attestor issued a stamp. GET /api/tasks/:id/trace returns the same derived trace as JSON, including missing evidence for pending tasks and consequences for future routing.
Intelligence Attribution — Every task completion records intelligenceUsed: { modelDid, providerDid }. Reputation stamps carry intelligenceDid. The full provenance chain (agent + model + provider) is verifiable.
Knowledge Attribution — Before each LLM call, agents query registered knowledge providers. Every consultation writes a knowledge.query record (providerDid, queryHash, verificationLevel). contextCids reference specific knowledge.document records — CID-addressable when published to a PDS. Reputation stamps carry knowledgeRefs.
Tool Attribution — After the LLM generates a response, agents invoke matching tool providers. Every invocation writes a tool.invocation record referencing the AT URI of the specific tool.definition (not just a name — the definition has its own DID and CID). Reputation stamps carry toolRefs.
Set KB_ENDPOINT and TOOL_ENDPOINT env vars to connect live providers; without them, a built-in mock provider with seed documents and tools runs automatically.
# Who are the agents?
npm run query "SELECT handle, did, created_at FROM agent_identities"
# What happened in the last run?
npm run query "SELECT seq, collection, rkey, operation FROM firehose_events ORDER BY seq DESC LIMIT 20"
# Who earned the most stamps?
npm run query "SELECT did, COUNT(*) AS stamps FROM firehose_events WHERE collection = 'network.mycelium.reputation.stamp' GROUP BY did ORDER BY 2 DESC"
# What proof-chain records were produced?
npm run query "SELECT collection, COUNT(*) FROM firehose_events WHERE collection IN ('network.mycelium.match.recommendation', 'network.mycelium.task.assignment', 'network.mycelium.verification.result') GROUP BY 1 ORDER BY 1"
# Which tasks got rejected?
npm run query "SELECT rkey, content FROM records WHERE collection = 'network.mycelium.task.posting'"duckdb data/mycelium.duckdbnpm run dashboard # → http://localhost:3000The dashboard shows live SSE events, network participants, agent profiles, task timelines, proof chains, and evidence-linked reputation stamps.
After a task is posted, inspect its proof chain:
curl "http://localhost:3000/api/tasks/task-001/trace"npm test # run all 481 tests once
npm run test:watch # watch modeTest coverage: schemas, identity, firehose, repository, wanted-board, orchestrator, reputation, audit/WorkTrace, agents, intelligence, knowledge, tools, storage, atproto.
Full design rationale, schemas, and implementation notes in docs/PRD/:
README.md— Executive summary and MVP scopeARCHITECTURE.md— Component design and data flowSCHEMAS.md— All 19 Lexicon record type definitionsINTELLIGENCE.md— Intelligence provider strategyE2E-SCENARIO.md— Detailed demo walkthroughIMPLEMENTATION-PLAN.md— Phased build plan
- Lexicon publishing — Serve
network.mycelium.*Lexicon JSON from a controlled domain so NSIDs are resolvable by any AT Protocol client (the/.well-known/atproto-lexicon/:nsidroute exists; needs a registered domain) - Federation v2 — Multi-Mayor federation with real cross-node task discovery is proven on the older
feat/federationbranch; the next product step is forward-porting that topology onto the current proof-chain foundation. - Production hardening — Rate limiting, structured logging, health check endpoints, graceful shutdown