The Vaporview extension includes a Waveform Control Protocol (WCP) server so external tools can control the viewer over TCP, following the WCP specification (wcp on GitLab).
This document explains how to enable the server, configure it, and use it from external clients.
Vaporview exposes a small set of settings under the vaporview configuration section.
-
vaporview.wcp.enabled- Type: boolean
- Default:
false - Behavior:
- When
true, the WCP server is started automatically when the extension is activated (VS Code startup or first use of Vaporview). - When
false, the server is not started automatically; you can still start it manually via commands.
- When
-
vaporview.wcp.port- Type: number
- Default:
54322 - Range:
0–65535 - Behavior:
- 0: Ask the OS to auto-assign an available port.
- Non-zero: Use the specified TCP port.
- If the port is already in use, the server will fail to start and an error will be logged to the Vaporview output channel.
You can edit these settings via:
- VS Code Settings UI:
- Open Settings → search for “vaporview wcp”.
settings.json:
"vaporview.wcp.enabled": true,
"vaporview.wcp.port": 54322There are three commands exposed by the extension for controlling the WCP server:
-
vaporview.wcp.start- Starts the WCP server if it is not already running.
- Uses the value of
vaporview.wcp.port(default54322,0for auto-assign). - Shows a notification with the actual port in use.
- If the server cannot be started (e.g., port in use), an error message is shown.
-
vaporview.wcp.stop- Stops the server if it is running.
- Shows a notification when the server is stopped.
-
vaporview.wcp.status- Shows the current state of the server:
- If running: the TCP port and the number of active connections.
- If not running: a simple “not running” message.
- Shows the current state of the server:
These commands can be run from:
- The Command Palette (
Ctrl+Shift+P/Cmd+Shift+P→ search for “WCP:”). - Keybindings or custom commands that you define yourself.
The server is created and managed by the extension (src/extension_core/extension.ts):
- On activation:
- The extension reads
vaporview.wcp.enabledandvaporview.wcp.port. - If
vaporview.wcp.enabledistrue, it creates aWCPServerinstance and callsstart().
- The extension reads
- On configuration change:
- If you toggle
vaporview.wcp.enabledor changevaporview.wcp.port, the extension will:- Start the server if it was disabled and is now enabled.
- Stop the server if it was enabled and is now disabled.
- Restart the server if it is enabled and the port value changes.
- If you toggle
- On extension shutdown:
- The server is stopped as part of the normal VS Code disposal process.
Internally, the server listens only on 127.0.0.1 (loopback) and accepts multiple TCP clients. It keeps track of active connections and exposes this count to the vaporview.wcp.status command.
The server implements the Waveform Control Protocol (WCP) as defined in the reference project:
https://gitlab.com/waveform-control-protocol/wcp
- Transport:
- TCP, JSON messages separated by newline (
\n).
- TCP, JSON messages separated by newline (
- Message format:
- Requests are objects with at least
methodandid(and optionalparams). - Responses include either a
resultfield (on success) or anerrorfield (on failure), plus the originalid.
- Requests are objects with at least
Example request:
{"method": "greeting", "params": {}, "id": 1}Example response:
{
"result": {
"name": "VaporView",
"version": "X.Y.Z",
"protocol": "WCP",
"protocol_version": "0",
"capabilities": ["greeting", "get_item_list", "..."]
},
"id": 1
}The exact command set and semantics follow the WCP specification where possible. Some commands are specific to Vaporview (e.g., open_document, add_signal) but still use the same JSON-RPC-like pattern.
-
Start the WCP server
- Ensure VS Code with the Vaporview extension is running.
- Either:
- Set
vaporview.wcp.enabled = true(auto-start on activation), or - Run
vaporview.wcp.startfrom the Command Palette.
- Set
-
Determine the port
- If you use a fixed port (e.g.,
54322), connect directly to that. - If you set
vaporview.wcp.port = 0, retrieve the actual port using:- The notification shown when the server starts.
- The
vaporview.wcp.statuscommand.
- If you use a fixed port (e.g.,
-
Connect from your client
- Open a TCP connection to
127.0.0.1:<port>. - Send newline-delimited JSON WCP requests.
- Read newline-delimited JSON responses.
- Open a TCP connection to
-
Typical command sequence
greeting– discover capabilities and verify connectivity.open_documentorload– open a waveform file (responds immediately withack, then sendswaveform_loadedevent when loading completes).- Wait for
waveform_loadedevent before proceeding with other commands. add_items/add_signal– add signals to the viewer.get_item_list,get_item_info,focus_item,set_viewport_to, etc.
For a full list of commands and expected parameters/results, see the server implementation in src/extension_core/wcp_server.ts and the WCP specification (wcp on GitLab).
-
Server fails to start (port in use)
- Choose a different
vaporview.wcp.portor set it to0to let the OS pick an available port.
- Choose a different
-
Client cannot connect
- Confirm the server is running via
vaporview.wcp.status. - Check that you are connecting to
127.0.0.1and the correct port.
- Confirm the server is running via
-
Commands return errors
- The
errorobject in the response includes a code and message. - Common causes include invalid parameters (e.g., unknown netlist ID, out-of-range time).
- The
Vaporview aims to follow the WCP specification as defined in the reference project (wcp on GitLab), but there are a few intentional behavior differences and extensions:
-
Document selection via
uriparameter (all commands)- Every WCP command in Vaporview accepts an optional
uriparameter inparams. - If
uriis provided, the command targets that specific document. - If
uriis omitted, Vaporview applies the command to the active document, or if none is active, the last active document. - This is an extension to the spec to better fit VS Code’s multi-document model.
- Every WCP command in Vaporview accepts an optional
-
Use of
netlist_idas Displayed Item Reference- Vaporview uses its internal
netlist_idas the WCP "displayed item" identifier. - Anywhere the WCP spec refers to an item ID (e.g., in
get_item_info,get_item_list,set_item_color,set_value_format,focus_item, etc.), Vaporview usesnetlist_idvalues that come from its netlist table.
- Vaporview uses its internal
-
add_itemsreturn behavior- In the reference spec,
add_itemsmay return IDs of added items and can report errors for items that could not be added. - In Vaporview:
add_itemsdoes not return an error if no items were added (e.g., nothing matched or all items were skipped). It still returns a successful response.- On success,
add_itemsalways returns:{"ids": []}
even if items were actually added in the viewer. The command is effectively "fire and forget" from the client's perspective.
- In the reference spec,
-
waveform_loadedevent forload,reload, andopen_document- Per the WCP specification, the
loadcommand responds instantly withackif the file is found, and sends awaveform_loadedevent when loading completes. - Vaporview implements this behavior for
load,reload, andopen_documentcommands. - The server preserves the exact URI format from the input parameter in both the
ackresponse and thewaveform_loadedevent. - Clients should listen for the
waveform_loadedevent before sending these commands to avoid race conditions, and wait for the exact URI they sent in the command.
- Per the WCP specification, the
These differences should be kept in mind when using generic WCP clients or comparing behavior against the reference implementation described in the WCP project (wcp on GitLab).
In addition to the standard WCP methods described in the reference project (wcp on GitLab), the Vaporview server exposes several Vaporview-specific commands. Many of these correspond directly to VS Code API commands described in API_DOCS.md (for example, vaporview.openFile, waveformViewer.addVariable, waveformViewer.removeVariable, and others).
-
get_capabilities- Returns a list of all supported server capabilities (both standard WCP and Vaporview-specific methods).
- Clients should use this to discover which methods are available in the running server.
-
open_document- Convenience wrapper to open a waveform file in Vaporview.
- Internally maps to the
vaporview.openFilecommand and supports options likeuri,load_all, andmax_signals. - Returns a WCP-style ack object including the document
uriimmediately if the file is found. - The
uriin the ack response uses the exact same format as theuriparameter in the request. - Sends a
waveform_loadedevent to all connected clients when the document is fully loaded, using the same URI format as the input.
-
add_signal- Adds a single signal to the viewer using either
netlist_id,instance_path, orscope_path + name. - Internally maps to
waveformViewer.addVariable. - Returns
{ "success": true }on success (or an error response on failure).
- Adds a single signal to the viewer using either
-
remove_signal- Removes a single signal from the viewer; accepts the same selectors as
add_signal. - Internally maps to
waveformViewer.removeVariable. - Returns
{ "success": true }when the removal command is issued successfully.
- Removes a single signal from the viewer; accepts the same selectors as
-
set_marker- Sets the main or alternate marker in the viewer at a given time (optionally with units) and marker type (
0main,1alt). - Internally maps to the
waveformViewer.setMarkercommand.
- Sets the main or alternate marker in the viewer at a given time (optionally with units) and marker type (
-
set_value_format- Sets the displayed value format for a signal (e.g., binary, hexadecimal, decimal, octal, signed, float formats, etc.).
- Parameters:
id(required): The netlist ID of the signal to formatformat(required): The format string (see supported formats below)uri(optional): Document URI (defaults to active document)
- Supported formats:
binary- Binary representationhexadecimal- Hexadecimal representationdecimal- Decimal representationoctal- Octal representationsigned- Signed decimal representationfloat8,float16,float32,float64- Floating point formatsbfloat16- BFloat16 formattensorfloat32- TensorFloat32 formatascii- ASCII character representationstring- String representation
- Returns: WCP-style ack response with document URI
- Errors: Returns error if signal is not found, not displayed, or format is invalid (invalid formats return ack without error, per WCP spec)
- Example:
{ "method": "set_value_format", "params": { "id": 123, "format": "hexadecimal" }, "id": 1 }
-
get_marker- Reads back the current marker time and units for either the main or alternate marker.
- Internally uses
waveformViewer.getViewerStateand translates the result into the WCPget_markerresponse shape.
-
get_viewer_state- Returns a snapshot of the viewer state including URI, marker times, time unit, zoom ratio, scroll position, and displayed signals.
- Parameters:
uri(optional): Document URI (defaults to active document)
- Response format:
{ "uri": "file:///path/to/waveform.vcd", "marker_time": 1000, "alt_marker_time": 2000, "time_unit": "ns", "zoom_ratio": 1.5, "scroll_left": 500, "displayed_signals": [ { "name": "top.a", "id": 123 }, { "name": "top.b", "id": 124 } ] } - Response fields:
uri: The document URImarker_time: Main marker time in document time unitsalt_marker_time: Alternate marker time in document time unitstime_unit: Display time unit (e.g., "ns", "ps", "us")zoom_ratio: Current zoom ratioscroll_left: Horizontal scroll position in time unitsdisplayed_signals: Array of displayed signals, each withname(instance path) andid(netlist ID)
- Internally maps to
waveformViewer.getViewerStateand converts the result into the WCP-style response.
-
get_values_at_time- Returns the values of one or more signals (specified by
instance_paths) at a given time. - Internally maps to
waveformViewer.getValuesAtTime, then adapts the return value to the WCPget_values_at_timeresult format (list of{instance_path, value}).
- Returns the values of one or more signals (specified by
-
get_open_documents- Lists all open Vaporview documents and the last active document.
- Internally maps to
waveformViewer.getOpenDocumentsand converts the resulting URIs into strings for WCP clients.
All of these Vaporview-specific WCP methods follow the same transport and request/response structure as the standard WCP commands and respect the optional uri parameter described above.
The WCP server broadcasts events to all connected clients. Events are JSON messages with type: "event" and do not have an id field (unlike command responses).
The waveform_loaded event is sent when a waveform document finishes loading. This event is fired by the following commands:
load– After the waveform file is fully loadedreload– After the document is reloaded and readyopen_document– After the waveform file is fully loaded
Event Format:
{
"type": "event",
"event": "waveform_loaded",
"uri": "file:///path/to/waveform.vcd"
}Important Notes:
- The
load,reload, andopen_documentcommands return anackresponse immediately if the file is found (per WCP specification). - The
waveform_loadedevent is sent asynchronously when loading completes. - Clients should set up event listeners before sending these commands to avoid missing the event due to race conditions.
- The server preserves the exact URI format from the input parameter. The
urifield in both theackresponse and thewaveform_loadedevent will match the URI format that was sent in the command. - Clients should wait for the exact URI they sent in the command (e.g., if you send
/path/to/file.vcd, wait for/path/to/file.vcd; if you sendfile:///path/to/file.vcd, wait forfile:///path/to/file.vcd). - Clients can filter events by URI to wait for a specific document to load.