Skip to main content
Glama
NatLabRockies

openstudio-mcp

openstudio-mcp

MCP Badge

Model Context Protocol server for OpenStudio building energy simulation. It lets MCP hosts — Claude Desktop, Claude Code, Cursor, VS Code — create, query, and modify OpenStudio models, run EnergyPlus, and read results, all in plain language. The server handles the OpenStudio/EnergyPlus complexity behind MCP tool calls.

146 tools · 12 workflow skills · 480+ integration tests


What you can ask for

  • "Create a 10-zone office with VAV reheat and run an annual simulation."

  • "What's the EUI? Show me the unmet heating hours."

  • "Switch the HVAC from VAV to VRF heat pumps and compare energy use."

  • "Add R-30 roof insulation and see how it affects the cooling load."

  • "Build two adjacent zones from floor plans, match the shared wall, add 40% south glazing."

  • "Write a measure that sets all lights to 8 W/m², test it, apply it, and compare the EUI."

The AI picks the right tools, calls them in sequence, and summarizes — no scripting.


Related MCP server: OpenStudio MCP Server

Quick start (local)

Runs the server locally over stdio — one container per user, launched by your MCP host. For a shared deployment, see Remote & multi-user.

Prerequisites: Docker Desktop running, and an MCP host (Claude Desktop is the easiest start).

1. Build the image

git clone https://github.com/NatLabRockies/openstudio-mcp.git
cd openstudio-mcp

Machine

Build command

Intel/AMD (Linux, Windows, Intel Mac)

docker build -t openstudio-mcp:dev -f docker/Dockerfile .

Apple Silicon (M-series)

docker build --platform linux/arm64 -t openstudio-mcp:dev -f docker/Dockerfile.arm64 .

Both produce the same openstudio-mcp:dev image. The arm64 Dockerfile builds natively from NREL's arm64 .deb (the upstream nrel/openstudio base is amd64-only, so plain Dockerfile runs under slow emulation on Apple Silicon).

2. Configure your host

Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows), then restart Claude Desktop:

{
  "mcpServers": {
    "openstudio-mcp": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-v", "./tests/assets:/inputs:ro",
        "-v", "./runs:/runs",
        "-v", "./.claude/skills:/skills:ro",
        "-e", "OPENSTUDIO_MCP_MODE=prod",
        "openstudio-mcp:dev", "openstudio-mcp"
      ]
    }
  }
}

The -v host:container mounts expose your folders inside the container: /inputs for your models (starts with the bundled test models), /runs for simulation outputs, /skills for the workflow guides. Use absolute paths if ./ doesn't resolve from where your host launches Docker.

3. Verify and chat

Look for the hammer icon in Claude Desktop's input — click it to see the openstudio-mcp tools. Then try, in order:

"Create an example model and tell me about it" → "Create a baseline office with ASHRAE System 3 and show me the HVAC components" → "Load /inputs/MyBuilding.osm, apply the 90.1-2019 typical template, and run a simulation"

Use the /inputs mount for your own files rather than uploading through chat — Claude Desktop's upload sandbox can't reach MCP tools, so the AI may fall back to writing scripts. Drop a file in the host folder mapped to /inputs and reference it by that path. Simulation outputs in /runs are already reachable.

Other hosts: Claude Code, VS Code Copilot, Windsurf, and Gemini CLI use similar JSON config — see the MCP docs.

Client

Status

Notes

Claude Desktop

✅ Full

all tools available

Claude Code

✅ Full

ToolSearch auto-defers tools for efficient discovery

VS Code Copilot

✅ Compatible

MCP via config

Windsurf

✅ Compatible

under the 100-tool limit

Gemini CLI

✅ Compatible

use includeTools/excludeTools if needed

OpenAI API

✅ Compatible

use defer_loading for best results

Cursor

⚠️ Limited

40-tool hard cap — use Claude Code or Windsurf


Remote & multi-user (HTTP)

The quick start runs one container per user over stdio. To host it on one machine and let teammates connect from their own laptops — each with an isolated session, run directory, and optional bearer-token or JWT auth — run it over streamable HTTP (-e MCP_TRANSPORT=http). Works with Claude Code, Cursor, and VS Code.

See docs/remote-multi-user.md for setup, auth, the isolation model, and log access — and docs/run-retention.md for optional disk garbage-collection.


Security and simulation sandbox

OpenStudio measures are Ruby or Python programs and must be treated as untrusted code. EnergyPlus workflows can also invoke measure code. Docker isolates the container from the host, while openstudio-mcp adds a second sandbox around the child processes used by apply_measure, test_measure, measure metadata refresh, and simulations.

