dsvlab-mcp

dsvlab-mcp

Enables AI to programmatically control DS-VLAB circuit testing environment for automated testing.

Category
访问服务器

README

dsvlab-mcp — DS-VLAB 电路测试 MCP 服务器

让 AI(MCP 客户端)程序化控制 DS-VLAB v2.0 多思计组原理虚拟实验室中的电路:加载电路、上电、施加输入、单步/连续运行、读取引脚与存储、批量跑真值表,实现自动化测试。

架构

AI 客户端 ─stdio─► dsvlab-mcp(本服务) ─Playwright─► Edge/Chromium(加载 index.html)
                                                    │ page.evaluate()
                                                    ▼
                                          window.mycircuit / cDispatch
                                          / recovercircuit()(原系统全局)
  • 不改动原项目任何源码(18 个 component、dispatch、circuitdiagram、fileoperation 一律不动)。
  • 全部新文件集中在 mcp/dsvlab-mcp/
  • 复用原项目 tools/circuit-validator-core.js(UMD)做加载前校验。
  • 默认用系统自带的 Edge(channel: 'msedge'),无需下载 Chromium

安装

cd mcp/dsvlab-mcp
npm install
npm run build          # tsc 编译到 dist/
# 可选:跑集成测试(会用 Edge headless 加载 example_bus_demo.txt)
npm test

不需要 npx playwright install —— 默认走系统 Edge。若想用 Playwright 自带 Chromium,设环境变量 DSVLAB_CHANNEL=chromium 后执行 npx playwright install chromium

配置(MCP 客户端)

ZCode / Claude Desktop

files/config.sample.json 的内容并入客户端的 MCP 配置(按本机实际路径调整):

{
  "mcpServers": {
    "dsvlab": {
      "command": "node",
      "args": ["C:/.../dsvlab2.0/mcp/dsvlab-mcp/dist/index.js"],
      "env": {
        "DSVLAB_INDEX": "C:/.../dsvlab2.0/index.html",
        "DSVLAB_CHANNEL": "msedge",
        "DSVLAB_HEADLESS": "0"
      }
    }
  }
}

环境变量

变量 默认 说明
DSVLAB_INDEX <项目根>/index.html index.html 绝对路径
DSVLAB_CHANNEL msedge 浏览器 channel:msedge / chrome / chromium
DSVLAB_HEADLESS 0(可见) 1 = 无头(不弹窗,适合 CI)

浏览器是 lazy 启动:MCP 服务连上后不立即弹窗,第一次调用工具时才启动。

工具清单(共 25 个)

电路

工具 说明
load_circuit 加载电路 txt(默认先校验,有 errors 拒绝加载)
clear_circuit 清空画布

画电路(辅助生成,配合 docs/AI画电路手册.md 流程)

工具 说明
list_component_catalog 列出全部 23 种元件:名称/类型/引脚数
get_component_pins 查元件引脚表(画电路必查,引脚号禁止臆测)
build_circuit 由结构化描述生成合法 txt(带校验),可直接 load_circuit 加载

电源

工具 说明
power_on / power_off / reset 开/关/复位电源

仿真

工具 说明
step 单步:跑空一次就绪队列(一次稳定传播)
run 连续运行:启动 ContinuousPulse 跑 N 毫秒后停
stop 停止所有连续脉冲(清 timer)
press_switch 翻转开关(toggle)
set_switch 设置开关到 0/1(处理初值高阻,自动判断是否需要翻转)
trigger_pulse 触发单脉冲(须先 power_on)
apply_input 给指定引脚施加 0/1 并传播
set_pulse_width 设置时钟周期(ms,默认 800,测试建议 50)

读取

工具 说明
list_components 所有元件概览
get_component 元件全部引脚(pinName/pinFunction/pinValue)
read_pin / read_all_pins 读引脚值(0低 / 1高 / 2高阻)
read_memory / write_memory 读写 RAM6116/EPROM memory(运行时,不随 txt 保存)
snapshot 全电路所有引脚快照

批量测试

工具 说明
run_truth_table 批量跑真值表(自动遍历 2^n 或自定义 cases)
assert_pins 一次性断言多引脚值,返回 pass/fail

使用示例(AI 视角)

1. load_circuit(text=<电路txt全文>)        → 加载并校验
2. power_on()
3. set_switch(id="CP8", value=0)           → 使能 74LS245
4. for each 输入组合: set_switch + step + read_pin
   或直接: run_truth_table(switch_ids=["CP0",...], outputs=[{id,pin}])
5. assert_pins(expected=[{id,pin,value},...])

关键技术点

  1. 桥接层(src/inject.ts):注入到页面的一段 window.__bridge 脚本,把对原系统 cDispatch/mycircuit/recovercircuit 的调用集中封装,Node 侧通过 page.evaluate 一次性调用,返回可序列化 JSON。减少跨进程往返。
  2. 调用对照(均已查源码确认):
    • 加载:recovercircuit('demo', mycircuit, txt)(fileoperation.js:136)
    • 上电/断电:cDispatch.powerOn()/powerOff()(dispatch.js:93/99)
    • 单步:cDispatch.runCircuit()(dispatch.js:75)
    • 触发源器件:cDispatch.sourceTrigger(c|id)(dispatch.js:86)
    • 读引脚:comp.pinValue[pinNo](0低/1高/2高阻)
  3. pinValue 三态:0 低 / 1 高 / 2 高阻未驱动,断言要区分。
  4. Switch 初值坑:原系统 new Array([0]) 产生 [[0]],pinValue[0] 实际是数组 [0],[0]==0 成立但 [0]===0 不成立。故 setSwitch 用宽松比较 !=,与原系统一律 == 的语义一致。
  5. memory 限制:RAM6116/EPROM 的 memory 硬编码在源码(js/component/ram6116.js 等),不随电路 txt 保存;运行时 component.memory 可读写,但刷新页面会重置回源码值。
  6. 异步脉冲:ContinuousPulse/SinglePulsesetTimeout 自驱动(默认 800ms);run(duration) 用真实等待,stop() 清 timer。测试时 set_pulse_width(50) 加速。
  7. MCP 用 stdio:禁用 console.log(破坏协议流),用 console.error
  8. TS + zod + MCP SDK 的 TS2589:zod ZodRawShape 与 SDK 泛型组合会触发 "Type instantiation excessively deep"。本项目统一用 server.registerTool<any, any> + handler (args:any, _extra:any): Promise<any> 规避。

调试

# MCP Inspector:浏览器里查看所有工具、手动调用
npx @modelcontextprotocol/inspector node dist/index.js

# 跑集成测试
npm test

已知限制

  • 不改原项目源码,因此 RAM/EPROM memory 初值仍需改 js/component/*.js(本工具只在运行时改 component.memory,刷新即失)。
  • run(duration) 基于真实时钟等待,大批量时序测试较慢;组合逻辑用 step/run_truth_table 即可。
  • 单步无 GUI 按钮,step = cDispatch.runCircuit()(跑空就绪队列)。

集成测试结果

tests/integration.test.tsfiles/examples/example_bus_demo.txt(8 开关 → 74LS245 → 8 LED)端到端验证:

  • ✅ 加载 18 个元件
  • -E=0 使能时 A→B 透传,8 个 LED 全亮
  • -E=1 禁能时 B 侧高阻,LED 不亮

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选