# yusong652/pfc-mcp [Health: Active]

**Category:** 🔬 Research  
**Repository:** https://github.com/yusong652/pfc-mcp  
**GitHub Stars:** 223  
**Views:** 3  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/yusong652-pfc-mcp

## Description
MCP server for ITASCA PFC discrete element simulation — browse documentation, execute scripts, capture plots, and manage long-running tasks via a WebSocket bridge to the PFC GUI.

## Tools
Capabilities this server exposes over MCP:

- **itasca_browse_commands** — Browse Itasca command documentation by path (like glob + cat).

Navigation levels:
- No command: All command categories overview
- Category only (e.g., "ball"): List commands in category
- Full command (e.g., "ball create"): Full documentation

When to use:
- You know the command category or exact command
- You want to explore available commands

Related tools:
- itasca_query_command: Search commands by keywords (when path unknown)
- itasca_browse_reference: Browse reference docs (e.g., "contact-models linear")
- **itasca_browse_python_api** — Browse Itasca Python SDK documentation by path (like glob + cat).
- **itasca_browse_reference** — Browse ITASCA reference documentation (syntax elements, model properties).

Works across engines via the required ``software`` selector (pfc/flac/3dec).
References are language elements used within commands, not standalone commands.

Navigation levels:
- No topic: All reference categories for the engine
- Category (e.g., "constitutive-models"): List items in category
- Full path (e.g., "constitutive-models mohr-coulomb"): Full documentation
- Sub-item path (e.g., "plot-items zone contour"): Sub-item details

When to use:
- Need material/contact/joint model property names (kn, ks, fric, cohesion, friction, ...)
- Need range filtering syntax (position, cylinder, group, id)
- Need plot item configuration (contour, label, color-by, cut, transparency, legend)
- Setting up model-assignment commands (e.g. "... cmodel assign ... property ...")
- Using range filters in any command
- Configuring "plot item create" commands

Related tools:
- itasca_browse_commands: Command syntax (e.g., "zone create")
- itasca_query_command: Search commands by keywords
- **itasca_query_command** — Search Itasca command documentation by keywords (like grep).

Returns matching command paths. Use itasca_browse_commands for full documentation.

When to use:
- You have keywords but don't know exact command path
- Example: "ball create", "contact property", "model solve"

Related tools:
- itasca_browse_commands: Get full documentation for a known command path
- itasca_browse_reference: Browse reference docs (e.g., "contact-models linear")
- itasca_query_python_api: Search Python SDK by keywords
- **itasca_query_python_api** — Search Itasca Python SDK documentation by keywords (like grep).

Returns matching API paths with signatures. Use itasca_browse_python_api for full documentation.

When to use:
- You have keywords but don't know exact API path
- Example: "ball velocity", "create", "contact force"

Related tools:
- itasca_browse_python_api: Get full documentation for a known API path
- itasca_query_command: Search Itasca commands by keywords
- **itasca_execute_task** — Submit a Python script file for asynchronous execution in the Itasca engine.

Returns a task_id immediately; the script runs in the background.
Companion tools manage the lifecycle:
- itasca_check_task_status: poll output, progress, and final status
- itasca_interrupt_task: cancel a running task
- itasca_list_tasks: browse task history
For synchronous, inline execution, use itasca_execute_code instead.

While the task is cycling, itasca_execute_code shares the same
__main__ namespace in the engine's main thread, so you can
inspect or modify simulation state live — probe progress, tune
parameters mid-run, swap callbacks, or trigger early termination
via a sentinel variable. Submit with reasonable starting values
and refine as the task runs.

Console output from itasca.command() inside the script (table
dumps, list output, command summaries) is captured into the task
log alongside Python prints, visible through
itasca_check_task_status.

Script-writing rules:
- Multi-line itasca.command("""...""") batches are normalized
  to one engine call per command, keeping the task interruptible
  mid-batch. Normalization recognizes itasca.command through its
  import name; call it through that name directly — rebinding
  via intermediate variables (`_it = itasca`) bypasses it and
  logs a bridge warning.
- Pass each FISH definition block (`fish define` /
  `fish operator` / legacy bare `define`, through its
  terminating standalone `end`) whole, in ONE itasca.command()
  string; feeding one line-by-line leaves the engine blocked in
  interactive FISH mode until completed manually in the GUI
  console. Per-line loops are fine for ordinary commands.
- `program call '<file>'` (.p3dat / .p2dat / .dat / ...) is
  supported: the bridge runs the file inline, one command per
  engine call, so the bridge stays reachable, the task stays
  interruptible, and the file's output lands in the task log
  command by command.
- **itasca_check_task_status** — Check status and paginated output for a submitted Itasca task.

Output combines Python prints and Itasca console output from
itasca.command() calls (table dumps, list output, command
summaries) interleaved in execution order. Use skip_newest /
limit to paginate, or filter to keep only matching lines.
- **itasca_list_tasks** — List tracked Itasca tasks with pagination.
- **itasca_interrupt_task** — Request graceful interruption of a running Itasca task.
- **itasca_execute_code** — Execute Python code synchronously in the running Itasca engine process.

