Agent skill

Run Modelica

by LunCoSim in LunCoSim/lunco-sim

Recipe for running Modelica models and building experiments/graphs in lunica (LunCoSim), driven from the HTTP API with curl.

Apache-2.0Auto-check passedAgent Workflows

Install Run Modelica

skills CLI
$ npx skills add LunCoSim/lunco-sim --skill run-modelica -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install LunCoSim/lunco-sim run-modelica --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/LunCoSim/lunco-sim.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/run-modelica .claude/skills/run-modelica && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
run-modelica
GitHub stars
107
Token cost
~13k tokens
SKILL.md length
5,765 words
Files
1
Skills in repo
40
Repo updated
First seen
Licence
Apache-2.0

At a glance

Recipe for running Modelica models and building experiments/graphs in lunica (LunCoSim), driven from the HTTP API with curl.

  • Works in 9 steps: Launch an app in API mode → The request envelope → Two run modes — pick the right one → …
  • Ever you need to: launch the workbench
  • SKILL.md covers 0. Launch an app in API mode, 1. The request envelope, 2. Two run modes — pick the… and 3. Recipe A — run a model live…, plus 5 more sections
  • Calls curl, cargo and python3

What it does

Run Modelica is an agent skill from LunCoSim/lunco-sim. Recipe for running Modelica models and building experiments/graphs in lunica (LunCoSim), driven from the HTTP API with curl. Trigger whenever you need to: launch the workbench, open/compile a Modelica model, run it live (interactive realtime) or as a fast batch, sweep parameters across many runs, read simulation results/trajectories, poke runtime inputs, or plot and compare runs — without asking the user to click. Covers the --api launch, the POST /api/commands envelope, the command + query catalog, run…

Its SKILL.md is about 13k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Agent Workflows, covering MCP servers and REST APIs. It works with Model Context Protocol. The repository describes itself as: Collaborative Multiphysics Cosimulator For Space Missions 🌎🚀🌚. The licence is Apache-2.0.

When your agent uses it

  • Ever you need to: launch the workbench
  • Open/compile a Modelica model
  • Run it live (interactive realtime)
  • As a fast batch

Example prompts

  • “/run-modelica”

Workflow steps

9 steps, taken from the step headings in SKILL.md.

  1. Launch an app in API mode
  2. The request envelope
  3. Two run modes — pick the right one
  4. Recipe A — run a model live (interactive)
  5. Recipe B — build an experiment (batch + parameter sweep)
  6. Recipe C — read experiment results
  7. Recipe D — visualize & compare runs (plots)
  8. Command & query catalog
  9. Gotchas

What it can do on your machine

Read from SKILL.md and the folder at commit 43f1301. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • curl
    • cargo
    • python3

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use curl, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Run Modelica loads about 13k tokens when it runs. Until then it costs about 179 tokens; SKILL.md has 5,765 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~179
When it runs · the whole SKILL.md, loaded when a task matches
~13k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from LunCoSim/lunco-sim at commit 43f1301, republished under its Apache-2.0 licence (© LunCoSim). 5,765 words, ~13,161 tokens.

