Instant Connection for Pixel Streaming
— New Feature Automated Setup

How to Automate WEAP Workflows with Claude Code on Vagon

How to Automate WEAP Workflows with Claude Code on Vagon

How to Automate WEAP Workflows with Claude Code on Vagon
Table of Contents
A new demand forecast arrives, and your WEAP comparison needs updating. The inputs must be checked, the alternative scenario recalculated, and the results exported without changing the Reference assumptions. Repeating that sequence manually takes time and makes each run harder to reproduce.
Claude Code can help build a Python runner around WEAP’s documented automation API. Instead of generating disconnected scripts, the workflow uses one configuration to identify the working Area, define an approved scenario change, select the reporting period, and write a comparison CSV.
On Vagon Cloud Computer, WEAP, Claude Code, Python, and the project files can share one Windows desktop. You can develop the runner, execute the calculations, and inspect the saved model and exported results in the same workspace.
This guide follows a municipal demand-management example, from model inventory through scenario editing and result checks. The objective is a repeatable automation tool with traceable inputs and outputs, while modeling decisions remain with the people responsible for the analysis.

Source: SEI
Define the Comparison Before Building the Runner
Start with an existing WEAP Area whose Reference scenario already calculates successfully. The automation will work on a separate copy, create a demand-management alternative beneath Reference, and export the same result variables for both scenarios.
For the first version, limit the change to one verified municipal demand-site variable. WEAP’s Annual Water Use Rate represents water use per unit of activity. Reducing that rate is not equivalent to reducing population, changing supply capacity, or modifying a return-flow assumption.

Source: SEI
If the approved baseline expression is a constant, the example can apply a reviewed replacement constant. If it contains growth or references to other assumptions, preserve that structure through an explicitly approved expression instead.
Establish What the Runner May Do
The initial workflow will:
Verify the working Area, Reference scenario, branch, and variable.
Create a new alternative scenario with Reference as its parent.
Apply one configured expression change and read it back.
Calculate the comparison and export results for a defined period.
It will leave Reference’s input expressions unchanged and stop if the alternative name already exists. Updating an existing alternative can be added later as a separate operating mode.
Use One Configuration Throughout
The same configuration must supply the scenario names, target branch, replacement expression, reporting years, metrics, and units. The runner should not read a scenario name from configuration during editing and then use a different hardcoded name during export.
Give Claude Code this assignment:
Build one configuration-driven runner for the agreed comparison. Separate validation, scenario editing, calculation, and CSV export into functions. Report missing information rather than inventing model details.
That gives the code a clear scope and makes the resulting comparison easier to test.
Prepare WEAP and the Automation Tools on Vagon Cloud Computer
Use a Windows desktop with WEAP, Claude Code, and native Windows Python available in the same session. This lets the runner access WEAP through COM while you keep the application open for checking the model and results.
Check application selection for the tools you need, and install WEAP from its official installer if necessary. Complete activation before testing the connection: the WEAP licensing requirements specify that API access requires the unlocked version.
Open the original Area, confirm that Reference calculates, and create a separate working copy through WEAP’s Area management tools. Record the copy’s exact name and directory.

