Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Ferroplan

БесплатноНе проверен

Model Context Protocol server for the ferroplan PDDL planner (solve / validate / decompose over stdio)

GitHubEmbed

Описание

Model Context Protocol server for the ferroplan PDDL planner (solve / validate / decompose over stdio)

README

ferroplan

ferroplan

CI docs live demo license

A fast, data-parallel PDDL planner in Rust — a deterministic planning core for the age of AI.

The bet: an LLM should be the author and supervisor of a planner, not its runtime. The same reason you don't ask a model to add a column of numbers — you have it emit code that does the arithmetic deterministically, and for free — applies one level up: don't ask an LLM to be the planner for a whole village of agents. Have it author a PDDL domain that then plans deterministically, cheaply, and inspectably at scale, and let it only nudge that domain at runtime. PDDL is the auditable interface between your intent, the model's authoring, and a fast solver — and ferroplan is that solver.

Why PDDL, not prompt-spaghetti:

  • Cost — a solved domain plans essentially for free; an LLM call per decision per agent does not.
  • Determinism — same problem, same plan; you can regression-test it.
  • Inspectability — you can read a domain and an axiom; you cannot read a model's weights.
  • Scale — a village of agents each replanning is tractable for a fast solver, not as a wall of LLM calls.

▶ Try it live in your browser — pick a built-in example or paste your own PDDL; it plans entirely client-side via WebAssembly, no install. There's also a browser visualizer + block editor.

Where it stands

62% coverage across 22 IPC boards (3,916/6,366) on m5-air, including 381 certified optima.

track coverage
net-benefit 246/270 ███████████████░ 91%
seq-sat 503/580 ██████████████░░ 87%
seq-mco t8 240/280 ██████████████░░ 86%
seq-mco t4 237/280 ██████████████░░ 85%
seq-mco t2 230/280 █████████████░░░ 82%

Best five shown. Full standings → STANDINGS.md · per-track detail, quality scoring and failure classes in benchmarks/ipc-standings.md.

ferroplan is a from-scratch reimplementation of the FF family of planners with a data-oriented core (bitset states, structure-of-arrays / CSR operator tables), enforced hill-climbing (EHC) with a best-first fallback, parallel grounding and parallel heuristic evaluation, plus an SGPlan-style partition-and-resolve mode, PDDL3 preference/metric optimization, and PDDL2.1 temporal planning (durative actions). It ships both a library (with a structured, JSON-serializable API) and the ff command-line binary — a drop-in for Metric-FF's ff -o domain -f problem.

On classical and ADL benchmarks it runs within ~1.4× of the heavily-optimized C Metric-FF (EHC reaches goals in dozens of evaluations, not thousands); numeric trails and IPC-5 preference quality is competitive-not-winning — see Benchmarks.

Status: v0.22.0ferroplan, ferroplan-cli and ferroplan-mcp are on crates.io. APIs may shift before 1.0.

What's new in 0.22.0 — the coverage cycle, and the re-entries that ran hot. 58% coverage across 16 IPC boards (2,867/4,916), 373 certified optima — up from 53% across 13 boards last cycle. On the thirteen boards comparable to 0.21, coverage moves 2,153 → 2,248 (+95), the floor of this cycle's own ambition band; three long-dormant boards re-entered (propositional, net-benefit, constraints) and overshot expectations by a wide margin — net-benefit reaches 92%, the strongest board this cut. On the IPC-6 (2008) boards, ferroplan's raw coverage now clears the official 2008 track winners outright: 284/300 vs LAMA's 281/300 on seq-sat, 150/270 vs Gamer's 134/270 on seq-opt. Two boards moved backward and are named, not netted away (2014 seq-agile −1, 2014 tempo-sat −3). New this cut: docs/ipc-rankings.md, a rough per-year, per-track field placement against the actual IPC competitions. Full record: docs/roadmap-0.22.md.

What's new in 0.21.0 — the numeric cycle, and the ladders that pay their own way. The sailing wall is down: sailing-numeric was 0/20 in both prior releases — named in 0.20 as "a genuine numeric-reachability wall" and deferred — and is now 19/20, with block-grouping and pathwaysmetric off zero for the first time too. The temporal debt carried since 0.18 is paid: map-analyzer's three VAL-RED rows go green, and the twelve boards now carry zero VAL failures. The −26 regression the v0.19 backfill exposed in 0.20 is repaired and overshot — rung budgets are wall-denominated instead of fixed-pop, so novelty-light keeps its visit-all win while the searches it was starving come back. The optimal ladder learns the clock: a root informativeness gate decides whether LM-cut earns the remaining wall, taking LM-cut proofs from 13 to 53 and putting scanalyzer and parc-printer in motion for the first time. Against 0.19 re-measured on the same machine, the twelve comparable boards go 1,943 → 2,132 (+189); standings 53% across 13 boards, 354 certified optima. Two boards stay behind and are named rather than netted away (tempo-sat −3, 2014 seq-opt −6, all city-car). Every board here carries its own measured conditions. Full record: docs/roadmap-0.21.md.

