Skip to main content
Glama

NOTE

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 pymol2 — no GUI, no plugin, no socket

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 .xtc/.trr + LAMMPS dump (MDAnalysis bridge)

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 (wjgoarxiv/pymol-mcp, release v0.1.0) and awesome-mcp-servers Biology (PR #9110, merged)

Features

  • Embedded & headless — one long-lived PyMOL instance on a dedicated worker thread; nothing to click, works in CI.

  • The model can see — render_image ray-traces and returns a PNG as MCP image content. Use ray_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

IMPORTANT

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 -q

It'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

load_structure · fetch_pdb · list_objects · get_object_info · reset_session

Selection

select · get_selection_info

Representation

show · hide · color · spectrum · set_background

View / Render

orient · zoom · turn · set_projection · render_image → 🖼️ inline PNG

Measurement

measure_distance · measure_angle · measure_dihedral · align · save_file

Trajectory / MD

load_trajectory (GROMACS/DCD) · load_trajectory_mda (LAMMPS/NetCDF via MDAnalysis)

Clathrate domain

identify_cages (TRACE) · cage_occupancy · mark_cages · hbond_network · order_parameter (F3 / F4) · chill_plus · mark_chill_plus

Scripting (opt-in)

run_pml · run_python

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

default

unchanged

Preserve the current scene style

pymolwiki_outline

ray_trace_mode=1

Color with black outlines

pymolwiki_bw

ray_trace_mode=2

Black-and-white outline mode

pymolwiki_color

ray_trace_mode=3

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 containing CO2, CH4, or METH (carbon atom). The bundled tests/fixtures/hydrate_sI.gro is TIP4P water only, so occupancy is zero there.

  • mark_cages — draw each cage as a wireframe polyhedron (CGO object cages): 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, then render_image or save_file.

  • mark_cages geometry defaults — use a bold 0.18 Å cage edge radius and a 0.38 Å vertex radius by default. Pass edge_radius or vertex_radius to override them. cage_types draws 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. The state argument 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 named chill_plus for render_image. It uses the same one-based state argument.

  • Performance — chill_plus uses 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.

TIP

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 structure

How 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_state

Requirements

Dependency

Required

Purpose

Python 3.11+ (conda)

Yes

Runtime that can import pymol2

pymol-open-source 3.x

Yes

The visualization engine (conda)

fastmcp 3.x, numpy, scipy

Yes

MCP server + analysis

MDAnalysis

No (extra md)

LAMMPS / NetCDF / xtc bridge (GPL-2.0+)

ffmpeg

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 tools
alignAlignB

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

    B3.2/5.0

    Scored across 32 tools

    Disambiguation4/5

    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.

    Naming Consistency4/5

    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.

    Tool Count3/5

    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.

    Completeness4/5

    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

    ActivityStale
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      F
      maintenance
      A Model Context Protocol server that enables AI assistants to interact with LAMMPS for molecular dynamics simulations through natural language commands.
      13
      Apache 2.0
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables 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
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      Integrates GROMACS molecular dynamics simulations with VMD visualization, enabling setup, execution, analysis, and 3D visualization of molecular dynamics workflows through natural language.
      24
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Drive VMD headlessly from any MCP client to analyze structures and trajectories, and ray-trace publication-quality images with no display.
      12
      MIT