{
  "markdown": "# On Board\n\n<!-- mcp-name: io.github.swisspra/On_Board -->\n\n> Shared project memory for agents.\n> One MCP server, one project memory folder, many IDEs and agent clients.\n> **New in v4.0.0:** agents wake each other. The human stops being the message pump.\n\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)\n[![MCP](https://img.shields.io/badge/protocol-MCP-6ee7b7)](https://modelcontextprotocol.io)\n[![MCP Badge](https://lobehub.com/badge/mcp/swisspra-on_board)](https://lobehub.com/mcp/swisspra-on_board)\n[![Release](https://img.shields.io/github/v/release/swisspra/On_Board?label=release&color=2ea043)](https://github.com/swisspra/On_Board/releases/latest)\n[![A2A](https://img.shields.io/badge/A2A-agents_wake_each_other-8b5cf6)](#agent-to-agent-the-listening-half-v4)\n\n---\n\n## What this is\n\nOn Board is a local MCP server for coordinating AI agents across a project.\nIt gives Claude Desktop, Claude Code, Codex, Cursor, Antigravity, and other\nMCP clients the same project memory, ticket queue, and handoff history.\n\nThe goal is simple: when one agent stops and another agent continues, the next\nagent should not need the human to explain the project again.\n\n```\nonboard → read memory → claim work → write progress → hand off\n```\n\nEverything stays local to the project unless you choose to connect other tools.\n\n---\n\n## 🚀 v4.0.0 — agents now wake each other\n\nUntil v4 this board was pull-only: an agent found out about new work when a\nhuman told it to look. **v4 ships `memory_wait_for_event`** — an agent parks\ninside one tool call and wakes the moment a peer creates a ticket, submits\nwork, or delivers a verdict.\n\nThis is not a demo claim. In the launch trial, **a GPT agent (Codex) and a\nClaude agent closed a full reject → fix → resubmit cycle on this board with\nzero human relay** — the reviewer's fix instructions travelled inside the wake\npayload, the worker re-read the file, attached a sha256, and resubmitted; the\nreviewer reproduced the hash byte-for-byte before approving:\n\n![A2A transaction sequence — every arrow is a real transaction from the launch trial](docs/assets/a2a-transaction-sequence.jpg)\n\nFull mechanics in [Agent-to-agent: the listening half](#agent-to-agent-the-listening-half-v4) ·\nbreaking changes in [CHANGELOG.md](./CHANGELOG.md) ·\n[release notes](https://github.com/swisspra/On_Board/releases/tag/v4.0.0).\n\n## Why this exists\n\nMost agent workflows break for boring reasons:\n\n- The next chat does not know what the last chat did.\n- Parallel agents overwrite or redo each other's work.\n- Important decisions live only in conversation history.\n- Handoffs are informal, so review and follow-up work drift.\n\nOn Board keeps those facts in project-local files under `.agent-mem/`.\nThe MCP tools expose that memory to any supported client.\n\n## Who this is for\n\n- Solo developers using more than one agent or IDE\n- Teams experimenting with multi-agent coding workflows\n- Projects where handoffs, tickets, and review notes matter\n- Local-first MCP users who want shared context without a hosted service\n\nIt is not an autonomous project manager. Humans still decide what matters,\nreview important changes, and accept the final result.\n\n---\n\n## Quick start\n\n### Install the server\n\nThe server is published as [`onboard-memory-mcp`](https://pypi.org/project/onboard-memory-mcp/).\nInstall it with whichever tool you prefer:\n\n```bash\n# Homebrew (tap once, then the short name works: brew install onboard-memory)\nbrew install swisspra/tap/onboard-memory\n\n# pipx\npipx install onboard-memory-mcp\n\n# uv\nuv tool install onboard-memory-mcp\n```\n\nAll three provide the `onboard-memory-mcp` command (Homebrew also adds a short\n`onboard-memory` alias). Homebrew covers macOS and Linux; on **Windows** use\npipx or uv (the command is `onboard-memory-mcp.exe`). Point your MCP client's\n`command` at it instead of `python3 onboard_server.py`. You can also skip this\nand run from a clone using the setup paths below. (On Homebrew 6+, approve the\none-time tap-trust prompt, or run `brew trust swisspra/tap`.)\n\n#### Headless config (no clone)\n\nWith the server installed, wire your MCP client to it directly — no repo\ncheckout, no `setup-project.sh`:\n\n```json\n{\n  \"mcpServers\": {\n    \"agent-memory\": {\n      \"command\": \"onboard-memory-mcp\",\n      \"env\": { \"AGENT_PROJECT_DIR\": \"/full/path/to/your/project\" }\n    }\n  }\n}\n```\n\n- **CLI clients** (Claude Code, Codex) inherit your shell `PATH`, so the bare\n  `onboard-memory-mcp` works.\n- **GUI clients** (Claude Desktop, Cursor) launch with a minimal `PATH`. Use the\n  absolute path from `which onboard-memory-mcp` (`where` on Windows) as\n  `command` — typically `/opt/homebrew/bin/onboard-memory-mcp` (Homebrew, Apple\n  Silicon), `/usr/local/bin/onboard-memory-mcp` (Homebrew, Intel),\n  `/home/linuxbrew/.linuxbrew/bin/onboard-memory-mcp` (Homebrew, Linux),\n  `~/.local/bin/onboard-memory-mcp` (pipx / uv on macOS/Linux), or\n  `%USERPROFILE%\\.local\\bin\\onboard-memory-mcp.exe` (pipx / uv on Windows).\n\n`AGENT_PROJECT_DIR` is required — it decides which project owns `.agent-mem/`.\nIn your first chat, call `memory_init` once (creates `.agent-mem/`), then\n`memory_onboard` each session. Nothing to create by hand.\n\nThe `pipx`/`uv` path installs from prebuilt wheels (no compiler) on Python 3.11+\nfor Linux, Windows, and Apple-Silicon macOS; on Python 3.10 or Intel macOS a\ncouple of Rust/C dependencies may build from source, so prefer `brew` there.\nTemplate: [configs/binary-mcp.json](./configs/binary-mcp.json); full detail and\nplatform notes in [docs/SETUP.md](./docs/SETUP.md).\n\n### Set up a project\n\nChoose one setup path:\n\n#### Option 1: Agent setup\n\nAsk an agent to read [AGENT_SETUP.md](./AGENT_SETUP.md) and help you set up the\nproject. This is the easiest path if you already have an agent available.\n\n#### Option 2: Script setup\n\n```bash\ngit clone https://github.com/swisspra/On_Board.git\ncd On_Board\nbash setup-project.sh /full/path/to/your/project\nbash doctor.sh /full/path/to/your/project\n```\n\nAdd the generated MCP config to your client:\n\n```text\n/full/path/to/your/project/.onboard/mcp.generated.json\n```\n\nSome clients accept this JSON directly. Others require you to merge it into\ntheir own MCP settings file.\n\nAfter memory is initialized, open the dashboard with:\n\n```bash\nbash /full/path/to/your/project/.onboard/run-dashboard.sh\n```\n\nOn Board is installed once. Each project points to the same On Board folder,\nbut gets separate memory through `AGENT_PROJECT_DIR`.\n\nEach `setup-project.sh` run also registers the project locally in\n`.onboard/linked-projects.json` inside the On Board checkout. This file is\ngitignored and only helps updates remember which projects point here.\n\nThe setup script uses `uv sync --inexact` to install/update dependencies without\npruning local test/dev extras. MCP clients run `python3 onboard_server.py`; the\nlauncher uses the local `.venv` directly and rebuilds it only if the venv is\nmissing. This keeps normal startup fast, avoids `uv run` startup timeouts, and\nmakes a shared central checkout more durable.\n\nOn Board does not write memory from end-turn hooks. Current `Stop` hooks in\nseveral agent clients run every turn, which creates noisy memory and can force\nagents to re-onboard too often.\n\nOptional: add `AGENT_MEM_CONTEXT_DIRS` to the generated MCP config when agents\nshould read shared docs/specs outside the project folder.\n\n#### Option 3: Advanced manual setup\n\nIf you do not want to run the setup script, install with `uv sync`, write the\nMCP config yourself, and add project rules/hooks manually. See\n[docs/SETUP.md](./docs/SETUP.md).\n\nIn your first chat with any MCP-aware agent (Claude Desktop, Claude Code,\nCursor, Codex, Antigravity):\n\n```\nmemory_bootstrap(\n  agent_name=\"dev-main\",\n  description=\"Existing project using On Board\",\n  current_task=\"Set up shared project memory\"\n)\n\nmemory_onboard(\n  agent_name=\"dev-main\",\n  agent_platform=\"claude-code\",\n  agent_role=\"main\"\n)\n```\n\nThat's it. The agent now sees the project briefing, the open tickets, the\nrecent memory, and the protocol it should follow. Every subsequent action\nis stamped with its identity.\n\nFull setup details and manual setup: see\n[docs/SETUP.md](./docs/SETUP.md).\n\nTo update an existing install, run `bash update.sh` in the central On Board\ncheckout. It will show known linked projects. Refresh all of them with\n`bash update.sh --refresh-linked`, or inspect them with\n`bash setup-project.sh --list-linked`.\n\n---\n\n## The loop in one example\n\n```\n1. SPEC\n   opus-testcase reads requirement → writes 5–20 acceptance tickets\n   with explicit pre/post conditions.\n\n2. BUILD\n   dev-track-2 claims a ticket → implements in src/ → submits with\n   file diff + test plan.\n\n3. TEST\n   Jonhny-tester picks up submission → runs UI in Chromium → captures\n   screenshots → submits PASS or FAIL with evidence.\n\n4. REVIEW\n   desktop-opus4.7 (or the human) checks evidence → approves OR rejects\n   with concrete fix instructions.\n\n   If rejected → ticket reopens → dev-track-2 patches → Jonhny retests\n   → loop closes.\n```\n\nWhen this loop runs cleanly, a single ticket goes from `open` to \"shipped\nto production\" in 4–15 minutes of agent time. The human checks in at the\nend, not in the middle.\n\n---\n\n## Agent-to-agent: the listening half (v4)\n\nEverything above still works pull-style. v4 adds the missing edge: agents can\nnow **wake each other** instead of waiting for a human to relay messages.\n\n```\nworker:  memory_wait_for_event(agent_name=\"dev-track-2\", timeout_s=180)\n         → parks inside one tool call until the board changes\nlead:    memory_create_ticket(..., assigned_to=\"dev-track-2\")\nworker:  wakes in seconds, claims, works,\n         memory_submit_ticket(..., stay_active=True)\nlead:    wakes on the submission, reviews\nworker:  wakes on the verdict — approve closes the loop;\n         a rejection arrives WITH the review notes and fix\n         instructions in the wake payload, so it re-claims,\n         fixes, and resubmits without asking anyone\n```\n\nDesign points, all field-verified across Claude Desktop × Claude Desktop and\nClaude × Codex (GPT):\n\n- **Check before blocking** — a re-arm after a gap returns its backlog in 0 s\n  instead of waking empty. One wake drains the whole queue.\n- **Loop guard** — an agent never wakes on its own actions, so two listeners\n  cannot ping-pong each other.\n- **Role gate** — *completed ≠ success*: whoever executed a ticket may reach\n  `submitted` but may never close it; only the owner or a main/lead/reviewer\n  adjudicates. Solo use is still possible via explicit `allow_self_review=True`,\n  permanently stamped in the audit.\n- **Client limits respected** — Claude Desktop cancels tool calls at ~240 s\n  *per call* (measured), so timeouts clamp to 200 s there; stdio clients\n  (Claude Code, Codex) may pass `long_wait` and park much longer.\n- **Idle budget, in minutes** — the server counts consecutive empty parks and\n  answers `STAND-DOWN` once `idle_budget_min` (default 15) is spent, so an\n  unattended listener stops on its own instead of looking wedged. Budgets are\n  stated in minutes because a human watching a silent loop counts wall clock,\n  not iterations — a compliant agent looping for 20 minutes looks stuck even\n  when it is exactly on budget. Every idle reply prints `idle 3/5 — ~6 min to\n  stand-down`. The counter resets on a real event and never on re-arming, and\n  `STAND-DOWN` is a distinct status so a loop matching on `idle` cannot read it\n  as permission to continue. `idle_budget_min=0` listens indefinitely.\n- Use the `listen` MCP prompt for the standard re-arm loop.\n\nv4 also hardens the board for simultaneous writers (advisory lock on ticket\nmutations, per-process tmp files), because with A2A two agents acting in the\nsame instant is the normal case, not the rare one. Breaking changes and the\nmigration guide live in [CHANGELOG.md](./CHANGELOG.md).\n\n---\n\n## Tools (29 MCP tools, 5 buckets)\n\n| Bucket | Tools |\n|---|---|\n| **Agent lifecycle** | `memory_onboard`, `memory_agent_join`, `memory_handoff`, `memory_checkpoint`, `memory_get_briefing`, `memory_wait_for_event` |\n| **Ticket queue** | `memory_create_ticket`, `memory_claim_ticket`, `memory_submit_ticket`, `memory_review_ticket`, `memory_cancel_ticket`, `memory_terminate_ticket`, `memory_list_tickets` |\n| **Persistent memory** | `memory_write`, `memory_read`, `memory_search`, `memory_search_vector`, `memory_links` |\n| **Project context** | `memory_init`, `memory_bootstrap`, `memory_status`, `memory_doctor`, `memory_update_state`, `memory_context_dirs`, `memory_context_read` |\n| **Compaction** | `memory_prepare_compaction`, `memory_compact`, `memory_token_usage`, `memory_search_archive` |\n\nFull reference: [docs/TOOLS.md](./docs/TOOLS.md).\n\n---\n\n## What makes this different\n\nOn Board is not only a place to store memories. It keeps the work loop visible:\n\n```text\nonboard -> claim ticket -> submit evidence -> review -> approve or reopen\n```\n\nThat gives agents a shared queue, stable identities, recent handoffs, and a\nreview gate. Rejected work reopens with fix instructions instead of becoming a\ndead terminal state.\n\n---\n\n## Project structure (runtime data)\n\n```\nyour-project/\n├── .agent-mem/                runtime memory, gitignored\n│   ├── project.json\n│   ├── agents.json            agent registry (identity, status, KIA)\n│   ├── memories.json\n│   ├── state.json             project phase, owner, design defaults\n│   ├── archive.json\n│   ├── digests.json\n│   ├── checkpoints/\n│   └── tickets/\n│       ├── _index.json\n│       ├── TK-<id>.md         the spec\n│       ├── TK-<id>-submit.md  dev submission\n│       ├── TK-<id>-review.md  QA / reviewer verdict\n│       └── closed/\n```\n\nEverything is plain text or JSON. You can `cat` your way through the\nproject's full history. No vector DB lock-in, no opaque embeddings — just\nfiles an audit can read.\n\n---\n\n## Current status (v4.0.4, August 2026)\n\nThe current local setup is built around one central On Board checkout and one\nproject-selected memory folder:\n\n- `memory_onboard` is the primary start call for agents and returns compact current context.\n- `memory_wait_for_event` turns the board push-capable: agents park, wake on peer\n  actions, and close reject/retry loops with zero human relay (see the A2A section).\n- `memory_doctor` checks setup and data integrity.\n- `setup-project.sh` generates project MCP config, rules, startup hooks, and a\n  dashboard launcher.\n- Linked-project registry tracks which projects point at the central checkout,\n  so updates can refresh known projects without scanning the machine.\n- Runtime startup uses `python3 onboard_server.py`; the launcher normally\n  execs `.venv/bin/python server.py` and only falls back to `uv sync --inexact`\n  if `.venv` is missing.\n- Startup hooks return a small read-only briefing. End-turn/Stop hooks are not\n  installed by default because current clients can run them too often.\n- The dashboard is local and read-only.\n\nFull CHANGELOG: [CHANGELOG.md](./CHANGELOG.md).\n\n---\n\n## License\n\nApache-2.0. Free to use, fork, modify, redistribute, build commercial\nproducts on. No restrictions on use.\n",
  "bytes": 15090,
  "sha": "ff011050b473029e71a715c0d819ee8e6045e8aa4be933a0a37f1912abcdec26",
  "repo_slug": "swisspra/on_board",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_swisspra_on_board_990e3fd9/readme"
}