Skip to content

Getting Started

github-actions[bot] edited this page Nov 12, 2026 · 18 revisions

Getting Started

Requirements

  • Node.js 22 or newer (CI tests Node 22 and 24 on Linux, macOS and Windows), or Docker.
  • A UNI-T UTS series analyzer on your network, reachable from the machine that runs the server. Raw SCPI is served on TCP port 5025 (verified on the UTS3036B; other models are expected to behave the same but are untested).
  • An MCP client such as Claude Code or Claude Desktop.

The server is pure Node (no native modules, no VISA).

Prepare the analyzer

  1. Connect the analyzer to your network and note its IP address (shown in the instrument's LAN/system settings).
  2. Check that port 5025 is reachable from your computer:
    • macOS / Linux: nc -z -w 2 192.168.1.100 5025
    • Windows (PowerShell): Test-NetConnection 192.168.1.100 -Port 5025
  3. Replace 192.168.1.100 in this page with your analyzer's address. Never commit real addresses or serial numbers to a repository.

Install

Release v1.1.0 is out. Pick one of these; each registers the server under the name uni-t-uts. UTS_IP is optional: without it, tell the assistant "connect to the analyzer at 192.168.1.100" and it uses the connect tool.

Using Cursor, VS Code, Windsurf or another client? See Add to Client.

Claude Code

Easiest: the Claude Code plugin (this repository is also a plugin marketplace). Inside Claude Code:

/plugin marketplace add Reid-n0rc/uni-t-uts-mcp
/plugin install uni-t-uts@uni-t-uts-mcp

or from a shell: claude plugin marketplace add Reid-n0rc/uni-t-uts-mcp and claude plugin install uni-t-uts@uni-t-uts-mcp. The plugin runs npx -y uni-t-uts-mcp pinned to this release (1.1.0) and asks for the analyzer address, port and transport (all optional; change them later in /plugin). The server's tools then appear under the plugin. On Windows, where npx is a .cmd file, use the manual claude mcp add ... cmd /c npx commands below if the plugin's server does not start. Plugin and marketplace formats follow https://code.claude.com/docs/en/plugins-reference and https://code.claude.com/docs/en/plugins/marketplace-reference.md; the plugin files are generated by npm run clients:sync.

Or register the server by hand; pick one, each registers the server under the name uni-t-uts.

# From the npm registry (shortest; npx downloads and runs it)
claude mcp add uni-t-uts -e UTS_IP=192.168.1.100 -- npx -y uni-t-uts-mcp

# From the release tarball (same files as npm, fetched from GitHub: no build step, no install scripts)
claude mcp add uni-t-uts -e UTS_IP=192.168.1.100 -- npx -y https://github.com/Reid-n0rc/uni-t-uts-mcp/releases/download/v1.1.0/uni-t-uts-mcp-1.1.0.tgz

# From the git tag (npm clones the repository and builds it; needs git)
claude mcp add uni-t-uts -e UTS_IP=192.168.1.100 -- npx -y github:Reid-n0rc/uni-t-uts-mcp#v1.1.0

# Docker (Linux image, amd64 and arm64)
claude mcp add uni-t-uts -- docker run -i --rm -e UTS_IP=192.168.1.100 ghcr.io/reid-n0rc/uni-t-uts-mcp:1.1.0

On Windows, where npx is a .cmd file that clients cannot launch directly, put cmd /c in front of it:

claude mcp add uni-t-uts -e UTS_IP=192.168.1.100 -- cmd /c npx -y uni-t-uts-mcp

# or from the release tarball
claude mcp add uni-t-uts -e UTS_IP=192.168.1.100 -- cmd /c npx -y https://github.com/Reid-n0rc/uni-t-uts-mcp/releases/download/v1.1.0/uni-t-uts-mcp-1.1.0.tgz

Claude Desktop: the .mcpb bundle

Download uni-t-uts-mcp-1.1.0.mcpb from the v1.1.0 release and double-click it; Claude Desktop asks for the analyzer address (optional), port and transport. Installing it in Claude Desktop itself has not been verified yet; the JSON configuration below always works.

Claude Desktop, Cursor, VS Code and other clients

Add an mcpServers entry to the client's MCP configuration (Claude Desktop: claude_desktop_config.json; Cursor: ~/.cursor/mcp.json; some VS Code-style clients use a servers key instead of mcpServers).

macOS / Linux:

{ "mcpServers": { "uni-t-uts": { "command": "npx", "args": ["-y", "uni-t-uts-mcp"], "env": { "UTS_IP": "192.168.1.100" } } } }

Or from the release tarball:

{ "mcpServers": { "uni-t-uts": { "command": "npx", "args": ["-y", "https://github.com/Reid-n0rc/uni-t-uts-mcp/releases/download/v1.1.0/uni-t-uts-mcp-1.1.0.tgz"], "env": { "UTS_IP": "192.168.1.100" } } } }

Windows:

{ "mcpServers": { "uni-t-uts": { "command": "cmd", "args": ["/c", "npx", "-y", "uni-t-uts-mcp"], "env": { "UTS_IP": "192.168.1.100" } } } }

Or from the release tarball:

{ "mcpServers": { "uni-t-uts": { "command": "cmd", "args": ["/c", "npx", "-y", "https://github.com/Reid-n0rc/uni-t-uts-mcp/releases/download/v1.1.0/uni-t-uts-mcp-1.1.0.tgz"], "env": { "UTS_IP": "192.168.1.100" } } } }

Docker (any OS with Docker):

{ "mcpServers": { "uni-t-uts": { "command": "docker", "args": ["run", "-i", "--rm", "-e", "UTS_IP=192.168.1.100", "ghcr.io/reid-n0rc/uni-t-uts-mcp:1.1.0"] } } }

The github: spec works in the same place as the tarball URL (replace the last argument).

From a clone (contributors)

git clone https://github.com/Reid-n0rc/uni-t-uts-mcp.git
cd uni-t-uts-mcp
npm ci && npm run build
npm run client-config -- --host 192.168.1.100

npm run client-config only prints, it never writes a file: it shows the exact Claude Code command and the JSON block for your OS and the absolute path of your clone. Use --from npm, --from tarball, --from github or --from docker to print the other forms.

Environment variables

The server connects automatically at startup when UTS_IP is set (a failed auto-connect is only logged; you can still call the connect tool).

Variable Description
UTS_IP Analyzer hostname or IP. Enables auto-connect and is the default host for the connect tool
UTS_PORT TCP port of the raw transport, default 5025
UTS_TRANSPORT auto (default: VXI-11 if the analyzer offers it, otherwise raw), raw or vxi11. Default for the connect tool's transport parameter; setting only UTS_PORT means raw
UTS_VXI11_DEVICE VXI-11 logical device name, default inst0
UTS_INSTRUMENTS Optional, for several analyzers at once: name=host[:port],name2=host2[:port2] or JSON ({"name":"host:port"}). UTS_IP is the instrument named default; these add more, all connected at startup. connect, disconnect and identify take a name; list_instruments shows them ; every other tool takes an optional instrument argument
UTS_BUSY_TIMEOUT_S How many seconds a tool call waits for another call to finish before failing with Instrument busy, default 120

To set the address in a shell instead of the client configuration: export UTS_IP=192.168.1.100 (bash, zsh), $env:UTS_IP = "192.168.1.100" (PowerShell) or set UTS_IP=192.168.1.100 (cmd).

Raw TCP or VXI-11

The default transport is auto: VXI-11 when the analyzer offers it, otherwise raw SCPI over TCP port 5025 (UTS_TRANSPORT=raw or vxi11 forces one). VXI-11 uses TCP port 111 (the portmapper) and a port the portmapper reports, which changes between instrument restarts, so a host firewall must allow outbound connections to the analyzer. Over VXI-11 the analyzer queues commands sent during a sweep instead of dropping them, and single_sweep waits with one blocking *OPC?. VXI-11 was verified against the real UTS3036B (issue #75): every tool gives the same values as over raw, nothing is dropped during a sweep, and the screen image is not truncated. Details: Architecture and the programming guide.

First steps

Ask your assistant to:

  1. Identify the analyzer (identify). You should get a line like UNI-TREND,UTS3036B,<serial>,V1.04.0040.
  2. Read the current settings (get_frequency, get_amplitude, get_bandwidth, get_sweep, get_acquisition, get_trace).
  3. Change something small (for example set_frequency with a new center and span) and check the returned state and any warnings.

To try the tools without an AI client, use the MCP Inspector from a clone of the repository:

UTS_IP=192.168.1.100 npm run inspector      # macOS / Linux
$env:UTS_IP = "192.168.1.100"; npm run inspector   # Windows PowerShell

If something does not work, see Troubleshooting.

Good to know before you start

  • The front panel locks while you use it. Once the server sends commands, the analyzer is in remote mode and its touch screen and buttons stop responding. Press Esc on the analyzer to return it to local mode (verified on a UTS3036B over raw TCP; the remote ways back to local do not work on that firmware).
  • The analyzer ignores every command while a single sweep is running on the raw socket, so long manual sweep times make other tools time out. The server copes with this for its own sweeps. See Instrument Behavior.
  • Parallel tool calls are safe. The server runs tool calls one at a time per instrument, in the order they arrive, so results and errors are never mixed up. A long operation such as single_sweep makes other calls wait, and a call that waits longer than UTS_BUSY_TIMEOUT_S seconds fails with Instrument busy without having sent anything.
  • Several analyzers at once. Name them in UTS_INSTRUMENTS (for example sa1=192.168.1.100:5025,sa2=analyzer2.local) or add them with connect and a name, then pass instrument to any tool. Calls to different analyzers run in parallel, calls to the same analyzer are queued, and an error on one never affects another. list_instruments shows them.
  • Some commands are blocked unless explicitly confirmed (reset, network settings, panel lock, file writes). See Safety and Security.
  • The screenshot tool works over VXI-11 only; see the Roadmap.

Clone this wiki locally