pymol-mcp
This server turns a headless PyMOL instance into an MCP-driven molecular visualization and clathrate-hydrate analysis toolkit.
Structure I/O: load/fetch PDB, CIF, GRO, MOL2, SDF, XYZ, and other structure files; list objects; inspect atom/state/chain info; reset sessions; save PDB/PNG/PSE/MOL2 files.
Visualization: show/hide/color/spectrum representations, set backgrounds, orient/zoom/turn camera, switch orthographic/perspective projection, and render ray-traced PNG images inline for the model to see.
Measurements & alignment: measure distances, angles, and dihedrals; sequence-align and superpose structures.
Trajectory support: load GROMACS/DCD trajectories natively and MDAnalysis-readable trajectories (LAMMPS dump, AMBER NetCDF) via the optional
mdextra.Clathrate-hydrate analysis: identify cages (sI/sII/sH), compute cage occupancy, draw cage wireframes, compute F3/F4 order parameters, build water H-bond networks, and classify water with CHILL+ (liquid/ice/hydrate) with optional CGO overlays.
Opt-in scripting: execute raw PyMOL command-language or Python snippets when
PYMOL_MCP_ALLOW_CODE_EXEC=1is set.Protocol-safe design: runs over stdio JSON-RPC with a dedicated worker thread and permanent stdout redirect, compatible with Claude, Codex, Gemini CLI, Cline, and other MCP clients.
An MCP server that embedsPyMOL in-process, headless — no GUI, no socket plugin, no manual setup. It exposes 30+ typed tools, returns rendered images inline so the model can see what it draws, loads GROMACS/LAMMPS trajectories, and ships a clathrate-hydrate analysis toolkit (H-bond networks, F3/F4 order parameters) with numerically validated science.
Demo
Related MCP server: vmd-mcp
Highlights
Runtime | Embedded, headless |
Tools | 30+ typed tools with real, structured return values |
Vision | ray-traced PNG returned inline so the model sees what it draws |
MD trajectories | GROMACS |
Domain science | cage perception (TRACE), occupancy, H-bonds, F3/F4 — validated |
Robustness | worker-thread session, stdout-safe transport, pytest suite |
Safety | arbitrary-code passthrough off by default |
Directory | Glama ( |
Features
Embedded & headless — one long-lived PyMOL instance on a dedicated worker thread; nothing to click, works in CI.
The model can see —
render_imageray-traces and returns a PNG as MCP image content. Useray_style="pymolwiki_color"for the PyMOLWiki quantized-color outline profile.MD-native — load GROMACS
.gro+.xtc, or bridge LAMMPS/NetCDF/… through MDAnalysis with in-memory coordinate injection.Clathrate-hydrate toolkit — H-bond networks and F3/F4 order parameters ported from a validated Rust engine, all in nm with correct triclinic PBC.
Typed, safe tools — every argument is schema-validated; the arbitrary-code passthrough is opt-in (
PYMOL_MCP_ALLOW_CODE_EXEC=1).Protocol-hardened — PyMOL's chatty stdout is permanently redirected so it can never corrupt the JSON-RPC stream (with a subprocess test that proves it).
Quick Start
PyMOL open-source is aconda package, and the server must run in a Python that can import pymol2.
Install into that interpreter — do not use uvx/fastmcp install (they build isolated envs without PyMOL).
# 1. Create the environment (or reuse one that already has pymol-open-source)
conda env create -f env.yml # env named `pymol-mcp`
conda activate pymol-mcp
# 2. Install this package (with the optional MD bridge + dev tools)
pip install -e ".[md,dev]"
# 3. Verify
pytest -qIt's a standard MCP server over stdio, so it works with any MCP-capable client (Claude Code / Desktop,
Codex CLI, Gemini CLI, Cline, Continue, …). Point the command at the absolute conda interpreter so it
can import pymol2.
Most clients use an mcpServers block (Claude Code / Desktop, Gemini CLI, Cline, Continue, …):
{
"mcpServers": {
"pymol": {
"command": "/absolute/path/to/conda/envs/pymol-mcp/bin/python",
"args": ["-m", "pymol_mcp"]
}
}
}[mcp_servers.pymol]
command = "/absolute/path/to/conda/envs/pymol-mcp/bin/python"
args = ["-m", "pymol_mcp"]Prefer not to hardcode a path? Use "command": "conda", "args": ["run", "-n", "pymol-mcp", "python", "-m", "pymol_mcp"] instead (requires conda on the client's PATH). See llms-install.md for a full from-scratch setup.
To enable the opt-in scripting tools, add "env": {"PYMOL_MCP_ALLOW_CODE_EXEC": "1"} to the server entry.
Then ask your agent things like:
Load ./hydrate.gro, color water by F4 order parameter, and render it.
Load md.gro + traj.xtc, show CO2 guests as spheres, render frame 50.
What's the mean H-bond coordination of the water in this structure?
Load tests/fixtures/hydrate_sII.gro, identify and mark cages, hide the waters, set orthographic projection, and render.Tool Catalog
Group | Tools |
Session / IO |
|
Selection |
|
Representation |
|
View / Render |
|
Measurement |
|
Trajectory / MD |
|
Clathrate domain |
|
Scripting (opt-in) |
|
PyMOLWiki Ray styles
render_image accepts a fixed ray_style profile. If you omit it, the tool uses pymolwiki_outline.
Use ray_style="default" explicitly to preserve the current PyMOL settings.
Profile | PyMOL setting | Use |
| unchanged | Preserve the current scene style |
|
| Color with black outlines |
|
| Black-and-white outline mode |
|
| Quantized color with black outlines |
The PyMOLWiki profiles set antialiasing to 2. They use the built-in PyMOL ray tracer. They restore the previous ray settings after each render. Set a white background for the closest match to the PyMOLWiki examples.
set_projection switches the camera between orthographic (parallel cage edges, typical publication lattice) and perspective. PyMOL's default field of view is 20°; raise it (e.g. 40) to make depth obvious. save_file writes a PNG/PDB/PSE to disk and creates missing parent directories. list_objects includes CGO overlays such as cages and chill_plus.
{
"selection": "all",
"width": 1600,
"height": 1200,
"ray_style": "pymolwiki_color"
}Domain: clathrate-hydrate science
Ported from a validated Rust reference implementation and re-checked against ground truth. All analysis runs in
nanometres with a correct fractional-coordinate minimum-image convention (orthorhombic and triclinic),
a signed atan2 dihedral for F4, and a periodic-image KDTree for neighbour search.
identify_cages— full TRACE cage perception: ring finding → geometric validation → constraint-propagation assembly → Euler (SEC) validation → face-count typing (5¹², 5¹²6², 5¹²6⁴, …) and an sI/sII/sH structure call.cage_occupancy— assign guest molecules (CO₂/CH₄) to cages and report per-type occupancy (θ_S, θ_L). Guests are detected only from residue names containingCO2,CH4, orMETH(carbon atom). The bundledtests/fixtures/hydrate_sI.grois TIP4P water only, so occupancy is zero there.mark_cages— draw each cage as a wireframe polyhedron (CGO objectcages): cylinders on O–O edges and spheres at oxygen vertices, colored by type (5¹² cyan, 5¹²6² violet, 5¹²6⁴ red, 5¹²6⁸ blue, 4³5⁶6³ lime). Hide the water object, thenrender_imageorsave_file.mark_cagesgeometry defaults — use a bold 0.18 Å cage edge radius and a 0.38 Å vertex radius by default. Passedge_radiusorvertex_radiusto override them.cage_typesdraws a subset (e.g.["5^12 6^8"]). Cages that wrap the periodic box can appear as fragments; that is a drawing limit, not a miscount.order_parameter— F4 (torsional) and F3 (three-body angular). F4 ≈ 0.7–0.95 → hydrate, ≈ 0 → liquid, ≈ −0.4 → ice Ih.hbond_network— water H-bond graph (O–O ≤ 0.36 nm and a donor H–O···O angle < 35°) with coordination stats.chill_plus— classify each water as liquid, ice, or hydrate with the CHILL+ q3 bond correlation method. It returns six class counts, per-water classes, fractions, and the unique O–O network. The default cutoff is 0.35 nm. Thestateargument uses one-based PyMOL states and defaults to 1.mark_chill_plus— draw the non-liquid CHILL+ O–O network as a color-coded CGO overlay namedchill_plusforrender_image. It uses the same one-basedstateargument.Performance —
chill_plususes a sparse cell list for orthorhombic cells, including 90° angle roundoff within a scale-aware machine-precision tolerance. It keeps the canonical MIC distance check. It uses a bounded-temporary-memory O(n²) fallback for real tilts. Adjacency and edge outputs still scale with the edge count. Large triclinic systems need a separate benchmark.
Validated against ground truth: on a structure II reference, identify_cages finds exactly **128 × 5¹²
64 × 5¹²6⁴** cages (the textbook 2:1 sII lattice), on structure I exactly 16 × 5¹² + 48 × 5¹²6², and on structure H 48 × 5¹² + 32 × 4³5⁶6³ + 16 × 5¹²6⁸ (16 unit cells); F4 over the first ten waters reproduces the reference value 0.926698 exactly, F3 = 0.0028 (hydrate-like ≤ 0.04), and the H-bond network is a perfect tetrahedral (mean coordination 4.00) framework.
A typical cage figure, exercised through the MCP tools:
load_structure tests/fixtures/hydrate_sII.gro (object sII)
identify_cages → structure_type sII
mark_cages → CGO object "cages"
hide water representation
set_projection orthographic (or perspective, field_of_view=40)
set_background white
render_image / save_file path.png
reset_session before the next structureHow it works
MCP client (Claude · Codex · Gemini …)
│ stdio JSON-RPC
▼
┌───────────────────────────────────────────────┐
│ pymol-mcp (FastMCP, conda env with pymol2) │
│ • permanent stdout redirect (protocol-safe) │
│ • ONE worker thread owns + drives pymol2 │
│ • typed @mcp.tool functions │
└───────────────────────────────────────────────┘
│ cmd.* (headless) │ numpy / scipy (nm)
▼ ▼
PyMOL 3.x ── ray → PNG analysis/ (hbond, F3/F4)
coords via iterate_stateRequirements
Dependency | Required | Purpose |
Python 3.11+ (conda) | Yes | Runtime that can |
| Yes | The visualization engine (conda) |
| Yes | MCP server + analysis |
| No (extra | LAMMPS / NetCDF / xtc bridge (GPL-2.0+) |
| No | Movie export (future) |
Contributing
Issues and PRs welcome — see CONTRIBUTING.md.
License
MIT. The optional md extra pulls MDAnalysis (GPL-2.0-or-later), imported lazily; the core
package stays MIT.
Available Tools
32 toolsalignAlignB
Sequence-align and superpose mobile onto target (use for different structures).
Inputs: mobile (required), target (required). Returns: object
cage_occupancyCage OccupancyC
Compute clathrate cage occupancy: assign guest molecules to detected cages (one per cage).
Inputs: box, selection, object_name, guest_selection. Returns: object
chill_plusChill PlusA
Classify water molecules as liquid, ice, or hydrate with CHILL+.
The result contains the six class counts, per-water classes, fractions, and the unique O-O cutoff network in water input order.
Inputs: box, state, cutoff_nm, selection, +1 more. Returns: object
colorColorC
Color a selection.
Inputs: color (required), selection. Returns: result
fetch_pdbFetch PdbA
Fetch a structure from the RCSB PDB (requires network) and load it.
Inputs: code (required), object_name. Returns: object
get_object_infoGet Object InfoB
Return atom count, state count, and chains for a loaded object.
Inputs: name (required). Returns: object
get_selection_infoGet Selection InfoB
Summarize a selection: atom count, chains, and residue names present.
Inputs: selection. Returns: object
hbond_networkHbond NetworkA
Build the water hydrogen-bond network and report coordination statistics.
A well-formed clathrate framework has ~4 H-bonds per water (tetrahedral).
Inputs: box, rcut_nm, angle_deg, selection, +1 more. Returns: object
hideHideC
Hide a representation for a selection.
Inputs: selection, representation. Returns: result
identify_cagesIdentify CagesA
Identify clathrate cages (TRACE): ring perception -> cage assembly -> face-count typing.
Returns per-type cage counts (5^12, 5^12 6^2, 5^12 6^4, ...) and the overall structure (sI / sII / sH). Validated: sII -> 128x 5^12 + 64x 5^12 6^4; sI -> 16x 5^12 + 48x 5^12 6^2.
Inputs: box, rcut_nm, angle_deg, selection, +1 more. Returns: object
list_objectsList ObjectsA
List all loaded object names in the current PyMOL session.
Inputs: no named parameters. Returns: result
load_structureLoad StructureA
Load a molecular structure or single-frame coordinate file into PyMOL.
Returns the created object name and its atom/state counts.
Inputs: path (required), object_name. Returns: object
load_trajectoryLoad TrajectoryA
Load a GROMACS/DCD trajectory: load the structure, then append frames as states.
Requires matching atom count/order (trjconv strip/reorder is the common pitfall).
Inputs: structure_path (required), trajectory_path (required), stop, start, +2 more. Returns: object
load_trajectory_mdaLoad Trajectory MdaA
Load any MDAnalysis-readable trajectory (LAMMPS dump, AMBER NetCDF, ...) by injecting
coordinates into PyMOL states. Requires the optional md extra (MDAnalysis).
Inputs: trajectory_path (required), max_frames, length_unit, object_name, +3 more. Returns: object
mark_cagesMark CagesA
Draw each detected cage as a wireframe polyhedron — cylinders along the O-O ring edges
plus spheres at the water-oxygen vertices, colored by cage type (5^12=cyan, 5^12 6^2=violet,
5^12 6^4=red, ...). Builds a single CGO object named cages for render_image.
Inputs: box, selection, cage_types, edge_radius, +2 more. Returns: object
mark_chill_plusMark Chill PlusC
Draw the classified CHILL+ O-O network as a colored CGO object named chill_plus.
Inputs: box, state, cutoff_nm, selection, +3 more. Returns: object
measure_angleMeasure AngleA
Measure the angle (degrees) defined by three single-atom selections.
Inputs: atom1 (required), atom2 (required), atom3 (required). Returns: object
measure_dihedralMeasure DihedralB
Measure the dihedral (degrees) defined by four single-atom selections.
Inputs: atom1 (required), atom2 (required), atom3 (required), atom4 (required). Returns: object
measure_distanceMeasure DistanceA
Measure the distance (Angstroms) between two single-atom selections.
Inputs: atom1 (required), atom2 (required). Returns: object
order_parameterOrder ParameterA
Compute the F3 or F4 water order parameter for a clathrate-hydrate system.
F4 ~ 0.7-0.95 = hydrate, ~0 = liquid, ~ -0.4 = ice Ih. F3 <= 0.04 = hydrate-like.
Inputs: box, kind, selection, object_name. Returns: object
orientOrientB
Orient the camera along the principal axes of a selection.
Inputs: selection. Returns: result
render_imageRender ImageB
Ray-trace the current scene to a PNG and return it inline.
Inputs: zoom, width, height, ray_style, +1 more.
reset_sessionReset SessionA
Reinitialize PyMOL, clearing all objects, selections, and settings.
Inputs: no named parameters. Returns: result
run_pmlRun PmlA
[opt-in] Execute raw PyMOL command-language statements. Requires PYMOL_MCP_ALLOW_CODE_EXEC=1.
Inputs: command (required). Returns: result
run_pythonRun PythonA
[opt-in] Execute a Python snippet with PyMOL cmd in scope. Requires PYMOL_MCP_ALLOW_CODE_EXEC=1.
Inputs: code (required). Returns: result
save_fileSave FileC
Save a selection/session to a file (format from extension).
Inputs: path (required), state, selection. Returns: object
selectSelectB
Create a named selection and return how many atoms it matched.
Inputs: name (required), selection (required). Returns: object
set_backgroundSet BackgroundB
Set the render background color.
Inputs: color. Returns: result
showShowB
Show (or exclusively set with only=True) a molecular representation for a selection.
Inputs: representation (required), only, selection. Returns: result
spectrumSpectrumC
Color a selection along a spectrum of a per-atom expression (e.g. B-factor).
Inputs: palette, selection, expression. Returns: result
turnTurnB
Rotate the camera about an axis.
Inputs: axis (required), angle. Returns: result
zoomZoomC
Zoom the camera onto a selection.
Inputs: buffer, selection. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 32 tools
Most tools target a clearly distinct action+resource (measure_*, show/hide/color/spectrum, camera/*, analysis tools). A few boundaries soften: run_pml vs run_python (both code execution, though distinct languages and both opt-in), and the cage trio (identify_cages analyzes, mark_cages visualizes, cage_occupancy assigns guests) requires reading descriptions to separate, but they are genuinely different operations.
All names are consistently snake_case with no camelCase mixing, and most follow a readable verb_noun or verb pattern (render_image, set_background, measure_distance, load_trajectory). A handful are bare verbs or nouns (color, spectrum, orient, zoom, hide, chill_plus, order_parameter), a minor deviation from the dominant verb_noun convention but still predictable and readable.
32 tools is on the heavy side for a single PyMOL server and pushes past the typical 3-15 comfort band. The surface is genuinely broad (rendering, camera, selection, measurement, four loaders, and six hydrate-analysis tools), so many tools earn their place, but the count feels somewhat inflated with narrow one-purpose tools.
The surface covers a full lifecycle: loading (structure, PDB fetch, two trajectory loaders), inspection, selection, representation, coloring, camera control, measurement, alignment, saving, rendering, and deep hydrate analysis. Minor gaps exist (no explicit delete/remove object beyond reset_session, no frame-stepping tool for trajectories), but these are workable around.
Maintenance
Related MCP Connectors
MD workbench for agents: 13 analysis tools, renders, hosted GPU runs; LAMMPS + OpenMM.
Three ML interatomic potentials check a molecule: trust (Beta-posterior score, 90% CI) or DFT.
Thermodynamic properties and cycles with CoolProp: fluid states, refrigeration, Rankine, Brayton.
Agent-to-Agent (A2A) + Model Context Protocol (MCP) hub for peptides.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceA Model Context Protocol server that enables AI assistants to interact with LAMMPS for molecular dynamics simulations through natural language commands.13Apache 2.0
- FlicenseNot gradedqualityDmaintenanceEnables control of VMD2 for molecular dynamics analysis through natural language, allowing users to load structures, set representations, measure distances, compute RMSD, and render images without Tcl scripting.7-
- AlicenseNot gradedqualityCmaintenanceIntegrates GROMACS molecular dynamics simulations with VMD visualization, enabling setup, execution, analysis, and 3D visualization of molecular dynamics workflows through natural language.24MIT
- AlicenseAqualityDmaintenanceDrive VMD headlessly from any MCP client to analyze structures and trajectories, and ray-trace publication-quality images with no display.12MIT