System Architecture¶
This page describes how idfkit-mcp is structured, where data lives, and what crosses the network boundary.
High-Level Overview¶
---
config:
theme: 'neutral'
---
graph TB
subgraph Clients["MCP Clients"]
direction TB
Claude["Claude Desktop / Code"]
Cursor["Cursor / VS Code"]
Custom["Custom MCP Client"]
end
subgraph Server["idfkit-mcp Server"]
Transport["Transport Layer<br/><small>stdio | SSE | streamable-http</small>"]
Middleware["Middleware<br/><small>logging, error handling, session binding</small>"]
Tools["35 Tools<br/><small>schema, read, write, validation,<br/>simulation, geometry, schedules, weather, docs</small>"]
Resources["12 Resources<br/><small>JSON state resources + MCP App viewers</small>"]
Session["Session Manager<br/><small>up to 20 concurrent sessions</small>"]
State["ServerState<br/><small>document, schema, sim results,<br/>weather file, change log, docs index</small>"]
end
subgraph Core["idfkit (core library)"]
Parser["IDF / epJSON Parser"]
Schema["Bundled Schemas<br/><small>EnergyPlus 8.9 – 25.2</small>"]
Validator["Validator"]
SimRunner["Simulation Runner"]
WeatherIdx["Weather Station Index<br/><small>16,000+ stations</small>"]
Docs["Doc URL Builder"]
end
subgraph Local["Local Disk"]
ModelFiles["Model Files<br/><small>IDF / epJSON</small>"]
SimOutput["Simulation Output<br/><small>SQL, HTML, CSV, error files</small>"]
WeatherFiles["Weather Files<br/><small>EPW / DDY</small>"]
SessionCache["Session Cache<br/><small>~/.cache/idfkit/sessions/</small>"]
DocsCache["Docs Cache<br/><small>~/.cache/idfkit/docs/</small>"]
end
subgraph External["External (Internet)"]
DocsSite["docs.idfkit.com<br/><small>search indexes</small>"]
WeatherDL["EnergyPlus Weather<br/><small>EPW downloads (climate.onebuilding.org)</small>"]
end
Clients -->|"JSON-RPC"| Transport
Transport --> Middleware --> Tools & Resources
Tools --> Session --> State
Resources --> State
State --> Core
State -->|"read / write"| Local
State -.->|"download & cache"| DocsSite
Core -.->|"download"| WeatherDL
Core -->|"read / write"| ModelFiles
SimRunner -->|"write"| SimOutput
Layered Architecture¶
The server is organized in four layers:
---
config:
theme: 'neutral'
---
block
columns 1
block:transport["Transport"]
stdio["stdio<br/>(single client)"]
sse["SSE<br/>(HTTP streaming)"]
http["streamable-http<br/>(multi-session)"]
end
block:middleware["Middleware"]
mw["Logging · Error mapping · Session binding"]
end
block:tools_resources["Tools & Resources"]
schema_t["Schema (4)"]
read_t["Read (6)"]
write_t["Write (9)"]
val_t["Validation (2)"]
sim_t["Simulation (8)"]
weather_t["Weather (2)"]
geom_t["Geometry (1)"]
sched_t["Schedules (1)"]
docs_t["Docs (2)"]
res["Resources (12)"]
end
block:state_layer["Session & State"]
state["ServerState — per-session document, schema, results, change log, caches"]
end
block:core["Core Library (idfkit)"]
idfkit["Parsing · Validation · Simulation · Weather · Schemas"]
end
Data Flow¶
Where data lives¶
| Data | Location | Lifetime |
|---|---|---|
| EnergyPlus schemas (IDD/epJSON) | Bundled with idfkit | Permanent (per idfkit version) |
| Weather station index (16,000+ stations) | Bundled with idfkit | Permanent (per idfkit version) |
| Model files (IDF/epJSON) | User's filesystem | User-managed |
| Weather files (EPW/DDY) | ~/.cache/idfkit/weather/ or user path |
Cached after download |
| Session state | ~/.cache/idfkit/sessions/<cwd-hash>.json |
Persists across restarts; cleared with clear_session |
| Documentation search index | ~/.cache/idfkit/docs/v{X.Y}/search.json |
Cached 7 days after download |
| Simulation output | Temp directory or user-specified path | Per-simulation run |
What comes from the internet¶
Only two things are fetched over the network:
-
Documentation search indexes from
docs.idfkit.com-- full-text search data for EnergyPlus I/O Reference and Engineering Reference. Downloaded once per EnergyPlus version and cached locally for 7 days. -
Weather files (EPW/DDY) from the EnergyPlus weather repository. Downloaded on demand via the
download_weather_filetool and cached locally.
Everything else -- schemas, station indexes, parsing, validation -- is fully offline using data bundled with idfkit.
What requires a local installation¶
EnergyPlus must be installed locally to run simulations. The server discovers it by checking (in order):
ENERGYPLUS_DIRenvironment variable- System
PATH - Standard OS install locations (
/usr/local/EnergyPlus-*,C:\EnergyPlusV*, etc.)
Simulation is the only feature that requires EnergyPlus. All other tools (modeling, validation, schema exploration, weather search) work without it.
Session Management¶
sequenceDiagram
participant Client as MCP Client
participant Server as idfkit-mcp
participant Disk as Cache Directory
Client->>Server: First tool call
Server->>Disk: Check for persisted session<br/>(keyed by CWD hash)
alt Session file exists
Disk-->>Server: Restore file_path, sim_dir, weather_file
Server->>Server: Lazy-load model & results on access
end
Server-->>Client: Tool result
Note over Server: State mutating tools auto-persist
Client->>Server: load_model("office.idf")
Server->>Disk: Save session state
Client->>Server: run_simulation(...)
Server->>Disk: Save session state (+ sim_dir)
Client->>Server: clear_session()
Server->>Disk: Delete session file
Server->>Server: Reset all in-memory state
Transport behavior:
- stdio (Claude Desktop, Codex): Single session, persistence enabled. Session survives server restarts.
- SSE / streamable-http (multi-client): Up to 20 concurrent sessions keyed by
mcp-session-idheader. LRU eviction when full. Persistence disabled (sessions are ephemeral).
Tool Categories¶
graph TB
subgraph Schema["Schema Exploration"]
A1[list_object_types]
A2[describe_object_type]
A3[search_schema]
A4[get_available_references]
end
subgraph Read["Model Read"]
B1[load_model]
B2[convert_osm_to_idf]
B3[list_objects]
B4[search_objects]
B5[get_zone_properties]
B6[get_change_log]
end
subgraph Write["Model Write"]
C1[new_model]
C2[add_object]
C3[batch_add_objects]
C4[update_object]
C5[remove_object]
C6[rename_object]
C7[duplicate_object]
C8[save_model]
C9[clear_session]
end
subgraph Validation
D1[validate_model]
D2[check_model_integrity]
end
subgraph Simulation
E1[run_simulation]
E2[list_output_variables]
E3[query_timeseries]
E4[query_simulation_table]
E5[list_simulation_reports]
E6[view_simulation_report]
E7[analyze_peak_loads]
E8[export_timeseries]
end
subgraph Weather
F1[search_weather_stations]
F2[download_weather_file]
end
subgraph Geometry
H1[view_geometry]
end
subgraph Schedules
I1[view_schedules]
end
subgraph Documentation
G1[search_docs]
G2[get_doc_section]
end
Typical Workflow¶
sequenceDiagram
participant Agent as AI Agent
participant MCP as idfkit-mcp
participant EP as EnergyPlus
Agent->>MCP: describe_object_type("Zone")
MCP-->>Agent: Field schema with constraints
Agent->>MCP: new_model(version="24.2")
MCP-->>Agent: Empty model created
Agent->>MCP: batch_add_objects([...zones, walls, windows...])
MCP-->>Agent: Objects added
Agent->>MCP: validate_model()
MCP-->>Agent: Validation results (errors, warnings)
Agent->>MCP: check_model_integrity()
MCP-->>Agent: Domain QA findings (orphan schedules, missing controls, geometry issues)
Agent->>MCP: search_weather_stations("Chicago")
MCP-->>Agent: Matching stations with WMO IDs
Agent->>MCP: download_weather_file("725300")
MCP-->>Agent: EPW path
Agent->>MCP: run_simulation(design_day=true)
MCP->>EP: Execute simulation
EP-->>MCP: Results (SQL, HTML, errors)
MCP-->>Agent: Success + runtime + error summary
Agent->>MCP: read idfkit://simulation/results
MCP-->>Agent: Structured QA diagnostics (unmet hours, end uses, flags)
Agent->>MCP: analyze_peak_loads()
MCP-->>Agent: Peak load decomposition + QA flags
Agent->>MCP: save_model("office.idf")
MCP-->>Agent: File saved