WaterTAP Engine MCP
by puran-water
README.md
# WaterTAP Engine MCP
> **⚠️ DEVELOPMENT STATUS: This project is under active development and is not yet production-ready. APIs, interfaces, and functionality may change without notice. Use at your own risk for evaluation and testing purposes only. Not recommended for production deployments.**
A water treatment process simulation engine exposing [WaterTAP](https://github.com/watertap-org/watertap) capabilities through dual adapters for AI agent integration.
## Motivation
WaterTAP provides sophisticated equation-oriented models for water treatment processes (RO, NF, crystallizers, evaporators, biological treatment), but the modeling workflow requires substantial domain expertise: DOF management, proper scaling, sequential initialization, and solver diagnostics.
WaterTAP Engine MCP inverts this paradigm by making **natural language the primary interface**. Instead of manually managing DOF, scaling, and initialization, engineers can work with a companion skill that orchestrates these operations:
> "Evaluate hardness removal (IX or lime/soda softening) upstream of RO in this ZLD flowsheet: compare regenerant and chemical costs against natural gas savings from reduced evaporator thermal load, and calculate the IRR on incremental pre-treatment CAPEX."
This enables:
- **Collapsed iteration cycles**: Build -> solve -> diagnose -> patch -> re-solve without manual DOF tracking
- **Explicit hygiene operations**: Every fix, scale, and init is visible and controllable
- **Structured diagnostics**: DOF suggestions, scaling issues, and failure explanations surfaced directly to agents
- **Reproducible sessions**: Version-controlled flowsheet definitions with deterministic metadata
The goal is not to replace domain expertise, but to **remove friction** so engineers can focus on design decisions rather than solver mechanics.
## WaterTAP vs QSDsan: Solver Paradigms
This server is a sibling to [qsdsan-engine-mcp](../qsdsan-engine-mcp/) but uses a fundamentally different solver approach:
| Aspect | WaterTAP (This Server) | QSDsan |
|--------|------------------------|--------|
| **Solver Type** | Equation-oriented NLP (IPOPT) | ODE integration (solve_ivp) |
| **Modeling Framework** | Pyomo + IDAES | BioSTEAM |
| **Simulation Mode** | Steady-state algebraic | Dynamic ODE time-stepping |
| **Simulation Speed** | ~seconds to minutes per solve | ~milliseconds to seconds per run |
| **Optimization** | Native gradient-based (pyomo.environ.SolverFactory) | Requires external optimizer |
| **DOF Management** | Explicit - requires DOF=0 before solve | Implicit - feed-forward sequential |
| **Scaling** | Critical for convergence | Not required |
| **Sensitivities** | Automatic via NLP solver | Finite-difference approximation |
### Steady-State vs Dynamic Simulation
**WaterTAP (Equation-Oriented, Steady-State)**
- Solves a system of nonlinear algebraic equations: `F(x) = 0`
- All variables solved simultaneously to find steady-state directly
- Requires DOF = 0 (number of equations = number of unknowns)
- Ideal for **design optimization**: "What membrane area minimizes LCOW?"
- Supports native **sensitivity analysis** and **gradient-based optimization**
- Slower per solve but faster for optimization (exact gradients)
**QSDsan (ODE Integration, Dynamic)**
- Integrates differential equations forward in time: `dx/dt = f(x,t)`
- Simulates transient behavior from t=0 to t=T
- Variables update sequentially; no DOF constraint
- Ideal for **dynamic behavior**: "How does effluent quality change during startup?"
- Supports **Monte Carlo sampling** and **scenario enumeration** (fast per run)
- Faster per run but requires many runs for optimization (finite-difference)
### When to Use WaterTAP
- **Membrane process optimization**: RO/NF with detailed concentration polarization, fouling models
- **Gradient-based optimization**: Minimize LCOW, maximize recovery, optimal pressure
- **Rigorous thermodynamics**: Multi-component phase equilibria, crystallization
- **Design decisions**: Optimal membrane area, stage configuration, pressure setpoints
- **Sensitivity analysis**: How does recovery change with feed salinity?
### When to Use QSDsan
- **Biological treatment dynamics**: Activated sludge transients, digester startup/upset
- **Rapid scenario enumeration**: Monte Carlo uncertainty quantification, DOE
- **Time-series analysis**: Diurnal patterns, storm events, process disturbances
- **Simpler mass balances**: When steady-state is sufficient but dynamics are informative
- **Training simulators**: Interactive "what-if" exploration with fast feedback
## Architecture: Dual Adapters
The engine exposes identical functionality through two adapters:
```
+-------------------------------------+
| WaterTAP Engine Core |
| (Registries, Pipeline, Sessions) |
+-----------------+-------------------+
|
+-----------------------+---------------------+
| | |
v v v
+----------------+ +----------------+ +----------------+
| MCP Adapter | | CLI Adapter | | Python API |
| (server.py) | | (cli.py) | | (direct use) |
+----------------+ +----------------+ +----------------+
| |
v v
+----------------+ +----------------+
| MCP Clients | | Agent Skills |
| (Claude, etc) | | (Claude Code) |
+----------------+ +----------------+
```
### MCP Adapter (`server.py`)
For MCP-compatible clients (Claude Desktop, Cline, etc.):
```bash
python server.py
```
### CLI Adapter (`cli.py`)
For CLI-based agent runtimes and Agent Skills:
```bash
python cli.py --help
```
## Tool Surface
### Session Management Tools
| Tool | MCP | CLI | Description |
|------|-----|-----|-------------|
| `create_session` | `create_session` | `session new` | Create new flowsheet session |
| `get_session` | `get_session` | `session show` | Get session details |
| `list_sessions` | `list_sessions` | `session list` | List all sessions |
| `delete_session` | `delete_session` | `session delete` | Remove session |
### Registry & Discovery Tools
| Tool | MCP | CLI | Description |
|------|-----|-----|-------------|
| `list_units` | `list_units` | `units list` | List available unit types |
| `list_property_packages` | `list_property_packages` | `packages list` | List property packages |
| `list_translators` | `list_translators` | `translators list` | List ASM/ADM translators |
| `get_unit_spec` | `get_unit_spec` | `units spec` | Get DOF, scaling, init hints |
### Flowsheet Construction Tools
| Tool | MCP | CLI | Description |
|------|-----|-----|-------------|
| `create_feed` | `create_feed` | `flowsheet add-feed` | Add feed with state |
| `create_unit` | `create_unit` | `flowsheet add-unit` | Add unit operation |
| `create_translator` | `create_translator` | `flowsheet add-translator` | Add ASM/ADM translator |
| `connect_ports` | `connect_ports` | `flowsheet connect` | Wire units together |
| `update_unit` | `update_unit` | `flowsheet update-unit` | Modify unit parameters |
| `delete_unit` | `delete_unit` | `flowsheet delete-unit` | Remove unit |
| `validate_flowsheet` | `validate_flowsheet` | `flowsheet validate` | Pre-build validation |
### DOF Management Tools
| Tool | MCP | CLI | Description |
|------|-----|-----|-------------|
| `get_dof_status` | `get_dof_status` | `dof status` | Get DOF count per unit |
| `fix_variable` | `fix_variable` | `dof fix` | Fix variable to value |
| `unfix_variable` | `unfix_variable` | `dof unfix` | Release variable |
| `list_unfixed_vars` | `list_unfixed_vars` | `dof unfixed` | Show unfixed variables |
### Scaling Tools
| Tool | MCP | CLI | Description |
|------|-----|-----|-------------|
| `set_scaling_factor` | `set_scaling_factor` | `scale set` | Set explicit scaling |
| `calculate_scaling_factors` | `calculate_scaling_factors` | `scale calculate` | Run IDAES scaling |
| `report_scaling_issues` | `report_scaling_issues` | `scale report` | Find scaling problems |
### Solver Operations Tools
| Tool | MCP | CLI | Description |
|------|-----|-----|-------------|
| `initialize_unit` | `initialize_unit` | `init unit` | Initialize single unit |
| `initialize_flowsheet` | `initialize_flowsheet` | `init flowsheet` | Sequential initialization |
| `propagate_state` | `propagate_state` | `init propagate` | State between ports |
| `build_and_solve` | `build_and_solve` | `solve` | Full hygiene pipeline |
| `get_solve_status` | `get_solve_status` | `status` | Job status |
| `run_diagnostics` | `run_diagnostics` | `diagnose` | DiagnosticsToolbox |
### Zero-Order Tools
| Tool | MCP | CLI | Description |
|------|-----|-----|-------------|
| `load_zo_parameters` | `load_zo_parameters` | `zo load` | Load from database |
| `list_zo_databases` | `list_zo_databases` | `zo databases` | Available databases |
| `get_zo_unit_parameters` | `get_zo_unit_parameters` | `zo params` | Unit parameters |
### Costing Tools
| Tool | MCP | CLI | Description |
|------|-----|-----|-------------|
| `enable_costing` | `enable_costing` | `costing enable` | Enable costing block |
| `add_unit_costing` | `add_unit_costing` | `costing add-unit` | Enable costing for unit |
| `disable_unit_costing` | `disable_unit_costing` | `costing disable-unit` | Disable unit costing |
| `set_costing_parameters` | `set_costing_parameters` | `costing set-params` | Set cost parameters |
| `list_costed_units` | `list_costed_units` | `costing list` | Show costing status |
| `compute_costing` | `compute_costing` | `costing compute` | Calculate LCOW, CapEx, OpEx |
| `get_costing` | `get_costing` | `costing results` | Get costing results |
### Results Tools
| Tool | MCP | CLI | Description |
|------|-----|-----|-------------|
| `get_results` | `get_results` | `results` | Overall solve results |
| `get_stream_results` | `get_stream_results` | `results streams` | Stream tables |
| `get_unit_results` | `get_unit_results` | `results units` | Unit performance |
## Property Packages
13 supported property packages:
| Package | Components | Use Case |
|---------|------------|----------|
| **SEAWATER** | H2O + TDS | Seawater RO/NF, mass basis |
| **NACL** | H2O + NaCl | Brackish RO, mass basis |
| **NACL_T_DEP** | H2O + NaCl | Temperature-dependent thermal |
| **WATER** | H2O | Pure water, Liq + Vap |
| **MCAS** | Multi-ion | Ion-specific NF, molar basis |
| **ZERO_ORDER** | Database-driven | Simple ZO models |
| **ASM1** | 13 | Activated sludge (basic) |
| **ASM2D** | 19 | Activated sludge with bio-P |
| **ASM3** | - | Activated sludge extended |
| **MODIFIED_ASM2D** | - | Modified ASM2d |
| **ADM1** | 63 | Anaerobic digestion |
| **MODIFIED_ADM1** | - | Modified ADM1 |
| **ADM1_VAPOR** | - | ADM1 vapor phase |
**Warning - Class-Name Collisions:**
- `NaClParameterBlock` exists in both `NaCl_prop_pack.py` AND `NaCl_T_dep_prop_pack.py`
- `WaterParameterBlock` exists in both `water_prop_pack.py` AND `zero_order_properties.py`
Always use the full module path from the registry, not the class name alone.
## Translators
**Only ASM↔ADM translators exist in WaterTAP!** The registry includes 8 translators:
**Core Translators (4):**
| Source | Destination | Translator |
|--------|-------------|------------|
| ASM1 | ADM1 | Translator_ASM1_ADM1 |
| ADM1 | ASM1 | Translator_ADM1_ASM1 |
| ASM2D | ADM1 | Translator_ASM2d_ADM1 |
| ADM1 | ASM2D | Translator_ADM1_ASM2d |
**Modified Model Translators (4):**
| Source | Destination | Translator |
|--------|-------------|------------|
| ModifiedASM2D | ADM1 | Translator_ModifiedASM2d_ADM1 |
| ADM1 | ModifiedASM2D | Translator_ADM1_ModifiedASM2d |
| ASM2D | ModifiedADM1 | Translator_ASM2d_ModifiedADM1 |
| ModifiedADM1 | ASM2D | Translator_ModifiedADM1_ASM2d |
For non-biological flowsheets, use the **same property package** throughout.
## Unit Registry
21+ unit operations available across categories:
- **Membrane:** ReverseOsmosis0D, ReverseOsmosis1D, Nanofiltration0D, NanofiltrationDSPMDE0D
- **Zero-Order:** NanofiltrationZO, UltraFiltrationZO, PumpZO, FeedZO
- **Thermal:** Evaporator, Condenser, Compressor, Crystallization
- **Pumps/ERD:** Pump, EnergyRecoveryDevice, PressureExchanger
- **Utilities:** Feed, Product, Mixer, Separator (from IDAES)
- **Biological:** (Use property package compatibility for ASM/ADM)
```bash
# List all units
python cli.py units list --json-out
# Filter by category
python cli.py units list --category membrane
```
## Solver Hygiene Pipeline
The `build_and_solve` tool runs the full hygiene pipeline:
```
IDLE -> DOF_CHECK -> SCALING -> INITIALIZATION -> PRE_SOLVE_DIAGNOSTICS -> SOLVING
|
COMPLETED <-- POST_SOLVE_DIAGNOSTICS <----------------------------------------+
^ | (if failed) |
+------- RELAXED_SOLVE ---------------------------------------------------+
| (if still fails)
FAILED
```
Each stage provides structured output for diagnosis:
- **DOF_CHECK:** Underspecified/overspecified analysis with suggestions
- **SCALING:** Unscaled variables and constraint warnings
- **INITIALIZATION:** Per-unit init status and DOF after init
- **DIAGNOSTICS:** Constraint residuals, bound violations
## Quick Start
### Using CLI
```bash
# Create session
python cli.py session new --property-package SEAWATER --id my_ro
# Add feed and units
python cli.py flowsheet add-feed --session my_ro --flow 100 \
--tds 35000 --temp 25 --pressure 1.01
python cli.py flowsheet add-unit --session my_ro --type ReverseOsmosis0D \
--id RO1 --config '{"has_pressure_change": true}'
# Fix DOF
python cli.py dof fix --session my_ro --unit RO1 --var "A_comp[0, H2O]" --value 4.2e-12
python cli.py dof fix --session my_ro --unit RO1 --var "B_comp[0, TDS]" --value 3.5e-8
python cli.py dof fix --session my_ro --unit RO1 --var area --value 50
python cli.py dof fix --session my_ro --unit RO1 --var "permeate.pressure[0]" --value 101325
# Check DOF
python cli.py dof status --session my_ro
# Solve
python cli.py solve --session my_ro --run-full-pipeline
```
### Using MCP
Configure in your MCP client (e.g., Claude Desktop `config.json`):
```json
{
"mcpServers": {
"watertap-engine": {
"command": "python",
"args": ["/path/to/watertap-engine-mcp/server.py"]
}
}
}
```
Then use natural language with the companion skill:
> "Evaluate hardness removal upstream of RO in this ZLD flowsheet and calculate the IRR on incremental pre-treatment CAPEX based on reduced evaporator thermal load."
## Installation
```bash
# Clone repository
git clone https://github.com/puran-water/watertap-engine-mcp.git
cd watertap-engine-mcp
# Create virtual environment
python -m venv venv
source venv/bin/activate # or venv\Scripts\activate on Windows
# Install dependencies
pip install -r requirements.txt
# For full WaterTAP support (optional, for solve operations):
pip install watertap idaes-pse pyomo
```
### Dependencies
- Python 3.10+
- WaterTAP 1.0+ (optional, for solve)
- IDAES-PSE 2.0+ (optional, for solve)
- FastMCP (for MCP adapter)
- Typer (for CLI adapter)
## File Structure
```
watertap-engine-mcp/
├── server.py # MCP Adapter (FastMCP) - 57 tools
├── cli.py # CLI Adapter (typer)
├── worker.py # Background job worker
├── core/
│ ├── property_registry.py # 13 property packages
│ ├── translator_registry.py # ASM/ADM translators
│ ├── unit_registry.py # Unit specs with DOF, scaling
│ ├── water_state.py # Feed state abstraction
│ └── session.py # Session management
├── solver/
│ ├── pipeline.py # Hygiene pipeline state machine
│ ├── dof_resolver.py # DOF analysis
│ ├── scaler.py # Scaling tools
│ ├── initializer.py # Sequential initialization
│ ├── diagnostics.py # DiagnosticsToolbox wrapper
│ └── recovery.py # Failure recovery
├── utils/
│ ├── model_builder.py # Session -> Pyomo model
│ ├── auto_translator.py # Translator insertion
│ ├── job_manager.py # Background jobs
│ ├── state_translator.py # Feed state conversion
│ └── topo_sort.py # Topological sort
├── templates/ # Pre-built flowsheet templates
│ ├── ro_train.py
│ ├── nf_softening.py
│ └── mvc_crystallizer.py
├── jobs/ # Session/job persistence (runtime)
└── tests/ # 373 tests
```
## Companion Skill
The `watertap-flowsheet-builder` skill (at `~/skills/watertap-skill/`) provides domain intelligence:
- DOF suggestions with typical values for each unit type
- Property package selection guidance
- Translator selection for biological chains
- Failure diagnosis patterns
- Workflow orchestration for common flowsheets
The skill orchestrates the atomic server tools - server provides explicit operations, skill provides intelligence.
## Testing
```bash
# Run all tests
pytest tests/ -v
# Skip slow tests
pytest tests/ -v -m "not slow"
```
## License
MIT
## Acknowledgments
Built on [WaterTAP](https://github.com/watertap-org/watertap) by the National Alliance for Water Innovation (NAWI).
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues