gr-mcp/main.py
Ryan Malloy 5db7d71d2b feat: add AI-assisted block development tools
Implements complete workflow for generating GNU Radio blocks from
descriptions:

Block Generation:
- generate_sync_block, generate_basic_block, generate_interp_block,
  generate_decim_block tools for creating different block types
- Template-based code generation with customizable work logic
- Automatic validation via AST parsing and signature checking

Protocol Analysis:
- Parse protocol specifications into structured models
- Generate decoder pipelines matching modulation to demodulator blocks
- Templates for BLE, Zigbee, LoRa, POCSAG, ADS-B protocols

OOT Export:
- Export generated blocks to full OOT module structure
- Generate CMakeLists.txt, block YAML, Python modules
- gr_modtool-compatible output

Dynamic Tool Registration:
- enable_block_dev_mode/disable_block_dev_mode for context management
- Tools only registered when needed (reduces LLM context usage)

Includes comprehensive test coverage and end-to-end demo.
2026-02-09 12:36:54 -07:00

52 lines
1.5 KiB
Python

from __future__ import annotations
import logging
import os
from fastmcp import FastMCP
from gnuradio_mcp.middlewares.platform import PlatformMiddleware
from gnuradio_mcp.providers.mcp import McpPlatformProvider
from gnuradio_mcp.providers.mcp_block_dev import McpBlockDevProvider
from gnuradio_mcp.providers.mcp_runtime import McpRuntimeProvider
logger = logging.getLogger(__name__)
try:
from gnuradio import gr
from gnuradio.grc.core.platform import Platform
except ImportError:
raise Exception("Cannot find GNU Radio!") from None
platform = Platform(
version=gr.version(),
version_parts=(gr.major_version(), gr.api_version(), gr.minor_version()),
prefs=gr.prefs(),
)
platform.build_library()
app: FastMCP = FastMCP("GNU Radio MCP", instructions="Create GNU Radio flowgraphs")
pmw = PlatformMiddleware(platform)
# Auto-discover OOT modules from common install locations
oot_candidates = [
"/usr/local/share/gnuradio/grc/blocks",
os.path.expanduser("~/.local/share/gnuradio/grc/blocks"),
]
for path in oot_candidates:
if os.path.isdir(path):
try:
result = pmw.add_block_path(path)
if result.blocks_added > 0:
logger.info(f"OOT: +{result.blocks_added} blocks from {path}")
except Exception:
pass
McpPlatformProvider.from_platform_middleware(app, pmw)
McpRuntimeProvider.create(app)
McpBlockDevProvider.create(app) # flowgraph_mw set when flowgraph is loaded
if __name__ == "__main__":
app.run()