Model Context Protocol server for DWSIM chemical process simulation
Project description
DWSIM MCP Server
ol-dwsim-mcp-server lets LLM agents drive DWSIM, the
open-source chemical process simulator, through a typed
Model Context Protocol interface. It is
the Python façade in OntoLedgy's thermodynamics stack: agents (Claude
Desktop, VS Code Copilot, Codex CLI, custom orchestrators) call MCP tools
such as add_compound, add_unit, connect, run, and flash_tp; the
server translates those calls into in-process .NET interop with the DWSIM
assemblies via pythonnet, executes the simulation, and returns
structured, JSON-friendly results — convergence state, stream conditions,
phase compositions, mass-balance checks, and diagnostic messages.
The server exposes 35 tools spanning session lifecycle, flowsheet
construction, equation-of-state property packages, equilibrium flashes
(TP / PH / PS), and sensitivity / optimisation studies. It enforces
per-session memory and timeout limits, emits structured logs and
OpenTelemetry traces, and supports optional OAuth (Clerk) when deployed
beyond a local workstation. A pre-built DwsimWorker distribution is
bundled so beta users can connect without building the C# layer.
Typical use cases: conversational flowsheet authoring, automated parameter sweeps, AI-assisted process design reviews, and integration into agentic chemical-engineering workflows where a planning agent delegates simulation tasks to DWSIM and reasons over the returned results.
Architecture
The MCP server acts as a façade layer that:
- Implements MCP protocol using the official Python SDK
- Exposes DWSIM capabilities as composable MCP tools (35 tools available)
- Uses pythonnet for in-process .NET interop with DWSIM assemblies
- Provides structured logging and observability
- Enforces safety and resource limits
Quick Start
Prerequisites
- Python 3.11+
- .NET Framework 4.8 (Windows)
- DWSIM binaries (see below)
- uv package manager (recommended)
Installation
cd mcp_service/server
uv sync
DWSIM Assemblies
Ensure DWSIM binaries are available:
- Default location:
mcp_service/dwsim_worker/dwsim_binaries/x64/Debug - Override with
DWSIM_PATHenvironment variable
Connecting to AI Assistants
Quick Setup for Beta Testers
If you don't want to build the C# layer, use the pre-built distribution:
cd dwsim_interop_services
.\prebuilt\setup.ps1
See prebuilt/README.md for details.
Option A: VS Code Copilot (settings.json)
Add to your VS Code settings.json (Ctrl+, → Open Settings JSON):
{
"github.copilot.chat.mcpServers": {
"dwsim": {
"command": "uv",
"args": ["run", "dwsim-mcp"],
"cwd": "C:\\path\\to\\dwsim_interop_services\\mcp_service\\server",
"env": {
"PYTHONPATH": "C:\\path\\to\\dwsim_interop_services"
}
}
}
}
Option B: VS Code Copilot (mcp.json)
Create/edit %APPDATA%\Code\User\mcp.json:
{
"servers": {
"dwsim": {
"command": "uv",
"args": ["run", "dwsim-mcp"],
"cwd": "C:\\path\\to\\dwsim_interop_services\\mcp_service\\server",
"env": {
"PYTHONPATH": "C:\\path\\to\\dwsim_interop_services"
}
}
}
}
Option C: Claude Desktop
Edit %APPDATA%\Claude\claude_desktop_config.json:
{
"mcpServers": {
"dwsim": {
"command": "uv",
"args": ["run", "dwsim-mcp"],
"cwd": "C:\\path\\to\\dwsim_interop_services\\mcp_service\\server",
"env": {
"PYTHONPATH": "C:\\path\\to\\dwsim_interop_services"
}
}
}
}
Option D: OpenAI Codex CLI
Edit %USERPROFILE%\.codex\config.json:
{
"mcpServers": {
"dwsim": {
"command": "uv",
"args": ["run", "dwsim-mcp"],
"cwd": "C:\\path\\to\\dwsim_interop_services\\mcp_service\\server",
"env": {
"PYTHONPATH": "C:\\path\\to\\dwsim_interop_services"
}
}
}
}
Then run: codex --mcp
Verification
After configuration:
- Reload/Restart your AI assistant
- Ask: "What DWSIM tools do you have available?"
- You should see 35 tools listed
For detailed instructions, see docs/resources/getting-started.md
Running Manually (for testing)
cd C:\path\to\dwsim_interop_services\mcp_service\server
$env:PYTHONPATH = "C:\path\to\dwsim_interop_services"
uv run dwsim-mcp
Configuration
Create a .env file or set environment variables:
# Worker connection
DWSIM_WORKER_PIPE_NAME=dwsim_worker_pipe
DWSIM_WORKER_STARTUP_TIMEOUT=30
# Resource limits
DWSIM_MAX_SESSIONS=10
DWSIM_SESSION_TIMEOUT=3600
DWSIM_OPERATION_TIMEOUT=300
DWSIM_MEMORY_LIMIT_MB=2048
DWSIM_MEMORY_POLL_INTERVAL_SECONDS=2
DWSIM_MEMORY_RECOVERY_RATIO=0.9
# Logging
LOG_LEVEL=INFO
LOG_FORMAT=json
Authentication
OAuth authentication is optional. By default, the server runs without auth
(DWSIM_AUTH_ENABLED=false). For local development, keep auth disabled.
To enable OAuth with Clerk, configure the Clerk issuer, audience, and scopes. See the setup guide: docs/mcp/clerk-oauth-setup.md.
Minimal example:
DWSIM_AUTH_ENABLED=true
CLERK_ISSUER_URL=https://<your-tenant>.clerk.accounts.dev
CLERK_AUDIENCE=dwsim-mcp
CLERK_REQUIRED_SCOPES=user
Usage
Starting the MCP Server
# Using Poetry
poetry run dwsim-mcp
# Using Python module
python -m dwsim_mcp_server
# With custom config
python -m dwsim_mcp_server --config config.yaml
Using as a Library
from dwsim_mcp_server import MCPServer
async def main():
server = MCPServer()
await server.start()
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Development
Running Tests
# All tests
pytest
# With coverage
pytest --cov=dwsim_mcp_server --cov-report=html
# Specific test file
pytest tests/unit/test_session.py
# Fuller run (includes smoke; requires DwsimWorker.dll built in Debug)
pytest tests/smoke tests/unit tests/integration
Code Quality
# Format code
black dwsim_mcp_server tests
# Lint
ruff check dwsim_mcp_server tests
# Type checking
mypy dwsim_mcp_server
Project Structure
server/
├── dwsim_mcp_server/ # Main Python package
│ ├── server.py # MCP server bootstrap
│ ├── tools/ # MCP tool implementations
│ ├── resources/ # MCP resource providers
│ ├── ipc/ # IPC client for worker communication
│ ├── converters/ # Model converters
│ ├── config/ # Configuration management
│ └── observability/ # Logging, tracing, metrics
├── tests/ # Test suite
├── pyproject.toml # Poetry configuration
└── requirements.txt # Pip dependencies
Available MCP Tools
Session Management
create_session- Create a new DWSIM simulation sessionclose_session- Close and cleanup a sessionsave_case- Save session to DWSIM fileload_case- Load existing DWSIM file
Flowsheet Building
add_compound- Add chemical compound to simulationset_property_package- Configure thermodynamic property packageadd_stream- Add material or energy streamadd_unit- Add unit operation (mixer, separator, reactor, etc.)connect- Connect streams to unit operations
Simulation
run- Execute flowsheet simulationget_status- Check simulation statusget_results- Retrieve simulation results
Simulation Tools Details
run
Execute a simulation for the session and return convergence details and stream properties.
Input:
{
"session_id": "session-1234",
"timeout_seconds": 120
}
Output:
{
"status": "converged",
"convergence_state": "Converged",
"elapsed_ms": 1250.0,
"stream_results": [
{
"id": "stream-001",
"name": "Vapor Outlet",
"temperature_k": 350.0,
"pressure_pa": 101325.0,
"total_molar_flow_mol_per_s": 10.5,
"phases": []
}
],
"messages": ["Calculation converged successfully."],
"mass_balance_valid": true,
"mass_balance_error_percent": 0.4
}
get_status
Retrieve the latest simulation status for a session.
Input:
{
"session_id": "session-1234"
}
Output:
{
"status": "running",
"is_running": true,
"last_run_timestamp": "2024-12-19T20:30:00Z",
"elapsed_ms": 450.0
}
get_results
Retrieve cached results from the most recent run. Use object_id to request a single stream.
Input:
{
"session_id": "session-1234",
"object_id": "stream-001"
}
Output:
{
"status": "converged",
"convergence_state": "Converged",
"elapsed_ms": 1250.0,
"stream_results": [
{
"id": "stream-001",
"name": "Vapor Outlet",
"temperature_k": 350.0,
"pressure_pa": 101325.0,
"total_molar_flow_mol_per_s": 10.5,
"phases": []
}
],
"messages": [],
"mass_balance_valid": true,
"mass_balance_error_percent": 0.4
}
Simulation Workflow Example
{"tool": "create_session", "arguments": {"name": "Separator Run"}}
{"tool": "add_compound", "arguments": {"session_id": "session-1234", "compound_name": "Water"}}
{"tool": "set_property_package", "arguments": {"session_id": "session-1234", "package_name": "peng-robinson", "options": {}}}
{"tool": "add_stream", "arguments": {"session_id": "session-1234", "name": "feed", "temperature": 298.15, "pressure": 101325.0, "molar_flow": 10.0, "composition": {"Water": 1.0}}}
{"tool": "add_unit", "arguments": {"session_id": "session-1234", "unit_type": "separator", "name": "sep-01", "parameters": {}}}
{"tool": "connect", "arguments": {"session_id": "session-1234", "source_id": "stream-001", "target_id": "unit-001", "port_name": "Inlet"}}
{"tool": "run", "arguments": {"session_id": "session-1234", "timeout_seconds": 120}}
{"tool": "get_status", "arguments": {"session_id": "session-1234"}}
{"tool": "get_results", "arguments": {"session_id": "session-1234"}}
Simulation Error Codes
Simulation tools return structured error payloads when operations fail:
CONVERGENCE_FAILURE- Solver did not convergeSIMULATION_TIMEOUT- Calculation exceeded timeoutINVALID_FLOWSHEET_STATE- Missing or invalid flowsheet topologyNO_RESULTS_AVAILABLE- Results requested before a successful runRESOURCE_LIMIT_EXCEEDED- Memory or resource cap exceededSESSION_EXPIRED- Session lifetime exceeded
Thermodynamics
flash_tp- Flash calculation at temperature and pressureflash_ph- Flash at pressure and enthalpyflash_ps- Flash at pressure and entropy
Analysis
sensitivity_analysis- Perform sensitivity studyoptimization- Optimize process variables
Troubleshooting
Worker Connection Issues
If the server cannot connect to the .NET worker:
- Ensure the worker is running:
DwsimWorker.exe - Check the pipe name matches in both server and worker configs
- Verify Named Pipes are available (Windows) or use TCP fallback
Import Errors
# Ensure all dependencies are installed
pip install -r requirements.txt
# Verify PYTHONPATH includes project root
export PYTHONPATH="${PYTHONPATH}:$(pwd)"
Performance Issues
- Adjust
DWSIM_OPERATION_TIMEOUTfor complex simulations - Increase
DWSIM_MAX_SESSIONSif running concurrent simulations - Enable worker process pooling in config
Simulation Troubleshooting
- If
runreturnsINVALID_FLOWSHEET_STATE, ensure at least one unit operation exists and streams are connected. - If
get_resultsreturnsNO_RESULTS_AVAILABLE, run a simulation first and verify it converged. - If
SIMULATION_TIMEOUToccurs, increasetimeout_secondsfor theruntool or adjustDWSIM_OPERATION_TIMEOUT.
License
GPLv3 - See LICENSE file for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ol_dwsim_mcp_server-0.1.5-py3-none-any.whl.
File metadata
- Download URL: ol_dwsim_mcp_server-0.1.5-py3-none-any.whl
- Upload date:
- Size: 16.0 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
226ebee49d2741f595a91f5b23e7c1e1ccadb1b571fc33b54ef52a2dc8187322
|
|
| MD5 |
ee4de432056394d91475e2faf35c3f6c
|
|
| BLAKE2b-256 |
697482757c0ea5d0cf4c28a94ce0cc72a038071801c6b432039ec1fb421f61e8
|
Provenance
The following attestation bundles were made for ol_dwsim_mcp_server-0.1.5-py3-none-any.whl:
Publisher:
release.yml on OntoLedgy/ol_dwsim_interop_services
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ol_dwsim_mcp_server-0.1.5-py3-none-any.whl -
Subject digest:
226ebee49d2741f595a91f5b23e7c1e1ccadb1b571fc33b54ef52a2dc8187322 - Sigstore transparency entry: 1449740487
- Sigstore integration time:
-
Permalink:
OntoLedgy/ol_dwsim_interop_services@404dc8d3b400a48de04eb59c42db667f8a78faa4 -
Branch / Tag:
refs/tags/v0.1.5 - Owner: https://github.com/OntoLedgy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@404dc8d3b400a48de04eb59c42db667f8a78faa4 -
Trigger Event:
push
-
Statement type: