Back to MCP Servers

Stella

Create, read, validate, and save Stella system dynamics models (.stmx files in XMILE format) for scientific simulation and modeling.

data-science-tools
By bradleylab
32Updated 2 weeks agoPythonMIT

Installation

npx -y stella-mcp

Configuration

{
  "mcpServers": {
    "stella-mcp": {
      "command": "npx",
      "args": ["-y", "stella-mcp"]
    }
  }
}

How to use

  1. Run the installation command above (if needed)
  2. Open your Claude Code settings file (~/.claude/settings.json)
  3. Add the configuration to the mcpServers section
  4. Restart Claude Code to apply changes

Stella MCP Server

A vendor-neutral Model Context Protocol (MCP) server for creating and manipulating Stella system dynamics models. Any compliant MCP client can build, read, validate, and save .stmx files in the XMILE format; optional host features still vary.

What is this for?

Stella is a system dynamics modeling tool used for simulating complex systems in fields like ecology, biogeochemistry, economics, and engineering. This MCP server allows AI assistants to:

  • Create models from scratch - Build stock-and-flow diagrams programmatically
  • Read existing models - Parse and understand .stmx files
  • Validate models - Check for errors like undefined variables or missing connections
  • Modify models - Add stocks, flows, auxiliaries, and connectors
  • Save models - Export valid XMILE files that open in Stella Professional

This is particularly useful for:

  • Teaching system dynamics modeling
  • Rapid prototyping of models through natural language
  • Batch creation or modification of models
  • Documenting and explaining existing models

Installation

From PyPI

pip install stella-mcp

From source

git clone https://github.com/bradleylab/stella-mcp.git
cd stella-mcp
pip install -e .

Requirements

  • Python 3.10+
  • mcp>=2.0.0,<3

Configuration

Via uvx (no install required)

If you have uv installed, the lowest-friction configuration runs the published package directly:

{
  "mcpServers": {
    "stella": {
      "command": "uvx",
      "args": ["stella-mcp"]
    }
  }
}

Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "stella": {
      "command": "stella-mcp"
    }
  }
}

Claude Code

Add to your .claude/settings.json:

{
  "mcpServers": {
    "stella": {
      "command": "stella-mcp"
    }
  }
}

Development mode

If running from source:

{
  "mcpServers": {
    "stella": {
      "command": "python",
      "args": ["-m", "stella_mcp.server"],
      "cwd": "/path/to/stella-mcp"
    }
  }
}

Recommended Agent Workflow

For a new model:

  1. On MCP 2026-07-28, call create_workspace and carry the returned workspace_id through stateful calls. Legacy stdio clients may omit it.
  2. build_model with a stable model_id and the full set of stocks, auxiliaries, and flows in one call (connector sync and validation run by default, so the response doubles as an inspection).
  3. Fix validation errors with update_*, rename_variable, or delete_variable.
  4. Extend incrementally with add_variables (batch) or the single-add tools.
  5. simulate to sanity-check behavior (requires the sim extra).
  6. Save with save_model.

For imported models:

  1. read_model with compat_mode="permissive" to inspect warnings.
  2. Run inspect_model to understand model structure.
  3. Use compat_mode="strict" before final save when round-trip fidelity matters.

Available Tools

Model Creation & I/O

ToolDescription
create_modelCreate a new model with name and time settings (start, stop, dt, method)
set_sim_specsUpdate simulation time settings on an existing model
read_modelLoad an existing .stmx file
save_modelSave model to a .stmx file
delete_modelRemove a model from the workspace (saved files untouched)

Templates

ToolDescription
list_templatesList built-in and user-defined templates (supports source/query/tag filters)
get_template_infoGet detailed metadata for one template
load_templateLoad a template as a model in the current workspace
save_as_templateSave the current model as a reusable user template (optional description/tags)

Model Building

ToolDescription
build_modelCreate and populate a model in one call (atomic batch)
add_variablesAdd multiple variables/connectors/modules to an existing model (atomic batch)
add_stockAdd a stock (reservoir) with initial value and units
add_flowAdd a flow between stocks with an equation
add_auxAdd an auxiliary variable (parameter or calculation)
update_stockUpdate stock fields while preserving relationships
update_flowUpdate flow fields while preserving stock links
update_auxUpdate auxiliary variable fields
add_connectorAdd a dependency connector between variables
sync_connectors_from_equationsAdd missing dependency connectors inferred from equations
set_connector_routingSet connector angle and explicit waypoint routing metadata
rename_variableRename a stock/flow/aux and update references in equations/connectors/modules
delete_variableDelete a stock/flow/aux with consistency checks and cleanup
create_moduleCreate a logical module/group of variables
add_to_moduleAdd variables to an existing module/group
remove_from_moduleRemove variables from a module/group
rename_moduleRename a module/group
delete_moduleDelete a module/group
set_module_viewSet explicit module box position/size on the diagram
set_module_styleSet module box style (border/background/font/label side) on the diagram
auto_place_module_boxesAuto-place module boxes around their members

