paraview-mcp-python 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- paraview_mcp_python-0.1.0.dist-info/METADATA +339 -0
- paraview_mcp_python-0.1.0.dist-info/RECORD +8 -0
- paraview_mcp_python-0.1.0.dist-info/WHEEL +4 -0
- paraview_mcp_python-0.1.0.dist-info/entry_points.txt +2 -0
- paraview_mcp_python-0.1.0.dist-info/licenses/LICENSE +21 -0
- paraview_mcp_server/__init__.py +4 -0
- paraview_mcp_server/headless.py +350 -0
- paraview_mcp_server/server.py +671 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: paraview-mcp-python
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for controlling ParaView via AI assistants
|
|
5
|
+
Project-URL: Homepage, https://github.com/djeada/paraview-mcp-server
|
|
6
|
+
Project-URL: Repository, https://github.com/djeada/paraview-mcp-server
|
|
7
|
+
Project-URL: Issues, https://github.com/djeada/paraview-mcp-server/issues
|
|
8
|
+
Author-email: Adam Djellouli <adam@djellouli.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai,mcp,model-context-protocol,paraview,scientific-computing,visualization
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Requires-Dist: mcp>=1.0.0
|
|
25
|
+
Requires-Dist: pydantic>=2.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: mypy>=1.15; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-cov>=6.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.11; extra == 'dev'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# paraview-mcp-server
|
|
35
|
+
|
|
36
|
+
**Control ParaView with AI assistants through the Model Context Protocol.**
|
|
37
|
+
|
|
38
|
+
`paraview-mcp-server` is a two-process bridge that lets AI assistants such as Claude Desktop
|
|
39
|
+
and Codex CLI open datasets, apply filters, color data, and export screenshots in ParaView
|
|
40
|
+
using natural language.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## How it works
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
MCP Client (Claude Desktop, Codex CLI, …)
|
|
48
|
+
⇅ stdio
|
|
49
|
+
paraview-mcp-server ← thin MCP server, defines 31 tools
|
|
50
|
+
⇅ JSON / TCP localhost:9876
|
|
51
|
+
ParaView bridge (pvpython) ← dispatches commands with paraview.simple
|
|
52
|
+
⇅
|
|
53
|
+
paraview.simple / servermanager
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- The **MCP server** is a normal Python package. It speaks MCP over stdio and forwards
|
|
57
|
+
every tool call as a JSON request to the bridge over a local TCP socket.
|
|
58
|
+
- The **bridge** runs inside `pvpython`. It receives JSON commands, dispatches them through
|
|
59
|
+
a command registry, calls `paraview.simple`, and returns JSON results.
|
|
60
|
+
- Neither process depends on the other's code at import time.
|
|
61
|
+
- A **headless pvpython executor** lets the MCP server run scripts in a separate
|
|
62
|
+
`pvpython` process for long-running or async workflows (no bridge needed).
|
|
63
|
+
|
|
64
|
+
See [`docs/architecture.md`](docs/architecture.md) for a full diagram, protocol reference,
|
|
65
|
+
and tool namespace table.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Quick start
|
|
70
|
+
|
|
71
|
+
### 1. Install the MCP server
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install paraview-mcp-python
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
For local development from this repository:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
git clone https://github.com/djeada/paraview-mcp-server.git
|
|
81
|
+
cd paraview-mcp-server
|
|
82
|
+
python -m venv .venv
|
|
83
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
84
|
+
pip install -e .
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 2. Start the ParaView bridge
|
|
88
|
+
|
|
89
|
+
In a terminal that has `pvpython` on `PATH`:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pvpython scripts/start_paraview_bridge.py
|
|
93
|
+
# → ParaView bridge ready on 127.0.0.1:9876
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The bridge listens for JSON commands from the MCP server.
|
|
97
|
+
|
|
98
|
+
### 3. Register the MCP server with your AI client
|
|
99
|
+
|
|
100
|
+
**Claude Desktop** — add to `claude_desktop_config.json`:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"mcpServers": {
|
|
105
|
+
"paraview": {
|
|
106
|
+
"command": "/absolute/path/to/.venv/bin/paraview-mcp-server"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Codex CLI:**
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
codex mcp add paraview -- /absolute/path/to/.venv/bin/paraview-mcp-server
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Example prompts
|
|
121
|
+
|
|
122
|
+
Once both processes are running and your MCP client is configured:
|
|
123
|
+
|
|
124
|
+
- *"List all sources in the current ParaView session."*
|
|
125
|
+
- *"Open `/data/disk_out_ref.ex2`."*
|
|
126
|
+
- *"Create a slice through X = 0 of the disk dataset."*
|
|
127
|
+
- *"Color the dataset by Pressure."*
|
|
128
|
+
- *"Save a screenshot to `/tmp/view.png`."*
|
|
129
|
+
- *"Apply a contour filter on Pressure with isovalues 0.5 and 1.0."*
|
|
130
|
+
- *"Set the camera to position [10, 5, 5] looking at the origin."*
|
|
131
|
+
- *"Set the background to a gradient from white to dark blue."*
|
|
132
|
+
- *"Export an animation to `/tmp/anim.avi`."*
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Tool reference (31 tools)
|
|
137
|
+
|
|
138
|
+
### Scene / session
|
|
139
|
+
| Tool | Description |
|
|
140
|
+
|---|---|
|
|
141
|
+
| `paraview_scene_get_info` | Session info: source count, active view type |
|
|
142
|
+
| `paraview_scene_list_sources` | List all pipeline sources |
|
|
143
|
+
| `paraview_scene_list_views` | List open render views |
|
|
144
|
+
| `paraview_source_get_properties` | Properties of a named source |
|
|
145
|
+
|
|
146
|
+
### Data loading
|
|
147
|
+
| Tool | Description |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `paraview_source_open_file` | Open a dataset (VTK, VTU, ExodusII, CSV, …) |
|
|
150
|
+
| `paraview_source_delete` | Remove a source from the pipeline |
|
|
151
|
+
| `paraview_source_rename` | Rename a source |
|
|
152
|
+
|
|
153
|
+
### Filters — basic
|
|
154
|
+
| Tool | Description |
|
|
155
|
+
|---|---|
|
|
156
|
+
| `paraview_filter_slice` | Slice filter with origin + normal |
|
|
157
|
+
| `paraview_filter_clip` | Clip filter with origin + normal |
|
|
158
|
+
| `paraview_filter_contour` | Contour / isosurface by scalar array and values |
|
|
159
|
+
| `paraview_filter_threshold` | Threshold filter by scalar range |
|
|
160
|
+
|
|
161
|
+
### Filters — advanced
|
|
162
|
+
| Tool | Description |
|
|
163
|
+
|---|---|
|
|
164
|
+
| `paraview_filter_calculator` | Calculator filter with expression |
|
|
165
|
+
| `paraview_filter_stream_tracer` | Stream Tracer for vector field streamlines |
|
|
166
|
+
| `paraview_filter_glyph` | Glyph filter for vector visualization |
|
|
167
|
+
|
|
168
|
+
### Display / coloring
|
|
169
|
+
| Tool | Description |
|
|
170
|
+
|---|---|
|
|
171
|
+
| `paraview_display_show` | Make a source visible |
|
|
172
|
+
| `paraview_display_hide` | Hide a source |
|
|
173
|
+
| `paraview_display_color_by` | Color by a data array |
|
|
174
|
+
| `paraview_display_set_representation` | Surface / Wireframe / Points / Volume |
|
|
175
|
+
| `paraview_display_set_opacity` | Set opacity (0.0 – 1.0) |
|
|
176
|
+
| `paraview_display_rescale_transfer_function` | Rescale color map to data range |
|
|
177
|
+
|
|
178
|
+
### Camera / view
|
|
179
|
+
| Tool | Description |
|
|
180
|
+
|---|---|
|
|
181
|
+
| `paraview_view_reset_camera` | Fit all visible sources in the view |
|
|
182
|
+
| `paraview_view_set_camera` | Set camera position, focal point, view-up |
|
|
183
|
+
| `paraview_view_set_background` | Set solid or gradient background color |
|
|
184
|
+
|
|
185
|
+
### Export
|
|
186
|
+
| Tool | Description |
|
|
187
|
+
|---|---|
|
|
188
|
+
| `paraview_export_screenshot` | Save a PNG or JPEG screenshot |
|
|
189
|
+
| `paraview_export_data` | Export source data to VTK/CSV/… |
|
|
190
|
+
| `paraview_export_animation` | Export animation to video/frames |
|
|
191
|
+
|
|
192
|
+
### Python execution
|
|
193
|
+
| Tool | Description |
|
|
194
|
+
|---|---|
|
|
195
|
+
| `paraview_python_exec` | Run Python in bridge or headless pvpython |
|
|
196
|
+
| `paraview_python_exec_async` | Start a long-running Python job (headless) |
|
|
197
|
+
|
|
198
|
+
### Job management
|
|
199
|
+
| Tool | Description |
|
|
200
|
+
|---|---|
|
|
201
|
+
| `paraview_job_status` | Get status of an async job |
|
|
202
|
+
| `paraview_job_cancel` | Cancel a running async job |
|
|
203
|
+
| `paraview_job_list` | List all known async jobs |
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Python execution
|
|
208
|
+
|
|
209
|
+
`paraview_python_exec` is the escape hatch for workflows that need more than the fixed
|
|
210
|
+
tool set. The script runs in the bridge process where `paraview.simple` is already imported.
|
|
211
|
+
|
|
212
|
+
**Parameters:**
|
|
213
|
+
|
|
214
|
+
| Parameter | Type | Description |
|
|
215
|
+
|---|---|---|
|
|
216
|
+
| `code` | `str` | Inline Python source (mutually exclusive with `script_path`) |
|
|
217
|
+
| `script_path` | `str` | Path to a `.py` file (mutually exclusive with `code`) |
|
|
218
|
+
| `args` | `dict` | Arguments exposed as `args` inside the script |
|
|
219
|
+
| `timeout_seconds` | `int` | Cooperative timeout (default: 30s) |
|
|
220
|
+
| `transport` | `str` | `"bridge"` (default) or `"headless"` (separate pvpython process) |
|
|
221
|
+
|
|
222
|
+
**Execution namespace:**
|
|
223
|
+
|
|
224
|
+
| Variable | Type | Description |
|
|
225
|
+
|---|---|---|
|
|
226
|
+
| `pvs` | module | `paraview.simple` |
|
|
227
|
+
| `args` | dict | Arguments from the `args` parameter |
|
|
228
|
+
| `__result__` | Any | Set this to return a JSON-serialisable value |
|
|
229
|
+
|
|
230
|
+
**Example:**
|
|
231
|
+
|
|
232
|
+
```python
|
|
233
|
+
# Open a file and create a slice
|
|
234
|
+
src = pvs.OpenDataFile(args["filepath"])
|
|
235
|
+
view = pvs.GetActiveViewOrCreate("RenderView")
|
|
236
|
+
pvs.Show(src, view)
|
|
237
|
+
filt = pvs.Slice(Input=src)
|
|
238
|
+
filt.SliceType.Origin = [0, 0, 0]
|
|
239
|
+
filt.SliceType.Normal = [1, 0, 0]
|
|
240
|
+
pvs.Show(filt, view)
|
|
241
|
+
pvs.ResetCamera(view)
|
|
242
|
+
__result__ = {"done": True}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
See [`docs/python-execute-design.md`](docs/python-execute-design.md) for the full design,
|
|
246
|
+
schema reference, and more examples.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Async job execution
|
|
251
|
+
|
|
252
|
+
For long-running pipelines, use `paraview_python_exec_async`:
|
|
253
|
+
|
|
254
|
+
1. Start a job → returns `job_id` immediately
|
|
255
|
+
2. Poll with `paraview_job_status` → check `status` field
|
|
256
|
+
3. Cancel with `paraview_job_cancel` if needed
|
|
257
|
+
|
|
258
|
+
Async jobs run in a separate headless `pvpython` process via `HeadlessPvpythonExecutor`.
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Safety model
|
|
263
|
+
|
|
264
|
+
- **Blocked modules** — scripts cannot import `subprocess`, `shutil`, `socket`, `ctypes`,
|
|
265
|
+
`multiprocessing`, `webbrowser`, or several network-facing stdlib modules.
|
|
266
|
+
- **Output bounding** — stdout/stderr capped at **50 KB**.
|
|
267
|
+
- **Cooperative timeout** — default 30 seconds per script execution.
|
|
268
|
+
- **Script path validation** — optionally restrict execution to approved root directories.
|
|
269
|
+
- The bridge runs inside `pvpython` with the same trust level as a local ParaView session.
|
|
270
|
+
- This is a local desktop automation tool — not a public API sandbox.
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Development
|
|
275
|
+
|
|
276
|
+
### Install dev dependencies
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
pip install -e ".[dev]"
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Run tests
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
pytest tests/
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Tests do **not** require ParaView to be installed. The command handler tests patch
|
|
289
|
+
`_import_pv` with a `MagicMock` that mimics the `paraview.simple` API.
|
|
290
|
+
|
|
291
|
+
### Send a raw bridge command (for debugging)
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
python scripts/paraview_bridge_request.py scene.get_info
|
|
295
|
+
python scripts/paraview_bridge_request.py source.open_file --params '{"filepath":"/data/disk.vtu"}'
|
|
296
|
+
python scripts/paraview_bridge_request.py export.screenshot --params '{"filepath":"/tmp/shot.png"}'
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Project structure
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
paraview-mcp-server/
|
|
305
|
+
├── pyproject.toml
|
|
306
|
+
├── src/
|
|
307
|
+
│ └── paraview_mcp_server/
|
|
308
|
+
│ ├── __init__.py # Re-exports main()
|
|
309
|
+
│ ├── server.py # FastMCP stdio server (31 tools)
|
|
310
|
+
│ └── headless.py # Headless pvpython executor + job manager
|
|
311
|
+
├── bridge/
|
|
312
|
+
│ ├── __init__.py
|
|
313
|
+
│ ├── server.py # TCP socket bridge server
|
|
314
|
+
│ ├── command_handler.py # Command registry + paraview.simple handlers (27 commands)
|
|
315
|
+
│ └── execution.py # python.execute helper with safety controls
|
|
316
|
+
├── scripts/
|
|
317
|
+
│ ├── start_paraview_bridge.py
|
|
318
|
+
│ ├── paraview_bridge_request.py
|
|
319
|
+
│ └── library/ # Reusable pvpython snippets
|
|
320
|
+
│ ├── open_dataset.py
|
|
321
|
+
│ ├── create_slice.py
|
|
322
|
+
│ ├── create_contour.py
|
|
323
|
+
│ ├── color_by.py
|
|
324
|
+
│ ├── reset_camera.py
|
|
325
|
+
│ └── save_screenshot.py
|
|
326
|
+
├── docs/
|
|
327
|
+
│ ├── architecture.md
|
|
328
|
+
│ └── python-execute-design.md
|
|
329
|
+
└── tests/
|
|
330
|
+
├── test_server.py # 31 tools, connection, headless, async jobs
|
|
331
|
+
├── test_protocol.py # Wire encoding, fake bridge integration
|
|
332
|
+
└── test_command_handler.py # All 27 handlers + safety controls
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## License
|
|
338
|
+
|
|
339
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
paraview_mcp_server/__init__.py,sha256=dHbGG7bmecZtwNF24-l-rVWZH8wm0dG4mFfP-QF1yPk,200
|
|
2
|
+
paraview_mcp_server/headless.py,sha256=9X5-JvSPWkzOkjEMGj_aTzO3Kc1snY5BvcYj81EYfJs,12594
|
|
3
|
+
paraview_mcp_server/server.py,sha256=AgD3emMbC8X3t_zoiMMUzH5TEHrhAZN97HKrx31K6lE,21708
|
|
4
|
+
paraview_mcp_python-0.1.0.dist-info/METADATA,sha256=AHueAl2bsOFRnvfkNHw-aJQz2ilX6pJtqkGSQ-NVKrY,11135
|
|
5
|
+
paraview_mcp_python-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
6
|
+
paraview_mcp_python-0.1.0.dist-info/entry_points.txt,sha256=afqGvqg8Wt3637crbudFjbvnyjgky43sqhHN0r8FN_4,65
|
|
7
|
+
paraview_mcp_python-0.1.0.dist-info/licenses/LICENSE,sha256=bCZz53QzJ-Dkb8S8hTzahaKjpPIsORWg8O9DiSNzrOY,1071
|
|
8
|
+
paraview_mcp_python-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Adam Djellouli
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|