Build and run open simulations anywhere
Simcraft is a visual IDE, CLI, and MCP server for discrete-event, agent-based, system dynamics and resource-flow models, built on an open standard.
Pre-alpha, version 0.1.0. No account needed. Interfaces can change before 1.0.0.

Every paradigm on one canvas
Mix queues, populations and stocks in one model.






One document, three views
Diagram, Stage and Code show the same OSDL document.



Concept render. The Stage view is in development.


Streamed results and interactive simulations
Charts, the diagram and the event stream update as the run plays. Pause, step, scrub or update a parameter at any point.



Collaborate with an AI Assistant
Ask the Assistant to edit a model and run an experiment, or connect Claude or ChatGPT over MCP.
The Assistant and MCP need an account. Invitation-only beta.

Orders back up at lunch. Try one more courier and tell me what changes.
Selected: Couriers
Assistant
- DoneRead the couriers parameterget_model
- DoneAdd a third courieredit_model
- DoneNo problemsvalidate_model
- DoneOne day, completedrun_experiment
With three couriers the bakery delivers 30 orders instead of 28, and next-day orders fall from 7 to 5. Couriers are busy 51% of the time, down from 73%.
Selected: Couriers
Claude and ChatGPT connect over MCP with 15 tools.
claude mcp add --transport http simcraft https://app.simcraft.io/mcp
- get_authoring_guide
- list_libraries
- describe_component_type
- list_examples
- get_example
- list_models
- create_model
- get_model
- render_model
- edit_model
- validate_model
- run_experiment
- get_run
- get_run_series
- get_run_distribution
One document, many tools
{
"id": "doctors",
"type": "des.server",
"label": "Doctors",
"params": {
"serviceTime": {
"dist": "exponential",
"rate": { "expr": "1 / treatmentTime" }
},
"capacity": { "expr": "effectiveDoctors.value" }
}
},{
"id": "effectiveDoctors",
"type": "sd.auxiliary",
"label": "Effective doctors",
"params": {
"value": {
"expr": "max(1, round(baseDoctors * (1 - 0.5 * fatigue.value)))"
}
}
}
A model is plain JSON. Here a discrete-event server reads a system dynamics value.OSDL on GitHub
from simcraft import Model, des
m = Model("mm1-queue")
arrivals = m.add(des.Source(id="arrivals", interarrival=des.Exponential(rate=0.9)))
waiting = m.add(des.Queue(id="waiting", discipline="fifo"))
teller = m.add(des.Server(id="teller", service_time=des.Exponential(rate=1.0)))
done = m.add(des.Sink(id="done"))
arrivals >> waiting >> teller >> done
m.save("mm1-queue.osdl.json")
results = m.run(duration=10_000, replications=30)
The Python SDK builds the same document format. Not yet published.
{
"model_id": "5248dc3e-01a9-4e28-bcaf-9e0d578a2575",
"label": "Add a courier shelf",
"ops": [
{
"op": "add_component",
"component": { "id": "shelf", "type": "des.queue" },
"near": "dispatch"
},
{ "op": "connect", "from": "dispatch.out", "to": "shelf.in" }
]
}
Claude and ChatGPT edit and run your cloud models. Each edit is one step you can undo. Invitation-only beta.
$ simcraft validate clinic-hybrid.osdl.json
clinic-hybrid.osdl.json: valid (schema + diagnostics + buildable, 7 components)
$ simcraft run clinic-hybrid.osdl.json --seed 42 --events a.ndjson > a.json
$ simcraft run clinic-hybrid.osdl.json --seed 42 --events b.ndjson > b.json
$ shasum -a 256 a.ndjson b.ndjson
e8ad4d777536259434fb152974dbe5659db5a8cc59d311d7b11955d8501f189a a.ndjson
e8ad4d777536259434fb152974dbe5659db5a8cc59d311d7b11955d8501f189a b.ndjson
Same document, experiment and seed, same 159,851 events. CLI not yet published.
const sim = Simulation.fromEngine(new SimcraftEngine(), document);
sim.events.on("entity.moved", (event) => {
console.log(event.time, event.from, event.to);
});
const results = await sim.run({ experiment: "one-week", seed: 42 });{"seq":2000,"time":27.087630178280868,"type":"entity.moved","source":"triage","payload":{"entityId":"patients#62","from":"patients","to":"triage"}}
{"seq":2001,"time":27.087630178280868,"type":"state.changed","source":"patients","payload":{"path":"patients.held","value":0.0}}
{"seq":2002,"time":27.100000000000115,"type":"metric.updated","source":"fatigue","payload":{"name":"fatigue.value","value":0.24883315774918094}}
{"seq":2005,"time":27.154559380806752,"type":"state.changed","source":"doctors","payload":{"path":"doctors.busy","value":2.0}}The TypeScript client streams typed events from the WebAssembly engine. Not yet published.
/-- Dispatch one calendar entry and its post-event checks: exactly one
calendar-dispatch semantic unit. -/
def stepOnce (state : MachineState) : StepDisposition :=
match state.popNextCalendarEntry with
| none => .completed .quiescent state
| some (entry, popped) =>
if state.pastEndTime entry.time then .completed .endTime state
else
let state := { popped with time := entry.time }
let step := dispatchCalendarTarget entry.target stateMachine/Kernel.lean
The Lean reference machine defines the modeled kernel. Engine traces are compared with its traces for each conformance case.
OSDL on GitHubLive in your browser
Both models run on the Simcraft engine, compiled to WebAssembly.
-
A weekday on the Tube
Published Tube service and central London bus timetables with simulated passenger demand. Not a live transport feed.
-
The Kessler cascade
How orbital collisions create debris and raise the risk of later collisions. An illustrative scenario, not an orbital forecast.
Powered by TfL Open Data. Contains OS data © Crown copyright and database rights 2016. Track alignment © OpenStreetMap contributors, ODbL. NASA Blue Marble and Black Marble imagery
Repeatable traces
Same document, experiment and seed give the same event stream.
Live branching
Change a parameter mid-run and the run forks a branch.
Collaborative AI
The Assistant in the IDE and connected tools over MCP edit your model with you. Invitation-only beta.
Conformance-tested kernel
Engine traces are compared with a Lean reference machine.
Clean Git diffs
Models are plain JSON, so changes review like code.
Portable component libraries
Package your own components as WebAssembly for the CLI and server. Not yet public.
Open format
OSDL is Apache-2.0, with published schemas and a conformance suite.
Portable engine
The same model runs in the browser, on the CLI or on a server. CLI and server not yet public.
Python integrations
Dagster, MLflow and ClearML through the Python SDK. Not yet published.
Pre-alpha, version 0.1.0. No account needed. Interfaces can change before 1.0.0.