Earlier releases are summarised in the changelog and its archive.

Features

  • EHC + best-first — enforced hill-climbing with helpful actions (the FF speed default), falling back to weighted best-first when it stalls. Selectable per solve (--search auto|ehc|best-first|…).
  • FF heuristic — delete-relaxation relaxed-plan heuristic over a data-oriented task, deferred evaluation, tunable g/h weights.
  • Data parallelism — parallel grounding and parallel batch heuristic evaluation (std::thread); the plan found is identical for any thread count.
  • PDDL coverage — STRIPS, typing, negative/disjunctive preconditions, numeric fluents (Metric-FF style), ADL (conditional effects, forall/exists, equality), and derived predicates / axioms (:derived, static/stratified — closed into the initial state via a datalog fixpoint).
  • PDDL3 preferences — soft goal preferences (incl. forall-quantified and precondition preferences) compiled away, with anytime branch-and-bound metric optimization. (Exact-optimal on small/medium instances; best-found, flagged, on the largest — see Limitations.)
  • PDDL2.1 temporal:durative-actions with at start/over all/at end conditions & effects, constant or parameter-dependent durations, and required concurrency, via a decision-epoch forward search; output in the IPC temporal plan format (t: (action) [dur]) with a makespan.
  • SGPlan-style partitioning — an optional partition-and-resolve mode.
  • Robust — a published library shouldn't crash: malformed/pathological PDDL (incl. deeply-nested forms) returns a typed error, never a panic.
  • Structured output — the library returns typed, serde-serializable results; the CLI emits classic FF text or JSON.

GUI

ferroplan-bevy is a Bevy app that visualizes a domain+problem as a typed graph, animates the plan, and edits both problems and domains in a Blockly-style block editor (cargo run -p ferroplan-bevy).

ferroplan-bevy visualizing a delivery problem as a typed graph

Install / build

# install the `ff` CLI from crates.io
cargo install ferroplan-cli    # puts `ff` on your PATH

# …or build from a clone
cargo build --release          # produces target/release/ff
cargo run --release --bin ff -- -o domain.pddl -f problem.pddl

As a library dependency: cargo add ferroplan (see Library below).

CLI (ff)

# drop-in: classic Metric-FF text output
ff -o domain.pddl -f problem.pddl

# structured JSON solution
ff -o domain.pddl -f problem.pddl --json

# pick a mode / search strategy
ff -o domain.pddl -f problem.pddl --mode partition
ff -o domain.pddl -f problem.pddl --search best-first --weight-h 3

# temporal (durative actions) — auto-detected; prints the IPC temporal plan
ff -o temporal-domain.pddl -f problem.pddl --mode temporal

# decompose a too-big temporal goal into ordered, individually-solved contracts
# (the "LLM authors, planner decomposes" bet, made inspectable — text or --json)
ff -o temporal-domain.pddl -f problem.pddl --mode temporal --decompose

# self-contained JSON job: {"domain": "...", "problem": "...", "options": {...}}
ff --json-request job.json

Run ff --help for all flags (--search, --weight-g/--weight-h, --max-evaluated, --satisfice, --threads, …).

Library

use ferroplan::{solve, Options};

let domain  = std::fs::read_to_string("domain.pddl")?;
let problem = std::fs::read_to_string("problem.pddl")?;

// Syntax-check before solving (no grounding/solving) — fast authoring feedback.
let report = ferroplan::parse(&domain);
assert!(report.ok, "{:?}", report.error);

let solution = ferroplan::solve(&domain, &problem, &Options::default())?;
if let Some(plan) = solution.plan {
    for step in &plan.steps {
        println!("{} {}", step.action, step.args.join(" "));
    }
    println!("metric: {:?}", plan.metric);
}
# Ok::<(), ferroplan::SolveError>(())

The public, serde-serializable surface: solve (plan a domain+problem), decompose (split a too-big temporal goal into validated contracts), parse (syntax-check + summarize PDDL without solving), Session (ground once, replan many — for a live loop that re-solves the same world every tick), and plan::validate_plan (independently check a plan). See examples/ for solve, parse, json_api, and replan (Session vs. re-solving from scratch, with timings).

Configuration

