MCP server to read waveform files
Overview
An MCP (Model Context Protocol) server for reading and analyzing waveform files (VCD/FST format) using the wellen library. The built binary will be at ~/.cargo/bin/waveform-mcp. The built binary will be at target/release/waveform-mcp. The server supports two transport modes: - (default): Uses standard input/output for MCP communication - : Uses streamable HTTP server for remote access at /mcp endpoint When running in HTTP mode, the server listens on the specified bind address (default: 127.0.0.1:8000). HTTP mode allows the waveform store to be shared across multiple HTTP sessions, enabling remote analysis of waveform files.
README
Waveform MCP Server
An MCP (Model Context Protocol) server for reading and analyzing waveform files (VCD/FST format) using the wellen library.
Usage
Installation
Install via cargo:
cargo install waveform-mcp
The built binary will be at ~/.cargo/bin/waveform-mcp.
Install manually:
# Clone the repository
git clone https://github.com/jiegec/waveform-mcp
cd waveform-mcp
# Build the server
cargo build --release
The built binary will be at target/release/waveform-mcp.
Running
# Run the server with stdio transport (default)
target/release/waveform-mcp
# Run the server in HTTP mode
target/release/waveform-mcp --http
# Run the server in HTTP mode with custom bind address
target/release/waveform-mcp --http --bind-address 0.0.0.0:8000
The server supports two transport modes:
- Stdio mode (default): Uses standard input/output for MCP communication
- HTTP mode: Uses streamable HTTP server for remote access at
/mcpendpoint
When running in HTTP mode, the server listens on the specified bind address (default: 127.0.0.1:8000). HTTP mode allows the waveform store to be shared across multiple HTTP sessions, enabling remote analysis of waveform files.
Features
- Open VCD (Value Change Dump) and FST (Fast Signal Trace) waveform files
- List all signals in a waveform with hierarchical paths
- Read the waveform module hierarchy as an indented tree
- Read signal values at specific time indices (single or multiple)
- Get signal metadata (type, width, index range)
- Find signal events (changes) within a time range
- Format time values with timescale information (e.g., “10ns”, “5000ps”)
- Streamable HTTP server support for remote access
Tools
The server provides 8 MCP tools:
-
open_waveform - Open a waveform file
file_path: Path to .vcd or .fst filealias: Optional alias for the waveform (defaults to filename)overwrite: Optional flag to reopen a waveform whose id is already open (default: false); otherwise opening an id twice is an error
When the file does not exist, files with a similar name in the same directory are suggested. Failures are reported as tool errors, like every other tool.
Example response:
Waveform opened successfully with alias: waveform.vcd -
close_waveform - Close a waveform and free its memory
waveform_id: ID or alias of the waveform to close
Example response:
Waveform 'waveform.vcd' closed successfully -
list_signals - List all signals in an open waveform
waveform_id: ID or alias of the waveformpattern: Optional pattern (a string or an array of strings) matched against the full signal path, e.g.tb.dut.abc_bank. Multiple patterns are OR-edmatch_mode: Howpatternis interpreted (default:substring)substring- case-insensitive substring match (the pattern is a literal fragment)glob- case-insensitive glob over the whole path:*(any characters, including dots),?(one character),[0-9],{a,b}— e.g.*bank*,tb.*.clkregex- regular expression, case-insensitive by default (use(?-i)to opt out)
hierarchy_prefix: Optional prefix to filter signals by hierarchy path (AND-ed withpattern)recursive: Optional flag to include signals from sub-hierarchies (default: true)limit: Optional maximum number of signals to return (default: 100)
Invalid glob or regex patterns are reported as errors rather than silently matching nothing, and when nothing matches the response suggests the closest signal paths.
Example response:
Found 3 signals: top.clock top.reset top.data -
read_hierarchy - Read the waveform module hierarchy as an indented tree
waveform_id: ID or alias of the waveformscope_path: Optional scope path to start fromrecursive: Optional flag to include descendants (default: false)limit: Optional maximum number of modules to return (default: 200)
Example response:
Hierarchy rooted at 'top': top submodule -
read_signal - Read signal values at specific time indices
waveform_id: ID or alias of the waveformsignal_path: Hierarchical path to signal (e.g., “top.module.signal”)time_index: Optional single time index to read (provide exactly one oftime_indexortime_indices)time_indices: Optional array of time indices to read multiple values
Example response:
Time index 0 (0ns): 0 Time index 10 (10ns): 1 Time index 20 (20ns): 1 -
get_signal_info - Get metadata about a signal
waveform_id: ID or alias of the waveformsignal_path: Hierarchical path to signal
Example response:
Signal: top.data Type: Wire Width: 8 bits Index: [7:0] -
find_signal_events - Find all signal changes within a time range
waveform_id: ID or alias of the waveformsignal_path: Hierarchical path to signalstart_time_index: Optional start of time range (default: 0)end_time_index: Optional end of time range (default: last time index)limit: Optional maximum number of events to return (default: unlimited)
Example response:
Found 3 events for signal 'top.clock' (time range: 0 to 20): Time index 0 (0ns): 0 Time index 10 (10ns): 1 Time index 20 (20ns): 0 -
find_conditional_events - Find events where a condition is satisfied
waveform_id: ID or alias of waveformcondition: Conditional expression to evaluatestart_time_index: Optional start of time range (default: 0)end_time_index: Optional end of time range (default: last time index)limit: Optional maximum number of events to return (default: 100)
Example response:
Found 2 events for condition '!$past(TOP.signal) && TOP.signal' (time range: 0 to 50): Time index 5 (50ns): top.signal = 8'h0A Time index 15 (150ns): top.signal = 8'hFFSupported condition syntax:
- Signal paths (e.g.,
TOP.signal) - Bitwise operators:
~(NOT),&(AND),|(OR),^(XOR) - Boolean operators:
&&(AND),||(OR),!(NOT) - Comparison operators:
==,!= - Parentheses for grouping:
(condition) $past(signal)- read signal value from previous time index- Verilog-style literals:
4'b0101(binary),3'd2(decimal),5'h1A(hex) - Bit extraction:
signal[bit]for single bit,signal[msb:lsb]for range
Operator precedence (highest to lowest):
~,!(bitwise NOT, logical NOT)==,!=(equality/inequality)&(bitwise AND)^(bitwise XOR)|(bitwise OR)&&(logical AND)||(logical OR)
Examples:
- Find when signal1 AND signal2 are true:
TOP.signal1 && TOP.signal2 - Find when counter equals a specific value:
TOP.counter == 4'd10 - Find rising edge:
!$past(TOP.signal) && TOP.signal - Find falling edge:
$past(TOP.signal) && !TOP.signal - Find handshake cycles (when both valid and ready are asserted):
TOP.valid && TOP.ready - Complex condition:
(TOP.valid && TOP.data != 8'hFF) || TOP.error - Bitwise operations:
TOP.flags & 4'b0001(check if bit 0 is set) - Bitwise NOT:
~TOP.mask(invert all bits)
Standalone CLI
In addition to the MCP server, a standalone CLI tool waveform-cli is available for direct command-line access without an MCP client.
CLI Usage
# Help
waveform-cli --help # general usage
waveform-cli help list_signals # detailed help for one command
waveform-cli list_signals --help # same as above
# Basic command
waveform-cli open_waveform /path/to/waveform.vcd
# Chain multiple commands with --
waveform-cli open_waveform test.vcd -- list_signals test.vcd --contains clk
# Full workflow example
waveform-cli open_waveform test.vcd --alias mywave -- \\
list_signals mywave -- \\
read_signal mywave top.clk --time-indices 0,1,2,3 -- \\
close_waveform mywave
CLI Commands
- open_waveform
[--alias] [–overwrite] - Open waveform file (--overwritereopens a waveform that is already open) - close_waveform `` - Close waveform
- list_signals
[--contains] [–glob] [--regex] [–hierarchy] [--recursive] [–limit ``]--contains/-p/--pattern: case-insensitive substring match (default)--glob/-g: case-insensitive glob over the whole path, e.g.--glob '*bank*'--regex/-x: regular expression, case-insensitive by default- The three flags are mutually exclusive: the flag you use selects the match mode, and it
applies to the whole command. Repeat the same flag to OR several patterns together, e.g.
--glob '*bank*' --glob '*ram*' --patternis an alias of--contains
- read_hierarchy
[--scope] [–recursive] [--limit] - read_signal
[–time-index| --time-indices] - get_signal_info
- Get signal metadata - find_signal_events
[–start] [--end] [–limit ``] - find_conditional_events
[–start] [--end] [–limit ``]
Every command also accepts --help/-h, and waveform-cli --version prints the version.
Options accept both --flag value and --flag=value; use the = form when the value itself
starts with - (for example --contains=-h).
Development
Building
cargo build
cargo build --release
Testing
cargo test
License
Install
This server does not publish a one-line install command.
Open the repository installation guide New to MCP? Start with the mcpskill.org guide →