GNU Radio MCP Server
An MCP (Model Context Protocol) server that bridges an LLM to a live GNU Radio SDR flowgraph. Control your software-defined radio — tune frequencies, adjust gain, capture IQ samples, analyse spectra, and sweep for signals — all through natural language via any MCP-compatible client.
Architecture
┌─────────────┐ MCP (stdio / HTTP) ┌──────────────────┐
│ LLM / │◄──────────────────────────────►│ gnuradio_mcp │
│ Claude │ tool calls & │ MCP Server │
│ Desktop │ responses │ │
└─────────────┘ └──┬──────────┬───┘
│ │
XML-RPC │ │ ZMQ SUB
(control) │ │ (IQ data)
▼ ▼
┌────────────────────┐
│ GNU Radio │
│ Companion │
│ Flowgraph │
│ ┌──────────────┐ │
│ │ XMLRPC Server │ │
│ │ ZMQ PUB Sink │ │
│ └──────────────┘ │
└────────┬───────────┘
│
▼
┌────────────────────┐
│ SDR Hardware │
│ (HackRF / RTL-SDR │
│ / USRP / Sim) │
└────────────────────┘
Quick Start (Simulation — No Hardware)
pip install gnuradio-mcp-server
# Open simulation_mcp.grc in GNU Radio Companion and click Run
# (provides two test tones at +10 kHz and +50 kHz from center)
gnuradio-mcp
Quick Start (HackRF)
pip install gnuradio-mcp-server
# Open hackrf_mcp.grc in GNU Radio Companion and click Run & ensure HackRF is connected
GNURADIO_HARDWARE=hackrf gnuradio-mcp
Claude Desktop Integration
Add the following to your claude_desktop_config.json:
{
"mcpServers": {
"gnuradio_mcp": {
"command": "gnuradio-mcp",
"args": [],
"env": {
"GNURADIO_HARDWARE": "hackrf",
"GNURADIO_GR_HOST": "127.0.0.1",
"GNURADIO_GR_XMLRPC_PORT": "8080",
"GNURADIO_GR_ZMQ_PORT": "5555"
}
}
}
}
For HTTP transport:
{
"mcpServers": {
"gnuradio_mcp": {
"url": "http://127.0.0.1:8000/mcp",
"transport": "streamable-http"
}
}
}
Tools Reference
| # | Tool Name | Description | Read-Only |
|---|---|---|---|
| 1 | gnuradio_flowgraph_start |
Start the GNU Radio flowgraph | No |
| 2 | gnuradio_flowgraph_stop |
Stop the GNU Radio flowgraph | No |
| 3 | gnuradio_flowgraph_status |
Get flowgraph status and current parameters | Yes |
| 4 | gnuradio_set_center_frequency |
Set the SDR center frequency | No |
| 5 | gnuradio_set_sample_rate |
Set the SDR sample rate | No |
| 6 | gnuradio_set_gain |
Set the SDR gain (IF/RF/BB stages) | No |
| 7 | gnuradio_set_variable |
Set an arbitrary flowgraph variable | No |
| 8 | gnuradio_get_variable |
Read an arbitrary flowgraph variable | Yes |
| 9 | gnuradio_list_variables |
List all flowgraph variables | Yes |
| 10 | gnuradio_capture_samples |
Capture IQ samples and return a power summary | Yes |
| 11 | gnuradio_get_spectrum_snapshot |
FFT/PSD analysis with peak detection | Yes |
| 12 | gnuradio_detect_signals |
Sweep a frequency range and detect active signals | Yes |
| 13 | gnuradio_ping |
Health check (XML-RPC + ZMQ connectivity) | Yes |
Environment Variables
All variables use the GNURADIO_ prefix:
| Variable | Default | Description |
|---|---|---|
GNURADIO_GR_HOST |
127.0.0.1 |
GNU Radio host address |
GNURADIO_GR_XMLRPC_PORT |
8080 |
XML-RPC server port |
GNURADIO_GR_ZMQ_PORT |
5555 |
ZMQ PUB sink port |
GNURADIO_GR_XMLRPC_TIMEOUT |
5 |
XML-RPC timeout in seconds |
GNURADIO_GR_ZMQ_TIMEOUT_MS |
3000 |
ZMQ receive timeout in ms |
GNURADIO_HARDWARE |
hackrf |
Hardware type: hackrf/rtlsdr/usrp/simulation |
GNURADIO_FREQ_MIN_HZ |
1000000 |
Minimum tunable frequency (Hz) |
GNURADIO_FREQ_MAX_HZ |
6000000000 |
Maximum tunable frequency (Hz) |
GNURADIO_GAIN_MIN_DB |
0 |
Minimum gain (dB) |
GNURADIO_GAIN_MAX_DB |
62 |
Maximum gain (dB) |
GNURADIO_SAMP_RATE_MIN |
100000 |
Minimum sample rate (sps) |
GNURADIO_SAMP_RATE_MAX |
20000000 |
Maximum sample rate (sps) |
GNURADIO_DEFAULT_SAMP_RATE |
2000000 |
Default sample rate for DSP |
GNURADIO_TRANSPORT |
stdio |
Transport: stdio / streamable_http |
GNURADIO_HTTP_PORT |
8000 |
HTTP transport port |
Edge Cases & Known Limitations
-
Sample rate restart: Some SDR hardware (especially RTL-SDR) requires a flowgraph restart after changing the sample rate. The
gnuradio_set_sample_ratetool includes a warning about this. -
ZMQ dtype requirement: The ZMQ PUB Sink in your flowgraph must output
complex64(8 bytes per sample). Misaligned data will raise aGRHardwareError. -
Frequency clamping: Frequencies outside the configured
[freq_min_hz, freq_max_hz]range are rejected before being sent to hardware. Adjust the env vars for your specific hardware. -
Context overflow warning: Capturing more than 65,536 IQ samples triggers a warning, as the response summary may still be large. Use
gnuradio_get_spectrum_snapshotfor analysed results instead. -
XML-RPC not thread-safe: A new
ServerProxyis created per RPC call to avoid shared-state bugs in async contexts. -
ZMQ socket lifecycle: Each
recv_samplescall opens and closes its own ZMQ SUB socket. This is intentional — the slight overhead avoids shared-socket state issues.
Development
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Run with HTTP transport
GNURADIO_TRANSPORT=streamable_http python -m gnuradio_mcp.server
License
MIT
Metadata
Release files for gnuradio-mcp-server 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| gnuradio_mcp_server-0.1.1.tar.gz | 23.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gnuradio_mcp_server-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.8 kB
Release files / gnuradio_mcp_server-0.1.1.tar.gz
| Download URL | gnuradio_mcp_server-0.1.1.tar.gz |
|---|---|
| Size | 23.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1bf7cc123c688474476c2cbf1ff7ec963b83603728e29715a3974648dfbc494c
|
|
BLAKE2b-256 checksum How to use checksums |
05a4ed1ff0b7d30ab8804168519b8dcc822fb86b9be239ed0fb7a5931748d916
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / gnuradio_mcp_server-0.1.1-py3-none-any.whl
| Download URL | gnuradio_mcp_server-0.1.1-py3-none-any.whl |
|---|---|
| Size | 20.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
561c8f6db3dfbf85403056027e7b2bd3857ad7f852ef15abe60d613e8b9b11fc
|
|
BLAKE2b-256 checksum How to use checksums |
545c8e21e48e6f21373b69bba92ac676a77c59ecc1af366bbe7ac640bb10496b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Security for gnuradio-mcp-server 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.