Summary
powermcp run opendss crashes during startup on macOS arm64 before the MCP server can complete initialize / list_tools.
In the same environment, other PowerMCP stdio servers start normally:
powermcp run pandapower: MCP initialize + list tools succeeds
powermcp run powerio: MCP initialize + list tools succeeds
powermcp run opendss: process exits; MCP client receives Connection closed
The failure appears to come from eager OpenDSS engine construction at import time:
# OpenDSS/core/engine.py
from py_dss_interface import DSS
from py_dss_toolkit import dss_tools
dss = DSS()
dss_tools.update_dss(dss)
On my macOS arm64 machine, DSS() raises before the FastMCP server is created, so MCP clients only see a generic connection failure.
Environment
- PowerMCP commit tested:
cc99f348b394766b9958962638b2b31dee982755
- Installed package version:
powermcp 0.1.3
- Python:
3.12.11
- Platform: macOS arm64
py-dss-interface: 2.2.1
py-dss-toolkit: 0.7.0
Reproduction
python -m powermcp run opendss
or via an MCP stdio client:
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
params = StdioServerParameters(
command="python",
args=["-m", "powermcp", "run", "opendss"],
)
async with stdio_client(params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
await session.list_tools()
Actual behavior
The MCP client sees:
McpError: Connection closed
The server traceback ends with:
File ".../PowerMCP/OpenDSS/core/engine.py", line 6, in <module>
dss = DSS()
File ".../py_dss_interface/DSS.py", line 93, in __init__
os.chdir(self._dll_path)
AttributeError: 'DSS' object has no attribute '_dll_path'
Expected behavior
The OpenDSS MCP server should not crash before MCP initialization. Ideally it should either:
- initialize successfully, or
- expose the MCP tools and return an actionable structured error from OpenDSS tools when the backend cannot initialize, or
- fail during an explicit preflight/doctor step with a clear platform/dependency diagnostic before users add it to an MCP client config.
Proposed direction
Would you be open to a PR that makes OpenDSS backend initialization lazy?
The conservative fix would be:
- do not construct
py_dss_interface.DSS() at module import time;
- let
create_mcp() and initialize/list_tools complete even if the OpenDSS backend is unavailable on the current platform;
- initialize
DSS() on first OpenDSS tool call;
- if backend initialization fails, return the existing
_err(...) response shape with an actionable message instead of crashing the stdio process;
- add a small regression test that server creation/listing tools does not instantiate
DSS() or crash when DSS() is monkeypatched to raise.
This should be backwards-compatible for users where py_dss_interface already works: the default backend, tool names, and tool schemas would remain unchanged. The only behavior change would be that unsupported/misconfigured platforms get MCP-level diagnostics instead of a process-level Connection closed failure.
A separate follow-up could consider an optional opendssdirect.py / dss-python fallback for macOS, but I would keep that out of the first PR unless maintainers prefer that direction.
If this approach sounds acceptable, I can prepare a PR.
Summary
powermcp run opendsscrashes during startup on macOS arm64 before the MCP server can completeinitialize/list_tools.In the same environment, other PowerMCP stdio servers start normally:
powermcp run pandapower: MCP initialize + list tools succeedspowermcp run powerio: MCP initialize + list tools succeedspowermcp run opendss: process exits; MCP client receivesConnection closedThe failure appears to come from eager OpenDSS engine construction at import time:
On my macOS arm64 machine,
DSS()raises before the FastMCP server is created, so MCP clients only see a generic connection failure.Environment
cc99f348b394766b9958962638b2b31dee982755powermcp 0.1.33.12.11py-dss-interface:2.2.1py-dss-toolkit:0.7.0Reproduction
or via an MCP stdio client:
Actual behavior
The MCP client sees:
The server traceback ends with:
Expected behavior
The OpenDSS MCP server should not crash before MCP initialization. Ideally it should either:
Proposed direction
Would you be open to a PR that makes OpenDSS backend initialization lazy?
The conservative fix would be:
py_dss_interface.DSS()at module import time;create_mcp()andinitialize/list_toolscomplete even if the OpenDSS backend is unavailable on the current platform;DSS()on first OpenDSS tool call;_err(...)response shape with an actionable message instead of crashing the stdio process;DSS()or crash whenDSS()is monkeypatched to raise.This should be backwards-compatible for users where
py_dss_interfacealready works: the default backend, tool names, and tool schemas would remain unchanged. The only behavior change would be that unsupported/misconfigured platforms get MCP-level diagnostics instead of a process-levelConnection closedfailure.A separate follow-up could consider an optional
opendssdirect.py/dss-pythonfallback for macOS, but I would keep that out of the first PR unless maintainers prefer that direction.If this approach sounds acceptable, I can prepare a PR.