- pyproject.toml URLs now point to git.supported.systems/MCP/gr-mcp - README clone URL updated to match - Version bumped to 2026.02.20 (date-based scheme) - Published to PyPI as gnuradio-mcp==2026.2.20
286 lines
9.2 KiB
Markdown
286 lines
9.2 KiB
Markdown
# GR-MCP: GNU Radio MCP Server
|
|
|
|
[](https://www.python.org/downloads/)
|
|
[](LICENSE)
|
|
|
|
**GR-MCP** is a [FastMCP](https://gofastmcp.com) server for [GNU Radio](https://www.gnuradio.org/) that enables programmatic, automated, and AI-driven creation of GNU Radio flowgraphs. It exposes 80+ MCP tools for building, validating, running, and exporting `.grc` files — plus block development, protocol analysis, and OOT module management.
|
|
|
|
> **What can you do with it?**
|
|
> - Build and validate flowgraphs programmatically
|
|
> - Generate custom GNU Radio blocks from natural language descriptions
|
|
> - Parse protocol specifications into decoder pipelines
|
|
> - Analyze IQ recordings to detect signal characteristics
|
|
> - Export blocks to distributable OOT modules
|
|
> - Run flowgraphs in Docker containers with real-time variable control
|
|
> - Install and manage OOT modules via Docker
|
|
|
|
|
|
## Quickstart
|
|
|
|
### 1. Install
|
|
|
|
```bash
|
|
git clone https://git.supported.systems/MCP/gr-mcp
|
|
cd gr-mcp
|
|
|
|
# Create venv with system site-packages (required for gnuradio)
|
|
uv venv --system-site-packages --python 3.14
|
|
uv sync
|
|
```
|
|
|
|
### 2. Run
|
|
|
|
```bash
|
|
uv run gnuradio-mcp
|
|
```
|
|
|
|
### 3. Add to your MCP client
|
|
|
|
**Claude Code:**
|
|
```bash
|
|
claude mcp add gnuradio-mcp -- uv run --directory /path/to/gr-mcp gnuradio-mcp
|
|
```
|
|
|
|
**Claude Desktop / Cursor / other MCP clients:**
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"gnuradio-mcp": {
|
|
"command": "uv",
|
|
"args": ["run", "--directory", "/path/to/gr-mcp", "gnuradio-mcp"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Requirements
|
|
|
|
- Python >= 3.14
|
|
- GNU Radio (tested with GRC v3.10.12.0)
|
|
- Docker (optional — for runtime control, block testing, OOT builds)
|
|
- [uv](https://docs.astral.sh/uv/) package manager
|
|
|
|
> **Note:** GR-MCP is designed for single-session use. All connected MCP clients share the same flowgraph state. Run one server instance per concurrent session.
|
|
|
|
|
|
## Features
|
|
|
|
### Flowgraph Building (30 tools)
|
|
|
|
Build, edit, validate, and export `.grc` files:
|
|
|
|
| Category | Tools |
|
|
|----------|-------|
|
|
| Blocks | `make_block`, `remove_block`, `get_blocks` |
|
|
| Parameters | `get_block_params`, `set_block_params` |
|
|
| Ports | `get_block_sources`, `get_block_sinks` |
|
|
| Connections | `connect_blocks`, `disconnect_blocks`, `get_connections` |
|
|
| Validation | `validate_block`, `validate_flowgraph`, `get_all_errors` |
|
|
| Persistence | `save_flowgraph`, `load_flowgraph` |
|
|
| Code Gen | `generate_code` |
|
|
| Discovery | `get_all_available_blocks`, `search_blocks`, `get_block_categories` |
|
|
| Options | `get_flowgraph_options`, `set_flowgraph_options` |
|
|
| Python | `create_embedded_python_block`, `evaluate_expression` |
|
|
| Bypass | `bypass_block`, `unbypass_block` |
|
|
| Import/Export | `export_flowgraph_data`, `import_flowgraph_data` |
|
|
| OOT Paths | `load_oot_blocks`, `add_block_path`, `get_block_paths` |
|
|
|
|
### Block Development (18 tools, dynamically registered)
|
|
|
|
Generate, validate, test, and export custom blocks. These tools are registered on-demand via `enable_block_dev_mode` to minimize context usage:
|
|
|
|
| Category | Tools |
|
|
|----------|-------|
|
|
| Generation | `generate_sync_block`, `generate_basic_block`, `generate_interp_block`, `generate_decim_block` |
|
|
| Validation | `validate_block_code`, `parse_block_prompt` |
|
|
| Testing | `test_block_in_docker` |
|
|
| Integration | `inject_generated_block` |
|
|
| Protocol | `parse_protocol_spec`, `generate_decoder_chain`, `get_missing_oot_modules` |
|
|
| Signal | `analyze_iq_file` |
|
|
| OOT Export | `generate_oot_skeleton`, `export_block_to_oot`, `export_from_flowgraph` |
|
|
| Mode | `enable_block_dev_mode`, `disable_block_dev_mode`, `get_block_dev_mode` |
|
|
|
|
### Runtime Control (36 tools)
|
|
|
|
Run flowgraphs in Docker containers with real-time control:
|
|
|
|
| Category | Tools |
|
|
|----------|-------|
|
|
| XML-RPC | `connect`, `disconnect`, `get_status`, `list_variables`, `get_variable`, `set_variable` |
|
|
| Execution | `start`, `stop`, `lock`, `unlock` |
|
|
| ControlPort | `connect_controlport`, `disconnect_controlport`, `get_knobs`, `set_knobs`, `get_knob_properties`, `get_performance_counters`, `post_message` |
|
|
| Docker | `launch_flowgraph`, `list_containers`, `stop_flowgraph`, `remove_flowgraph`, `connect_to_container`, `capture_screenshot`, `get_container_logs` |
|
|
| Coverage | `collect_coverage`, `generate_coverage_report`, `combine_coverage`, `delete_coverage` |
|
|
| OOT Mgmt | `detect_oot_modules`, `install_oot_module`, `list_oot_images`, `remove_oot_image`, `build_multi_oot_image`, `list_combo_images`, `remove_combo_image` |
|
|
|
|
### MCP Resources
|
|
|
|
| Resource URI | Description |
|
|
|-------------|-------------|
|
|
| `oot://directory` | Curated directory of 20 OOT modules (12 preinstalled) |
|
|
| `oot://directory/{module}` | Details for a specific OOT module |
|
|
| `prompts://block-generation/*` | Block generation patterns and templates |
|
|
| `prompts://protocol-analysis/*` | Decoder pipeline guidance |
|
|
|
|
|
|
## Usage Examples
|
|
|
|
### Building a flowgraph
|
|
|
|
```python
|
|
# Create blocks
|
|
make_block(block_type="analog_sig_source_x", name="sig_source")
|
|
make_block(block_type="audio_sink", name="speaker")
|
|
|
|
# Configure
|
|
set_block_params(block_name="sig_source", params={
|
|
"freq": "1000",
|
|
"amplitude": "0.5",
|
|
"waveform": "analog.GR_COS_WAVE"
|
|
})
|
|
|
|
# Wire and save
|
|
connect_blocks(
|
|
source_block="sig_source", source_port="0",
|
|
sink_block="speaker", sink_port="0"
|
|
)
|
|
validate_flowgraph()
|
|
save_flowgraph(path="/tmp/my_flowgraph.grc")
|
|
```
|
|
|
|
### Generating a custom block
|
|
|
|
```python
|
|
enable_block_dev_mode()
|
|
|
|
generate_sync_block(
|
|
name="pm_demod",
|
|
description="Phase modulation demodulator",
|
|
inputs=[{"dtype": "complex", "vlen": 1}],
|
|
outputs=[{"dtype": "float", "vlen": 1}],
|
|
parameters=[{"name": "sensitivity", "dtype": "float", "default": 1.0}],
|
|
work_logic="Extract instantaneous phase from complex samples"
|
|
)
|
|
```
|
|
|
|
### Protocol analysis to decoder chain
|
|
|
|
```python
|
|
enable_block_dev_mode()
|
|
|
|
# Parse a protocol spec
|
|
protocol = parse_protocol_spec(
|
|
"GFSK at 250k baud, deviation: 25khz, preamble 0xAA, sync 0x2DD4"
|
|
)
|
|
|
|
# Generate the decoder pipeline
|
|
chain = generate_decoder_chain(protocol=protocol, sample_rate=2000000.0)
|
|
# Returns: blocks, connections, variables, missing_oot_modules
|
|
```
|
|
|
|
### Exporting to an OOT module
|
|
|
|
```python
|
|
enable_block_dev_mode()
|
|
|
|
# Generate block
|
|
block = generate_sync_block(name="my_filter", ...)
|
|
|
|
# Export to distributable OOT module
|
|
export_block_to_oot(
|
|
generated=block,
|
|
module_name="mymodule",
|
|
output_dir="/path/to/gr-mymodule",
|
|
author="Your Name"
|
|
)
|
|
# Creates: CMakeLists.txt, python/mymodule/my_filter.py, grc/mymodule_my_filter.block.yml
|
|
```
|
|
|
|
### Runtime control (Docker)
|
|
|
|
```python
|
|
# Launch flowgraph in container
|
|
launch_flowgraph(
|
|
flowgraph_path="/path/to/flowgraph.py",
|
|
name="my-sdr",
|
|
xmlrpc_port=8080,
|
|
enable_vnc=True
|
|
)
|
|
|
|
# Tune in real-time
|
|
connect_to_container(name="my-sdr")
|
|
set_variable(name="freq", value=2.4e9)
|
|
|
|
# Inspect and clean up
|
|
capture_screenshot(name="my-sdr")
|
|
stop_flowgraph(name="my-sdr")
|
|
```
|
|
|
|
|
|
## Architecture
|
|
|
|
```
|
|
src/gnuradio_mcp/
|
|
├── server.py # FastMCP app entry point
|
|
├── models.py # Pydantic models for all tools
|
|
├── utils.py # Unique IDs, error formatting
|
|
├── oot_catalog.py # Curated OOT module directory
|
|
├── middlewares/
|
|
│ ├── platform.py # GNU Radio Platform wrapper
|
|
│ ├── flowgraph.py # Block/connection management
|
|
│ ├── block.py # Parameter/port access
|
|
│ ├── ports.py # Port resolution utilities
|
|
│ ├── docker.py # Docker container lifecycle
|
|
│ ├── xmlrpc.py # XML-RPC variable control
|
|
│ ├── thrift.py # ControlPort/Thrift client
|
|
│ ├── oot.py # OOT module Docker builds
|
|
│ ├── block_generator.py # Code generation for custom blocks
|
|
│ ├── oot_exporter.py # Export blocks to OOT modules
|
|
│ └── protocol_analyzer.py # Protocol parsing, decoder chains, IQ analysis
|
|
└── providers/
|
|
├── base.py # PlatformProvider (flowgraph tools)
|
|
├── mcp.py # McpPlatformProvider (registers tools)
|
|
├── runtime.py # RuntimeProvider (Docker/XML-RPC/Thrift)
|
|
├── mcp_runtime.py # McpRuntimeProvider (registers tools)
|
|
├── block_dev.py # BlockDevProvider (generation/analysis)
|
|
└── mcp_block_dev.py # McpBlockDevProvider (dynamic registration)
|
|
```
|
|
|
|
**Data flow:** GNU Radio objects → Middlewares (validation/rewrite) → Pydantic Models (serialization) → MCP Tools
|
|
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# Install all dependencies
|
|
uv sync --all-extras
|
|
|
|
# Run tests
|
|
pytest
|
|
|
|
# Run specific test suite
|
|
pytest tests/unit/
|
|
pytest tests/integration/
|
|
|
|
# Pre-commit hooks (black, flake8, isort, mypy)
|
|
pre-commit run --all-files
|
|
```
|
|
|
|
|
|
## Docker Images (Optional)
|
|
|
|
For runtime control and block testing:
|
|
|
|
```bash
|
|
# Runtime image (Xvfb + VNC + ImageMagick)
|
|
docker build -f docker/Dockerfile.gnuradio-runtime -t gnuradio-runtime:latest docker/
|
|
|
|
# Coverage image (adds python3-coverage)
|
|
docker build -f docker/Dockerfile.gnuradio-coverage -t gnuradio-coverage:latest docker/
|
|
```
|
|
|
|
|
|
## License
|
|
|
|
[MIT](LICENSE)
|