PXE200 SA MCP
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., "@PXE200 SA MCP measure channel power at 2.4 GHz with 20 MHz span and save a screenshot"
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.
pxe200-sa-mcp
MCP server for the Harogic PXE200 spectrum analyzer. It drives SAStudio4 on the PXE through an
SCPI bridge plugin (libScpiBridge.so, TCP 5025) that runs inside SAStudio4.
Default PXE IP:
10.0.0.223(then10.0.0.211as a fallback), port 5025. If your PXE has a different address, setPXE_HOST, e.g.PXE_HOST=192.168.1.50(several addresses can be given, comma separated).
Requirements
Python 3.10+ and uv (for
uvx) on the computer running the AI harnessThe PXE200 on the same LAN, with the bridge plugin installed in SAStudio4 (see Bridge plugin)
Related MCP server: Instrument MCP Server
Install
Claude Code:
claude mcp add --scope user pxe200-sa -e PXE_HOST=10.0.0.223 -- uvx --from git+https://github.com/apiwat59/pxe200-sa-mcp pxe200-sa-mcpAny other MCP harness (Claude Desktop, Cursor, Windsurf, VS Code, Cline, ...) — add to its MCP config JSON:
{
"mcpServers": {
"pxe200-sa": {
"command": "uvx",
"args": ["--from", "git+https://github.com/apiwat59/pxe200-sa-mcp", "pxe200-sa-mcp"],
"env": { "PXE_HOST": "10.0.0.223" }
}
}
}Codex CLI (~/.codex/config.toml):
[mcp_servers.pxe200-sa]
command = "uvx"
args = ["--from", "git+https://github.com/apiwat59/pxe200-sa-mcp", "pxe200-sa-mcp"]
env = { PXE_HOST = "10.0.0.223" }Without uv: pip install git+https://github.com/apiwat59/pxe200-sa-mcp, then use pxe200-sa-mcp as the command.
Environment
Variable | Default | Meaning |
|
| Bridge address(es), comma separated, tried in order |
|
| Where reports, screenshots and CSV go |
ภาษาไทย (สั้น ๆ)
IP เริ่มต้นของ PXE คือ 10.0.0.223 (ถ้าไม่ได้จะลอง 10.0.0.211) พอร์ต 5025 — ถ้าเครื่องของคุณใช้ IP อื่น ให้ตั้ง
PXE_HOSTต้องติดตั้ง uv ก่อน แล้วใช้คำสั่ง
claude mcp add ...ด้านบน หรือคัดลอก JSON ไปใส่ในไฟล์ตั้งค่า MCP ของโปรแกรมที่ใช้ต้องติดตั้ง bridge plugin ใน SAStudio4 บนเครื่อง PXE ก่อน (หัวข้อ Bridge plugin)
Bridge plugin
bridge/src/bridge_plugin.cpp is a SAStudio4 plugin that opens an SCPI server on TCP 5025 and drives the
running GUI. Build it on the PXE (Qt 5 dev headers, pkg-config, g++):
sh bridge/build.sh # -> bridge/libScpiBridge.so ; set SA4=<SAStudio4 folder> if not the defaultCopy libScpiBridge.so into <SAStudio4>/plugin/ and restart SAStudio4. bridge/deploy.sh does the
rebuild + restart on our unit (it expects the sources in ~/sa4dev/scpi; adjust paths for yours).
Tested with SAStudio4 4.3.55.35. iplugin.h / propertysystem.h are minimal declarations reconstructed
from SAStudio4's exported libraries; no vendor code is included.
Quick check from a PC: python scpi_client.py 10.0.0.223 "*IDN?"
Tools
Generic, any control:
sa_controls(catalog search),sa_menu(open a menu, live values),sa_get,sa_set,sa_press,sa_dialog,sa_app(File/Mode/System menus),sa_file(file dialogs),sa_read(labels, tables, plots, windows, device, widget tree),sa_gui/sa_scpi(raw).Measurement:
sa_configure(mode-aware),sa_trace,sa_sweep,sa_trace_data(any graph; DET in seconds),sa_peak,sa_channel_power,sa_channel_table,sa_measure(CP/OBW/ACPR),sa_results(all results of the current mode),sa_marker,sa_peak_table,sa_view(dock views).Files and state:
sa_files(list/download exports, images, states),sa_state(save/list/recall),sa_info(versions, temperature, USB, battery, menu states),sa_screenshot.Digital Demod (needs a working
lib/libDigitalSigDemod.soin SAStudio4, not part of this repo):dd_configureopens the mode and sets modulation, symbol rate, center, filter alpha, averaging and reference level, then waits until two reads agree.dd_resultsgives the results as numbers (EVM / phase / magnitude / frequency error / SNR for PSK and QAM, FSK error / deviation / offset for FSK2, FSK4 and GMSK);repeat=nadds mean, median, min and max.dd_constellationsaves the constellation, the ideal points and the eye as CSV plus a PNG. All three can add items to the report.Report:
report_start,report_add_note,report_edit_item,report_set_info,report_status,report_list,report_open,report_export.
Safety
DANGER (refused unless
confirm=trueafter the user agreed): signal-generator RF output and sweep (AUXS page, hidden on this unit), RxPort, reference clock source, calibration / antenna-factor table Apply/Clear/Delete/Import, Screen Lock, Date/Time, Power On State, Setting Mode, Fan/Display/Device.Blocked: File/Exit (would kill SAStudio4 and the bridge).
Mode-switch prompts ("Switch to phase noise mode?") are answered Cancel automatically and reported.
MMEM:*reads only below/media/rpdzkj/userdata.The bridge port has no authentication: keep the PXE on a trusted LAN.
Values
Numbers are entered on SAStudio4's own keypad with the unit given ('30kHz', '250ms', '-3dB',
'2GB'); Hz and seconds are scaled to whatever unit buttons the keypad has. Choices take the option
text (sa_controls lists them), toggles take On/Off.
Absolute power: the rule (learned the hard way)
A jammer test once reported 184 W for a 25 W module: PosPeak + Max Hold read noise-like signals (jammers, OFDM, multi-tone) ~10 dB too high. Now enforced by the tools:
sa_total_powermeasures RMS + Average, cross-checks against the peak detector (>3 dB apart = noise-like) and restores the detector/trace. Use it for every watt / dBm-total figure.sa_channel_power,sa_channel_table,sa_trace_dataattachpower_basis(detector, trace type) and awarningslist (peak detector / Max Hold, ADC overflow, mismatch with rating). A report item with warnings is marked FAIL. Max Hold is for edges, flatness and hopping occupancy.report_start(rated_power_w=...): every power result is compared with the DUT rating (+-3 dB).sa_configure(ref_level_dbm=...)is the level AT THE INPUT; the tool adds the offset for the screen value. (Before, ref 20 with offset 40 put the input range at -20 dBm: silent ADC overflow, power read 40 dB low.)
Digital Demod notes
The symbol rate must match the signal. A wrong rate or modulation still gives steady numbers (FSK4 read 7.5 % at 60 ksym/s instead of 55.56, QPSK on a QAM16 signal read 45 % EVM).
dd_resultswarns above 15 %.Right after a change the screen can show results from the old setting for a second or two.
dd_configurewaits for that; take figures withdd_results(repeat=10)and quote the median.FilterType is greyed out in SAStudio4 4.3.55.35 and stays RRC; FilterAlpha can be set.
SAStudio4 lists QAM32 as "QAM34"; the tools accept QAM32. PSK8 also accepts 8PSK.
The bridge reports this mode as
INST? UNKNOWN; the tools detect it by the constellation graph.Reading eye traces costs about 0.1 s each.
dd_constellationreads 100 by default, the screen holds up to about 400.
Available Tools
42 toolsdd_configureDd ConfigureB
Open SAStudio4's Digital Demod mode (if not open) and set modulation, symbol rate, center, filter, averaging and reference level, with read-back. Blank arguments are left unchanged.
Inputs: center, mod_type, avg_number, filter_type, +4 more. Returns: object
dd_constellationDd ConstellationB
Read the measured constellation points (plus the ideal reference points and the eye traces) from the Digital Demod screen, save them as CSV and a PNG plot, and return the plot.
Inputs: eye, note, label, return_image, +2 more.
dd_resultsDd ResultsB
Digital Demod results as numbers. PSK/QAM: EVM rms/peak %, phase error deg, magnitude error %, frequency error Hz, SNR(MER) dB. FSK/GMSK: FSK error %, magnitude error %, carrier offset Hz, deviation Hz. ASK: ASK error %, carrier offset Hz. Use repeat > 1 for a stable figure.
Inputs: note, label, repeat, interval_s, +2 more. Returns: object
report_add_noteReport Add NoteC
Add a free-text section (setup, observation, conclusion) to the report.
Inputs: text (required), result, heading. Returns: result
report_edit_itemReport Edit ItemC
Edit label/note/result/limit of a report item, or delete it.
Inputs: index (required), note, label, limit, +2 more. Returns: object
report_exportReport ExportB
Generate the report document(s) from the active session.
Inputs: fmt. Returns: object
report_listReport ListB
List report folders.
Inputs: no named parameters. Returns: result
report_openReport OpenB
Resume an existing report session.
Inputs: folder (required). Returns: object
report_set_infoReport Set InfoC
Update report header fields / overall conclusion.
Inputs: dut, setup, title, project, +3 more. Returns: object
report_startReport StartB
Start a new report session. Later screenshots / traces / measurements are saved into its folder. Pass rated_power_w whenever the DUT's power rating is known.
Inputs: title (required), dut, setup, project, +3 more. Returns: object
report_statusReport StatusB
Show the active report and its items.
Inputs: no named parameters. Returns: object
sa_appSa AppB
Application menu (File / Mode / System). File/Exit is blocked; Power On State, Setting Mode, Fan/Display/Device need confirm=true.
Inputs: path, confirm. Returns: object
sa_channel_powerSa Channel PowerB
Channel power integrated over [center +- bandwidth/2] from the displayed trace (same method as SAStudio4's Channel Power, works on Max Hold and any span).
Inputs: center (required), bandwidth (required), note, label, +2 more. Returns: object
sa_channel_tableSa Channel TableB
Channel power and peak for a regular channel plan, from one trace read (use a Max Hold trace for hopping transmitters). Returns per-channel dBm/W plus min/max/spread.
Inputs: count (required), spacing (required), bandwidth (required), first_center (required), +4 more. Returns: object
sa_configureSa ConfigureA
Set up the analyzer (any mode). Only the given parameters change; returns the resulting settings. In HARM / PN / IQS / DET the mode's own controls are used (HARM center/span/level, PN carrier, IQS/DET analysis bandwidth for span). ref_level_dbm is the level at the input: with an external attenuator of 40 dB and a +40 dB offset, ref_level_dbm=20 shows 60 dBm on screen. The offset is applied first, then the reference level (so the input range never drops below the one you asked for).
Inputs: rbw, vbw, span, stop, +7 more. Returns: object
sa_connectSa ConnectB
Connect to the SCPI bridge inside SAStudio4 on the PXE200.
Inputs: host. Returns: object
sa_controlsSa ControlsA
Catalog of every control of a mode (from the survey; no instrument access): name, caption, kind (number/enum/toggle/action/file/...), options, where it lives and its risk class. Use the names with sa_get / sa_set / sa_press. Dialog controls are listed under 'dialogs'.
Inputs: menu, mode, search, include_generator. Returns: object
sa_dialogSa DialogA
See open dialogs / message boxes (text and buttons) and answer or close them.
Inputs: action, button, window. Returns: object
sa_fileSa FileA
Drive an open SAStudio4 file dialog (after sa_app 'File/Save State' / 'File/Recall State', record path, replay file, export): change folder, type a name or pick a file, confirm. Returns the folder listing.
Inputs: name, select, confirm, directory. Returns: object
sa_filesSa FilesB
List or download files SAStudio4 wrote (DataExport CSV/profile, saved images, state .xml, records).
Inputs: path, fetch. Returns: object
sa_getSa GetB
Read any control: navigates to it and returns value, options, caption, kind.
Inputs: name (required), menu, mode, panel, +1 more. Returns: object
sa_guiSa GuiA
Generic access to any SAStudio4 control by name, for settings without a dedicated tool. Menu controls are only reachable while their right-hand menu page is shown: open it with action=menu.
Inputs: action (required), value, target. Returns: object
sa_infoSa InfoB
Instrument info: model, UID, firmware/FPGA/MCU/API/GUI versions, temperature, USB link and rate, battery, clock, current mode and the checked items of the title menus (theme, power-on state...).
Inputs: gnss. Returns: object
sa_markerSa MarkerC
Markers on the current graph (any mode): enable, place, peak search, next peaks, marker->center, noise marker, delta, peak tracking, signal track. Returns the marker table (all markers with x/y).
Inputs: trace, value, action, marker, +2 more. Returns: object
sa_measureSa MeasureA
Run one of SAStudio4's own measurements (Meas menu) and read its result. Note: entering Channel Power can change span/RBW to the measurement's own settings.
Inputs: kind (required), note, label, obw_xdb, +4 more. Returns: object
sa_modeSa ModeC
Switch the SAStudio4 measurement mode.
Inputs: mode (required). Returns: object
sa_peakSa PeakC
Highest point of the trace (optionally within a range).
Inputs: stop, start, trace, show_marker. Returns: object
sa_peak_tableSa Peak TableB
Turn on SAStudio4's Peak Table (10 strongest peaks) and read it (n, frequency, level).
Inputs: show. Returns: object
sa_pressSa PressB
Press any SAStudio4 button (momentary actions, menu buttons). Reports dialogs it opened.
Inputs: name (required), menu, mode, panel, +4 more. Returns: object
sa_readSa ReadA
Raw readouts of what is on screen: labels (result values, annotations), tables (peak/harmonic/SEM/ mapping/pulse tables), plots (graphs + trace point counts), windows, device info, widget tree.
Inputs: what, scope. Returns: object
sa_resultsSa ResultsC
All results SAStudio4 currently shows, parsed: Channel Power / ACPR (all pairs) / OBW / IM3 / SEM table + verdict (SA), AM/FM demod metrics and pulse statistics (IQS/DET), phase-noise table (PN), harmonic table + THD (HARM), mapping results + table (MAP), graph annotations, markers, notices (e.g. 'Carrier Loss!'), overflow.
Inputs: mode, note, label, add_to_report. Returns: object
sa_scpiSa ScpiB
Send a raw command to the bridge (queries end with '?'). Supported: *IDN? *OPC? *WAI SYST:ERR? FREQ:CENT|STAR|STOP|SPAN, BAND[:VID], DISP:WIND:TRAC:Y:RLEV, INIT[:CONT], SWE:WAIT? n, SWE:COUN?, CALC:MARK:MAX, CALC:MARK[n]:X?|Y?, INST , TRAC:DATA? n, TRAC:DATA:X? n, TRAC:CAT?, CONF:CHP|OBW|ACP|OFF, FETC:CHP?|OBW?|ACP?, CHP:BWID|FREQ, OBW:XDB, CALC:CHP? c,bw[,n], GUI:LIST?|CLICK|SET|SELECT|OPTIONS?|VALUE?|TEXT, DEBUG:TAP , DEBUG:LAB?, DEBUG:BUTT?.
Inputs: command (required), timeout_s. Returns: object
sa_screenshotSa ScreenshotC
Capture the SAStudio4 screen as PNG (saved to the report folder, with the current settings).
Inputs: note, label, return_image.
sa_setSa SetA
Set any SAStudio4 value control (number / choice / on-off) the way a user would, with read-back. Confirmation pop-ups that would switch mode are cancelled and reported.
Inputs: name (required), value (required), menu, mode, +3 more. Returns: object
sa_stateSa StateC
Save / list / recall complete SAStudio4 setups (File > Save State / Recall State).
Inputs: name, action, confirm. Returns: object
sa_statusSa StatusC
Current mode, frequency range, RBW/VBW, reference level, offset and ADC overflow flag.
Inputs: no named parameters. Returns: object
sa_sweepSa SweepC
Run control. single = stop after one fresh sweep and return when it is complete.
Inputs: action, sweeps. Returns: object
sa_total_powerSa Total PowerA
Absolute power of a band, measured the right way: RMS detector + Average trace, cross-checked against the peak detector. If peak and RMS differ by more than 3 dB the signal is noise-like (jammer, OFDM, multi-tone): only the RMS figure is valid. Restores the detector and trace type. Checks the result against the DUT rating and returns warnings when it does not match. Set the span so the whole signal is inside it, and the offset (attenuator) before calling.
Inputs: center (required), bandwidth (required), note, label, +3 more. Returns: object
sa_traceSa TraceB
Set a trace's type (Max Hold for hopping/bursty signals) and optionally accumulate for hold_s seconds.
Inputs: trace, hold_s, restart, trace_type. Returns: object
sa_trace_dataSa Trace DataB
Read a displayed trace of any graph (values include amp offset). Spectrum graphs: peak, band power, occupied ranges. Time graphs (DET PvT, IQS IQ): X in seconds. Saves CSV + plot.
Inputs: note, plot, save, stop, +5 more. Returns: object
sa_viewSa ViewC
List / show / hide the dock views of the current mode.
Inputs: on, name. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 42 tools
Several generic-access tools overlap substantially: sa_scpi (raw SCPI), sa_gui (control by name), and the sa_get/sa_set/sa_press trio (generic control access) all offer ways to read/write arbitrary settings, and sa_configure overlaps with sa_set. The power-measurement cluster (sa_measure, sa_channel_power, sa_total_power, sa_channel_table) and the read cluster (sa_trace_data, sa_read, sa_results) also require careful reading to distinguish. The detailed descriptions do help, but the boundaries are genuinely blurry in places.
Overwhelmingly consistent snake_case with clear namespaced prefixes (sa_, dd_, report_) that group tools logically by domain. Verbs are used predictably (sa_get/sa_set/sa_press, report_start/open/list). A few noun-style names (sa_status, sa_controls, sa_files, sa_info) are minor deviations but still readable.
42 tools is heavy and lands in the '25+' range that the rubric flags as potentially too many. However the server covers a genuinely broad instrument surface (multiple SA modes, Digital Demod, GUI control, files, state, and a full reporting subsystem), so many tools earn their place. It is on the excessive side but not arbitrary padding.
The surface is remarkably complete for an instrument-control server: connect/status, configuration, measurement, results parsing, markers, traces, GUI control, dialogs, file/state management, Digital Demod, and a full report lifecycle (start/open/list/status/add/edit/export). Generic sa_get/sa_set/sa_press/sa_scpi cover the long tail, leaving no obvious dead ends beyond a trivial missing explicit disconnect.
Maintenance
Related MCP Connectors
Protocol-native energy infrastructure orchestration for AI data centers. Provides 46 MCP tools across 8 grid protocols (IEC-61850, DNP3, Modbus, OCPP, OpenADR, IEEE 2030.5, IEC 60870-5-104, ICCP) with 5 core API primitives: connect, dispatch, settle, comply, and intel. Enables AI agents to programmatically interact with substations, grid interfaces, and energy assets for real-time workload-grid coordination.
Safety tools for AI agents: safe page reader, prompt-injection, secrets, PII and MCP server scans
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Read your Yellowhead Diagnostics, scans and action items in an AI assistant, and start Diagnostics.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to directly control NI oscilloscopes (e.g., PXIe-5160/5164/5110) through the Model Context Protocol, including waveform acquisition, measurement, and configuration.MIT
- AlicenseCqualityBmaintenanceEnables natural language control of test instruments like spectrum analyzers and power supplies via SCPI commands, with auto-discovery and multi-instrument session support.1001MIT
- AlicenseCqualityDmaintenanceEnables AI tools to remotely control a SIGLENT SDS800X HD series oscilloscope, configure acquisition, capture waveforms, and analyze signal quality safely through high-level SCPI tools.204GPL 3.0
- AlicenseNot gradedqualityCmaintenanceEnables LLMs to control a PicoScope 5000A USB oscilloscope for signal generation, block capture, measurements, and frequency response sweeps.1MIT