# Thorlabs Optical Power Meter

An MCP server for Thorlabs power meters. Your agent can take readings, log stability over time, and change wavelength, averaging and range over SCPI.

- MCP server · `type=mcp` · Claude Code, Codex, Cursor, GitHub Copilot, Windsurf (Devin Desktop), Cline, Zed, Gemini CLI · ★ 23
- Author: K-Dense-AI
- License: Apache-2.0 · policy=link-only · description only; the file stays with the author
- Source: https://github.com/K-Dense-AI/lab-instrument-mcps/tree/HEAD/servers/physics/thorlabs-power-meter
- Updated: 2026-09-26
- HTML: https://affpapa.org/en/nevibecode/mcp/thorlabs-optical-power-meter

## What it does

The server talks to PM100D, PM100A, PM100USB and PM400 consoles over USB, using USBTMC through VISA, and speaks the documented SCPI command set. PM101 and PM5020 share those commands but have not been checked against hardware.

Its tools cover a single power reading, a logged series with mean, standard deviation and drift, sensor head temperature, plus control over correction wavelength, averaging, range and dark zeroing. Three tools come from the shared LabMCP base: `get_connection_info`, `get_command_log` and `reconnect`. Launch with `--read-only` and readings still work while wavelength, averaging, range and zero changes are blocked.

No meter on the bench? `uvx labmcp-thorlabs-pm --simulate --check` starts a PM100D simulator. On Windows PyVISA cannot see the Thorlabs driver, so you install the NI-VISA runtime and switch the meter over with Thorlabs Driver Switcher. On Linux the device needs a udev rule for vendor ID `1313`. Zeroing only works with the beam blocked and the aperture covered, so the agent asks you to confirm first.

## Requirements
- Needs: Python and uv (commands run via uvx)
- Environment variables: `LABMCP_ADDRESS`, `LABMCP_SIMULATE`, `LABMCP_READ_ONLY`, `LABMCP_LIMITS` — keys and tokens: ask the human for the values, never commit them or put them in shared files.

## Install

### Claude Code (native platform)

**Platform CLI**
```bash
claude mcp add --env LABMCP_ADDRESS=<LABMCP_ADDRESS> --env LABMCP_SIMULATE=<LABMCP_SIMULATE> --env LABMCP_READ_ONLY=<LABMCP_READ_ONLY> --env LABMCP_LIMITS=<LABMCP_LIMITS> --transport stdio thorlabs-power-meter -- uvx labmcp-thorlabs-pm
```
Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from labmcp-thorlabs-pm <command>

### Codex

**Platform CLI**
```bash
codex mcp add thorlabs-power-meter --env LABMCP_ADDRESS=<LABMCP_ADDRESS> --env LABMCP_SIMULATE=<LABMCP_SIMULATE> --env LABMCP_READ_ONLY=<LABMCP_READ_ONLY> --env LABMCP_LIMITS=<LABMCP_LIMITS> -- uvx labmcp-thorlabs-pm
```
Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from labmcp-thorlabs-pm <command>

### Cursor

**Config file**
File `.cursor/mcp.json`:
```json
{
    "mcpServers": {
        "thorlabs-power-meter": {
            "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>"
            }
        }
    }
}
```
Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from labmcp-thorlabs-pm <command>

### GitHub Copilot

**Config file**
File `.vscode/mcp.json`:
```json
{
    "servers": {
        "thorlabs-power-meter": {
            "type": "stdio",
            "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>"
            }
        }
    }
}
```
Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from labmcp-thorlabs-pm <command>

### Gemini CLI

**Platform CLI**
```bash
gemini mcp add -e LABMCP_ADDRESS=<LABMCP_ADDRESS> -e LABMCP_SIMULATE=<LABMCP_SIMULATE> -e LABMCP_READ_ONLY=<LABMCP_READ_ONLY> -e LABMCP_LIMITS=<LABMCP_LIMITS> thorlabs-power-meter uvx labmcp-thorlabs-pm
```
Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from labmcp-thorlabs-pm <command>

## When to use it
- read laser power without typing SCPI commands by hand
- log a run of readings and see warm-up drift
- match the correction wavelength to the sensor head
- dark-zero the sensor with the beam blocked
- verify the connection before trusting a measurement

## Example prompts
- Connect to the power meter and show which console and sensor head you found
- Log a series of power readings and report stability and drift
- Set the correction wavelength to 632.8 nm and read the power

## Similar
- [tao-train-optical-inspection](https://affpapa.org/en/nevibecode/skills/tao-train-optical-inspection.md) — skill · 1600 installs
- [discover-analytics-patterns](https://affpapa.org/en/nevibecode/skills/discover-analytics-patterns.md) — skill · 42800 installs
- [instrument-events](https://affpapa.org/en/nevibecode/skills/instrument-events.md) — skill · 42800 installs
- [statistical-power](https://affpapa.org/en/nevibecode/skills/statistical-power.md) — skill · 1300 installs
- [dd-apm](https://affpapa.org/en/nevibecode/skills/dd-apm.md) — skill · 2000 installs
- [observability-onboarding](https://affpapa.org/en/nevibecode/skills/observability-onboarding.md) — skill · 1000 installs

From the same set: [k-dense-ai/lab-instrument-mcps](https://affpapa.org/en/nevibecode/by/k-dense-ai/lab-instrument-mcps.md) — 15 cards

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
