MCP server for controlling ParaView via AI assistants
Project description
ParaView MCP Server
Control ParaView with AI assistants through the Model Context Protocol.
paraview-mcp-python provides an MCP server plus a ParaView-side bridge so
AI assistants such as Codex CLI and Claude Desktop can inspect a ParaView
session, open datasets, apply filters, color data, run ParaView Python, and
export screenshots.
The command installed for MCP clients is still:
paraview-mcp-server
What Parts Are There?
There are three moving pieces:
| Part | Runs where | Purpose |
|---|---|---|
| MCP client | Codex CLI, Claude Desktop, or another MCP host | Starts the MCP server and calls tools. |
| MCP server | Normal Python environment | Speaks MCP over stdio and forwards tool calls to ParaView over TCP. |
| ParaView GUI bridge | Already-open ParaView GUI process | Receives TCP JSON commands and executes paraview.simple operations in that live GUI session. |
The ParaView bridge is the ParaView-side component. It plays the same role as
the Blender add-on in blender-mcp-server: it must run inside the application
you want to control. For live GUI control, start the bridge from ParaView's
Python Shell using scripts/start_paraview_gui_bridge.py.
┌──────────────────────────────┐ stdio ┌────────────────────────┐
│ MCP Client │ ◄──────────────► │ MCP Server │
│ Codex / Claude / other host │ │ paraview-mcp-server │
└──────────────────────────────┘ └──────────┬─────────────┘
│ JSON/TCP
│ 127.0.0.1:9876
┌──────────▼─────────────┐
│ ParaView Bridge │
│ live GUI process │
└──────────┬─────────────┘
│
┌──────────▼─────────────┐
│ paraview.simple │
│ ParaView runtime │
└────────────────────────┘
Why a ParaView-side bridge? ParaView's useful automation API is
paraview.simple, and it must execute inside a ParaView Python runtime. The
MCP server itself is only a protocol adapter; it cannot modify a ParaView GUI
unless the bridge is running inside that GUI process.
For live GUI modification, use:
Codex/Claude -> MCP server -> bridge inside open ParaView GUI -> live GUI session
For headless automation, use:
Codex/Claude -> MCP server -> bridge inside pvpython -> headless ParaView runtime
See docs/architecture.md for a full diagram, protocol reference,
and tool namespace table.
Install
Option A: Install the MCP server from PyPI
Use this when you only need the MCP server executable in your normal Python environment:
pip install paraview-mcp-python
This installs:
paraview-mcp-server
Option B: Clone this repository for the ParaView bridge
The bridge code must be available to ParaView's Python runtime. For live GUI control and local development, clone the repository:
git clone https://github.com/djeada/paraview-mcp-server.git
cd paraview-mcp-server
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .
This creates:
.venv/bin/paraview-mcp-server
Start Everything
Start the pieces in this order.
1. Start the ParaView GUI Bridge
Open ParaView, then run the GUI bridge script from the Python Shell:
- In ParaView, open Tools -> Python Shell.
- Click Run Script.
- Select:
/absolute/path/to/paraview-mcp-server/scripts/start_paraview_gui_bridge.py
Expected output:
ParaView MCP GUI bridge started on 127.0.0.1:9876
Do not start the live GUI bridge with paraview --script scripts/start_paraview_gui_bridge.py. ParaView runs startup scripts before the
embedded GUI Python environment is fully ready for pipeline edits. Use Tools
-> Python Shell -> Run Script for the live GUI bridge.
If paraview-mcp-python is installed into ParaView's Python environment, you
can also start the live GUI bridge directly from the Python Shell:
from bridge.gui_bridge import start_gui_bridge, stop_gui_bridge
start_gui_bridge()
Leave ParaView open. MCP commands now modify this live GUI session.
To stop the bridge from the ParaView Python Shell:
stop_gui_bridge()
2. Optional: Start a Headless pvpython Bridge
Use this only when you do not need to modify an already-open ParaView GUI:
cd /path/to/paraview-mcp-server
pvpython scripts/start_paraview_bridge.py
Expected output:
ParaView bridge ready on 127.0.0.1:9876
Keep that terminal running. This controls the pvpython session, not a GUI
window opened separately.
3. Verify the Bridge Directly
Before involving an MCP client, send one raw bridge command:
python scripts/paraview_bridge_request.py scene.get_info
Expected response shape:
{
"success": true,
"result": {
"source_count": 0,
"active_view_type": "RenderView"
}
}
If this fails, fix the bridge before configuring Codex or Claude.
4. Register the MCP Server with Codex CLI
If you installed from PyPI:
codex mcp add paraview -- paraview-mcp-server
codex mcp list
If you are using the local repository:
codex mcp add paraview -- /absolute/path/to/paraview-mcp-server/.venv/bin/paraview-mcp-server
codex mcp list
Codex starts the MCP server automatically when needed. The ParaView bridge must already be running separately.
5. Register with Claude Desktop
Claude Desktop — add to claude_desktop_config.json:
{
"mcpServers": {
"paraview": {
"command": "/absolute/path/to/.venv/bin/paraview-mcp-server"
}
}
}
For a PyPI install, use the absolute path returned by:
which paraview-mcp-server
Restart Claude Desktop after editing the config.
6. Verify Through Your MCP Client
With the bridge still running, ask your MCP client:
List all sources in the current ParaView session.
The client should call paraview_scene_list_sources and return the current
ParaView pipeline sources from the live GUI session if you started
start_paraview_gui_bridge.py.
What Can It Control?
There are two levels of control:
- Fixed MCP tools for common workflows: scene inspection, loading data, filters, display/coloring, camera, screenshots, data export, and animation export.
- Python execution through
paraview_python_exec, which can run trusted local Python inside the ParaView bridge session. Use this for anything not covered by a fixed tool, including arbitraryparaview.simplescripts.
So the fixed tool list is intentionally finite, but the Python execution tool is the general escape hatch for the broader ParaView API.
Example prompts
Once both processes are running and your MCP client is configured:
- "List all sources in the current ParaView session."
- "Open
/data/disk_out_ref.ex2." - "Create a slice through X = 0 of the disk dataset."
- "Color the dataset by Pressure."
- "Save a screenshot to
/tmp/view.png." - "Apply a contour filter on Pressure with isovalues 0.5 and 1.0."
- "Set the camera to position [10, 5, 5] looking at the origin."
- "Set the background to a gradient from white to dark blue."
- "Export an animation to
/tmp/anim.avi."
Tool reference (31 tools)
Scene / session
| Tool | Description |
|---|---|
paraview_scene_get_info |
Session info: source count, active view type |
paraview_scene_list_sources |
List all pipeline sources |
paraview_scene_list_views |
List open render views |
paraview_source_get_properties |
Properties of a named source |
Data loading
| Tool | Description |
|---|---|
paraview_source_open_file |
Open a dataset (VTK, VTU, ExodusII, CSV, …) |
paraview_source_delete |
Remove a source from the pipeline |
paraview_source_rename |
Rename a source |
Filters — basic
| Tool | Description |
|---|---|
paraview_filter_slice |
Slice filter with origin + normal |
paraview_filter_clip |
Clip filter with origin + normal |
paraview_filter_contour |
Contour / isosurface by scalar array and values |
paraview_filter_threshold |
Threshold filter by scalar range |
Filters — advanced
| Tool | Description |
|---|---|
paraview_filter_calculator |
Calculator filter with expression |
paraview_filter_stream_tracer |
Stream Tracer for vector field streamlines |
paraview_filter_glyph |
Glyph filter for vector visualization |
Display / coloring
| Tool | Description |
|---|---|
paraview_display_show |
Make a source visible |
paraview_display_hide |
Hide a source |
paraview_display_color_by |
Color by a data array |
paraview_display_set_representation |
Surface / Wireframe / Points / Volume |
paraview_display_set_opacity |
Set opacity (0.0 – 1.0) |
paraview_display_rescale_transfer_function |
Rescale color map to data range |
Camera / view
| Tool | Description |
|---|---|
paraview_view_reset_camera |
Fit all visible sources in the view |
paraview_view_set_camera |
Set camera position, focal point, view-up |
paraview_view_set_background |
Set solid or gradient background color |
Export
| Tool | Description |
|---|---|
paraview_export_screenshot |
Save a PNG or JPEG screenshot |
paraview_export_data |
Export source data to VTK/CSV/… |
paraview_export_animation |
Export animation to video/frames |
Python execution
| Tool | Description |
|---|---|
paraview_python_exec |
Run Python in bridge or headless pvpython |
paraview_python_exec_async |
Start a long-running Python job (headless) |
Job management
| Tool | Description |
|---|---|
paraview_job_status |
Get status of an async job |
paraview_job_cancel |
Cancel a running async job |
paraview_job_list |
List all known async jobs |
Python execution
paraview_python_exec is the escape hatch for workflows that need more than the fixed
tool set. The script runs in the bridge process where paraview.simple is already imported.
Parameters:
| Parameter | Type | Description |
|---|---|---|
code |
str |
Inline Python source (mutually exclusive with script_path) |
script_path |
str |
Path to a .py file (mutually exclusive with code) |
args |
dict |
Arguments exposed as args inside the script |
timeout_seconds |
int |
Cooperative timeout (default: 30s) |
transport |
str |
"bridge" (default) or "headless" (separate pvpython process) |
Execution namespace:
| Variable | Type | Description |
|---|---|---|
pvs |
module | paraview.simple |
args |
dict | Arguments from the args parameter |
__result__ |
Any | Set this to return a JSON-serialisable value |
Example:
# Open a file and create a slice
src = pvs.OpenDataFile(args["filepath"])
view = pvs.GetActiveViewOrCreate("RenderView")
pvs.Show(src, view)
filt = pvs.Slice(Input=src)
filt.SliceType.Origin = [0, 0, 0]
filt.SliceType.Normal = [1, 0, 0]
pvs.Show(filt, view)
pvs.ResetCamera(view)
__result__ = {"done": True}
See docs/python-execute-design.md for the full design,
schema reference, and more examples.
Async job execution
For long-running pipelines, use paraview_python_exec_async:
- Start a job → returns
job_idimmediately - Poll with
paraview_job_status→ checkstatusfield - Cancel with
paraview_job_cancelif needed
Async jobs run in a separate headless pvpython process via HeadlessPvpythonExecutor.
Python execution trust model
- Trusted local execution —
paraview_python_execcan run arbitrary Python available to the active ParaView Python process, including imports and fullparaview.simpleworkflows. - Output bounding — stdout/stderr capped at 50 KB.
- Cooperative timeout — default 30 seconds per script execution.
- Script path validation — optionally restrict execution to approved root directories.
- The bridge runs inside ParaView's Python runtime with the same trust level as that local session.
- This is a local desktop automation tool — not a public API sandbox.
Development
Install dev dependencies
pip install -e ".[dev]"
Run tests
pytest tests/
Tests do not require ParaView to be installed. The command handler tests patch
_import_pv with a MagicMock that mimics the paraview.simple API.
Send a raw bridge command (for debugging)
python scripts/paraview_bridge_request.py scene.get_info
python scripts/paraview_bridge_request.py source.open_file --params '{"filepath":"/data/disk.vtu"}'
python scripts/paraview_bridge_request.py export.screenshot --params '{"filepath":"/tmp/shot.png"}'
Project structure
paraview-mcp-server/
├── pyproject.toml
├── src/
│ └── paraview_mcp_server/
│ ├── __init__.py # Re-exports main()
│ ├── server.py # FastMCP stdio server (31 tools)
│ └── headless.py # Headless pvpython executor + job manager
├── bridge/
│ ├── __init__.py
│ ├── server.py # TCP socket bridge server
│ ├── gui_bridge.py # Non-blocking live GUI bridge lifecycle
│ ├── command_handler.py # Command registry + paraview.simple handlers (27 commands)
│ └── execution.py # trusted local python.execute helper
├── scripts/
│ ├── start_paraview_gui_bridge.py
│ ├── start_paraview_bridge.py
│ ├── paraview_bridge_request.py
│ └── library/ # Reusable pvpython snippets
│ ├── open_dataset.py
│ ├── create_slice.py
│ ├── create_contour.py
│ ├── color_by.py
│ ├── reset_camera.py
│ └── save_screenshot.py
├── docs/
│ ├── architecture.md
│ └── python-execute-design.md
└── tests/
├── test_server.py # 31 tools, connection, headless, async jobs
├── test_protocol.py # Wire encoding, fake bridge integration
└── test_command_handler.py # All 27 handlers + execution controls
License
MIT — see LICENSE.
Project details
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 paraview_mcp_python-0.1.3.tar.gz.
File metadata
- Download URL: paraview_mcp_python-0.1.3.tar.gz
- Upload date:
- Size: 43.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8a1e9bca0ba5a560d158a3871d391daf781c1feaaab7b06e677d66334e4e469
|
|
| MD5 |
7f3350fcfe1f8a8ba0cc0fd37df7a8f9
|
|
| BLAKE2b-256 |
a4c01ea49679ebfe91e1778a76dd1b9562b37193f549a3f15794b071da17d478
|
Provenance
The following attestation bundles were made for paraview_mcp_python-0.1.3.tar.gz:
Publisher:
publish-pypi.yml on djeada/paraview-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
paraview_mcp_python-0.1.3.tar.gz -
Subject digest:
f8a1e9bca0ba5a560d158a3871d391daf781c1feaaab7b06e677d66334e4e469 - Sigstore transparency entry: 1981067095
- Sigstore integration time:
-
Permalink:
djeada/paraview-mcp-server@eb634324a420c630ab267ef8a4d238c53100d719 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/djeada
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@eb634324a420c630ab267ef8a4d238c53100d719 -
Trigger Event:
push
-
Statement type:
File details
Details for the file paraview_mcp_python-0.1.3-py3-none-any.whl.
File metadata
- Download URL: paraview_mcp_python-0.1.3-py3-none-any.whl
- Upload date:
- Size: 29.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7215e78f4b17cf083b57aaa65473695d2d24ee9af81ddf1da9b887134356b99e
|
|
| MD5 |
22862ac958fd8d5611825bdc6720c288
|
|
| BLAKE2b-256 |
dd33f323d85faa7eca71e9f19af929dd4de9557a9caeea9aaa1bb57fd87f7aa4
|
Provenance
The following attestation bundles were made for paraview_mcp_python-0.1.3-py3-none-any.whl:
Publisher:
publish-pypi.yml on djeada/paraview-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
paraview_mcp_python-0.1.3-py3-none-any.whl -
Subject digest:
7215e78f4b17cf083b57aaa65473695d2d24ee9af81ddf1da9b887134356b99e - Sigstore transparency entry: 1981067211
- Sigstore integration time:
-
Permalink:
djeada/paraview-mcp-server@eb634324a420c630ab267ef8a4d238c53100d719 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/djeada
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@eb634324a420c630ab267ef8a4d238c53100d719 -
Trigger Event:
push
-
Statement type: