# lbnl-eta/energyplus-mcp architecture

> Architecture diagram of the GitHub repository lbnl-eta/energyplus-mcp, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/lbnl-eta/energyplus-mcp
- Repository: https://github.com/lbnl-eta/energyplus-mcp

## Overview

1. **Purpose and boundary**
   This repo is a Python-based **Model Context Protocol (MCP) server** for EnergyPlus. Its job is to expose building-model operations as tools to external MCP clients; it does not implement a UI or store persistent app state. The primary domain objects are **EnergyPlus IDF models**, **weather EPW files**, and **simulation outputs**.

2. **Top-level request flow**
   An MCP client connects to the server over either **stdio** or **streamable HTTP**. The server accepts tool calls, routes them through a tool registry, and then delegates to EnergyPlus-specific orchestration code. Results are returned directly to the client, usually as structured text/data plus generated files in the workspace.

3. **Protocol layer**
   `server.py` is the main MCP entrypoint and likely hosts the **FastMCP** application. This layer is the contract boundary with clients: it defines the 35 tools, handles initialization, and exposes server management capabilities such as status and logs.

4. **HTTP transport and auth boundary**
   `http_app.py` and `auth.py` define the optional **authenticated HTTP transport** used for remote-style deployments and local testing. This is a separate boundary from stdio: HTTP requests go through bearer-token validation and health-check endpoints before reaching the MCP handler.

5. **Configuration and EnergyPlus installation detection**
   `config.py` centralizes environment-driven configuration such as `EPLUS_IDD_PATH`, sample/output paths, transport mode, host/port, and HTTP token settings. It also encodes the coupling to the installed **EnergyPlus distribution**, including the default version and installation layout, so the server can run in Docker or on a local machine.

6. **Core EnergyPlus orchestration**
   `energyplus_tools.py` is the main service layer that performs the actual work behind tools: loading models, validating them, modifying IDF content, running simulations, and collecting results. This is the most important internal boundary: higher layers speak MCP, while this layer speaks EnergyPlus model and filesystem operations.

7. **Domain-focused utility modules**
   The `utils/` package contains specialized helpers for EnergyPlus object families and outputs:
   - `people_utils.py`, `lights_utils.py`, `electric_equipment_utils.py` for load objects
   - `schedules.py` for schedule inspection/modification
   - `output_variables.py` and `output_meters.py` for output discovery/configuration
   - `diagrams.py` for HVAC visualization
   - `path_utils.py` for resolving files safely across repo/workspace boundaries  
   These modules keep domain-specific logic out of the transport and orchestration layers.

8. **Data sources and file-based workflow**
   The repo is centered on **files on disk** rather than a database or external service. `sample_files/` provides small IDFs and EPWs used by tools and tests, while `illustrative examples/` contains larger reference models and their EnergyPlus output artifacts. Typical flow is: load IDF → inspect/modify → run simulation with EPW → inspect generated outputs.

9. **Simulation and output artifacts**
   EnergyPlus runs generate a broad set of outputs: `.err`, `.csv`, `.eso`, `.eio`, `.rdd`, `.mtd`, `.mdd`, diagrams, and HTML reports. The tools layer appears to surface both simulation execution and post-processing, including plots and loop diagrams, so the output directory is part of the operational architecture.

10. **Operational modes**
    The repository supports three runtime patterns: local stdio MCP, Docker-based stdio MCP, and HTTP MCP with tokens. The devcontainer/Dockerfile bakes in EnergyPlus 26.1.0, making the container image the deployment boundary for clients that want a self-contained runtime.

11. **Testing and validation**
    `tests/` covers configuration transport behavior, auth behavior, server behavior, and EnergyPlus integration-related paths. This suggests the most important failure modes are startup/configuration, authorization, and tool availability rather than business logic persistence.

12. **Diagramming takeaway**
    For an architecture diagram, the most accurate shape is: **MCP client → transport/auth layer → MCP server/tool registry → EnergyPlus orchestration → domain utilities + filesystem/EnergyPlus engine**. The only external runtime dependency that materially affects the architecture is the **EnergyPlus installation**, which is required for model parsing, simulation, and output generation.

Main entry points: [`energyplus-mcp-server/energyplus_mcp_server/energyplus_tools.py`](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/energyplus_tools.py) (EnergyPlus tools), [`energyplus-mcp-server/energyplus_mcp_server/http_app.py`](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/http_app.py) (HTTP app), [`energyplus-mcp-server/energyplus_mcp_server/server.py`](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/server.py) (Server), [`energyplus-mcp-server/energyplus_mcp_server/config.py`](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/config.py) (Config)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_grp_transport["Transport"]
  node_client(("MCP client<br/>external client"))
  node_server_py["Server<br/>mcp entrypoint<br/>[server.py]"]
  node_http_app["HTTP app<br/>transport<br/>[http_app.py]"]
  node_auth["Auth<br/>[auth.py]"]
end

subgraph group_grp_core["Core"]
  node_config["Config<br/>[config.py]"]
  node_tools["Tool layer<br/>mcp tools<br/>[server.py]"]
  node_eplus_tools["EnergyPlus tools<br/>orchestration"]
  node_eplus_install[("EnergyPlus install<br/>external runtime")]
end

subgraph group_grp_utils["Utilities"]
  node_people_utils["People<br/>idf helpers<br/>[people_utils.py]"]
  node_lights_utils["Lights<br/>idf helpers<br/>[lights_utils.py]"]
  node_electric_utils["Electric loads<br/>idf helpers"]
  node_schedules["Schedules<br/>idf helpers<br/>[schedules.py]"]
  node_outputs["Outputs<br/>result helpers"]
  node_meters["Meters<br/>result helpers<br/>[output_meters.py]"]
  node_diagrams["Diagrams<br/>hvac viz<br/>[diagrams.py]"]
  node_path_utils["Paths<br/>fs safety<br/>[path_utils.py]"]
end

subgraph group_grp_runtime["Runtime data"]
  node_samples["Samples<br/>idf/epw files"]
  node_examples["Examples<br/>reference runs"]
end

node_client -->|"stdio MCP"| node_server_py
node_client -->|"HTTP MCP"| node_http_app
node_http_app -->|"validate"| node_auth
node_server_py -->|"register"| node_tools
node_http_app -->|"dispatch"| node_server_py
node_server_py -->|"load"| node_config
node_http_app -->|"load"| node_config
node_tools -->|"delegate"| node_eplus_tools
node_eplus_tools -->|"invoke"| node_eplus_install
node_eplus_tools -->|"resolve"| node_path_utils
node_eplus_tools -->|"modify"| node_schedules
node_eplus_tools -->|"edit"| node_people_utils
node_eplus_tools -->|"edit"| node_lights_utils
node_eplus_tools -->|"edit"| node_electric_utils
node_eplus_tools -->|"configure"| node_outputs
node_eplus_tools -->|"configure"| node_meters
node_eplus_tools -->|"render"| node_diagrams
node_eplus_tools -->|"read"| node_samples
node_eplus_tools -->|"write"| node_examples

click node_server_py "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/server.py"
click node_http_app "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/http_app.py"
click node_auth "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/auth.py"
click node_config "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/config.py"
click node_tools "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/server.py"
click node_eplus_tools "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/energyplus_tools.py"
click node_people_utils "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/people_utils.py"
click node_lights_utils "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/lights_utils.py"
click node_electric_utils "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/electric_equipment_utils.py"
click node_schedules "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/schedules.py"
click node_outputs "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/output_variables.py"
click node_meters "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/output_meters.py"
click node_diagrams "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/diagrams.py"
click node_path_utils "https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/path_utils.py"
click node_samples "https://github.com/lbnl-eta/energyplus-mcp/tree/main/energyplus-mcp-server/sample_files"
click node_examples "https://github.com/lbnl-eta/energyplus-mcp/tree/main/energyplus-mcp-server/illustrative examples"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_client,node_server_py,node_http_app,node_auth toneBlue
class node_config,node_tools,node_eplus_tools,node_eplus_install toneAmber
class node_people_utils,node_lights_utils,node_electric_utils,node_schedules,node_outputs,node_meters,node_diagrams,node_path_utils toneMint
class node_samples,node_examples toneRose
```

## Components

### Transport

MCP entrypoints and optional HTTP/auth boundary

- **MCP client**: external client · External MCP consumer connecting over stdio or HTTP
- [Server](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/server.py): mcp entrypoint · Main MCP server entrypoint defining tools and startup · `energyplus-mcp-server/energyplus_mcp_server/server.py`
- [HTTP app](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/http_app.py): transport · Streamable HTTP endpoint layer for remote or local use · `energyplus-mcp-server/energyplus_mcp_server/http_app.py`
- [Auth](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/auth.py): bearer auth · Token validation and HTTP access control boundary · `energyplus-mcp-server/energyplus_mcp_server/auth.py`

### Core

Server coordination and EnergyPlus orchestration

- [Config](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/config.py): runtime config · Environment-driven settings for paths, transport, host, port, and tokens · `energyplus-mcp-server/energyplus_mcp_server/config.py`
- [Tool layer](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/server.py): mcp tools · Registry and dispatch surface exposed to MCP clients · `energyplus-mcp-server/energyplus_mcp_server/server.py`
- [EnergyPlus tools](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/energyplus_tools.py): orchestration · Core service layer implementing model loading, validation, edits, runs, and result collection · `energyplus-mcp-server/energyplus_mcp_server/energyplus_tools.py`
- **EnergyPlus install**: external runtime · Installed EnergyPlus distribution used for IDD/IDF parsing and simulation execution

### Utilities

Domain helpers for model edits, outputs, and file safety

- [People](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/people_utils.py): idf helpers · Load-object helpers for people definitions · `energyplus-mcp-server/energyplus_mcp_server/utils/people_utils.py`
- [Lights](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/lights_utils.py): idf helpers · Load-object helpers for lighting definitions · `energyplus-mcp-server/energyplus_mcp_server/utils/lights_utils.py`
- [Electric loads](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/electric_equipment_utils.py): idf helpers · Load-object helpers for electric equipment definitions · `energyplus-mcp-server/energyplus_mcp_server/utils/electric_equipment_utils.py`
- [Schedules](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/schedules.py): idf helpers · Schedule inspection and modification helpers · `energyplus-mcp-server/energyplus_mcp_server/utils/schedules.py`
- [Outputs](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/output_variables.py): result helpers · Helpers for output variables and meters discovery/configuration · `energyplus-mcp-server/energyplus_mcp_server/utils/output_variables.py`
- [Meters](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/output_meters.py): result helpers · Helpers for output meter discovery/configuration · `energyplus-mcp-server/energyplus_mcp_server/utils/output_meters.py`
- [Diagrams](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/diagrams.py): hvac viz · Visualization helpers for HVAC and loop diagrams · `energyplus-mcp-server/energyplus_mcp_server/utils/diagrams.py`
- [Paths](https://github.com/lbnl-eta/energyplus-mcp/blob/main/energyplus-mcp-server/energyplus_mcp_server/utils/path_utils.py): fs safety · Safe path resolution across repo and workspace boundaries · `energyplus-mcp-server/energyplus_mcp_server/utils/path_utils.py`

### Runtime data

Workspace files and bundled example models

- [Samples](https://github.com/lbnl-eta/energyplus-mcp/tree/main/energyplus-mcp-server/sample_files): idf/epw files · Bundled sample IDF and EPW inputs for tools and tests · `energyplus-mcp-server/sample_files`
- [Examples](https://github.com/lbnl-eta/energyplus-mcp/tree/HEAD/energyplus-mcp-server/illustrative%20examples): reference runs · Illustrative model runs and generated EnergyPlus artifacts · `energyplus-mcp-server/illustrative examples`

## Connections

- MCP client → Server: stdio MCP · Clients can connect directly over standard input/output
- MCP client → HTTP app: HTTP MCP · Clients can connect through streamable HTTP
- HTTP app → Auth: validate · HTTP requests are checked for bearer-token access
- Server → Tool layer: register · Server defines and exposes the tool surface
- HTTP app → Server: dispatch · HTTP transport forwards requests into the MCP server
- Server → Config: load · Server startup depends on configuration settings
- HTTP app → Config: load · HTTP transport uses host, port, and token settings
- Tool layer → EnergyPlus tools: delegate · Tool calls are routed to EnergyPlus orchestration
- EnergyPlus tools → EnergyPlus install: invoke · Orchestration relies on the installed EnergyPlus runtime
- EnergyPlus tools → Paths: resolve · File operations use safe path resolution helpers
- EnergyPlus tools → Schedules: modify · Model edits include schedule handling
- EnergyPlus tools → People: edit · People-related model objects are handled by specialized helpers
- EnergyPlus tools → Lights: edit · Lighting-related model objects are handled by specialized helpers
- EnergyPlus tools → Electric loads: edit · Electric-load objects are handled by specialized helpers
- EnergyPlus tools → Outputs: configure · Simulation outputs include variables and reporting setup
- EnergyPlus tools → Meters: configure · Simulation outputs include meter reporting setup
- EnergyPlus tools → Diagrams: render · Post-processing can generate HVAC visualizations
- EnergyPlus tools → Samples: read · Tools can operate on bundled sample inputs
- EnergyPlus tools → Examples: write · Simulation runs produce example output artifacts and reports
