Drive the Rohde & Schwarz CMW500 Wideband Radio Communication Tester from any MCP-compatible AI client. Direct TCP/IP SCPI (port 5025) — 131 tools spanning LTE/GSM/WCDMA signaling, LTE RX, WLAN (incl. signaling + throughput), Bluetooth/BLE, GPRF, and coexistence — plus per-unit bench profiles, a test-plan + reporting engine, SCPI-reference resources, and guided prompts. No CMWrun dependency.
Important
Hardware required. This MCP server controls a real R&S CMW500 Wideband Radio Communication Tester over TCP/IP SCPI. You need an actual CMW500 on the network to be useful. The server is a thin driver — no built-in simulator. The relevant CMW500 application licenses (LTE / WLAN / Bluetooth / GPRF) must be enabled on the unit for the matching tool surface to do anything.
mcp-rs-cmw500 is a Model Context Protocol
server that automates the R&S CMW500 Wideband Radio Communication Tester
over direct TCP/IP SCPI (port 5025). No CMWrun dependency, no proprietary
middleware — your AI agent talks to the CMW500 the same way a Python script
would, only in natural language.
The server covers: LTE signaling (cell config, NAS/bearer, C-DRX, full TX measurements) and LTE RX sensitivity via the Extended-BLER engine; WLAN non-signaling (802.11a/b/g/n/ac/ax, 20/40/80/160 MHz) plus WLAN AP-emulation signaling for LTE+Wi-Fi coex; Bluetooth/BLE non-signaling (Classic DH1-DH5 + LE 1M/2M/Coded) plus BLE signaling PER; GPRF generator/analyzer; shared signal-path control; and a coexistence layer — an LTE↔BLE desense sweep engine and a pure-computation intermod/harmonic (IMD) frequency planner. It also exposes MCP resources (a curated SCPI reference + live capability discovery) and prompts (guided coex/RX workflows).
Coexistence & HaLow note. The CMW500 supports 802.11a/b/g/n/ac/ax but not 802.11ah/HaLow natively. LTE+Wi-Fi and LTE↔BLE coex run on the instrument directly; HaLow (and other sub-GHz) coex is handled by the IMD planner plus using the GPRF generator as an aggressor against an externally measured victim link.
What mcp-rs-cmw500 does well:
- 🤖 AI-native via MCP. First-class Model Context Protocol server with 79 tools across 5 RF technology domains. Any Claude / LLM agent can drive it.
- 🐍 Python + MCP surfaces. Import
rs_cmw500_mcpfor direct driver access, or run as an MCP server for AI-agent automation. - ⚡ Direct SCPI. TCP/IP straight to the CMW500 — no CMWrun, no NI-VISA install, no vendor middleware.
- ✅ Pre-built templates.
lte_tx_power,gprf_power,nonsig_rx,wlan_tx,wlan_rx,ble_tx,ble_rx,bt_classic_tx. - 🔒 AGPL-3.0-or-later. Safety system (power / frequency clamps), SCPI-injection-guarded, raw-SCPI disable flag.
git clone https://github.com/RFingAdam/mcp-rs-cmw500.git
cd mcp-rs-cmw500
uv pip install -e ".[dev]"cp .env.example .env # edit with your CMW500 IP + safety limits| Variable | Default | Description |
|---|---|---|
CMW_DEFAULT_HOST |
127.0.0.1 |
CMW500 IP address |
CMW_DEFAULT_PORT |
5025 |
SCPI TCP port |
CMW_MAX_GENERATOR_POWER_DBM |
0 |
Max generator output |
CMW_MAX_EXPECTED_POWER_DBM |
33 |
Max analyzer input |
CMW_MAX_FREQUENCY_HZ |
6e9 |
Upper frequency bound |
CMW_ALLOW_RAW_SCPI |
false |
Enable raw SCPI commands |
|
Python import asyncio
from rs_cmw500_mcp.driver import CMW500Driver
from rs_cmw500_mcp.models.cmw_types import CellConfig
async def main():
async with CMW500Driver("192.168.1.100", 5025) as cmw:
await cmw.lte_configure_cell(
CellConfig(band=7, bandwidth_mhz=20, dl_earfcn=3100, dl_level_dbm=-70),
)
await cmw.lte_cell_on()
# ... wait for UE attach ...
await cmw.lte_meas_configure(stat_count=10)
await cmw.lte_meas_trigger()
results = await cmw.lte_meas_fetch_all()
print(results)
asyncio.run(main()) |
MCP (Claude Desktop, Claude Code, any MCP client) {
"mcpServers": {
"rs-cmw500": {
"command": "uv",
"args": [
"--directory", "/path/to/mcp-rs-cmw500",
"run", "rs-cmw500-mcp"
]
}
}
}Then ask your assistant:
The agent walks the LTE measurement workflow tool-by-tool and returns the result set. |
rs-cmw500-mcp # MCP server over stdio131 MCP tools, grouped:
| Group | Count | Examples |
|---|---|---|
| Connection | 6 | cmw_discover, cmw_connect, cmw_identify, cmw_get_status, cmw_query_options |
| GPRF Generator | 7 | cmw_gen_set_frequency, cmw_gen_set_level, cmw_gen_output_on/off, cmw_gen_load_arb, cmw_gen_configure_arb |
| GPRF Analyzer | 11 | cmw_meas_configure_power, cmw_meas_configure_spectrum, cmw_meas_trigger(_spectrum), cmw_meas_fetch_power/spectrum |
| GPRF Signal Path | 4 | cmw_set_signal_path, cmw_get_signal_path, cmw_set_port, cmw_system_all_off |
| LTE Signaling | 16 | cmw_lte_configure_cell, cmw_lte_cell_on/off, cmw_lte_configure_nas/bearer/cdrx, cmw_lte_meas_* |
| LTE RX / Sensitivity | 4 | cmw_lte_rx_configure, cmw_lte_attach_wait, cmw_lte_rx_measure_bler, cmw_lte_rx_sensitivity |
| WLAN Non-Signaling | 11 | cmw_wlan_configure, cmw_wlan_set_standard/bandwidth/frequency, cmw_wlan_fetch_* |
| WLAN Signaling (AP) | 4 | cmw_wlan_sig_configure_ap, cmw_wlan_sig_ap_on/off, cmw_wlan_sig_get_state |
| Bluetooth/BLE Non-Signaling | 11 | cmw_bt_configure, cmw_bt_set_technology/ble_mode/packet_type, cmw_bt_fetch_* |
| BLE Signaling (PER) | 5 | cmw_ble_sig_configure, cmw_ble_sig_connect/detach, cmw_ble_sig_measure_per, cmw_ble_sig_sensitivity |
| GSM Signaling | 6 | cmw_gsm_sig_configure, cmw_gsm_sig_cell_on/off, cmw_gsm_sig_get_state, cmw_gsm_meas_tx, cmw_gsm_sig_ber |
| WCDMA Signaling | 6 | cmw_wcdma_sig_configure, cmw_wcdma_sig_cell_on/off, cmw_wcdma_sig_get_state, cmw_wcdma_meas_tx, cmw_wcdma_sig_ber |
| WLAN Throughput (DAU) | 3 | cmw_data_throughput, cmw_data_iperf_run, cmw_data_ping |
| Coexistence | 5 | cmw_coex_plan, cmw_coex_step, cmw_coex_result, cmw_coex_measure_point, cmw_coex_validate_routing |
| RF Planner (IMD) | 2 | cmw_imd_analyze, cmw_imd_batch |
| Bench Profile | 5 | cmw_profile_load, cmw_profile_show, cmw_profile_save, cmw_profile_list, cmw_profile_apply |
| Test Plan / Reporting | 8 | cmw_testplan_define, cmw_testplan_step/run, cmw_testplan_result, cmw_testplan_report, cmw_testplan_save/load/list |
| SCPI / System | 7 | cmw_scpi_send, cmw_scpi_query, cmw_scpi_query_opc, cmw_system_error, cmw_selftest, cmw_reset, cmw_preset |
| Templates | 3 | cmw_list_templates, cmw_load_template, cmw_apply_template |
| State | 3 | cmw_save_state, cmw_load_state, cmw_get_full_state |
| Limits | 4 | cmw_define_limit, cmw_check_limits, cmw_list_limits, cmw_clear_limits |
Available templates: lte_tx_power, gprf_power, nonsig_rx, wlan_tx,
wlan_rx, ble_tx, ble_rx, bt_classic_tx. Full tool reference in
docs/tools.md.
Beyond tools, the server publishes MCP resources and prompts:
- Resources (
cmw://…): a curated SCPI quick-reference per subsystem (cmw://scpi/{lte,gsm,wcdma,bluetooth,wlan}-signaling,…/wlan-throughput,…/gprf,…/routing,…/system), a reliability-code table, a JSON band-plan dump, overridable band presets, the active bench profile (cmw://profile), and livecmw://capabilities(installed options). This lets an agent construct correct SCPI for any licensed subsystem via the raw-SCPI tools. - Prompts:
bench_bringup,lte_ble_desense_sweep,lte_wifi_coexistence_throughput,rx_sensitivity_search,imd_hit_analysis,subghz_aggressor_sweep— each states the exact tool-call sequence, neutral defaults, and safety reminders.
The coex layer runs one technology as an aggressor while measuring another as a victim:
- LTE ↔ BLE desense —
cmw_coex_planexpands LTE bands × EARFCNs (plus an optional aggressor-off baseline) against BLE data channels;cmw_coex_stepadvances the resumable sweep;cmw_coex_resultreturns a rows(LTE condition) × cols(BLE channel) sensitivity matrix plus long-format data. - LTE + Wi-Fi — emulate an LTE eNB and a Wi-Fi AP simultaneously (separate
RF connectors;
cmw_coex_validate_routingguards against a shared connector). - IMD planning —
cmw_imd_analyze/cmw_imd_batchpredict which harmonic/intermod products land in a victim band (GNSS, Wi-Fi, HaLow, LTE, …) before you spend bench time.
- Per-unit bench profile — one JSON (via
CMW_PROFILE_FILEorcmw_profile_load) captures a unit's connection, safety limits, RF routing map, external attenuation, and expected licenses. Tools consult it for defaults only when an argument is omitted (explicit always wins), so it's drop-in per unit. - Test-plan + reporting engine —
cmw_testplan_definebuilds an ordered plan whose steps invoke any registered tool, with pass/fail limits on dotted result paths and${ctx.key}chaining between steps;cmw_testplan_step/runexecute it resumably;cmw_testplan_reportrenders Markdown / self-contained HTML / CSV. So an agent can author → configure → measure → check → report across any domain. - Bench validation —
cmw_selftestidentifies the unit, lists installed options, and runs a read-only smoke per licensed domain; thebench_bringupprompt walks the whole setup. Hardware integration checks live behindCMW_TEST_HOST(-m integration).
| Domain | Measurements | Standards |
|---|---|---|
| LTE signaling | Cell setup, NAS attach, bearer, C-DRX, TX power, EVM, ACLR, SEM, frequency error | 3GPP TS 36.521 |
| LTE RX sensitivity | Extended-BLER (EBL) coarse+fine search to a target BLER per EARFCN | 3GPP TS 36.521 |
| WLAN | 802.11a/b/g/n/ac/ax @ 20/40/80/160 MHz: TX power, EVM, spectrum flatness, freq error; AP-emulation signaling | IEEE 802.11 |
| Bluetooth Classic | DH1-DH5 packet types: TX power, modulation (DEVM), frequency offset/drift | Bluetooth Core 5.x |
| BLE | 1M / 2M / Coded: TX power, modulation, frequency; signaling PER RX sensitivity | Bluetooth Core 5.x |
| Coexistence | LTE↔BLE desense sweep, LTE+Wi-Fi, IMD/harmonic planning (GNSS/Wi-Fi/HaLow/LTE) | — |
| GPRF | CW/ARB output, power, spectrum — for vendor-specific test sequences | — |
The server enforces configurable safety limits to protect your equipment:
- Generator power — bounded between
CMW_MIN_GENERATOR_POWER_DBMandCMW_MAX_GENERATOR_POWER_DBM. - Analyzer expected power — bounded by
CMW_MAX_EXPECTED_POWER_DBM. - Frequency range — bounded between
CMW_MIN_FREQUENCY_HZandCMW_MAX_FREQUENCY_HZ. - SCPI sanitization — all parameters validated against injection patterns.
- Raw SCPI off by default — must explicitly set
CMW_ALLOW_RAW_SCPI=true. - Path traversal — state-file paths validated against directory traversal.
mcp-rs-cmw500 fits in the following eng-mcp-suite
workflow bundles:
lab-automation— pair withcopper-mountain-vna-mcp,mcp-rs-spectrum-analyzer, andmcp-rs-siggenfor end-to-end RF bench-test workflows driven from a single agent session.cellular-compliance— drive 3GPP TS 36.521 LTE test cases under AI control withmcp-emc-regulationssupplying market-specific limits.
eng-mcp-suite install --workflow lab-automation- 📘 Quick Start — install through first call.
- 🛠️ Tool reference — every MCP tool, every argument.
- 📐 Usage examples — an LTE TX measurement walkthrough.
- 🏗️ Architecture — how this MCP fits in eng-mcp-suite.
- 📝 Changelog
This MCP server is part of
Part of eng-mcp-suite — an open
umbrella of MCP servers for RF / EMC / PCB / signal-integrity engineering. Drop
into the lab-automation workflow bundle with
eng-mcp-suite install --workflow lab-automation.
| Domain | Sibling MCPs |
|---|---|
| RF / Transmission lines | lineforge |
| EMC regulatory | mcp-emc-regulations |
| EM simulation | mcp-openems, mcp-nec2-antenna |
| Diagrams | drawio-engineering-mcp |
| Lab gear | copper-mountain-vna-mcp · mcp-rs-spectrum-analyzer · mcp-rs-siggen · mcp-rs-cmw500 |
See CONTRIBUTING.md for development guidelines.
uv run pytest tests/ -q # all unit tests (no hardware)
uv run pytest tests/ -m "not integration" -q
ruff check src/ tests/ && ruff format src/ tests/
mypy src/rs_cmw500_mcp/AGPL-3.0-or-later. Relicensed from Apache-2.0 in v0.3.0 to align with the eng-mcp-suite toolkit-wide AGPL move.
- Rohde & Schwarz — for the published CMW500 SCPI command reference.
- The MCP working group — for the Model Context Protocol specification.
Part of eng-mcp-suite — built for RF engineers, PCB designers, EMC labs, and AI agents.