Every solver knob lives on one Options struct (library-first, serde- serializable). The CLI flags and JSON job options map to the same fields; omitted JSON fields fall back to the defaults shown.

ferroplan::solve(&domain, &problem, &ferroplan::Options {
    mode:            Mode::Auto,        // auto | ff | partition | pddl3 | temporal
    search:          Search::Auto,      // auto | ehc | best-first | ehc-then-best-first
    helpful_actions: true,              // helpful-action pruning (EHC)
    weight_g:        1.0,               // best-first path-length weight
    weight_h:        5.0,               // best-first heuristic weight  (1·g + 5·h)
    threads:         0,                 // 0 = auto
    max_evaluated:   None,              // search node cap
    optimize:        true,              // PDDL3: optimize metric vs. satisfice
    ..Default::default()                // every field is optional
})?;

CLI equivalents: --mode, --search, --no-helpful, --weight-g/--weight-h, --max-evaluated, --satisfice, --threads. Via JSON: {"domain": "...", "problem": "...", "options": {"search": "best-first"}}.

Workspace layout

crate what
ferroplan the library: engine + modes + solve / decompose / Session API
ferroplan-cli the ff binary (clap + JSON)
ferroplan-mcp an MCP server exposing solve / validate / decompose over stdio — so an LLM agent can author PDDL and drive the planner
ferroplan-bevy Bevy app: visualize, inspect & animate a domain+problem (cargo run -p ferroplan-bevy [domain.pddl problem.pddl])
ferroplan-wasm WebAssembly binding behind the client-side browser demosolve a domain+problem entirely in-page
ferroplan-py Python binding (pip-installable extension module) exposing solve for embedding in Python tools

Examples

examples/ collects worked domains that exercise the full feature set — see the examples index for a feature-by-feature map and a suggested reading order. Highlights:

  • rpg — the clean intro: durative actions with renewable (workers) and consumable resources, gather → craft → build.
  • rpg-world — a ~120-action crafting/economy domain (durative actions, numeric resources, renewable capacities, a reachability axiom) with a corpus of validated contracts, a flavor-×-scale suite/, an adversarial hard/ batch, and an industrial-city showcase that runs a whole metal/stone/wood industry as a pipeline of contracts.
  • cabin — deep numeric build plus a durative "crew" twin (makespan vs. crew size, skill-gated scheduling).
  • reachability — the worked derived-axiom (:derived) example: static transitive-closure reachability.
  • village — a full-ADL stress test (when, forall+when, or, negation) over durative + numeric state.
  • villagers — a data-driven recipe planner with numeric PDDL3 metric optimization; the "embed in a game" model.
  • logistics — transshipment: per-location goods, trucks with capacity, a train line.
  • jobshop — scheduling with machine-exclusion (scales to 100 concurrent jobs).
  • BORDERS.md — a measured map of where one-shot planning solves vs. where a goal must be decomposed into contracts. The decompose API / ff --decompose acts on that border: it splits a too-big temporal goal into ordered, individually-solved contracts and stitches them into one validated plan (e.g. hard/order-8 → 8 named contracts), falling back to a monolithic solve when a goal can't be split.

Benchmarks

ferroplan measures itself against three International Planning Competitions — IPC-5 (2006), IPC-6 (2008), IPC-7 (2011) — every deterministic satisficing track, at standard budgets with every plan VAL-validated. The one honest table per competition (generated by benchmarks/standings.py, refreshed each cut): benchmarks/ipc-standings.md — also rendered as the book's Standings chapter. Highlights: IPC-5 preference tracks are reference-scored from the vendored official archive — on the qualitative track ferroplan beats SGPlan5, the competition winner, 24–10 with 4 ties, winning rovers, storage, and tpp outright — and the IPC-7 sequential multi-core track is entered under competition wall-clock rules.

Classical and ADL coverage/speed are additionally measured against the C Metric-FF over a vendored subset. Headline (native Metric-FF, EHC default):

category ferroplan solved speed vs Metric-FF
STRIPS 40/40 0.71× (~1.4× slower)
ADL 23/24 0.77× (~1.3× slower)
numeric 36/40 0.22×

Per-board detail: IPC-5 preferences benchmarks/ipc5-scoreboard.md / benchmarks/ipc5-qualitative-scoreboard.md; classical/numeric detail: benchmarks/results.md (and the project site). The comparison oracles are not bundled (GPL / non-commercial licences) — reproduce per benchmarks/COMPARING.md.

Profiling & perf tracking: PROFILING.md — a deterministic metrics harness (benchmarks/perf.py run/compare against a committed baseline, so improvement/regression is measurable across machines) plus the samply / flamegraph / criterion-baseline workflow for finding and tracking hotspots.