Returns stdout and an optional result variable immediately.
Code runs in the engine's main thread, sharing the same __main__
namespace as any running task — side effects persist and are
immediately visible to the task on its next cycle.

The tool stays responsive while a task submitted via
itasca_execute_task is cycling (calls interleave at cycle
gaps), so use it as a live REPL — nothing has to be
pre-scripted into the task up front. Typical uses:
- Query model state and read Itasca command output:
  itasca.command('ball list') etc. — table dumps, list output,
  and command summaries are captured and interleaved with
  Python prints in execution order
- Live inspection and tuning during a running task: check
  forces or contact statistics, modify parameters, swap
  callbacks, set sentinel variables the task reads each cycle
- Create and export plots: itasca.command('plot ...')

Environment: the engine's embedded Python interpreter
(Itasca 9+ → Python 3.10, pre-9 → Python 3.6 or older; the
product+version is encoded in sys.executable, e.g. PFC900).
When unsure, check sys.version_info before relying on newer
syntax.

Code-writing rules (shared with itasca_execute_task):
- Multi-line itasca.command("""...""") batches are normalized
  to one engine call per command, keeping the bridge reachable
  mid-batch. Normalization recognizes itasca.command through
  its import name; call it through that name directly —
  rebinding via intermediate variables (`_it = itasca`)
  bypasses it and the output carries a bridge warning.
- Pass each FISH definition block (`fish define` /
  `fish operator` / legacy bare `define`, through its
  terminating standalone `end`) whole, in ONE itasca.command()
  string; feeding one line-by-line leaves the engine blocked in
  interactive FISH mode until completed manually in the GUI
  console. Per-line loops are fine for ordinary commands.
- `program call '<file>'` (.p3dat / .p2dat / .dat / ...) is
  supported: the bridge runs the file inline, one command per
  engine call, so the bridge stays reachable, the run stays
  interruptible, and the file's output arrives command by
  command.

Synchronous semantics: the request blocks until the code
finishes or hits the timeout (default 10s, max 600s), and
output is returned in full. The call is not tracked by
itasca_list_tasks and cannot be interrupted mid-execution.
For cancellable, pollable, or background work, submit via
itasca_execute_task instead.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `uvx` (confidence: high):

```json
"mcpServers": {
  "pfc-mcp": {
    "command": "uvx",
    "args": ["itasca-mcp"]
  }
}
```

## Documentation

## What yusong652/pfc-mcp does

yusong652/pfc-mcp gives MCP-compatible AI agents access to ITASCA simulation workflows. It supports PFC, FLAC, 3DEC, MPoint, and MassFlow, with documentation selected by engine and, where applicable, version. Agents can inspect command syntax, search for commands and Python API paths, browse reference topics, execute Python code, submit scripts, monitor background work, interrupt tasks, and review task history.

The documentation tools are useful for discovering exact command paths and engine-specific details before changing a model. Reference material covers items such as constitutive-model properties, range filters, plot configuration, and other language elements used inside commands.

## How it works

The MCP process communicates with the ITASCA application through a bridge started from the engine's embedded Python environment. Documentation browsing and search do not require that bridge. Execution tools use the running engine process and can interact with its main Python namespace.

`itasca_execute_code` runs code synchronously and returns output after completion or timeout. It shares state with a background task, so an agent can inspect or modify a simulation while that task is cycling. `itasca_execute_task` submits a Python script and returns a task identifier immediately. Status polling exposes progress and output, while interruption requests a graceful stop.

Output from Python and `itasca.command()` is collected in execution order. Multi-command batches are normalized so the bridge remains reachable between commands. FISH definitions must be sent as complete blocks, and `program call` files are processed command by command.

## Setup and configuration

Install an ITASCA engine and `uv`, then register the server with an MCP client using `uvx itasca-mcp`. The repository documents command-line registration for Claude Code, Codex CLI, and Gemini CLI, as well as an equivalent JSON MCP configuration.

Download `addon.py` and run it from the ITASCA GUI's IPython console, either by pasting its contents or executing the file. On later engine sessions, start the bridge with:

```python
import itasca_mcp_bridge
itasca_mcp_bridge.start()
```

The engine's embedded Python version depends on the installed ITASCA release. ITASCA 9 and later use Python 3.10; older releases may use Python 3.6 or earlier, so scripts should match the engine interpreter.

## Tools and capabilities

- Browse command documentation by category or full command path.
- Search command and Python API documentation by keyword.
- Browse engine reference topics, including model properties, range syntax, and plot items.
- Run synchronous Python code with a configurable timeout.
- Submit scripts as background tasks and inspect paginated output.
- Interrupt running tasks and list tracked task history.
- Query or modify live simulation state while an asynchronous task runs.
- Create and export plots through ITASCA commands.

## Limitations and notes

Synchronous execution blocks until completion or timeout and is not tracked as a task, so it cannot be interrupted through the task tools. Background execution is the appropriate choice for cancellable or pollable work. The bridge must be active for execution features, and the selected `software` value determines which engine's documentation and runtime are used. Commands entered in FISH definition blocks should not be sent one line at a time because that can leave the engine in interactive FISH mode.

_Full upstream README: https://allmcps.com/mcp/yusong652-pfc-mcp/readme_