Download SKILL.mdSave it as .claude/skills/run-modelica/SKILL.md (or your agent's skills folder).
name
run-modelica
description
Recipe for running Modelica models and building experiments/graphs in lunica (LunCoSim), driven from the HTTP API with curl. Trigger whenever you need to: launch the workbench, open/compile a Modelica model, run it live (interactive realtime) or as a fast batch, sweep parameters across many runs, read simulation results/trajectories, poke runtime inputs, or plot and compare runs — without asking the user to click. Covers the `--api` launch, the `POST /api/commands` envelope, the command + query catalog, run bounds/solver semantics, and reading experiment results. Prefer curl over the MCP `mcp__lunco__*` tools — the MCP bridge is often unavailable; every MCP tool has a curl equivalent shown here.

Run Modelica models & build experiments

lunica exposes a reflect-registered command API and structured query providers over POST /api/commands. Drive everything with curl. The mcp__lunco__* tools mirror this API but are frequently down — use curl as the primary surface; only fall back to MCP if a human explicitly asks.

0. Launch an app in API mode

Modelica runs inside any app that embeds LunCoApiPlugin + the Modelica workbench. Build the named binary in the current worktree, then invoke it directly. The API server only exists when you pass --api. Default port is 4101 (lunco_api_contracts::DEFAULT_API_PORT).

Before creating a new Modelica file, inventory the maintained package roots and the closest composed USD network in the current checkout. Reuse existing component classes through USD or the generated wrapper when their equations and public contract fit; add a new mission/vehicle model only when the equation or interface is genuinely absent. An isolated Modelica compile proves neither USD wiring nor runtime physics.

Compile admission preserves an existing participant/vehicle name; generated class identity belongs to simulation metadata. Verify a control HUD against the physical vehicle identity after compile and reload.

For shared plume calculations, reuse LunCo.Propulsion.computePlumePhotometry. PlumePhotometry supplies named USD ports; RCSJet calls the function directly with static nozzle parameters. See USD-driven visuals for the fixed-size result contract. Validate model refactors through the production rcs_feed_starvation and rocket_engine_plume_defaults scene gates, then measure cold solver preparation and running-step cost separately.

For material-dependent equations, use the component's typed SysML material assignment and property source described in the mission engineering material gate. Keep values and units typed until the Modelica-source emission boundary, and derive generated parameter literals from that source rather than maintaining a second hand-edited material table in .mo. The shared material catalogue and generic cross-domain binding are not yet established; if the current bridge cannot provide a required property with its unit and applicability, report that generic gap instead of substituting a copied constant.

For radiation or surface thermal models, also resolve the typed finish/coating assigned to the analyzed face and use its sourced engineering optical/thermal properties. UsdShade shader presets are presentation mappings only and must not be used as Modelica property sources.

AppLaunchModelica surface
lunica"$LUNICA_BIN" --api 4101The Modelica workbench itself — nothing to switch to. Prefer this for pure Modelica work.
luncosim$LUNCOSIM_BIN --api 4101Ground-physics simulator; an explicit --scene launch opens View, while Modelica lives under the modelica_analyze perspective — switch to it (below) before diagrams/plots render.
luncosim-server$LUNCOSIM_SERVER_BIN --api 4101Headless LunCoSim host; use the GUI luncosim command for the workbench.

In luncosim, switch to the Modelica view before plotting/screenshotting. The compile/run/experiment commands and query providers work regardless (they're headless-safe), but the diagram/plot panels only paint when their perspective is active. Switch with:

bash
curl -s -X POST http://127.0.0.1:4101/api/commands -H "Content-Type: application/json" \
  -d '{"type":"ExecuteCommand","command":"ActivatePerspective","params":{"id":"modelica_analyze"}}'
# other ids: "sandbox_view", "rover_build". Reset a broken layout: {"type":"ExecuteCommand","command":"ResetWorkspaceLayout","params":{}}
  • Add --no-ui for a headless compile/run server (no window, no GPU). The API surface is identical; screenshots, diagrams, and 3D viz are what you lose (so perspective switching is moot). GetExperimentResult/SnapshotVariables still give full numeric results headless.
  • Use production luncosim for scene-test and visual evidence. Use luncosim-server or luncosim --no-ui for numeric/API evidence only, and report the binary, revision, readiness state, and evidence type separately.
  • Launch your own session on an explicitly free API port. Never reuse or stop another session. Verify PID, executable, and checkout before controlling your session; use its API Exit and verify shutdown before replacing its binary.
  • Standalone Modelica ports exclude entities with SimComponent; the co-simulation backend owns their topology publication. Live sample changes must not invalidate resolved handles without a structural contract change.
No-API alternative

The standalone runner is owned by lunco-modelica-execution, not lunco-modelica-core. For a one-shot current-source compile and fixed-step solve with CSV output:

bash
cargo run -p lunco-modelica-execution --bin modelica_run -- \
  assets/models/AnnotatedRocketStage.mo AnnotatedRocketStage.RocketStage \
  --duration 30 --dt 0.001 --input valve_command=0.7 \
  --record altitude,velocity --output /tmp/run.csv

This runner uses the shared compiler and solver path, but it is not a substitute for the active Twin/API test when the source depends on Twin-indexed packages, Editor state, or scene composition.

Wait for readiness with an until loop (never chained sleeps):

bash
until curl -s -o /dev/null -X POST http://127.0.0.1:4101/api/commands \
  -H "Content-Type: application/json" \
  -d '{"type":"ExecuteCommand","command":"Ping","params":{}}'; do sleep 1; done

Stop with the Exit command (never pkill/kill — those need user confirm):

bash
curl -s -X POST http://127.0.0.1:4101/api/commands \
  -H "Content-Type: application/json" -d '{"type":"ExecuteCommand","command":"Exit","params":{}}'
Structured package lookup
Attach a Modelica source to a USD body

For a multi-domain run, use the shared AttachProgram { doc_id, spec } command instead of writing marker components or maintaining a separate binding table. The spec authors the LunCoProgramAPI child, explicit scalar inputs and outputs, and native USD connections in one journaled change set. In Rhai the same surface is assembly_edit::attach_program(...) with assembly_edit::program_input_connection(...), assembly_edit::program_input_default(...), and assembly_edit::program_output(...) helpers. Verify the result with ListPorts, CosimStatus, and GetBrokenConnections; a source without declared ports is reported as source-only and does not step.

Modelica packages under assets/models/<Root>/ and inside a Twin use the standard package.mo/package.order layout and members' within declarations. A Twin may declare [modelica].paths (Twin-relative, with "." meaning the Twin root) and externals in twin.toml. Without that section, the Modelica owner derives roots from the indexed Twin .mo files, so package discovery does not depend on a hard-coded folder. A qualified reference such as LunCo.Electrical.Battery is resolved by its root segment through the normal Modelica search-path inventory; do not add a library-specific Rust load call. Every live compile admits its required roots through the existing LoadSourceRoot worker path before it sends Compile. File-backed source assets carry root requirements from their prepared AST interface, document compiles derive them from the primary and sibling ASTs, and a generated policy's source_roots list is its required root manifest. The worker commits root preparations in admission order before compilation, rejects unadmitted roots, and reports failed roots without retrying synchronous discovery. Synchronous compiler helpers remain for CLI and batch callers. The worker's successful load acknowledgement carries the authored top-level namespaces parsed by that exact source-set operation. The registry retains those names on the scoped owner entry, and compile admission resolves each qualified namespace to its unique source-set ID. Missing or ambiguous namespace ownership is a terminal diagnostic. Failed or stale acknowledgements cannot publish Ready or recreate a retired namespace; Twin close removes the entry and its names. Verify Twin package admission through the existing authored path_interoperability.rhai namespace assertions: load a Twin package, compile a separate wrapper using its qualified member, inspect the solved output, then verify a missing namespace produces a terminal compile error. An unqualified source asset already present in an admitted root compiles the root-owned class only when its exact source CID is in the admitted content closure. Changed or conflicting source text is rejected; update and readmit the source root before compiling it. This prevents a second URI from duplicating the same root definition while preserving the root's authority. The policy list does not replace composed USD facts for member-class discovery. The worker's prepared-solve cache keys library state from the revisions that ModelicaCompiler records while admitting source roots. Its source key is captured from the successful strict compiler's participating-source closure before clearing user overlays. Generated class/network-title identity is normalized; equations, parameters, initial values, participating siblings, and contributing library bytes remain structural. Unrelated sibling edits and runtime document IDs do not invalidate prepared solve IR. The captured key remains with the immutable DAE through shared reuse and resets; the precompile DAE cache uses the full submitted input set until the strict closure is known. It does not scan the complete Modelica tree during the first live stepper build.

For preparation evidence, use actual owner INFO logs: cache=memory-hit at in-memory admission, cache=disk-hit after persistent lookup, and cache=miss when lowering runs. Disk preparation includes lookup, lowering, and total duration plus the source key. Stepper construction is not evidence of cache reuse.

Generated USD networks compile their complete synthesized source plus admitted source roots; unrelated editor documents are not sibling inputs. The reserved bundled generated/ filename namespace drives provenance and structural cache classification. Verify repeat-load cache reuse while changing document-open order; authored Modelica documents retain their multi-document source sets.

Domain discovery does not resynthesize ordinary scene-owned networks when a content prim receives its GID: that identity does not enter their namespace. Instance-scoped identities and unsettled provenance remain discovery inputs, alongside prim paths, stage revisions, wiring, and member-source events.

Initial network results may publish as a bounded four-root prefix only while their own fixed-clock admission hold is present and no prior projection is installed. Live replacements remain one per Update; repeated results for a root wait for ECS publication. Worker completion never bypasses the oldest request or its Twin/stage/instance validation.

On native runs, one dedicated Rumoca actor owns the mutable session and shared DAE cache. Source-root installation, Compile, Reset, parameter updates, and cache-invalidating Step auto-init share a FIFO. The worker commits results in submission order after entity-session and library-generation checks; a Step that needs a rebuild resumes only after its initialization commits. These continuations leave the Modelica command owner free to service other entities, and actor requests plus solve preparations share bounded admission. Persistent solve-cache reads and writes run with DAE lowering in the preparation pool; the native owner thread does not perform cache I/O or fall back to synchronous lowering. Wasm keeps compilation inside its Modelica Web Worker.

Shared immutable RAM caches use the captured lunco_modelica_runtime::ModelicaCacheLimits resource: positive compiled and prepared entry capacities, each defaulting to 64 per worker. Follow the Modelica cache contract for configuration timing, FIFO reuse, and browser startup/respawn admission. Entry caps bound graph count rather than heap bytes; eviction preserves live owners. Run the generic immutable_reuse_cache_ tests and compile the browser worker bundle when changing configuration transport. Do not infer Twin teardown from shared immutable cache contents. For shared browser worker transport changes, run the generic worker_lifecycle_ tests in a real browser and compile both Modelica execution and DEM bake consumers. Replacement must release the old handlers, including replacement inside an executing callback; failed replacement leaves an empty slot. For native compiler heartbeat changes, run the generic compile_heartbeat_ lifetime tests; ensure normal, error, and unwind exit interrupt the wait and release the owned thread.

Native optional solve-cache reuse captures the cache-owned lunco_modelica_worker::worker::PreparedSolveDiskLimits resource before ModelicaExecutionPlugin starts the worker. Defaults are 32 retained records, 64 MiB compressed, 256 MiB decoded, and a 64 MiB zstd window; see the cache ownership contract for valid ranges and configuration timing. Missing records are cache misses; rejected existing records warn and recompute admitted equations. Invalid limits are a typed worker startup failure. For decode changes, run the generic prepared_solve_disk_cache_ tests; do not substitute repository models for the inline-storage boundary fixtures. For publication/retention changes, also run persistent_solve_cache_ and storage cache_directory_transaction_ tests, including the native Windows CI path. Keep heavy encoding outside the storage transaction; never remove its lock file or broaden retention beyond the owned cache namespace. Optional publication failures warn while preserving the admitted solver result.

On native desktop startup, cache-miss solve-IR lowering runs in the worker's bounded preparation pool because the DAE input and solve options are immutable. The worker alone commits the resulting solve model and constructs the live stepper; Step, Reset, parameter updates, and source-root changes remain ordered behind that commit. Persistent solve-IR entries are keyed by structural source identity, the content-sensitive admitted-library revision, solver, and parameter overrides. A source-root change clears worker-local prepared models while retaining disk entries for future matching revisions. Readiness is still the completion barrier, so physics must not be started before /api/ready reports ready=true, world_hold=false, and pending_count=0.

Bundled and workspace source roots are parsed to completion before admission and installed as one parsed source set. A failed member therefore keeps the root out of the Rumoca session; do not treat a nonzero parsed count as readiness.

The registry marks each root as Application- or Twin-owned. Twin root IDs include the stable Twin ID. TwinClosed removes only that Twin's source sets and queues ordered unloads to the Rumoca actor; other Twin and application roots remain.

Twin closure also retires its open Modelica documents through the core CloseDocument owner, including linked execution entities. Workspace replacement closes every editor document before TwinAdded; unfinished UI preparations are canceled and file-read completions are fenced by their admitted runtime owner. Individual document closure also cancels parse preparation, save-close continuations, and document-owned modals before retiring the editor state. Reopening the same Twin starts fresh. RestartScene leaves editable documents resident while rebuilding their scene-owned execution.

Operation IDs fence an in-flight file read from installing a source set after its owner closes. If the worker has not created its channel yet, pending unloads stay queued and are sent before a later Twin load. A disconnected channel is a terminal unload failure: it reports a runtime fault, retains the queued operation, and blocks later Twin root admission instead of retrying on every update.

For policy-owned generated models, keep contract assertions in authored assets/scenarios/tests/*.rhai scenes; standalone live probes may use assets/scripting/tests/*.rhai. Rust should provide the composed facts and invoke the registered policy; Rhai should assert the generated source, topology, layout, and UI metadata. The policy result is strict: it must return source, units, layout.units, layout.members, source_roots, and member_output_aliases (the last may be an explicit empty array). Missing or invalid fields are projection errors; do not add a Rust-side generated-model fallback. layout.units uses root-diagram coordinates, while each entry in layout.members is local to the owning unit diagram; member overlaps are checked within that unit coordinate system.

On native development checkouts, the active prelude and policy files are read from assets/scripting/ at startup, so Rhai edits require a restart rather than a Rust rebuild. A present editable directory is authoritative: unreadable or empty directories and parse failures are errors. Packaged/wasm builds use their compiled-in asset set because no editable source tree is available.

When reviewing a generated diagram, click its generated browser row first. A single-unit network opens the unit-level class and shows its real members; multi-unit networks open the root wrapper. Use FitCanvas after drill-in when the tab was opened alongside the root, since navigation is scoped to the focused Modelica tab.

For electrical generated networks, verify the unit diagram's labelled power bus and follow at least one routed connect(...) branch through the rail. The Rhai policy uses readable network_system/network_unit_N unit instances and a topology-derived hub with adaptive branch lanes, so inspect a larger network with FitCanvas rather than assuming the six-member demo's geometry scales. Components that need directional presentation apply LunCoModelicaTopologyAPI with source, storage, or load; this metadata does not alter acausal solver direction. Member icons must resolve from their native Modelica classes; a fabricated card or direct solar-to-motor wire is a projection defect, not an acceptable fallback.

When an authored Modelica endpoint also carries InputPorts, that component is the single public command boundary. SetPorts and Rhai writes land there, and the generic Modelica bridge mirrors only names accepted by the compiled model into its solver input buffer. External live SetPorts commands with a stable producer id enter the shared next-fixed-tick queue and are captured as ordered named writes; Simulation-clock Rhai writes remain derived behavior. Do not add a vehicle-specific setter. External API/direct and non-Simulation Rhai ReleasePort/ReleaseControl commands use the same producer identity and ordered session boundary. Releases clear local holds only; Twin policy sends explicit setpoints with SetPorts. Battery empty events use the authored 0.1% usable-storage reserve in Battery.mo, not a solver-epsilon comparison.

Node movement has two valid outcomes. On an editable .mo document, drag a component and verify that the standard annotation(Placement(...)) changes in the source and survives a re-projection. On a generated document, the canvas is intentionally read-only because USD plus the Rhai policy owns the source; use Duplicate to edit, then perform the same placement check. A drag that appears to work but disappears on reload is a product bug, not an acceptable generated-model editing mode.

Use the shared AST strip_within_prefix for qualified lookup and editing; similarly spelled package prefixes must not match an authored within package. Reuse the AST's qualified_name_segments and parent_qualified for class paths; quoted identifiers containing dots remain one segment. Extraction checks do not prove the compiler accepts that qualified name: validate compilation separately through its actual command/error boundary.

For class source extraction, reuse lunco-modelica-ast::ast_extract::class_full_text_span from the same parsed bytes. Its inline seam test covers same-line enclosing declarations and class qualifiers; do not derive declaration bounds by scanning backward through arbitrary identifiers. Read-only library views also require exact qualified identity. The generic library extraction seam checks sibling leaf names and a missing sibling without reading repository fixtures.

Duplicate admission pins its original target scope and resident source snapshot. Check an exact nested qualified class when sibling packages share a short name; known-source errors must report failure without installing a substitute document. Closing the source or target lifetime during preparation must cancel publication and release pending names, tabs and status. Use inline parser tests for span and rewrite boundaries, and authored Rhai commands/queries for these public lifecycle outcomes. assets/scenarios/tests/modelica_duplicate_lifecycle.rhai exercises qualified siblings and quoted names, error diagnostics and exact-name reuse, observed pending source-close cancellation, original-target Twin replacement without retagging, and a valid successor. Run it in a UI-capable host with Application/Retain lifetime and API-authored root_a, root_b, entry_scene fixtures. Asynchronous folder scanning permits a duplicate to install while its old Twin is live; the gate preserves that valid retained-source outcome. Exact Twin/connection retirement of never-ready tasks belongs to the generic resource seam test, since public folder replacement cannot force that worker boundary. Native preparation runs on the existing task pool; browser Bevy tasks retain the browser editor's deferred parsing contract.

Projection must remain responsive while a native package or inherited icon is being resolved. Verify that /api/ready stays responsive, the canvas shows an explicit loading/error state, and the completion event reprojects the authored icons. Do not add a synchronous parse, mutex wait, invented icon, or domain specific visual retry path to hide a miss.

Energy-flow animation is generic Modelica behavior, not generated-policy code: LunCo.Electrical.Pin.i is a standard flow Real, just like the rocket and lander FluidPort flow variables. Confirm the connector projection reports the flow variable and that a non-zero live instance.p.i moves dots along the rendered edge; zero current must remain visually idle. If dots are absent, inspect the flow metadata and node-state keys at the shared canvas owner before adding any policy-specific renderer.

1. The request envelope

Everything is one endpoint: POST /api/commands. The JSON shape is always {"type":"ExecuteCommand","command":"<Name>","params":{...}}. Always include params even when empty ("params":{}) — this keeps every request explicit and discoverable.

bash
curl -s -X POST http://127.0.0.1:4101/api/commands \
  -H "Content-Type: application/json" \
  -d '{"type":"ExecuteCommand","command":"<Name>","params":{ ... }}'

Two kinds of command share this envelope:

  • Commands (fire-and-forget mutations): return {"data":{"accepted":true}}; result-returning commands put their command-specific payload in the same data envelope. Invalid parameters return HTTP 422. A deferred command may complete its command acknowledgement later on the same request; that acknowledgement is not necessarily completion of the domain work. In particular, RunExperiment returns its exact experiment_id once the run is registered, while the numerical solve continues asynchronously.
  • Query providers (return data): return the payload directly, e.g. {"runs":[...]}. ListRuns, GetExperimentResult, DescribeModel, SnapshotVariables, CompileStatus, GetDiagnostics, ListCompileCandidates, ListBundled, ListOpenDocuments, FindModel are all query providers — invoked with the same tagged ExecuteCommand form. Built-in discovery and entity listing use their own explicit type values.

doc_id: 0 always means "the active document/tab".

2. Two run modes — pick the right one

Interactive (live)Batch (Fast Run / Experiment)
VerbRunActiveModelFastRunActiveModel / RunExperiment
Pacewall-clock realtime, steps foreveras fast as possible, t_start→t_end, then stops
Use forinspection, physics-in-loop, 3D viz, possessionparameter sweeps, regression, "what if I bump this constant?"
Read resultsSnapshotVariables (live), ReadPorts/WatchPortsGetExperimentResult (full trajectory)
Poke inputsSetModelInput (admitted for the next fixed tick in a live session)overrides baked into the run request
Stored aslive stepping modelfirst-class Experiment in the registry (plot/compare)

3. Recipe A — run a model live (interactive)

bash
API=http://127.0.0.1:4101/api/commands
post(){ curl -s -X POST $API -H "Content-Type: application/json" -d "$1"; }

# 1. Open a model. Prefer the unified opener (bundled example / qualified source-library name / path):
post '{"type":"ExecuteCommand","command":"Open","params":{"uri":"bundled://SpringMass.mo"}}'
#    bundled://Name.mo | Modelica.Blocks.Examples.PID_Controller | /abs/path.mo | mem://Untitled
#    List embedded examples first: {"type":"ExecuteCommand","command":"ListBundled","params":{}}

# 2. Wait for the AST parse (background). Poll CompileStatus until ast_parsed:true:
post '{"type":"ExecuteCommand","command":"CompileStatus","params":{"doc_id":0}}'   # -> {state, ast_parsed, candidates, picker_pending, ...}
#    Read parser/compiler/lint findings and actionable Rumoca suggestions.
#    Poll while complete is false; pending is not a clean result.
post '{"type":"ExecuteCommand","command":"GetDiagnostics","params":{"doc_id":0}}' # -> {state,complete,channels[],diagnostics:[{domain,source,code,severity,message,uri,line,column,suggestion}]}

# 3. Compile + play. class REQUIRED if the file has >1 non-package class
#    (the GUI picker can't be shown over the API). Discover choices:
post '{"type":"ExecuteCommand","command":"ListCompileCandidates","params":{"doc_id":0}}'   # -> {candidates:[{qualified,short}]}
post '{"type":"ExecuteCommand","command":"RunActiveModel","params":{"doc_id":0,"class":"SpringMass"}}'

# 4. Read live values (t + parameters + inputs + variables). Filter with names:
post '{"type":"ExecuteCommand","command":"SnapshotVariables","params":{"doc_id":0,"names":["x","v"]}}'

# 5. Poke a runtime input live (no recompile, admitted for the next fixed tick):
#    For an open workbench model, use doc_id and keep producer_id stable.
post '{"type":"ExecuteCommand","command":"SetModelInput","params":{"doc_id":0,"name":"F","value":10.0,"producer_id":4101}}'
#    For a live Twin participant, use its stable target_gid from ListEntities
#    and leave doc_id at 0; do not pass both selectors.
post '{"type":"ExecuteCommand","command":"SetModelInput","params":{"doc_id":0,"target_gid":123456,"name":"throttle","value":0.5,"producer_id":4101}}'

# 6. Pause / Resume / Reset / Restart:
post '{"type":"ExecuteCommand","command":"PauseActiveModel","params":{"doc_id":0}}'
post '{"type":"ExecuteCommand","command":"RestartActiveModel","params":{"doc_id":0}}'   # reset t=0 then run

RunActiveModel = compile-if-stale then play. If already compiled & clean it just unpauses (no recompile). CompileModel compiles only (stays paused); ResumeActiveModel unpauses only.

If a live compile fails on an unbalanced DAE, its ordinary Modelica Error event in Recent status events explains why simulation did not start and lists the unknowns Rumoca's structural matcher could not pair with equations, plus their categories and referencing equation rows. Selecting the row expands the full message. GetDiagnostics also returns the explanation with the structured compiler findings. Those names identify values the current equations cannot determine; add or correct independent equations or constraints. The diagnostic DAE is never simulated.

Show full SKILL.md (2,468 more words)Show less

4. Recipe B — build an experiment (batch + parameter sweep)

RunExperiment is the agent-facing sweep verb: overrides come from the command, not the UI, so you can sweep parameters without touching source. Each run is stored as an Experiment. Its command acknowledgement contains the exact experiment_id after registration; the acknowledgement is not a completed numeric result. Retain that id, poll RunStatus with it, and read the trajectory with GetExperimentResult using the same id. Do not identify a run by its label or by whichever run is newest.

Runs capture their exact ExperimentOrigin at admission: a pinned local document runtime lifetime or an authenticated replicated connection/mount. Presentation grouping never determines ownership. Definition replay under another origin rejects before mutation; same-origin replay preserves terminal history. Closing that Twin cancels unfinished runs and retires late updates and playback signals; completed results stay queryable within the bounded history. Loose-document runs have application lifetime. A run's execution definition freezes when its registry row becomes Queued, before runner admission. Change bounds, parameters, or inputs by creating a new run; retained results keep the definition that produced them. An identical definition replay preserves later display labels and results, and conflicting replay is rejected visibly. A completion must match its immutable pending-handle origin before registry publication. A completion from an inactive Twin cannot automatically select the replacement Twin's plot, and a different pinned experiments document cannot receive its automatic plot selection. Registry deletion and bounded eviction also remove the retained document/owner attribution and plot visibility. Closing a Twin retires its document pins and archived plot selections. A run receives immutable source text at admission, and annotations are read from its current document; a same-name model in another Twin cannot supply either. Native cancellation uses the admitted run flag at evaluation and simulation-driver checkpoints. An executing numerical kernel returns before its next checkpoint; no cancelled trajectory publishes, and worker exit releases the scheduler slot.

For a production lifecycle regression, admit a run from a Twin document and queue another behind it, replace the Twin, then query both exact run ids for Cancelled. Verify the replacement's plot and playback signals receive no old completion. Include an application-owned loose-document run as a negative ownership case, plus a completed run whose retained result remains readable. For the same-name source/bounds regression, launch RunScenarioAsset with source_asset: "lunco://scenarios/tests/modelica_run_admission_isolation.rhai" in an owned UI-capable Modelica host. Its bounded asynchronous gate uses two scratch documents, the ordinary RunExperiment acknowledgements and exact run ids, and verifies that the unannotated document keeps the one-second default and each trajectory retains its own admitted source. Require the authored MODELICA_RUN_ADMISSION_ISOLATION verdict; launch acceptance alone is insufficient.

bash
# One run with a parameter override + custom bounds + a label:
post '{"type":"ExecuteCommand","command":"RunExperiment","params":{
  "doc_id":0, "class":"RocketStage",
  "overrides":[{"name":"Isp","value":"300"}],
  "inputs":[{"name":"throttle","value":"1.0"}],
  "t_start":0, "t_end":120, "n_intervals":600,
  "solver":"bdf", "tolerance":1e-6,
  "label":"Isp=300"
}}'

Sweep = loop the same call with different overrides + labels (one run each):

bash
for isp in 280 300 320 340; do
  post "{\"type\":\"ExecuteCommand\",\"command\":\"RunExperiment\",\"params\":{\"doc_id\":0,\"class\":\"RocketStage\",
    \"overrides\":[{\"name\":\"Isp\",\"value\":\"$isp\"}],
    \"t_end\":120,\"n_intervals\":600,\"label\":\"Isp=$isp\"}}"
done

overrides / inputs are [{name, value}] with string values (string injection, v1). overrides = top-level parameter literals; inputs = runtime input variables.

Bounds & solver semantics
  • t_start / t_end — sim horizon (seconds). Default from model annotation.
  • dt — output Interval (seconds between samples). Mutually exclusive with…
  • n_intervals — output NumberOfIntervals: emits n+1 evenly-spaced samples. Takes precedence over dt when set.
  • tolerance — solver tolerance.
  • solver — family: "bdf"|"dassl"|"ida" → BDF; "esdirk34"|"rk"|"dopri"|"trbdf2" → ESDIRK34; "auto"/omit → backend default (BDF).
  • h0 — initial step size (seconds).
  • Omit any field to fall back to the model's experiment(...) annotation, then the backend default.

Bounds admission rejects nonfinite or non-increasing horizons, nonpositive explicit dt, tolerance, or h0, and output grids exceeding 200,000 intervals. n_intervals must be positive. Rejection returns the owning error without registering a run or changing the requested grid. A used authored NumberOfIntervals must also be a finite positive integer within that limit; only authored Interval=0 has the documented omitted-spacing meaning. QueryExperimentBounds reports invalid annotation bounds as a query error. Production regression: attach lunco://scenarios/tests/modelica_run_bounds_admission.rhai with RunScenarioAsset to an addressable loaded scene root in an owned Modelica host. It checks rejected explicit and authored bounds leave no experiment rows, then requires a valid successor to complete.

FastRunActiveModel is the same batch engine but reads bounds from the UI "Simulation Setup" draft instead of the command — prefer RunExperiment for scripted/agent runs so everything is explicit.

For Rhai callers, cmd("RunExperiment", ...) can return a pending command record while the deferred acknowledgement is being assembled. Poll command_result(command_id) only until that acknowledgement supplies the experiment_id; then poll RunStatus by that exact experiment id. The modelica_editor::experiment_ticket / poll_experiment_ticket helpers wrap both phases in a bounded, non-blocking caller-owned ticket. Keep the returned ticket across ticks, and do not block the Editor/Rhai thread in a wait loop. The ticket also binds readback to the explicit Modelica document and source generation so a changed model cannot be mistaken for the solved source.

5. Recipe C — read experiment results

bash
# List runs (newest first). Optional {"doc_id":N} filter. Each row is self-describing:
# experiment_id, name, state (Pending|Queued|Running|Done|Failed|Cancelled),
# wall_time_ms, the overrides that produced it, and the bounds it ran under.
post '{"type":"ExecuteCommand","command":"ListRuns","params":{}}'

# Pull a full trajectory: times + series (dotted Modelica path -> samples).
# For an explicit RunExperiment, always use its exact experiment_id:
post '{"type":"ExecuteCommand","command":"GetExperimentResult","params":{
  "experiment_id":"<id returned by RunExperiment>",
  "variables":["altitude","velocity"], "max_points":500
}}'
# max_points = strided downsample, final sample always kept. Omit = uncapped.
# Returns {state:"Done", times:[...], series:{"altitude":[...], ...}} or an
# error if the run is not Done (Pending/Running/Failed-without-partial).

RunStatus is the query provider for one run's progress and terminal state:

bash
post '{"type":"ExecuteCommand","command":"RunStatus","params":{"experiment_id":"<exact id>"}}'

Poll until done, failed, or cancelled; only request the trajectory after done. ListRuns is useful for discovery and UI review, not as a substitute for retaining the id returned by the dispatch you just made.

A native worker panic, thread-admission failure, or disconnect without a terminal result produces failed with its cause and retires the handle. Live-worker startup or transport failure produces a worker-wide typed diagnostic, holds the affected simulation, and rejects subsequent live compiles. Scene reload does not restart a failed application worker; restart the owned app after resolving the reported startup problem. The scheduler releases the worker slot on every exit. A compiler poisoned by a panic rejects subsequent compilation visibly; treat that diagnostic as a failed run rather than polling indefinitely.

Cancel / clean up:

bash
post '{"type":"ExecuteCommand","command":"CancelExperiment","params":{"all":true}}'           # or {"experiment_id":"<uuid>"}
post '{"type":"ExecuteCommand","command":"DeleteExperiment","params":{"all":true}}'           # terminal runs only
post '{"type":"ExecuteCommand","command":"RenameExperiment","params":{"experiment_id":"<uuid>","name":"baseline"}}'

6. Recipe D — visualize & compare runs (plots)

How the experiment→plot model works

The Experiments panel is the comparison view — unlike Dymola/OMEdit you don't juggle .mat filenames. It's one multi-series plot that draws a curve for every visible run × every picked variable. So:

  • Variables you pick (e.g. altitude, velocity) = which series shape.
  • Runs that are visible = which experiments overlay on top of each other.
  • A 4-run Isp sweep with 1 picked variable → 4 curves (one per Isp), auto- labeled by run. Pick 2 variables → 8 curves. Comparison is the default.
  • New runs overlay automatically as they finish Done — no re-plotting.

Two pickers live on the panel header (GUI): ▾ Variables N/M (which signals) and ▾ Runs (which completed runs to overlay). Y-axis auto-groups by unit.

Driving it from the API
bash
API=http://127.0.0.1:4101/api/commands
post(){ curl -s -X POST $API -H "Content-Type: application/json" -d "$1"; }

# Open a plot tab seeded with the variables to compare across runs.
# source=0 = fresh panel; source=<VizId> = clone another plot's signal set + picks.
post '{"type":"ExecuteCommand","command":"NewPlotPanel","params":{"title":"Ascent","signals":["altitude","velocity"],"source":0}}'

# Add another signal to an existing plot (plot=0 = the default graph):
post '{"type":"ExecuteCommand","command":"AddSignalToPlot","params":{"plot":0,"signal":"mass"}}'

signals in NewPlotPanel become the plot's picked variables; every completed run then contributes those series. Run one sweep (§4), open the plot once with the variables you care about, and each new run lands on the same axes.

Typical end-to-end: sweep → compare
bash
# 1. sweep 4 runs (see §4 loop) with labels Isp=280..340
# 2. open the comparison plot on the variable of interest
post '{"type":"ExecuteCommand","command":"NewPlotPanel","params":{"title":"Isp sweep","signals":["altitude"],"source":0}}'
# 3. confirm the runs landed, then screenshot for the human
post '{"type":"ExecuteCommand","command":"ListRuns","params":{}}'
curl -s -X POST $API -H "Content-Type: application/json" \
  -d '{"type":"ExecuteCommand","command":"CaptureScreenshot","params":{}}' -o /tmp/sweep.png   # then Read the PNG
Numbers vs pixels
  • Analysis / assertions → GetExperimentResult (§5). Raw times+series; compare runs by fetching each experiment_id and diffing arrays. Never scrape a plot widget for values.
  • Show the human → CaptureScreenshot (needs the UI build, not --no-ui).
  • Export → CSV: the GUI's per-panel CSV export mirrors GetExperimentResult; for scripted export just persist the GetExperimentResult JSON yourself.

7. Command & query catalog

Discovery / docs

commandparamsreturns / effect
Ping{}readiness check
CreateNewScratchModel{source, name}create a Modelica Editor document and return its exact doc_id
ListBundled{}embedded example models (bundled:// URIs)
FindModel{query, limit?}fuzzy search examples/Twin/source libraries/open docs → URIs
Open{uri}open bundled/source-library/path/mem into a tab
ListOpenDocuments{}doc_id, title, kind, origin, dirty, active per tab
DescribeModel{doc, class?}AST: components, connections, inputs, parameters, outputs (pre-compile)
CompileStatus{doc}state, ast_parsed, candidates, picker_pending, drilled_in_class
GetDiagnosticsexactly one of {doc_id} or {scope}shared parser/compiler/lint diagnostics; poll complete, then read channel states, stable codes, source locations, and suggestions. scope is loaded_stages or twin
ListCompileCandidates{doc}{candidates:[{qualified,short}]} — the picker choices

Compile & run

commandparamseffect
CompileModel{doc, class?, force?, resume_after_compile?}compile only (stays paused)
RunActiveModel{doc, class?}compile-if-stale + play (live)
PauseActiveModel / ResumeActiveModel / ResetActiveModel{doc}live stepping control
RestartActiveModel{doc}reset t=0 then run
FastRunActiveModel{doc, class?, t_end?, dt?, n_intervals?, tolerance?, solver?, h0?}batch, bounds from UI draft
RunExperiment{doc, class?, overrides[], inputs[], t_start?, t_end?, dt?, n_intervals?, tolerance?, solver?, h0?, label?}dispatch a batch run; acknowledgement returns exact experiment_id
SetModelInput{doc_id, target_gid?, name, value, producer_id?}select an editor model by doc_id or a live Twin participant by target_gid; live API, direct typed, and actorless Rhai callers need a stable nonzero producer_id
ConfirmClassPicker{qualified?, cancel?}only if a picker modal opened in the GUI

Results & viz

commandparamsreturns / effect
SnapshotVariables{doc, names?}one-shot live {t, parameters, inputs, variables}
ListRuns{doc?}experiment rows (newest first)
RunStatus{experiment_id}one run's progress/terminal state
GetExperimentResult{experiment_id? | doc, variables?, max_points?}full trajectory {times, series}
CancelExperiment / DeleteExperiment / RenameExperimentsee §5run lifecycle
NewPlotPanel / AddSignalToPlotsee §6plotting
CaptureScreenshot{}raw PNG bytes (save -o, then Read)

8. Gotchas

  • Direction-to-joint controller: write the coordinate contract before changing equations: world direction, inverse mount frame, joint axes/order, and the mesh's physical boresight. A compiling model or its own zero error is insufficient; inspect the live direction inputs, setpoints, measured joint angles, and rendered mechanism after a full scene reload.

  • Missing params → silent no-op. Always send "params":{}.

  • Multi-class file → compile/run need class. Without it, if >1 non-package class the run aborts with picker_pending (the GUI would show a modal). Call ListCompileCandidates first, pass the short or qualified name.

  • Fire before parse → no compilable top-level class. Poll CompileStatus until ast_parsed:true before compiling/running a just-opened doc.

  • GetExperimentResult errors unless the run is Done (or Failed with a partial). Check ListRuns state first; a big sweep runs async.

  • Unified opening: prefer Open{uri}. OpenClass resolves a Modelica class through the source-aware document/library path; OpenFile resolves a filesystem URI.

  • File lifetime: native file opens pin canonical local/replicated root ownership before installation; browser mounted files read OPFS, while picker/private saves have Application lifetime. Closing the admitted owner retires file work even when the source remains in the editor registry. Dirty source cannot transfer owners through a path reopen; save or close it before a clean explicit reopen. Alias reopens resolve source and resident identities on the file worker. Their captured owner/generation must still match at install, so a late read cannot replace a concurrently changed or newly installed different-owner source.

  • Browser imports and saves: shared picker results carry request-owned bytes into the existing asynchronous file-load pipeline; same-name picks create distinct pathless Application documents. Browser Save marks the document saved only after download admission succeeds. Verify cancellation/read failure, same-name overlapping reads and App teardown through the shared picker browser tests; see the picker owner contract.

  • Portable Twin saves: Save All and Save As Twin preflight generated filenames with the shared lunco-assets-path component validator before any save or manifest command. Reserved device names (even with .mo), final dots/spaces and forbidden characters reject visibly; no replacement filename hides invalid state. Rename uses lossless command paths and confines the actual source parent through Storage. Verify name algebra with the asset-path tests and source scope through the authored modelica_save_all_scope.rhai production gate; these prove different boundaries.

  • Complete result admission: finite ordered times, matching series/metadata lengths, and finite values are required before a trajectory is marked Done. experiments.result_limits supplies the shared budgets; defaults are 8,000,000 scalar values and 256 MiB artifact bytes. Failed partial streams may retain explicit missing-value holes. A malformed optional artifact warns without replacing a valid runtime result. Native and browser Fast Runs capture the same limits at admission. Actual lowered output dimensions and the requested grid are checked before batch trajectory allocation; event samples also consume the scoped recorder budget. Exercise modelica_output_budget.rhai with the documented default value cap and max_parallel=1 to prove visible rejection and valid successor completion.

  • Durable batch history: completed Twin-owned results persist asynchronously with their immutable definition and actual compiler source CID. Application runs have no Twin destination. Inspect source_cid and restored_history in GetExperimentResult; an archived result never claims the currently edited source or starts playback. Parsed-only contributing libraries without source bytes warn that persistence is unavailable while the run remains valid. Exercise modelica_artifact_history.rhai in fresh seed/restore sessions and verify the UUID artifact is durable before stopping the seed session. Seed creates a fresh Twin around its API-authored scene; restore opens the saved Twin through OpenTwin. Include a corrupt optional artifact and changed same-name source; history must retain its original CID and values. See the artifact owner contract.

  • File diagnostics: GetFile acknowledges asynchronous read admission. It uses the same captured native/OPFS source path as document opens; inspect its log text or structured read-error diagnostic. Closing the admitted Twin or replicated lifetime retires the pending request before publication.

  • Live ≠ batch: SnapshotVariables reads the live stepping model; GetExperimentResult reads a stored batch run. They are different objects.

  • Blank plot/diagram in luncosim → the Modelica perspective isn't active. ActivatePerspective{"id":"modelica_analyze"} before capturing (§0). In lunica it's already the whole app. Commands/results don't need it — only the visible panels do.

  • Don't restart to "start clean" — drive the API to add the state you need.

  • MCP fallback: if the user insists on MCP, every command above maps to an mcp__lunco__* tool (compile_model, run_scenario→rhai only, set_input, snapshot_variables, read_ports, describe_model, find_model, open_uri, list_bundled, list_open_documents). Batch experiment verbs (RunExperiment/ListRuns/GetExperimentResult) have no dedicated MCP tool — use curl (or the generic mcp__lunco__execute_command).

Solar generation and charging

Use the reusable components/power/solar_panel.usda probe and Sun-direction connections. A generated assembly exposes target_mount_x/y/z boundary inputs from the panel's Environment.outputs:sun_mount_* source; inherit the panel's input wiring. Keep parameters:area as a parameter and author only inputs that the current Modelica source declares.

Observe delivered power together with generated current and shared terminal voltage. The panel's public voltage/current/available-power channels target its physical USD prim and resolve through the generated participant. Bus voltage can remain positive at night while solar current is zero. To verify charging, use an owned session with a temporary partly discharged battery and observe SOC rising; a full pack cannot rise above 100%. Do not persist diagnostic battery overrides.

Omitted library inputs

Omitted inputs retain the owning Modelica library's defaults, including nested components in generated USD networks. Explicit authored inputs take precedence. The worker's initialized solver observation supplies runtime readback; do not copy defaults into each Twin to compensate for a lifecycle bridge replacing unbound slots with zero. Verify after advancing physics, not only at compile time.

Rumoca owns these defaults as qualified DAE input initialization expressions; internal and connected bindings remain equation-owned. Verify class and instance isolation, override, reset, batch execution, and invalid-default diagnostics with modelica_scoped_input_defaults.rhai in an owned production session.

Run the focused production regression after building the normal luncosim:

sh
LUNCOSIM_BIN=target/debug/luncosim LUNCOSIM_EPHEMERAL_SETTINGS=1 \
LUNCOSIM_ISOLATED_RUN=1 python3 scripts/api/run_editor_scene_test.py \
  --port 4261 --timeout 90 --scene scenes/fixtures/usd_query_api/site.usda \
  --scenario lunco://scenarios/tests/modelica_scoped_input_defaults.rhai \
  --log target/modelica-scoped-input-defaults.log

The fixture admits a Twin owner; the runner attaches the observer to that owner, requires a real Rhai verdict, then verifies API Exit and port release.

Modelica index warming reads LUNCOSIM_WARM_DIRS as the operating system's path list: colon-separated on Unix and semicolon-separated on Windows, so Windows drive letters remain intact. Shipped package roots use the fallible asset-library resolver; root failures are reported before admitting sources. USD participant/network source loads use the stage's prepared typed load address, retaining literal filenames and native reference admission during initial load and parameter recompilation. Program format selection preserves # in named/native filenames; HTTP source URLs use their path component when selecting the executor. Twin Modelica directories may use . to designate the admitted Twin root; the directory resolver preserves this manifest semantic without permitting parent traversal or using it as a concrete file address.

© LunCoSim, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/run-modelica of LunCoSim/lunco-sim.

Open the folder on GitHubat commit 43f1301

Compare with similar skills

Run Modelica next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Run Modelica compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Run Modelica this skillLunCoSim/lunco-sim107—~13kAutomated safety check: PassApache-2.0
Tandem Browserhydro13/tandem-browser616—~9.1kAutomated safety check: PassMIT
MCP Apps Builderawslabs/cli-agent-orchestrator1.4k—~1.7kAutomated safety check: PassApache-2.0
Openmaopenma-ai/open-managed-agents315—~854Automated safety check: PassApache-2.0
Pixiu MCP Gatewayapache/dubbo-go-pixiu567—~3.1kAutomated safety check: PassApache-2.0
Test MCPtomaspavlin/rohlik-mcp121—~593Automated safety check: NotesMIT

Similar skills

  • Tandem Browser

    hydro13/tandem-browser

    Use Tandem Browser's MCP server (local and remote agents) or HTTP API (local and remote agents) to inspect, browse, and interact with the user's shared browser safely.

    616 GitHub stars~9.1k tokensUpdated 8 days ago
    Agent WorkflowsAuto-check passed
  • MCP Apps Builder

    awslabs/cli-agent-orchestrator

    Official

    Load the official MCP Apps builder skills (create-mcp-app, migrate-oai-app, add-app-to-server, convert-web-app) from github.com/modelcontextprotocol/ext-apps.

    1.4k GitHub stars~1.7k tokensUpdated today
    Agent WorkflowsAuto-check passed
  • Openma

    openma-ai/open-managed-agents

    Use the openma platform to build, deploy, and manage AI agents.

    315 GitHub stars~854 tokensUpdated today
    AI & LLM EngineeringAuto-check passed
  • Pixiu MCP Gateway

    apache/dubbo-go-pixiu

    Creates and validates dubbo-go-pixiu MCP gateway conf.yaml. An agent skill from apache/dubbo-go-pixiu.

    567 GitHub stars~3.1k tokensUpdated 7 days ago
    Backend & APIsAuto-check passed
  • Test MCP

    tomaspavlin/rohlik-mcp

    Build and test MCP tools using direct API calls or MCP Inspector.

    121 GitHub stars~593 tokensUpdated 6 mo ago
    Agent WorkflowsAuto-check: notes
  • Clipmivo Video

    BarneyD66/clipmivo-tools

    Create and manage AI video tasks through ClipmivoAI using its MCP server, CLI or REST API.

    142 GitHub stars~945 tokensUpdated 24 days ago
    Media & CreativeAuto-check passed

More from LunCoSim/lunco-sim

All 40 skills in this repo
  • Nightly Changelog

    LunCoSim/lunco-sim

    Generate concise LunCoSim nightly GitHub release notes with platform downloads, installation guidance, an AI-agent mission prompt, and a changelog link.

    107 GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Build or repair a reusable scene component through a live LunCoSim Editor session.

    107 GitHub stars~4.4k tokensUpdated today
    Auto-check passed
  • Assembly Quality

    LunCoSim/lunco-sim

    Build or review a componentized LunCoSim USD assembly with a realistic, dimensionally checkable presentation.

    107 GitHub stars~1.6k tokensUpdated today
    Auto-check passed
  • Author Rhai Tests

    LunCoSim/lunco-sim

    Author and review LunCoSim behavioral, asset-backed, component, mission, visual, and requirements-verification tests.

    107 GitHub stars~3.5k tokensUpdated today
    Auto-check passed
  • Author Rhai Tool

    LunCoSim/lunco-sim

    Create, extend, register, or debug a reusable LunCoSim Rhai tool library for live USD authoring, component linting, inspection, or test support.

    107 GitHub stars~5.2k tokensUpdated today
    Auto-check passed
  • Author Tutorial

    LunCoSim/lunco-sim

    Author an interactive tutorial, guided lesson, onboarding flow, coach-mark tour, or objectives checklist in LunCoSim.

    107 GitHub stars~1.4k tokensUpdated today
    Auto-check passed

Questions about Run Modelica

What does Run Modelica do?

Recipe for running Modelica models and building experiments/graphs in lunica (LunCoSim), driven from the HTTP API with curl. Run Modelica is an agent skill from LunCoSim/lunco-sim. Recipe for running Modelica models and building experiments/graphs in lunica (LunCoSim), driven from the HTTP API with curl.

When should I use Run Modelica?

Run Modelica fits situations like: ever you need to: launch the workbench; open/compile a Modelica model; run it live (interactive realtime); as a fast batch.

How do I install Run Modelica in Claude Code?

Run `npx skills add LunCoSim/lunco-sim --skill run-modelica -a claude-code`. Or copy the skill folder (skills/run-modelica in LunCoSim/lunco-sim) into .claude/skills/run-modelica in your project. Claude Code loads it when a task matches its description.

How do I install Run Modelica in Codex?

Run `npx skills add LunCoSim/lunco-sim --skill run-modelica -a codex`. Or copy the skill folder (skills/run-modelica in LunCoSim/lunco-sim) into .agents/skills/run-modelica in your project. Codex loads it when a task matches its description.

Can I use Run Modelica in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add LunCoSim/lunco-sim --skill run-modelica -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/run-modelica, .gemini/skills/run-modelica, .github/skills/run-modelica and .opencode/skills/run-modelica in your project.

What does Run Modelica need to run?

Going by SKILL.md and its folder, Run Modelica needs the command-line tools its instructions call (curl, cargo and python3).

Does Run Modelica access the network?

SKILL.md contains no URLs. Its commands use curl, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Run Modelica safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Run Modelica use?

Run Modelica is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Run Modelica use?

About 13k tokens (SKILL.md is roughly 53k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Run Modelica?

Skills that share tags, products or a category with Run Modelica: Tandem Browser (hydro13/tandem-browser, 616 stars), MCP Apps Builder (awslabs/cli-agent-orchestrator, 1.4k stars), Openma (openma-ai/open-managed-agents, 315 stars) and Pixiu MCP Gateway (apache/dubbo-go-pixiu, 567 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Run Modelica?

LunCoSim (a GitHub organization) maintains it in LunCoSim/lunco-sim, which has 107 GitHub stars. The repository holds 40 skills in this directory. The repository was last updated on October 10, 2026.

Source: LunCoSim/lunco-sim on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.