Lablink Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Lablink Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<!-- mcp-name: io.github.techmanual-ai/lablink-mcp -->
<h1 align="center">LabLink</h1>
<p align="center"> Unified & extensible MCP server enabling connectivity to all types of lab equipment </p>
<p align="center"> <a href="https://pypi.org/project/lablink-mcp/"><img src="https://img.shields.io/pypi/v/lablink-mcp?style=for-the-badge&logo=pypi&logoColor=white&color=3775A9" alt="PyPI version"></a> <img src="https://img.shields.io/badge/python-3.10+-3776AB?style=for-the-badge&logo=python&logoColor=white" alt="Python 3.10+"> <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green?style=for-the-badge" alt="License: MIT"></a> <a href="https://github.com/techmanual-ai/lablink-mcp/actions"><img src="https://img.shields.io/github/actions/workflow/status/techmanual-ai/lablink-mcp/ci.yml?style=for-the-badge&logo=githubactions&logoColor=white&label=tests" alt="CI status"></a> <img src="https://img.shields.io/badge/MCP-server-6E56CF?style=for-the-badge" alt="MCP server"> </p>
<p align="center"> <a href="https://github.com/techmanual-ai/lablink-mcp/stargazers"><img src="https://img.shields.io/github/stars/techmanual-ai/lablink-mcp?style=flat-square&logo=github" alt="Stars"></a> <a href="https://github.com/techmanual-ai/lablink-mcp/releases"><img src="https://img.shields.io/github/v/release/techmanual-ai/lablink-mcp?style=flat-square" alt="Release"></a> <img src="https://img.shields.io/badge/drivers-5-6E56CF?style=flat-square" alt="5 drivers"> <a href="CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen?style=flat-square" alt="PRs welcome"></a> </p>
<p align="center"> <a href="#-install">Install</a> · <a href="#-quick-start">Quick Start</a> · <a href="#mcp-tools">Tools</a> · <a href="#device-configuration">Configuration</a> · <a href="#cli-reference">CLI</a> · <a href="CONTRIBUTING.md">Contributing</a> </p>
<img src="docs/assets/banner.svg" alt="LabLink — one agent, every interface" width="100%">
LabLink gives an AI agent direct, structured access to lab hardware and services — without a human in the loop. Connect by alias, send commands, read results, and iterate across any combination of devices in a single session.
visa_query, ssh_exec, rest_get) — no leaky one-size-fits-all interfaceEach device is addressed by an alias whose config type field selects the driver. Per-driver tools register only when that driver's dependencies are installed.
| Protocol | type | Transport | Operation tools | Extra | Hardware-validated |
|---|---|---|---|---|---|
| VISA / SCPI | visa | PyVISA (USB-TMC, TCPIP, GPIB, Serial) | visa_query, visa_write | [visa] | ✅ |
| SSH | ssh | Paramiko | ssh_exec, ssh_shell_session, ssh_start_stream, ssh_read_stream, ssh_stop_stream | [ssh] | ✅ |
| REST | rest | httpx | rest_get, rest_post, rest_put, rest_patch, rest_delete | [rest] | ✅ |
| Serial | serial | pyserial (RS232/RS422/RS485) | serial_query, serial_write, serial_read, serial_flush | [serial] | ⚪ |
| Python shell | python_shell | subprocess REPL | python_shell_exec, python_shell_eval | [python_shell] | ✅ |
An external routing stub also lets a device be handled by a vendor-supplied MCP server, surfacing routing hints to the agent on connect().
Legend — ✅ exercised end-to-end on real hardware · ⚪ covered by unit tests with the driver library mocked (real use needs real hardware).
pip install lablink-mcp # core only (no drivers)
pip install lablink-mcp[visa] # + PyVISA
pip install lablink-mcp[ssh] # + Paramiko
pip install lablink-mcp[all] # all driversOne TOML file per device at ~/.lablink/devices/<alias>.toml. The type field selects the driver.
VISA instrument:
# ~/.lablink/devices/tek_mso44.toml
type = "visa"
alias = "tek_mso44"
resource_string = "USB0::0x0699::0x0527::C012345::INSTR"
manufacturer = "Tektronix"
model_number = "MSO44"
timeout_ms = 5000
description = "4-channel mixed signal oscilloscope"Find your resource string:
python -c "import pyvisa; print(pyvisa.ResourceManager('@py').list_resources())"SSH host:
# ~/.lablink/devices/rpi_dev.toml
type = "ssh"
alias = "rpi_dev"
host = "192.168.1.42"
port = 22
username = "pi"
auth_type = "ssh_key"
auth_ssh_key_path = "~/.ssh/id_rsa"
timeout_ms = 10000See examples/configs/ for templates for all drivers.
lablink list # show all configured devices
lablink connect tek_mso44 # open session, print identity
lablink visa query tek_mso44 "*IDN?" # send SCPI queryClaude Code — add to ~/.claude.json (global) or .mcp.json in your project root:
{
"mcpServers": {
"lablink-mcp": {
"command": "lablink-mcp"
}
}
}Claude Desktop — add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"lablink-mcp": {
"command": "lablink-mcp"
}
}
}| Tool | Description |
|---|---|
connect(alias) | Open session, return identity, device memory, and topology slice |
disconnect(alias) | Close session |
list_devices() | List all configured aliases with status |
diagnose(alias?) | Reachability and dependency check; system audit (with topology warnings) when no alias given |
system_topology(alias?) | Return the bench wiring map; or a single device's slice |
| Driver | Tools |
|---|---|
visa | visa_query, visa_write |
ssh | ssh_exec, ssh_shell_session, ssh_start_stream, ssh_read_stream, ssh_stop_stream |
rest | rest_get, rest_post, rest_put, rest_patch, rest_delete |
serial | serial_query, serial_write, serial_read, serial_flush |
python_shell | python_shell_exec, python_shell_eval |
Per-driver tools are only registered when that driver's dependencies are installed. All tools return structured dicts. On failure:
{"success": false, "error": "VISA timeout", "hint": "Check that the instrument is powered on."}One TOML file per device at ~/.lablink/devices/<alias>.toml. Override the directory:
export LABLINK_CONFIG_DIR=/path/to/devices/| Field | Required | Description |
|---|---|---|
type | yes | Driver: visa, ssh, rest, serial, python_shell |
alias | yes | Must match the filename (e.g. tek_mso44.toml → alias = "tek_mso44") |
timeout_ms | yes | Default communication timeout in milliseconds |
description | no | Shown in lablink list output |
See examples/configs/ for complete templates.
VISA — adds resource_string, manufacturer, model_number, read_termination, write_termination, techmanual_document_ids
SSH — adds host, port, username, auth fields (auth_type, auth_ssh_key_path, auth_token_env, etc.)
REST — adds base_url, auth fields
Serial — adds serial_port, baud_rate, data_bits, parity, stop_bits, read_termination, write_termination
python_shell — adds python_path (path to interpreter), working_dir
Credentials are always referenced by environment variable name — never stored in config files directly.
The CLI mirrors the MCP tool surface for development and debugging.
lablink list # list all configured devices
lablink diagnose # system dep check (all drivers)
lablink diagnose tek_mso44 # device-specific reachability check
lablink connect tek_mso44 # open session, print identity
lablink disconnect tek_mso44 # close session
lablink visa query tek_mso44 "*IDN?" # SCPI query
lablink visa write tek_mso44 "CH1:SCALE 0.5" # SCPI write
lablink ssh exec rpi_dev "uname -a" # run SSH command
lablink rest get my_api /status # HTTP GET
lablink rest post my_api /jobs --body '{"n":1}' # HTTP POST
lablink serial query my_device "MEAS?" # serial write + readPer-protocol commands appear only when that driver's deps are installed.
`list_resources()` returns an empty tuple `()`
libusb. Install via pip install libusb-package.VISA timeout on connect or query
timeout_ms in your instrument config.LabLink uses pyvisa-py by default — a pure-Python implementation with no additional software required.
To use NI-VISA instead (e.g. for GPIB or if you already have it installed):
export LABLINK_VISA_BACKEND=@nitechmanual.ai is a searchable index of technical manuals for T&M equipment. When both MCP servers are loaded, your agent can look up SCPI commands and execute them without human intervention.
Add techmanual_document_ids to your VISA config to enable targeted lookups:
techmanual_document_ids = [1291, 1323] # user manual, programming guideWhen this field is set, connect() returns the IDs so the agent can fetch relevant pages without a search query.
Home Assistant is a local-first, open-source smart-home hub. It unifies thousands of devices across ecosystems — Apple Home, Alexa, Google, Zigbee, Z-Wave, Matter — behind one local REST API. That means LabLink's existing rest driver drives your whole home through a single alias; no extra driver to install.
Create a Long-Lived Access Token in Home Assistant (Profile → Security → Long-Lived Access Tokens), export it, and point a REST config at your hub:
# ~/.lablink/devices/home_assistant.toml
type = "rest"
alias = "home_assistant"
timeout_ms = 10000
base_url = "http://homeassistant.local:8123/api"
auth_type = "bearer"
auth_token_env = "HASS_TOKEN" # export HASS_TOKEN=<your-token>Then your agent can read and command anything HA manages:
lablink rest get home_assistant /states # every entity's state
lablink rest post home_assistant /services/light/turn_on --body '{"entity_id": "light.kitchen"}'See examples/configs/rest_home_assistant.toml for the full template.
LabLink ships five protocol drivers — visa, ssh, rest, serial, and python_shell — on a shared multi-driver dispatch core. (An external routing stub also lets a device be handled by a vendor-supplied MCP server.) GPIB is covered by visa through PyVISA; RS232/RS422/RS485 are electrical variants of the one serial driver.
Deliberately out of scope:
deployment or hosted endpoint.
real hardware.
does not parse or interpret SCPI or any other protocol syntax. That knowledge lives in the agent or in techmanual.ai.
containers defeats the point of local lab use.
Streaming-first protocols (MQTT, WebSocket) and others (Modbus, OPC-UA, CAN, …) are considered case-by-case as demand surfaces.
See docs/ARCHITECTURE.md for the data models, driver contract, dispatch model, and a step-by-step guide to adding a new driver. Adding a driver requires no changes to lablink/mcp_server.py or lablink/cli.py — just a new lablink/interfaces/<type>/ package and one line in each registry.
Contributions are welcome — see CONTRIBUTING.md to get started.
pip install -e ".[dev]"
pytest tests/All tests mock hardware drivers — no real instruments required.
Create ~/.lablink/topology.toml to give the agent a machine-readable map of how your bench is physically wired — which ports connect to which, what signals flow, and what safety limits apply.
# ~/.lablink/topology.toml
name = "rf_bench"
[[node]]
alias = "siglent_sdg6022"
role = "signal generator"
[[node]]
alias = "tek_mso44"
role = "oscilloscope"
[[node]]
id = "pad_10db" # passive gear: no alias needed
role = "10 dB attenuator"
[[link]]
from = "siglent_sdg6022:OUTPUT1"
to = "pad_10db:IN"
signal = "stimulus"
params = { impedance_ohm = 50 }
[[link]]
from = "pad_10db:OUT"
to = "tek_mso44:CH1"
signal = "stimulus (attenuated)"
[[link]]
from = "keysight_e36313:CH1"
to = "dut_serial:12V_IN"
signal = "DC power"
[[link.constraint]]
severity = "critical"
limit = "voltage <= 13.5"
note = "DUT is damaged above 13.5 V on 12V_IN."Call system_topology() to retrieve the full map, or system_topology(alias) to get one device's wiring slice. connect() and diagnose(alias) also inject the slice automatically as topology_context.
Constraints are advisory only. LabLink surfaces severity / limit / note to the agent; it does not and cannot enforce them (it does not parse protocol syntax). The agent is responsible for honoring limits.
Validate the file with:
lablink topology validate
lablink topology show # full map
lablink topology show tek_mso44 # one device's sliceSee examples/topology.toml for a full annotated example.
Override the default path:
export LABLINK_TOPOLOGY_FILE=/path/to/topology.toml| Variable | Default | Purpose |
|---|---|---|
LABLINK_CONFIG_DIR | ~/.lablink/devices/ | Device config directory |
LABLINK_TOPOLOGY_FILE | ~/.lablink/topology.toml | System topology file (independent of LABLINK_CONFIG_DIR) |
LABLINK_VISA_BACKEND | @py | pyvisa backend (@py or @ni) |
LABLINK_LOG_DIR | ~/.lablink/logs/ | Event log directory; set to "" to disable |
TMAI_API_KEY | — | techmanual.ai API key for agent-directed manual lookups |
LabLink is released under the MIT License.
<!-- MCP server VISA instruments · MCP server SCPI · MCP server GPIB · MCP server SSH · MCP server serial device · MCP server REST API · MCP server oscilloscope · MCP server Raspberry Pi · MCP server RS-232 · MCP server RS-485 · MQTT MCP server · Modbus MCP server · WebSocket MCP server · OPC-UA MCP server · CAN bus MCP server · AI agent lab instrument control · AI agent SCPI · AI agent VISA · AI agent oscilloscope · AI agent power supply · AI agent DMM · AI agent NI-DAQmx · AI agent nidaqmx · AI agent PicoScope · AI agent serial port · Claude lab automation · LLM instrument control · lab automation MCP · automated test equipment AI · SCPI automation AI · instrument control AI agent · multi-protocol MCP server · hardware control MCP server · FastMCP lab instruments · bench instrument AI · give AI agent hardware access · AI test automation Python · vendor SDK AI agent · AI agent function generator · AI agent spectrum analyzer · AI agent signal analyzer · AI agent bench instrument · Keysight MCP server · Keysight oscilloscope MCP · Keysight SCPI AI · Keysight InfiniiVision MCP · Keysight signal generator MCP · Keysight power supply MCP · Tektronix MCP server · Tektronix SCPI automation · Tektronix oscilloscope AI · Rigol MCP server · Rigol oscilloscope MCP · Rigol DS1054Z MCP · Siglent MCP server · Siglent oscilloscope AI agent · Rohde Schwarz MCP server · R&S MCP server · R&S oscilloscope AI · Fluke MCP server · Fluke multimeter AI agent · National Instruments MCP · NI DAQ MCP server · NI-DAQmx MCP · Yokogawa MCP server · Anritsu MCP server · LeCroy MCP server · Thorlabs MCP server · Newport MCP server · BK Precision MCP server · Arduino serial MCP · Arduino MCP server · microcontroller MCP server · Home Assistant MCP server · MCP server Home Assistant · Home Assistant AI agent · AI agent smart home · smart home MCP server · control smart home AI · Home Assistant REST API MCP · AI agent home automation · LLM smart home control · AI agent smart lights · AI agent thermostat · AI agent smart lock · Zigbee MCP server · Z-Wave MCP server · Matter MCP server · home automation AI agent -->
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.