Source: SEI
Create a Small Python Project
Keep the runner, configuration, and outputs organized:
From PowerShell in the project folder, prepare the environment:
python -m venv .venv
.\.
python -m venv .venv
.\.
pywin32 provides Windows COM access; pytest will support checks that do not require a running WEAP instance. Use the virtual environment’s Python explicitly when launching the runner.
The examples will build on scripts/weap_runner.py. Connection and inventory code belong in that runner, so later functions do not depend on variables left behind by a separately executed script.
Transfer the Complete Model Inputs
Use Vagon Files to bring over the Area backup, approved data, and supporting documents. Restore the working Area in WEAP and check every external file reference.
Keep Area-specific input files within the Area directory or its subdirectories where practical. The separate automation project holds the instructions and outputs; it is not itself the WEAP dataset.
Choose CPU and memory resources around model size and measured calculation time. Once the baseline opens and calculates correctly, the workspace is ready for the first connection check.
Connect to WEAP and Confirm the Working Area
Open the working Area in WEAP before running the script. The first check should report what Python can access without changing expressions, calculating scenarios, or saving the model.
Start scripts/weap_runner.py with a connection function and an inventory function:
import time
import win32com.client
def connect_weap(timeout=60):
weap = win32com.client.Dispatch("WEAP.WEAPApplication")
deadline = time.monotonic() + timeout
while not weap.ProgramStarted:
if time.monotonic() >= deadline:
raise TimeoutError("WEAP did not become ready")
time.sleep(0.5)
return weap
def show_inventory(weap):
print("WEAP version:", weap.SoftwareVersion)
print("Working Area:", weap.ActiveArea.Name)
print("Area directory:", weap.ActiveAreaDirectory)
for index in range(1, weap.Scenarios.Count + 1):
scenario = weap.Scenarios.Item(index)
print("Scenario:", scenario.Name)
if __name__ == "__main__
import time
import win32com.client
def connect_weap(timeout=60):
weap = win32com.client.Dispatch("WEAP.WEAPApplication")
deadline = time.monotonic() + timeout
while not weap.ProgramStarted:
if time.monotonic() >= deadline:
raise TimeoutError("WEAP did not become ready")
time.sleep(0.5)
return weap
def show_inventory(weap):
print("WEAP version:", weap.SoftwareVersion)
print("Working Area:", weap.ActiveArea.Name)
print("Area directory:", weap.ActiveAreaDirectory)
for index in range(1, weap.Scenarios.Count + 1):
scenario = weap.Scenarios.Item(index)
print("Scenario:", scenario.Name)
if __name__ == "__main__
Run it from the automation project folder:
.\..\.These properties and collections are documented in the WEAP Application API. COM activation may connect to an existing instance or start WEAP. Compare the reported Area name and directory with the working copy visible in the application.
The timeout limits the readiness polling after COM activation returns; it is not a timeout for every possible COM operation.
Keep Application Access Explicit
Later functions will receive the connection as an argument, such as validate_config(weap, config). They will not assume that a variable created by another script remains available.
Before defining the scenario change, ask Claude Code to extend the inventory with the approved branch path:
Check the branch with BranchExists. If it exists, list its variable names, units, and current expressions in Reference. Report the scenario context explicitly. Do not assign expressions, create scenarios, calculate, or save.
Confirm the target against WEAP’s Data View. Keep its full branch path and exact variable name for the configuration. If the inventory reports a different Area or an unavailable target, resolve that mismatch before enabling model-changing functions.