Limitations

  • Numeric trails Metric-FF: EHC's helpful-action lookahead stalls on some numeric domains and falls back to (complete, slower) best-first.
  • IPC-5 preferences: compiled away, then optimized by an exact-closure metric optimizer with anytime sweeps, a diversified restart ladder, and the deterministically-budgeted ESPC penalty loop — all defaults. Coverage is full (48/48) on the vendored simple-preferences suite and ferroplan leads SGPlan5 under both quality conventions on three of the six domains (openstacks, storage, rovers), with trucks ahead on totals — see the scoreboard. The tpp/pathways p05–p08 tails still trail (best-found, flagged not proven optimal, measured direction-bound); the design record for the remaining work is in docs/espc-preferences-spec.md and docs/roadmap-0.5.md.
  • PDDL3 trajectory constraints ((:constraints ...)): the six untimed modal operators (always, sometime, at-most-once, sometime-after, sometime-before, at end) are enforced on the classical path — compiled into monitor automata and cross-checked by the independent verifier. Hard constraints latch a forced-terminal END action (linear in monitors — the 0.8 construction; goal-side compilation via FF_NO_TRAJ_END=1); soft (preference name ...) constraints are priced through the PDDL3 metric machinery like native goal preferences (the IPC-5 qualitative-preferences suite is vendored and scored against the official IPC-5 field: ahead of SGPlan5, the track winner, 24W/4T/10L overall, winning three of five domains outright — see benchmarks/ipc5-qualitative-scoreboard.md). The timed operators (within, hold-during, hold-after, always-within) and the temporal path are still rejected by name rather than silently dropped (FF_CONSTRAINTS_REJECT=1 restores the pre-0.7 blanket rejection).
  • Temporal: durative actions with constant, parameter-dependent, or state-dependent durations and required concurrency are supported, and every solved plan on the full IPC-2008/2011 tempo-sat corpus is VAL-validated (399/630 at 30 s, 399/399 valid — see benchmarks/ipc67-temporal.md). Coverage on the remainder is search-limited: the recorded walls (machine-shop, storage, model-train) are guidance problems, not semantics — and since the 0.14 extension, over all invariants are enforced on every happening, with object-symmetry orbits collapsing interchangeable-object state blowups (match-cellar 10/20 → 20/20, turn-and-open off zero). Duration inequalities ((>= ?duration L) / (<= ?duration U) / and ranges) are supported — the search commits to the shortest feasible duration — as are timed initial literals ((at <time> <literal>) in :init) and ?duration inside numeric effect expressions (duration-dependent effects). Continuous (#t) effects are not yet supported.
  • Derived predicates (:derived): static/stratified axioms are supported (closed into the initial state); dynamic derived predicates (bodies over changing facts) are not yet.

Acknowledgments

This project is built in deep respect for the planners that came before it.

SGPlan (SGPlan5 / SGPlan6), by Chih-Wei Hsu and Benjamin W. Wah at the University of Illinois, has been the standard to beat in this corner of automated planning for the better part of two decades — the IPC-winning system whose constraint-partitioning and extended-saddle-point penalty-coordination ideas still define the state of the art for satisficing planning with preferences and with temporal/resource constraints. I've followed that line of research for many years, and to build something that even comes close to it on a slice of the benchmarks is, genuinely, an honor. Enormous credit to that team for the depth, rigor, and sheer durability of the work — ferroplan is in no small part an attempt to learn from it, in Rust.

Equal thanks to Jörg Hoffmann's FF / Metric-FF, whose relaxed-plan heuristic and enforced hill-climbing are the backbone of this engine; to the IPC organizers and domain authors whose benchmarks make progress measurable; and to Derek Long and Maria Fox's VAL, used here to independently validate the temporal plans.

Thanks also to Sean Chatman, whose downstream fork drives ferroplan as the deterministic core of a Claude Code agent control plane, and in doing so put real pressure on the MCP and library surfaces. The optional schema feature (typed JSON Schema for Options/Mode/Search instead of an opaque Value) and the wasm set_timed_fact / world_bytes / mind_bytes bindings came from that work; his stateful-session MCP server is the design we're measuring our own against.

License

Dual-licensed under either of MIT or Apache-2.0, at your option.

from github.com/hhh42/ferroplan

Установка Ferroplan

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/hhh42/ferroplan

FAQ

Ferroplan MCP бесплатный?

Да, Ferroplan MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Ferroplan?

Нет, Ferroplan работает без API-ключей и переменных окружения.

Ferroplan — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Ferroplan в Claude Desktop, Claude Code или Cursor?

Открой Ferroplan на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Ferroplan with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории development