MCP Server
pyadi-iio includes a Model Context Protocol (MCP) server that enables AI assistants and other MCP clients to interact with ADI hardware at runtime. The server exposes tools for device discovery, connection management, property configuration, data capture, and signal generation across all supported device classes.
Installation
Install pyadi-iio with the MCP optional dependencies:
pip install pyadi-iio[mcp]
This installs fastmcp and numpy as additional dependencies.
Running the Server
Start the MCP server using the installed entry point:
pyadi-iio-mcp
Or run it directly as a module:
python -m adi.mcp_server
The server communicates over stdio using the MCP protocol. To use it with an MCP client, configure the client to launch the server as a subprocess. For example, in a Claude Desktop claude_desktop_config.json:
{
"mcpServers": {
"pyadi-iio": {
"command": "pyadi-iio-mcp"
}
}
}
Available Tools
The server provides the following tools:
Device Discovery
list_device_classes – List all available pyadi-iio device classes with an optional name filter. This is useful for finding the correct class name for a specific part.
# Example tool call
list_device_classes(filter_text="936")
# Returns: ["ad9361", "ad9363", "ad9364"]
Connection Management
connect_device – Create a connection to any pyadi-iio device by class name and URI. Returns a connection_id UUID used by all subsequent tools, along with a summary of device capabilities.
# Connect to an AD9361-based device
connect_device(device_class="ad9361", uri="ip:192.168.2.1")
# Connect with extra constructor arguments
connect_device(
device_class="ad9084",
uri="ip:192.168.2.1",
kwargs='{"rx1_device_name": "axi-ad9084-rx-hpc"}',
)
disconnect_device – Close a connection and clean up resources.
Device Introspection
discover_device_capabilities – Inspect a connected device to learn what it supports. Returns whether the device has RX, TX, and DDS capabilities, along with a list of all available properties including read/write metadata and documentation. An optional filter narrows the property list.
# See all properties related to "nco"
discover_device_capabilities(connection_id="...", filter_text="nco")
Property Access
get_property – Read any device property by name. Works with any property exposed by the device class, from sample rates to NCO frequencies to gain settings.
get_property(connection_id="...", property_name="rx_sample_rate")
set_property – Write any writable device property. The value is passed as a JSON-encoded string to support all types (integers, floats, lists, strings).
# Set a scalar value
set_property(connection_id="...", property_name="rx_lo", value="2400000000")
# Set a list value
set_property(
connection_id="...",
property_name="rx_channel_nco_frequencies",
value="[100000000, 200000000]",
)
Data Capture
capture_rx_data – Capture receive data and save it to a .npy file for analysis. Supports configurable buffer sizes and channel selection.
capture_rx_data(
connection_id="...",
output_path="/tmp/capture.npy",
buffer_size=65536,
enabled_channels="[0, 1]",
)
Signal Generation
configure_dds – Configure the FPGA-side DDS to generate a single tone on a specified TX channel. Useful for loopback testing and spectral analysis.
configure_dds(
connection_id="...", frequency=10000000, scale=0.9, channel=0,
)
Example Workflow
A typical interaction with the MCP server follows this pattern:
Discover available device classes with
list_device_classesConnect to hardware with
connect_deviceExplore the device with
discover_device_capabilitiesConfigure the device with
set_propertyCapture data with
capture_rx_dataor generate signals withconfigure_ddsRead back configuration with
get_propertyDisconnect when done with
disconnect_device
# 1. Find the right device class
list_device_classes(filter_text="pluto")
# -> ["Pluto"]
# 2. Connect
result = connect_device(device_class="Pluto", uri="ip:192.168.2.1")
conn_id = result["connection_id"]
# 3. Explore what the device can do
discover_device_capabilities(connection_id=conn_id, filter_text="lo")
# 4. Configure
set_property(connection_id=conn_id, property_name="rx_lo", value="2400000000")
set_property(connection_id=conn_id, property_name="sample_rate", value="2084000")
# 5. Capture data
capture_rx_data(connection_id=conn_id, output_path="/tmp/data.npy")
# 6. Disconnect
disconnect_device(connection_id=conn_id)
API Reference
MCP server for pyadi-iio — runtime device configuration and data capture.
Provides generic tools that work with any pyadi-iio device class through runtime introspection of device properties and capabilities.
- async adi.mcp_server.capture_rx_data(connection_id: str, output_path: str, buffer_size: int = 65536, enabled_channels: str | None = None) str
Capture RX data from a connected device and save to a .npy file.
- Parameters:
connection_id – UUID of an active connection.
output_path – Filesystem path where the .npy file will be saved.
buffer_size – Number of samples to capture (default 65536).
enabled_channels – JSON list of channel indices to enable (e.g. “[0, 1]”). Default: device current setting.
- Returns:
JSON with status, npy_path, and capture metadata.
- async adi.mcp_server.configure_dds(connection_id: str, frequency: int = 10000000, scale: float = 0.9, channel: int = 0) str
Configure the DDS (Digital Direct Synthesis) to generate a single tone.
Sets a single-tone output on the specified TX channel using the FPGA-side DDS. Useful for loopback testing and spectral analysis.
- Parameters:
connection_id – UUID of an active connection.
frequency – Tone frequency in Hz (default 10 MHz). Must be < half the sample rate.
scale – Tone scale factor in range [0, 1] (default 0.9). 1.0 is full-scale.
channel – TX channel index (0-based, default 0).
- Returns:
JSON with status and configured DDS parameters.
- async adi.mcp_server.connect_device(device_class: str, uri: str, kwargs: str | None = None) str
Create a connection to any pyadi-iio device.
- Parameters:
device_class – Name of the device class (e.g. “ad9361”, “Pluto”, “ad9084”). Use list_device_classes to discover available classes.
uri – IIO URI of the target device (e.g. “ip:192.168.2.1”).
kwargs – Optional JSON string of extra constructor keyword arguments (e.g. ‘{“rx1_device_name”: “axi-ad9084-rx-hpc”}’).
- Returns:
JSON with connection_id and device capability summary.
- async adi.mcp_server.disconnect_device(connection_id: str) str
Disconnect from a device and clean up the connection.
- Parameters:
connection_id – UUID of an active connection.
- Returns:
JSON with status.
- async adi.mcp_server.discover_device_capabilities(connection_id: str, filter_text: str | None = None) str
Discover what a connected device supports.
Returns RX/TX/DDS capabilities and all available properties with read/write metadata.
- Parameters:
connection_id – UUID of an active connection.
filter_text – Optional substring to filter property names (case-insensitive).
- Returns:
JSON with device capabilities and property list.
- async adi.mcp_server.get_property(connection_id: str, property_name: str) str
Read a property from a connected device.
- Parameters:
connection_id – UUID of an active connection.
property_name – Name of the property to read (e.g. “rx_lo”, “sample_rate”). Use discover_device_capabilities to see available properties.
- Returns:
JSON with the property value.
- async adi.mcp_server.list_device_classes(filter_text: str | None = None) str
List available pyadi-iio device classes.
- Parameters:
filter_text – Optional substring to filter class names (case-insensitive).
- Returns:
JSON with a list of available device class names.
- async adi.mcp_server.set_property(connection_id: str, property_name: str, value: str) str
Set a property on a connected device.
- Parameters:
connection_id – UUID of an active connection.
property_name – Name of the property to set (e.g. “rx_lo”, “sample_rate”). Use discover_device_capabilities to see writable properties.
value – JSON-encoded value to set (e.g. “1000000000”, “[100, 200]”, ‘“auto”’).
- Returns:
JSON with status and the confirmed value read back from the device.