Source: SEI
Put the Scenario Change and Reporting Rules in One Configuration
Save the approved instructions in config/comparison.json. The runner will read this file for both scenario editing and result export, so names and reporting settings are not repeated inside the code.
For the single-site comparison, use this structure:
{
"working_area": "Basin_Automation",
"working_area_directory": "C:/Users/YourName/Documents/WEAP Areas/Basin_Automation",
"baseline_scenario": "Reference",
"parent_scenario": "Reference",
"alternative_scenario": "Demand Management",
"change": {
"branch": "\\Demand Sites\\South City",
"variable": "Annual Water Use Rate",
"expected_parent_expression": "100",
"new_expression": "90"
},
"report": {
"first_year": 2025,
"last_year": 2030,
"metrics": ["Unmet Demand", "Supply Delivered"]
{
"working_area": "Basin_Automation",
"working_area_directory": "C:/Users/YourName/Documents/WEAP Areas/Basin_Automation",
"baseline_scenario": "Reference",
"parent_scenario": "Reference",
"alternative_scenario": "Demand Management",
"change": {
"branch": "\\Demand Sites\\South City",
"variable": "Annual Water Use Rate",
"expected_parent_expression": "100",
"new_expression": "90"
},
"report": {
"first_year": 2025,
"last_year": 2030,
"metrics": ["Unmet Demand", "Supply Delivered"]
Replace the illustrative names, directory, expressions, and years with values confirmed in your model. The input change assumes an approved constant baseline and replacement. It is not a recommendation to reduce demand by a particular amount.
The reporting unit applies to the selected result variables, not automatically to the water-use-rate input. Confirm that input’s unit, scale, and activity denominator separately in WEAP.
Check the Parent Expression in the Correct Context
WEAP’s expression interface can return an inherited expression when a scenario has no local override.
For this first-run workflow, expected_parent_expression means the effective expression read while the configured parent scenario is active. The runner must verify it before creating the alternative. It will then place an explicit replacement in the new child scenario.

Source: SEI
Require parent_scenario and baseline_scenario to match for this initial example. Reject an existing alternative rather than silently updating it. Supporting other inheritance structures can be added later with separate checks.
Validate the Reporting Period Before Editing
The runner should also confirm that:
The configured Area name and directory match the open working copy.
The input variable exists and is editable.
The reporting metrics exist at the configured branch.
The requested years fall within the comparison scenarios’ supported period.
If CSV inputs are involved, check their coverage and missing-value rules before execution. WEAP’s ReadFromFile defaults can replace missing data with zero, so gaps need an explicit modeling decision rather than an automatic cleanup.
Validate the Configuration Before Applying the Change
Keep validation and editing as separate functions in scripts/weap_runner.py. That makes it possible to test the configuration without creating a scenario.
Start by loading the JSON file:
import json
import os
from pathlib import Path
def load_config():
project = Path(__file__).resolve().parents[1]
import json
import os
from pathlib import Path
def load_config():
project = Path(__file__).resolve().parents[1]
The path is resolved from the script’s location, not whichever directory happens to be open in the terminal.
Check the Area, Scenario, and Target Expression
Add this model-validation function below the connection code:
This checks model targets and period bounds. It does not establish that the replacement expression is scientifically appropriate or that a requested output unit is compatible. Keep those items in the approved specification.
Apply Only After Validation Passes
WEAP’s Scenario API creates a child beneath the specified parent. Add the editing function:
def apply_change(weap, config):
alternative = config["alternative_scenario"]
change = config["change"]
def apply_change(weap, config):
alternative = config["alternative_scenario"]
change = config["change"]
For this stage, replace the earlier inventory-only entry point with:
if __name__ == "__main__
if __name__ == "__main__
Run this first on a disposable working copy. Inspect the alternative in WEAP’s Data View and confirm that Reference retained its original expression.

Source: SEI
The operation is not transactional. If creation or assignment fails, do not rerun blindly against the partially modified Area. Restore a clean working copy, diagnose the failure, and repeat validation. Calculation and saving will be deliberate subsequent steps.
Calculate the Comparison and Keep a Run Log
Activating the alternative does not, by itself, define which scenarios WEAP calculates. Configure the comparison set explicitly, then request a fresh calculation.
Add this function to scripts/weap_runner.py. It selects the baseline and alternative, retains Current Accounts, and records calculation messages in a run-specific log.
def calculate_comparison(weap, config, run_id):
project = Path(__file__).resolve().parents[1]
def calculate_comparison(weap, config, run_id):
project = Path(__file__).resolve().parents[1]
The WEAP Application API documents calculation status, error counts, logging, and elapsed time. The third argument to Calculate forces recalculation, including when external input files have changed without WEAP recognizing that results are stale.
The function leaves the comparison scenarios selected for results review. It does not restore the previous display selection or save the Area.
Add Calculation to the Runner
Import uuid at the top of the file. In the existing entry point, add these lines after apply_change(weap, config) and replace the earlier inventory-stage completion message:
Run the assembled script on the working copy. Review the calculation log and WEAP’s Messages tab before treating the outputs as valid. Warnings may still need attention even when the calculation error count is zero.
This version uses the configured calculation-worker setting. Start with one worker for the initial verification; evaluate WEAP’s supported parallel options separately once the two-scenario workflow is reliable.
Export Both Scenarios to a Comparison CSV
The exporter should use the same configuration as the editing stage. It should not contain a second set of scenario names, branches, or reporting years.
For this first version, keep the reporting scope narrow: monthly Areas, the two configured volume metrics, and cubic metres. Add these checks inside validate_config, after report is assigned:
if int(weap.NumTimeSteps) != 12:
raise ValueError("This exporter requires a 12-timestep Area")
if report["unit"] != "m^3":
raise ValueError("This example exports cubic metres only")
if not report["metrics"] or not set(report["metrics"]
if int(weap.NumTimeSteps) != 12:
raise ValueError("This exporter requires a 12-timestep Area")
if report["unit"] != "m^3":
raise ValueError("This example exports cubic metres only")
if not report["metrics"] or not set(report["metrics"]
These checks belong before apply_change. Other reporting frequencies and metrics need their own validation rather than silently reusing this exporter.
Write Labeled Results, Not Console Output
Add import csv and import math at the top of the runner, then add:
def export_results(weap, config, run):
project = Path(__file__).resolve().parents[1]
folder = project / "reports" / run["run_id"]
def export_results(weap, config, run):
project = Path(__file__).resolve().parents[1]
folder = project / "reports" / run["run_id"]
After calculation succeeds, call it from the existing entry point:
The file retains its .partial.csv name if export fails. Only a completed export becomes comparison.csv.
Preserve the Time Convention
WEAP’s ResultValue interface uses water-year timestep numbering. Timestep 1 is not necessarily January. Record the Area’s water-year convention alongside the report.

Source: SEI
Keep these rows as timestep volumes. Aggregate them later over an explicitly defined period, and retain the unrounded export for checking against WEAP. A missing result stops this example rather than becoming an invented zero.
Test the Runner Before Using Its Comparison
The assembled runner now creates an alternative, calculates results, and writes a CSV. Before using that output, test both its refusal conditions and its behavior inside WEAP.
Keep the if __name__ == "__main__": guard in place. It lets tests import functions without automatically connecting to WEAP or editing an Area.
Start with a Refusal Test
Create tests/test_validation.py:
Run the test from the project folder:
.\..\.This checks one validation boundary without starting WEAP. It does not establish that COM operations work. Extend the tests to cover an existing alternative, an unexpected parent expression, invalid reporting years, and unsupported metrics.
Verify the Application Behavior Separately
Use a disposable Area copy for integration checks:
A failed validation must leave the alternative uncreated and input expressions unchanged.
A successful edit must place the replacement in the alternative while preserving Reference.
The CSV must contain both scenarios and the configured period, metrics, and units.
Selected exported values must match WEAP’s Results View.
For the illustrative 2025–2030 configuration, two scenarios, twelve timesteps, and two metrics produce 288 data rows, excluding the header. That is an expected structural count, not evidence that the numbers are correct.
Check a normal period, a high-demand period, and any unexpectedly large scenario difference. Use matching units and allow only the agreed numerical tolerance.

Source: SEI
Save and Reopen the Working Area
The runner intentionally does not save automatically. After reviewing the changes and results, save the working Area in WEAP, close it, and reopen it. Confirm the alternative and its expression are preserved.
Do not rerun the create-mode runner merely to check the saved Area: it should reject the existing alternative. Use the inventory function or WEAP’s interface instead.
Keep policy interpretation separate from these tests. Passing them establishes specific automation behaviors, not calibration or the suitability of a demand-management decision.
Add MCP or Computer Use Only Where They Help
The Python runner is the main automation path. Claude Code can prepare and launch it, while WEAP’s COM API handles application operations. Neither scenario editing nor CSV export requires an MCP server.
Use MCP for a Reusable Tool Interface
Once the runner has passed your tests, a custom MCP server could expose selected functions to the assistant. Useful starting operations include inspecting the active Area, validating a configuration, and retrieving an existing run report.
Keep those separate from operations that create scenarios, change expressions, calculate, or save. A conversational interface should preserve the runner’s checks rather than introduce another way to bypass them.
This would be an integration you build and verify, not a ready-made official WEAP connector.
Use Computer Use for Application Review
Where supported and enabled, Claude Code’s computer use can help open a result chart, inspect the displayed scenario, or capture a calculation warning.
Give it a bounded task:
Open the unmet-demand result for the configured branch and compare Reference with Demand Management. Do not change inputs, recalculate, or save.

Source: SEI
The control session must target the Vagon desktop where WEAP is running. A terminal session alone does not grant screen access.
Use the CSV and API checks for numerical verification, with the interface providing a complementary view. A chart can make a difference easier to understand, but it cannot establish that the correct input expressions and reporting settings were used.
Keep the Workflow Ready for the Next Update
Keep each comparison’s configuration beside its CSV, with the input-file versions, script version, calculation log, and WEAP Area backup. The run identifier links the report folder to its calculation log; retaining the configuration explains what that run was intended to do.

Source: SEI
Before processing another update, decide how to preserve the previous comparison. This runner requires a new alternative name. Either restore a clean working copy or configure a distinct alternative for the next approved run. Do not delete an earlier scenario simply to bypass the existing-name check.
On Vagon Cloud Computer, the configured Windows tools, automation project, and WEAP installation can remain together between sessions. You can prepare the next dataset, execute the runner, and inspect the results in the same workspace from another device.
Save and back up the model deliberately, and confirm that calculations and exports have finished before stopping the computer.
Start with this single-site comparison, then expand the runner only when a new requirement has matching validation and tests. The result is a reusable workflow that reduces repetitive model handling while keeping assumptions, changes, and outputs traceable.
FAQs
Can Claude Code automate WEAP calculations?
Yes. Claude Code can prepare and run a Windows Python script that controls WEAP through its COM API. WEAP performs the calculations; Claude Code helps develop and operate the automation.
Do I need an MCP server?
No. The Python runner works without MCP. A custom MCP server is optional if you want to expose validated functions as conversational tools.
Does the WEAP evaluation version support this workflow?
No. WEAP’s licensing documentation states that API access requires the unlocked version. Confirm activation separately from installation.
Why does the runner reject an existing alternative scenario?
This version creates new alternatives rather than updating existing ones. That prevents an ordinary rerun from overwriting a previous comparison. Use a clean working copy or configure a distinct alternative name.
Can I use different metrics or reporting frequencies?
The example exporter supports twelve-timestep Areas and the specified volume metrics in cubic metres. Daily results, storage, reliability, and other outputs need appropriate validation, time handling, and aggregation rules.
Does the runner save the Area automatically?
No. It changes the working model in memory and exports results. Review the changes, save the working Area explicitly, and reopen it to confirm that the intended scenario expressions were preserved.
Can I run it from WSL?
Use native Windows Python for the COM runner described here. A Linux interpreter inside WSL should not be assumed to have direct access to WEAP’s Windows COM interface.
Will a GPU make the calculations faster?
Do not assume so. Choose resources using model size, memory requirements, and measured calculation time. WEAP documents calculation-worker options, but those are separate from GPU acceleration.
Can Claude Code decide which scenario is best?
It can summarize validated results and highlight differences. Selecting a preferred scenario also requires reviewing assumptions, calibration, uncertainty, costs, and planning objectives. Passing automation tests does not establish that a scenario is suitable for a real-world decision.
A new demand forecast arrives, and your WEAP comparison needs updating. The inputs must be checked, the alternative scenario recalculated, and the results exported without changing the Reference assumptions. Repeating that sequence manually takes time and makes each run harder to reproduce.
Claude Code can help build a Python runner around WEAP’s documented automation API. Instead of generating disconnected scripts, the workflow uses one configuration to identify the working Area, define an approved scenario change, select the reporting period, and write a comparison CSV.
On Vagon Cloud Computer, WEAP, Claude Code, Python, and the project files can share one Windows desktop. You can develop the runner, execute the calculations, and inspect the saved model and exported results in the same workspace.
This guide follows a municipal demand-management example, from model inventory through scenario editing and result checks. The objective is a repeatable automation tool with traceable inputs and outputs, while modeling decisions remain with the people responsible for the analysis.

Source: SEI
Define the Comparison Before Building the Runner
Start with an existing WEAP Area whose Reference scenario already calculates successfully. The automation will work on a separate copy, create a demand-management alternative beneath Reference, and export the same result variables for both scenarios.
For the first version, limit the change to one verified municipal demand-site variable. WEAP’s Annual Water Use Rate represents water use per unit of activity. Reducing that rate is not equivalent to reducing population, changing supply capacity, or modifying a return-flow assumption.

Source: SEI
If the approved baseline expression is a constant, the example can apply a reviewed replacement constant. If it contains growth or references to other assumptions, preserve that structure through an explicitly approved expression instead.
Establish What the Runner May Do
The initial workflow will:
Verify the working Area, Reference scenario, branch, and variable.
Create a new alternative scenario with Reference as its parent.
Apply one configured expression change and read it back.
Calculate the comparison and export results for a defined period.
It will leave Reference’s input expressions unchanged and stop if the alternative name already exists. Updating an existing alternative can be added later as a separate operating mode.
Use One Configuration Throughout
The same configuration must supply the scenario names, target branch, replacement expression, reporting years, metrics, and units. The runner should not read a scenario name from configuration during editing and then use a different hardcoded name during export.
Give Claude Code this assignment:
Build one configuration-driven runner for the agreed comparison. Separate validation, scenario editing, calculation, and CSV export into functions. Report missing information rather than inventing model details.
That gives the code a clear scope and makes the resulting comparison easier to test.
Prepare WEAP and the Automation Tools on Vagon Cloud Computer
Use a Windows desktop with WEAP, Claude Code, and native Windows Python available in the same session. This lets the runner access WEAP through COM while you keep the application open for checking the model and results.
Check application selection for the tools you need, and install WEAP from its official installer if necessary. Complete activation before testing the connection: the WEAP licensing requirements specify that API access requires the unlocked version.
Open the original Area, confirm that Reference calculates, and create a separate working copy through WEAP’s Area management tools. Record the copy’s exact name and directory.

Source: SEI
Create a Small Python Project
Keep the runner, configuration, and outputs organized:
From PowerShell in the project folder, prepare the environment:
python -m venv .venv
.\.
pywin32 provides Windows COM access; pytest will support checks that do not require a running WEAP instance. Use the virtual environment’s Python explicitly when launching the runner.
The examples will build on scripts/weap_runner.py. Connection and inventory code belong in that runner, so later functions do not depend on variables left behind by a separately executed script.
Transfer the Complete Model Inputs
Use Vagon Files to bring over the Area backup, approved data, and supporting documents. Restore the working Area in WEAP and check every external file reference.
Keep Area-specific input files within the Area directory or its subdirectories where practical. The separate automation project holds the instructions and outputs; it is not itself the WEAP dataset.
Choose CPU and memory resources around model size and measured calculation time. Once the baseline opens and calculates correctly, the workspace is ready for the first connection check.
Connect to WEAP and Confirm the Working Area
Open the working Area in WEAP before running the script. The first check should report what Python can access without changing expressions, calculating scenarios, or saving the model.
Start scripts/weap_runner.py with a connection function and an inventory function:
import time
import win32com.client
def connect_weap(timeout=60):
weap = win32com.client.Dispatch("WEAP.WEAPApplication")
deadline = time.monotonic() + timeout
while not weap.ProgramStarted:
if time.monotonic() >= deadline:
raise TimeoutError("WEAP did not become ready")
time.sleep(0.5)
return weap
def show_inventory(weap):
print("WEAP version:", weap.SoftwareVersion)
print("Working Area:", weap.ActiveArea.Name)
print("Area directory:", weap.ActiveAreaDirectory)
for index in range(1, weap.Scenarios.Count + 1):
scenario = weap.Scenarios.Item(index)
print("Scenario:", scenario.Name)
if __name__ == "__main__
Run it from the automation project folder:
.\.These properties and collections are documented in the WEAP Application API. COM activation may connect to an existing instance or start WEAP. Compare the reported Area name and directory with the working copy visible in the application.
The timeout limits the readiness polling after COM activation returns; it is not a timeout for every possible COM operation.
Keep Application Access Explicit
Later functions will receive the connection as an argument, such as validate_config(weap, config). They will not assume that a variable created by another script remains available.
Before defining the scenario change, ask Claude Code to extend the inventory with the approved branch path:
Check the branch with BranchExists. If it exists, list its variable names, units, and current expressions in Reference. Report the scenario context explicitly. Do not assign expressions, create scenarios, calculate, or save.
Confirm the target against WEAP’s Data View. Keep its full branch path and exact variable name for the configuration. If the inventory reports a different Area or an unavailable target, resolve that mismatch before enabling model-changing functions.

Source: SEI
Put the Scenario Change and Reporting Rules in One Configuration
Save the approved instructions in config/comparison.json. The runner will read this file for both scenario editing and result export, so names and reporting settings are not repeated inside the code.
For the single-site comparison, use this structure:
{
"working_area": "Basin_Automation",
"working_area_directory": "C:/Users/YourName/Documents/WEAP Areas/Basin_Automation",
"baseline_scenario": "Reference",
"parent_scenario": "Reference",
"alternative_scenario": "Demand Management",
"change": {
"branch": "\\Demand Sites\\South City",
"variable": "Annual Water Use Rate",
"expected_parent_expression": "100",
"new_expression": "90"
},
"report": {
"first_year": 2025,
"last_year": 2030,
"metrics": ["Unmet Demand", "Supply Delivered"]
Replace the illustrative names, directory, expressions, and years with values confirmed in your model. The input change assumes an approved constant baseline and replacement. It is not a recommendation to reduce demand by a particular amount.
The reporting unit applies to the selected result variables, not automatically to the water-use-rate input. Confirm that input’s unit, scale, and activity denominator separately in WEAP.
Check the Parent Expression in the Correct Context
WEAP’s expression interface can return an inherited expression when a scenario has no local override.
For this first-run workflow, expected_parent_expression means the effective expression read while the configured parent scenario is active. The runner must verify it before creating the alternative. It will then place an explicit replacement in the new child scenario.

Source: SEI
Require parent_scenario and baseline_scenario to match for this initial example. Reject an existing alternative rather than silently updating it. Supporting other inheritance structures can be added later with separate checks.
Validate the Reporting Period Before Editing
The runner should also confirm that:
The configured Area name and directory match the open working copy.
The input variable exists and is editable.
The reporting metrics exist at the configured branch.
The requested years fall within the comparison scenarios’ supported period.
If CSV inputs are involved, check their coverage and missing-value rules before execution. WEAP’s ReadFromFile defaults can replace missing data with zero, so gaps need an explicit modeling decision rather than an automatic cleanup.
Validate the Configuration Before Applying the Change
Keep validation and editing as separate functions in scripts/weap_runner.py. That makes it possible to test the configuration without creating a scenario.
Start by loading the JSON file:
import json
import os
from pathlib import Path
def load_config():
project = Path(__file__).resolve().parents[1]
The path is resolved from the script’s location, not whichever directory happens to be open in the terminal.
Check the Area, Scenario, and Target Expression
Add this model-validation function below the connection code:
This checks model targets and period bounds. It does not establish that the replacement expression is scientifically appropriate or that a requested output unit is compatible. Keep those items in the approved specification.
Apply Only After Validation Passes
WEAP’s Scenario API creates a child beneath the specified parent. Add the editing function:
def apply_change(weap, config):
alternative = config["alternative_scenario"]
change = config["change"]
For this stage, replace the earlier inventory-only entry point with:
if __name__ == "__main__
Run this first on a disposable working copy. Inspect the alternative in WEAP’s Data View and confirm that Reference retained its original expression.

Source: SEI
The operation is not transactional. If creation or assignment fails, do not rerun blindly against the partially modified Area. Restore a clean working copy, diagnose the failure, and repeat validation. Calculation and saving will be deliberate subsequent steps.
Calculate the Comparison and Keep a Run Log
Activating the alternative does not, by itself, define which scenarios WEAP calculates. Configure the comparison set explicitly, then request a fresh calculation.
Add this function to scripts/weap_runner.py. It selects the baseline and alternative, retains Current Accounts, and records calculation messages in a run-specific log.
def calculate_comparison(weap, config, run_id):
project = Path(__file__).resolve().parents[1]
The WEAP Application API documents calculation status, error counts, logging, and elapsed time. The third argument to Calculate forces recalculation, including when external input files have changed without WEAP recognizing that results are stale.
The function leaves the comparison scenarios selected for results review. It does not restore the previous display selection or save the Area.
Add Calculation to the Runner
Import uuid at the top of the file. In the existing entry point, add these lines after apply_change(weap, config) and replace the earlier inventory-stage completion message:
Run the assembled script on the working copy. Review the calculation log and WEAP’s Messages tab before treating the outputs as valid. Warnings may still need attention even when the calculation error count is zero.
This version uses the configured calculation-worker setting. Start with one worker for the initial verification; evaluate WEAP’s supported parallel options separately once the two-scenario workflow is reliable.
Export Both Scenarios to a Comparison CSV
The exporter should use the same configuration as the editing stage. It should not contain a second set of scenario names, branches, or reporting years.
For this first version, keep the reporting scope narrow: monthly Areas, the two configured volume metrics, and cubic metres. Add these checks inside validate_config, after report is assigned:
if int(weap.NumTimeSteps) != 12:
raise ValueError("This exporter requires a 12-timestep Area")
if report["unit"] != "m^3":
raise ValueError("This example exports cubic metres only")
if not report["metrics"] or not set(report["metrics"]
These checks belong before apply_change. Other reporting frequencies and metrics need their own validation rather than silently reusing this exporter.
Write Labeled Results, Not Console Output
Add import csv and import math at the top of the runner, then add:
def export_results(weap, config, run):
project = Path(__file__).resolve().parents[1]
folder = project / "reports" / run["run_id"]
After calculation succeeds, call it from the existing entry point:
The file retains its .partial.csv name if export fails. Only a completed export becomes comparison.csv.
Preserve the Time Convention
WEAP’s ResultValue interface uses water-year timestep numbering. Timestep 1 is not necessarily January. Record the Area’s water-year convention alongside the report.

Source: SEI
Keep these rows as timestep volumes. Aggregate them later over an explicitly defined period, and retain the unrounded export for checking against WEAP. A missing result stops this example rather than becoming an invented zero.
Test the Runner Before Using Its Comparison
The assembled runner now creates an alternative, calculates results, and writes a CSV. Before using that output, test both its refusal conditions and its behavior inside WEAP.
Keep the if __name__ == "__main__": guard in place. It lets tests import functions without automatically connecting to WEAP or editing an Area.
Start with a Refusal Test
Create tests/test_validation.py:
Run the test from the project folder:
.\.This checks one validation boundary without starting WEAP. It does not establish that COM operations work. Extend the tests to cover an existing alternative, an unexpected parent expression, invalid reporting years, and unsupported metrics.
Verify the Application Behavior Separately
Use a disposable Area copy for integration checks:
A failed validation must leave the alternative uncreated and input expressions unchanged.
A successful edit must place the replacement in the alternative while preserving Reference.
The CSV must contain both scenarios and the configured period, metrics, and units.
Selected exported values must match WEAP’s Results View.
For the illustrative 2025–2030 configuration, two scenarios, twelve timesteps, and two metrics produce 288 data rows, excluding the header. That is an expected structural count, not evidence that the numbers are correct.
Check a normal period, a high-demand period, and any unexpectedly large scenario difference. Use matching units and allow only the agreed numerical tolerance.

Source: SEI
Save and Reopen the Working Area
The runner intentionally does not save automatically. After reviewing the changes and results, save the working Area in WEAP, close it, and reopen it. Confirm the alternative and its expression are preserved.
Do not rerun the create-mode runner merely to check the saved Area: it should reject the existing alternative. Use the inventory function or WEAP’s interface instead.
Keep policy interpretation separate from these tests. Passing them establishes specific automation behaviors, not calibration or the suitability of a demand-management decision.
Add MCP or Computer Use Only Where They Help
The Python runner is the main automation path. Claude Code can prepare and launch it, while WEAP’s COM API handles application operations. Neither scenario editing nor CSV export requires an MCP server.
Use MCP for a Reusable Tool Interface
Once the runner has passed your tests, a custom MCP server could expose selected functions to the assistant. Useful starting operations include inspecting the active Area, validating a configuration, and retrieving an existing run report.
Keep those separate from operations that create scenarios, change expressions, calculate, or save. A conversational interface should preserve the runner’s checks rather than introduce another way to bypass them.
This would be an integration you build and verify, not a ready-made official WEAP connector.
Use Computer Use for Application Review
Where supported and enabled, Claude Code’s computer use can help open a result chart, inspect the displayed scenario, or capture a calculation warning.
Give it a bounded task:
Open the unmet-demand result for the configured branch and compare Reference with Demand Management. Do not change inputs, recalculate, or save.

Source: SEI
The control session must target the Vagon desktop where WEAP is running. A terminal session alone does not grant screen access.
Use the CSV and API checks for numerical verification, with the interface providing a complementary view. A chart can make a difference easier to understand, but it cannot establish that the correct input expressions and reporting settings were used.
Keep the Workflow Ready for the Next Update
Keep each comparison’s configuration beside its CSV, with the input-file versions, script version, calculation log, and WEAP Area backup. The run identifier links the report folder to its calculation log; retaining the configuration explains what that run was intended to do.

Source: SEI
Before processing another update, decide how to preserve the previous comparison. This runner requires a new alternative name. Either restore a clean working copy or configure a distinct alternative for the next approved run. Do not delete an earlier scenario simply to bypass the existing-name check.
On Vagon Cloud Computer, the configured Windows tools, automation project, and WEAP installation can remain together between sessions. You can prepare the next dataset, execute the runner, and inspect the results in the same workspace from another device.
Save and back up the model deliberately, and confirm that calculations and exports have finished before stopping the computer.
Start with this single-site comparison, then expand the runner only when a new requirement has matching validation and tests. The result is a reusable workflow that reduces repetitive model handling while keeping assumptions, changes, and outputs traceable.
FAQs
Can Claude Code automate WEAP calculations?
Yes. Claude Code can prepare and run a Windows Python script that controls WEAP through its COM API. WEAP performs the calculations; Claude Code helps develop and operate the automation.
Do I need an MCP server?
No. The Python runner works without MCP. A custom MCP server is optional if you want to expose validated functions as conversational tools.
Does the WEAP evaluation version support this workflow?
No. WEAP’s licensing documentation states that API access requires the unlocked version. Confirm activation separately from installation.
Why does the runner reject an existing alternative scenario?
This version creates new alternatives rather than updating existing ones. That prevents an ordinary rerun from overwriting a previous comparison. Use a clean working copy or configure a distinct alternative name.
Can I use different metrics or reporting frequencies?
The example exporter supports twelve-timestep Areas and the specified volume metrics in cubic metres. Daily results, storage, reliability, and other outputs need appropriate validation, time handling, and aggregation rules.
Does the runner save the Area automatically?
No. It changes the working model in memory and exports results. Review the changes, save the working Area explicitly, and reopen it to confirm that the intended scenario expressions were preserved.
Can I run it from WSL?
Use native Windows Python for the COM runner described here. A Linux interpreter inside WSL should not be assumed to have direct access to WEAP’s Windows COM interface.
Will a GPU make the calculations faster?
Do not assume so. Choose resources using model size, memory requirements, and measured calculation time. WEAP documents calculation-worker options, but those are separate from GPU acceleration.
Can Claude Code decide which scenario is best?
It can summarize validated results and highlight differences. Selecting a preferred scenario also requires reviewing assumptions, calibration, uncertainty, costs, and planning objectives. Passing automation tests does not establish that a scenario is suitable for a real-world decision.
Get Beyond Your Computer Performance
Run applications on your cloud computer with the latest generation hardware. No more crashes or lags.

Trial includes 1 hour usage + 7 days of storage.
Summarize with AI

Ready to focus on your creativity?
Vagon gives you the ability to create & render projects, collaborate, and stream applications with the power of the best hardware.

Run heavy applications on any device with
your personal computer on the cloud.
San Francisco, California
Solutions
Vagon Teams
Vagon Streams
Use Cases
© 2026 Vagon. All rights reserved.
Run heavy applications on any device with
your personal computer on the cloud.
San Francisco, California
Solutions
Vagon Teams
Vagon Streams
Use Cases
© 2026 Vagon. All rights reserved.
Run heavy applications on any device with
your personal computer on the cloud.
San Francisco, California
Solutions
Vagon Teams
Vagon Streams
Use Cases
© 2026 Vagon. All rights reserved.