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.
@@ -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,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ paraview-mcp-server = paraview_mcp_server:main
@@ -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.
@@ -0,0 +1,4 @@
1
+ from paraview_mcp_server.headless import HeadlessJobManager, HeadlessPvpythonExecutor
2
+ from paraview_mcp_server.server import main
3
+
4
+ __all__ = ["main", "HeadlessPvpythonExecutor", "HeadlessJobManager"]