The default OSMCP_SANDBOX=auto mode provides the following controls on Linux, including Docker Desktop's Linux VM:

  • Privilege drop: child processes run as the image's unprivileged sandbox user (UID/GID 1001), while the MCP server retains only the privileges needed to prepare run directories.

  • Filesystem policy: Landlock denies filesystem access by default. The current run or staged measure directory is writable; required system and OpenStudio directories are read-only. /repo, /inputs, and other users' run directories are not exposed to measure code.

  • Network policy: seccomp denies outbound IP networking by default.

  • Secret isolation: child processes receive an allowlisted environment instead of inheriting API keys, tokens, and other server environment variables.

  • Process hardening: no_new_privs prevents privilege recovery through setuid executables. Resource limits constrain generated file size and process count, and simulations have a wall-clock timeout.

  • Staging: input models, weather files, measures, and OSWs are copied into a private run directory before execution. Escaping symlinks are rejected.

On Linux, auto fails closed if Landlock or the seccomp network filter cannot be installed: the untrusted child process does not run. On native macOS or Windows without Docker, kernel confinement is unavailable and the server warns that only environment filtering is active. Use the Docker image when running untrusted measures.

Sandbox options

Variable

Default

Behavior

OSMCP_SANDBOX

auto

auto, full, and landlock request environment filtering, UID/GID drop, resource limits, Landlock filesystem confinement, and seccomp network denial. posix omits Landlock and seccomp. off disables child-process confinement and is only appropriate for trusted local code. Unknown values fall back to auto.

OSMCP_SANDBOX_NET

deny

deny blocks outbound IP networking. allow permits it for trusted measures that must fetch external resources.

OSMCP_SANDBOX_UID / OSMCP_SANDBOX_GID

1001

Account used for confined child processes. Values less than 1 are rejected. The default matches the sandbox user built into the image.

OSMCP_SANDBOX_RLIMIT_FSIZE

10737418240

Maximum size in bytes of one file created by a child process. 0 disables this limit.

OSMCP_SANDBOX_RLIMIT_NPROC

1024

Maximum processes/threads for the sandbox UID. 0 disables this limit.

OSMCP_SANDBOX_RLIMIT_NOFILE

0

Optional open-file descriptor limit.

OSMCP_SANDBOX_RLIMIT_CPU

0

Optional CPU-seconds limit. Disabled by default because annual simulations can be long-running.

OSMCP_SANDBOX_RLIMIT_AS

0

Optional virtual-memory limit. Prefer Docker memory limits because restrictive address-space limits can break EnergyPlus.

OSMCP_SIM_TIMEOUT_SECONDS

7200

Wall-clock timeout for a simulation. 0 disables the timeout.

Secure deployment guidance

  • Mount /inputs read-only: -v /host/inputs:/inputs:ro.

  • Mount only the output directory at /runs; any process allowed to write /runs can modify that host directory by design.

  • Mount workflow guides read-only at /skills, or use the copy already baked into the image: -v /host/.claude/skills:/skills:ro.

  • Do not mount the repository, home directory, Docker socket, credentials, or broad host paths into production containers. The /repo source mount in the testing commands is for development only.

  • Keep OSMCP_SANDBOX=auto and OSMCP_SANDBOX_NET=deny for untrusted measure authoring. Docker's --network none can provide an additional container-wide network boundary when remote access is not required.

  • Use Docker CPU, memory, PID, and disk quotas as outer limits. The in-process resource limits are defense in depth, not replacements for container limits.

The sandbox protects the host and other run directories, but it intentionally allows measure code to modify its own staged run directory. Treat resulting OSM, SQL, report, and log files as untrusted outputs.


Workflow skills

In Claude Code, 12 bundled skills add workflow automation and domain knowledge:

Skill

Type

What it does

/simulate

Workflow

one-command simulate + results extraction

/energy-report

Workflow

comprehensive multi-category energy report

/new-building

Workflow

full model creation from scratch

/retrofit

Workflow

before/after ECM analysis

/add-hvac

Task

guided HVAC system selection

/qaqc

Task

pre-simulation model quality check

/view

Task

quick 3D model visualization

/troubleshoot

Task

diagnose simulation failures

measure-authoring

Knowledge

measure creation, SDK verification, wiring patterns

ashrae-baseline-guide

Knowledge

ASHRAE 90.1 system selection

openstudio-patterns

Knowledge

tool dependencies and model relationships

tool-workflows

Knowledge

multi-tool recipes for common operations

