Skip to content

Runtime Control

Once a flowgraph is running, you can read and modify variables, control execution, and monitor status through XML-RPC. This enables real-time tuning without restarting.

How It Works

Generated flowgraphs expose variables through an XML-RPC server:

┌─────────────────────────────┐ XML-RPC (HTTP) ┌─────────────────┐
│ GR-MCP │ ←─────────────────────→ │ Flowgraph │
│ (MCP Server) │ get_freq() │ (Python) │
│ │ set_freq(101.1e6) │ │
└─────────────────────────────┘ └─────────────────┘

The flowgraph’s variables become get_X() and set_X() methods automatically.

Prerequisites

Your flowgraph must include an XML-RPC server block, or be launched via GR-MCP’s launch_flowgraph() which configures this automatically.

Connect to a Flowgraph

# Most common: connect to a GR-MCP container
connect_to_container(name="fm-radio")

Both methods return ConnectionInfoModel with endpoint details.

Variable Operations

List Variables

list_variables()
# Returns: [
# VariableModel(name="freq", value=101100000.0, type="float"),
# VariableModel(name="gain", value=40, type="int"),
# VariableModel(name="samp_rate", value=2000000.0, type="float"),
# ]

Get a Variable

101100000.0
get_variable(name="freq")

Set a Variable

set_variable(name="freq", value=98.5e6)
# Returns: True

Thread-Safe Updates

For multiple parameter changes:

# Pause signal processing
lock()
# Make changes (no audio during this)
set_variable(name="freq", value=102.7e6)
set_variable(name="gain", value=35)
set_variable(name="bandwidth", value=200e3)
# Resume processing
unlock()

The flowgraph buffers input during the lock and processes it on unlock.

Execution Control

# Stop the flowgraph (tb.stop())
stop()
# Restart the flowgraph (tb.start())
start()

Check Connection Status

get_status()
# Returns RuntimeStatusModel:
# connected: True
# connection: ConnectionInfoModel(url="http://localhost:8080", ...)
# containers: [ContainerModel(...), ...]

Disconnect

disconnect()
# Closes XML-RPC connection (and ControlPort if active)

Example: FM Band Scanner

#!/usr/bin/env python3
"""Scan FM broadcast band and measure signal strength."""
import asyncio
import time
from fastmcp import Client
FM_STATIONS = [88.1, 90.3, 94.7, 98.5, 101.1, 103.5, 107.9]
async def scan_fm_band():
async with Client("gr-mcp") as client:
await client.call_tool("enable_runtime_mode", {})
# Launch with a signal strength indicator
await client.call_tool("launch_flowgraph", {
"flowgraph_path": "/tmp/fm_scanner.py",
"name": "fm-scanner",
"xmlrpc_port": 8080
})
time.sleep(3)
await client.call_tool("connect_to_container", {"name": "fm-scanner"})
# Scan each station
results = []
for freq_mhz in FM_STATIONS:
await client.call_tool("set_variable", {
"name": "freq",
"value": freq_mhz * 1e6
})
time.sleep(0.5) # Allow settling
# Read signal level (if flowgraph exposes it)
try:
level = await client.call_tool("get_variable", {"name": "signal_level"})
results.append((freq_mhz, level.data))
except Exception:
results.append((freq_mhz, None))
# Report findings
for freq, level in results:
status = f"{level:.1f} dB" if level else "no signal"
print(f"{freq:.1f} MHz: {status}")
# Cleanup
await client.call_tool("stop_flowgraph", {"name": "fm-scanner"})
await client.call_tool("remove_flowgraph", {"name": "fm-scanner"})
if __name__ == "__main__":
asyncio.run(scan_fm_band())

Error Handling

Common errors and solutions:

ErrorCauseSolution
”Not connected”No active XML-RPC connectionCall connect() or connect_to_container()
”Unknown variable”Variable not exposed via XML-RPCCheck flowgraph has XML-RPC block with callback vars
”Connection refused”Container not running / wrong portVerify with list_containers(), get_status()
”Timeout”Flowgraph unresponsiveCheck logs with get_container_logs()

Next Steps