{"_id":"meshfleet","_rev":"6-55481c9cab9b3d08cd678dbe1592d73e","name":"meshfleet","dist-tags":{"latest":"0.20.0"},"versions":{"0.11.1":{"name":"meshfleet","version":"0.11.1","keywords":["mcp","opencode","agent","orchestration","swarm","fleet","p2p","peer-to-peer","model-context-protocol","audit","receipts","quorum","multi-agent"],"license":"MIT","_id":"meshfleet@0.11.1","maintainers":[{"name":"johnwhitman","email":"johndw@gmail.com"}],"homepage":"https://meshfleet.app","bugs":{"url":"https://github.com/johnmwhitman/agent-mesh/issues"},"bin":{"meshfleet":"dist/index.js","agent-mesh":"dist/bin/inspect.js","agent-mesh-dashboard":"dist/bin/dashboard.js"},"dist":{"shasum":"1c099a5e38c75d35d25b842d4d1cd79125b6c641","tarball":"https://registry.npmjs.org/meshfleet/-/meshfleet-0.11.1.tgz","fileCount":22,"integrity":"sha512-Gxau76yv/nx6Htxhys59pIulq72YPP1wL8z/BB7c3RBaiMk8Gl8wwQgFJnfZgvNdLCQ3VJ71FCpeWmurehO5Dg==","signatures":[{"sig":"MEUCIE7kDo1XJ2t+98oObW6fb4DwtG9eosS+CHisIDPLyPRZAiEAgBEIvdpo2TKYRwsLegZ18T4NMv8gDTY8w72Wm5KRV2s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":153554},"main":"dist/index.js","type":"module","engines":{"node":">=18"},"gitHead":"42efae539da09002ed6ecdace8d8bea60383f90c","scripts":{"dev":"tsx watch src/index.ts","test":"node scripts/run-tests.mjs","build":"tsc","start":"node dist/index.js","inspect":"node dist/bin/inspect.js","typecheck":"tsc --noEmit","release:pack":"npm pack","prepublishOnly":"npm run build && npm test","release:verify":"npm run build && npm test && npm pack --dry-run","release:publish":"npm run release:verify && npm publish"},"_npmUser":{"name":"johnwhitman","email":"johndw@gmail.com"},"repository":{"url":"git+https://github.com/johnmwhitman/agent-mesh.git","type":"git"},"_npmVersion":"11.17.0","description":"Auditable multi-agent coordination for OpenCode — parallel agent fleets with P2P messaging, witnessed receipts, and quorum ratification. Who saw this, who approved it, prove it.","directories":{},"_nodeVersion":"26.4.0","dependencies":{"@modelcontextprotocol/sdk":"^1.29.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/meshfleet_0.11.1_1783109081823_0.6701948250208587","host":"s3://npm-registry-packages-npm-production"}},"0.13.0":{"name":"meshfleet","version":"0.13.0","keywords":["mcp","opencode","agent","orchestration","swarm","fleet","p2p","peer-to-peer","model-context-protocol","audit","receipts","quorum","multi-agent"],"license":"MIT","_id":"meshfleet@0.13.0","maintainers":[{"name":"johnwhitman","email":"johndw@gmail.com"}],"homepage":"https://meshfleet.app","bugs":{"url":"https://github.com/johnmwhitman/agent-mesh/issues"},"bin":{"meshfleet":"dist/index.js","agent-mesh":"dist/bin/inspect.js","agent-mesh-dashboard":"dist/bin/dashboard.js"},"dist":{"shasum":"d8de48fa859d937d43e1f0d311efca65feb3cb0b","tarball":"https://registry.npmjs.org/meshfleet/-/meshfleet-0.13.0.tgz","fileCount":26,"integrity":"sha512-XmQXlwjBqpbbO06W5649knsyi+vs75hL2m9wL3lzCv0FBKr5aOX4+iX8u3agaYhlgtR1Od5cpHT6je1CUogKBQ==","signatures":[{"sig":"MEUCIQD88Idqt+EHuTHqDA1nKFpwXYA7P1tW7H0jtgreIu6WxwIgBVghsWZrHzfkwc/ymBwfFg1Ki3NTObual+cFRJGnrn4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":223269},"main":"dist/index.js","type":"module","engines":{"node":">=20"},"gitHead":"45d0a9157d1357eb7893c5a72bcc46f39fde57d3","scripts":{"dev":"tsx watch src/index.ts","test":"node scripts/run-tests.mjs","build":"tsc","start":"node dist/index.js","inspect":"node dist/bin/inspect.js","typecheck":"tsc --noEmit","release:pack":"npm pack","prepublishOnly":"npm run build && npm test","release:verify":"npm run build && npm test && npm pack --dry-run","release:publish":"npm run release:verify && npm publish"},"_npmUser":{"name":"johnwhitman","email":"johndw@gmail.com"},"repository":{"url":"git+https://github.com/johnmwhitman/agent-mesh.git","type":"git"},"_npmVersion":"11.17.0","description":"Auditable multi-agent coordination for OpenCode — parallel agent fleets with P2P messaging, witnessed receipts, and quorum ratification. Who saw this, who approved it, prove it.","directories":{},"_nodeVersion":"26.4.0","dependencies":{"better-sqlite3":"^12.11.1","@modelcontextprotocol/sdk":"^1.29.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/better-sqlite3":"^7.6.13"},"_npmOperationalInternal":{"tmp":"tmp/meshfleet_0.13.0_1784238949400_0.9550902120961757","host":"s3://npm-registry-packages-npm-production"}},"0.15.0":{"name":"meshfleet","version":"0.15.0","keywords":["mcp","opencode","agent","orchestration","swarm","fleet","p2p","peer-to-peer","model-context-protocol","audit","receipts","quorum","multi-agent"],"license":"MIT","_id":"meshfleet@0.15.0","maintainers":[{"name":"johnwhitman","email":"johndw@gmail.com"}],"homepage":"https://meshfleet.app","bugs":{"url":"https://github.com/johnmwhitman/agent-mesh/issues"},"bin":{"meshfleet":"dist/index.js","agent-mesh":"dist/bin/inspect.js","agent-mesh-dashboard":"dist/bin/dashboard.js"},"dist":{"shasum":"9965159fdbfcdc9ece446daabee1e786ebd0ec01","tarball":"https://registry.npmjs.org/meshfleet/-/meshfleet-0.15.0.tgz","fileCount":56,"integrity":"sha512-2v6GtIDRZuQDtIdrte5EmQ2/JtfW0s4qKsInVxJOLYs0IKCAnsmKedq3Jywj5l5m+LIkSL5rOsovP8qUKm/THQ==","signatures":[{"sig":"MEUCIBvec7poQVu6J/vz8K2KlJBCJoUdviDmOoxfgmolMpbCAiEA6x2DqoXFpmem/OeqY6GytGAVxo6rg8VLtv075p/a4Ug=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":541970},"main":"dist/index.js","type":"module","engines":{"node":">=20"},"exports":{".":"./dist/index.js","./bin/inspect":"./dist/bin/inspect.js","./package.json":"./package.json","./bin/dashboard":"./dist/bin/dashboard.js"},"gitHead":"14a607dfa144751c816af1c72622632930266579","scripts":{"dev":"tsx watch src/index.ts","test":"node scripts/run-tests.mjs","build":"tsc","start":"node dist/index.js","inspect":"node dist/bin/inspect.js","typecheck":"tsc --noEmit","release:pack":"npm pack","prepublishOnly":"npm run build && npm test","release:verify":"npm run build && npm test && npm pack --dry-run","release:publish":"npm run release:verify && npm publish"},"_npmUser":{"name":"johnwhitman","email":"johndw@gmail.com"},"repository":{"url":"git+https://github.com/johnmwhitman/agent-mesh.git","type":"git"},"_npmVersion":"11.17.0","description":"Auditable multi-agent coordination for OpenCode — parallel agent fleets with P2P messaging, witnessed receipts, and quorum ratification. Who saw this, who approved it, prove it.","directories":{},"_nodeVersion":"26.4.0","dependencies":{"better-sqlite3":"^12.11.1","@modelcontextprotocol/sdk":"^1.29.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/better-sqlite3":"^7.6.13"},"_npmOperationalInternal":{"tmp":"tmp/meshfleet_0.15.0_1784856874236_0.6826735752613997","host":"s3://npm-registry-packages-npm-production"}},"0.16.0":{"name":"meshfleet","version":"0.16.0","keywords":["mcp","opencode","agent","orchestration","swarm","fleet","p2p","peer-to-peer","model-context-protocol","audit","receipts","quorum","multi-agent"],"license":"MIT","_id":"meshfleet@0.16.0","maintainers":[{"name":"johnwhitman","email":"johndw@gmail.com"}],"homepage":"https://meshfleet.app","bugs":{"url":"https://github.com/johnmwhitman/agent-mesh/issues"},"bin":{"meshfleet":"dist/index.js","agent-mesh":"dist/bin/inspect.js","agent-mesh-dashboard":"dist/bin/dashboard.js"},"dist":{"shasum":"daea388e90e6fc12269380af44985865f7bdb642","tarball":"https://registry.npmjs.org/meshfleet/-/meshfleet-0.16.0.tgz","fileCount":60,"integrity":"sha512-k/OYiX8HmlZ9ThSJalOSQRJxJ/ReBYYEeM/gcpzBJ8AsfeNPVT+6ca7bk0l4Bbd2pk3D//sBXhUTcyC4U8Lc2Q==","signatures":[{"sig":"MEUCIQCz0DiTqhZmjkfQLUeP8cM5DjIEgtqKqvHuf+0yTWqe3gIgMijOQbAMBgt9JG0mkn0D0Gqpi1bb8XP0OpNqCsAVYeo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":773597},"main":"dist/index.js","type":"module","engines":{"node":">=20"},"exports":{".":"./dist/index.js","./bin/inspect":"./dist/bin/inspect.js","./package.json":"./package.json","./bin/dashboard":"./dist/bin/dashboard.js"},"gitHead":"d753da133bd3f5ae8e3bec62aa771e47722f03a6","scripts":{"dev":"tsx watch src/index.ts","test":"node scripts/run-tests.mjs","build":"tsc","start":"node dist/index.js","inspect":"node dist/bin/inspect.js","typecheck":"tsc --noEmit","release:pack":"npm pack","prepublishOnly":"npm run build && npm test","release:verify":"npm run build && npm test && npm pack --dry-run","release:publish":"npm run release:verify && npm publish"},"_npmUser":{"name":"johnwhitman","email":"johndw@gmail.com"},"repository":{"url":"git+https://github.com/johnmwhitman/agent-mesh.git","type":"git"},"_npmVersion":"11.17.0","description":"Auditable multi-agent coordination for OpenCode — parallel agent fleets with P2P messaging, witnessed receipts, and quorum ratification. Who saw this, who approved it, prove it.","directories":{},"_nodeVersion":"26.4.0","dependencies":{"better-sqlite3":"^12.11.1","@modelcontextprotocol/sdk":"^1.29.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/better-sqlite3":"^7.6.13"},"_npmOperationalInternal":{"tmp":"tmp/meshfleet_0.16.0_1784954040698_0.11984180987337156","host":"s3://npm-registry-packages-npm-production"}},"0.18.0":{"name":"meshfleet","version":"0.18.0","keywords":["mcp","opencode","agent","orchestration","swarm","fleet","p2p","peer-to-peer","model-context-protocol","audit","receipts","quorum","multi-agent"],"license":"MIT","_id":"meshfleet@0.18.0","maintainers":[{"name":"johnwhitman","email":"johndw@gmail.com"}],"homepage":"https://meshfleet.app","bugs":{"url":"https://github.com/johnmwhitman/agent-mesh/issues"},"bin":{"meshfleet":"dist/index.js","agent-mesh":"dist/bin/inspect.js","agent-mesh-dashboard":"dist/bin/dashboard.js"},"dist":{"shasum":"dfb6746c23f63e5e315366334366d8c4246092cb","tarball":"https://registry.npmjs.org/meshfleet/-/meshfleet-0.18.0.tgz","fileCount":47,"integrity":"sha512-6nPrCIRzY3AlKcSCojMTauqfb8FvvHAjiQ7H6mrsbt0WVasGDXXZOVU0knQnusI14+2IuExw30CU659h9csrCg==","signatures":[{"sig":"MEUCIHE1/n5jLQP1Ds0c6LfKStNni3wjErduoUp6lT/8XddyAiEAmO8G2sITWGQa32v4ydqnSWPKJuofPpU+TJSr5lrqAtg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":687843},"main":"dist/index.js","type":"module","engines":{"node":">=20"},"exports":{".":"./dist/index.js","./bin/inspect":"./dist/bin/inspect.js","./package.json":"./package.json","./bin/dashboard":"./dist/bin/dashboard.js"},"gitHead":"cdadbfb88df478c5345a65bf5abbbc1a41cc1331","scripts":{"dev":"tsx watch src/index.ts","test":"node scripts/run-tests.mjs","build":"npm run clean && tsc","clean":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"","start":"node dist/index.js","inspect":"node dist/bin/inspect.js","typecheck":"tsc --noEmit","release:pack":"npm pack","prepublishOnly":"npm run build && npm test","release:verify":"npm run build && npm test && npm pack --dry-run","release:publish":"npm run release:verify && npm publish"},"_npmUser":{"name":"johnwhitman","email":"johndw@gmail.com"},"repository":{"url":"git+https://github.com/johnmwhitman/agent-mesh.git","type":"git"},"_npmVersion":"11.17.0","description":"Auditable multi-agent coordination for OpenCode — parallel agent fleets with P2P messaging, witnessed receipts, and quorum ratification. Who saw this, who approved it, prove it.","directories":{},"_nodeVersion":"26.4.0","dependencies":{"better-sqlite3":"^12.11.1","@modelcontextprotocol/sdk":"^1.29.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/better-sqlite3":"^7.6.13"},"_npmOperationalInternal":{"tmp":"tmp/meshfleet_0.18.0_1785202727603_0.7346571111698545","host":"s3://npm-registry-packages-npm-production"}},"0.20.0":{"name":"meshfleet","version":"0.20.0","description":"Auditable multi-agent coordination for OpenCode — parallel agent fleets with P2P messaging, witnessed receipts, and quorum ratification. Who saw this, who approved it, prove it.","main":"dist/index.js","type":"module","exports":{".":"./dist/index.js","./package.json":"./package.json","./recommend-route":"./dist/recommend-route.js","./routeplane-catalog":"./dist/routeplane-catalog.js","./fleetbudget-observations":"./dist/fleetbudget-observations.js","./fleetbudget-sanitizer":"./dist/fleetbudget-sanitizer.js","./wrapper-usage-observations":"./dist/wrapper-usage-observations.js","./speculative-backlog-planner":"./dist/speculative-backlog-planner.js","./bin/inspect":"./dist/bin/inspect.js","./bin/dashboard":"./dist/bin/dashboard.js"},"bin":{"meshfleet":"dist/index.js","meshfleet-routeplane-catalog":"dist/bin/routeplane-catalog.js","meshfleet-fleetbudget-sanitize":"dist/bin/fleetbudget-sanitize.js","agent-mesh":"dist/bin/inspect.js","agent-mesh-dashboard":"dist/bin/dashboard.js"},"scripts":{"clean":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"","build":"npm run clean && tsc","dev":"tsx watch src/index.ts","start":"node dist/index.js","inspect":"node dist/bin/inspect.js","test":"node scripts/run-tests.mjs","typecheck":"tsc --noEmit","prepublishOnly":"npm run build && npm test","release:pack":"npm pack","release:verify":"npm run build && npm test && npm pack --dry-run","release:publish":"npm run release:verify && npm publish"},"keywords":["mcp","opencode","agent","orchestration","swarm","fleet","p2p","peer-to-peer","model-context-protocol","audit","receipts","quorum","multi-agent"],"license":"MIT","homepage":"https://meshfleet.app","repository":{"type":"git","url":"git+https://github.com/johnmwhitman/agent-mesh.git"},"bugs":{"url":"https://github.com/johnmwhitman/agent-mesh/issues"},"dependencies":{"@modelcontextprotocol/sdk":"^1.29.0","better-sqlite3":"^12.11.1"},"devDependencies":{"@types/better-sqlite3":"^7.6.13","@types/node":"^20.0.0","tsx":"^4.0.0","typescript":"^5.0.0"},"engines":{"node":">=20"},"gitHead":"9d9e7cdaa4ad424e4f2e27424c5ac6fb64b40447","_id":"meshfleet@0.20.0","_nodeVersion":"26.4.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-m8yWSWTIniZJ0vTJkcjWeC0xELiPHjysH1/1aJ0O/kfo9z7rWYZO1BflUSOHh2GorrjED5UXzjZpN68T8D7D6g==","shasum":"6ccbb164d020e810e7f42bffba0c2a522652389c","tarball":"https://registry.npmjs.org/meshfleet/-/meshfleet-0.20.0.tgz","fileCount":64,"unpackedSize":955516,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDbJKnjOBKHPIPufvzChNzCsZCbjxT0/8ERBFfzBh4c9AIgFgtb82YXL7XRtABMKz/3oLToSpCCOe2bXM6LLwefEgs="}]},"_npmUser":{"name":"johnwhitman","email":"johndw@gmail.com"},"directories":{},"maintainers":[{"name":"johnwhitman","email":"johndw@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/meshfleet_0.20.0_1785536274516_0.3206853639715188"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-03T20:04:41.749Z","modified":"2026-07-31T22:17:54.903Z","0.11.1":"2026-07-03T20:04:41.961Z","0.13.0":"2026-07-16T21:55:49.557Z","0.15.0":"2026-07-24T01:34:34.412Z","0.16.0":"2026-07-25T04:34:00.944Z","0.18.0":"2026-07-28T01:38:47.797Z","0.20.0":"2026-07-31T22:17:54.746Z"},"bugs":{"url":"https://github.com/johnmwhitman/agent-mesh/issues"},"license":"MIT","homepage":"https://meshfleet.app","keywords":["mcp","opencode","agent","orchestration","swarm","fleet","p2p","peer-to-peer","model-context-protocol","audit","receipts","quorum","multi-agent"],"repository":{"type":"git","url":"git+https://github.com/johnmwhitman/agent-mesh.git"},"description":"Auditable multi-agent coordination for OpenCode — parallel agent fleets with P2P messaging, witnessed receipts, and quorum ratification. Who saw this, who approved it, prove it.","maintainers":[{"name":"johnwhitman","email":"johndw@gmail.com"}],"readme":"# Agent Mesh — meshfleet.app\n\n> **Auditable multi-agent coordination for OpenCode.** Spawn parallel agents as independent OS processes. Route work to specialists. Let agents collaborate peer-to-peer — with witnessed receipts and quorum ratification, so you can answer: *who saw this, who approved it, prove it.* The core is MIT and free.\n\n**Website**: [meshfleet.app](https://meshfleet.app) · **Source version**: 0.20.0 (npm publish pending) · [CI](https://github.com/johnmwhitman/agent-mesh/actions)\n\n*Maintained: source is 0.20.0 and untagged; the newest tag is v0.19.0 (2026-07-28); npm latest remains v0.18.0 · issues answered within 48h · no download-count theater.*\n\n> **Project status — deliberately pre-1.0, actively maintained.** Releases are intentionally\n> infrequent (we cut versions when something is worth shipping, not on a calendar); the repo\n> carries a monthly maintenance heartbeat and issues get a first response within 48 hours.\n>\n> **The boundary, as a covenant:** the mechanisms are free and stay free — coordination,\n> receipts, councils, provider-neutral advisory interfaces, and the ability to *run*\n> verification are MIT, forever. Cryptographic **signing** and auditor-grade\n> attestation are a separate paid layer\n> ([meshfleet-pro](https://meshfleet.app/pro)). Account-specific provider operations\n> and managed policy are also outside this core. No existing core mechanism moves\n> behind a paywall. The core neither owns nor independently controls provider-account\n> credentials, balances, reset policy, spend authority, or external publication.\n>\n> **Host portability:** this is an agent audit trail, **OpenCode first** — not an\n> OpenCode-only idea. The core is a standard MCP server; broader host support tracks\n> real demand.\n\n---\n\n## Why Meshfleet?\n\nOpenCode is a single-agent runtime. You talk to it, it does things. The moment you need **multiple specialists** running in parallel — explore, then review, then implement — you hit the 30-minute background-task timeout.\n\nMeshfleet adds the missing layer: a fleet of agents that run in parallel, message each other, hand off work, and self-organize. As independent OS processes, not background tasks. No artificial ceiling.\n\n```typescript\nconst { fleet_id } = await callTool(\"spawn_fleet\", {\n  agents: [\n    { role: \"Explorer\",   prompt: \"Map the auth layer\",    agent: \"codebase-onboarding-engineer\" },\n    { role: \"Analyst\",    prompt: \"Review the architecture\", agent: \"oracle\" },\n    { role: \"Engineer\",   prompt: \"Implement JWT refresh\",  agent: \"backend-architect\", model: \"opencode-go/minimax-m3\" },\n  ],\n});\n```\n\nThree specialists. Three independent processes. They hand off, ask questions, alert on problems. You read the result.\n\nEach agent accepts an optional `model` (`provider/model`) selector. When set, Meshfleet persists it as the immutable request (`Agent.requested_model`) and launches `opencode run --model <value>` for that agent; the observed runtime banner lands in `Agent.runtime_model`, and a `complete` agent whose banner is missing or contradicts the request fails closed. Omitting `model` keeps the old argv exactly. The selector is data, not shell text, and the banner is observed evidence — not authentication, billing, provider availability, or attestation. Default execution is still OpenCode; there is no public runtime-adapter selector, credential flow, account-control plane, automatic model choice, or default token-budget policy. Local smoke tests exercised the installed OpenCode IDs `opencode-go/minimax-m3` and `kilo/kilo-auto/free`; that evidence is environment-local. The separate pure `recommend_route` advisory may opt in to a caller-evidenced near-reset tie-break, but it never polls an account, grants provider authority, or executes a paid service.\n\nAnd when an agent's action matters, Meshfleet can prove what happened. Every message writes **per-recipient receipts** (delivered, seen, acked). Decisions can go through **councils** — quorum-based ratification with required sign-offs, recorded on the same ledger. The design is a port of a bus that ran a 10+ agent fleet in production for 40 days and 18,404 messages, including quorum-ratified decisions.\n\n---\n\n## Install in 30 seconds\n\nFrom npm (the package is `meshfleet`; the `agent-mesh` npm name is squatted by a placeholder):\n\n```bash\nnpm install -g meshfleet\n```\n\nOr from source:\n\n```bash\ngit clone https://github.com/johnmwhitman/agent-mesh.git \\\n  ~/.config/opencode/mcp-servers/agent-mesh\ncd ~/.config/opencode/mcp-servers/agent-mesh\nnpm install && npm run build\n```\n\nAdd to `~/.config/opencode/opencode.jsonc` (npm install):\n\n```jsonc\n{\n  \"mcp\": {\n    \"meshfleet\": {\n      \"type\": \"local\",\n      \"enabled\": true,\n      \"command\": [\"npx\", \"-y\", \"meshfleet\"]\n    }\n  }\n}\n```\n\nFor noncanonical development-only source-checkout usage (not the recommended release config):\n\n```jsonc\n{\n  \"mcp\": {\n    \"meshfleet\": {\n      \"type\": \"local\",\n      \"enabled\": true,\n      \"command\": [\"node\", \"~/.config/opencode/mcp-servers/agent-mesh/dist/index.js\"]\n    }\n  }\n}\n```\n\nRestart OpenCode. Spawn a fleet. [Wiring it into your client →](#wiring-it-into-your-client)\n\n---\n\n## Wiring it into your client\n\nMeshfleet is a standard stdio MCP server. The invocation is always the same — `npx -y meshfleet`\n(the `meshfleet` bin in `package.json` points at the server, `dist/index.js`) — only the config\nfile around it changes per client.\n\n**Honesty labels.** \"Tested\" means verifiable from this repo itself. Client-specific shapes below\nfollow each client's documented config format — we haven't wired CI to every editor, so those are\nmarked \"per \\<client\\> docs — verification welcome.\"\n\n### Any MCP client (generic stdio) — tested: this exact shape ships in this repo as [`mcp.json`](./mcp.json)\n\n```json\n{\n  \"mcpServers\": {\n    \"meshfleet\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"meshfleet\"]\n    }\n  }\n}\n```\n\n### OpenCode — primary host; canonical `meshfleet` server identity\n\n`~/.config/opencode/opencode.jsonc`:\n\n```jsonc\n{\n  \"mcp\": {\n    \"meshfleet\": {\n      \"type\": \"local\",\n      \"enabled\": true,\n      \"command\": [\"npx\", \"-y\", \"meshfleet\"]\n    }\n  }\n}\n```\n\n### Claude Code — per Claude Code docs — verification welcome\n\nCLI form:\n\n```bash\nclaude mcp add meshfleet -- npx -y meshfleet\n```\n\nOr project-scoped `.mcp.json` at the repo root:\n\n```json\n{\n  \"mcpServers\": {\n    \"meshfleet\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"meshfleet\"]\n    }\n  }\n}\n```\n\n### Codex — same host-neutral stdio server\n\nConfigure Codex's MCP server entry with the same command and arguments:\n\n```json\n{\n  \"mcpServers\": {\n    \"meshfleet\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"meshfleet\"]\n    }\n  }\n}\n```\n\nThese Claude Code, Codex, OpenCode, and generic MCP configurations all call the\nsame inbound stdio server. This proves client interoperability at the MCP\nboundary only: workers spawned by Meshfleet still execute through OpenCode's\n`opencode run`. The `subscribe_inbox` SSE endpoint is optional acceleration; it\nis not required for compatibility, and clients can use `get_inbox` polling.\n\nIf any block above doesn't work in your client, [open an issue](https://github.com/johnmwhitman/agent-mesh/issues) — config rot is a bug.\n\n---\n\n## The CLI\n\nOnce Meshfleet is installed, the `agent-mesh` CLI gives you terminal visibility into your running fleets, and `agent-mesh-dashboard` gives you a live TUI.\n\n```bash\n$ npx agent-mesh inspect\n3 fleets:\n\nbc34d339-935c-4…  complete  3 agents, 3 done (34.8m)\n37ae1cf2-5ce8-4…  complete  1 agents, 1 done (28.2m)\nd648beb0-cfb2-4…  failed    2 agents, 2 done (27.3s)\n\n$ npx agent-mesh inspect --metrics\nTotal fleets:       7\n  completed:        3\n  failed:           4\nTotal agents:       16\nSuccess rate:       42.9%\nAvg duration:       1.34s\n\n$ npx agent-mesh inspect --events 5\nTIMESTAMP            EVENT              DETAIL\n──────────────────────────────────────────────────────────────────────\n2026-07-02 12:40:12  agent_spawned       fleet=f-1 agent=a-1\n2026-07-02 12:40:12  agent_spawned       fleet=f-1 agent=a-2\n2026-07-02 12:40:12  fleet_created       fleet=f-1\n\n$ npx agent-mesh inspect timeline f-1 --from 2026-07-02T12:40:00Z --to 2026-07-02T12:45:00Z\nLocal ledger timestamps in [1782996000000,1782996300000) · not authenticity, completeness, tamper evidence, authenticated provenance, or external time\nTIMESTAMP            KIND                SUMMARY\n──────────────────────────────────────────────────────────────────────\n2026-07-02 12:40:13  message             handoff agent-a→agent-b\n2026-07-02 12:40:18  receipt             ack by agent-b on 3f9c1a2b\n\n$ npx agent-mesh inspect --follow            # or -f; add --fleet <id> to scope to one fleet\nledger: ~/.config/opencode/agent-mesh.db  · poll 400ms  · ctrl-c to stop\nwatching… no messages yet  (spawn a fleet or send_message from MCP)\n2026-07-22 09:14:03  handoff  agent-a → agent-b  msg=3f9c1a2b  {\"task\":\"review PR #42\"}\n```\n\nTimeline bounds are optional digits-only epoch milliseconds, ISO dates\n(`YYYY-MM-DD`), or timezone-bearing ISO datetimes\n(`YYYY-MM-DDTHH:mm:ss[.fraction](Z|±HH:mm)`). Fractional precision is\nnormalized to epoch milliseconds. Bounds select the half-open interval\n`[from,to)` over timestamps stored in the local ledger. Add `--json` for the\nadditive `timeline_window` inspect envelope. An unbounded `inspect timeline\n[fleet]` keeps the original text and JSON shapes. This is read-only\nlocal-record selection, not proof of authenticity, completeness, tamper\nevidence, authenticated provenance, or external time.\n\n---\n\n## 36 MCP tools\n\n**Fleets**\n\n| Tool | What it does |\n|---|---|\n| `spawn_fleet` | Spawn N parallel agents as independent OS processes; each agent may set an optional `model` (`provider/model`) selector that becomes `opencode run --model <value>` and is preserved across retries and Discussion wakeups |\n| `spawn_from_template` | Spawn a fleet from a saved template |\n| `save_fleet_template` / `list_fleet_templates` | Reusable, versioned fleet configs |\n| `list_fleets` / `fleet_status` | All fleets, or one fleet's full state |\n| `collect_results` | Gather every agent's final output in one call |\n| `set_fleet_timeout` | Per-fleet timeout override (in ms) |\n| `attach_agent` | Dynamically attach a premade agent to a running fleet; the agent may set the same optional `model` (`provider/model`) selector |\n\n**Messaging & receipts**\n\n| Tool | What it does |\n|---|---|\n| `send_message` | P2P message (5 types) — or `to_agent_id: \"*\"` to broadcast to the whole fleet |\n| `send_messages` | Batched sends, one atomic transaction per batch (up to 1000 messages; larger batches are rejected) |\n| `get_inbox` / `ack_message` | Poll and acknowledge; every ack writes a per-recipient receipt |\n| `subscribe_inbox` | Push delivery over SSE instead of polling (optional auth token) |\n| `receipt` / `get_receipts` | Write and query the witnessed-delivery ledger: who saw what, when |\n| `verify_ledger` | Audit the whole ledger's internal consistency — errors mean it asserts something its own records don't support |\n| `verify_ledger_v2` | Versioned unsigned-snapshot consistency envelope around the unchanged verifier report from a dedicated read-only file snapshot; the handler performs no ledger writes |\n| `verify_ledger_v3` | Opt-in detached verifier envelope with severity-derived local consistency labels only; not provenance or confidence; the handler uses a dedicated read-only file snapshot and performs no ledger writes |\n\n**Councils (quorum ratification)**\n\n| Tool | What it does |\n|---|---|\n| `open_ratification` | Put a decision to the fleet: quorum, deadline, required sign-offs, optional per-voter weights |\n| `cast_vote` | An agent votes, on the record — re-casting changes the effective vote without rewriting history |\n| `tally_ratification` / `sweep_ratifications` | Resolve outcomes; expire past-deadline votes |\n\n**Routing & ops**\n\n| Tool | What it does |\n|---|---|\n| `register_capability` | Self-describe role + skills for routing |\n| `route_work` | Match a task to the best agent by keyword + role overlap |\n| `recommend_route` | Advisory ranking for caller-supplied agent/runtime/model candidates, with hard privacy/capability filters and an opt-in near-reset tie-break |\n| `plan_speculative_backlog` | Pure projection of caller-approved speculative work, preserving route gates and explicitly leaving capacity unmodeled |\n| `compile_route_candidates` | Pure offline projection of sanitized manifest/observation snapshots; does not rank, persist, execute, authorize, wake, or contact providers |\n| `record_routing_outcome` | Feed results back to improve routing |\n| `list_agents` | Discover 100+ premade agent personalities |\n| `get_health` / `ping` | Fleet health and liveness |\n\n**Discussions (bounded two-agent negotiation)**\n\n| Tool | What it does |\n|---|---|\n| `ask_peer` | Open a bounded Discussion: send the root question, optionally reserve one peer attempt, wait for a settled answer |\n| `wake_agent` | The sole general-purpose Discussion run trigger — atomically reserve and launch one bounded attempt |\n| `reply_discussion` | Submit the one reply an active wake attempt is authorized to produce; never launches an agent |\n| `get_discussion` | Read-only: derive transcript, attempts, budget, and fail-closed status from durable messages and receipts |\n\nSee [docs/discussions.md](docs/discussions.md) for the full quickstart, tool reference, and terminal-state precedence.\n\nThat's 36. We counted twice this time.\n\nRoutePlane catalog discovery is a separate package library and CLI, not an MCP\ntool: it fetches RoutePlane's fixed loopback model catalog and projects\ncaller-owned policy into advisory candidates. Its package-library API,\n`recommendRoutePlaneCatalog()`, composes an already-fetched snapshot; the opt-in\n`fetchAndRecommendRoutePlaneCatalog()` fetches that fixed loopback catalog once\nbefore the same composition. Their `evaluated` and `no_compiled_candidates`\nstatuses preserve catalog diagnostics separately from task exclusions and remain\nadvisory with all effects false. Neither API deploys, publishes, selects\nproviders, executes models, contacts providers beyond that explicit loopback\ncatalog fetch, polls budget telemetry, or infers authority from provider labels.\n[RoutePlane catalog boundary → docs/ROUTEPLANE-CATALOG.md](docs/ROUTEPLANE-CATALOG.md)\n\nFleetbudget ingress and observation projection are separate package surfaces,\nnot MCP tools. The new `meshfleet/fleetbudget-sanitizer` library and\n`meshfleet-fleetbudget-sanitize` stdin CLI strictly validate the current\nunversioned `fleetbudget --json` byte shape against a caller-owned collection\ninterval. They retain `lane` only as an opaque evidence identifier plus\n`measured`, `used`, `total`, and `unit`; `routes`, `state`, `utilization`,\n`note`, and `detail` are validated and erased. The CLI reads stdin and never\ninvokes Fleetbudget, another provider process, or a route command.\n\nSanitized raw lanes deliberately contain no typed quota window, so even a\ncomplete or exhausted raw ceiling remains diagnostic-only: it produces\n`WINDOW_MISSING`, no observation, and no availability, exhaustion, allocation,\nranking, or route authority. `compileFleetBudgetObservations()` still accepts\ncaller-supplied versioned snapshots with explicit candidate bindings when a\nreal typed quota window exists. Several candidates may share a lane ID as\ncopied, unsplit evidence; the compiler returns observations or diagnostics,\ncanonical provenance hashes, and all-false effects. Neither surface sums,\nallocates, reserves, synchronizes, executes, or authorizes. Validated window\nbounds flow through the route-candidate compiler without their lane/window ID.\nAn explicit `prefer_near_reset` recommendation can use those bounds only after\nthe existing final score as a tie-break; there is no default account-optimization\npolicy.\nStructured collector versioning,\nproducer-owned observation timing, and typed quota windows are required before\nraw measured budget can become actionable. [Safe host collection and exact boundary → docs/FLEETBUDGET-OBSERVATIONS.md](docs/FLEETBUDGET-OBSERVATIONS.md)\n\n`plan_speculative_backlog` is a separate, pure queue projection over closed,\ncaller-supplied inputs. A task is proposed only when the caller includes opaque\n`state: \"approved\"` evidence; this is not MeshFleet authorization. It composes the\nexisting `recommend_route` hard gates and may opt into its already-landed\nnear-reset tie-break per task, but never treats reset urgency as a global queue\npriority. Candidate quality tags are declared eligibility only, not a quality\nmeasurement. Asset and video candidates require text-only or caller-attested\nrights material, private review, and a human release requirement. The result\ncontains a canonical supplied-input hash only as replay evidence, has all\neffects false, and reports shared-candidate capacity as explicitly unmodeled:\nit does not execute, schedule, poll, read credentials, infer providers, bind\npools, reserve capacity, spend budgets, send, publish, or establish freshness,\nprovenance, approval, provider state, a receipt, or an execution commitment.\nThe `proposed` and `blocked` arrays are priority-descending/task-ID-ascending,\nand each entry carries its zero-based `queue_index` in that global order.\n[Advisory routing → docs/ADVISORY-ROUTING.md](docs/ADVISORY-ROUTING.md)\n\nSanitized fleet wrapper usage is available through the separate pure\n`meshfleet/wrapper-usage-observations` package surface. It accepts only the\nclosed, already-decoded `fleet.wrapper-usage-summary/v1` object and returns a\ndistinct `accepted`/`groups` status envelope with all effects and authorities\nfalse. It preserves `routeplane-unattributed` exactly and copies source\nrejections and aggregate counts without prompts, raw event IDs, provider or\nquota inference, derived rates, persistence, execution, scheduling, routing,\nlogging activation, or MeshFleet health changes. It is not an MCP tool and is\nnot structurally interchangeable with route-candidate observations.\n[Wrapper usage status boundary → docs/WRAPPER-USAGE-OBSERVATIONS.md](docs/WRAPPER-USAGE-OBSERVATIONS.md)\n\n[Advisory routing → docs/ADVISORY-ROUTING.md](docs/ADVISORY-ROUTING.md) · [Fleetbudget observations → docs/FLEETBUDGET-OBSERVATIONS.md](docs/FLEETBUDGET-OBSERVATIONS.md) · [Architecture orientation → AGENT-MESH-SPEC.md](AGENT-MESH-SPEC.md) · [P2P/receipts → SPEC-P2P.md](SPEC-P2P.md) · [Councils → SPEC-COUNCILS.md](SPEC-COUNCILS.md)\n\n---\n\n## 5 message types\n\n| Type | Use it for |\n|---|---|\n| `handoff` | Passing context to the next agent in a pipeline |\n| `question` | Asking a clarifying question (with optional `correlation_id`) |\n| `result` | Reporting a final outcome |\n| `alert` | Broadcasting a problem to all fleet peers |\n| `request_help` | Escalating when stuck (target a specific peer with relevant skills) |\n\n64 KB payload cap. The default encoding is JSON, but payloads are strings — send whatever you want. Broadcasts (`to_agent_id: \"*\"`) fan out to every fleet peer, and each recipient acks independently — the receipts ledger shows exactly who saw it.\n\n---\n\n## 4 collaboration patterns\n\n- **Pipeline handoff**: A → B → C. Each specialist hands context to the next. No orchestrator in the loop.\n- **Debate consensus**: A and B review the same artifact, debate via questions, converge before reporting.\n- **Failure recovery**: C hits a blocker, broadcasts `alert`, peers with relevant skills respond with fixes.\n- **Ratified decision**: a council votes on a risky action — quorum, deadline, required sign-off — and the outcome (including who stayed silent) is on the ledger.\n\n[More on the receipts wedge →](https://meshfleet.app)\n\n---\n\n## What the verifier catches — and what it can't\n\n\"Prove it\" is a claim about detection, so it ships with the evidence:\n[`test/fixtures/corpus/`](test/fixtures/corpus/README.md) is a corpus of 77 deliberately\nfalsified ledgers, each one a clean baseline plus **one declared change**. Results are\nreported in three separate buckets, never blended into a single coverage number:\n\n| Bucket | N | What it means |\n|---|---|---|\n| `caught` | 54 | An overclaim — the ledger asserts something its own records don't support. Raises an error and fails the ledger. |\n| `anomaly` | 13 | Surprising, but claims no more than the records support. Warning only, and deliberately *not* counted as caught. |\n| `undetectable` | 10 | The unsigned local core structurally cannot see it. Produces zero findings. |\n\n**That third bucket is published on purpose.** The core polices internal coherence; it\ncannot police provenance, content binding, completeness, or absolute time. So a payload\nswapped *after* a council approved it, a ballot minted for an agent that legitimately\nholds a seat, a ghost agent with a coherent history, and a wholesale clock shift all\nverify clean — and each is committed as a fixture asserting exactly that. This is the\nfree-core boundary as something you can run, rather than something we assert. It is also\nprecisely the line [Meshfleet Pro](https://meshfleet.app/pro) exists on the other side of:\nsignatures are what make those vectors detectable, and signatures are not in this core.\n\nTogether the `caught` and `anomaly` vectors name every check the verifier can emit outside\nthe `discussion.*` family, and that inventory is re-derived from source on every run — so\na new check without a fixture fails the build.\n\n### Implemented versioned evidence scope\n\n`verify_ledger_v2` is an implemented opt-in MCP verifier surface. The existing\n`verify_ledger`, `VerifyReport`, `VerifyFinding`, `agent-mesh inspect --verify`,\nand `meshfleet.inspect/v1` remain unchanged.\n\nAt tool dispatch, its handler reads the configured ledger through a dedicated\nread-only file snapshot and performs no ledger writes. In normal parent mode,\nserver startup recovery or migration may initialize or change the configured\nledger before any tool dispatch; those pre-dispatch effects are unchanged by\nv2 and are outside this handler boundary.\n\nThe MCP tool returns this envelope. The matching opt-in `agent-mesh inspect\n--verify-v2 [file]` CLI mode is implemented: it audits the supplied file, or\nthe configured ledger, through the same dedicated read-only file snapshot. With\n`--json` it emits this same object; otherwise it emits one evidence-scope header\nfollowed by the unchanged legacy verifier text:\n\n```json\n{\n  \"schema\": \"meshfleet.verify/v2\",\n  \"evidence_scope\": {\n    \"profile\": \"unsigned_snapshot_consistency/v1\",\n    \"ok_means\": \"no_detected_internal_consistency_contradiction\",\n    \"assurance_ceiling\": \"internal_consistency_of_the_unsigned_snapshot_read\",\n    \"not_established\": [\n      \"authorship_and_authenticated_provenance\",\n      \"pre_read_snapshot_integrity_and_tamper_evidence\",\n      \"content_binding\",\n      \"completeness_and_deletion\",\n      \"external_delivery_and_execution\",\n      \"external_time\"\n    ]\n  },\n  \"report\": \"the unchanged VerifyReport\"\n}\n```\n\n`report.ok` retains its exact current meaning: no detected internal\nconsistency contradiction in the unsigned snapshot read (`report.errors ===\n0`). It does not establish authorship or authenticated provenance, pre-read\nsnapshot integrity or tamper evidence, content binding, completeness or absence\nof deletion, external delivery or execution, or external time. The scope is\ngenerated verifier output, never caller or ledger input; it is a ceiling on\nwhat the report establishes, not a confidence score, integrity verdict, or\npromotion.\n\n### Implemented opt-in verifier v3 local consistency bands\n\n`verify_ledger_v3` and `agent-mesh inspect --verify-v3 [file]` are separate,\nopt-in verifier surfaces. They retain the same six-item\n`unsigned_snapshot_consistency/v1` `evidence_scope`, but return a new exact\nfour-key envelope with a detached copy of the unchanged `VerifyReport`:\n\n```json\n{\n  \"schema\": \"meshfleet.verify/v3\",\n  \"evidence_scope\": {\n    \"profile\": \"unsigned_snapshot_consistency/v1\",\n    \"ok_means\": \"no_detected_internal_consistency_contradiction\",\n    \"assurance_ceiling\": \"internal_consistency_of_the_unsigned_snapshot_read\",\n    \"not_established\": [\n      \"authorship_and_authenticated_provenance\",\n      \"pre_read_snapshot_integrity_and_tamper_evidence\",\n      \"content_binding\",\n      \"completeness_and_deletion\",\n      \"external_delivery_and_execution\",\n      \"external_time\"\n    ]\n  },\n  \"report\": {\n    \"ok\": true,\n    \"scope\": {\n      \"covers\": \"internal consistency — every receipt, flag, inbox entry, and ratification tally is supported by the ledger's own records\",\n      \"excludes\": \"authenticity — there is no hash chain or signature here, so an edit that rewrites the ledger consistently is indistinguishable from honest history\"\n    },\n    \"errors\": 0,\n    \"warnings\": 0,\n    \"counts\": { \"fleets\": 0, \"agents\": 0, \"messages\": 0, \"receipts\": 0, \"ratifications\": 0 },\n    \"findings\": []\n  },\n  \"finding_local_bands\": []\n}\n```\n\nThere is exactly one local band for each report finding, in the report's\nexisting order: `error` becomes `local_consistency_error` and `warning` becomes\n`local_consistency_warning`. The mapping does not sort, deduplicate, inspect\ncheck names, or score findings. An unknown or missing severity fails closed.\nZero findings produce zero bands; they do not produce an `undetectable`\nfinding.\n\nThe report copy and band array are frozen only for caller alias safety. They do\nnot supply tamper evidence. The labels are severity-derived local consistency\nlabels only, not provenance or confidence; no labels means neither authenticity\nnor completeness. As with v2, the handler reads through the dedicated read-only\nfile snapshot and performs no ledger writes. `verify_ledger`, `verify_ledger_v2`,\n`VerifyReport`, existing inspect JSON, their text, their exits, ledger behavior,\nand sidecars remain unchanged.\n\n---\n\n## How it compares\n\n| Tool | Best for | Tradeoffs |\n|---|---|---|\n| **OpenCode `task()`** | Single-task work | 30-min timeout, no P2P |\n| **LangGraph** | Python graph apps | Python-only, hosted-first |\n| **CrewAI** | Role-based Python agents | Python-only, hosted |\n| **AutoGen** | Research projects | Heavy, Python-only |\n| **Hand-rolled cron** | Specific one-off workflows | No shared abstractions |\n| **Meshfleet** | OpenCode + multi-agent, local-first, auditable | TypeScript-only (for now) |\n\nNone of them answer \"who saw this, who approved it, prove it.\" That's the lane.\n\n[FAQ →](https://meshfleet.app/faq)\n\n---\n\n## Architecture\n\n```\nsrc/\n├── db.ts                # The withLedger transaction seam over SQLite (the write boundary)\n├── core.ts              # Data layer: ledger, messages, receipts, capabilities, events\n├── migrate.ts           # One-shot JSON→SQLite migration (runs once at startup)\n├── ratify.ts            # Councils: quorum ratification over the receipts substrate\n├── templates.ts         # Versioned fleet templates\n├── routing-feedback.ts  # Outcome-informed work routing\n├── health.ts            # Fleet health scoring\n├── realtime.ts          # SSE push delivery (subscribe_inbox)\n├── inspector.ts         # Pure formatters for CLI output\n├── index.ts             # MCP server: transport + tool handlers\n└── bin/\n    ├── inspect.ts       # CLI: npx agent-mesh inspect\n    └── dashboard.ts     # Live TUI: npx agent-mesh-dashboard\n```\n\nEvery write goes through **one** function — `withLedger(mutator)` in `db.ts` — which runs the mutation inside a single SQLite `BEGIN IMMEDIATE` transaction. Agents are real OS processes that each boot their own agent-mesh instance on the same ledger, so writes are genuinely concurrent; SQLite (WAL + `busy_timeout`) provides cross-process write exclusion, so this codebase owns no locking protocol and lost-update is impossible by construction. (An earlier JSON read-modify-write store silently lost 57 of 120 receipts under a two-process test; the SQLite seam passes the same test 200/200.) Readers use a lock-free `readLedger()`. Pure formatters live in `inspector.ts` — easy to test, no I/O.\n\nThe ledger lives at `~/.config/opencode/agent-mesh.db` (SQLite); the event log at `~/.config/opencode/agent-mesh.events.log` (NDJSON). Dump the ledger as human-readable JSON any time with `npx agent-mesh inspect --export`. On first run after upgrading from a JSON ledger, the server migrates it once (validated, with a `.migrated.<ts>` backup kept).\n\n[Architecture orientation →](AGENT-MESH-SPEC.md) · [P2P messaging spec →](SPEC-P2P.md)\n\n---\n\n## Requirements\n\n- Node.js >= 20\n- OpenCode CLI in `$PATH` (any model provider OpenCode supports)\n- That's it\n\n---\n\n## License\n\nThe core is MIT — use it, fork it, ship it in your product. No attribution beyond the license file. (A commercial assurance layer, [Meshfleet Pro](https://meshfleet.app/pro), lives in a separate repo and doesn't change what's here.)\n\n---\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md). Bugs → [issues](https://github.com/johnmwhitman/agent-mesh/issues). Security → [SECURITY.md](./SECURITY.md). Roadmap → [ROADMAP.md](./ROADMAP.md).\n","readmeFilename":"README.md"}