Workflow/task skills are invoked with /name; knowledge skills load automatically. Any MCP host can also discover these guides via the list_skills() and get_skill(name) tools (mount -v ./.claude/skills:/skills:ro).


Tool reference

146 tools, grouped by area — expand a group to see its tools. New here? create_new_building, run_simulation, and extract_summary_metrics cover most workflows; list_skills() and recommend_tools(task) help the AI find the rest.

Tool

Description

create_new_building

Create a complete building end-to-end (geometry + weather + typical template)

create_bar_building

Create bar-building geometry from type, floor area, aspect ratio

create_typical_building

Add constructions, loads, HVAC, SWH to a model with geometry

create_example_osm

Minimal single-zone example (testing/demos)

create_baseline_osm

10-zone baseline with ASHRAE system 1–10 (testing/demos)

inspect_osm_summary

Quick structural summary of an OSM file

load_osm_model

Load OSM into memory for querying/editing

save_osm_model

Save the in-memory model to disk

list_files

Discover files in /inputs and /runs

get_building_info

Building name, area, volume, orientation

get_model_summary

Object counts by category

delete_object

Delete any named object (28+ types)

rename_object

Rename any named object

Read/write any OpenStudio object by introspection — covers types without a dedicated tool.

Tool

Description

list_model_objects

List objects of any type (CamelCase, IDD colon, or underscore)

get_object_fields

Read all properties of an object — returns values + available setters

set_object_property

Write any property via official setters — auto-coerces types

Tool

Description

list_spaces

List spaces with area/volume

get_space_details

Surfaces, loads, zone for a space

list_thermal_zones

List thermal zones with spaces

get_thermal_zone_details

Zone equipment, thermostat, multiplier

create_space

Create a space (optional story/space type)

create_thermal_zone

Create a thermal zone, assign spaces

Tool

Description

list_surfaces

List surfaces (walls, floors, roofs)

get_surface_details

Vertices, construction, boundary

list_subsurfaces

List windows, doors, skylights

create_surface

Create a surface from explicit 3D vertices

create_subsurface

Create a window/door on a parent surface

create_space_from_floor_print

Extrude a floor polygon into a space with all surfaces

match_surfaces

Intersect + match shared walls between adjacent spaces

set_window_to_wall_ratio

Add a centered window by glazing ratio

import_floorspacejs

Import geometry from a FloorSpaceJS JSON file

List constructions/sets via list_model_objects("Construction") / ("DefaultConstructionSet").

Tool

Description

list_materials

Materials with thermal properties

get_construction_details

Construction layers with thermal properties

create_standard_opaque_material

Material with conductivity/density

create_construction

Layered construction from materials

assign_construction_to_surface

Assign a construction to a surface

List schedules via list_model_objects("ScheduleRuleset").

Tool

Description

get_schedule_details

Schedule type, values, rules

create_schedule_ruleset

Constant schedule (Fractional/Temp/OnOff)

List loads via list_model_objects("People"), ("Lights"), etc.; use get_object_fields for definitions.

Tool

Description

get_load_details

Detailed info for any load by name

create_people_definition

People load (by area or count)

create_lights_definition

Lighting load (by area or wattage)

create_electric_equipment

Electric equipment load

create_gas_equipment

Gas equipment load

create_infiltration

Infiltration (by area or ACH)

List space types via list_model_objects("SpaceType").

Tool

Description

get_space_type_details

Space-type loads, schedules, standards

Tool

Description

list_air_loops

Air loops with zones served

get_air_loop_details

Air-loop components, sizing, OA system

add_air_loop

Create an air loop and connect zones

list_plant_loops

Plant loops (heating, cooling, condenser)

get_plant_loop_details

Plant-loop supply/demand components

list_zone_hvac_equipment

Zone-level HVAC equipment

get_zone_hvac_details

Zone equipment details

Tool

Description

add_baseline_system

ASHRAE 90.1 baseline system (types 1–10)

list_baseline_systems

All baseline + modern template types

get_baseline_system_info

Metadata for a specific system type

replace_air_terminals

Replace ALL terminals on an air loop

replace_zone_terminal

Replace the terminal on a single zone

add_doas_system

DOAS with fan coils, radiant, or chilled beams

add_vrf_system

VRF multi-zone heat-pump system

add_radiant_system

Low-temperature radiant heating/cooling

List components via list_model_objects("BoilerHotWater"), loop detail tools, etc. Covers 15 component types (see reference).

Tool

Description

get_component_properties

Read all properties of a named component

set_component_properties

Modify properties on a named component

set_economizer_properties

OA economizer settings on an air loop

set_sizing_properties

Plant-loop sizing (exit temp, delta-T)

set_sizing_system_properties

