mcp
Description
cicwave-mcp is an MCP server that
exposes cicwave’s headless plotting and analysis as tools an agent can
call directly — no shelling out to the CLI, no hand-written session
YAML. This is aimed at the “agent drives testing” workflow: point an
agent at a simulation/measurement file and let it request a plot (and
get the image back inline) or a numeric summary as part of a test run.
It requires the mcp extra, and Python 3.10+ (the
MCP Python SDK’s
own requirement — the rest of cicwave supports 3.8+):
pip install "cicwave[mcp]"
Both SDK generations work: 1.x (FastMCP) and 2.x, which renamed that
class to MCPServer and moved it out of mcp.server.fastmcp.
Running it
cicwave-mcp
This speaks MCP over stdio, so it’s normally launched by an MCP client rather than run directly. For Claude Code:
claude mcp add cicwave -- cicwave-mcp
Or add it to an .mcp.json / client config directly:
{
"mcpServers": {
"cicwave": {
"command": "cicwave-mcp"
}
}
}
Rendering runs Qt in offscreen mode automatically (no display needed).
Tools
plot
Render a plot from one or more data files and return the image inline.
| Argument | Required | Description |
|---|---|---|
files |
yes* | Local paths or http(s):// URLs — see URL sources. *Omit when pivot names a spec that fetches its own data |
waves |
no | Column/signal names to plot. Omit to plot every numeric column of the first file except the x-axis |
x |
no | X-axis column. Omit to auto-detect |
pivot |
no | Path to a pivot spec to reshape long-format data first; waves then refers to post-pivot names. A spec with a source: block also fetches the data — see API sources |
title |
no | Plot title |
url_format |
no | Force the format for an extension-less URL |
pivot_info
Inspect the dimensions available in a file for a pivot spec — the same
output as cicwave --pivot spec.yaml --pivot-info. Use this before
calling plot/analyze with a pivot spec so the agent isn’t guessing
column names and unique values.
| Argument | Required | Description |
|---|---|---|
pivot |
yes | Path to the pivot spec |
file |
yes* | Local path or URL. *Omit when the spec has a source: block |
url_format |
no | Force the format for an extension-less URL |
analyze
Run headless numeric analysis and return a text summary — the same
backends as pivot spec analysis.steps
and the GUI’s right-click analysis menu, but with the steps passed
directly instead of embedded in a spec file.
| Argument | Required | Description |
|---|---|---|
steps |
yes | List of step dicts — rms, dynamic_parameters, adc_psd, linear_fit, difference (see Pivot for each type’s keys) |
file |
yes* | Local path or URL. *Omit when pivot names a spec with a source: block |
pivot |
no | Reshape first, and apply the spec’s analysis.preprocess block (e.g. two’s-complement decode) before running steps |
x |
no | X-axis column override |
url_format |
no | Force the format for an extension-less URL |
Example
A typical “agent drives testing” turn: run a simulation that writes
output_tran/tran_typical.csv, then ask the agent to check it —
plot(files=["output_tran/tran_typical.csv"], waves=["v(out)"], x="time")
returns the rendered plot directly in the conversation, and
analyze(file="output_tran/tran_typical.csv",
steps=[{"type": "rms", "column": "v(out)"}])
returns "[v(out)] RMS=0.897141" as text — no file round-trip needed
for either.