ovito-mcp 2026.1.dev2__tar.gz
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.
- ovito_mcp-2026.1.dev2/.gitignore +271 -0
- ovito_mcp-2026.1.dev2/.gitlab-ci.yml +87 -0
- ovito_mcp-2026.1.dev2/LICENSE +39 -0
- ovito_mcp-2026.1.dev2/PKG-INFO +240 -0
- ovito_mcp-2026.1.dev2/README.md +208 -0
- ovito_mcp-2026.1.dev2/RELEASING.md +94 -0
- ovito_mcp-2026.1.dev2/ovito_mcp/__init__.py +1275 -0
- ovito_mcp-2026.1.dev2/ovito_mcp/__main__.py +16 -0
- ovito_mcp-2026.1.dev2/ovito_mcp/rag/__init__.py +293 -0
- ovito_mcp-2026.1.dev2/ovito_mcp/rag/db.py +542 -0
- ovito_mcp-2026.1.dev2/pyproject.toml +47 -0
- ovito_mcp-2026.1.dev2/tests/test_docs_index.py +114 -0
- ovito_mcp-2026.1.dev2/tests/test_docs_index_discovery.py +76 -0
- ovito_mcp-2026.1.dev2/tests/test_rag_db.py +176 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,python,macos,linux,windows
|
|
2
|
+
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,python,macos,linux,windows
|
|
3
|
+
|
|
4
|
+
### Linux ###
|
|
5
|
+
*~
|
|
6
|
+
|
|
7
|
+
# temporary files which can be created if a process still has a handle open of a deleted file
|
|
8
|
+
.fuse_hidden*
|
|
9
|
+
|
|
10
|
+
# KDE directory preferences
|
|
11
|
+
.directory
|
|
12
|
+
|
|
13
|
+
# Linux trash folder which might appear on any partition or disk
|
|
14
|
+
.Trash-*
|
|
15
|
+
|
|
16
|
+
# .nfs files are created when an open file is removed but is still being accessed
|
|
17
|
+
.nfs*
|
|
18
|
+
|
|
19
|
+
### macOS ###
|
|
20
|
+
# General
|
|
21
|
+
.DS_Store
|
|
22
|
+
.AppleDouble
|
|
23
|
+
.LSOverride
|
|
24
|
+
|
|
25
|
+
# Icon must end with two \r
|
|
26
|
+
Icon
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Thumbnails
|
|
30
|
+
._*
|
|
31
|
+
|
|
32
|
+
# Files that might appear in the root of a volume
|
|
33
|
+
.DocumentRevisions-V100
|
|
34
|
+
.fseventsd
|
|
35
|
+
.Spotlight-V100
|
|
36
|
+
.TemporaryItems
|
|
37
|
+
.Trashes
|
|
38
|
+
.VolumeIcon.icns
|
|
39
|
+
.com.apple.timemachine.donotpresent
|
|
40
|
+
|
|
41
|
+
# Directories potentially created on remote AFP share
|
|
42
|
+
.AppleDB
|
|
43
|
+
.AppleDesktop
|
|
44
|
+
Network Trash Folder
|
|
45
|
+
Temporary Items
|
|
46
|
+
.apdisk
|
|
47
|
+
|
|
48
|
+
### macOS Patch ###
|
|
49
|
+
# iCloud generated files
|
|
50
|
+
*.icloud
|
|
51
|
+
|
|
52
|
+
### Python ###
|
|
53
|
+
# Byte-compiled / optimized / DLL files
|
|
54
|
+
__pycache__/
|
|
55
|
+
*.py[cod]
|
|
56
|
+
*$py.class
|
|
57
|
+
|
|
58
|
+
# C extensions
|
|
59
|
+
*.so
|
|
60
|
+
|
|
61
|
+
# Distribution / packaging
|
|
62
|
+
.Python
|
|
63
|
+
build/
|
|
64
|
+
develop-eggs/
|
|
65
|
+
dist/
|
|
66
|
+
downloads/
|
|
67
|
+
eggs/
|
|
68
|
+
.eggs/
|
|
69
|
+
lib/
|
|
70
|
+
lib64/
|
|
71
|
+
parts/
|
|
72
|
+
sdist/
|
|
73
|
+
var/
|
|
74
|
+
wheels/
|
|
75
|
+
share/python-wheels/
|
|
76
|
+
*.egg-info/
|
|
77
|
+
.installed.cfg
|
|
78
|
+
*.egg
|
|
79
|
+
MANIFEST
|
|
80
|
+
|
|
81
|
+
# PyInstaller
|
|
82
|
+
# Usually these files are written by a python script from a template
|
|
83
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
84
|
+
*.manifest
|
|
85
|
+
*.spec
|
|
86
|
+
|
|
87
|
+
# Installer logs
|
|
88
|
+
pip-log.txt
|
|
89
|
+
pip-delete-this-directory.txt
|
|
90
|
+
|
|
91
|
+
# Unit test / coverage reports
|
|
92
|
+
htmlcov/
|
|
93
|
+
.tox/
|
|
94
|
+
.nox/
|
|
95
|
+
.coverage
|
|
96
|
+
.coverage.*
|
|
97
|
+
.cache
|
|
98
|
+
nosetests.xml
|
|
99
|
+
coverage.xml
|
|
100
|
+
*.cover
|
|
101
|
+
*.py,cover
|
|
102
|
+
.hypothesis/
|
|
103
|
+
.pytest_cache/
|
|
104
|
+
cover/
|
|
105
|
+
|
|
106
|
+
# Translations
|
|
107
|
+
*.mo
|
|
108
|
+
*.pot
|
|
109
|
+
|
|
110
|
+
# Django stuff:
|
|
111
|
+
*.log
|
|
112
|
+
local_settings.py
|
|
113
|
+
db.sqlite3
|
|
114
|
+
db.sqlite3-journal
|
|
115
|
+
|
|
116
|
+
# Flask stuff:
|
|
117
|
+
instance/
|
|
118
|
+
.webassets-cache
|
|
119
|
+
|
|
120
|
+
# Scrapy stuff:
|
|
121
|
+
.scrapy
|
|
122
|
+
|
|
123
|
+
# Sphinx documentation
|
|
124
|
+
docs/_build/
|
|
125
|
+
|
|
126
|
+
# PyBuilder
|
|
127
|
+
.pybuilder/
|
|
128
|
+
target/
|
|
129
|
+
|
|
130
|
+
# Jupyter Notebook
|
|
131
|
+
.ipynb_checkpoints
|
|
132
|
+
|
|
133
|
+
# IPython
|
|
134
|
+
profile_default/
|
|
135
|
+
ipython_config.py
|
|
136
|
+
|
|
137
|
+
# pyenv
|
|
138
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
139
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
140
|
+
# .python-version
|
|
141
|
+
|
|
142
|
+
# pipenv
|
|
143
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
144
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
145
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
146
|
+
# install all needed dependencies.
|
|
147
|
+
#Pipfile.lock
|
|
148
|
+
|
|
149
|
+
# poetry
|
|
150
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
151
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
152
|
+
# commonly ignored for libraries.
|
|
153
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
154
|
+
#poetry.lock
|
|
155
|
+
|
|
156
|
+
# pdm
|
|
157
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
158
|
+
#pdm.lock
|
|
159
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
160
|
+
# in version control.
|
|
161
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
162
|
+
.pdm.toml
|
|
163
|
+
|
|
164
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
165
|
+
__pypackages__/
|
|
166
|
+
|
|
167
|
+
# Celery stuff
|
|
168
|
+
celerybeat-schedule
|
|
169
|
+
celerybeat.pid
|
|
170
|
+
|
|
171
|
+
# SageMath parsed files
|
|
172
|
+
*.sage.py
|
|
173
|
+
|
|
174
|
+
# Environments
|
|
175
|
+
.env
|
|
176
|
+
.venv
|
|
177
|
+
env/
|
|
178
|
+
venv/
|
|
179
|
+
ENV/
|
|
180
|
+
env.bak/
|
|
181
|
+
venv.bak/
|
|
182
|
+
|
|
183
|
+
# Spyder project settings
|
|
184
|
+
.spyderproject
|
|
185
|
+
.spyproject
|
|
186
|
+
|
|
187
|
+
# Rope project settings
|
|
188
|
+
.ropeproject
|
|
189
|
+
|
|
190
|
+
# mkdocs documentation
|
|
191
|
+
/site
|
|
192
|
+
|
|
193
|
+
# mypy
|
|
194
|
+
.mypy_cache/
|
|
195
|
+
.dmypy.json
|
|
196
|
+
dmypy.json
|
|
197
|
+
|
|
198
|
+
# Pyre type checker
|
|
199
|
+
.pyre/
|
|
200
|
+
|
|
201
|
+
# pytype static type analyzer
|
|
202
|
+
.pytype/
|
|
203
|
+
|
|
204
|
+
# Cython debug symbols
|
|
205
|
+
cython_debug/
|
|
206
|
+
|
|
207
|
+
# PyCharm
|
|
208
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
209
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
210
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
211
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
212
|
+
#.idea/
|
|
213
|
+
|
|
214
|
+
### Python Patch ###
|
|
215
|
+
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
|
|
216
|
+
poetry.toml
|
|
217
|
+
|
|
218
|
+
# ruff
|
|
219
|
+
.ruff_cache/
|
|
220
|
+
|
|
221
|
+
# LSP config files
|
|
222
|
+
pyrightconfig.json
|
|
223
|
+
|
|
224
|
+
### VisualStudioCode ###
|
|
225
|
+
.vscode/*
|
|
226
|
+
!.vscode/settings.json
|
|
227
|
+
!.vscode/tasks.json
|
|
228
|
+
!.vscode/launch.json
|
|
229
|
+
!.vscode/extensions.json
|
|
230
|
+
!.vscode/*.code-snippets
|
|
231
|
+
|
|
232
|
+
# Local History for Visual Studio Code
|
|
233
|
+
.history/
|
|
234
|
+
|
|
235
|
+
# Built Visual Studio Code Extensions
|
|
236
|
+
*.vsix
|
|
237
|
+
|
|
238
|
+
### VisualStudioCode Patch ###
|
|
239
|
+
# Ignore all local history of files
|
|
240
|
+
.history
|
|
241
|
+
.ionide
|
|
242
|
+
|
|
243
|
+
### Windows ###
|
|
244
|
+
# Windows thumbnail cache files
|
|
245
|
+
Thumbs.db
|
|
246
|
+
Thumbs.db:encryptable
|
|
247
|
+
ehthumbs.db
|
|
248
|
+
ehthumbs_vista.db
|
|
249
|
+
|
|
250
|
+
# Dump file
|
|
251
|
+
*.stackdump
|
|
252
|
+
|
|
253
|
+
# Folder config file
|
|
254
|
+
[Dd]esktop.ini
|
|
255
|
+
|
|
256
|
+
# Recycle Bin used on file shares
|
|
257
|
+
$RECYCLE.BIN/
|
|
258
|
+
|
|
259
|
+
# Windows Installer files
|
|
260
|
+
*.cab
|
|
261
|
+
*.msi
|
|
262
|
+
*.msix
|
|
263
|
+
*.msm
|
|
264
|
+
*.msp
|
|
265
|
+
|
|
266
|
+
# Windows shortcuts
|
|
267
|
+
*.lnk
|
|
268
|
+
|
|
269
|
+
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,python,macos,linux,windows
|
|
270
|
+
|
|
271
|
+
.claude
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
default:
|
|
2
|
+
image: python:3.11
|
|
3
|
+
|
|
4
|
+
stages:
|
|
5
|
+
- test
|
|
6
|
+
- publish
|
|
7
|
+
|
|
8
|
+
variables:
|
|
9
|
+
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
|
10
|
+
|
|
11
|
+
cache:
|
|
12
|
+
paths:
|
|
13
|
+
- .cache/pip
|
|
14
|
+
|
|
15
|
+
test:
|
|
16
|
+
stage: test
|
|
17
|
+
parallel:
|
|
18
|
+
matrix:
|
|
19
|
+
# The floor and ceiling of requires-python. This package needs
|
|
20
|
+
# torch, so every extra matrix entry is expensive; the two ends catch the version
|
|
21
|
+
# incompatibilities that matter.
|
|
22
|
+
- PYTHON_VERSION: ["3.10", "3.14"]
|
|
23
|
+
image: python:${PYTHON_VERSION}
|
|
24
|
+
script:
|
|
25
|
+
# Install the CPU-only torch build first so the sentence-transformers dependency
|
|
26
|
+
# below is already satisfied and pip never pulls the ~2.5GB CUDA wheel. CI has no GPU.
|
|
27
|
+
- pip install torch --index-url https://download.pytorch.org/whl/cpu
|
|
28
|
+
- pip install -e ".[test]"
|
|
29
|
+
- pytest -q
|
|
30
|
+
|
|
31
|
+
publish-pypi:
|
|
32
|
+
stage: publish
|
|
33
|
+
rules:
|
|
34
|
+
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+/
|
|
35
|
+
variables:
|
|
36
|
+
HATCH_INDEX_USER: __token__
|
|
37
|
+
# HATCH_INDEX_AUTH holds the PyPI API token. It is not defined here: set it as a
|
|
38
|
+
# masked CI/CD variable in the GitLab project settings (see RELEASING.md).
|
|
39
|
+
# Disable keyring, which otherwise hangs waiting for a backend on a headless runner.
|
|
40
|
+
PYTHON_KEYRING_BACKEND: keyring.backends.null.Keyring
|
|
41
|
+
script:
|
|
42
|
+
# Fail fast, and legibly, when the token never reached the job. Without this the
|
|
43
|
+
# symptom is an opaque "403 Forbidden" from PyPI at the very end of the pipeline,
|
|
44
|
+
# which looks like a bad token rather than a missing one.
|
|
45
|
+
- |
|
|
46
|
+
if [ -z "$HATCH_INDEX_AUTH" ]; then
|
|
47
|
+
echo "HATCH_INDEX_AUTH is empty or unset in this job." >&2
|
|
48
|
+
echo "A 'Protected' CI/CD variable is only exposed to protected refs. Either add a" >&2
|
|
49
|
+
echo "protected-tag rule covering 'v*' under Settings > Repository > Protected tags," >&2
|
|
50
|
+
echo "or clear the Protected flag on the variable." >&2
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
case "$HATCH_INDEX_AUTH" in
|
|
54
|
+
pypi-*) ;;
|
|
55
|
+
*)
|
|
56
|
+
echo "HATCH_INDEX_AUTH does not look like a PyPI API token." >&2
|
|
57
|
+
echo "Expected it to start with 'pypi-'; got ${#HATCH_INDEX_AUTH} characters." >&2
|
|
58
|
+
echo "Check for a truncated paste, surrounding quotes, or trailing whitespace." >&2
|
|
59
|
+
exit 1
|
|
60
|
+
;;
|
|
61
|
+
esac
|
|
62
|
+
- pip install hatch
|
|
63
|
+
# Fail on a tag that disagrees with the packaged version. PyPI refuses re-uploads of
|
|
64
|
+
# a version, so a mismatch has to be caught before `hatch publish`, not after.
|
|
65
|
+
#
|
|
66
|
+
# The tag is compared against the PEP 440 *normalized* version, because that is what
|
|
67
|
+
# ends up in the artifact filename and on PyPI. `hatch version` echoes the literal
|
|
68
|
+
# string from pyproject.toml, so a non-canonical spelling like "2026.1-rc1" would
|
|
69
|
+
# otherwise satisfy a literal comparison while publishing as "2026.1rc1".
|
|
70
|
+
# `packaging` is available here as a hatchling dependency.
|
|
71
|
+
- |
|
|
72
|
+
RAW_VERSION="$(hatch version)"
|
|
73
|
+
VERSION="$(python -c 'import sys; from packaging.version import Version; print(Version(sys.argv[1]))' "$RAW_VERSION")"
|
|
74
|
+
if [ "v$VERSION" != "$CI_COMMIT_TAG" ]; then
|
|
75
|
+
echo "Tag $CI_COMMIT_TAG does not match the version that would be published ($VERSION)." >&2
|
|
76
|
+
if [ "$RAW_VERSION" != "$VERSION" ]; then
|
|
77
|
+
echo "Note: pyproject.toml says '$RAW_VERSION', which normalizes to '$VERSION'." >&2
|
|
78
|
+
echo "Write the version in canonical PEP 440 form to avoid this." >&2
|
|
79
|
+
fi
|
|
80
|
+
echo "Retag as v$VERSION, or bump the version to match the tag." >&2
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
- hatch build
|
|
84
|
+
- hatch publish
|
|
85
|
+
environment:
|
|
86
|
+
name: pypi
|
|
87
|
+
url: https://pypi.org/project/ovito-mcp/
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# OVITO Pro Add-on Package License
|
|
2
|
+
Copyright (c) 2026 OVITO GmbH. All rights reserved.
|
|
3
|
+
|
|
4
|
+
This software (the "Software") is a copyrighted work of OVITO GmbH ("Licensor"). The Software is made available in source form on the Python Package Index (PyPI) for distribution convenience only. Making the source code accessible does not constitute a grant of open-source rights, and no rights are granted to any person except as expressly set out below.
|
|
5
|
+
|
|
6
|
+
## 1. Grant of License
|
|
7
|
+
Subject to the terms of this License, Licensor grants you a limited, non-exclusive, non-transferable, non-sublicensable license to install, execute, and use the Software, solely if and for so long as you hold a valid, active license to OVITO Pro issued by OVITO GmbH ("OVITO Pro License").
|
|
8
|
+
This license to use the Software:
|
|
9
|
+
- is granted only to the same individual, group, or organization holding the corresponding OVITO Pro License, subject to the same installation limits as that OVITO Pro License;
|
|
10
|
+
- terminates automatically upon expiration, termination, or non-renewal of the underlying OVITO Pro License, without notice;
|
|
11
|
+
- does not include any right to use the Software independently of, or separately from, OVITO Pro.
|
|
12
|
+
|
|
13
|
+
## 2. Restrictions
|
|
14
|
+
Except as expressly permitted under Section 1, you may not:
|
|
15
|
+
|
|
16
|
+
a. use the Software without holding a valid, active OVITO Pro License;
|
|
17
|
+
b. copy, distribute, sublicense, sell, rent, lease, or otherwise make the Software available to any third party;
|
|
18
|
+
c. modify, adapt, translate, or create derivative works based on the Software;
|
|
19
|
+
d. reverse engineer, decompile, or disassemble the Software, except to the extent such restriction is prohibited by applicable mandatory law;
|
|
20
|
+
e. remove or alter any copyright, trademark, or other proprietary notices contained in the Software;
|
|
21
|
+
f. use the Software for any purpose other than in conjunction with your licensed use of OVITO Pro.
|
|
22
|
+
|
|
23
|
+
## 3. Ownership
|
|
24
|
+
The Software is licensed, not sold. Licensor retains all right, title, and interest in and to the Software, including all intellectual property rights therein. No rights are granted other than those expressly set forth in this License.
|
|
25
|
+
|
|
26
|
+
## 4. No Warranty
|
|
27
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
|
|
28
|
+
|
|
29
|
+
## 5. Limitation of Liability
|
|
30
|
+
IN NO EVENT SHALL LICENSOR BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW.
|
|
31
|
+
|
|
32
|
+
## 6. Termination
|
|
33
|
+
This License terminates automatically, without notice from Licensor, upon any breach of its terms, or upon expiration or termination of the underlying OVITO Pro License. Upon termination, you must cease all use of the Software and delete all copies in your possession.
|
|
34
|
+
|
|
35
|
+
## 7. Governing Law
|
|
36
|
+
This License shall be governed by the laws of the Federal Republic of Germany, without regard to its conflict-of-law provisions. The place of jurisdiction shall be Darmstadt, Germany, to the extent permitted by law.
|
|
37
|
+
|
|
38
|
+
## 8. Contact
|
|
39
|
+
For questions regarding this License, contact: mail@ovito.org
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ovito-mcp
|
|
3
|
+
Version: 2026.1.dev2
|
|
4
|
+
Summary: MCP server for interactive work in OVITO Pro
|
|
5
|
+
Project-URL: Homepage, https://www.ovito.org
|
|
6
|
+
Project-URL: Documentation, https://docs.ovito.org/reference/data_inspector/coding_agent.html
|
|
7
|
+
Project-URL: Repository, https://gitlab.com/ovito-org/ovito-mcp-server
|
|
8
|
+
Project-URL: Bug Tracker, https://gitlab.com/ovito-org/ovito-mcp-server/-/issues
|
|
9
|
+
Author-email: OVITO GmbH <support@ovito.org>
|
|
10
|
+
License: Proprietary
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: jupyter,mcp,molecular-dynamics,ovito,visualization
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: Other/Proprietary 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: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Requires-Dist: jupyter-client>=8.0
|
|
25
|
+
Requires-Dist: jupyter-core>=5.0
|
|
26
|
+
Requires-Dist: mcp>=1.2.0
|
|
27
|
+
Requires-Dist: numpy>=1.26
|
|
28
|
+
Requires-Dist: sentence-transformers>=5.6.0
|
|
29
|
+
Provides-Extra: test
|
|
30
|
+
Requires-Dist: pytest; extra == 'test'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# OVITO MCP Server
|
|
34
|
+
|
|
35
|
+
An MCP server that connects a coding agent to a live **OVITO Pro** session, so an LLM can
|
|
36
|
+
do interactive OVITO work — execute Python in a persistent kernel, inspect the scene,
|
|
37
|
+
drive the GUI window, and look up documentation. Runs as a stdio MCP server in Claude
|
|
38
|
+
Code, GitHub Copilot CLI, Codex, OpenCode, Antigravity, or any other MCP host.
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
pip install ovito-mcp
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Register it with your coding agent — for Claude Code:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
claude mcp add ovito-mcp --scope user -- ovito-mcp
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
See [Agent configuration](#agent-configuration) below for the equivalent config in other
|
|
53
|
+
agents.
|
|
54
|
+
|
|
55
|
+
Then, in OVITO Pro, open the **AI Agent** tab in the data inspector panel at the bottom
|
|
56
|
+
of the main window, pick your coding agent, and press **Start**. OVITO launches the agent
|
|
57
|
+
and hands it the connection details of its own embedded Python kernel, so the agent
|
|
58
|
+
attaches to the session you are looking at — anything it does shows up live in the GUI,
|
|
59
|
+
and you can keep interacting with the same scene yourself.
|
|
60
|
+
|
|
61
|
+
That's the whole setup. **No environment variables are required**, and you do not need to
|
|
62
|
+
tell the server where OVITO is installed: it is already talking to a running OVITO Pro.
|
|
63
|
+
|
|
64
|
+
See the [AI Agent manual page](https://docs.ovito.org/reference/data_inspector/coding_agent.html)
|
|
65
|
+
for the OVITO-side documentation, including security considerations.
|
|
66
|
+
|
|
67
|
+
## How it works
|
|
68
|
+
|
|
69
|
+
- `ovito_mcp/__init__.py` uses `jupyter_client` to attach to (or, as a fallback, start) an
|
|
70
|
+
OVITO kernel, and exposes tools to `execute` code and manage the kernel lifecycle. State
|
|
71
|
+
persists across calls — variables, imports, and the OVITO pipeline carry over.
|
|
72
|
+
- OVITO Pro's *AI Agent* panel starts an embedded kernel and passes its connection-file
|
|
73
|
+
path to the agent in the startup prompt; the agent calls `connect_kernel()` with it.
|
|
74
|
+
The same kernel can also be attached from JupyterLab to watch along.
|
|
75
|
+
- `start_kernel()` is the fallback for standalone use with no OVITO Pro session running.
|
|
76
|
+
It launches a separate OVITO process and is the only part of the server that needs
|
|
77
|
+
`OVITO_EXE` — see [Advanced configuration](#advanced-configuration).
|
|
78
|
+
- GUI tools (`create_window`, `close_window`, `screenshot_window`) drive OVITO Pro's Qt
|
|
79
|
+
main window inside the kernel, so a human can watch and interact with the same scene.
|
|
80
|
+
- Scene-inspection tools (`list_pipelines`, `list_modifiers`, `inspect_pipeline_data`,
|
|
81
|
+
`get_timeline_info`, `set_current_frame`) let the LLM read back pipeline/data state
|
|
82
|
+
without hand-writing introspection code.
|
|
83
|
+
- The documentation tools (`search_ovito_docs` and friends) perform semantic search over a
|
|
84
|
+
local SQLite index of the OVITO manual and Python API docs, so the LLM can look up
|
|
85
|
+
correct usage instead of guessing at APIs. The index ships inside OVITO Pro and is found
|
|
86
|
+
automatically — nothing to configure.
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
connect_kernel(<connection_file>) # the normal path: attach to OVITO Pro's own kernel
|
|
90
|
+
\-> start_kernel() # fallback: launch a separate OVITO process (needs OVITO_EXE)
|
|
91
|
+
\-> execute("import ovito; print(ovito.version_string)")
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Advanced configuration
|
|
95
|
+
|
|
96
|
+
Neither variable below is needed for the standard flow described in
|
|
97
|
+
[Quick start](#quick-start). Set them only for the cases described.
|
|
98
|
+
|
|
99
|
+
| Env var | Purpose |
|
|
100
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
101
|
+
| `OVITO_EXE` | Path to the OVITO Pro executable (`ovito.exe` on Windows, `ovito` on Linux, `Ovito.app/Contents/MacOS/ovito` on macOS). Required *only* by `start_kernel()`, i.e. when you want the agent to launch OVITO itself instead of connecting to a running session. |
|
|
102
|
+
| `OVITO_RAG_DB` | Path to an alternative documentation database (`.sqlite3`). Overrides the copy that ships with OVITO Pro — useful when developing against a hand-built database. |
|
|
103
|
+
|
|
104
|
+
Both are read at import time but never validated there, so the server always starts
|
|
105
|
+
without configuration. `start_kernel()` raises `ValueError` if `OVITO_EXE` is unset, and
|
|
106
|
+
the documentation tools report a message telling you to connect a kernel first if the
|
|
107
|
+
database cannot be located.
|
|
108
|
+
|
|
109
|
+
By default the documentation database is discovered by asking the connected kernel for
|
|
110
|
+
`ovito.__file__` and looking for `rag.sqlite3` next to the resolved `ovito` package. That
|
|
111
|
+
works without `OVITO_EXE`, which is why the standard flow needs no setup at all.
|
|
112
|
+
|
|
113
|
+
## Tools
|
|
114
|
+
|
|
115
|
+
**Kernel lifecycle**
|
|
116
|
+
|
|
117
|
+
| Tool | Purpose |
|
|
118
|
+
| --------------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
119
|
+
| `connect_kernel(connection_file)` | Attach to an already-running kernel via its connection file; state is shared with whoever else is driving it. |
|
|
120
|
+
| `start_kernel()` | Launch a new OVITO kernel and make it active (tears down any current session first). Requires `OVITO_EXE`. |
|
|
121
|
+
| `get_kernel_id()` | UUID of the active kernel. |
|
|
122
|
+
| `kernel_status()` | Active kernel id, ownership (started here vs. externally connected), liveness. |
|
|
123
|
+
| `interrupt_kernel()` | Interrupt a running execution (kernels started by this server only). |
|
|
124
|
+
| `restart_kernel()` | Restart and clear all state (kernels started by this server only). |
|
|
125
|
+
| `shutdown_kernel()` | Shut down an owned kernel, or detach from an externally-connected one (left running). |
|
|
126
|
+
|
|
127
|
+
**Execution**
|
|
128
|
+
|
|
129
|
+
| Tool | Purpose |
|
|
130
|
+
| --------------------------- | ------------------------------------------------------------------------------------------ |
|
|
131
|
+
| `execute(code, timeout=60)` | Run Python in the active kernel; returns status, stdout/stderr, result, and any traceback. |
|
|
132
|
+
|
|
133
|
+
**GUI window**
|
|
134
|
+
|
|
135
|
+
| Tool | Purpose |
|
|
136
|
+
| ------------------------------ | ----------------------------------------------------------------------------------------------- |
|
|
137
|
+
| `create_window(contents=None)` | Open (or reuse) OVITO's graphical main window in the kernel so a human can watch/interact live. |
|
|
138
|
+
| `close_window()` | Close a window this server itself created — never one it merely reused. |
|
|
139
|
+
| `screenshot_window()` | Return a PNG screenshot of the open OVITO main window. |
|
|
140
|
+
|
|
141
|
+
**Scene inspection**
|
|
142
|
+
|
|
143
|
+
| Tool | Purpose |
|
|
144
|
+
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
145
|
+
| `list_pipelines()` | List pipelines in the scene with their keys and names. |
|
|
146
|
+
| `list_modifiers(pipeline_key)` | List modifiers on a given pipeline. |
|
|
147
|
+
| `inspect_pipeline_data(pipeline_key)` | Markdown overview of a pipeline's computed output: attributes, data objects, property containers, simulation cell. |
|
|
148
|
+
| `list_pipeline_status()` | Status (including warning/error triangles) of every pipeline, modifier, and visual element in the scene. |
|
|
149
|
+
| `get_timeline_info()` | Current frame and frame range. |
|
|
150
|
+
| `set_current_frame(frame)` | Set the current animation frame (keeps the GUI in sync; use instead of setting `ovito.scene.anim.current_frame` directly). |
|
|
151
|
+
|
|
152
|
+
**Documentation**
|
|
153
|
+
|
|
154
|
+
| Tool | Purpose |
|
|
155
|
+
| ------------------------------------------------------ | ------------------------------------------------------------------------- |
|
|
156
|
+
| `search_ovito_docs(query, top_k=5)` | Semantic search across the OVITO manual and Python API docs. |
|
|
157
|
+
| `search_ovito_manual(query, top_k=5)` | Semantic search over manual pages only. |
|
|
158
|
+
| `search_ovito_api_symbols(query, top_k=5)` | Semantic search over Python API symbols only. |
|
|
159
|
+
| `get_ovito_manual_page(full_page_id)` | Fetch a manual page's full text by id (from a manual search result). |
|
|
160
|
+
| `get_ovito_docstring(doc_string_id=None, symbol=None)` | Fetch a Python symbol's full docstring by id or exact qualified name. |
|
|
161
|
+
|
|
162
|
+
These are backed by `ovito_mcp.rag` — a single inspectable SQLite file (`rag.sqlite3`)
|
|
163
|
+
searched with a two-stage strategy: bi-encoder retrieval over stored embeddings, then
|
|
164
|
+
cross-encoder re-ranking of the candidates. No vector-store service is required. Manual
|
|
165
|
+
hits are resolved to their complete source page rather than the matching chunk, so results
|
|
166
|
+
are not truncated excerpts.
|
|
167
|
+
|
|
168
|
+
If no database can be located, these tools return a configuration hint instead of crashing
|
|
169
|
+
the server; every other tool is unaffected.
|
|
170
|
+
|
|
171
|
+
## Agent configuration
|
|
172
|
+
|
|
173
|
+
All configurations below assume `ovito-mcp` is on your `PATH` (it is installed as a
|
|
174
|
+
console script by `pip install ovito-mcp`). If you installed into an environment that
|
|
175
|
+
isn't active when the agent runs, use the absolute path to the script instead —
|
|
176
|
+
`/path/to/env/bin/ovito-mcp`. No `env` block is needed.
|
|
177
|
+
|
|
178
|
+
### Claude Code / Claude Desktop
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
claude mcp add ovito-mcp --scope user -- ovito-mcp
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Or add this to your `~/.claude.json`:
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
"mcpServers": {
|
|
188
|
+
"ovito-mcp": {
|
|
189
|
+
"type": "stdio",
|
|
190
|
+
"command": "ovito-mcp"
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### OpenCode
|
|
196
|
+
|
|
197
|
+
Add this to your `~/.opencode.json`:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
"mcp": {
|
|
201
|
+
"ovito-mcp": {
|
|
202
|
+
"type": "local",
|
|
203
|
+
"command": ["ovito-mcp"],
|
|
204
|
+
"enabled": true
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Google Antigravity
|
|
210
|
+
|
|
211
|
+
Add this to your `~/.antigravity/config.json`:
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
"mcpServers": {
|
|
215
|
+
"ovito-mcp": {
|
|
216
|
+
"command": "ovito-mcp"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### OpenAI Codex
|
|
222
|
+
|
|
223
|
+
Add this to your `$HOME/.codex/config.toml`:
|
|
224
|
+
|
|
225
|
+
```toml
|
|
226
|
+
[mcp_servers.ovito-mcp]
|
|
227
|
+
command = "ovito-mcp"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### GitHub Copilot
|
|
231
|
+
|
|
232
|
+
Add this to your `~/.copilot/mcp-config.json`:
|
|
233
|
+
|
|
234
|
+
```json
|
|
235
|
+
"mcpServers": {
|
|
236
|
+
"ovito-mcp": {
|
|
237
|
+
"command": "ovito-mcp"
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|