openstudio-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@openstudio-mcpCreate an example model and tell me about it"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
openstudio-mcp
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-mcpMachine | Build command |
Intel/AMD (Linux, Windows, Intel Mac) |
|
Apple Silicon (M-series) |
|
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
sandboxuser (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_privsprevents 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 |
|
|
|
|
|
|
|
| Account used for confined child processes. Values less than 1 are rejected. The default matches the |
|
| Maximum size in bytes of one file created by a child process. |
|
| Maximum processes/threads for the sandbox UID. |
|
| Optional open-file descriptor limit. |
|
| Optional CPU-seconds limit. Disabled by default because annual simulations can be long-running. |
|
| Optional virtual-memory limit. Prefer Docker memory limits because restrictive address-space limits can break EnergyPlus. |
|
| Wall-clock timeout for a simulation. |
Secure deployment guidance
Mount
/inputsread-only:-v /host/inputs:/inputs:ro.Mount only the output directory at
/runs; any process allowed to write/runscan 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
/reposource mount in the testing commands is for development only.Keep
OSMCP_SANDBOX=autoandOSMCP_SANDBOX_NET=denyfor untrusted measure authoring. Docker's--network nonecan 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 |
| Workflow | one-command simulate + results extraction |
| Workflow | comprehensive multi-category energy report |
| Workflow | full model creation from scratch |
| Workflow | before/after ECM analysis |
| Task | guided HVAC system selection |
| Task | pre-simulation model quality check |
| Task | quick 3D model visualization |
| Task | diagnose simulation failures |
| Knowledge | measure creation, SDK verification, wiring patterns |
| Knowledge | ASHRAE 90.1 system selection |
| Knowledge | tool dependencies and model relationships |
| 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 a complete building end-to-end (geometry + weather + typical template) |
| Create bar-building geometry from type, floor area, aspect ratio |
| Add constructions, loads, HVAC, SWH to a model with geometry |
| Minimal single-zone example (testing/demos) |
| 10-zone baseline with ASHRAE system 1–10 (testing/demos) |
| Quick structural summary of an OSM file |
| Load OSM into memory for querying/editing |
| Save the in-memory model to disk |
| Discover files in /inputs and /runs |
| Building name, area, volume, orientation |
| Object counts by category |
| Delete any named object (28+ types) |
| Rename any named object |
Read/write any OpenStudio object by introspection — covers types without a dedicated tool.
Tool | Description |
| List objects of any type (CamelCase, IDD colon, or underscore) |
| Read all properties of an object — returns values + available setters |
| Write any property via official setters — auto-coerces types |
Tool | Description |
| List spaces with area/volume |
| Surfaces, loads, zone for a space |
| List thermal zones with spaces |
| Zone equipment, thermostat, multiplier |
| Create a space (optional story/space type) |
| Create a thermal zone, assign spaces |
Tool | Description |
| List surfaces (walls, floors, roofs) |
| Vertices, construction, boundary |
| List windows, doors, skylights |
| Create a surface from explicit 3D vertices |
| Create a window/door on a parent surface |
| Extrude a floor polygon into a space with all surfaces |
| Intersect + match shared walls between adjacent spaces |
| Add a centered window by glazing ratio |
| Import geometry from a FloorSpaceJS JSON file |
List constructions/sets via list_model_objects("Construction") / ("DefaultConstructionSet").
Tool | Description |
| Materials with thermal properties |
| Construction layers with thermal properties |
| Material with conductivity/density |
| Layered construction from materials |
| Assign a construction to a surface |
List schedules via list_model_objects("ScheduleRuleset").
Tool | Description |
| Schedule type, values, rules |
| Constant schedule (Fractional/Temp/OnOff) |
List loads via list_model_objects("People"), ("Lights"), etc.; use get_object_fields for definitions.
Tool | Description |
| Detailed info for any load by name |
| People load (by area or count) |
| Lighting load (by area or wattage) |
| Electric equipment load |
| Gas equipment load |
| Infiltration (by area or ACH) |
List space types via list_model_objects("SpaceType").
Tool | Description |
| Space-type loads, schedules, standards |
Tool | Description |
| Air loops with zones served |
| Air-loop components, sizing, OA system |
| Create an air loop and connect zones |
| Plant loops (heating, cooling, condenser) |
| Plant-loop supply/demand components |
| Zone-level HVAC equipment |
| Zone equipment details |
Tool | Description |
| ASHRAE 90.1 baseline system (types 1–10) |
| All baseline + modern template types |
| Metadata for a specific system type |
| Replace ALL terminals on an air loop |
| Replace the terminal on a single zone |
| DOAS with fan coils, radiant, or chilled beams |
| VRF multi-zone heat-pump 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 |
| Read all properties of a named component |
| Modify properties on a named component |
| OA economizer settings on an air loop |
| Plant-loop sizing (exit temp, delta-T) |
| Air-loop SizingSystem (SAT, OA, flow methods) |
| Read all SizingSystem properties |
| SizingZone properties (supports zone lists) |
| Read all SizingZone properties |
| Read SPM properties (7 types) |
| Modify SPM properties (7 types) |
Tool | Description |
| Plant loop with pump, bypass, SPM |
| Add boiler/chiller/tower to supply side |
| Remove supply-side equipment |
| Add coil/heater to the demand side |
| Remove a demand-side component |
| Add baseboard/unit heater to a zone |
| Remove zone equipment |
| Batch-remove all equipment from zones |
| Reorder zone cooling/heating priority |
Tool | Description |
| Available EPW files (with .stat/.ddy) |
| City, lat, lon, timezone from a weather file |
| Add a heating/cooling design day |
| Read sizing flags and timesteps/hour |
| Modify sizing flags and/or timestep |
| Read run-period dates |
| Set run-period dates |
Tool | Description |
| Run a simulation from an OSM + optional EPW |
| Run EnergyPlus from an OSW file |
| Validate an OSW workflow file |
| Pre-sim check: weather, design days, HVAC, constructions |
| Poll run status |
| Tail simulation logs |
| List output files |
| Cancel a running simulation |
| Add an EnergyPlus output variable |
| Add an EnergyPlus output meter |
Reclaim disk from old run directories. See docs/run-retention.md.
Tool | Description |
| Delete old run dirs you own (preview with |
| Delete one of your run directories |
| Protect a run from automatic cleanup |
| Allow a pinned run to be cleaned up again |
Tool | Description |
| EUI, energy, unmet hours |
| Energy by end use and fuel (IP/SI) |
| Opaque + fenestration U-values and areas |
| Autosized zone/system HVAC capacities |
| Per-zone areas, conditions, multipliers |
| Autosized component values (filterable) |
| Time-series output data with date/cap filters |
| Parse eplusout.err into Fatal/Severe/Warning |
| Output variables from a completed run |
| Compare two runs: EUI delta + end-use breakdown |
| Read any file by absolute path (mounts only) |
| 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 an OpenStudio measure to the in-memory model |
| List a measure's arguments, defaults, choices |
| Create a custom Ruby/Python ModelMeasure |
| Edit a custom measure's code or arguments |
| Run a custom measure's tests (auto-detects language) |
| List custom measures you've created |
| List ~61 bundled ComStock measures |
Typed wrappers over ~79 bundled common measures (reporting, envelope, renewables, visualization, cleanup).
Tool | Description |
| List bundled measures by category |
| Interactive 3D Three.js viewer of geometry |
| 3D viewer with simulation data on surfaces |
| ~25-section HTML report |
| ASHRAE baseline QA/QC checks |
| Shift heating/cooling setpoints |
| Bulk-replace exterior window constructions |
| Ideal air loads on all zones (quick sizing) |
| Remove orphan/unused objects |
| Set weather + climate zone + design days |
| Apply thermostat schedules from a library |
| Replace existing thermostat schedules |
| Shift schedule profiles by hours |
| Add rooftop PV panels |
| Add PV to shading surfaces |
| Add EV charging load |
| Add zone ventilation design flow |
| Set lifecycle-cost parameters |
| Add cost per floor area |
| Set walls/floors adiabatic |
Tool | Description |
| List available workflow guides |
| Step-by-step instructions for a workflow |
| Recommend the relevant tool group for a task |
| Look up OpenStudio SDK classes + methods (verify before calling) |
| Ruby wiring recipes for HVAC (24 patterns) |
| Server health check |
| 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:
# | Example | # | Example |
1 | 11 | ||
2 | 12 | ||
3 | 13 | ||
4 | 14 | ||
5 | 15 | ||
6 | 16 | ||
7 | 17 | ||
8 | 18 | ||
9 | 19 | ||
10 |
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 withtools.py(MCP registration) +operations.py(business logic); they auto-registerState: 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
Create
mcp_server/skills/<name>/__init__.py,operations.py,tools.pyoperations.py— pure logic, returns{"ok": True/False, ...}tools.py— exportsregister(mcp), defines tool schemasAdd
tests/test_<name>.pyand a CI step in.github/workflows/ci.ymlAuto-registers via
skills/__init__.py; add names toEXPECTED_TOOLSand bump counts intests/test_tool_baseline.py
New Claude Code skill (workflow guide)
Create
.claude/skills/<name>/SKILL.mdwith YAML frontmatter (name,description)Add workflow instructions referencing MCP tool names;
user-invocable: true|false,context: forkfor fire-and-forgetAdd
tests/test_skill_<name>.py+ a CI shard, an example indocs/examples/, and a README rowAuto-appears in
list_skills()via the/skillsmount
New HVAC component type
Add
_get_<type>_props(obj)/_set_<type>_props(obj, props)incomponents.pyAdd an entry to
COMPONENT_TYPES; add a test intests/test_component_properties.pyNo dynamic dispatch — every OpenStudio API call must be explicit and grepable
License
See LICENSE.
This server cannot be installed
Maintenance
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