Skip to main content

Model Context Protocol server for Gatan Microscopy Suite 3.60 โ€” multimodal TEM/STEM/EELS/4D-STEM control via local LLMs

Project description

GMS-MCP ๐Ÿ”ฌ

arXiv Tests Python 3.10+ License: MIT Code style: ruff Northwestern NUANCE

A vendor-agnostic, privacy-preserving Model Context Protocol server for multimodal electron microscopy control via local large language models.

GMS-MCP connects Gatan Microscopy Suite (GMS) 3.60 to any MCP-compatible LLM โ€” running entirely on your institution's hardware, with zero cloud dependencies.


Highlights

Capability Details
Instrument API Gatan DigitalMicrograph / GMS 3.60
LLM backend Local Ollama (air-gap compatible)
Voice control Optional local push-to-talk + Whisper transcription
Data handling On-site, local-first workflow
Modalities TEM / HRTEM, STEM (HAADF/BF/ABF), 4D-STEM / NBED, EELS, diffraction
Built-in analysis Virtual BF/HAADF, CoM, DPC, radial profiles, max-FFT, filtering, maximum-spot mapping
Automation Stage control, beam/optics control, detector configuration, tilt series, persistent live-processing jobs
Validation Pydantic v2 physical-bound checks on tool inputs
Simulation Physics-plausible DMSimulator for hardware-free development
Testing 67-test suite (61 hardware-independent + 6 Ollama integration)
Transport stdio + Streamable HTTP + optional ZeroMQ live-job bridge
License MIT

Architecture

Ollama LLM (local, port 11434)
    โ†•  LangChain ReAct agent
MultiServerMCPClient
    โ†•  stdio subprocess  OR  HTTP /mcp
gms_mcp.server  (FastMCP 3.x)
    โ†•  ZeroMQ TCP bridge
DM Plugin  (inside GMS process)
    โ†•  DigitalMicrograph Python API
Microscope hardware (TEM / STEM column)

The DMSimulator activates automatically when DigitalMicrograph is unavailable, providing physics-plausible synthetic data for all five modalities โ€” enabling full development and testing without a microscope.


Quick Start

1. Install

Published release from PyPI:

# Core server only
pip install nuance-gms-mcp

# With Ollama client support
pip install "nuance-gms-mcp[ollama]"

# With local voice control (microphone + Whisper transcription)
pip install "nuance-gms-mcp[ollama,voice]"

# With ZeroMQ bridge for live GMS connection
pip install "nuance-gms-mcp[ollama,zmq]"

# Install the latest code from this repository instead of the published PyPI release
pip install "git+https://github.com/NUANCE-IT/Gatan_MCP.git"

# Full development install from a local clone
git clone https://github.com/NUANCE-IT/Gatan_MCP
cd Gatan_MCP
pip install -e ".[all]"

Use pip install nuance-gms-mcp when you want the published release from PyPI. Use pip install -e ".[all]", pip install ., or the direct GitHub URL when you want this repository's current source tree.

2. Install Ollama + pull a model

# Install Ollama: https://ollama.ai
curl -fsSL https://ollama.ai/install.sh | sh

# Pull the recommended model (best tool-calling performance)
ollama pull qwen2.5:7b

# Alternatives
ollama pull qwen2.5:14b    # higher accuracy, slower
ollama pull llama3.1:8b    # reliable, widely tested

3. Run in simulation mode (no microscope needed)

# Start the interactive microscope agent
GMS_SIMULATE=1 python -m gms_mcp.client

# Or a single non-interactive query
GMS_SIMULATE=1 python -m gms_mcp.client \
  --query "Acquire a 512ร—512 HAADF STEM image at 10 ยตs dwell time" \
  --no-interactive --verbose

3b. Run with local voice control

# Push-to-talk microphone input with local faster-whisper transcription
GMS_SIMULATE=1 python -m gms_mcp.client --voice

# Voice input plus spoken replies on macOS (uses the built-in 'say' command)
GMS_SIMULATE=1 python -m gms_mcp.client --voice --speak

# One-shot voice command, then exit
GMS_SIMULATE=1 python -m gms_mcp.client --voice --no-interactive

Voice mode records locally, transcribes locally with Whisper, and sends the resulting text transcript through the same Ollama โ†’ MCP tool-calling path as typed instructions.

4. Connect to a live GMS instance

On the microscope PC (inside GMS Python environment):

# Install ZeroMQ inside GMS virtual environment
cd C:\ProgramData\Miniconda3\envs\GMS_VENV_PYTHON
pip install pyzmq fastmcp

# Run the DM plugin inside GMS Python console
exec(open("src/gms_mcp/dm_plugin.py").read())

On any workstation (or the same PC):

# Start the HTTP server (for remote access / Claude.ai connector)
python -m gms_mcp.server --transport http --port 8000

# Or stdio for direct Ollama use
GMS_MCP_ZMQ=tcp://microscope-pc:5555 python -m gms_mcp.client

When GMS_MCP_ZMQ is set, persistent live-processing jobs are created and managed inside the DM bridge so long-running state stays aligned with the live GMS process.


Available Tools

Tool Domain Description
gms_get_microscope_state Diagnostics Read all instrument parameters
gms_get_front_image Workspace Inspect the current front-most DM image and tags
gms_acquire_tem_image Acquisition TEM / HRTEM image with exposure, binning, ROI
gms_acquire_stem Acquisition HAADF / BF / ABF STEM scan
gms_acquire_4d_stem Acquisition Full 4D-STEM / NBED dataset
gms_acquire_eels Acquisition EELS spectrum with GIF/IFC control
gms_acquire_diffraction Acquisition Electron diffraction + auto d-spacing extraction
gms_apply_image_filter Analysis Median / Gaussian filtering on the front image or ROI
gms_compute_radial_profile Analysis 1D radial profile from diffraction or HRTEM FFT
gms_compute_max_fft Analysis Max-FFT map over local windows in the front image
gms_start_live_processing_job Workflow Start a persistent live radial-profile, difference, FFT-map, filtered-view, or maximum-spot-mapping job
gms_get_live_processing_job_status Workflow Poll a live job for iterations, status, and latest summary
gms_get_live_processing_job_result Workflow Retrieve the latest derived result from a live job
gms_stop_live_processing_job Workflow Stop a live-processing job
gms_get_stage_position Stage Read X, Y, Z, ฮฑ, ฮฒ
gms_set_stage_position Stage Move stage (validated bounds)
gms_set_beam_parameters Optics Spot size, focus, beam shift/tilt, stigmators
gms_configure_detectors Detectors Insert/retract camera, CCD temp, HAADF/BF/ABF
gms_acquire_tilt_series Workflow Automated tomographic tilt series
gms_run_4dstem_analysis Analysis Virtual BF/HAADF, CoM, DPC maps
gms_run_4dstem_maximum_spot_mapping Analysis Color maximum-spot map from a 4D-STEM dataset

All tools enforce physical parameter bounds via Pydantic v2 before any hardware command is issued.


Example Session

You: What is the current microscope configuration?

Agent: [calls gms_get_microscope_state]
       The microscope is in TEM mode at 200 kV, spot size 3,
       magnification 50,000ร—. Stage at X=0, Y=0, ฮฑ=0ยฐ.
       Camera (OneView) is inserted at -25ยฐC.

You: Acquire a HAADF STEM image at 512ร—512, 10 ยตs dwell time.

Agent: [calls gms_acquire_stem with width=512, height=512, dwell_us=10.0, signals=[0]]
       Acquired 512ร—512 HAADF image. Mean intensity: 487 counts,
       max: 2341 counts. Total frame time: 2.62 s.
       Pixel calibration: 0.0196 nm/pixel.

You: Now acquire an EELS spectrum at the Ti L-edge (460 eV).

Agent: [calls gms_acquire_eels with energy_offset_eV=400.0, dispersion_idx=1]
       EELS spectrum acquired. Energy range: 400โ€“912 eV at 0.25 eV/channel.
       Ti Lโ‚‚,โ‚ƒ edge detected at 462 eV. ZLP not visible (energy offset applied).
       Recommend checking for beam damage โ€” reduce exposure if signal is sufficient.

You: Tilt to -60ยฐ and run a tilt series to +60ยฐ in 2ยฐ steps.

Agent: [calls gms_set_stage_position with alpha_deg=-60.0]
       [calls gms_acquire_tilt_series with start_deg=-60, end_deg=60, step_deg=2.0]
       Tilt series complete: 61 frames, ฮฑ = -60ยฐ to +60ยฐ, 1 s exposure each.
       Mean intensity stable across tilt range (CV = 4.2%).

Connecting to Claude.ai

  1. Start the HTTP server: python -m gms_mcp.server --transport http --port 8000
  2. Expose via HTTPS (e.g. ngrok http 8000)
  3. In Claude.ai โ†’ Settings โ†’ Connectors โ†’ Add custom connector
  4. Enter URL: https://your-ngrok-url.ngrok.io/mcp

Running Tests

# All hardware-independent tests (~18 s)
pytest tests/ -v -m "not ollama"

# Full suite including Ollama end-to-end tests
OLLAMA_MODEL=qwen2.5:7b pytest tests/ -v

# With coverage
pytest tests/ -m "not ollama" --cov=gms_mcp --cov-report=html

Test suite summary:

Class Tests Hardware required
TestDMSimulator 17 None
TestMCPServerTools 39 None
TestServerTransport 4 None
TestOllamaIntegration 6 Ollama + model

Project Structure

Gatan_MCP/
โ”œโ”€โ”€ .github/workflows/ci.yml     # lint + typecheck + test matrix + build
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ CHANGELOG.md
โ”œโ”€โ”€ CONTRIBUTING.md
โ”œโ”€โ”€ LICENSE                       # MIT, Roberto dos Reis & Vinayak P. Dravid
โ”œโ”€โ”€ README.md                     # badges, highlights, quick-start
โ”œโ”€โ”€ pyproject.toml                # packaging, ruff, mypy, pytest config
โ”œโ”€โ”€ src/gms_mcp/
โ”‚   โ”œโ”€โ”€ __init__.py               # version
โ”‚   โ”œโ”€โ”€ server.py                 # FastMCP server โ€” 21 tools
โ”‚   โ”œโ”€โ”€ simulator.py              # DMSimulator physics twin
โ”‚   โ”œโ”€โ”€ client.py                 # Ollama ReAct agent
โ”‚   โ””โ”€โ”€ dm_plugin.py              # ZeroMQ bridge with persistent live-job backend
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ conftest.py               # session fixtures, GMS_SIMULATE=1
โ”‚   โ””โ”€โ”€ test_gms_mcp.py           # 67 tests (61 hardware-free)
โ”œโ”€โ”€ examples/
โ”‚   โ”œโ”€โ”€ 01_basic_query.py
โ”‚   โ”œโ”€โ”€ 02_tem_acquisition.py
โ”‚   โ”œโ”€โ”€ 03_eels_workflow.py
โ”‚   โ”œโ”€โ”€ 04_4dstem_analysis.py
โ”‚   โ”œโ”€โ”€ 05_tilt_series.py
โ”‚   โ”œโ”€โ”€ 06_diffraction_dspacing.py
โ”‚   โ”œโ”€โ”€ 07_voice_acquisition.py
โ”‚   โ””โ”€โ”€ 08_voice_confirmed_stage_moves.py
โ”œโ”€โ”€ docs/
โ”‚   โ”œโ”€โ”€ index.md
โ”‚   โ”œโ”€โ”€ installation.md
โ”‚   โ”œโ”€โ”€ architecture.md           # ASCII diagram, data-flow walkthrough
โ”‚   โ”œโ”€โ”€ tools_reference.md        # full API for all 21 tools
โ”‚   โ”œโ”€โ”€ dm_api_reference.md       # DM Python quick reference
โ”‚   โ””โ”€โ”€ gms_live_setup.md         # microscope PC wiring guide

Supported Ollama Models

Model Tool-calling Multi-step Latency (RTX 4090)
qwen2.5:7b โญ 97% 90% 4.2 s
qwen2.5:14b 99% 95% 8.7 s
llama3.1:8b 94% 82% 5.1 s
llama3.2:3b 82% 58% 2.8 s
mistral-nemo 88% 70% 6.3 s

Citation

If you use GMS-MCP in your research, please cite:

@article{dosReis2025gmsmcp,
  author    = {dos Reis, Roberto and Dravid, Vinayak P.},
  title     = {{GMS-MCP}: A Vendor-Agnostic, Privacy-Preserving Model
               Context Protocol Server for Multimodal Electron Microscopy
               Control via Local Large Language Models},
  journal   = {arXiv preprint arXiv:2025.XXXXX},
  year      = {2025},
  url       = {https://arxiv.org/abs/2025.XXXXX}
}

Acknowledgements

This work was supported by the NUANCE Center at Northwestern University (NSF MRSEC DMR-2308691, NSF NNCI).

We thank the developers of FastMCP, LangChain, Ollama, and the dmscripting.com community.


Contributing

See CONTRIBUTING.md. We welcome:

  • New acquisition modalities (e.g., EFTEM, Lorentz TEM)
  • Additional Ollama model benchmarks
  • Live GMS testing reports
  • Documentation improvements

License

MIT ยฉ 2025 Roberto dos Reis & Vinayak P. Dravid, Northwestern University

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nuance_gms_mcp-0.1.1.tar.gz (64.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nuance_gms_mcp-0.1.1-py3-none-any.whl (52.6 kB view details)

Uploaded Python 3

File details

Details for the file nuance_gms_mcp-0.1.1.tar.gz.

File metadata

  • Download URL: nuance_gms_mcp-0.1.1.tar.gz
  • Upload date:
  • Size: 64.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nuance_gms_mcp-0.1.1.tar.gz
Algorithm Hash digest
SHA256 0e3769f2d8d63fb8cb172ef425404394a4152dafc380ab4e8db444a790f41dd0
MD5 68f1e719eb576c43250bd4971d3bc2ab
BLAKE2b-256 626456153904d93db7b286a91ceb4581a4db06f44a5946fefccb2d8627e0ff60

See more details on using hashes here.

Provenance

The following attestation bundles were made for nuance_gms_mcp-0.1.1.tar.gz:

Publisher: ci.yml on NUANCE-IT/Gatan_MCP

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nuance_gms_mcp-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: nuance_gms_mcp-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 52.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nuance_gms_mcp-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ab46869b2205bfc0000b3e023860918b321ddfc9df47feadecc688dee3e52559
MD5 899cbbac236faf9916987fc8d0e7b09f
BLAKE2b-256 0f7e2ca33261f97501275929a6174ec6be0af89ca54e284d88499d4849674f77

See more details on using hashes here.

Provenance

The following attestation bundles were made for nuance_gms_mcp-0.1.1-py3-none-any.whl:

Publisher: ci.yml on NUANCE-IT/Gatan_MCP

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page