Air-loop SizingSystem (SAT, OA, flow methods)

get_sizing_system_properties

Read all SizingSystem properties

set_sizing_zone_properties

SizingZone properties (supports zone lists)

get_sizing_zone_properties

Read all SizingZone properties

get_setpoint_manager_properties

Read SPM properties (7 types)

set_setpoint_manager_properties

Modify SPM properties (7 types)

Tool

Description

create_plant_loop

Plant loop with pump, bypass, SPM

add_supply_equipment

Add boiler/chiller/tower to supply side

remove_supply_equipment

Remove supply-side equipment

add_demand_component

Add coil/heater to the demand side

remove_demand_component

Remove a demand-side component

add_zone_equipment

Add baseboard/unit heater to a zone

remove_zone_equipment

Remove zone equipment

remove_all_zone_equipment

Batch-remove all equipment from zones

set_zone_equipment_priority

Reorder zone cooling/heating priority

Tool

Description

list_weather_files

Available EPW files (with .stat/.ddy)

get_weather_info

City, lat, lon, timezone from a weather file

add_design_day

Add a heating/cooling design day

get_simulation_control

Read sizing flags and timesteps/hour

set_simulation_control

Modify sizing flags and/or timestep

get_run_period

Read run-period dates

set_run_period

Set run-period dates

Tool

Description

run_simulation

Run a simulation from an OSM + optional EPW

run_osw

Run EnergyPlus from an OSW file

validate_osw

Validate an OSW workflow file

validate_model

Pre-sim check: weather, design days, HVAC, constructions

get_run_status

Poll run status

get_run_logs

Tail simulation logs

get_run_artifacts

List output files

cancel_run

Cancel a running simulation

add_output_variable

Add an EnergyPlus output variable

add_output_meter

Add an EnergyPlus output meter

Reclaim disk from old run directories. See docs/run-retention.md.

Tool

Description

cleanup_runs

Delete old run dirs you own (preview with dry_run, then delete)

delete_run

Delete one of your run directories

pin_run

Protect a run from automatic cleanup

unpin_run

Allow a pinned run to be cleaned up again

Tool

Description

extract_summary_metrics

EUI, energy, unmet hours

extract_end_use_breakdown

Energy by end use and fuel (IP/SI)

extract_envelope_summary

Opaque + fenestration U-values and areas

extract_hvac_sizing

Autosized zone/system HVAC capacities

extract_zone_summary

Per-zone areas, conditions, multipliers

extract_component_sizing

Autosized component values (filterable)

query_timeseries

Time-series output data with date/cap filters

extract_simulation_errors

Parse eplusout.err into Fatal/Severe/Warning

list_output_variables

Output variables from a completed run

compare_runs

Compare two runs: EUI delta + end-use breakdown

read_file

Read any file by absolute path (mounts only)

copy_file

Copy a file to a host-mounted path

Apply bundled measures, or write/test/apply custom ones. See examples 1, 2, 19.

Tool

Description

apply_measure

Apply an OpenStudio measure to the in-memory model

list_measure_arguments

List a measure's arguments, defaults, choices

create_measure

Create a custom Ruby/Python ModelMeasure

edit_measure

Edit a custom measure's code or arguments

test_measure

Run a custom measure's tests (auto-detects language)

list_custom_measures

List custom measures you've created

list_comstock_measures

List ~61 bundled ComStock measures

Typed wrappers over ~79 bundled common measures (reporting, envelope, renewables, visualization, cleanup).

Tool

Description

list_common_measures

List bundled measures by category

view_model

Interactive 3D Three.js viewer of geometry

view_simulation_data

3D viewer with simulation data on surfaces

generate_results_report

~25-section HTML report

run_qaqc_checks

ASHRAE baseline QA/QC checks

adjust_thermostat_setpoints

Shift heating/cooling setpoints

replace_window_constructions

Bulk-replace exterior window constructions

enable_ideal_air_loads

Ideal air loads on all zones (quick sizing)

clean_unused_objects

Remove orphan/unused objects

change_building_location

Set weather + climate zone + design days

set_thermostat_schedules

Apply thermostat schedules from a library

replace_thermostat_schedules

Replace existing thermostat schedules

shift_schedule_time

Shift schedule profiles by hours

add_rooftop_pv

Add rooftop PV panels

add_pv_to_shading

Add PV to shading surfaces

add_ev_load

Add EV charging load

add_zone_ventilation

Add zone ventilation design flow

set_lifecycle_cost_params

Set lifecycle-cost parameters

add_cost_per_floor_area

Add cost per floor area

set_adiabatic_boundaries

