mcpField
T
Thorlabs Optical Power Meter

Thorlabs Optical Power Meter

Local
github.comScience & Education23Updated 5w ago

About Thorlabs Optical Power Meter

An MCP server for Thorlabs optical power meters, using SCPI over USBTMC/VISA to read power, log changes, and adjust meter settings. It supports laser measurement workflows and has been tested with a wire-level simulator, not real hardware.

Key features

  1. 01Read optical power and sensor temperature
  2. 02Log power series and stability metrics
  3. 03Set wavelength correction, averaging, and range
  4. 04Dark-zero the sensor
  5. 05Inspect meter and sensor information

Use cases

  1. 01Measure laser power at a selected wavelength
  2. 02Track laser warm-up drift and stability
  3. 03Configure wavelength and range before measuring
  4. 04Check whether a thermal sensor is still warming up

MCP support

Provides MCP clients with reading, configuration, and zeroing tools for Thorlabs optical power meters, sending SCPI commands over USBTMC/VISA.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"k-dense-ai-labmcp-thorlabs-pm": {
"command": "uvx",
"args": [
"labmcp-thorlabs-pm"
],
"env": {
"LABMCP_ADDRESS": "<LABMCP_ADDRESS>",
"LABMCP_SIMULATE": "<LABMCP_SIMULATE>",
"LABMCP_READ_ONLY": "<LABMCP_READ_ONLY>",
"LABMCP_LIMITS": "<LABMCP_LIMITS>"
}
}
}
}
Run commanduvx labmcp-thorlabs-pm
Environment variables to set
LABMCP_ADDRESSInstrument address, e.g. serial:///dev/ttyUSB0 or tcp://192.168.1.50:5025
LABMCP_SIMULATESet to 1 to use the built-in simulator (no hardware)
LABMCP_READ_ONLYSet to 1 to disable all state-changing tools
LABMCP_LIMITSSafety limit overrides, e.g. max_temperature_c=80

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
pypilabmcp-thorlabs-pm0.1.2

Tools

11

Saved tool list · updated 2w ago

This tool takes no parameters.

Details

From the project README

Thorlabs Optical Power Meter — MCP Server

Let an AI agent read laser power, log stability and warm-up drift, set the wavelength correction, averaging and range, and dark-zero the sensor on Thorlabs optical power meters through their documented SCPI command set over USB (USBTMC / VISA).

Packagelabmcp-thorlabs-pm
InstrumentsPM100D, PM100A, PM100USB, PM400 consoles with C-series photodiode and thermal sensors. PM101 and PM5020 use the same documented commands but are unverified (see Notes)
InterfacesUSB (USBTMC, via VISA)
ProtocolSCPI: PM100D Operation Manual 17654-D02 §6.4, PM100USB Operation Manual 19570-D02 §6.3, PM400 Operating Manual v1.1 §5.5, and Thorlabs' per-model SCPI command references
Status🧪 simulated: tested against a wire-level SCPI simulator, not yet verified on hardware. Report a hardware test

Try it without hardware

uvx labmcp-thorlabs-pm --simulate --check
uvx labmcp-thorlabs-pm --simulate --option sim_sensor=S302C --check   # thermal sensor head

The simulator is a PM100D with an S120C photodiode (or S302C thermopile) looking at a 1.234 mW, 632.8 nm HeNe laser. Setting the wrong wavelength on the photodiode gives a proportionally wrong reading, as on the real bench.

Connect your power meter

  1. Driver. Thorlabs meters enumerate as USB Test & Measurement Class (USBTMC) devices, vendor ID 0x1313.
    • Windows: the Thorlabs driver (TLPM / Thorlabs VISA) is not visible to PyVISA. Install the free NI-VISA runtime, then switch the meter to the NI-VISA driver with the Thorlabs Driver Switcher (installed with the Thorlabs Optical Power Monitor software), and start the server with ?backend=@ivi (see below). This is the route Thorlabs documents for PyVISA.
    • Linux: pyvisa-py talks USBTMC directly (installed with this package). Give your user access to the device, e.g. /etc/udev/rules.d/99-thorlabs-pm.rules:
      SUBSYSTEM=="usb", ATTR{idVendor}=="1313", MODE="0666"
      
      then sudo udevadm control --reload-rules and re-plug the meter. NI-VISA also works (?backend=@ivi).
    • macOS: pyvisa-py + libusb (brew install libusb); NI-VISA is an alternative.
  2. Find the resource string: uvx labmcp ports (or python -m pyvisa info). It looks like USB0::0x1313::0x8078::P0012345::INSTR (the product ID depends on the model: PM100D 0x8078, PM100USB 0x8072).
  3. Test the connection:
    uvx labmcp-thorlabs-pm --address USB0::0x1313::0x8078::P0012345::INSTR --check
    uvx labmcp-thorlabs-pm --address "visa://USB0::0x1313::0x8078::P0012345::INSTR?backend=@ivi" --check   # NI-VISA
    
    For the second input of a PM5020 add --option channel=2.

Add to your MCP client

Claude Code

claude mcp add power-meter -- uvx labmcp-thorlabs-pm --address USB0::0x1313::0x8078::P0012345::INSTR

Claude Desktop / Cursor / Windsurf (claude_desktop_config.json, .cursor/mcp.json, …)

