wavekit-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@wavekit-mcpLoad sim.vcd and analyze clock signal edges"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
wavekit-mcp
English | 中文
An MCP server that gives AI assistants a persistent, sandboxed Python environment for waveform analysis using wavekit.
The AI can open VCD/FST/FSDB files, load and manipulate waveforms, run temporal pattern matching, and iterate across multiple tool calls — all within a shared execution context that persists state between calls.
Why wavekit-mcp?
The problem: Digital waveforms are huge. A single simulation can produce millions of transitions across thousands of signals. Sending this data to an LLM directly is both inefficient and ineffective — the AI sees noise, not insight.
Our approach: Give the AI tools, not data. wavekit-mcp exposes wavekit's full waveform analysis capabilities through a persistent Python session. The AI writes code to:
Load signals from VCD/FST/FSDB files
Apply temporal pattern matching
Compute statistics, detect anomalies, extract events
The AI gets only the answers it asks for — a mean, a timing violation, a filtered subset — never the raw waveform. Output limits ensure the AI must think in terms of signal semantics, not value sequences.
Related MCP server: FSDB MCP Server
Installation
pip install wavekit-mcpStart the server:
wavekit-mcp
wavekit-mcp --config /path/to/wavekit_mcp.tomlMCP client example:
{
"mcpServers": {
"wavekit": {
"command": "wavekit-mcp",
"args": ["--config", "/path/to/wavekit_mcp.toml"]
}
}
}Configuration
Copy wavekit_mcp.toml.example and edit as needed. All fields are optional.
[limits]
max_sessions = 8
run_timeout_sec = 120
output_max_chars = 4000
[file_access]
read_enabled = false
write_enabled = false
read_allowed_paths = ["/tmp/**"]
write_allowed_paths = ["/tmp/**"]
[log]
file = "" # empty = stderr only
level = "INFO"
[sandbox]
# Defaults already allow wavekit, wavekit.*, numpy, numpy.*
# allowed_imports = ["plotly", "matplotlib.*"]Scalar fields can be overridden by environment variables:
WAVEKIT_MCP_RUN_TIMEOUT_SEC=300 wavekit-mcpTools
Tool | Description |
| Create a persistent Python execution session. |
| Close a session and release worker resources. |
| List active sessions. |
| Execute Python and return |
| Return recent execution records. |
| Inspect wavekit Reader/Waveform/pattern API docs. |
Each session pre-injects only:
wavekit— usewavekit.VcdReader,wavekit.Waveform, etc.Viewer— optional waveform visualization helper.
Import everything else explicitly:
import numpy as np
import wavekit
from wavekit.pattern import Pattern, match, collect, Channel, MatchStatusrun() returns the last expression in a REPL-like form: the value is displayed as truncated repr(...) text; the real Python objects remain in the session namespace.
Basic usage
# call 1
import numpy as np
import wavekit
r = wavekit.VcdReader("/data/sim.vcd")
data = r.load_waveform("tb.dut.data[7:0]", clock="tb.clk")
# call 2 — state persists
print(f"samples={len(data.value)} mean={np.mean(data.value):.2f}")Reader examples
Matched loading
waves = r.load_matched_waveforms(
signal_path="tb.dut.fifo_{0..3}.w_ptr[2:0]",
clock_path="tb.clk",
)
for key, wave in waves.items():
print(f"{key}: mean={np.mean(wave.value):.2f}")Matched APIs return dict[CaptureKey, ...]. CaptureKey is a tuple of typed captures such as BraceCapture, RegexCapture, or WildcardCapture.
Unknown/X/Z masks
value = r.load_waveform("tb.bus[7:0]", clock="tb.clk", xz_value=0)
unknown = r.load_unknown_mask("tb.bus[7:0]", clock="tb.clk")
known_value = value.mask(unknown == 0)
unknowns = r.load_matched_unknown_masks(
signal_path="tb.dut.fifo_{0..3}.data[7:0]",
clock_path="tb.clk",
)Expressions
occupancy = r.eval(
"tb.dut.w_ptr[3:0] - tb.dut.r_ptr[3:0]",
clock="tb.clk",
)
occupancies = r.eval(
"tb.fifo_{0..3}.w_ptr[2:0] - tb.fifo_{0..3}.r_ptr[2:0]",
clock="tb.clk",
mode="zip",
)Query syntax
Syntax | Example | Meaning |
Plain path |
| Exact signal/scope path. |
Brace |
| Alternatives or integer ranges. |
|
| Canonical regex with captures. |
| `tb.@(req | ack)` |
|
| One-level / recursive wildcard. |
|
| FSDB module-definition match. |
Use r.top_scopes, r.get_matched_signals(path), and r.get_matched_scopes(path) to explore hierarchy.
Pattern matching
Pattern builds declarative timing checks. Execute with module-level match(...).
from wavekit.pattern import Pattern, match, MatchStatus
ar_fire = arvalid & arready
r_fire = rvalid & rready
records = match(
Pattern()
.wait(ar_fire)
.wait(r_fire)
.capture("rdata", rdata),
timeout=256,
)
ok = records.filter_ok()
print(f"transactions={len(ok)}")
print(f"latencies={ok.end.clock - ok.start.clock}")
print(ok.captures["rdata"].value[:8])
timeouts = records.filter_status(MatchStatus.Timeout)
require_failures = records.filter_status(MatchStatus.RequireViolated)Use consume(..., channel=...) when a match must claim an event exclusively. Successful blocking steps continue in the same cycle; use .delay(1) for next-cycle behavior.
For value-dependent flows, use programmable collect(...):
from wavekit.pattern import collect
cmd_fire = cmd_valid & cmd_ready
rsp_fire = rsp_valid & rsp_ready
def read_cmd(ctx):
if not ctx.value(cmd_fire):
return None
addr = int(ctx.value(cmd_addr))
ctx.consume(rsp_fire, channel="rsp")
return {"addr": addr, "status": int(ctx.value(rsp_status))}
commands = collect(read_cmd, timeout=128)
print(f"commands={len(commands)}")Viewer
viewer = Viewer()
viewer.waveforms.append(data)
viewer.markers.append(time=int(data.time[0]), name="start")
viewer.zoom_to_fit()
viewer.push_state()
print(viewer.url)Keep the session open while the user is viewing; closing the session closes the viewer.
Security
User code runs under RestrictedPython in a worker process. Imports are restricted by sandbox.allowed_imports; file I/O is disabled unless explicitly enabled in [file_access].
This prevents accidental operations and isolates crashes, but it is not a complete sandbox for hostile code.
AI assistant skill
This repository includes a wavekit-mcp skill:
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for building and testing AI agents with multi-model experimentation and insights.
- ArcjetOAuthcom.arcjet
An MCP server for Arcjet - the runtime security platform that ships with your AI code.
Cloud-hosted MCP server for durable AI memory
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
Related MCP Servers
- FlicenseAqualityFmaintenanceA comprehensive Model Context Protocol server that connects AI assistants to Electronic Design Automation tools, enabling Verilog synthesis, simulation, ASIC design flows, and waveform analysis through natural language interaction.6109-
- AlicenseNot gradedqualityCmaintenanceAn MCP server for reading and querying FSDB waveform files, enabling AI assistants to browse hierarchy, search signals, and extract waveform data with value changes.13MIT
- AlicenseBqualityBmaintenanceAn MCP server that enables AI assistants to analyze schematics, inspect PCBs, trace connections, validate designs, and generate embedded code for KiCad projects.39129MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to analyze hardware simulation VCD waveforms and GTKWave save files, providing access to signal values, bus definitions, and groupings without loading entire files.5MIT