Skip to main content

mcpXL30

WORK IN PROGRESS

mcpXL30 is an MCP (Model Context Protocol) server that exposes a curated subset of the pyxl30 control library to LLM agents (i.e. AI contorl of the XL30 ESEM).

Note that this project was partially generated with LLM support.

Features

  • Async MCP tools for common Philips XL30 operations (identify, read/set high tension, change scan modes, trigger pump/vent cycles, capture TIFF images).
  • Live MCP resources that describe the connected instrument and active config.
  • Safety envelope that limits accelerating voltage and sensitive operations.
  • Fine grained settings that control allowed operations for the LLM agent.
  • Optional remote HTTP/UDS transport with the authentication workflow explained in my blog post.

Installation

pip install .
# or
pip install ".[remote]"  # adds FastAPI/uvicorn/argon2 for remote mode

Configuration

The server loads JSON configuration from ~/.config/mcpxl30/config.json by default (override via --config). A minimal example:

{
  "instrument": {
    "port": "/dev/ttyUSB0",
    "log_level": "INFO",
    "retry_count": 3,
    "reconnect_count": 3
  },
  "image_capture": {
    "remote_directory": "C:\\\\TEMP",
    "filename_prefix": "MCPIMG_"
  },
  "safety": {
    "max_high_tension_kv": 15.0,
    "allow_venting": false,
    "allow_pumping": true,
    "allow_scan_mode_changes": true,
    "allow_stage_motion": false,
    "allow_detector_switching": true,
    "allow_beam_shift": true,
    "allow_scan_rotation_changes": true,
    "allow_image_filter_changes": true,
    "allow_specimen_current_mode_changes": false,
    "allow_beam_blank_control": true,
    "allow_oplock_control": false
  },
  "logging": {
    "level": "INFO",
    "logfile": null
  },
  "remote_server": {
    "uds": "/var/run/mcpxl30.sock",
    "api_key_kdf": {
      "algorithm": "argon2id",
      "salt": "<base64>",
      "time_cost": 3,
      "memory_cost": 65536,
      "parallelism": 1,
      "hash_len": 32,
      "hash": "<base64>"
    }
  }
}

Use mcpxl30-genkey --config /path/to/config.json (or mcpxl30 --genkey) to generate a new API key and populate the Argon2 hash inside the remote_server block. The plain token prints once to stdout.

The safety block gates riskier capabilities. Keep allow_stage_motion and allow_oplock_control disabled unless you trust the calling agent. Imaging and detector-related fields default to safe-but-capable settings, but you can toggle them per deployment.

Running the server

stdio transport (default)

mcpxl30 --config ~/.config/mcpxl30/config.json

The process utilizes the stdio transport.

Remote FastAPI/uvicorn transport

pip install "mcpXL30[remote]"
mcpxl30 --transport remotehttp --config ~/.config/mcpxl30/config.json
  • The FastAPI app exposes /mcp (MCP streaming API) and /status (unauthenticated health check).
  • Authentication expects the API key in Authorization: Bearer, X-API-Key, or the ?api_key= query parameter.
  • Binding uses a Unix domain socket (remote_server.uds) unless you specify a TCP port, in which case host (default 0.0.0.0) applies.

MCP functionality

Tools

Instrument Basics

Tool Purpose
instrument_identify Return the microscopes type/serial, scan mode, high tension.
read_high_tension / set_high_tension Inspect or change accelerating voltage (safety-capped).
get_scan_mode / set_scan_mode Read or change scan mode (allow_scan_mode_changes).
capture_image / trigger_photo_capture Store images (TIFF or console photo).
control_vent, pump_chamber Chamber vent/pump control (safety gated).

Beam & Detector Controls

Tool Purpose
get_spot_size / set_spot_size Read or set probe current (1–10).
get_magnification / set_magnification Read or set magnification (20–400 000).
get_stigmator / set_stigmator Inspect/update stigmator X/Y.
get_detector / set_detector Inspect or switch active detector (allow_detector_switching).
read_high_tension Included above but relevant for beam tuning.

Scan Timing & Geometry

Tool Purpose
get_line_time / set_line_time Read or set line time (ms or TV).
get_lines_per_frame / set_lines_per_frame Inspect or adjust lines per frame.
get_scan_rotation / set_scan_rotation Read or set scan rotation (allow_scan_rotation_changes).
get_area_dot_shift / set_area_dot_shift Manage area/dot shift percentages (allow_beam_shift).
get_selected_area_size / set_selected_area_size Control selected area dimensions.

Imaging Utilities

Tool Purpose
get_contrast / set_contrast Read or set contrast (0–100).
get_brightness / set_brightness Read or set brightness (0–100).
auto_contrast_brightness, auto_focus Run built-in adjustment routines.
get_databar_text / set_databar_text Inspect or update the image databar text.

Stage & Alignment

Tool Purpose
stage_home Home the stage (allow_stage_motion).
get_stage_position / set_stage_position Read or move X/Y/Z/tilt/rotation (allow_stage_motion).
get_beam_shift / set_beam_shift Inspect or adjust beam shift (allow_beam_shift).

Image Filtering & Specimen Current

Tool Purpose
get_image_filter_mode / set_image_filter_mode Manage FastMCP image filter + frame count (allow_image_filter_changes).
get_specimen_current_detector_mode / set_specimen_current_detector_mode Inspect or change detector mode (allow_specimen_current_mode_changes).
get_specimen_current Read specimen current (requires measure mode).

Beam Safety & Locks

Tool Purpose
is_beam_blanked, blank_beam, unblank_beam Inspect or control beam blank state (allow_beam_blank_control).
get_oplock_state, set_oplock_state Inspect or control the operator lock (allow_oplock_control).

Every setter uses blocking pyxl30 calls inside asyncio.to_thread, preserving the FastMCP event loop responsiveness. Review the safety settings to enable only the tools you trust agents with.

All setters perform blocking pyxl30 calls inside asyncio.to_thread so the MCP event loop stays responsive.

Resources

  • mcpxl30://instrument/capabilities – supported scan modes, image filter names, and the configured safety envelope.
  • mcpxl30://instrument/config – sanitized live configuration (excludes API secrets).

Examples

An examples/example_config.json file is included to bootstrap deployments. The repository mirrors mcpMQTT's project layout so existing FastMCP infrastructure (supervisors, packaging, docs) can be reused with minimal changes.

Metadata

Release files for mcpXL30 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcpXL30 0.1.0
File Size Uploaded
mcpxl30-0.1.0.tar.gz 21.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mcpXL30 0.1.0
File Interpreter ABI Platform
mcpxl30-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 41.7 kB

Release files / mcpxl30-0.1.0.tar.gz

Download URL mcpxl30-0.1.0.tar.gz
Size 21.2 kB
Tags Source
SHA-256 checksum
How to use checksums
cabd0efddf12f63fe0a6c58c463902968bd48f59d922a62a6c75890a9a1e77a6
BLAKE2b-256 checksum
How to use checksums
a8196380856cf4707189fb5b4ccb4f76bd8109da619f0f2588cfa2e736eb54ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.11

Release files / mcpxl30-0.1.0-py3-none-any.whl

Download URL mcpxl30-0.1.0-py3-none-any.whl
Size 20.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0c60c36c68fb742efcfb2e9661f0f8df5a2c7a4f33b2cc3bbe270b2969634c82
BLAKE2b-256 checksum
How to use checksums
69b7f62f95eaaba78abda57d03981571c4618221d55c254613d78c644044f968
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.11

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page