{"apiVersion":"v1","directorySlug":"sim-mcp-a5d2c28ac0","title":"pflow - Visual Editor for Petri Nets","description":"One abstraction for state machines, resource flows, game mechanics, and token standards. Build Petri net models you can simulate, analyze, and generate code from.","pageUrl":"https://www.mcpbundles.com/skills/sim-mcp-a5d2c28ac0","connectPath":"importable","connectAction":"import_server","catalogListing":false,"bundleSlug":null,"listingKind":"remote_mcp","kind":"provider","transportUrl":"https://sim.pflow.xyz/mcp","hostedMcpUrl":null,"toolCount":46,"toolInventoryStatus":"observed","refreshedAt":"2026-11-03T13:26:00.516172+00:00","registryName":"xyz.pflow/sim-mcp-a5d2c28ac0","registryVersion":"2026.11.3","registryEligible":true,"tools":[{"name":"sim_bind","description":"Record an intended connection between two stored models' declared ports — fromModel's fromPort feeding toModel's toPort — as a new content-addressed Binding, alongside sim_link's Relation graph rather than inside either model (ROADMAP.md Phase 9). This does not run anything, does not validate that either port exists or has the right direction, and does not touch either model: it is a proposal to connect, discoverable afterward via sim_edges on either model id (a from/to Relation is recorded auto","inputSchema":{"type":"object","required":["fromModel","fromPort","toModel","toPort"],"properties":{"toPort":{"type":"string"},"toModel":{"type":"string"},"fromPort":{"type":"string"},"fromModel":{"type":"string"},"transform":{"type":"string"}}},"logicalName":"sim_bind","displayName":"sim_bind","title":"sim_bind","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_calibrate","description":"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 tran","inputSchema":{"type":"object","required":["id","log"],"properties":{"id":{"type":"string"},"log":{"type":"string"}}},"logicalName":"sim_calibrate","displayName":"sim_calibrate","title":"sim_calibrate","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_canonical","description":"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 al","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"logicalName":"sim_canonical","displayName":"sim_canonical","title":"sim_canonical","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_classify","description":"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","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"verify":{"type":"boolean"},"inline_context":{"type":"boolean"}}},"logicalName":"sim_classify","displayName":"sim_classify","title":"sim_classify","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_code_to_flow","description":"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. The same generator the /api/code-to-flow endpoint uses; 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.","inputSchema":{"type":"object","required":["code"],"properties":{"code":{"type":"string"},"name":{"type":"string"},"focus":{"type":"string"},"language":{"type":"string"}}},"logicalName":"sim_code_to_flow","displayName":"sim_code_to_flow","title":"sim_code_to_flow","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_compare","description":"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.","inputSchema":{"type":"object","required":["id","scenarios"],"properties":{"id":{"type":"string"},"full":{"type":"boolean"},"scenarios":{"type":"string"}}},"logicalName":"sim_compare","displayName":"sim_compare","title":"sim_compare","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_components","description":"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.","inputSchema":{"type":"object"},"logicalName":"sim_components","displayName":"sim_components","title":"sim_components","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_compose","description":"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 s","inputSchema":{"type":"object","required":["component"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"attach":{"type":"string"},"params":{"type":"string"},"prefix":{"type":"string"},"component":{"type":"string"}}},"logicalName":"sim_compose","displayName":"sim_compose","title":"sim_compose","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_conformance","description":"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","inputSchema":{"type":"object","required":["id","log"],"properties":{"id":{"type":"string"},"log":{"type":"string"}}},"logicalName":"sim_conformance","displayName":"sim_conformance","title":"sim_conformance","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_create_collection","description":"Mint a named Collection 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) and read them back with sim_neighbors(collectionID, \"hasMember\") or sim_edges(collectionID). Content-addressed: creating a collection with a name already used returns the existing id, n","inputSchema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"logicalName":"sim_create_collection","displayName":"sim_create_collection","title":"sim_create_collection","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_create_model","description":"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.","inputSchema":{"type":"object","required":["model"],"properties":{"model":{"type":"string"}}},"logicalName":"sim_create_model","displayName":"sim_create_model","title":"sim_create_model","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_crosscheck","description":"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 structu","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"hours":{"type":"number"},"realizations":{"type":"number"}}},"logicalName":"sim_crosscheck","displayName":"sim_crosscheck","title":"sim_crosscheck","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_dataset","description":"Generate a synthetic event log from a stored model (seeded SSA playout; case-per-arrival). Returns CSV. Deterministic: same id, same seed, same bytes.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"seed":{"type":"number"},"cases":{"type":"number"}}},"logicalName":"sim_dataset","displayName":"sim_dataset","title":"sim_dataset","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_delete_model","description":"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).","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"logicalName":"sim_delete_model","displayName":"sim_delete_model","title":"sim_delete_model","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_diagnose","description":"Test a stored model without writing a fitness test for it. Reports generic gates (mass balance, dormant sources, whether staffing has a knee, whether any knob binds), every derived control ranked by MEASURED influence on the outcome (pool/source/patience/parameter knobs, rate-knob influence is signed), the parameter classes discovered among them, and four structural readings needing no run behind them (T-invariants, siphons/traps with deadlock witnesses, CTMC lumpability, constrained lumping). P","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"seed":{"type":"number"},"hours":{"type":"number"},"realizations":{"type":"number"},"inline_context":{"type":"boolean"},"maxRealizations":{"type":"number"}}},"logicalName":"sim_diagnose","displayName":"sim_diagnose","title":"sim_diagnose","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_diff","description":"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.","inputSchema":{"type":"object","required":["a","b"],"properties":{"a":{"type":"string"},"b":{"type":"string"}}},"logicalName":"sim_diff","displayName":"sim_diff","title":"sim_diff","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_distill","description":"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 separat","inputSchema":{"type":"object","required":["id","groups"],"properties":{"id":{"type":"string"},"groups":{"type":"string"},"options":{"type":"string"}}},"logicalName":"sim_distill","displayName":"sim_distill","title":"sim_distill","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_edges","description":"List every relation touching an entity, as either subject or object — the two-directional view datum_edges gives. A filtered scan over every stored relation rather than a maintained index: this is a simulation sandbox's model graph, not a large corpus, so scanning on each call is the honest tradeoff over a second data structure that could drift from the source of truth.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"logicalName":"sim_edges","displayName":"sim_edges","title":"sim_edges","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_evaluate","description":"Score a player's legal next moves by NEXT-MOVE ELIMINATION (the tic-tac-toe blog technique): compute the expected objective from the given marking with all moves available, then once per candidate with that move's rate zeroed — the move whose elimination loses the most is the best move. Needs the game schema (simulation.objective + simulation.players). Ungated nets use the continuous ODE relaxation; gated nets use exact seeded SSA rollouts, and the response says which — the same rule sim_scenari","inputSchema":{"type":"object","required":["id","player"],"properties":{"id":{"type":"string"},"player":{"type":"string"},"horizon":{"type":"number"},"marking":{"type":"string"},"realizations":{"type":"number"}}},"logicalName":"sim_evaluate","displayName":"sim_evaluate","title":"sim_evaluate","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_extend","description":"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 m","inputSchema":{"type":"object","required":["id","operations"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"operations":{"type":"string"}}},"logicalName":"sim_extend","displayName":"sim_extend","title":"sim_extend","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_get_binding","description":"Fetch a stored Binding (see sim_bind) by id: which model/port feeds which, and any recorded transform.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"logicalName":"sim_get_binding","displayName":"sim_get_binding","title":"sim_get_binding","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_get_model","description":"Fetch a stored model's full Petri-net JSON by id.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"logicalName":"sim_get_model","displayName":"sim_get_model","title":"sim_get_model","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_invariants","description":"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","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"logicalName":"sim_invariants","displayName":"sim_invariants","title":"sim_invariants","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_license_model","description":"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.","inputSchema":{"type":"object","required":["id","license"],"properties":{"id":{"type":"string"},"license":{"type":"string"}}},"logicalName":"sim_license_model","displayName":"sim_license_model","title":"sim_license_model","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_link","description":"Record a typed edge between any two stored entities — models, prompts, artifacts, maps, collections, or anything else addressed by a content id — with no fixed predicate vocabulary: the caller's choice, the same as datum_link (\"hasMember\", \"cites\", \"supersedes\", whatever the relationship actually is). Distinct from the Lineage a model/prompt/artifact already carries, which is specifically derivation (parent -> prompt -> child); a Relation is any OTHER assertion about how two entities relate, inc","inputSchema":{"type":"object","required":["subject","predicate","object"],"properties":{"object":{"type":"string"},"subject":{"type":"string"},"predicate":{"type":"string"}}},"logicalName":"sim_link","displayName":"sim_link","title":"sim_link","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_list_bindings","description":"List the content id of every stored Binding.","inputSchema":{"type":"object"},"logicalName":"sim_list_bindings","displayName":"sim_list_bindings","title":"sim_list_bindings","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_list_models","description":"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.","inputSchema":{"type":"object"},"logicalName":"sim_list_models","displayName":"sim_list_models","title":"sim_list_models","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_map_get","description":"Fetch a stored Map's key->value data by id.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"logicalName":"sim_map_get","displayName":"sim_map_get","title":"sim_map_get","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_map_list","description":"List the content id of every stored Map.","inputSchema":{"type":"object"},"logicalName":"sim_map_list","displayName":"sim_map_list","title":"sim_map_list","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_map_put","description":"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.","inputSchema":{"type":"object","required":["data"],"properties":{"data":{"type":"string"}}},"logicalName":"sim_map_put","displayName":"sim_map_put","title":"sim_map_put","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_my_sheets","description":"List the sheets this user has published, with their URLs.","inputSchema":{"type":"object"},"logicalName":"sim_my_sheets","displayName":"sim_my_sheets","title":"sim_my_sheets","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_neighbors","description":"One-hop traversal from an entity: every object reachable via a relation where it is the subject, optionally filtered to a single predicate (omit for all of them). Pass a collection's id with predicate hasMember to list its members.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"predicate":{"type":"string"}}},"logicalName":"sim_neighbors","displayName":"sim_neighbors","title":"sim_neighbors","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_optimize","description":"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).","inputSchema":{"type":"object","required":["id","parameters","objectives"],"properties":{"id":{"type":"string"},"seed":{"type":"number"},"hours":{"type":"number"},"samples":{"type":"number"},"objectives":{"type":"string"},"parameters":{"type":"string"}}},"logicalName":"sim_optimize","displayName":"sim_optimize","title":"sim_optimize","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_param_heatmap","description":"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.","inputSchema":{"type":"object","required":["id","param_x","param_y","observable","range_x","range_y"],"properties":{"id":{"type":"string"},"hours":{"type":"number"},"param_x":{"type":"string"},"param_y":{"type":"string"},"range_x":{"type":"string"},"range_y":{"type":"string"},"log_scale":{"type":"boolean"},"observable":{"type":"string"}}},"logicalName":"sim_param_heatmap","displayName":"sim_param_heatmap","title":"sim_param_heatmap","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_prompt","description":"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","inputSchema":{"type":"object","required":["parent","text"],"properties":{"text":{"type":"string"},"parent":{"type":"string"},"system":{"type":"string"}}},"logicalName":"sim_prompt","displayName":"sim_prompt","title":"sim_prompt","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_propose_types","description":"Propose candidate @type values for one or more stored models, e.g. \"QueueingSystem\" or \"ResourcePool\", from each model's own Diagnosis — never from a fresh simulation this tool runs itself for the sole purpose of classifying, only from an existing measurement it reuses. 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 wit","inputSchema":{"type":"object","properties":{"ids":{"type":"string"},"limit":{"type":"number"},"realizations":{"type":"number"}}},"logicalName":"sim_propose_types","displayName":"sim_propose_types","title":"sim_propose_types","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_publish","description":"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.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"scenario":{"type":"string"}}},"logicalName":"sim_publish","displayName":"sim_publish","title":"sim_publish","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_publish_app","description":"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","inputSchema":{"type":"object","required":["id","html"],"properties":{"id":{"type":"string"},"html":{"type":"string"}}},"logicalName":"sim_publish_app","displayName":"sim_publish_app","title":"sim_publish_app","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_publish_compare","description":"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.","inputSchema":{"type":"object","required":["id","scenarios"],"properties":{"id":{"type":"string"},"scenarios":{"type":"string"}}},"logicalName":"sim_publish_compare","displayName":"sim_publish_compare","title":"sim_publish_compare","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_receipt","description":"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. Reprod","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"scenario":{"type":"string"}}},"logicalName":"sim_receipt","displayName":"sim_receipt","title":"sim_receipt","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_refine","description":"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.","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"tags":{"type":"string"},"signer":{"type":"string"},"signature":{"type":"string"},"assertedClasses":{"type":"string"}}},"logicalName":"sim_refine","displayName":"sim_refine","title":"sim_refine","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_reroll","description":"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","inputSchema":{"type":"object","required":["prompt"],"properties":{"text":{"type":"string"},"prompt":{"type":"string"},"system":{"type":"string"}}},"logicalName":"sim_reroll","displayName":"sim_reroll","title":"sim_reroll","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_run_pipeline","description":"Run a set of stored Bindings (see sim_bind) as a composed pipeline: each bound model runs through its own ordinary scenario, in topological order, with an output port's own trajectory resampled into the target's input-transition schedule. One seed and horizon shared across every model in the pipeline, same discipline sim_compare enforces within one model. Refuses a cyclic binding set, and refuses any binding whose named port does not exist with the right direction (output must be a place, input","inputSchema":{"type":"object","required":["bindingIds"],"properties":{"seed":{"type":"number"},"hours":{"type":"number"},"bindingIds":{"type":"string"},"realizations":{"type":"number"}}},"logicalName":"sim_run_pipeline","displayName":"sim_run_pipeline","title":"sim_run_pipeline","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_scenario","description":"Run a seeded what-if scenario against a stored model: marking overrides, rate overrides, piecewise rate schedules, and params assignments to the model's declared structural parameters (arc weights, capacities — batch sizes and shelf sizes). Pure read — asking cannot change the model. Returns trajectory, final marking, metrics, contention, caveats and assumptions. \"samples\" (default 60) is the trajectory's resolution: the number of evenly spaced points from 0 to hours inclusive at which times and","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"scenario":{"type":"string"}}},"logicalName":"sim_scenario","displayName":"sim_scenario","title":"sim_scenario","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_supersede_model","description":"Mark an old version of your model as replaced by a newer one. The old id keeps working and its commons dedication (if any) stands — only the listing moves on to the successor. Both models must be yours.","inputSchema":{"type":"object","required":["old","new"],"properties":{"new":{"type":"string"},"old":{"type":"string"}}},"logicalName":"sim_supersede_model","displayName":"sim_supersede_model","title":"sim_supersede_model","annotations":{"untrustedContentHint":true,"readOnlyHint":true}},{"name":"sim_verify","description":"Verify declared properties of a stored model: deadlock-free, bounded, mutual-exclusion, invariant expressions, reachable/unreachable targets. Verdicts are proved/refuted/unknown — unknown is never a pass — and each carries a method: structural means it holds for ANY initial marking (linear algebra on the incidence matrix, the strongest claim available), exhaustive means this marking's full state space, partial means truncated (only refutations sound). Caveats name anything the analysis net could","inputSchema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"properties":{"type":"string"}}},"logicalName":"sim_verify","displayName":"sim_verify","title":"sim_verify","annotations":{"untrustedContentHint":true,"readOnlyHint":true}}],"toolSource":"directory_preview","agentAction":"both","installLinks":[{"id":"cursor","label":"Cursor","href":"cursor://anysphere.cursor-deeplink/mcp/install?name=pflow---Visual-Editor-for-Petri-Nets&config=eyJ1cmwiOiAiaHR0cHM6Ly9zaW0ucGZsb3cueHl6L21jcCJ9"},{"id":"vscode","label":"VS Code","href":"vscode:mcp/install?%7B%22name%22%3A%22pflow---Visual-Editor-for-Petri-Nets%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fsim.pflow.xyz%2Fmcp%22%7D"},{"id":"vscode-insiders","label":"VS Code Insiders","href":"vscode-insiders:mcp/install?%7B%22name%22%3A%22pflow---Visual-Editor-for-Petri-Nets%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Fsim.pflow.xyz%2Fmcp%22%7D"},{"id":"claude-web","label":"Claude.ai","href":"https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=pflow+-+Visual+Editor+for+Petri+Nets&connectorUrl=https%3A%2F%2Fsim.pflow.xyz%2Fmcp"},{"id":"codex","label":"Codex","copyText":"codex mcp add \"pflow---Visual-Editor-for-Petri-Nets\" --url \"https://sim.pflow.xyz/mcp\""},{"id":"chatgpt","label":"ChatGPT","href":"https://www.mcpbundles.com/docs/integrations/chatgpt"}],"catalogUrl":"https://www.mcpbundles.com/api/directory/v1/servers/sim-mcp-a5d2c28ac0","callUrl":"https://www.mcpbundles.com/api/directory/v1/servers/sim-mcp-a5d2c28ac0/tools/{tool}","mcpServerUrl":"https://sim.pflow.xyz/mcp","liveCatalogUrl":"https://www.mcpbundles.com/api/directory/v1/servers/sim-mcp-a5d2c28ac0?live=1"}