USBTMC MCP Server
This server lets you discover, connect to, and control multiple USBTMC instruments over USB using SCPI commands, with extra utilities for Keysight and Tektronix devices.
Discover USB instruments with
usbtmc_list_devicesConnect to and disconnect from up to 16 devices using
usbtmc_connect/usbtmc_disconnectList active connections with
usbtmc_list_connected_devicesSend SCPI commands with
usbtmc_sendQuery instruments and read responses with
usbtmc_query/usbtmc_receiveClear device buffers to recover from communication errors with
usbtmc_clearUnlock Keysight modular instruments from firmware mode to USBTMC mode with
usbtmc_unlock_keysight_devicesCapture screenshots from Keysight/Agilent oscilloscopes with
usbtmc_screenshot_keysight_displayCapture screenshots from Tektronix oscilloscopes with
usbtmc_screenshot_tektronix_display
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@USBTMC MCP Server list all connected USBTMC devices"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
USBTMC MCP Server
A Model Context Protocol (MCP) server for controlling multiple USBTMC (USB Test and Measurement Class) devices simultaneously using SCPI commands.
Features
Multi-Device Support: Connect and control up to 16 instruments at once.
Unified Interface: Use standard SCPI commands via a simplified MCP toolset.
Keysight Support: Includes specialized tools to unlock Keysight modular instruments from firmware mode to USBTMC mode.
Screenshot Capture: Take screenshots from Keysight/Agilent and Tektronix oscilloscopes.
State Management: Automatic tracking of device IDs and connection states.
Related MCP server: instrument-mcp
Requirements
Python >= 3.13
mcp[cli]2.x (v0.2.0 and later; useusbtmc-lite-mcp0.1.x if you are pinned tomcp1.x)
Windows Additional Setup
This project uses libUSB as a backend for USB communication. On Windows, you need to install a compatible USB driver for your device using Zadig.
Download and run Zadig
Select your target USB device from the dropdown (enable Options → List All Devices if it does not appear)
Select WinUSB as the driver and click Replace Driver
Note: Replacing the driver will remove the device's original functionality (e.g., HID recognition). To restore it, uninstall the driver from Device Manager and reconnect the device.
Installation
Using uv (recommended):
uv pip install usbtmc-lite-mcpOr via pip:
pip install usbtmc-lite-mcpOr from source:
git clone https://github.com/NaoNaoMe/usbtmc-lite-mcp.git
cd usbtmc-lite-mcp
uv syncConfiguration
Claude Desktop Config
Add the server to your claude_desktop_config.json:
{
"mcpServers": {
"usbtmc-lite-mcp": {
"command": "uvx",
"args": [
"usbtmc-lite-mcp"
]
}
}
}Tools Overview
Connection
usbtmc_list_devices: Scan the USB bus for available USBTMC instruments.usbtmc_list_connected_devices: List all currently active device connections.usbtmc_connect: Establish a connection to a specific device (returns adevice_id).usbtmc_disconnect: Close the connection to a device.
Communication
usbtmc_query: Send a SCPI query (e.g.,*IDN?) and receive the response.usbtmc_send: Send a SCPI command.usbtmc_receive: Manually reads the response.usbtmc_clear: Clear device buffers and reset communication state.
Keysight / Tektronix Utilities
usbtmc_unlock_keysight_devices: Switch Keysight modular instruments to USBTMC mode.usbtmc_screenshot_keysight_display: Capture a screenshot from a Keysight/Agilent oscilloscope.usbtmc_screenshot_tektronix_display: Capture a screenshot from a Tektronix oscilloscope.
Example Workflow
List Devices: Call
usbtmc_list_devicesto find your instrument's serial number.Connect: Call
usbtmc_connectwith theserial_number. It will return adevice_id(e.g.,0).Identify: Call
usbtmc_querywithdevice_id: 0andcommand: "*IDN?".Configure: Call
usbtmc_sendto set parameters.Disconnect: Call
usbtmc_disconnectwhen finished.
License
This project is licensed under the MIT License — see the LICENSE file for details.
Available Tools
11 toolsusbtmc_clearAIdempotent
Clear the device input/output buffers and reset communication state.
Use this to recover from communication errors or stuck states.
Args: params (DeviceIdInput): Input containing: - device_id (int): The unique identifier returned by usbtmc_connect()
Returns: dict: Result containing: - success (bool): Whether the clear operation was successful - device_id (int): The target device_id - message (str): Success or error message
Inputs: params (required). Returns: object
usbtmc_connectA
Connect to a USBTMC device and receive a device_id for subsequent operations.
The device_id is used to identify the connection in all subsequent operations. If multiple devices match the criteria, the connection will fail - provide more specific criteria to uniquely identify the target device.
Args: params (ConnectInput): Connection parameters containing: - manufacturer (str, optional): Device manufacturer name to match - product (str, optional): Device product name to match - serial_number (str, optional): Unique device serial number (most specific)
Returns: dict: Result containing on success: - device_id (int): Unique identifier for this connection (use for all subsequent operations) - manufacturer (str): Device manufacturer name - product (str): Device product/model name - serial_number (str): Device serial number - message (str): Success message
On error:
- error (str): Error message describing the failureNote: Maximum 16 simultaneous connections are supported.
Inputs: params (required). Returns: object
usbtmc_disconnectAIdempotent
Disconnect from a specific USBTMC device.
Args: params (DeviceIdInput): Input containing: - device_id (int): The unique identifier returned by usbtmc_connect()
Returns: dict: Result containing: - success (bool): Whether the disconnection was successful - device_id (int): The disconnected device_id - product (str): Product name of the disconnected device - message (str): Success or error message
Inputs: params (required). Returns: object
usbtmc_list_connected_devicesARead-onlyIdempotent
List all currently connected (active) USBTMC devices.
Returns: dict: Result containing: - count (int): Number of connected devices - devices (list[dict]): List of connected device info, each containing: - device_id (int): Unique identifier for the connection - manufacturer (str): Device manufacturer name - product (str): Device product/model name - serial_number (str): Device serial number
Example: >>> result = usbtmc_list_connected_devices() >>> result { "count": 1, "devices": [ { "device_id": 0, "manufacturer": "Keysight Technologies", "product": "DSO-X 3024A", "serial_number": "MY12345678" } ] }
Inputs: no named parameters. Returns: object
usbtmc_list_devicesARead-onlyIdempotent
List all available USBTMC devices connected via USB.
This is typically the first step in the workflow:
usbtmc_list_devices() - Discover available devices
usbtmc_connect() - Connect to a device and get device_id
Use device_id for operations (send/query/etc.)
usbtmc_disconnect() - Close connection when done
Returns: dict: Result containing: - count (int): Number of devices found - devices (list[dict]): List of device info dictionaries, each containing: - manufacturer (str): Device manufacturer name - product (str): Device product/model name - serial_number (str): Unique device serial number
Example: >>> result = usbtmc_list_devices() >>> result { "count": 1, "devices": [ { "manufacturer": "Keysight Technologies", "product": "DSO-X 3024A", "serial_number": "MY12345678" } ] }
Inputs: no named parameters. Returns: object
usbtmc_queryA
Send a SCPI command and immediately receive the response.
Use for QUERY commands (with '?') that request information from the device. For SET commands (without '?'), use usbtmc_send() instead.
This is a convenience function combining send and receive operations.
Args: params (QueryInput): Input containing: - device_id (int): The unique identifier returned by usbtmc_connect() - command (str): SCPI command string to send (usually ends with '?') - wait_time (float): Time to wait between send and receive (default: 0.1s) - max_bytes (int): Maximum bytes to read (default: 1024)
Returns: dict: Result containing: - success (bool): Whether the query was successful - device_id (int): The target device_id - command (str): The command that was sent - response (str or None): Response data, or None if no data/timeout - message (str): Success or error message
Note: Wait time recommendations: - Simple queries (*IDN?, status): 0.1s (default) - Querying existing measurements: 0.1s - After changing settings: 0.5-2.0s
Inputs: params (required). Returns: object
usbtmc_receiveARead-only
Receive data from a specific USBTMC device.
Args: params (ReceiveInput): Input containing: - device_id (int): The unique identifier returned by usbtmc_connect() - max_bytes (int): Maximum bytes to read (default: 1024)
Returns: dict: Result containing: - success (bool): Whether data was received - device_id (int): The target device_id - data (str or None): Received data string, or None if no data/timeout - message (str): Success or error message
Inputs: params (required). Returns: object
usbtmc_screenshot_keysight_displayARead-only
Capture screenshot from a Keysight/Agilent oscilloscope.
Args: params (DeviceIdInput): Input containing: - device_id (int): The unique identifier returned by usbtmc_connect()
Returns: Image
Inputs: params (required).
usbtmc_screenshot_tektronix_displayARead-only
Capture screenshot from a Tektronix oscilloscope.
Args: params (DeviceIdInput): Input containing: - device_id (int): The unique identifier returned by usbtmc_connect()
Returns: Image
Inputs: params (required).
usbtmc_sendA
Send a SCPI command to a specific USBTMC device.
Use for SET commands (without '?') that configure device settings. For QUERY commands (with '?'), use usbtmc_query() instead.
This function only sends data; use usbtmc_receive() to read responses, or use usbtmc_query() for send+receive in one operation.
Args: params (SendInput): Input containing: - device_id (int): The unique identifier returned by usbtmc_connect() - command (str): SCPI command string to send
Returns: dict: Result containing: - success (bool): Whether the send was successful - device_id (int): The target device_id - command (str): The command that was sent - message (str): Success or error message
Inputs: params (required). Returns: object
usbtmc_unlock_keysight_devicesAIdempotent
Switch all Keysight devices from firmware update mode to USBTMC mode.
Some Keysight USB modular instruments (e.g., U2700 series) power on in firmware update mode and require a vendor-specific command to switch to normal USBTMC operation.
After calling this function, devices will re-enumerate on the USB bus. Wait a moment, then call usbtmc_list_devices() to discover them.
Returns: dict: Result containing: - unlocked_count (int): Number of successfully unlocked devices - total_found (int): Total devices found in firmware mode - message (str): Success or informational message - errors (list[str], optional): List of error messages if any device failed
Inputs: no named parameters. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 11 tools
Each tool targets a distinct operation: discovery, connection, communication, recovery, vendor unlock, and vendor-specific screenshots. The only potential confusion between list_devices and list_connected_devices is resolved by clear descriptions.
All tools follow a usbtmc_<verb>_<noun> pattern in lowercase snake_case, with consistent verb-first ordering and vendor qualifiers where needed.
11 tools is well-scoped for a USBTMC server, covering the full workflow without excessive fragmentation.
The tool set covers the complete lifecycle from discovery to disconnection, including send/receive/query for SCPI communication, recovery via clear, and vendor-specific features for Keysight and Tektronix.
Maintenance
Related MCP Connectors
Single-connection MCP gateway discovering and executing 490+ verified MCP & A2A tools.
One MCP endpoint for Claude, GPT & Gemini: 100+ tools + no-code connectors + agent workers.
MCP gateway and cloud hosting for MCP servers, agents and apps like RAG, managed from your agent.
Every service you connect, one MCP endpoint for all your AI tools. Sign in once.
Related MCP Servers
- AlicenseBqualityBmaintenanceAn MCP server for controlling lab instruments (oscilloscopes, signal generators, etc.) via standardized interfaces like USBTMC, RS-232, and LAN.100MIT
- AlicenseNot gradedqualityDmaintenanceConnects test and measurement instruments (oscilloscope, logic analyzer, multimeter, power supply) to AI via MCP, enabling natural language control and automated analysis.MIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to connect to and control Siglent oscilloscopes and power supplies over SCPI/TCP using typed tool calls with input validation, safety controls, and built-in observability.1Apache 2.0
- FlicenseNot gradedqualityBmaintenanceEnables unified discovery, query, and control of laboratory instruments (power supplies, oscilloscopes, signal generators, multimeters) via VISA/SCPI, with device-specific libraries and an MCP server exposing 19 tools for natural language interaction.-