{
  "mcpServers": {
    "power-meter": {
      "command": "uvx",
      "args": ["labmcp-thorlabs-pm", "--address", "USB0::0x1313::0x8078::P0012345::INSTR"]
    }
  }
}

Add --read-only to allow readings but block wavelength, averaging, range and zero changes. For other clients, generate the snippet with uvx labmcp config thorlabs-pm --address <resource> --client vscode (also cursor, codex, claude-code).

Tools

ToolKindDescription
get_command_log👁 readReturn the most recent raw commands sent to / replies received from the instrument (newest last). Useful for debugging and for recording what was done.
get_connection_info👁 readReport which instrument is connected (identity, address, simulated or real), whether the server is read-only, and the active safety limits. Call this first.
get_device_info👁 readIdentify the meter console and the attached sensor head (model, serial, type, wavelength range, power ranges), and report the present wavelength, averaging, range and zero value.
log_power_series👁 readLog a series of power readings to characterise laser stability, warm-up or drift. Returns mean, stdev, min/max, RMS and peak-to-peak stability (%) and drift (%/min), plus the readings (downsampled to max_points; use save_path, a new .csv file, to keep all of them).
read_power👁 readRead the optical power once (in W, plus dBm and a formatted string). The reading uses the configured correction wavelength and averaging; set the wavelength first.
read_sensor_temperature👁 readRead the sensor head temperature in °C (thermal sensors and other heads with a built-in temperature sensor only).
reconnect🛑 safetyClose and re-open the connection to the instrument (e.g. after it was power cycled or a cable was re-plugged).
set_averaging🎛 controlSet how many samples the meter averages for each reading. More averaging lowers noise but slows each reading (PM100 series: ~3 ms per sample; PM400/PM101/PM5020: 1 ms).
set_range🎛 controlSelect auto-ranging, or a fixed power range that fits range_w (the meter picks the most sensitive range that can hold that power). A fixed range reports over-range if exceeded.
set_wavelength🎛 controlSet the correction wavelength (nm) the meter uses to convert sensor signal to power. Must be within the sensor's calibrated range (see get_device_info); sent as a whole number of nm.
zero_sensor🎛 controlDark-zero the sensor (removes dark current / thermal offset). BEFORE calling, ask the user to block the beam and cover the sensor aperture completely, and wait for them to confirm: zeroing with light on the sensor corrupts all later readings. Takes a few seconds.

get_connection_info, get_command_log and reconnect are built into every LabMCP server.

A power meter only measures, so this server has no hazard tools. Your laser is the hazard: wear the right eyewear and never exceed the sensor's rated power or power density.

Safety limits

LimitDefaultMeaning
max_series_duration_s600 sLongest power-logging series an agent may start, estimated as count × max(interval, reading time), where a reading takes averaging × 3 ms plus ~10 ms

Override at launch: --limit max_series_duration_s=3600. One call can log at most 3640 s (the tool's timeout minus a margin): longer estimates are refused, and a series that runs slower than estimated stops early and returns what it measured (completed: false). save_path must end in .csv and must not exist yet (an existing file is never overwritten); it is checked before logging starts.

Example prompts

  • "Set the meter to 1064 nm and tell me the power after the objective."
  • "Log the laser power every 2 s for 10 minutes and report the RMS and peak-to-peak stability. Save the data to ~/data/laser_warmup.csv."
  • "I've capped the sensor. Zero it, then I'll remove the cap and you read the power."
  • "Measure the transmission of this ND filter: read the power without it, then again after I insert it, and give me the optical density."
  • "Is the thermal sensor head still warming up? Read its temperature every minute until it's stable."

Notes

  • Wavelength matters. Photodiode responsivity varies by a factor of several across the sensor's range, so a wrong wavelength setting gives a wrong power. The server sends whole nanometres (the PM400/PM101/PM5020 references specify an integer), so 632.8 nm is set as 633 nm. That changes the responsivity by far less than the sensor's calibration uncertainty.
  • Units. MEAS:POW? answers in the meter's configured unit (W or dBm). The driver reads SENS:POW:UNIT? first and always returns watts, so a front-panel unit change can't mislead the agent.
  • Out of range. The meter answers INFINITY / 9.9E37 when the signal exceeds a manually selected range. The server reports this as an error that suggests auto-ranging.
  • Zeroing (SENS:CORR:COLL:ZERO) runs in the background. The server polls …:ZERO:STAT?, checks the error queue, and returns the zero value (…:ZERO:MAGN?). Zero values are lost when the meter reboots.
  • Energy (pyroelectric) sensors are recognised but not supported: single-pulse energy measurement needs a trigger/fetch workflow that this server doesn't implement yet.
  • Averaging is SENS:AVER:COUN. One sample takes ~3 ms on the PM100 series and 1 ms on the PM400/PM101/PM5020. The reply timeout scales with the averaging count.
  • PM101 and PM5020: Thorlabs' command references for these list exactly the commands used here. The PM5020 adds a channel suffix (SENS2, MEAS2, SYST:SENS2:IDN?), selected with --option channel=2. Neither has been tested yet, and PM5020 LAN/serial connections have not been tried. The PM100D's Windows TLPM DLL driver is not used; this server speaks SCPI only.
  • The simulator's error replies for out-of-range values (-222,"Data out of range") use the standard SCPI code. The Thorlabs documents only list -113,"Undefined header" explicitly.

Hardware verification

ModelFirmwareInterfaceVerified byDate
none yet: be the first

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.