Skip to main content

MCP server for GNU Radio — build, validate, run, and export flowgraphs programmatically.

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gnuradio_mcp-2026.2.20.tar.gz (91.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gnuradio_mcp-2026.2.20-py3-none-any.whl (101.6 kB view details)

Uploaded Python 3

File details

Details for the file gnuradio_mcp-2026.2.20.tar.gz.

File metadata

  • Download URL: gnuradio_mcp-2026.2.20.tar.gz
  • Upload date:
  • Size: 91.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"EndeavourOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for gnuradio_mcp-2026.2.20.tar.gz
Algorithm Hash digest
SHA256 a587d7ad2f2dd1adc996a6bc033f8187dc8973b311a8edae5915d749f0366aac
MD5 7433c89fc38d7b06f64984f63b1047e3
BLAKE2b-256 c326eb6aad02038ecde028a61e968d7357e272f9f649e5a23ab2622d8ceeec02

See more details on using hashes here.

File details

Details for the file gnuradio_mcp-2026.2.20-py3-none-any.whl.

File metadata

  • Download URL: gnuradio_mcp-2026.2.20-py3-none-any.whl
  • Upload date:
  • Size: 101.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"EndeavourOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for gnuradio_mcp-2026.2.20-py3-none-any.whl
Algorithm Hash digest
SHA256 f74596ff1b2d0dfdbcf0dc14cf6d4102be525f52c8a6eeaf27c3db522f94d02d
MD5 1e442e9beb8459c98e81e675b4ae8552
BLAKE2b-256 3381c48a5efe28ca4c64789a56e9257d498ebe0fc5a93aaab0d6d864cda7a560

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page