
Cpm Planner
io.github.praxecv0.2.1更新於 Oct 11, 2026
Critical Path Method scheduling and lock-aware parallel cohorts for MCP agents.
概覽
一個 MCP 伺服器,用關鍵路徑法為代理任務圖排程,並租用鎖感知的平行工作批次。
- 功能
- 它接收任務圖並計算最早與最晚開始和完成時間、浮時、關鍵路徑以及限制完成的瓶頸任務。接著它租用檔案集互不重疊、鎖感知的就緒交付項目批次,讓多個工作單元可以平行而不衝突。唯讀工具可檢查計畫、依資源容量進行資源平準、執行蒙地卡羅風險分析,並對照凍結基準追蹤實獲值(PV、EV、AC、SPI、CPI)。選用的 AI 審查會提出經過驗證的時程改善建議。
- 適用情境
- 當助理或協調器需要規劃並協調帶相依關係、平行工作單元和共用檔案的多步驟工作時適用。它適合希望在儲存庫中保存計畫即程式碼檔案、進行資源平準、風險模擬或實獲值追蹤的團隊。簡單的單步驟任務不需要它。
- 執行需求
- 以本機程序透過 stdio 執行。可安裝預先建置的執行檔、npm 啟動器(Node 18 或更新版本)、Cargo 建置(Rust 1.99 或更新版本)或 Docker 映像。選用環境變數包括用於 SQLite 狀態路徑的 CPM_PLANNER_DB、用於計畫檔案的 CPM_PROJECT_ROOT、用於租約上限的 CPM_MAX_TTL_SECS,以及用於選用計畫審查的 OPENROUTER_API_KEY 或 CPM_OPENROUTER_KEY_FILE。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Cpm Planner,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
cpm-planner
[CI] [Release] [License: Apache-2.0]
cpm-planner is a Critical Path Method (CPM) planner for agent work, exposed as an MCP server. You submit a task graph and it computes the schedule: earliest and latest start and finish, slack, the critical path and the bottleneck tasks that gate completion. It then leases lock-aware cohorts of ready deliverables with disjoint file sets, so several workers can run in parallel without colliding. Plans can live in the repository as plan-as-code files with forkable, comparable variants; read-only tools lint, level against resource capacities and run Monte Carlo risk; earned-value tools track PV, EV, AC, SPI and CPI against a frozen baseline; and an optional AI review proposes verified schedule improvements. Any MCP client (Claude Code, Cursor, VS Code, Codex, a custom orchestrator, or a praxec workflow) drives it over stdio. It is a standalone tool with no dependency on praxec.
Contents
- Install
- Quickstart: plan as code
- Quickstart: earned value
- Use with AI agents
- MCP tools
- Use as a library
- Praxec
- Environment variables
- Documentation
- Contributing
- License
Install
Prebuilt binary (recommended)
Prebuilt packages are published for Linux, macOS and Windows on x86_64 and ARM64.
The installers resolve your OS and CPU and download the matching archive. They
verify its SHA-256 against the release's checksums.sha256 before installing,
then atomically replace the binary in a user-local directory. A checksum mismatch
aborts with a non-zero exit and installs nothing. Re-running the installer upgrades
in place.
The installer prints the absolute path it installed to. Use that path when you register the server with a GUI client.
Installer details: inspecting the script, PATH, upgrades and direct downloads
If you would rather read the script before running it, download, inspect, then run
(see Pin a version for <version>):
PATH. If the install directory is not on your PATH, the installer prints the
exact line to add. Pass --add-to-path (-AddToPath on Windows) to have it do that
for you, user-level only and never with sudo.
On Linux and macOS it appends the line only if it is not already there, to:
~/.zshrcfor zsh;~/.bash_profileif it exists, else~/.bashrc, for bash;~/.profilefor other shells.
For fish it prints fish_add_path <dir> for you to run instead of writing a file.
Downloads. The installers only accept https:// download URLs.
Upgrades. After upgrading, restart your MCP client so it launches the new
binary. On Windows the old exe is renamed to cpm-planner.exe.old and removed on
the next run.
Direct downloads. You can also download an archive yourself and check it
against checksums.sha256; a machine-readable release-manifest.json is published
too. All assets are at https://github.com/praxec/cpm-planner/releases/latest.
Pin a version
In the commands in this README, <version> is a release tag such as v0.2.0. Pick
one from the releases page.
npm
With Node 18 or later, install the cpm-planner command from npm:
The package is a small launcher. It downloads the release binary for your
platform, verifies its checksum and caches it, during install or, where npm
skips install scripts, on first run. The package
version is the release version, so npm install -g @matthew-cochran/[email protected]
pins one. To run it without installing, use npx -y @matthew-cochran/cpm.
For details and environment variables, see npm/README.md.
From source
Build and install a tagged release with Cargo (Rust 1.99 or newer):
The crates.io listing lags behind the GitHub releases until the next
cargo publish, so cargo install cpm-planner does not give you the current
version yet. Install from the tag as above.
Docker
-i keeps stdin open for the stdio transport.
The image sets CPM_PLANNER_DB=/data/cpm-planner.db and declares /data as a
volume owned by the unprivileged app user, so a named volume persists plan state
across runs. For a bind mount (-v "$PWD:/data"), run as yourself so the directory
is writable: --user "$(id -u):$(id -g)". Pass -e CPM_PLANNER_DB=... only to
override the path.
To register the image with a client, put docker in command and the rest in
args. For example, in Claude Code:
Verify the install
It prints cpm-planner <version>. To check the MCP side without a client, run the smoke
script from the repository. It performs the MCP initialize and tools/list handshake and
fails if plan.submit, plan.status or plan.get is missing:
Quickstart: plan as code
Write a plan as .cpm-planner/plans/<name>/<variant>.json (a PlanGraph):
plan.lint {path: ".cpm-planner/plans/checkout/main.json"}— static checks, no state written.plan.sync {path: ".cpm-planner/plans/checkout/main.json"}— register the variant and return itsplan_id.plan.status {plan_id}— schedule, critical path, ready set and locks.
plan.sync tracks the file by content hash; plan.status reports
definition_drift when the tracked file and the stored head graph disagree.
Quickstart: earned value
Freeze the baseline, record progress, then read the report (earned_pct is earned in
proportion under earning_rule: "weighted"; fifty_fifty credits 50% once a deliverable is in progress or has any
reported earned_pct, and the default zero_hundred
earns at completion):
plan.baseline {plan_id}— freeze the CPM schedule and budgets as baseline 1.plan.mark_status {plan_id, deliverable_id, caller_id, status: {"status": "in_progress"}, earned_pct: 50, actual_effort_hours: 4}— report progress and actual cost.plan.ev {plan_id}— PV, EV, AC, SV, CV, SPI, CPI, EAC and alerts.plan.snapshot {plan_id, format: "markdown"}— append the reading and export a Markdown table.
A ratio with a zero denominator is null and explained in undefined; alerts
(SPI_BELOW_0_9, CPI_BELOW_0_9) compare the two latest stored readings.
Use with AI agents
Any MCP client can run cpm-planner over stdio: register the cpm-planner
binary as the command, or, with Node 18 or later, npx -y @matthew-cochran/cpm.
For a GUI client, use the absolute path the installer printed.
Install the agent skills (/cpm-plan and friends) with
cpm-planner skills install --target <tool> --user (or --project <dir>), where
<tool> is claude, codex, cursor, copilot, gemini, all, or
agents-md (project only).
docs/AGENT-INSTALL.md has the per-client steps (Claude
Code, Claude Desktop, Codex, Cursor, VS Code, Gemini CLI and others), env
blocks, verification and troubleshooting. llms.txt indexes the docs
for LLMs.
MCP tools
plan.lint, plan.simulate and plan.review take exactly one of an inline graph, a stored
plan_id, or a plan-file path; plan.schedule takes graph or plan_id;
plan.schedule and plan.simulate reject what plan.submit rejects, and plan.lint reports it as findings. Monte Carlo output is reproducible for a given seed on the same platform
and toolchain; bit-identical results across targets or compiler versions are
not guaranteed, because float math functions can differ.
Plan-as-code workflow
Author a plan as a file at .cpm-planner/plans/<name>/<variant>.json, check it
with plan.lint {path}, register it with plan.sync {path} and execute the
returned plan_id. A named line has many variants but exactly one selected:
plan.fork creates a draft from structured edits, plan.compare scores the
variants, and plan.select makes one executable. Keep definitions in tracked
files — never keep untracked scratch graphs.
Plan review (optional)
plan.review asks Jev (typesafe/jev-1.13), TypeSafe's
calibrated-judgment model, about a lint-clean plan through OpenRouter: one
batched call of at most 64 questions per review. It is off until you set
OPENROUTER_API_KEY (or CPM_OPENROUTER_KEY_FILE); without a key the tool
still answers, with review_unavailable and the lint report. An invalid LLM
setting never stops the server: it is logged at startup and plan.review
reports review_unavailable with a reason naming the setting.
-
Probabilities are advisory. Treat findings as a second opinion. Proposals are verified mechanically (the edited plan must lint clean and simulate to a shorter makespan); apply one with
plan.fork {edits}, thenplan.compare. -
Cost. Each
plan.reviewcall that reaches the judge is one billed OpenRouter request; Jev costs about $0.042 per million input tokens on OpenRouter. Each report carries the provider'susagewhen given. At most 2 reviews that call the judge run at once per server; further calls wait for a slot (reviews that end before the call, such as no key or lint errors, never wait). -
Privacy. This is everything sent to OpenRouter in that one request:
- a fixed task sentence, the plan makespan and the critical path (ids);
- the questions: for each, its kind, the deliverable ids it names, and a
question sentence that quotes those ids and, depending on the kind, the
prerequisite's
consumestext, the deliverable's scheduled hours, the plan's median scheduled hours, and the heuristic signals that raised a missing-dependency question (a description mentions the other, files in the same or nested directories, a sharedmetadata.owner); - for every deliverable a question names: its id, scheduled hours, float
hours,
criticalandmilestoneflags, owned file paths (sent in full, not truncated), prerequisites (id,consumes, kind) and itsdescription,artifactandownermetadata.description,artifact,ownerandconsumesare cut to 500 characters each.
Nothing else in the graph (other deliverables, other metadata keys, estimates) is sent. Do not review plans whose contents you may not share with OpenRouter.
-
Audit. The key is never logged or returned, and neither is a misplaced value of any LLM variable. Every
plan.reviewcall records oneplan.reviewaudit event, whatever its outcome (including a missing plan, a bad path or a failed review); the only unaudited case is a call rejected for its params (invalid_params). The event has exactly these fields:status:ok,review_unavailable,invalid_graph, orerror(the review failed:PLAN_NOT_FOUND,INVALID_PATH,INVALID_CAPACITIES, …);code: the error prefix forerror, else null;failure_class: for areview_unavailablecaused by a failed judge call, its class (unauthorized,rate_limited,timeout,upstream,decode,transport,invalid_request); null otherwise (including no key and an unusable LLM setting);plan_id: the stored plan reviewed, null for an inlinegraphorpath;question_count: questions sent (0 when the judge was not called);jev_called: whether the judge was called;prompt_hash: sha256 of the canonical request, null when the judge was not called;model: the model the provider reported, else the configured model when the call failed; null when the judge was not called;endpoint: the judge endpoint's host; null when no judge is configured, lint found errors, or the review ended inerror.
The prompt itself is never recorded.
Use as a library
The CPM kernel is also a plain Rust library, independent of MCP:
The crate-level docs (cargo doc --open, or docs.rs
once a current version is published there) have a runnable example that drives the
planner through submit, lease and complete.
llm::jev::JevJudge (the plan.review judge) owns its HTTP client and
connection pool. A pooled connection is driven by the tokio runtime that
opened it, so use a judge (and its clones) from one runtime, and build a new
judge for another runtime.
Praxec
cpm-planner is fully standalone: it speaks plain MCP and has no code dependency on any particular client. Praxec packs use it as an MCP tool. To wire it into a praxec workflow, declare an MCP connection (protocol only, no shared code):
The easiest way to get it, plus a workflow pack that uses it, up and running is the one-command setup:
See the pack registry for this tool's provider coordinates (container image or release binary) and which packs depend on it.
Environment variables
Set these in a client's env block (or -e/--env flag, or docker run -e). All are optional.
Leases default to 5 minutes. For long-running work pass ttl_seconds (≤ the server maximum) on acquire/heartbeat, and heartbeat at least every ttl/3.
Documentation
- docs/README.md: index of the project documentation.
- docs/AGENT-INSTALL.md: install, register and verify cpm-planner for your AI coding tool.
- docs/architecture.md: modules, request flow, store schema and concurrency.
- docs/releasing.md: the release runbook.
- CONTRIBUTING.md, SECURITY.md, SUPPORT.md, CHANGELOG.md.
Contributing
Contributions are welcome. See CONTRIBUTING.md for the toolchain, the gates and the branch model. Everyone taking part agrees to the Code of Conduct.
License
來源:README.md,提交 1fdd3af
工具
0版本歷史
1- v0.2.1最新Oct 11, 2026


