MCP server for Digilent Analog Discovery devices
Project description
Analog Discovery MCP Server
Python MCP server for Digilent Analog Discovery 2 and Analog Discovery 3.
This project exposes a small local instrument-control tool surface for MCP clients:
- Detect the installed Digilent WaveForms SDK version.
- List connected WaveForms-compatible devices.
- Read one analog input voltage sample from channel 1 or 2.
- Capture analog input waveforms with optional analog edge triggers.
- Measure core voltage statistics from one analog input channel.
- Drive Wavegen outputs: sine, square, triangle, DC, and bounded custom samples.
- Read and drive static digital I/O pins.
- Safely release active outputs and the WaveForms device handle.
Analog waveform capture is supported for small local captures.
Requirements
- Python 3.11 or newer
- uv for local development
- Digilent WaveForms installed on the machine that runs the MCP server
WaveForms includes the WaveForms SDK dynamic library used by this server:
- Windows:
dwf - macOS:
/Library/Frameworks/dwf.framework/dwf - Linux:
libdwf.so
Install From PyPI
Run directly with uvx:
uvx analog-discovery-mcp-server
Or install into an environment:
pip install analog-discovery-mcp-server
analog-discovery-mcp-server
The server uses MCP stdio transport. Your MCP client starts this process and talks to it over standard input/output; no port or web server is opened.
Install From Source
For local development from a clone of this repository:
uv sync
uv run analog-discovery-mcp-server
Run Without Hardware
Use the fake backend to test MCP client wiring when no Analog Discovery device is connected:
AD_MCP_DWF_BACKEND=fake uvx analog-discovery-mcp-server
The fake backend is deterministic and for demos only. It reports one fake Analog Discovery 3 device, fixed voltage readings for channels 1 and 2, and simulated waveform capture payloads for client prototyping. It also simulates Wavegen output state and static digital I/O state for tests.
MCP Client Configuration
Example local configuration:
{
"mcpServers": {
"analog-discovery": {
"command": "uvx",
"args": [
"analog-discovery-mcp-server"
]
}
}
}
Development configuration from a source checkout:
{
"mcpServers": {
"analog-discovery-dev": {
"command": "uv",
"args": [
"--directory",
"/path/to/analog-discovery-mcp-server",
"run",
"analog-discovery-mcp-server"
]
}
}
}
Device Selection
Tools can select a device using either device_index or serial_number.
You can also set defaults:
export AD_MCP_DEVICE_INDEX=0
export AD_MCP_DEVICE_SERIAL=SN:210415BD66A3
Set only one default at a time. Explicit tool arguments override environment defaults.
Tools
These tools are available through MCP for both real WaveForms hardware and the fake backend.
Device And SDK
get_waveforms_version
Returns the detected WaveForms SDK version.
list_devices
Returns connected devices with index, name, serial number, and availability.
Analog Input
read_analog_voltage
Reads one analog input voltage sample.
Inputs:
channel:1or2device_index: optional zero-based device indexserial_number: optional device serial number
get_analog_capture_limits
Returns analog waveform capture limits for the selected device.
The fake backend reports AD3-like limits: 32,768 samples per channel and 65,536 total returned samples. The real backend reports supported analog input channels and WaveForms buffer limits, with a conservative total returned sample limit.
capture_analog_waveform
Returns analog input waveform samples for the selected channel or channels.
Inputs:
channels: optional list containing1,2, or both; default[1]sample_rate_hz: positive sample rate; default1000.0sample_count: samples per channel; default1000device_index: optional zero-based device indexserial_number: optional device serial numbertrigger_enabled: optional analog edge trigger enable; defaultfalsetrigger_channel: optional trigger channel; defaults to first requested channeltrigger_level_v: trigger level in volts; default0.0trigger_edge:risingorfalling; defaultrisingtrigger_hysteresis_v: trigger hysteresis in volts; default0.05trigger_auto_timeout_seconds: auto-trigger timeout; default1.0trigger_position_seconds: trigger position in capture window; default half duration
The server rejects requests above reported capture limits. It does not silently truncate or clamp sample arrays.
The response includes sample arrays plus metadata such as actual sample rate, trigger state, valid sample count, lost/corrupt sample counts, and WaveForms status time when available.
measure_analog_waveform
Captures one analog input channel and returns core voltage statistics without raw sample arrays.
Inputs match capture_analog_waveform for one channel. If a trigger is enabled,
trigger_channel must be the measured channel or omitted. To measure channel
2 while triggering from channel 1, use capture_analog_waveform with
channels: [1, 2] and compute statistics from the returned samples.
Outputs include:
min_voltagemax_voltagemean_voltagerms_voltagepeak_to_peak_voltage- capture metadata such as actual sample rate, duration, trigger state, and device
get_analog_input_status
Returns AnalogIn capability and status metadata for the selected device.
Outputs include channel count, frequency limits, buffer limits, current frequency and buffer size, per-channel range/offset, and current AnalogIn state when available.
Wavegen Output
get_wavegen_limits
Returns Wavegen output channels, supported waveforms, defaults, and per-channel limits.
start_wavegen
Starts Wavegen output on one analog output channel.
Inputs:
channel: output channel, usually1or2; default1waveform:sine,square,triangle,dc, orcustom; defaultsinefrequency_hz: output frequency for non-DC waveforms; default1000.0amplitude_v: peak amplitude for non-DC waveforms; default1.0offset_v: voltage offset, or DC output voltage fordc; default0.0duty_cycle_percent: symmetry/duty cycle; default50.0samples: normalizedcustomwaveform samples, each between-1.0and1.0sample_rate_hz: playback sample rate forcustom; required withsamplesdevice_index: optional zero-based device indexserial_number: optional device serial number
For dc, the server uses offset_v as the output voltage and returns an effective
amplitude_v of 0.0.
For custom, samples defines one repeated cycle. The server converts
sample_rate_hz / len(samples) into the WaveForms cycle frequency and validates the
sample count against get_wavegen_limits.
Example custom waveform:
{
"waveform": "custom",
"samples": [-1.0, 0.0, 1.0, 0.0],
"sample_rate_hz": 4000.0,
"amplitude_v": 1.0,
"offset_v": 0.0
}
start_synchronized_wavegen
Starts multiple Wavegen output channels with hardware synchronization.
Inputs:
channels: output channels; default[1, 2]waveforms: one waveform per channel; supportssine,square,triangle, anddcfrequencies_hz: one frequency per channel; default1000.0amplitudes_v: one peak amplitude per channel; default1.0offsets_v: one voltage offset per channel; default0.0duty_cycles_percent: one symmetry/duty cycle per channel; default50.0phase_degrees: one phase per channel; default[0.0, 180.0]for two channelsmaster_channel: channel that starts the synchronized group; default1device_index: optional zero-based device indexserial_number: optional device serial number
All provided per-channel lists must have the same length as channels. The synchronized
tool uses WaveForms master/slave hardware control and phase settings; custom waveforms
are not supported by this tool.
Example synchronized opposite-phase sine:
{
"channels": [1, 2],
"waveforms": ["sine", "sine"],
"frequencies_hz": [1000.0, 1000.0],
"amplitudes_v": [2.0, 2.0],
"offsets_v": [0.0, 0.0],
"phase_degrees": [0.0, 180.0],
"master_channel": 1
}
stop_wavegen
Stops Wavegen output on one channel. The fake backend preserves the last config in status.
get_wavegen_status
Returns Wavegen state, running flag, and current config when available.
release_device
Safely releases MCP ownership of the selected device. This stops active Wavegen channels tracked by the server, disables static DIO outputs, and closes the cached WaveForms device handle so other applications can open the hardware.
Inputs:
device_index: optional zero-based device indexserial_number: optional device serial number
Outputs include released, wavegen_channels_stopped,
digital_output_enable_mask, and device.
Digital I/O
Digital pin numbers are zero-based and match WaveForms labels: public pin 0 is DIO0.
get_digital_io_limits
Returns static digital I/O pin capabilities for the selected device.
Outputs include:
supported_input_pinssupported_output_pinsinput_maskoutput_enable_maskdevice
read_digital_inputs
Reads static digital input pin values.
Inputs:
pins: optional list of zero-based DIO pins; default reads all supported input pinsdevice_index: optional zero-based device indexserial_number: optional device serial number
Outputs include selected pins, string-keyed boolean values, raw input_mask, and device.
write_digital_outputs
Writes static digital output pin values.
Inputs:
pins: list of zero-based output pinsvalues: same-length list of booleanspreserve_existing: keep unselected output state when true; defaulttruedevice_index: optional zero-based device indexserial_number: optional device serial number
Outputs include selected pins, string-keyed boolean values, output_enable_mask,
output_mask, and device.
Development
uv sync
uv run ruff check
uv run mypy
uv run pytest -q
uv build
Test the MCP server without hardware:
AD_MCP_DWF_BACKEND=fake uv run analog-discovery-mcp-server
Hardware integration tests are skipped by default. Enable them explicitly:
AD_MCP_HARDWARE_TESTS=1 uv run pytest -m hardware
Hardware tests can also select a documented physical stand:
AD_MCP_HARDWARE_TESTS=1 AD_MCP_HARDWARE_STAND=advanced uv run pytest -m hardware -q
Available stands are documented in docs/HARDWARE_TESTING.md. External real MCP client/agent validation scenarios are documented in docs/REAL_AGENT_VALIDATION.md.
The staged development plan lives in docs/ROADMAP.md.
AI Assistance
This project was created and developed with help from AI coding agents. Human maintainers review, test, and maintain accepted changes, and remain responsible for correctness, licensing, safety, and releases.
AI tools are not authors or copyright holders for this project.
Safety
Wavegen and digital output tools drive hardware outputs. Verify wiring, voltage range, load, and common ground before starting output.
Reading and capturing analog input still opens and configures the selected WaveForms device as required by the SDK. Check input voltage limits before connecting any circuit to Analog Discovery hardware.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file analog_discovery_mcp_server-0.2.0.tar.gz.
File metadata
- Download URL: analog_discovery_mcp_server-0.2.0.tar.gz
- Upload date:
- Size: 122.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
afc4e88dd6fd4d80418aff83053981e87d1352b8dfe47b02f5cc7d85ce7bb7e7
|
|
| MD5 |
3eef754c185918426821f6f02ddace3a
|
|
| BLAKE2b-256 |
d54481cb33c13e179ce855e0e1fc4a1320610a6ab472ad850dd3f9dd9c413b24
|
Provenance
The following attestation bundles were made for analog_discovery_mcp_server-0.2.0.tar.gz:
Publisher:
release.yml on vliboras/analog-discovery-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
analog_discovery_mcp_server-0.2.0.tar.gz -
Subject digest:
afc4e88dd6fd4d80418aff83053981e87d1352b8dfe47b02f5cc7d85ce7bb7e7 - Sigstore transparency entry: 1943773724
- Sigstore integration time:
-
Permalink:
vliboras/analog-discovery-mcp-server@4adec632a6613db74842df046e8e6a3dd7983e0f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/vliboras
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4adec632a6613db74842df046e8e6a3dd7983e0f -
Trigger Event:
push
-
Statement type:
File details
Details for the file analog_discovery_mcp_server-0.2.0-py3-none-any.whl.
File metadata
- Download URL: analog_discovery_mcp_server-0.2.0-py3-none-any.whl
- Upload date:
- Size: 26.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81091abff6dccaaf80ca6d4d992340f0ba3b20157a0db3b82fb45c3d31e0b078
|
|
| MD5 |
7129956b36b544cf8940535d94df3165
|
|
| BLAKE2b-256 |
35748e6c923c6311c63ed70c9c5f79ec7281a28fe551d150591cf47362eb4006
|
Provenance
The following attestation bundles were made for analog_discovery_mcp_server-0.2.0-py3-none-any.whl:
Publisher:
release.yml on vliboras/analog-discovery-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
analog_discovery_mcp_server-0.2.0-py3-none-any.whl -
Subject digest:
81091abff6dccaaf80ca6d4d992340f0ba3b20157a0db3b82fb45c3d31e0b078 - Sigstore transparency entry: 1943773985
- Sigstore integration time:
-
Permalink:
vliboras/analog-discovery-mcp-server@4adec632a6613db74842df046e8e6a3dd7983e0f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/vliboras
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4adec632a6613db74842df046e8e6a3dd7983e0f -
Trigger Event:
push
-
Statement type: