Skip to main content
Glama
kdursunnizam-art

RELION MCP Server

README.md
# RELION MCP Server v3

An MCP (Model Context Protocol) server that lets AI agents drive [RELION 5.x](https://github.com/3dem/relion) — the gold-standard software for cryo-EM structure determination.

> **Tested and verified** against RELION 5.0.1 on Ubuntu 24.04 (WSL2). All CLI flags validated against actual `--help` output.

## What It Does

An AI agent (Claude Code, OpenClaw, NemoClaw, etc.) can process cryo-EM data through natural language:

```
You: "Import the movies from Movies/*.tiff, 200 kV, pixel size 0.885 Å, then run motion correction"
Agent: → relion_import(..., confirm=False)  → shows parameter preview
You: "Looks good, launch it"
Agent: → relion_import(..., confirm=True)   → job runs (instant)
       → relion_motioncorr(..., confirm=False) → preview
You: "Ok go"
Agent: → relion_motioncorr(..., confirm=True) → 🚀 Launched (PID 12345)
       → relion_job_status("MotionCorr/job001") → 🔄 RUNNING
       → relion_job_status("MotionCorr/job001") → ✅ COMPLETED
```

The server exposes **42 tools** covering the complete single-particle analysis pipeline, the RELION 5 tomography (subtomogram-averaging) pipeline, results-interpretation tools that let an agent make its own decisions, and STAR/image utilities.

## Key Features

### 1. Preview Before Launch
Every pipeline tool: `confirm=False` shows all parameters (✏️ user / 📋 tutorial default / ❌ missing / ⬜ optional), `confirm=True` launches the job.

### 2. Non-Blocking Background Execution
All long-running jobs launch via detached `Popen` and return immediately with PID. Monitor with `relion_job_status` and `relion_job_logs`.

### 3. GPU Support
Class2D, InitialModel, Class3D, and Refine3D all expose `--gpu` for GPU acceleration.

### 4. Blush Regularisation
RELION 5's neural-network prior is available on Class3D and Refine3D via `use_blush=True`.

### 5. VDAM Algorithm
Class2D and InitialModel support the VDAM gradient algorithm via `use_vdam=True`, with MPI=1 validation.

### 6. Live Flag Discovery
`relion_help` runs `relion_* --help` in real time with keyword filtering.

### 7. RELION GUI Integration
Every launched job is registered in the project's `default_pipeline.star` — with the correct RELION 5 process/node type labels, live status, and input/output edges — so a project driven by this server opens cleanly in the RELION GUI with a connected job graph. Best-effort and atomic; disable with `RELION_WRITE_PIPELINE=0`.

### 8. Tomography (Subtomogram Averaging)
The full RELION 5 STA numerical pipeline — import tilt series, reconstruct tomograms, extract pseudo-subtomograms, reconstruct particle, tomo CTF-refine and frame-align — is exposed as dedicated `relion_tomo_*` tools that build on the tomography optimisation-set data model and register with the correct tomo pipeline labels.

### 9. Results-Driven Decisions
Instead of forcing the agent to hand-parse STAR files, `relion_job_results` returns the metrics that actually drive the next decision (resolution, ranked class distributions), `relion_select_classes` acts on them numerically, and `relion_render_classes` lets a vision-capable agent *see* the 2D classes. Failed jobs come back with an actionable hint rather than a raw traceback.

## Architecture

```
AI Agent (Claude Code / OpenClaw / NemoClaw)
    │
    │  stdio or HTTP
    ▼
RELION MCP Server v3 (Python)
    │
    │  Popen (detached)        subprocess.run (short jobs)
    ▼                          ▼
RELION 5.x binaries        relion_import, relion_help
(background, non-blocking)  (synchronous, fast)
```

## Tools

### Pipeline Tools (17 tools — all with preview/confirm)

| Tool | Binary |
|------|--------|
| `relion_import` | `relion_import` |
| `relion_motioncorr` | `relion_run_motioncorr` |
| `relion_ctffind` | `relion_run_ctffind` |
| `relion_autopick` | `relion_autopick` |
| `relion_extract` | `relion_preprocess` |
| `relion_class2d` | `relion_refine` |
| `relion_select` | `relion_class_ranker` |
| `relion_initial_model` | `relion_refine --denovo_3dref` |
| `relion_class3d` | `relion_refine` |
| `relion_refine3d` | `relion_refine` |
| `relion_mask_create` | `relion_mask_create` |
| `relion_postprocess` | `relion_postprocess` |
| `relion_ctf_refine` | `relion_ctf_refine` |
| `relion_bayesian_polishing` | `relion_motion_refine` |
| `relion_blush` | `relion_python_blush` |
| `relion_local_resolution` | `relion_postprocess --locres` |
| `relion_modelangelo` | `relion_python_modelangelo` |

### Read-Only Tools (7 tools)

| Tool | Description |
|------|-------------|
| `relion_project_info` | Project overview |
| `relion_read_star` | Parse STAR files (multi-block aware) |
| `relion_job_status` | Job status + PID detection + stderr tail |
| `relion_job_logs` | Read stdout/stderr from background jobs |
| `relion_suggest_next_step` | Recommend next step (15-step pipeline) |
| `relion_run_command` | Run any `relion_*` binary (escape hatch) |
| `relion_help` | Parse `--help` output from any RELION binary |

### Control & Task Tools (2 tools)

| Tool | Description |
|------|-------------|
| `relion_wait_for_job` | Wait for a background job to finish and return its final status **plus** its metrics. Declared as an MCP **task** |
| `relion_abort` | Stop a running background job (`RELION_JOB_ABORT_NOW` + SIGTERM to the process group) |

### Tomography / STA Tools (8 tools — all with preview/confirm)

Based on the [RELION 5 subtomogram-averaging tutorial](https://relion.readthedocs.io/en/release-5.0/STA_tutorial/index.html). 3D refinement/classification of the pseudo-subtomograms reuses the existing `relion_class3d` / `relion_refine3d` tools.

| Tool | Binary |
|------|--------|
| `relion_tomo_import` | `relion_tomo_import_tomograms` |
| `relion_tomo_import_coords` | `relion_tomo_import_particles` |
| `relion_tomo_reconstruct_tomogram` | `relion_tomo_reconstruct_tomogram` |
| `relion_tomo_subtomo` | `relion_tomo_subtomo` (make pseudo-subtomograms) |
| `relion_tomo_reconstruct_particle` | `relion_tomo_reconstruct_particle` |
| `relion_tomo_ctf_refine` | `relion_tomo_refine_ctf` |
| `relion_tomo_align` | `relion_tomo_align` (frame align / Bayesian polishing) |
| `relion_tomo_suggest_next_step` | (read-only) STA pipeline progress |

> **Tilt-series alignment** (AreTomo2/IMOD), **denoising** (cryoCARE) and **template-match picking** are external-tool steps in RELION 5 and are not wrapped as dedicated tools — run them with their native tools or via `relion_run_command`. The RELION-native numerical path (import → reconstruct particle, plus tomo CTF-refine and frame-align) is fully covered.
>
> Tomo flags are taken from the RELION 5 reference docs (generated from each program's `--help`) but were not validated against a live binary; verify with `relion_help(program="relion_tomo_…")` on your build if a run fails.

### Results & Decision Tools (3 tools)

Turn the agent from a blind operator into a decision-maker: read metrics and select classes without hand-parsing STAR files.

| Tool | Description |
|------|-------------|
| `relion_job_results` | Auto-detect job type and return key metrics — PostProcess resolution + B-factor, Refine3D current resolution, **Class2D/3D per-class distribution & estimated resolution (ranked)**, CtfFind/MotionCorr stats |
| `relion_select_classes` | Select 2D/3D classes by **numeric** criteria (`rlnClassDistribution` ≥, `rlnEstimatedResolution` ≤, or explicit list) and write a particles.star — deterministic complement to `relion_select` |
| `relion_render_classes` | Render a `.mrcs` class-averages stack as a PNG montage returned inline, so a vision-capable agent can *see* which classes are good (needs `numpy` + `pillow`) |

### Utility Tools (5 tools)

| Tool | Binary |
|------|--------|
| `relion_star_handler` | `relion_star_handler` (select/filter/join/drop columns) |
| `relion_image_handler` | `relion_image_handler` (rescale, resize, low/high-pass, B-factor) |
| `relion_subtract` | `relion_particle_subtract` (partial signal subtraction) |
| `relion_symmetry_expand` | `relion_particle_symmetry_expand` |
| `relion_tomo_latest_optimisation_set` | (read-only) locate the newest tomo `optimisation_set.star` |

Also: `relion_read_star` now has a `summary=true` mode returning per-column count/min/mean/max instead of dumping rows, and job errors come with an actionable **Hint** (out-of-memory, GPU, missing path, MPI, STAR-label, binary-not-found).

## Tutorial Defaults (EMPIAR-10204)

All defaults match the RELION 5 beta-galactosidase tutorial:

| Step | Key defaults |
|------|-------------|
| Import | 200 kV, 0.885 Å, Cs 1.4, Q0 0.1 |
| MotionCorr | dose 1.277, patches 5×5, bfactor 150, float16, save_ps |
| CTF | Box 512, 30-5 Å, dF 5000-50000, dAst 100, **use_given_ps=True** |
| AutoPick | LoG, 150-180 Å, **upper_threshold=5**, maxres=20 |
| Extract | box 256 → 64, invert, bg_radius 200 |
| Class2D | K=50, T=2, mask 200, CTF, center |
| InitialModel | VDAM 100 mini-batches, T=4, C1 + apply_sym_later |
| Class3D | K=4, T=4, C1, ini_high 50, healpix 2 |
| Refine3D | D2, ini_high 50, MPI=3 (odd≥3), pool 30 |
| Mask | lowpass 15, **threshold 0.01, extend 3, soft_edge 8** |
| PostProcess | auto B-factor, autob_lowres 10 |
| CTF Refine | All flags off by default (multi-pass workflow) |
| Polishing | Train/Polish modes, sigma vel/div/acc, float16 |

## Prerequisites

- **RELION 5.x** compiled and in `PATH`
- **Python ≥ 3.10**
- **FastMCP** and dependencies (see `requirements.txt`):
  ```bash
  pip install -r requirements.txt
  ```
  - fastmcp >= 3.0 (bundles the `mcp` SDK and uvicorn for HTTP mode)
  - pydantic >= 2.0.0

## Installation

```bash
git clone https://github.com/kdursunnizam-art/relion-mcp-server.git
cd relion-mcp-server
pip install -r requirements.txt
```

Optionally, use a virtual environment (recommended for HTTP mode):

```bash
cd relion-mcp-server
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```

## Usage

### With Claude Code (recommended for local use)

#### stdio (local)
From your terminal:
```bash
claude mcp add-json relion '{"command":"python3","args":["/path/to/relion-mcp-server/relion_mcp.py"],"env":{"RELION_PROJECT_DIR":"/path/to/data/relion_tutorial"}}' --scope user
```
Verify:
```bash
claude mcp list
```
Remove / reconfigure:
```bash
claude mcp remove relion
```
Note: `--scope user` makes the server available in all your projects.

#### HTTP (remote) — EXPERIMENTAL

1. Start the server manually in a terminal:
```bash
cd /path/to/relion-mcp-server
source venv/bin/activate
export RELION_PROJECT_DIR=/path/to/data/relion_tutorial
python relion_mcp.py --transport http --port 8000 --host 0.0.0.0
```
Keep this terminal open.

2. Register the running server with Claude Code:
```bash
claude mcp add --transport http relion http://YOUR.IP.ADDRESS:8000/mcp --scope user
```

3. Verify:
```bash
claude mcp list
```
It should show `relion` with the HTTP transport and URL `http://YOUR.IP.ADDRESS:8000/mcp`.

Then in Claude Code:
```
> Use relion_project_info to show the project status
> Import movies from Movies/*.tiff with pixel size 0.885, 200 kV, Cs 1.4
> Run motion correction with dose 1.277 e-/Ų/frame and gain ref Movies/gain.mrc
> Show me the Class2D parameters before running (agent calls with confirm=False)
> Change threads to 8 and launch (agent calls with confirm=True)
```

### With Claude Desktop

Claude Desktop only supports stdio servers via manual config. Edit `claude_desktop_config.json`:
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "relion": {
      "command": "python3",
      "args": ["/path/to/relion-mcp-server/relion_mcp.py"],
      "env": {
        "RELION_PROJECT_DIR": "/path/to/data/projet_relion",
        "RELION_THREADS": "4",
        "RELION_MPI": "1"
      }
    }
  }
}
```

On Windows with WSL2, set `"command": "wsl"` and prepend `python3` to `args`:
```json
{
  "mcpServers": {
    "relion": {
      "command": "wsl",
      "args": ["python3", "/home/you/relion-mcp-server/relion_mcp.py"],
      "env": { "RELION_PROJECT_DIR": "/home/you/relion_tutorial" }
    }
  }
}
```
Restart Claude Desktop after editing the config.

### With OpenClaw / NemoClaw

#### stdio (local)
```bash
openclaw mcp add --transport stdio --scope user relion --cmd python3 --args "/path/to/relion-mcp-server/relion_mcp.py" --env RELION_PROJECT_DIR="/path/to/data/relion_tutorial"
```
Verify:
```bash
openclaw mcp list
```

#### HTTP (remote)
Start the server:
```bash
cd /path/to/relion-mcp-server
source venv/bin/activate
export RELION_PROJECT_DIR=/data/my_project
python relion_mcp.py --transport http --port 8000 --host 0.0.0.0
```
Register:
```bash
openclaw mcp add --transport http --scope user relion http://YOUR.IP.ADDRESS:8000/mcp
```

Or configure `openclaw.json` manually (both stdio and HTTP):
```json
{
  "skills": {
    "install": { "nodeManager": "npm" },
    "entries": {
      "mcp-integration": {
        "enabled": true,
        "config": {
          "servers": [
            {
              "name": "relion-stdio",
              "transport": "stdio",
              "command": "python3",
              "args": ["/path/to/relion-mcp-server/relion_mcp.py"],
              "env": { "RELION_PROJECT_DIR": "/path/to/data/projet_relion" }
            },
            {
              "name": "relion-http",
              "transport": "streamable-http",
              "url": "http://YOUR.IP.ADDRESS:8000/mcp"
            }
          ],
          "toolPrefix": true
        }
      }
    }
  }
}
```

## Configuration

| Environment Variable | Description | Default |
|---------------------|-------------|---------|
| `RELION_PROJECT_DIR` | RELION project directory | Current directory |
| `RELION_BIN` | Path prefix for RELION binaries | (uses PATH) |
| `RELION_THREADS` | Default thread count | 4 |
| `RELION_MPI` | Default MPI processes | 1 |
| `RELION_CONFINE_PATHS` | If `1`, reject any file path that resolves outside the project dir | 0 (off) |
| `RELION_WRITE_PIPELINE` | If `1`, register jobs in `default_pipeline.star` for RELION GUI integration | 1 (on) |

| CLI Flag | Description | Default |
|----------|-------------|---------|
| `--transport` | `stdio` or `http` | `stdio` |
| `--port` | HTTP port | 8000 |
| `--host` | HTTP host (use `0.0.0.0` for remote access) | 127.0.0.1 |
| `--project-dir` | Override `RELION_PROJECT_DIR` | (env or cwd) |

## Security

- Only `relion_*` executables can be run (validated)
- No shell injection: synchronous calls use `subprocess.run` with an argument list (no `shell=True`). Background jobs run through a generated `run.sh`, but **every argument and path is escaped with `shlex.quote`**, so filenames containing spaces or shell metacharacters are passed literally and can never be executed.
- File paths are resolved relative to the project directory. Set `RELION_CONFINE_PATHS=1` to additionally reject any path that resolves *outside* the project directory (off by default, since raw movies/gain refs often live on a separate scratch disk).
- **HTTP mode is unauthenticated.** It binds to `127.0.0.1` by default. For remote access set `--host 0.0.0.0` — the server then prints a warning, because this exposes tools that can launch RELION binaries (including `relion_run_command`). Only do this on a trusted, firewalled network, ideally behind an authenticating reverse proxy.
- Preview/confirm prevents accidental job launches; `relion_abort` can stop a running job.

## Framework: FastMCP 4 (MCP spec 2026-07-28)

Built on **standalone [FastMCP](https://github.com/PrefectHQ/fastmcp) 4.x** (`fastmcp[tasks]>=4.0`), which targets the current **MCP specification 2026-07-28** (stateless core, extensions framework).

- Import: `from fastmcp import FastMCP`.
- Every tool declares a human-readable `title` alongside its machine `name`.
- `relion_job_results` returns **structured output** (`structuredContent` + `outputSchema`).
- Long-running tools (`relion_wait_for_job`, `relion_run_command`, `relion_import`) use the
  **`io.modelcontextprotocol/tasks` extension**: the client receives a durable task handle and
  polls `tasks/get` instead of holding a request open for hours. Requires the `[tasks]` extra;
  without it those tools degrade to ordinary blocking calls.
- Deprecated MCP features (Roots, Sampling, Logging, HTTP+SSE) are **not** used.
- Server is launched with `mcp.run(transport="stdio")` or `mcp.run(transport="streamable-http", host=..., port=...)`.
- All tool functions are `async` and take a single Pydantic model parameter; FastMCP builds the JSON schema from it.
- Passes `python3 -m py_compile` cleanly and the `tests/` suite (`pytest`).

> Migrated from the FastMCP **1.x** bundled inside the official `mcp` SDK (`mcp.server.fastmcp`). That module was removed when the official SDK reached 2.0 (renamed to `MCPServer`), so this server now depends on the standalone package instead.

## Changelog

### v3.5 (current) — MCP 2026-07-28
- **Upgraded to FastMCP 4.x**, targeting MCP specification **2026-07-28** (was 2025-11-25).
- **Tool `title`** added to all 42 tools (human-readable label distinct from the machine `name`).
- **Structured output:** `relion_job_results` now returns `structuredContent` with an
  `outputSchema` instead of a Markdown string.
- **MCP Tasks extension** (`io.modelcontextprotocol/tasks`) enabled, plus a new
  `relion_wait_for_job` tool — the natural fit for refinements that run for hours.
- Verified that no deprecated MCP feature (Roots, Sampling, Logging, HTTP+SSE) is used.

### v3.4
- **Agentic decision loop (P1):** `relion_job_results` (auto-detecting metrics extractor: resolution, per-class distribution/estimated-resolution ranking, CTF/motion stats), `relion_select_classes` (deterministic numeric class selection → particles.star), and `relion_render_classes` (2D class-average montage returned as an inline image).
- **Coverage (P2):** `relion_star_handler`, `relion_image_handler`, `relion_subtract` (signal subtraction), `relion_symmetry_expand`.
- **Polish (P3):** actionable error **Hints** on failed jobs (out-of-memory / GPU / missing path / MPI / STAR-label / binary), `relion_read_star` `summary` mode (per-column stats), and `relion_tomo_latest_optimisation_set`.
- 41 tools total. Optional deps `numpy` + `pillow` (only for `relion_render_classes`).

### v3.3
- **Tomography (STA) pipeline added — 8 new tools** (`relion_tomo_import`, `relion_tomo_import_coords`, `relion_tomo_reconstruct_tomogram`, `relion_tomo_subtomo`, `relion_tomo_reconstruct_particle`, `relion_tomo_ctf_refine`, `relion_tomo_align`, `relion_tomo_suggest_next_step`), following the RELION 5 subtomogram-averaging tutorial. Flags taken from the RELION 5 reference docs.
- **Pipeline node-rules re-keyed by process label** (not directory), so the directories shared between SPA and tomo (Import, Extract, CtfRefine, Polish, Reconstruct) register with the correct type/node labels for each. Full `default_pipeline.star` integration with authoritative tomo labels (`relion.importtomo`, `relion.pseudosubtomo`, `relion.ctfrefinetomo`, `relion.framealigntomo`, …). 33 tools total.

### v3.2
- **Migrated to standalone FastMCP 3.x** (`from fastmcp import FastMCP`, `fastmcp>=3.0`) — the actively-developed, community-standard framework — replacing the FastMCP 1.x bundled in the official `mcp` SDK (removed in SDK 2.0). Tool schemas, annotations and behaviour are unchanged; host/port are now passed to `mcp.run(...)`.

### v3.1
- **Security fix — background jobs:** `run.sh` is now generated with `shlex.join`/`shlex.quote`, closing a shell-injection hole and fixing jobs breaking on paths/filenames containing spaces.
- **Bug fix — STAR parser:** `relion_read_star` now parses all data blocks and selects the correct one (auto-picks the main table, or an explicit `data_particles`/`particles`). Previously it merged `data_optics` + `data_particles` and returned garbage on standard particle files.
- **RELION GUI integration:** every job is now registered in the project's `default_pipeline.star` (processes, nodes, input/output edges) so jobs created by this server appear — correctly typed, connected, and status-tracked — when the project is opened in the RELION GUI. Label strings are taken verbatim from RELION 5 `src/pipeline_jobs.h`. Writes are atomic (`.bak` kept), merge-safe with existing pipelines, and best-effort (never block a launch). Toggle with `RELION_WRITE_PIPELINE=0`.
- **Global job numbering:** job directories now share one counter across all job types (`job001`, `job002`, …), matching RELION's own scheme.
- **New tools:** `relion_select` (auto class selection via `relion_class_ranker`) and `relion_abort` (stop a running job).
- **Hardening:** optional `RELION_CONFINE_PATHS`, PID-file based liveness (no more `pgrep`), unauthenticated-HTTP warning on non-local bind.
- **Cleanup:** removed a dead validator, standardised runtime messages to English, pinned `mcp>=1.26,<2.0`, added a `pytest` suite. 25 tools total.

### v3
- 68 missing params added, 11 defaults fixed, 3 MPI validations
- **GPU support** (`--gpu`) on Class2D, InitialModel, Class3D, Refine3D
- **Blush** on Class3D, Refine3D
- **VDAM** on Class2D, InitialModel (with MPI=1 validation)
- **Polishing fully rewritten**: train/polish modes, sigma params, opt_params
- **Compute params** factored: `--pool`, `--preread_images`, `--scratch_dir`, `--skip_padding`
- **2 new tools**: `relion_local_resolution`, `relion_modelangelo`
- **CTF Refine** fixed: +beamtilt, +fit_phase, +minres, defaults all False
- **Mask Create** defaults fixed to match tutorial
- **HTTP host/port** now correctly applied from CLI flags
- 23 tools total

### v2.1
- **Background execution**: long-running jobs launch via `Popen(start_new_session=True)` and return immediately with PID. No more agent blocking.
- **`relion_job_logs`**: read stdout/stderr from background jobs in real time
- **`relion_job_status` enhanced**: PID liveness detection, stderr tail on failure, RUNNING vs IDLE
- **`relion_help`**: run `relion_* --help` and parse all flags live, with keyword filtering
- Wrapper script (`run.sh`) in each job_dir auto-creates SUCCESS/FAILURE markers
- 21 tools total

### v2.0
- **Preview/confirm system** on all pipeline tools
- **5 new tools**: `relion_initial_model`, `relion_mask_create`, `relion_ctf_refine`, `relion_bayesian_polishing`, `relion_help`
- **Parameters added**: bfactor, gain_rot/flip, float16, save_ps, d_ast, phase shift, invert_contrast, white/black dust, --ctf flag, center_classes, healpix_order, skip_gridding, ref_correct_greyscale, MPI validation, autob_lowres/highres, mtf_angpix, skip_fsc_weighting
- **Tutorial defaults** from EMPIAR-10204 baked in
- 20 tools total

### v1.0
- Initial release with 15 tools
- Verified against RELION 5.0.1

## Tested With

- RELION 5.0.1 (commit cad71bf)
- Ubuntu 24.04 LTS (WSL2)
- Python 3.12, MCP SDK 1.26.0
- Claude Code 2.1.89
- OpenClaw 2026.4.2 (commit d74a122)
- Tutorial dataset: beta-galactosidase (EMPIAR-10204)

## License

MIT — RELION itself is GPLv2. This server interacts with RELION solely through its CLI.

## References

- Scheres, S.H.W. (2012). RELION: Implementation of a Bayesian approach to cryo-EM structure determination. *J. Struct. Biol.* 180(3), 519–530.
- Kimanius, D. et al. (2021). New tools for automated cryo-EM single-particle analysis in RELION-4.0. *Biochem. J.* 478(24), 4169–4185.
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [RELION Documentation](https://relion.readthedocs.io/)
- Steinberger, P. (2025). *OpenClaw: An open-source autonomous AI agent* (Version 2026.x.x) [Computer software]. GitHub. https://github.com/openclaw/openclaw