Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

xyz.pflow.sim/whatif

REMOTE · SIM.PFLOW.XYZ · SCANNED OCT 7

Conversational what-if simulation: build, diagnose and compare Petri-net models; CC0 catalog.

Available components

+2 this week 69 Trust /100

Recent critical change

Authorization (17 Sept 2026). See the changelog before you install this server.

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security57
Transport & Reachability100
Schema Quality & AI Usability76
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 19535 tokens (~348/item across 56 items; 55 tools + 1 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management67
  • Stability observed for 20 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
Tool Safety50
  • Injection-marker check failed: the description of parameter "system" on tool "sim_reroll" contains an instruction override, the text "override the original prompt", at byte 0 of that field, plus 1 further marker(s) of the same kind. See how to fix → Fail
  • All 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
  • An AI judge read all 56 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities60
  • Spec-recency check failed: implements MCP spec 2025-06-18; the latest is 2026-07-28. See how to fix → Fail
Install

How do I install the xyz.pflow.sim/whatif MCP server?

xyz.pflow.sim/whatif is a hosted endpoint at https://sim.pflow.xyz/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · sim.pflow.xyz

# add to Claude Code
claude mcp add --transport http xyz-pflow-sim-whatif 'https://sim.pflow.xyz/mcp'
// .cursor/mcp.json
{
  "mcpServers": {
    "xyz-pflow-sim-whatif": {
      "url": "https://sim.pflow.xyz/mcp"
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "xyz-pflow-sim-whatif": {
      "type": "http",
      "url": "https://sim.pflow.xyz/mcp"
    }
  }
}
# ~/.codex/config.toml
[mcp_servers.xyz-pflow-sim-whatif]
url = "https://sim.pflow.xyz/mcp"
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "xyz-pflow-sim-whatif": {
      "type": "remote",
      "url": "https://sim.pflow.xyz/mcp",
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add xyz-pflow-sim-whatif --url 'https://sim.pflow.xyz/mcp' --transport streamable-http
# ~/.hermes/config.yaml
mcp_servers:
  xyz-pflow-sim-whatif:
    url: "https://sim.pflow.xyz/mcp"
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "xyz-pflow-sim-whatif": {
      "Transport": "http",
      "Url": "https://sim.pflow.xyz/mcp"
    }
  }
}
# add to Vellum
assistant mcp add xyz-pflow-sim-whatif -t streamable-http -u 'https://sim.pflow.xyz/mcp'
// mcp.json
{
  "mcpServers": {
    "xyz-pflow-sim-whatif": {
      "type": "http",
      "url": "https://sim.pflow.xyz/mcp"
    }
  }
}

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 7 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 57 to 67. That category is still filling its 30-day observation window: 17 days of observed history at the previous scan, 20 at this one. The score rises as the window fills, whether or not the server changes.

  • 4 Oct 26 +1
    • Tool “sim_run_pipeline” rewrote its description, which is the text the model reads security
  • 3 Oct 26 0
    • New tool “sim_accept_migration”, which the server declares destructive security
    • New tool “sim_create_system”, which the server declares destructive security
    • New tool “sim_migration_offers”, which the server declares destructive security
    • New tool “sim_system”, which the server declares destructive security
    • Tool “sim_bind” rewrote its description, which is the text the model reads security
    • Tool “sim_check_witness” rewrote its description, which is the text the model reads security
    • Tool “sim_create_collection” rewrote its description, which is the text the model reads security
    • Tool “sim_edges” rewrote its description, which is the text the model reads security
    • Tool “sim_get_binding” rewrote its description, which is the text the model reads security
    • Tool “sim_link” rewrote its description, which is the text the model reads security
    • Tool “sim_neighbors” rewrote its description, which is the text the model reads security
    • Tool “sim_prove” rewrote its description, which is the text the model reads security
    • Tool “sim_query” rewrote its description, which is the text the model reads security
    • Tool “sim_reach” rewrote its description, which is the text the model reads security
    • Tool “sim_run_pipeline” rewrote its description, which is the text the model reads security
    • Tool “sim_supersede_model” rewrote its description, which is the text the model reads security
    • Schema quality: 239 → 346 ▼ functional
    • “sim_bind” added an optional parameter “convertFactor” cosmetic
    • “sim_bind” added an optional parameter “convertFrom” cosmetic
    • “sim_bind” added an optional parameter “convertTo” cosmetic
    • “sim_bind” added an optional parameter “delay” cosmetic
    • “sim_check_witness” added an optional parameter “reachResult” cosmetic
    • “sim_check_witness” added an optional parameter “refutation” cosmetic
    • “sim_prove” added an optional parameter “via” cosmetic
    • “sim_bind” reworded the description of “fromPort” cosmetic
    • “sim_bind” reworded the description of “toPort” cosmetic
    • “sim_bind” reworded the description of “transform” cosmetic
    • “sim_check_witness” reworded the description of “derivation” cosmetic
    • “sim_check_witness” reworded the description of “reach” cosmetic
    • “sim_prove” reworded the description of “predicate” cosmetic
    • “sim_reach” reworded the description of “from” cosmetic
    • “sim_reach” reworded the description of “system” cosmetic
    • “sim_reach” reworded the description of “to” cosmetic
  • 2 Oct 26 0
    • New tool “sim_check_witness”, which the server declares destructive security
    • New tool “sim_prove”, which the server declares destructive security
    • New tool “sim_query”, which the server declares destructive security
    • New tool “sim_reach”, which the server declares destructive security
    • Tool “sim_bind” rewrote its description, which is the text the model reads security
    • Tool “sim_canonical” rewrote its description, which is the text the model reads security
    • Tool “sim_classify” rewrote its description, which is the text the model reads security
    • Tool “sim_create_collection” rewrote its description, which is the text the model reads security
    • Tool “sim_edges” rewrote its description, which is the text the model reads security
    • Tool “sim_link” rewrote its description, which is the text the model reads security
    • Tool “sim_neighbors” rewrote its description, which is the text the model reads security
    • Tool “sim_supersede_model” rewrote its description, which is the text the model reads security
    • Schema quality: 196 → 239 ▼ functional
    • “sim_link” reworded the description of “object” cosmetic
    • “sim_link” reworded the description of “predicate” cosmetic
    • “sim_link” reworded the description of “subject” cosmetic
  • 30 Sept 26 +1
    • Tool “sim_calibrate” rewrote its description, which is the text the model reads security
    • Tool “sim_code_to_flow” rewrote its description, which is the text the model reads security
    • Tool “sim_compare” rewrote its description, which is the text the model reads security
    • Tool “sim_conformance” rewrote its description, which is the text the model reads security
    • Tool “sim_create_model” rewrote its description, which is the text the model reads security
    • Tool “sim_diagnose” rewrote its description, which is the text the model reads security
    • Tool “sim_distill” rewrote its description, which is the text the model reads security
    • Tool “sim_evaluate” rewrote its description, which is the text the model reads security
    • Tool “sim_link” rewrote its description, which is the text the model reads security
    • Tool “sim_optimize” rewrote its description, which is the text the model reads security
    • Tool “sim_param_heatmap” rewrote its description, which is the text the model reads security
    • Tool “sim_propose_types” rewrote its description, which is the text the model reads security
    • Tool “sim_publish” rewrote its description, which is the text the model reads security
    • Tool “sim_publish_app” rewrote its description, which is the text the model reads security
    • Tool “sim_publish_compare” rewrote its description, which is the text the model reads security
    • Tool “sim_receipt” rewrote its description, which is the text the model reads security
    • Tool “sim_refine” rewrote its description, which is the text the model reads security
    • Tool “sim_run_pipeline” rewrote its description, which is the text the model reads security
    • Schema quality: 178 → 196 ▼ functional
    • “sim_bind” reworded the description of “transform” cosmetic
    • “sim_compare” reworded the description of “scenarios” cosmetic
    • “sim_crosscheck” reworded the description of “hours” cosmetic
    • “sim_diagnose” reworded the description of “hours” cosmetic
    • “sim_distill” reworded the description of “options” cosmetic
    • “sim_evaluate” reworded the description of “horizon” cosmetic
    • “sim_evaluate” reworded the description of “realizations” cosmetic
    • “sim_optimize” reworded the description of “hours” cosmetic
    • “sim_optimize” reworded the description of “samples” cosmetic
    • “sim_optimize” reworded the description of “seed” cosmetic
    • “sim_param_heatmap” reworded the description of “hours” cosmetic
    • “sim_param_heatmap” reworded the description of “range_x” cosmetic
    • “sim_param_heatmap” reworded the description of “range_y” cosmetic
    • “sim_propose_types” reworded the description of “limit” cosmetic
    • “sim_propose_types” reworded the description of “realizations” cosmetic
    • “sim_publish” reworded the description of “scenario” cosmetic
    • “sim_publish_compare” reworded the description of “scenarios” cosmetic
    • “sim_receipt” reworded the description of “scenario” cosmetic
    • “sim_run_pipeline” reworded the description of “realizations” cosmetic
    • “sim_scenario” reworded the description of “scenario” cosmetic
  • 28 Sept 26 +1
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 25 Sept 26 +1
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 23 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 9 Oct 2026 · Probed https://sim.pflow.xyz/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=sim.pflow.xyz CN=WR3,O=Google Trust Services,C=US 1 Oct 2026 30 Dec 2026 RSA 2048 SHA256-RSA feaa8ca4234680401049f2e85024e248
SANs: sim.pflow.xyz
CN=WR3,O=Google Trust Services,C=US (CA) CN=GTS Root R1,O=Google Trust Services LLC,C=US 13 Dec 2023 20 Feb 2029 RSA 2048 SHA256-RSA 7ff005a91568d63abc22861684aa4b5a
CN=GTS Root R1,O=Google Trust Services LLC,C=US (CA) CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE 19 Jun 2020 28 Jan 2028 RSA 4096 SHA256-RSA 77bd0d6cdb36f91aea210fc4f058d30d

Background: What to check on a remote MCP endpoint →

DNSSEC insecure

Validation of sim.pflow.xyz. — Not signed

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
xyz. present 3599, 18130 8, 8 Verified
pflow.xyz. absent Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation
Authentication No authorisation required

The endpoint answered without asking for a token. Anyone who knows the URL can reach it.

Result No authorisation required
HTTP status 200

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://sim.pflow.xyz/mcp Verified 200
http (plaintext) http://sim.pflow.xyz/mcp HTTPS enforced 302 https://sim.pflow.xyz/mcp
MCP tools · 55 exposed · ~19,475 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
sim_accept_migration ~331

Carry offered taxonomic edges of a superseded model forward to its current successor. edges lists 1 to 25 edge ids that sim_migration_offers(model) offered; pass successor (the current it returned) so a different current successor — a re-point or a chain that grew since — is refused rather than followed. Every edge is checked before anything is written (it must touch model, be offered, pass sim_link's check, you must own model or have authored the edge, and the edge it becomes must pass its predicate's write rule for you — hasMember only for the collection's owner); one failure refuses the call and writes nothing. Each accepted edge is written on the successor attributed to you, with no timestamp, plus a migratedFrom edge from it to the old edge (provenance; sim_edges(<new edge>) shows it, and sim_query closure over migratedFrom traces it back across several supersessions). The old edge stays. Re-running converges on the same ids; an edge you already linked the same way is reused (existing: true, keeping its own timestamp). A call stopped after some edges were written says which were and which were not. Needs sign-in with write scope (opens OAuth the first time); MCP only. Costs 1 compute token per call.

NameTypeReqDescription
edgesarrayyes1 to 25 edge ids sim_migration_offers(model) offered
modelstringyescontent id of the superseded model
successorstring–the current successor sim_migration_offers returned; a different current successor now is refused

No output schema declared.

No examples provided.

sim_bind ~929

Record a checked connection between two stored models' declared ports, fromModel's fromPort (a place tagged port.output) feeding toModel's toPort (a transition tagged port.input), as a content-addressed Binding (ROADMAP.md Phase 9/11f). Checked now, by the same binds-port-v1 rule sim_run_pipeline applies: both ports exist with the right direction and element kind, the output is a token place, the input is not a delayed transition, the declared kinds are equal, port.unit agrees exactly where both ends declare one (a unit missing on either end is reported unchecked, never agreed), and a numeric transform is at most 1000000. Differing units bind only with a declared conversion, never inferred from the unit names ("order" and "orders" are two units): pass convertFrom, convertTo and convertFactor together (1 convertFrom = convertFactor convertTo), checked by binds-port-v2 — both ports declare port.unit, the two differ, convertFrom and convertTo are exactly those units, the factor is between 1e-06 and 1000000, and the transform times the factor is at most 1000000; sim_run_pipeline multiplies the resampled rate by the transform and then by the factor. A binding without a conversion is checked by binds-port-v1 exactly as before and keeps its id. A delay (hours, in (0, 10000]) is checked by binds-port-v3 (v2 plus check 12: a finite number in range; 0 is no delay and keeps the binding's id): the target receives the source's flow that many hours later and runs on its own declared rate before then, and a loop between models runs only through a binding that declares one. A self-binding is refused, with or without a delay: a model driving its own input is a loop inside one net, built with sim_extend. Set-level checks (a loop with no delayed binding, two bindings into one input, the schedule-segment cap, a loop over 4 models) belong to sim_run_pipeline and sim_create_system; a binding that closes a loop with bindings already stored is not refused here, since a loop exists only in…

NameTypeReqDescription
convertFactornumber–how many convertTo one convertFrom is (1 convertFrom = convertFactor convertTo), between 1e-06 and 1000000; sim_run_pipeline multiplies the resampled rate by it, after any numeric transform
convertFromstring–a declared unit conversion's source unit: exactly fromPort's port.unit. Pass convertFrom, convertTo and convertFactor together or none of them
convertTostring–a declared unit conversion's target unit: exactly toPort's port.unit, which must differ from fromPort's
delaynumber–hours after the source's flow that toPort receives it, in (0, 10000]; default unset, no delay. Before the delay ends toPort runs on its own declared rate. A loop between models runs only through a bi…
fromModelstringyesid of the model supplying the connection's output
fromPortstringyeselement id of the declared output port on fromModel: a token place tagged port.output (see GET /api/models/{id}/ports)
toModelstringyesid of the model receiving the connection
toPortstringyeselement id of the declared input port on toModel: a rated transition tagged port.input
transformstring–how fromPort's value becomes toPort's. A plain non-negative number is applied by sim_run_pipeline as a scale factor on the resampled rate; it scales, never converts a unit. Any other text (a unit not…

No output schema declared.

No examples provided.

sim_calibrate ~457

Calibrate a model against YOUR event log — the reading that meets reality. Upload CSV (case_id, activity, timestamp; the shape sim_dataset emits, activities = transition ids), and rates are learned from the observed timings: sources from inter-arrival times, services from the gap before their completions, all per hour. Instant-pickup transitions (declared rate >= 100) keep their declared rate — their observed gap is the queue wait, and learning it would destroy the calibration discipline. A transition declaring a delay (a fixed-duration timer, not a rate) is fit differently and returned in learnedDelays instead of learnedRates: the MEDIAN observed gap, in hours, written onto the transition itself since a delay has no solver-map slot — a gapCV in rateEvidence far from 0 means the log looks exponential, not fixed, and the calibration says so in a caveat rather than trusting the median anyway. Returns a NEW content-addressed model (learned rates in the solver map, learned delays on the transitions, declared values otherwise untouched, lineage recorded) plus a conformance report: fittingPercent (full replays) is the headline, worst traces named with the activities that could not fire. tokenFitness is a second, harsher reading of the same replay (raw tokens present vs. required at every step, not full-trace success) that under-reads any net with a resource pool — read fittingPercent, not tokenFitness, unless you specifically want the raw-token number. Every learned rate or delay has an entry in rateEvidence: n (gaps it rests on), gapCV (sample std dev over mean of those gaps; ~1 for exponential timings, near 0 for a true timer) and insufficient when n < 2 — n=0 yields nothing, n=1 a value with no spread. Learned values on a structure that cannot replay the traces would be numerology — read fittingPercent before trusting them. Costs 3 tokens from your account's compute bucket (a replay of the log, 2, and the stored model, 1).

NameTypeReqDescription
idstringyesmodel id to calibrate
logstringyesthe event log, as CSV text

No output schema declared.

No examples provided.

sim_canonical ~310

Tell whether two differently-labelled models are actually the same net: an isomorphism-invariant id computed from the model's EXACT automorphism orbits (orbits.go), not the colour-refinement (WL) kind sim_classify falls back to when the exact search can't decide. Two models differing only by renaming places or transitions share the same canonicalId even though their content-addressed ids (from sim_get_model) differ — this is the id to compare, not the model id, when checking whether a catalog already holds this net. Also returns the non-trivial automorphism orbits and generator count the id was computed from: zero generators means the net is rigid (no symmetry at all), which is itself a fact about the net's structure. Refuses (as a tool error) when the exact search would spend more than its 1,000,000-step budget (refinement steps, about half a second) — too large or too symmetric for this implementation, per orbits.go — rather than silently falling back to a weaker answer; sim_classify's own fallback covers that case for classification specifically. Costs 1 compute token (one search), as GET /api/models/{id}/canonical does. Equal canonical ids mean the same net under the comparison sim_prove uses for isomorphicTo; to get the place/transition bijection and record it as a witnessed edge, call sim_prove(subject, "isomorphicTo", object).

NameTypeReqDescription
idstringyesmodel id

No output schema declared.

No examples provided.

sim_check_witness ~912

Re-check a stored structural witness against both stored models with the independent checker (pkg/morphism), which does no search. Given a structural edge's id, checks every witness of that edge; an edge with none answers unwitnessed (unproven, not disproved). Verdicts: valid, invalid (the map is not a morphism of the stored models), or uncheckable (a model was deleted, a net is malformed, or the predicate is now checked under a newer definition). Public: no sign-in. A witness or edge id is free (no compute tokens). With derivation (from sim_query): re-checks every step's witness, the chain, the composed map's digest and the composed map against both end models, and answers {verdict, reason, hops} (the body POST /api/derivation/check returns); a derivation naming a definition other than the predicate's current one is uncheckable; costs 1 compute token. With reach (a sim_reach answer): replays a trace through metamodel.Enabled/Fire and the guards, or re-checks an invariant witness against the stored model, answering {verdict, reason}; from and to are held to the scenario caps (1,000,000 per place, 4,000,000 in total), and a replay is priced before its first firing and is uncheckable over 200,000,000 work units; an exhaustive no is uncheckable (re-run sim_reach); an unknown answer is refused; costs 1 compute token (POST /api/reach/check). With reach on a system's answer, via is re-checked whole with it: the system is stored and holds the net, every other model has exactly one embedding, each embedding's witness or derivation re-checks valid now, and any translation of component places follows them. With reachResult (the result id sim_reach returns): re-checks a stored answer end to end — the record (its bytes hash to its id, its stored question asks what the answer answers under the budgets it records, and over names what it rests on), via as above, and the witness — answering {verdict, reason, parts, answer, currency}; an unknown answer stays unknown (its witness pa…

NameTypeReqDescription
derivationstring–a sim_query derivation as a JSON string: {"predicate", "definition", "subject", "object", "steps": [{"edge", "witness", "inverse"}], "composed"}
idstring–a witness id, or a structural edge's relation id
reachstring–a sim_reach answer as a JSON string: the object exactly as returned, serialized
reachResultstring–the content id of a stored sim_reach answer (sim_reach's result)
refutationstring–a refuted sim_prove answer's refutation as a JSON string: the object exactly as returned, serialized ({"predicate", "subject", "object", "counterexample"})

No output schema declared.

No examples provided.

sim_classify ~252

Discover the parameter classes of a stored model and return them as JSON-LD with empty annotation slots for you to fill in (label, comment, unit, domain, substitutes — nothing else; membership/kind/evidence are derived and settled by measurement, not yours to edit). With verify=true a shared colour is checked by exact automorphism proof where the search can decide it (settling interchangeability outright, the stronger claim), falling back to the sampled permutation experiment only where it can't — the exact search refuses past its 1,000,000 refinement-step budget on nets too large or too symmetric for it. Read the sim://docs/classification resource once for the colour-refinement caveat and the annotation contract in full.

NameTypeReqDescription
idstringyesmodel id
inline_contextboolean–embed the full JSON-LD @context map in the result instead of the URL it is served from (https://sim.pflow.xyz/ns/v1/context). Default false: the URL resolves to the identical map, so only set this fo…
verifyboolean–run the permutation experiment (costs simulation; default false, and classes then say they are candidates)

No output schema declared.

No examples provided.

sim_code_to_flow ~179

Derive a Petri-net model from source code with the configured LLM (control flow, state machine, resources or concurrency focus), validate it, and store it as a NEW model you own. Runs generator.CodeToFlow directly — this tool is its only surface on sim.pflow.xyz, which mounts no code-to-flow HTTP endpoint; refused when this deployment has no LLM provider configured. Returns the new id when the answer validates, otherwise the raw model JSON and the validation errors so you can fix and sim_create_model it by hand.

NameTypeReqDescription
codestringyessource code to analyse
focusstring–control-flow (default), state-machine, resources or concurrency
languagestring–source language hint, e.g. go, python, javascript
namestring–name for the derived model

No output schema declared.

No examples provided.

sim_compare ~347

Run several scenarios against one model on one shared seed and return them side by side — the seed sharing is server-enforced, so differences are the scenarios, not the dice. Returns a summary by default (finals, throughput/mean/P95 metrics, contention, depletion — no time series); pass full=true for the complete trajectories, which run to hundreds of KB. A scenario carrying "summary": true stays summarized even under full=true, so one comparison can chart some scenarios and only read the rest. Unset hours default to 8, samples to 60 (the trajectory grid, which only matters under full=true — metrics are time-weighted and do not depend on it) and realizations to 16 per scenario. Each scenario can set its own "engine" (see sim_scenario / docs/engine-selection.md); comparing an "ode" run against an "ssa" one is legitimate but the shared seed only removes dice from scenarios using the same engine. Costs 1 token per scenario from the compute bucket (per address, or per account when signed in).

NameTypeReqDescription
fullboolean–include the sample-grid time series in every result (large; default false); a scenario with its own "summary": true is left summarized regardless
idstringyesmodel id
scenariosstringyesJSON array of at most 20 scenarios, each with a name, e.g. [{"name":"today","hours":8},{"name":"one more","hours":8,"marking":{"staff/available":3}},{"name":"bigger batches","hours":8,"params":{"batc…

No output schema declared.

No examples provided.

sim_components ~87

List the component registry: pre-baked subnet templates (arrivals, service, hazard, inventory, decision, mailbox, datastore) with the calibration discipline baked into the arcs and rates. Each entry names its ports (places you can attach onto existing places), its params with recommended defaults, and the discipline notes explaining WHY the template is shaped the way it is. Compose them with sim_compose.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

sim_compose ~245

Instantiate a registry component into a model and store the result as a NEW content-addressed model you own (lineage recorded when composing onto an existing id). Omit id to start a model from the component alone; pass attach to fuse a component port onto one of the model's existing places (e.g. attach {"queue": "tickets_queue"} wires a hazard onto the service's queue). Prefix namespaces the created elements (defaults to the component name). Three calls build a working helpdesk: arrivals, then service attached to its queue, then hazard attached to the same queue — the result passes diagnose because the discipline is in the template.

NameTypeReqDescription
attachstring–JSON object mapping port name -> existing place id
componentstringyesregistry component name (see sim_components)
idstring–model to compose onto; omit to start fresh
namestring–model name for the stored result (kept from the base when composing onto an id)
paramsstring–JSON object overriding param defaults, e.g. {"staff": 3}
prefixstring–instance prefix for created elements (default: component name)

No output schema declared.

No examples provided.

sim_conformance ~186

Check how well a stored model matches an observed event log WITHOUT rewriting its rates — the read sim_calibrate bundles into calibration, offered on its own and in full: fitness (can the model replay each case?), precision (does it allow behaviour never observed?), generalization and simplicity, with per-trace diagnostics naming the activities that could not fire. Log is CSV (case_id, activity, timestamp; the shape sim_dataset emits, activities = transition ids). The log is replayed one case at a time from the model's initial marking, so the model should be the per-case workflow; a resource net whose places are shared across cases will not fit. Caveats name what the analysable net encoded lossily. Costs 2 tokens from your account's compute bucket.

NameTypeReqDescription
idstringyesmodel id
logstringyesthe event log, as CSV text

No output schema declared.

No examples provided.

sim_conformance_stream ~435

Online conformance: replay an ORDERED event stream against a stored model and get a running verdict — does the model still match, or which event was the first that did not, and why. Unlike sim_conformance (whole finished cases, aggregate fitness) the order of events IS the stream's order, cases may interleave, and the answer names the first non-conforming event: its position, case, activity, whether the activity is unknown to the model or the transition was not enabled, the places that blocked it (need vs have), the case's marking just before it, and `repair` — the shortest unobserved transitions that would have enabled it (a local alignment of that one step, bounded; absent when none is found within repairDepth). This is token replay, not trace alignment. A divergent event is force-fired so the case resynchronises and later events are judged on their own. fitness is conforming events / events; tokenFitness is 1 - missing/consumed tokens. Give the stream as `events` (JSON array of {case, activity, timestamp?}) or `log` (CSV with a case_id, activity header, timestamp optional; rows are taken in the order given, not sorted). Activities are transition ids. Each case replays from the model's initial marking, so the model should be the per-case workflow; guard expressions are not evaluated and timestamps are not checked against delays (caveats says so). keepSteps adds the per-event running signal. Costs 2 tokens from your account's compute bucket.

NameTypeReqDescription
eventsstring–JSON array of {"case": ..., "activity": ..., "timestamp": ...} in stream order
idstringyesmodel id
keepStepsboolean–include the per-event running fitness (one entry per event)
logstring–the stream as CSV text (case_id, activity[, timestamp]) in stream order; used when events is not given
repairDepthnumber–most unobserved transitions a repair may use (default 4; negative turns repair off)

No output schema declared.

No examples provided.

sim_create_collection ~256

Mint a named Collection you own and return its content id. A collection carries no member list of its own — a mutable list would change the collection's own id every time something joined it, the same reason Lineage lives beside a model rather than inside it. Add members with sim_link(collectionID, "hasMember", memberID) — members must be stored entities — and read them back with sim_neighbors(collectionID, "hasMember") or sim_edges(collectionID). Only you, the owner, may add members: hasMember's write rule is subject-owner (https://sim.pflow.xyz/ns/predicates/v1), so sim_link refuses anyone else, naming the rule. The name and your account together are the content id: creating a collection with a name you already used returns your existing id, and another account's collection with the same name is a different collection. A collection created before collections had owners has none, so its membership is frozen as it stands (still readable); create your own to add to. Members cannot be removed: an edge, once written, is immutable. Needs sign-in with write scope (opens OAuth the first time); costs 1 compute token.

NameTypeReqDescription
namestringyescollection name

No output schema declared.

No examples provided.

sim_create_model ~136

Store a Petri-net model (JSON with name/places/transitions/arcs) and return its content id. Models are immutable; a changed model is a new id. Structural validation rejects malformed nets with every reason at once. The model is yours: it appears only in your own listing until you dedicate it to the commons with sim_license_model, and you can remove it with sim_delete_model. Anyone you give the id to can use it either way. Needs sign-in (opens OAuth the first time); anonymous callers can POST /api/models over HTTP instead, stored unowned.

NameTypeReqDescription
modelstringyesthe model JSON

No output schema declared.

No examples provided.

sim_create_system ~912

Define a System (ROADMAP.md Phase 11f): a content-addressed, stored set of models and the bindings between them, so the catalog can answer questions about them together. Pass collection (snapshot its model and binding members now; other members are listed under skipped, and a grown collection is a new system, the old id still readable) or models and bindings (JSON arrays of ids), not both. Every binding's endpoints join the models (listed under implied); every binding must pass the check sim_bind applies now (binds-port-v1, or binds-port-v2 for one that declares a unit conversion, or binds-port-v3 for one that declares a delay, and the system then records bindingCheck binds-port-v2 or binds-port-v3, v3 first; a legacy binding sim_bind would refuse today is refused here) and the set must close no loop without a delayed binding, take each input port once, fit the schedule-segment cap and hold no loop over the model limit — the checks sim_run_pipeline applies before it knows the hours. At most 64 models and 64 bindings, and a snapshotted collection of at most 256 members. The id is the hash of the sorted lists, the name and the snapshotted collection (if any), so the same call gives the same id; a snapshot and an explicit list of the same ids are different systems. Returns the id and the view sim_system computes (checks, the structural edges among the models with up to 128 witnesses re-checked now, and the shape: one-net, pipeline, separate or unknown). This is not refines: a system's edges are isomorphicTo and subnetOf (embeds by wiring / is the same coloured net). refines (trace inclusion with transitions matched by id) and preservesInvariant (the object's P-invariants pull back along an embedding) are proved one pair at a time by sim_prove and are never walked by closure, since neither is declared transitive. For "what contains this pattern?" ask sim_query with closure: {"select":["?m"],"where":[{"subject":"<pattern id>","predicate":"subnetOf","object":"?m","mode":…

NameTypeReqDescription
bindingsstring–JSON array of binding ids sim_bind returned; their models are included automatically
collectionstring–a collection id whose model and binding members to snapshot (instead of models/bindings); at most 256 members; part of the id
modelsstring–JSON array of model ids, e.g. ["id1","id2"]
namestring–a name for the system (at most 256 bytes); part of its id

No output schema declared.

No examples provided.

sim_crosscheck ~191

Run every applicable READING of a model against the others and report agreement or divergence with the reason: discrete SSA means vs the continuous mean-field solve, algebraically derived conservation laws vs simulated means, and (for game-schema models) the closed-form incidence ranking vs rollouts vs exact search. Divergence is a finding, not an error — small-count mean-field gaps and the prior's threat-blindness are named as such. Trust is agreement between independent readings of one structure. Gated nets (read arc, inhibitor, reached capacity, guard) have no ODE reading to compare against at all — see docs/engine-selection.md for the four-rule decision behind which readings even apply.

NameTypeReqDescription
hoursnumber–horizon (default 8, max 168)
idstringyesmodel id
realizationsnumber–SSA runs averaged, max 200 (default 24)

No output schema declared.

No examples provided.

sim_dataset ~89

Generate a synthetic event log from a stored model (seeded SSA playout; case-per-arrival). Returns CSV. Deterministic: same id, same seed, same bytes.

NameTypeReqDescription
casesnumber–cases to generate (default 200, max 2000 over MCP)
idstringyesmodel id
seednumber–PRNG seed (default 1)

No output schema declared.

No examples provided.

sim_delete_model ~55

Delete a model you created. Refused for the curated catalog, for models you do not own, and for models already dedicated to the commons (a dedication is irrevocable).

NameTypeReqDescription
idstringyesmodel id to delete

No output schema declared.

No examples provided.

sim_diagnose ~422

Returns what one more of each resource (and a change in each rate) is worth to the outcome, each ranked against a measured noise floor — no fitness test to write. Also reports generic gates (mass balance, dormant sources, staffing knee, whether any knob binds), the parameter classes among the controls, and four structural readings needing no run (T-invariants, siphons/traps with deadlock witnesses, CTMC lumpability, constrained lumping). Pure read. Loss/success inference and objective framing can be corrected by tagging places or declaring simulation.objective — read the sim://docs/classification resource once for how to read influence and noise, the structural readings, and the corrections.

NameTypeReqDescription
hoursnumber–horizon per run (default 8, max 168)
idstringyesmodel id
inline_contextboolean–embed the full JSON-LD @context map in the result instead of the URL it is served from (https://sim.pflow.xyz/ns/v1/context). Default false: the URL resolves to the identical map, so only set this fo…
maxRealizationsnumber–bounds how far the adaptive default may escalate (default 200, the same ceiling an explicit realizations refuses above). Ignored once realizations is set. For a caller with its own latency budget, no…
realizationsnumber–runs averaged per measurement, max 200. Leave unset and the default ADAPTS: a 24-realization pilot that doubles while the baseline outcome sits inside its own noise floor, up to 200 (or maxRealizatio…
seednumber–seed shared by every run, so differences measure the knob and not the dice (default 7)

No output schema declared.

No examples provided.

sim_diff ~92

Structural difference between two stored models: places, transitions and arcs added or removed, and surviving elements whose numbers changed (initial, capacity, rate, stages, arc weight or kind). The readout for what a builder turn, a sim_extend or a sim_refine actually changed between two ids in a lineage.

NameTypeReqDescription
astringyesmodel id (before)
bstringyesmodel id (after)

No output schema declared.

No examples provided.

sim_distill ~425

Distill exact search into the play scorer: fit rate multipliers for named transition groups so play's rankings agree with exact minimax, on positions sampled by random self-play and labeled by search. This is TACTICAL calibration — the counterpart of sim_calibrate, which learns rates from an event log. The division of labor is deliberate (petri-pilot experiments/ode-minimax): structure carries the tactic, and no fitting of an unmodified net's rates can express what its final state cannot separate — declare the structural prior as transitions in the model (e.g. forced-reply copies of the plays, catalyzed by the opponent's pattern) and distill the magnitudes it introduced. Zero agreement improvement is a finding about the structure, not a failed fit. Read agreementBefore/agreementAfter, not the loss: the hinge loss can overstate failure while every argmax is right. At most 16 groups, each non-empty, and no transition in two groups; the estimated work (loss evaluations × candidate moves × realizations × horizon) must stay under a fixed cap, and an over-cap request is refused with the estimate. Costs 5 tokens from your account's compute bucket at the defaults, scaled by that work estimate (rounded up).

NameTypeReqDescription
groupsstringyesJSON object: group name -> transition ids sharing one fitted multiplier, e.g. {"detectors":["x_win_0","o_win_0"],"draw":["call_draw"]}
idstringyesmodel id (needs simulation.objective, players with turnPlace)
optionsstring–JSON: {"games":20,"positions":40,"iters":40,"horizon":3,"realizations":40,"seed":11,"engine":""} (the defaults shown; 0 or unset takes the default). Caps: games at most 100, positions at most 100, it…

No output schema declared.

No examples provided.

sim_edges ~200

List every relation touching an entity, as either subject or object. Answered from an index by subject and object; each call re-lists the store so edges written by other instances are seen. Legacy edges whose predicate predates the registry are included with axis "unregistered". Structural edges (isomorphicTo, subnetOf, preservesInvariant, refines) list the witnesses that prove them; one listing none is marked unwitnessed and proves nothing. An isomorphicTo edge is the same net up to renaming, not the same behaviour: its definition (coloured-net-v1) does not compare guards, stages, schedules, constraints, objectives or non-refine tags such as outcome — read the witness (GET /api/lineage/{witnessId}, whose notCompared lists what that pair carries; sim_check_witness re-checks it) before treating two models as behaving alike.

NameTypeReqDescription
idstringyesentity id to look up

No output schema declared.

No examples provided.

sim_evaluate ~241

Score a player's legal next moves with the PLAY method (the blog post's move picker): apply each candidate hypothetically and score the expected objective of the position it leads to, by seeded SSA rollouts (seed 11, shared across candidates so a difference measures the move, not the dice) — the best move scores highest. Needs the game schema (simulation.objective + simulation.players). The response names the engine. This tool always uses play on SSA: next-move elimination (rate-zero ablation, which reads an ungated net through the continuous ODE relaxation), the closed-form incidence reduction and exact search are the HTTP evaluate endpoint's method option (eliminate | incidence | search), not selectable here.

NameTypeReqDescription
horizonnumber–model time to explore ahead (default 3, max 10000)
idstringyesmodel id
markingstring–JSON object, sparse marking override (the position to evaluate from); default = the initial marking
playerstringyesplayer name from simulation.players
realizationsnumber–SSA rollouts per candidate move (default 40, max 200)

No output schema declared.

No examples provided.

sim_extend ~200

Apply structural edits to a stored model and store the result as a NEW model you own, with lineage back to the original — the same vocabulary the guided builder uses behind its interview, now callable directly. Operations (JSON array, each with "op"): add_place {id, initial}, add_transition {id, guard, event}, add_arc {from, to, weight, kinetic, type}, remove_place, remove_transition, remove_arc {from, to}, set_rate {id, rate}, set_initial {id, initial}, set_capacity {id, capacity}. The edited model is validated before it is stored; a set of operations that leaves the net malformed is refused with every reason, and nothing is written. Returns the new id, the operations applied, and the structural diff.

NameTypeReqDescription
idstringyesmodel id to edit
namestring–optional name for the edited model
operationsstringyesJSON array of operations

No output schema declared.

No examples provided.

sim_get_binding ~120

Fetch a stored Binding by id, with its check computed now (binds-port-v1; binds-port-v2 for a binding that declares a unit conversion, which is returned as convert; binds-port-v3 for one that declares a delay, returned as delay in hours): ok (with the unit verdict: agree, converted or unchecked), refused (a binding recorded before the check that sim_bind and sim_run_pipeline would refuse today, flagged legacy) or uncheckable (a model it names was deleted).

NameTypeReqDescription
idstringyesbinding id

No output schema declared.

No examples provided.

sim_get_model ~34

Fetch a stored model's full Petri-net JSON by id.

NameTypeReqDescription
idstringyesmodel id (content hash)

No output schema declared.

No examples provided.

sim_invariants ~162

Derive a model's full algebraic invariant structure: conservation laws (Farkas P-invariants — weighted place sums every run preserves, the arithmetic a trust panel should show), firing cycles (T-invariants, named per-cycle with a readable detail sentence, each tagged StructuralProof), and the siphon/trap report (every minimal siphon and trap found from the arc structure, plus deadlock witnesses — minimal siphons holding no tokens at this model's own initial marking, which proves every transition needing one permanently disabled). This is the same computation sim_diagnose's structural fields read from, not a lesser copy of it. Pure structure, no simulation; every claim holds for every trajectory from this initial marking.

NameTypeReqDescription
idstringyesmodel id

No output schema declared.

No examples provided.

sim_license_model ~158

Dedicate a model you created to the commons under CC0-1.0, CC-BY-4.0, CC-BY-SA-4.0. It then appears in every user's listing with the license shown, and the dedication is IRREVOCABLE — it cannot be changed or deleted afterwards, which is what makes it safe for others to build on. CC0-1.0 is the cleanest choice for a model: attribution terms are hard to honor for a net someone folds into a larger one.

NameTypeReqDescription
idstringyesmodel id to dedicate
licensestringyesone of CC0-1.0, CC-BY-4.0, CC-BY-SA-4.0

No output schema declared.

No examples provided.

sim_link ~557

Record a typed edge between two stored entities (models, prompts, artifacts, maps, collections, bindings, relations — not witnesses), using a registered predicate. sim_link writes these (subject → object): @type (model → a https://sim.pflow.xyz/ns/models/v1 type name); about (artifact/prompt/map/collection → model/collection/binding/system); broader (model/collection/system → model/collection/system); cites (any entity → any entity); closeMatch (model → model); hasMember (collection → any entity); related (model/collection/system → model/collection/system). from, to and feeds are recorded only by sim_bind, produced only by sim_prompt/sim_reroll, supersededBy only by sim_supersede_model, migratedFrom only by sim_accept_migration; narrower is broader read backwards and is never stored; structural predicates (isomorphicTo, subnetOf, preservesInvariant, refines) are recorded only by sim_prove, together with the witness that proves them. Each is refused here, naming the tool that records it (or the reversed call, for narrower). Subject and object must be stored entities of the kinds the predicate relates, passed by content id (for @type, the object is a /ns/models/v1 type name). Full definitions at https://sim.pflow.xyz/ns/predicates/v1. Distinct from the Lineage a model/prompt/artifact already carries, which is specifically derivation (parent -> prompt -> child). Who may write an edge is its predicate's write rule (writeRule in the registry): hasMember is subject-owner — only the collection's owner (who created it with sim_create_collection) adds members, and a collection created before collections had owners takes no new ones; every other predicate sim_link writes is any-signed-in, an assertion attributed to you. A refusal names the rule. Edges are immutable and are never retracted. Linking the same subject/predicate/object again as the same user — either direction for a symmetric predicate — is idempotent: it returns the existing relation's id (existing: true) rather…

NameTypeReqDescription
objectstringyescontent id of the stored entity the edge points to; for @type, a type name from https://sim.pflow.xyz/ns/models/v1
predicatestringyesone of @type, about, broader, cites, closeMatch, hasMember, related
subjectstringyescontent id of the stored entity the edge starts from

No output schema declared.

No examples provided.

sim_list_bindings ~19

List the content id of every stored Binding.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

sim_list_models ~71

List the models visible to you: the curated catalog, models dedicated to the commons (their entry carries the license), and your own (marked mine). Other users' undedicated models are not listed, but any model id works with every sim_* tool — an id someone shares with you is the model.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

sim_map_get ~30

Fetch a stored Map's key->value data by id.

NameTypeReqDescription
idstringyesmap id

No output schema declared.

No examples provided.

sim_map_list ~18

List the content id of every stored Map.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

sim_map_put ~96

Store a key->value lookup table as its own content-addressed entity — a generated parameter sweep, a rate table, a component registry, anything shaped as key->value rather than free text (an artifact) or a Petri net (a model). Returns its content id; the same data, even with keys inserted in a different order, returns the same id.

NameTypeReqDescription
datastringyesthe table as a JSON object

No output schema declared.

No examples provided.

sim_migration_offers ~476

List what happens to the edges of a superseded model. Taxonomic edges (hasMember, @type, broader, related, closeMatch, cites, about) are OFFERED: each row gives the edge as it would read on the model's current successor (followed through its supersession chain), whether sim_link's checks pass for it now (passes, refused, or unchecked when the store could not answer), any earlier migrations of it, and the sim_accept_migration call that accepts it. Nothing moves automatically, the old edge stays, and this read writes nothing: offers are computed on read and never stored. Tool-written edges (from/to/feeds, produced, supersededBy), structural edges (isomorphicTo, subnetOf, preservesInvariant, refines) and legacy unregistered predicates STAY with the old model, each with its reason; a structural row names its witnesses and the sim_prove call that would make a new edge for the successor. Stored systems naming the model are listed under systems (sim_system {naming}'s answer, at most 100 rows): a System names exact ids, so supersession changes none of them, and systemsNote names the sim_create_system call with the successor. A chain that cycles, runs past 64 hops, ends at a deleted model or reaches a model now owned by someone else is reported as such, with no target. Accepting needs you to own the superseded model or to have authored the edge, and the edge it becomes must pass its predicate's write rule for you, as sim_link would (hasMember: you own the collection); youMayAccept says whether you may, per edge, and writeRule says why not when only the write rule refuses. 100 edges per page (pass next as after); predicate narrows to one stored predicate (narrower is refused: pass broader). Needs sign-in with read scope (opens OAuth the first time); anonymous over HTTP as GET /api/models/{id}/migrations, with no youMayAccept. Costs 1 compute token per call.

NameTypeReqDescription
afterstring–the next value a previous call returned, for the following page
modelstringyescontent id of the superseded model
predicatestring–read only this predicate's edges

No output schema declared.

No examples provided.

sim_my_sheets ~22

List the sheets this user has published, with their URLs.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

sim_neighbors ~298

One-hop traversal from an entity, read through the predicate registry. With no predicate: the object of every relation where the entity is the subject. With a predicate: the entities one hop along it — for an inverse name that is never stored (narrower) the stored predicate is read backwards (the subjects of the broader edges pointing at the entity), and for a symmetric one (related, closeMatch) both directions count, since an edge recorded from the other end says the same thing. A legacy free-form predicate still answers from its stored edges; a name that is neither registered nor used by any stored edge is refused. Pass a collection's id with predicate hasMember to list its members. A structural neighbour (isomorphicTo, subnetOf, preservesInvariant, refines) is a bare id here: sim_edges lists the edge's witnesses, and isomorphicTo does not compare guards, objectives or outcome tags. Ordered by timestamp, then relation id: tool-recorded edges (from/to/feeds, supersededBy, and edges carried forward by sim_accept_migration, unless it reused one you had already linked) carry no timestamp, come first and are in no particular order among themselves, so the last supersededBy neighbor is not necessarily the current successor. Not de-duplicated.

NameTypeReqDescription
idstringyessubject id to traverse from
predicatestring–restrict to this predicate; omit for every outgoing relation

No output schema declared.

No examples provided.

sim_optimize ~255

Multi-objective optimisation over transition rates for a stored model: Monte Carlo samples the rate ranges, runs each combination to the horizon with the continuous engine, and returns every sample with a Pareto flag — the non-dominated set is the trade-off frontier ('which staffing is non-dominated on served vs walked out'). Continuous reading: a model with a schedule or a gate is refused with the reason (use sim_compare with explicit scenarios for those). Costs 1 token per 50 samples (rounded up) from your account's compute bucket; rate ranges must be non-negative.

NameTypeReqDescription
hoursnumber–horizon per run (default 8, above 0 and at most 10000)
idstringyesmodel id
objectivesstringyesJSON array of {"place": id, "direction": "max"|"min"}
parametersstringyesJSON object transition_id → [min, max] rate range, e.g. {"finish_brew": [10, 40]}
samplesnumber–Monte Carlo samples (default 100, 1..1000; outside that is refused)
seednumber–sampling seed, a whole number (default 42)

No output schema declared.

No examples provided.

sim_param_heatmap ~259

Two-rate grid for a stored model: vary two transition rates over ranges, run each combination to the horizon with the continuous engine, and return the observable's final value as a grid — 'which regime of arrivals × restock keeps the queue empty'. Continuous reading: a model with a schedule or a gate is refused with the reason. Costs 1 token per 50 grid cells (rounded up; a 40x40 grid empties the bucket) from your account's compute bucket.

NameTypeReqDescription
hoursnumber–horizon per run (default 8, above 0 and at most 10000)
idstringyesmodel id
log_scaleboolean–space the grid in log10 (default false)
observablestringyesplace id whose final value fills the grid
param_xstringyesfirst transition id
param_ystringyessecond transition id
range_xstringyesJSON [start, stop, n] for param_x: non-negative rates, n a whole number 2..40
range_ystringyesJSON [start, stop, n] for param_y: non-negative rates, n a whole number 2..40

No output schema declared.

No examples provided.

sim_prompt ~316

Ask an LLM to derive something from a stored entity: a variant model, a report, a piece of generated code — whatever the prompt asks for. The parent's JSON rides along as context, the same way the guided builder gives its interviewer the draft. The parent is looked up as a model first, then a prompt, then an artifact, then a map — whichever resolves — and the context block is labelled by what kind it found ("## Parent model", "## Parent prompt", ...), so the LLM is never told a report is a Petri net. The prompt is stored first and content-addressed like a model, so it has an id of its own before the LLM ever answers; both the prompt and whatever came back are placed in lineage under the parent (sim_prompt as the activity), so Ancestry walks parent -> prompt -> result. A Relation{prompt, "produced", result} is recorded alongside — sim_reroll's forward index, and queryable directly via sim_edges/sim_neighbors. If the response parses and validates as a Petri-net model it is stored as a NEW model you own; otherwise the raw text is stored as an artifact. Refused if this deployment has no LLM provider configured.

NameTypeReqDescription
parentstringyesid to run the prompt against — a model, prompt, artifact, or map
systemstring–optional system-level instructions, in addition to the parent context this tool always supplies
textstringyesthe natural-language instruction

No output schema declared.

No examples provided.

sim_propose_types ~335

Propose candidate @type values for one or more stored models, e.g. "QueueingSystem" or "ResourcePool", from a small Diagnose run this tool performs on each model (nothing is cached or reused between calls). Every rule is a hand-written assumption about what a shape of knobs/loss/siphons/classes tends to mean, not a structural proof or a measurement, so results are ASSUMPTION-grade until a human reviews one and applies it — apply with sim_link(id, "@type", "<Type>"), there is no separate apply tool. Pure read; nothing here is written to any model. Defaults to scanning the visible catalog (up to limit) when ids is omitted. Costs one Diagnose run per model — 5 tokens each from the compute bucket (per address, or per account when signed in), charged as each model is reached — so limit and realizations are both capped.

NameTypeReqDescription
idsstring–JSON array of model ids to consider, e.g. ["id1","id2"]. Omit to scan every model ListFor("") would list (the public catalog), truncated to limit.
limitnumber–maximum number of models to diagnose (default 10, 1..25; over 25 is refused, and so are explicit ids naming more models than limit) — a cost control, since this runs a simulation per model
realizationsnumber–realizations per model's Diagnose run (default 8, 1..16; outside that is refused) — deliberately small, this only needs to name a shape, not measure precise influence

No output schema declared.

No examples provided.

sim_prove ~1,186

Prove a structural relation between two stored models and record it with its witness. isomorphicTo: an exact canonical-labelling search (the one behind sim_canonical, seeded with exactly what the check compares) finds a place/transition bijection preserving arcs (direction, type, weight, kinetic), place sort, initial marking, capacity, rate or delay and refine.* tags. It does not compare guards, stages, schedules, constraints, non-refine tags (outcome, port.*), data-place types and initial values, objectives, players or asserted classes; those the pair carries are listed as notCompared, so proved is not 'behaves the same'. subnetOf: a bounded embedding search finds an injective, sort-preserving map (token places to token places, data places to data places, transitions to transitions) of the subject's places and transitions into the object's whose arcs among the image are exactly the subject's (initial markings, capacities, rates, delays and tags are not compared). preservesInvariant (invariant-pullback-v1): an induced embedding as subnetOf's along which every P-invariant of the object pulls back to a P-invariant of the subject (the incidence the shared firing rule implies: consuming and producing arcs on token places). Proved carries the map and a cover — per subject transition, rational coefficients of object transitions with the same incidence — which proves it for every invariant at once, plus invariantDimension (0 means vacuous: the object conserves nothing). Embeddings are tried one image at a time (embeddings onto one image differ by a symmetry of the subject, which keeps or breaks the pullback with them), at most 16 images. refines (id-simulation-v1): every firing sequence of the subject from its initial marking, transitions the object has no transition of (by id) dropped as silent, is one of the object from its own; untimed, guards and fixed delays refused (unknown: a delay is a timer whose in-flight markings an atomic step skips), rates not compared, at le…

NameTypeReqDescription
objectstringyescontent id of the stored model the edge points to
predicatestringyesisomorphicTo, subnetOf, preservesInvariant or refines
recordboolean–when proved, store the witness and then the edge; false answers without writing (default true)
subjectstringyescontent id of the stored model the edge starts from
viastring–promote a fact sim_query derived instead of searching (JSON, as a string or an object): {"derivation": <a row's support[].derivation>} or {"result": "<sim_query result id>", "row": n, "support": k} (…

No output schema declared.

No examples provided.

sim_publish ~126

Publish a stored model into the signed-in user's Google Sheets: the model workbook (live formulas when honest, a refusal tab when not), a server-run scenario as data tabs, and trajectory + contention charts. Returns the sheet URL. Counts against the daily quota, and costs 1 token from your account's compute bucket for the run.

NameTypeReqDescription
idstringyesmodel id
scenariostring–optional scenario JSON to run for the data tabs; sim_scenario's defaults (hours 8, realizations 16, seed 20260809) fill whatever is omitted

No output schema declared.

No examples provided.

sim_publish_app ~356

Publish the generated application for a model you own — the single-file HTML a generator produced from the model's `view` prompt. Served at /app/<id> in a sandboxed opaque origin (no cookies, no session; only the CORS-open public API is reachable). START FROM THE RUNTIME, not from scratch: /lib/app-template.html is a working console that imports /lib/sim-console.js and composes <sim-controls>, <sim-disruptions>, <sim-net>, <sim-timeline>, <sim-trajectory> and <sim-results> — the same components the generic console at /whatif/ runs. Composing them is how an app inherits role derivation, the fungible-set collapse, the influence ranking that never filters, the contention ledger and the verbatim caveats, none of which the checks below can verify you reimplemented correctly. Root-relative /lib/ imports are allowed. Off-origin loading is stopped in two places: the upload checks refuse an off-origin <script src> or <link href>, and the app is served under a Content-Security-Policy that confines scripts, styles, fetches, images and fonts to this origin — which is what stops the forms the checks do not parse (an inline module's import "https://…", a dynamic import(), a CSS @import). Checks refuse an app that is empty, oversized, never references its model id, or carries an off-origin <script src>/<link href>; behavioral correctness (does the app actually do what the view says) is on the generator and any browser gate you run.

NameTypeReqDescription
htmlstringyesthe complete self-contained HTML document
idstringyesmodel id the app presents

No output schema declared.

No examples provided.

sim_publish_compare ~198

Publish a multi-scenario comparison into the signed-in user's Google Sheets — sim_compare's export, the counterpart of sim_publish for a single scenario. Runs every scenario on one shared seed (the same server-enforced sharing sim_compare uses, so differences are the scenarios and not the dice) and writes a comparison table plus a trajectory chart, rather than one scenario's own data tabs. Returns the sheet URL. Counts against the same daily publish quota as sim_publish, and costs 1 token per scenario from your account's compute bucket.

NameTypeReqDescription
idstringyesmodel id
scenariosstringyesJSON array of scenarios, each with a name, e.g. [{"name":"today","hours":8},{"name":"one more","hours":8,"marking":{"staff/available":3}}]; sim_compare's defaults (hours 8 and realizations 16 per sce…

No output schema declared.

No examples provided.

sim_query ~783

Answer a question over the edge graph between stored models: bounded paths, closure over transitive predicates, and conjunctive patterns of up to 4 triples joined on shared ?variables. The query argument is JSON: {"select": ["?m"], "where": [{"subject": "?m", "predicate": "subnetOf", "object": "<content id>", "mode": "closure"}, {"subject": "?m", "predicate": "@type", "object": "QueueingSystem"}]}; a term starting with ? is a variable, anything else a constant (a 24-hex content id, or for @type's object a model kind). Modes: edge (default; one stored edge, read through the registry: narrower is read as broader turned round, symmetric predicates match either way round), path (1..maxHops hops, maxHops 1 to 8 required; a row says reached by a path unless the predicate is transitive), closure (no maxHops; allowed only on the transitive predicates broader, isomorphicTo, migratedFrom, narrower, subnetOf, supersededBy). Put the bound term in object to walk backwards. Unregistered (legacy) predicates are one stored edge in their stored direction only, never walked or closed over. A structural edge (isomorphicTo, subnetOf, preservesInvariant, refines) counts only when one of its stored witnesses re-checks valid now; a derived structural fact carries a derivation (the chain of witnesses and the composed map's digest) that sim_check_witness(derivation=…) re-checks, and is never stored; excluded lists the edges not walked and why. Closure runs per predicate (isomorphicTo hops never feed a subnetOf closure). status complete means complete over the eligible edges (and, for path, within maxHops: hopLimitReached names patterns with edges beyond); truncated means a bound was reached, rows is absent and the rows found so far are in partialRows (true, but not all of them). A query with no variables answers yes, no or unknown (a bound stopped it, or a stored row could not be decoded); a no's caveat says how far the search looked (only closure rules out a derived edge, and a path cut a…

NameTypeReqDescription
querystringyesthe query as JSON: {"select": [variables], "where": [{"subject", "predicate", "object", "mode", "maxHops"}]}

No output schema declared.

No examples provided.

sim_reach ~1,049

Returns whether the marking to is reachable from the marking from in ONE stored net (a model, or a system that is one net): yes with a firing trace, no with a re-checkable P-invariant (or after an exhaustive search), or unknown with every reason. A sim_compose result is one fused net, so it qualifies; a sim_bind binding or a collection links rates, not tokens, and answers unknown (not-one-net). A system id (sim_create_system) is answered on its one net when one member has every other embedded in it by a witnessed subnetOf or isomorphicTo edge or a chain of edges of one predicate (the answer carries via: an edge and witness per member, or the derivation sim_check_witness(derivation=…) re-checks); otherwise it answers unknown: not-one-net when it holds bindings (they link rates, not tokens) or no member qualifies, system-truncated when its witness bound was reached or the chain search stopped at a bound. On a one-net system, a key in from or to may name a member's place as <model>:<place> (the member's id, or its name when no other member shares it): it is translated into the net place that member's embedding maps it to, the answer's from and to are the translated question, and via.translation lists each key's member, place and net place, which sim_check_witness(reach=…) re-checks against the stored witnesses. Refused, naming the key: a member or place the system does not have, a data place, a key that reads more than one way, a place two valid witnesses of the member's edge map differently, and two keys landing on one net place with different counts; more than 16 other witnesses to compare answers unknown (translation-budget). from is a sparse override on the model's declared initial marking (unset = declared). to constrains only the places it names, each to exactly that count; naming every token place asks for an exact marking. Unknown or data places, negative or fractional counts and counts over the scenario caps (1,000,000 per place, 4,000,000 in total) are refus…

NameTypeReqDescription
fromstring–JSON object of place -> whole token count overriding the declared initial marking, e.g. {"queue": 3}; unset = the declared marking. On a system, a key may be <model>:<place> for a member's place
systemstringyescontent id of one stored model, or of a system (sim_create_system)
tostringyesJSON object of the places to constrain, each to exactly that count, e.g. {"done": 1}. On a system, a key may be <model>:<place> for a member's place, translated into the net's

No output schema declared.

No examples provided.

sim_receipt ~274

Run a seeded scenario and get back the result PLUS a signed run receipt: an Ed25519 certificate over (model id, scenario, result hash, service revision). Anyone can check it two ways — verify the signature offline against the embedded public key (proves this service reported this result), and POST it to /api/receipts/verify (no auth) to replay the run and confirm the result hash reproduces (proves the run is reproducible, not invented). The current signing key is at GET /api/receipts/key. Reproducibility is the bottom rung of the trust ladder receipts build: play the model, check the anchors, re-run the seed, verify the certificate. Costs 1 token from your account's compute bucket.

NameTypeReqDescription
idstringyesmodel id to run
scenariostring–scenario JSON (hours, samples, seed, marking, rates, schedule, summary — the same shape sim_scenario takes); sim_scenario's defaults (hours 8, realizations 16, seed 20260809) fill whatever is omitted…

No output schema declared.

No examples provided.

sim_refine ~338

Refine a model's parameter classes by editing what the model SAYS (tags on a place or transition, or assertedClasses), then re-derive. Returns a NEW model id (ids are content addresses, so the original stays reachable) plus a before/after class diff. tags can only split classes; assertedClasses declares a merge and gets re-verified and costed, never trusted blind. Read the sim://docs/classification resource once for why the two levers are not symmetric. Costs 2 tokens from your account's compute bucket (the stored model, 1, and the verified re-classification, 1).

NameTypeReqDescription
assertedClassesstring–JSON array, e.g. [{"id":"items","members":["item0","item1"],"note":"one stocking decision"}]
idstringyesmodel id to refine
signaturestring–optional hex signature over the CID of the signed claim; see modelstore.SignedClaim for the exact bytes. An unverifiable signature is refused, not stored with a flag.
signerstring–optional {"type":"eth"|"ed25519","address":"..."} — signs the lineage claim so it is the refiner's word rather than the server's account of a session
tagsstring–JSON object of place OR transition id -> {key: value}, e.g. {"nurse_avail":{"refine.shift":"night"}}. Keys not prefixed refine. are stored as metadata and refine nothing. classify.go's colour refinem…

No output schema declared.

No examples provided.

sim_reroll ~276

Re-run a stored sim_prompt against the SAME parent it originally ran against — a sibling attempt, never a chain: it never derives from the previous attempt's output, only from the original parent, so rerolling ten times leaves ten independent siblings in lineage rather than a chain of ten. Reuses the original prompt's text and system unless you override them here. The original prompt and its result are left untouched; this stores a new prompt and a new result (model or artifact, same rule as sim_prompt) under Activity sim_reroll. When called with neither override and the deployment's LLM provider and model are unchanged since the original ran, the response carries a reproducibility field checked against every prior result this exact prompt has ever produced (via the same forward "produced" relation sim_edges/sim_neighbors can query directly): "verified" if this result content-matches one of them, "diverged" if it doesn't, "not verified" if there's no prior result on record yet.

NameTypeReqDescription
promptstringyesid of the sim_prompt (or earlier sim_reroll) to re-run
systemstring–override the original prompt's system text; default reuses it verbatim
textstring–override the original prompt's text; default reuses it verbatim

No output schema declared.

No examples provided.

Common questions

What is the xyz.pflow.sim/whatif MCP server?

xyz.pflow.sim/whatif is an MCP server listed in the public MCP registry as xyz.pflow.sim/whatif. Conversational what-if simulation: build, diagnose and compare Petri-net models; CC0 catalog. This page covers its hosted endpoint (https://sim.pflow.xyz/mcp).

Is the xyz.pflow.sim/whatif MCP server safe to use?

xyz.pflow.sim/whatif scores 69 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the xyz.pflow.sim/whatif MCP server expose?

xyz.pflow.sim/whatif exposes 55 tools: sim_accept_migration, sim_bind, sim_calibrate, sim_canonical, sim_check_witness, and 50 more. Their descriptions and schemas cost roughly 19,475 tokens of context every time the server is loaded.

Does the xyz.pflow.sim/whatif MCP server require authentication?

No. We connected to xyz.pflow.sim/whatif without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

Is the xyz.pflow.sim/whatif MCP server still maintained?

xyz.pflow.sim/whatif is still listed as active in the MCP registry. We last reached this channel on 7 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.