Ryan Malloy 41dcebbf6d fix: update project URLs from GitHub to Gitea, switch to date-based versioning
- 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
2026-02-20 15:53:02 -07:00
2025-04-27 11:07:35 +03:00

GR-MCP: GNU Radio MCP Server

Python Version License: MIT

GR-MCP is a FastMCP server for GNU Radio 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

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

uv run gnuradio-mcp

3. Add to your MCP client

Claude Code:

claude mcp add gnuradio-mcp -- uv run --directory /path/to/gr-mcp gnuradio-mcp

Claude Desktop / Cursor / other MCP clients:

{
  "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 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

# 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

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

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

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)

# 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

# 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:

# 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

Description
No description provided
Readme MIT 13 MiB
Languages
Python 98.6%
Shell 0.9%
C++ 0.5%