This guide is for contributors who want to run itasca-mcp from a local checkout, test changes before publishing to PyPI, or install the bridge from local source into a PFC embedded Python environment.
This repository contains two separate runtimes:
itasca-mcpThe MCP server package undersrc/itasca_mcp, running on standard Python>=3.10itasca-mcp-bridgeThe bridge package underitasca-mcp-bridge, running inside PFC embedded Python. This directory is a git submodule: its own repository (yusong652/itasca-mcp-bridge) with an independent release cycle.itasca-mcponly records which bridge commit to use, not the bridge's files.
Treat them as separate installation targets even though they appear in the same working tree.
Clone with the bridge submodule (it is required for Steps 3–7):
git clone --recurse-submodules https://github.com/yusong652/itasca-mcp.gitAlready cloned without --recurse-submodules? itasca-mcp-bridge/ is empty until you initialize it:
git submodule update --init --recursiveThen, from the repository root:
uv sync --group devRun tests:
uv run pytest testsitasca-mcp-bridge/ is a pinned pointer (a gitlink, mode 160000) to one commit of the separate yusong652/itasca-mcp-bridge repo — itasca-mcp tracks a single SHA there, not the bridge's source files. Practical consequences:
-
After pulling
itasca-mcp, re-sync the pin — the submodule working tree does not move on its own:git submodule update --init --recursive
-
To bump the bridge version, check out the desired commit inside
itasca-mcp-bridge/, then stage the moved pointer explicitly initasca-mcp:git add itasca-mcp-bridge && git commit -m "chore: bump itasca-mcp-bridge pin"
-
Push order matters: push the bridge repo first. The pinned commit must already exist on the public bridge repo, or other clones cannot fetch it.
-
git statusshowingmodified: itasca-mcp-bridge (untracked content)usually just means the submodule working tree has local/untracked files relative to the pin — not thatitasca-mcpis tracking bridge sources. Bump the pin only when you intend to.
If you want your MCP client to use local source instead of the published PyPI package, point it at the repository with uv run --directory:
{
"mcpServers": {
"itasca-mcp": {
"command": "uv",
"args": ["run", "--directory", "/path/to/itasca-mcp", "itasca-mcp", "--bridge-url", "ws://localhost:9001"]
}
}
}The --bridge-url argument is optional (defaults to ws://localhost:9001). To
connect to a bridge on a non-default port, pass --bridge-port instead of
spelling out the whole URL — e.g. "args": [..., "itasca-mcp", "--bridge-port", "9002"]
when the bridge was started with itasca_mcp_bridge.start(port=9002).
This is the simplest way to test MCP-side changes without building or publishing packages.
If you only need bridge-side changes to take effect in PFC, you do not need to install the bridge package at all. In the PFC IPython console:
%run C:/path/to/itasca-mcp/itasca-mcp-bridge/start_bridge.pyNotes:
- Use forward slashes in the path.
- Do not wrap the
%runpath in quotes. - Restart the bridge after source changes.
This is the fastest workflow for bridge development.
If you want to test the package installation path itself, install itasca-mcp-bridge from local source using the embedded Python interpreter from a terminal.
Pick the correct interpreter for your PFC version:
- PFC
6.0/7.0:C:/Program Files/Itasca/.../exe64/python36/python.exe - PFC
9.0:C:/Program Files/Itasca/.../exe64/python310/python.exe
Example commands:
& "C:\Program Files\Itasca\PFC700\exe64\python36\python.exe" -m pip install --user -e C:\path\to\itasca-mcp\itasca-mcp-bridge
& "C:\Program Files\Itasca\ItascaSoftware900\exe64\python310\python.exe" -m pip install --user -e C:\path\to\itasca-mcp\itasca-mcp-bridgeWhy use the embedded interpreter from a terminal:
- It installs into the exact Python environment used by PFC.
- It avoids relying on
subprocesscalls from inside the PFC console. - It is the most reliable workflow for editable installs.
The bridge package will pull a matching websockets version automatically:
- Python
3.6->websockets==9.1 - Python
3.10->websockets==16.0
For PyPI-based installation inside the PFC console, use the addon.py at the repository root — it handles both pip.main(...) (PFC 6/7) and pip._internal.cli.main.main(...) (PFC 9) automatically and starts the bridge.
For source installs, prefer the terminal-based embedded-interpreter workflow from Step 4 instead of trying to drive an editable install from inside the PFC GUI console.
Verify the bridge package inside embedded Python:
& "C:\Program Files\Itasca\ItascaSoftware900\exe64\python310\python.exe" -c "import itasca_mcp_bridge, websockets; print(itasca_mcp_bridge.__version__); print(websockets.__version__)"Then start the bridge in PFC and verify from your MCP client:
- Start the bridge in PFC with
itasca_mcp_bridge.start()or%run .../start_bridge.py - Restart the MCP client session
- Call
itasca_list_tasks
For most day-to-day work:
- Run
uv sync --group dev - Point your MCP client at the local checkout with
uv run --directory - Use
%run .../itasca-mcp-bridge/start_bridge.pyinside PFC - Run
uv run pytest tests - Restart the MCP client and bridge after changes when needed