Set walls/floors adiabatic

Tool

Description

list_skills

List available workflow guides

get_skill

Step-by-step instructions for a workflow

recommend_tools

Recommend the relevant tool group for a task

search_api

Look up OpenStudio SDK classes + methods (verify before calling)

search_wiring_patterns

Ruby wiring recipes for HVAC (24 patterns)

get_server_status

Server health check

get_versions

OpenStudio, EnergyPlus, Ruby versions


Reference

ASHRAE baseline systems

All 10 ASHRAE 90.1 Appendix G baseline systems via add_baseline_system, plus modern templates DOAS, VRF, Radiant.

#

Type

Description

1

PTAC

Packaged terminal AC (zone-level)

2

PTHP

Packaged terminal heat pump (zone-level)

3

PSZ-AC

Packaged single-zone rooftop AC

4

PSZ-HP

Packaged single-zone heat pump

5

Packaged VAV w/ Reheat

VAV with hot-water reheat

6

Packaged VAV w/ PFP Boxes

VAV with parallel fan-powered boxes

7

VAV w/ Reheat

Central VAV, chiller + boiler + tower

8

VAV w/ PFP Boxes

Central VAV, parallel fan-powered terminals

9

Gas Unit Heater

Heating-only (warehouses, garages)

10

Electric Unit Heater

Heating-only, electric

HVAC component types

The component-properties tools query/modify these 15 types:

Category

Components

Coils

CoilHeatingGas, CoilHeatingElectric, CoilHeatingWater, CoilCoolingWater, CoilCoolingDXSingleSpeed, CoilCoolingDXTwoSpeed, CoilHeatingDXSingleSpeed

Plant

BoilerHotWater, ChillerElectricEIR, CoolingTowerSingleSpeed

Fans

FanConstantVolume, FanVariableVolume, FanOnOff

Pumps

PumpConstantSpeed, PumpVariableSpeed


Examples

19 worked examples with full tool-call sequences:


Testing

Full guide — framework, annotated examples, CI shards, writing tests — in docs/testing/.

# Unit tests (no Docker)
pytest tests/test_skill_registration.py -v

# Integration tests (Docker)
docker build -t openstudio-mcp:dev -f docker/Dockerfile .
docker run --rm -v "$PWD:/repo" -v "$PWD/runs:/runs" \
  -e RUN_OPENSTUDIO_INTEGRATION=1 -e MCP_SERVER_CMD=openstudio-mcp \
  openstudio-mcp:dev bash -lc 'cd /repo && pytest -vv -s tests/'

Architecture

  • Transport: stdio (default) or streamable HTTP for remote/multi-user

  • Protocol: MCP (JSON-RPC); in stdio prod mode, stdout is reserved for JSON-RPC and logs go to stderr

  • Skills: 27 skill modules under mcp_server/skills/<name>/, each with tools.py (MCP registration) + operations.py (business logic); they auto-register

  • State: per-session in-memory model via model_manager; runs under /runs/<run_id>/ (or /runs/<user>/<run_id>/ in HTTP mode)

Set OPENSTUDIO_MCP_MODE=prod for MCP hosts (quiet logs, no banner). Full system diagram, security analysis, and hardening notes: docs/architecture.md.

New MCP skill

  1. Create mcp_server/skills/<name>/__init__.py, operations.py, tools.py

  2. operations.py — pure logic, returns {"ok": True/False, ...}

  3. tools.py — exports register(mcp), defines tool schemas

  4. Add tests/test_<name>.py and a CI step in .github/workflows/ci.yml

  5. Auto-registers via skills/__init__.py; add names to EXPECTED_TOOLS and bump counts in tests/test_tool_baseline.py

New Claude Code skill (workflow guide)

  1. Create .claude/skills/<name>/SKILL.md with YAML frontmatter (name, description)

  2. Add workflow instructions referencing MCP tool names; user-invocable: true|false, context: fork for fire-and-forget

  3. Add tests/test_skill_<name>.py + a CI shard, an example in docs/examples/, and a README row

  4. Auto-appears in list_skills() via the /skills mount

New HVAC component type

  1. Add _get_<type>_props(obj) / _set_<type>_props(obj, props) in components.py

  2. Add an entry to COMPONENT_TYPES; add a test in tests/test_component_properties.py

  3. No dynamic dispatch — every OpenStudio API call must be explicit and grepable


License

See LICENSE.

F
license - not found
-
quality - not tested
A
maintenance

Maintenance

Maintainers
<1hResponse time
2wRelease cycle
9Releases (12mo)
Commit activity
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/NatLabRockies/openstudio-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server