Spaces:
Runtime error
Runtime error
File size: 2,260 Bytes
7857730 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | """Claude Desktop stdio entry point for PCSWMM Engineering MCP.
This process exposes the same deterministic tool registry used by server.py,
without starting FastAPI or opening a TCP port. Standard output is reserved
exclusively for the MCP protocol.
"""
from __future__ import annotations
import logging
import os
from pathlib import Path
import sys
from mcp.server.fastmcp import FastMCP
import agent as agent_module
from pcswmm_tools import PCSWMM_TOOL_REGISTRY as TOOL_REGISTRY
SERVER_NAME = "pcswmm-engineering"
PROJECT_DIR = Path(__file__).resolve().parent
# Independent SWMM verification uses its own isolated worker interpreter.
worker_python = PROJECT_DIR / ".swmm-worker-venv" / "Scripts" / "python.exe"
if worker_python.is_file():
os.environ.setdefault("SWMM_WORKER_PYTHON", str(worker_python))
# Never write application logging to stdout: stdout carries JSON-RPC/MCP traffic.
logging.basicConfig(
level=os.environ.get("PCSWMM_MCP_LOG_LEVEL", "WARNING").upper(),
stream=sys.stderr,
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
)
mcp = FastMCP(
SERVER_NAME,
instructions=(
"Local-first deterministic stormwater engineering copilot. "
"Connect either an active PCSWMM SDK evidence package, an existing "
"deterministic Calgary evidence folder, or PySWMM/EPA SWMM evidence. "
"Validate the evidence, perform engineering QA/QC and Calgary screening, "
"configure report details, and generate engineer-review SWMR deliverables. "
"Do not invent hydraulic results or missing project criteria."
),
)
for tool_name, tool_function in TOOL_REGISTRY.items():
mcp.tool(name=tool_name)(tool_function)
@mcp.tool()
def agent_analyze(
question: str,
provider: str = "local",
model: str = "",
session_id: str = "",
api_key: str = "",
base_url: str = "",
) -> dict:
"""Run optional narrative orchestration over the deterministic MCP tools."""
return agent_module.run_agent(
question=question,
provider=provider,
model=model or None,
api_key=api_key or None,
base_url=base_url or None,
session_id=session_id or None,
)
if __name__ == "__main__":
mcp.run(transport="stdio")
|