1. Overview
PM Server は Claude Code 用のプロジェクト管理 MCP (Model Context Protocol) サーバー。 タスク追跡・進捗可視化・ブロッカー検知・ADR 記録・横断ダッシュボード・workflow 状態マシン・ SQLite メモリ層 (FTS5 全文検索) を一体提供する。
| 言語 | Python 3.11+ |
| 主要フレームワーク | FastMCP, Pydantic v2, Click, Jinja2, tomlkit |
| データ形式 | YAML (human-readable, git-friendly) + SQLite per-project (.pm/memory.db) + global (~/.pm/memory.db) + outbox (~/.pm/desktop/desktop.db) |
| 配布 | PyPI pm-server (Full RW) + .mcpb bundle (Lens RO / Desktop Outbox) |
| 対象ホスト | Claude Code, Claude Desktop, Claude Cowork, Codex CLI |
| 動作モード | PM_LENS=0 Full RW / PM_LENS=1 Lens RO / PM_LENS=1 + PM_DESKTOP_WRITE=1 Outbox bridge (Phase 2) |
| ライセンス | MIT |
2. Module Architecture
18 個の Python モジュールが server.py (FastMCP インスタンス) を中心に連携する。
データ層 (models / storage / memory / outbox) が下位、機能層 (workflow / hooks / installer /
discovery / velocity / dashboard / recall / rules) が中位、orchestration (server / __main__) が上位。
outbox.py は v0.8.0 で追加された Phase 2 Desktop Outbox SQLite store (ADR-019)。
点線 (utils.py) は多数モジュールから利用される依存。discovery.py は深さ 5 cap + 除外
ディレクトリ + ~/.pm/ スキップで bounded walk を保証 (PMSERV-081)。
memory.py は PM_LENS=1 時に ?mode=ro&immutable=1 で SQLite を開き
WAL sidecar の意図せぬ作成を防ぐ (PMSERV-080)。
3. MCP Tool Catalog
37 個の MCP ツールがカテゴリ別に提供される。配布モードによって登録される ツール集合が異なる:
RO は Lens モード (PM_LENS=1) で利用可能、
OUTBOX は Lens + PM_DESKTOP_WRITE=1 で追加開放される Desktop Outbox 書込み tool、
RW は full pm-server (Claude Code / Codex 配布) のみ。
| カテゴリ | ツール | 用途 | モード |
|---|---|---|---|
| Project setup | pm_init | 新規プロジェクトの .pm/ 初期化 | RW |
pm_discover | サブツリー walk で .pm/ project を検出 (depth=5 cap) | RW | |
pm_list | ~/.pm/registry.yaml の登録 project 一覧 | RO | |
pm_cleanup | 古いログ・記憶・summary の clean-up | RW | |
pm_update_claudemd | CLAUDE.md の pm-server セクションを最新化 | RW | |
pm_update_rules | Codex AGENTS.md を最新化 | RW | |
| Status & navigation | pm_status | フェーズ進捗・タスク数・blocker・diagnostics | RO |
pm_next | 優先度・依存・phase で次タスク推薦 | RO | |
pm_dashboard | HTML/テキスト ダッシュボード生成 | RO | |
pm_velocity | 4 週ベロシティ + 完了率 | RO | |
pm_risks | 遅延予測・blocker・期限超過のリスク一覧 | RO | |
| Tasks & issues | pm_tasks | フィルタ付きタスク一覧 | RO |
pm_add_task | 新規タスク登録 (ID 自動採番) | RW | |
pm_update_task | status/priority/blocked_by 等の更新 | RW | |
pm_blockers | blocked タスクと blocker 一覧 | RO | |
pm_add_issue | defect/enhancement issue を親 task 配下に追加 (defect で親 auto-revert) | RW | |
| Memory & session | pm_remember | observation/insight/lesson を SQLite 保存 | RW |
pm_recall | last session + recent memories + FTS5 検索 | RO | |
pm_memory_search | tags / type / task_id / cross_project 検索 | RO | |
pm_memory_stats | type 別カウント・最古/最新タイムスタンプ | RO | |
pm_memory_cleanup | 古い memory の dry-run / actual 削除 | RW | |
pm_log | daily log エントリ追記 (progress/decision/blocker/milestone) | RW | |
pm_session_summary | session summary の save/get/list | RW | |
| Cross-host Outbox (Phase 2, ADR-019) |
pm_outbox_remember | Desktop → 共有 outbox に memory/lesson を append (host 共有 bridge) | OUTBOX |
pm_outbox_log | Desktop → outbox に daily log entry を append (category 保持) | OUTBOX | |
pm_outbox_pending | outbox の pending/merged/rejected 一覧 (paginated) | RW | |
pm_outbox_merge | pending entries を target project の memory.db / daily log へ promote | RW | |
pm_outbox_reject | pending entries を reason 付きで reject (append-only 保持) | RW | |
| Decisions (ADR) | pm_add_decision | Architecture Decision Record の登録 | RW |
| Knowledge records | pm_record | research/spec/tradeoff/risk_analysis を構造化記録 | RW |
pm_knowledge | list/get/update/summary (update は RW) | RW | |
pm_knowledge_query | RO 専用クエリ (Lens 用に切り出し PMSERV-079) | RO | |
| Workflow engine | pm_workflow_start | development/discovery/super-research 起動 | RW |
pm_workflow_status | active workflow の step 詳細・gate・artifacts | RO | |
pm_workflow_advance | 次 step へ遷移 (gate user_approval 必要) | RW | |
pm_workflow_abandon | active workflow を放棄 | RW | |
pm_workflow_list | active/completed/paused/abandoned 一覧 | RO | |
pm_workflow_templates | builtin + custom テンプレート一覧 | RO |
15 RO + 2 OUTBOX-RW + 20 Full-RW = 37 ツール (2026-05-26, v0.9.0)。Lens 配布では RO_ALLOWLIST 外の
ツールが FastMCP に未登録 = 構造的不変条件 (ADR-015/017/018)。OUTBOX 2 ツールは PM_DESKTOP_WRITE=1
が追加で立った時のみ登録され、main .pm/memory.db は touch しない (ADR-019)。
4. Lens Mode (Read-Only) Flow
PM_LENS=1 環境変数が立った pm-server プロセスは、起動時に RO_ALLOWLIST 外のツールを
FastMCP に登録しない。これは Claude Desktop / Cowork のような passive ビューア host で「書き込み事故」を
構造的に防ぐ防衛機構。
server.mcp_config.env.PM_LENS=1 は配布意図のシグナル
(host が読まなければ無効) だが、RO_ALLOWLIST による FastMCP 未登録は code レベルの構造的不変条件。
1 箇所のロジック漏れがあっても他方で防御するレイヤード設計 (ADR-015/017/018)。
5. Workflow Engine
3 つの builtin テンプレートでステートマシン化された開発プロセスを提供。各 step が
tool_hint/skill_hint/agent_hint でガイダンスを返し、
gate: user_approval step では明示的承認待ち、loop: true step では
品質スコアによるループバックを許容する。
5.1 development (9 steps)
5.2 super-research (6 steps, depth_check ループ付き)
5.3 discovery (調査・ブレスト)
scope → research → analysis → synthesis → proposal の 5 step。完了時に chain_to: development
で次の開発 workflow 起動を提案する。
6. Task & Issue Lifecycle
タスクは todo → in_progress → review → done の主経路、別途 blocked (任意状態から推移可) を持つ。
issue (子 task) を severity=defect で起票すると親 task が自動的に done → review に巻き戻る。
6.1 Issue severity ごとの挙動
| severity | 親 task の自動状態変更 | warning | 使用シナリオ |
|---|---|---|---|
defect (default) | done → review (auto-revert) | parent_reverted | 品質レビュー中に欠陥発見 |
enhancement | 変更なし | — | 将来改善・親に紐付く提案 |
7. Data Layout
YAML (human-readable, git-friendly) + SQLite (高速検索) のハイブリッド。プロジェクトローカル
.pm/ と global ~/.pm/ が分離。
Per-project (<repo>/.pm/)
Global (~/.pm/)
Lens モード時の RO 担保
| レイヤ | 挙動 (PM_LENS=1) |
|---|---|
| YAML files | read-only open (load_* のみ呼ばれ save_* は到達不能 — RO_ALLOWLIST 外) |
| per-project SQLite | ?mode=ro&immutable=1 で接続 — WAL -shm sidecar 不生成 (PMSERV-080) |
| global SQLite | MemoryStore(readonly=True) で global_db_path=None 強制 — sync 経路無効化 |
| memory.db 不在 | :memory: SQLite に fallback (search は空、エラーなし) |
8. Distribution Channels
同一コードベースが 3 つの配布モードを持つ。PyPI は Full RW、.mcpb は構造的 RO (Lens)、
.mcpb + PM_DESKTOP_WRITE=1 は Lens に Outbox 書込みだけを足した bridge モード。
PyPI pm-server | .mcpb bundle (Lens) | .mcpb + PM_DESKTOP_WRITE | |
|---|---|---|---|
| 対象 host | Claude Code (CLI) / Codex CLI | Claude Cowork / その他 viewer | Claude Desktop (Phase 2 bridge) |
| インストール | pip install pm-server → pm-server install | .mcpb ファイルを host に drag & drop | .mcpb + manifest が PM_DESKTOP_WRITE=1 を auto-propagate (PMSERV-100) |
| 登録 tools | Full RW (37 tools) | Lens RO (15 tools) | RO 15 + OUTBOX-RW 2 = 17 tools |
| 環境変数 | 未設定 | PM_LENS=1 | PM_LENS=1, PM_DESKTOP_WRITE=1 |
| SQLite モード | RW main + outbox | ?mode=ro&immutable=1 main / outbox 不触 | main は RO 不変、outbox ~/.pm/desktop/desktop.db は append-only RW |
| 同一バイナリ? | はい — 配布物は 1 種類、env で role gating | ← | |
| バージョン同期 | pyproject.toml が source of truth、manifest.json は build_mcpb.py validator で lockstep (CI 強制) | ||
~/.pm/ と project 内 .pm/memory.db を共有しうるが、
Lens 側は memory.py:98-117 の ?mode=ro&immutable=1 で RO 接続するため、
Claude Code 側が WAL を書いていても -shm sidecar の意図せぬ生成は発生しない (PMSERV-080 / FINDING-J)。
installer.py の PM_LENS / PM_DESKTOP_WRITE 認識
install_claude_code() は --env PM_LENS=1 (+ PM_DESKTOP_WRITE=1) を
claude mcp add に注入、install_codex() は TOML inline_table
env = { PM_LENS = "1" } を section に書き込む。
InstallResult.lens_mode / InstallResult.desktop_write で caller が role を判別可能。
Phase 2 (PMSERV-100) で .mcpb manifest が PM_DESKTOP_WRITE を auto-propagate するため、
Desktop ユーザーは bundle drag & drop だけで outbox bridge が成立する。
9. Desktop Outbox (Phase 2 — ADR-019)
Claude Desktop (Lens) は本来 RO だが、PM_DESKTOP_WRITE=1 時に限り
~/.pm/desktop/desktop.db という専用 SQLite へ append-only で書き込める。
main の per-project .pm/memory.db は依然不可触 (Lens 不変条件保持)。
書込みは「outbox」として一旦溜まり、Claude Code 側で pm_outbox_pending →
pm_outbox_merge / pm_outbox_reject でレビューして promote する。
9.1 Cross-host data flow
9.2 状態遷移と invariant
| 段階 | tool | 結果 | 不変条件 |
|---|---|---|---|
| capture | pm_outbox_remember / pm_outbox_log | desktop.db に INSERT (status=pending) | main memory.db 不変 |
| review | pm_outbox_pending | filter (project/type/status) + paginate | RO クエリのみ |
| promote | pm_outbox_merge | main project の memory / daily log に追記 → status=merged | append-only trigger により past 行は immutable |
| discard | pm_outbox_reject | status=rejected + reason 保存 | 履歴は失われない (audit trail) |
9.3 関連 ADR / 実装
ADR-019 (Phase 2 設計) / ADR-020 (ADR-017 amendment) / ADR-021 (ADR-018 amendment) ·
PMSERV-094..104 (実装), PMSERV-100 (manifest 自動伝播), PMSERV-105 (v0.8.0 release) ·
outbox.py + tests 30 cases + lens invariant 4 amendment tests (test_lens_mode.py) ·
storage 設計: ~/.pm/desktop/desktop.db (cross-project shared, project ローカルではない)