KingstVIS MCP Server
# KingstVIS MCP Server
金沙滩 **KingstVIS** 逻辑分析仪软件的 Model Context Protocol (MCP) 服务器。
通过官方 **Socket API**(TCP 23367)控制软件完成采集,把采样数据导出成文件并
**离线解析/测量**——本工程的目标:从逻辑分析仪接口取出数据做离线分析。
- 协议与文件格式逆向笔记:`docs/NOTES.md`;官方文档原文:`docs/socket_api_text.txt` 与 `sdk/` 内 PDF+示例
- **26 个 MCP 工具**:连接/采样配置/触发/采集/导出/离线解析/通道测量/**内置解码器脚本管理**
- 三种导出格式全部支持解析:**.kvdat**(逆向的二进制跳变流,最紧凑、自带元数据,推荐归档)、
.csv/.txt(跳变列表,人可读)、.bin(每采样 uint16 LE,通道号=位序号)
- **内置解码器可全脚本控制**(逆向 `vis.config` 的 `<analyzers>` schema + 插件
SimpleArchive 设置串):`add_analyzer`/`remove_analyzer` 写配置并重启软件,
之后 `start` → `export_decoded` 拿到解码表——零 GUI 操作(详见 NOTES.md §5)
- **采样数据只落盘**(原生导出 + 派生 .npz),MCP 返回摘要与路径,绝不内联数组
- .npz 统一表示:`meta`(json) + 每通道 `pos_ch<N>`(uint64 边沿索引数组),
采集完成很久之后仍可离线分析(`parse_file`/`measure_channel` 无需连接)
## 快速开始
```bash
cd /Users/andylos/mcp_gen/kingstvis
python3 -m venv .venv
.venv/bin/pip install -e . pytest
.venv/bin/python -m pytest tests/ # 离线单元测试(mock VIS + 合成文件)
.venv/bin/python scripts/probe_device.py # 真机/模拟端到端自检(11 项)
```
## 启用 KingstVIS Socket API(一次性)
1. 关闭 KingstVIS,编辑 `~/Library/Application Support/kingst/vis.config`
(Windows: `%LOCALAPPDATA%\kingst\vis.config`)
2. `<enaSocket>1</enaSocket>`(端口默认 23367,可改 `<listenPort>`)
3. 重启软件并保持运行;首次监听需允许防火墙
> KingstVIS 3.6.6 为 x86_64 Qt 程序,Apple Silicon 上经 Rosetta 2 运行正常
> (本机已安装至 /Applications/KingstVIS.app 并已启用 Socket)。
> 无硬件时用 `start --simulate`(Demo 设备)走通全流程;软件通过 simulate
> 与真实采样的互斥报错,保证你始终知道数据是真是假。
## 配置(环境变量)
| 变量 | 默认 | 说明 |
|---|---|---|
| `KINGSTVIS_HOST` | `127.0.0.1` | KingstVIS 所在主机 |
| `KINGSTVIS_PORT` | `23367` | Socket API 端口 |
| `KINGSTVIS_DATA_DIR` | `./data` | 导出文件与 npz 的保存目录 |
| `KINGSTVIS_TIMEOUT` | `15` | 普通命令响应超时(秒) |
| `KINGSTVIS_START_TIMEOUT` | `300` | `start`(阻塞至采样完成)超时 |
## 接入 MCP 客户端
ZCode(`.zcode/settings.json`)或 Claude Desktop:
```json
{
"mcpServers": {
"kingstvis": {
"command": "/Users/andylos/mcp_gen/kingstvis/.venv/bin/python",
"args": ["-m", "kingstvis_mcp.server"],
"cwd": "/Users/andylos/mcp_gen/kingstvis",
"env": {
"KINGSTVIS_DATA_DIR": "/Users/andylos/mcp_gen/kingstvis/data"
}
}
}
}
```
## 工具总览(26 个)
| 分组 | 工具 |
|---|---|
| 系统/连接 (5) | `connect` `disconnect` `get_status` `get_last_error` `raw_command`(任意命令逃生舱) |
| 采集配置 (6) | `set_sample_rate` `get_sample_rate` `get_supported_sample_rates` `set_sample_depth` `set_sample_time` `set_threshold_voltage` |
| 触发/采集 (6) | `set_trigger`(reset/边沿/高低电平) `start`(阻塞, --simulate) `stop` `get_actual_sample_depth` `get_actual_sample_time` `capture`(配置→采集→导出→解析 一键) |
| 数据导出 (2) | `export_data`(kvdat/csv/txt/bin + 通道/时间窗 + 自动解析 npz) `export_decoded`(解码结果表) |
| **内置解码器管理 (4)** | `list_analyzers`(当前配置) `list_analyzer_plugins`(47 个内置插件) `add_analyzer`(写 vis.config + 重启, **全脚本零 GUI**) `remove_analyzer` |
| 离线分析 (3) | `parse_file`(任意历史导出→npz,无需连接) `measure_channel`(频率/占空比/脉宽/边沿统计) `list_edges`(分页边沿表) |
## 内置解码器的脚本控制(无 GUI)
官方 Socket API 只能 `export-decoded` 导出已有解析器的结果,不能添加/配置解析器。
本工程逆向出了 `vis.config` 的 `<analyzers>` schema 与插件的 SimpleArchive 设置串
格式(NOTES.md §5),从而补全了链路:
```bash
.venv/bin/python scripts/manage_analyzers.py add PWM --channels 0 # 单通道
.venv/bin/python scripts/manage_analyzers.py add I2C --channels 1 0 # SDA SCL
.venv/bin/python scripts/manage_analyzers.py add SPI --channels 0 1 2 3 # CLK MOSI MISO CS
# 或 MCP: add_analyzer(plugin="I2C", channels=[1, 0])
# 之后照常: start() -> export_decoded(analyzer=slot)
```
PWM 已端到端验证(解码出逐周期 正/负脉宽、周期、频率、占空比),I2C 在 demo
流量上验证(SDA/SCL 通道顺序确认);UART/SPI/CAN/DS18B20/1-Wire/USB-PD/Modbus
为 load-ok(可加载运行,个别参数按信号微调);其余 30+ 插件字段布局已逆向
(`manage_analyzers.py fields` 查看),传入正确的 parameters 串即可用;
UNIO 已知会崩溃、默认拒绝。真机信号上按 NOTES.md §5.4 的字段表微调。
## 典型工作流
```
# 一键流水线:冷启动软件->配置解析器->采样->原始导出+解码导出+测量->报告
# (软件未运行会自动拉起;解析器集合变化会自动改配置并重启)
.venv/bin/python scripts/auto_pipeline.py --simulate --channels 0 1 --analyzers PWM:0 PWM:1
.venv/bin/python scripts/auto_pipeline.py --rate 1e6 --depth 1e6 --channels 0 1 \
--analyzers PWM:0 PWM:1 --trigger 0 # 真机(需硬件在线)
# 或分步(MCP 工具)
set_sample_rate(1000000) -> start() -> export_data("cap.kvdat")
# 之后任意时刻离线分析
parse_file("data/cap.kvdat")
measure_channel("data/cap.npz", channel=0)
list_edges("data/cap.npz", channel=0, kind="rising", limit=100)
```
协议解码(I2C/SPI/UART/CAN...):`add_analyzer("UART", channel=3)` 脚本添加解析器
(自动重启软件),采集后 `export_decoded(..., analyzer=0)` 导出解码表;
也可用 `scripts/manage_analyzers.py` 命令行管理。
## 已知边界
- `start` 阻塞至采样完成;超大深度×低采样率可能超过 `KINGSTVIS_START_TIMEOUT`,
需按需调大或用 `stop` 中止(中止后连接会被重置以避免错位响应)。
- 响应以 0.5s 空闲间隙分帧(协议无终结符,与官方示例行为一致)。
- kvdat 的 `trigger_pos` = 触发点采样索引(真机已验证:与 get-actual-sample-time
的负起始时间严格对应)。
- 会话中没有解析器时 `export-decoded` 报 `invalid parameter`——用
`add_analyzer`/`manage_analyzers.py` 先添加(需重启软件生效)。
TDQS
Scored across 26 tools
Most tools target a distinct resource or action, with clear get/set/list/export/parse/measure families. A few pairs could initially be confused, such as start versus capture and raw_command versus the structured tools, but the descriptions clarify their roles.
Tool names mostly follow a predictable verb_noun pattern: get_*, set_*, list_*, export_*, add_*, remove_*. A few bare verbs like connect, disconnect, start, stop, capture, and the noun-only raw_command are minor deviations, but the overall style remains consistent and readable.
26 tools is on the heavy side for an MCP server, and the set covers many distinct concerns: connection, configuration, acquisition, export, analyzers, and offline analysis. The count is borderline but each tool does appear to serve a specific purpose within that broad scope.
The tool surface covers the full acquisition lifecycle, analyzer management, export, and offline parsing/measurement. Minor gaps exist, such as no getters for sample depth, sample time, threshold voltage, or trigger configuration, though raw_command and get_actual_* tools provide partial workarounds.