MCP server that exposes PSR/SDDP power-system tools to Claude Code
Project description
psr-study-assistant-mcp
An MCP server that exposes 55 PSR/SDDP power-system tools to Claude Code through a single unified server. Includes a skill that gives Claude a complete workflow guide — no tool discovery step required.
Prerequisites
| Requirement | Notes |
|---|---|
| Python 3.10+ | Must be on your PATH |
| PSR Factory ≥ 5.0.0b111 | Licence must be installed and active on this machine |
| Claude Code | Desktop app or CLI (latest version) |
Installation
1 — Install the package
pip install psr-study-assistant-mcp
This installs the psr-study-assistant-mcp command on your PATH.
2 — Register the MCP server
Add the following entry to ~/.claude/settings.json under "mcpServers":
"mcpServers": {
"psr-study-assistant-mcp": {
"command": "psr-study-assistant-mcp"
}
}
Claude Desktop uses
%APPDATA%\Claude\claude_desktop_config.jsoninstead of~/.claude/settings.json. The JSON structure is identical — add the block under"mcpServers".
3 - Skill
You can add the skill direclty on claude.
Email Notifications (optional)
The server can send email notifications (e.g. when a long simulation finishes). This feature is entirely optional — the server works normally without it.
To enable, add your SMTP credentials to the "env" block of the MCP server entry in settings.json:
"mcpServers": {
"psr-study-assistant-mcp": {
"command": "psr-study-assistant-mcp",
"env": {
"SMTP_USERNAME": "you@gmail.com",
"SMTP_PASSWORD": "xxxx xxxx xxxx xxxx"
}
}
}
The server reads these variables at startup and pre-configures SMTP automatically. You can verify it worked by calling the get_smtp_status tool — it will show your address without requiring a configure_smtp call.
All available variables (only SMTP_USERNAME and SMTP_PASSWORD are required to activate email):
| Variable | Default | Description |
|---|---|---|
SMTP_USERNAME |
— | Sender email address |
SMTP_PASSWORD |
— | App password or SMTP password |
SMTP_HOST |
smtp.gmail.com |
SMTP server hostname |
SMTP_PORT |
587 |
SMTP port |
SMTP_USE_TLS |
true |
Set to "false" to disable STARTTLS |
Gmail — generating an App Password
Gmail requires an App Password (a 16-character one-time code) instead of your regular account password. App Passwords are only available when 2-Step Verification is active.
Step 1 — Enable 2-Step Verification (skip if already on)
- Go to myaccount.google.com/security.
- Under "How you sign in to Google", click 2-Step Verification and follow the steps.
Step 2 — Generate the App Password
- Go to myaccount.google.com/apppasswords.
- In the "App name" field type
PSR Study Assistantand click Create. - Google shows a 16-character code (format:
xxxx xxxx xxxx xxxx).
Copy it immediately — it will not be shown again.
Step 3 — Add to settings.json
Paste the values into the "env" block shown above. Spaces in the password are optional — Google shows them for readability but they are not part of the credential.
Revoking the App Password
Go to myaccount.google.com/apppasswords, find PSR Study Assistant, and click the trash icon. Then remove the "env" block from settings.json.
Using a different email provider
Override the defaults in "env":
"env": {
"SMTP_HOST": "smtp.office365.com",
"SMTP_PORT": "587",
"SMTP_USERNAME": "you@company.com",
"SMTP_PASSWORD": "your-password",
"SMTP_USE_TLS": "true"
}
Troubleshooting
| Error | Likely cause | Fix |
|---|---|---|
SMTPAuthenticationError |
Wrong password or 2FA not enabled | Re-generate the App Password |
SMTPConnectError |
Firewall blocking port 587 | Set SMTP_USE_TLS to "false" and SMTP_PORT to "465" |
SMTP not configured |
Variables missing or misspelled | Check get_smtp_status — confirm key names in "env" |
Using the Plugin
Starting a session
Invoke the skill to load the full workflow guide:
/psr-gateway-complete C:/studies/my_case
You can also describe what you want to do:
/psr-gateway-complete C:/studies/my_case scale thermal marginal costs by 10%
Without the skill
All MCP tools are directly callable from any Claude Code session — the skill just provides additional workflow context.
Setup calls
Every session requires one setup call before domain tools:
| Goal | Setup tool |
|---|---|
| Read / query input data | setup_input_study(path) |
| Edit a case (safe copy) | setup_edit_study(original, target) |
| Edit in-place (needs user approval) | setup_edit_study_inplace(path) |
| Manage output files | setup_output_case(path) |
Example — query thermal plant capacity
setup_input_study("C:/studies/case")
get_objects_by_type("ThermalPlant")
get_objects_table("ThermalPlant", ["InstalledCapacity", "MarginalCost"])
Example — scale all thermal costs by 10%
setup_edit_study("C:/studies/case", "C:/studies/case_+10pct")
get_objects_table("ThermalPlant", ["MarginalCost"])
scale_dataframe("ThermalPlant Gas1 [3]", "MarginalCost", 10)
# ... repeat for each plant key
save_study("C:/studies/case_+10pct")
Tool Reference
All 55 tools across 10 categories:
| Category | Tools |
|---|---|
| Setup | setup_input_study, setup_edit_study, setup_edit_study_inplace, setup_output_case, save_study |
| Run | get_case_version, list_available_versions, run_psr_model, get_run_status, read_run_log, kill_run |
| Discovery | discover_objects, discover_object_properties, get_all_objects, get_objects_by_type, get_neighbors |
| Query | get_static_properties, get_dynamic_property, get_objects_table |
| Filter & Aggregate | query_by_property_condition, find_by_reference, count_by_reference, sum_property_by_reference |
| Input DataFrame | input_get_dataframe, input_aggregate_dataframe, input_filter_dataframe_by_index, input_filter_dataframe_by_value |
| Binary DataFrame | input_get_binary_dataframe, input_aggregate_binary_dataframe, input_filter_binary_dataframe_by_index, input_filter_binary_dataframe_by_value |
| Edit | modify_static_element, rename_element, modify_element_code, modify_element_key, get_dataframe_schema, set_dataframe, scale_dataframe, create_element, modify_study_setting |
| Output Management | list_enabled_outputs, list_enabled_outputs_paths, get_output_num, convert_output, change_output_availability |
| Output DataFrame | df_info, df_aggregate, df_select_columns, df_combine_columns, df_filter_by_value, df_filter_between, df_filter_by_index, df_merge, df_concat |
For full descriptions and usage examples see TOOLS_GUIDE.md and the skill at skills/psr-gateway-complete/SKILL.md.
Repository Structure
PSR-Plugin/
├── pyproject.toml # Package: psr-study-assistant-mcp
├── skills/
│ └── psr-gateway-complete/
│ └── SKILL.md # Analyst workflow guide (55 tools)
└── src/psr_mcp/
├── common.py # Study setup + artifact discovery
├── input_discover.py # Query and filter tools
├── edit_case.py # Edit tools
├── outputs.py # Output management + DataFrame tools
├── execution.py # Run/execution tools
├── notification.py # Email notification tools
├── state.py # Shared study state
└── gateway/
└── server.py # Unified gateway — all tools registered here
How the Gateway Works
All tools are registered at startup and immediately callable — no discovery or activation step is needed.
find_tools(query) is an optional helper that ranks the catalog by relevance to a natural-language query. Use it only when you don't know a tool's name.
Adding a New Tool
1 — Write the function in the appropriate module
# src/psr_mcp/input_discover.py
def my_new_tool(obj_key: str, value: float) -> str:
"""One-line summary."""
...
2 — Register it in the gateway catalog
# src/psr_mcp/gateway/server.py — CATALOG dict
"my_new_tool": {
"fn": _input.my_new_tool,
"stub": "Short label (5–10 words)",
"description": "One-line description shown in find_tools results.",
"tags": ["query", "input"],
},
Available tags: setup, input, edit, output, discovery, query, filter, aggregate, dataframe, binary, run.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
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 psr_study_assistant_mcp-0.3.0.tar.gz.
File metadata
- Download URL: psr_study_assistant_mcp-0.3.0.tar.gz
- Upload date:
- Size: 52.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b67a292d598f9a6cee2556406eb8dc8131eb360439363ee5151a3e1a97b8861
|
|
| MD5 |
9e3828916eb4ead9fba8042afe9ecbe8
|
|
| BLAKE2b-256 |
a6bed537f45f1eccab796e8ecd8079d520c69799835e904fac223ff7649454f4
|
File details
Details for the file psr_study_assistant_mcp-0.3.0-py3-none-any.whl.
File metadata
- Download URL: psr_study_assistant_mcp-0.3.0-py3-none-any.whl
- Upload date:
- Size: 48.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f18abfc72c0f30592ad11bd62af71b44c8de554670a2c46035d7f6c2b6430b8
|
|
| MD5 |
a1a6f3c19dbac47d9a4728ea8119eef3
|
|
| BLAKE2b-256 |
db8479e88957db9d95b0cffdb9fa78b10b9c49cc66d089591be7eaabd7bcf507
|