Skip to main content

FastMCP server exposing Philips XL30 ESEM controls via pyxl30 (unofficial)

Project description

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.

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

mcpxl30-0.1.0.tar.gz (21.2 kB view details)

Uploaded Source

Built Distribution

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

mcpxl30-0.1.0-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file mcpxl30-0.1.0.tar.gz.

File metadata

  • Download URL: mcpxl30-0.1.0.tar.gz
  • Upload date:
  • Size: 21.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.11

File hashes

Hashes for mcpxl30-0.1.0.tar.gz
Algorithm Hash digest
SHA256 cabd0efddf12f63fe0a6c58c463902968bd48f59d922a62a6c75890a9a1e77a6
MD5 dc393eabc8e365cf3cd2992245eeefe0
BLAKE2b-256 a8196380856cf4707189fb5b4ccb4f76bd8109da619f0f2588cfa2e736eb54ed

See more details on using hashes here.

File details

Details for the file mcpxl30-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mcpxl30-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.11

File hashes

Hashes for mcpxl30-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0c60c36c68fb742efcfb2e9661f0f8df5a2c7a4f33b2cc3bbe270b2969634c82
MD5 99b6527e1620569dee4be70f07f99566
BLAKE2b-256 69b7f62f95eaaba78abda57d03981571c4618221d55c254613d78c644044f968

See more details on using hashes here.

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