Companion: WattLab tools + EnergyPlus-MCP
Read this when the task involves Twin calibrate, Fuel bills, ECM Excel, or IDF/EnergyPlus.
openfdd-mcp alone is FDD / sites / historian — it does not perform EnergyPlus IDF surgery.
Cutover (2026-07-30): Operator UI is openfdd-web (WattLab section). vibe19/vibe20 app tips are frozen. Prefer baked wattlab in GHCR UI + /data workspace + EnergyPlus-MCP sidecar — not a separate vibe Studio on :8520.
Three surfaces (do not collapse)
| Surface | Role | How agents reach it |
|---|---|---|
| openfdd-mcp | JWT → central REST: health, CSV ingest, FDD SQL, Haystack, reports | Cursor mcp.json openfdd server; mcp/INSTRUCTIONS.md |
| EnergyPlus-MCP | LBNL ~35 tools in wattlab_workspace/third_party/EnergyPlus-MCP → image energyplus-mcp-dev |
Separate MCP server or stack energyplus-ensure / mcp-exec |
WattLab package + tools/ |
Studio pages (in openfdd-web), CLIs, Excel builders, skills | Baked/PYTHONPATH wattlab; files under ~/wattlab_workspace/tools/ |
Hard rule: never embed EnergyPlus IDF surgery inside openfdd-mcp. Twin/ECM IDF work → EnergyPlus-MCP; spreadsheet honesty → PyPI open_fdd.ecm_engineering.
When FDD / dump implies as-operated schedules or bills disagree with Twin shape, read fdd-ops-to-twin-knobs.md then use Twin dial skills against the open-fdd WattLab path (no IDF in openfdd-mcp).
Golden loop (Liberty Twin → ECM)
A. Context (every Twin/ECM session)
1. ~/wattlab_workspace/WORKSPACE.md
2. tools/AGENT_CONTEXT.md + tools/BEST_PRACTICES_EPLUS_MCP_ECM.md
3. reports/BUG_REPORT.md (OFDD-* / BUG-ECM-*)
4. Skills: wattlab-energyplus-mcp, wattlab-twin-calibrate-dial,
wattlab-twin-ops-reheat-dial, openfdd-ecm-engineering
Method SoT: BUG_REPORT_TWIN_DIAL_AI_CONTEXT.md (ops/reheat chess)
Product ECM: docs/ecm/OPENFDD_AGENT_ECM_HANDOFF.md + PyPI example workbook
B. FDD / sites / historian → openfdd-mcp (or JWT REST)
C. Twin / IDF / simulate → EnergyPlus-MCP (open-fdd stack companion)
D. ECM Excel / Compare → openfdd-web WattLab + PyPI open_fdd.ecm_engineering
Golden book: open_fdd/ecm_engineering/examples/liberty_dual_ahu/ECM_FULL_PARITY.xlsx
Paths
| Host | In vibe20 / UI container |
|---|---|
~/wattlab_workspace |
/data |
…/third_party/EnergyPlus-MCP |
/data/third_party/EnergyPlus-MCP |
…/tools/ |
/data/tools/ |
…/reports/notebooks/full_parity_ecm/ECM_FULL_PARITY.xlsx |
same under /data/reports/… |
Preferred ECM workbook (SoT)
- Preferred:
ECM_FULL_PARITY.xlsxviabuild_full_parity_ecm_workbook_v2.py - Studio merge:
reports/ecm_full_parity_compare.jsonwith top-levelrows+annual_usd(BUG-ECM-015) - Do not treat matched-hours /
ECM_EPLUS_MATCHED_HOURS.xlsxas the product SoT
Cursor dual-MCP snippet
Wire both servers. openfdd-only = FDD-blind-to-Twin.
Point OPENFDD_API_BASE at a reachable LAN/VPN Central (not the MCP container’s loopback unless you use --network host). Inject the integrator JWT via env — do not paste tokens into checked-in snippets.
{
"mcpServers": {
"openfdd": {
"command": "docker",
"args": [
"run", "--rm", "-i", "--network", "host",
"-e", "OPENFDD_API_BASE=http://127.0.0.1:8080",
"-e", "OPENFDD_MCP_TOKEN",
"ghcr.io/bbartling/openfdd-mcp:nightly"
],
"env": { "OPENFDD_MCP_TOKEN": "<integrator JWT>" }
},
"energyplus": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "/path/to/wattlab_workspace:/data",
"energyplus-mcp-dev"
]
}
}
}
Inside Compose, use OPENFDD_API_BASE=http://central:8080 (or the published Caddy URL on the LAN) instead of host loopback.
See also: mcp.md, cursor-openclaw.md, root mcp/INSTRUCTIONS.md.