Notes:

  • MCP 2026-07-28 clients call create_workspace once and include its returned workspace_id in stateful calls. Modern tool discovery marks that field as required on stateful tools. The ID routes application state; it is not an authorization credential.
  • Supported legacy stdio clients may omit workspace_id and use one process-local compatibility workspace; legacy discovery keeps the field optional.
  • Tools accept optional model_id so one workspace can manage multiple models safely.
  • create_model and read_model set the workspace's current model_id and return it.
  • add_flow and add_aux support optional graphical_function payloads (ypts plus exactly one of xscale or xpts).
  • add_stock/add_flow/add_aux reject duplicate variable names across variable types; add_connector requires both variables to exist.
  • set_connector_routing can target a connector by connector_uid or by from_var + to_var.
  • save_model and get_model_xml accept auto_layout (default true) and resolve_layout_violations (default false).
  • save_model, get_model_xml, and render_diagram return the latest layout viewport, metrics, and warnings in structured content. Their text result names any non-clean layout warning codes.
  • read_model, save_model, and get_model_xml accept compat_mode:
    • permissive (default): continue with warnings
    • strict: fail on compatibility issues
  • set_module_style updates module view styling and persists those attributes in XMILE view <group .../> elements.
  • save_as_template writes user templates to ~/.stella-mcp/templates by default (override via STELLA_MCP_TEMPLATE_DIR) and stores metadata in a .meta.json sidecar.
  • Tool failures return structured MCP errors with error.code, error.category, and error.message.
  • Every successful tool result retains readable text and supplies schema-validated structuredContent described by its JSON Schema 2020-12 outputSchema.

Workspace Lifecycle

ToolDescription
create_workspaceCreate an isolated workspace, optionally with a caller-selected lifetime
revoke_workspaceRevoke a workspace and discard its in-memory models

Model Inspection

ToolDescription
list_modelsList available workspace model IDs and indicate the current model
inspect_modelReturn a structured model summary for agent inspection
list_modulesList modules/groups in the current model
list_connectorsList connector IDs, endpoints, angles, and routing metadata
list_variablesList all stocks, flows, and auxiliaries
validate_modelCheck for errors (undefined variables, missing connections, etc.)
get_model_xmlPreview the XMILE XML output
render_diagramRender the model as an SVG stock-and-flow diagram
simulateRun the model via PySD and return time series + summaries (sim extra)
compare_scenariosRun named what-if override sets against a baseline and report deltas (sim extra)
sensitivity_analysisSweep parameters one-at-a-time and rank their effect on an output metric (sim extra)
calibrateFit constant parameters to an observed time-series (inverse of simulate) (sim extra)

Batch Building

build_model creates and populates a model in one call. Items apply in the order stocks → auxs → flows → connectors → modules; the whole batch is all-or-nothing, and on failure the error names the failing item (error.stage + error.index). The same item arrays work on an existing model via add_variables.

{
  "name": "build_model",
  "arguments": {
    "name": "SIR",
    "model_id": "sir",
    "sim_specs": {"start": 0, "stop": 100, "dt": 0.125, "time_units": "Days"},
    "stocks": [
      {"name": "Susceptible", "initial_value": "9999", "units": "people"},
      {"name": "Infected", "initial_value": "1", "units": "people"},
      {"name": "Recovered", "initial_value": "0", "units": "people"}
    ],
    "auxs": [
      {"name": "contact_rate", "equation": "6"},
      {"name": "infectivity", "equation": "0.25"},
      {"name": "recovery_time", "equation": "2", "units": "days"},
      {"name": "total_population", "equation": "Susceptible + Infected + Recovered"}
    ],
    "flows": [
      {"name": "infection", "equation": "Susceptible * contact_rate * infectivity * Infected / total_population", "from_stock": "Susceptible", "to_stock": "Infected"},
      {"name": "recovery", "equation": "Infected / recovery_time", "from_stock": "Infected", "to_stock": "Recovered"}
    ],
    "modules": [
      {"name": "Disease Dynamics", "members": ["Susceptible", "Infected", "Recovered"]}
    ]
  }
}

Connector sync and validation run by default (disable with "sync_connectors": false / "validate": false); the response includes the full structured model summary, so no follow-up inspect_model call is needed.

Tool Payload Examples

Create and switch between workspace models:

{"name":"create_model","arguments":{"name":"Population","model_id":"pop_v1"}}
{"name":"create_model","arguments":{"name":"Carbon","model_id":"carbon_v1"}}
{"name":"list_models","arguments":{}}
{"name":"delete_model","arguments":{"model_id":"pop_v1"}}
{"name":"inspect_model","arguments":{"model_id":"sir_baseline","include_validation":true}}

List and load templates:

{"name":"list_templates","arguments":{}}
{"name":"list_templates","arguments":{"source":"builtin","query":"epidem","tags":["epidemiology"]}}
{"name":"get_template_info","arguments":{"template_name":"sir"}}
{"name":"load_template","arguments":{"template_name":"sir","model_id":"sir_baseline"}}

Save current model as a user template:

{"name":"save_as_template","arguments":{"model_id":"pop_v1","template_name":"my_population_template","description":"Baseline single-stock growth starter","tags":["intro","population"]}}

Create and manage modules:

{"name":"create_module","arguments":{"model_id":"sir_baseline","name":"Disease Dynamics","members":["Susceptible","Infected","Recovered"]}}
{"name":"add_to_module","arguments":{"model_id":"sir_baseline","module_name":"Disease Dynamics","members":["infection","recovery"]}}
{"name":"list_modules","arguments":{"model_id":"

…
View source on GitHub