Loading...
Loading...
Drive JLCEDA Pro from Codex via WebSocket RPC using websocat as a short-lived local WS server (no Node/MCP required). Supports listing/calling all jlc.* tools and full EDA API passthrough (eda.invoke/get/keys).
npx skill4agent add xuf163/jlc-eda-mcp jlceda-eda-restwebsocatjlc.eda.keys/get/invokeeda.keys/get/invokeglobalThis.eda.*requestws://127.0.0.1:9050websocatREADME.mdschematic.* / library.* / eda.*tools.calltools.calldatatoolResultmethod:"schematic.listComponents"method:"tools.call"jlc.schematic.list_componentswebsocat-B 10485760websocatrequestcloseAfterResponse:truewebsocat -B 10485760 -t ws-l:127.0.0.1:9050 -hellotype=requestrequestwebsocatcloseAfterResponse:trueprintf '%s\n' '{"type":"request","id":"1","method":"ping","closeAfterResponse":true}' \
| websocat -B 10485760 -t --no-close --oneshot ws-l:127.0.0.1:9050 -多窗口 / 多工程:扩展会在端口池里自动协商一个可用端口(每个工程窗口一个端口)。9050-9059推荐:LLM 自动探测端口(无需用户报端口)
因为扩展是 WS 客户端,外部想“找端口”只能:在都临时起一个 WS 服务端,等扩展连上并读9050-9059(里面带工程信息)。hello更推荐:自动找到“当前有选区”的窗口端口(无需用户报端口/工程名)
在全部起 WS 服务端,并对每个端口发一次“选区探测”(9050-9059)。哪个端口返回的getAllSelectedPrimitives_PrimitiveId非空,通常就是用户当前正在操作的窗口。result.resultGit Bash / Linux / macOS(探测 9050-9059,输出“有选区”的端口回包):bashdir=".jlceda-bridge-discover" rm -rf "$dir" && mkdir -p "$dir" pids=() for p in {9050..9059}; do printf '%s\n' \ '{"type":"request","id":"sel","method":"eda.invoke","params":{"path":"sch_SelectControl.getAllSelectedPrimitives_PrimitiveId","jsonSafe":{"maxArrayLength":2000}},"closeAfterResponse":true}' \ | websocat -B 10485760 -q -t --no-close --oneshot "ws-l:127.0.0.1:$p" - >"$dir/$p.log" 2>&1 & pids+=($!) done sleep 20 for p in {9050..9059}; do if [ -f "$dir/$p.log" ] && grep -q '\"id\":\"sel\"' "$dir/$p.log" 2>/dev/null && ! grep -q '\"result\":\\[\\]' "$dir/$p.log" 2>/dev/null; then echo "== port $p =="; cat "$dir/$p.log" fi done for pid in "${pids[@]}"; do kill "$pid" 2>/dev/null || true; doneGit Bash / Linux / macOS(探测 9050-9059,输出所有):hellobashdir=".jlceda-bridge-discover" rm -rf "$dir" && mkdir -p "$dir" pids=() for p in {9050..9059}; do websocat -B 10485760 -q -t --no-close --oneshot "ws-l:127.0.0.1:$p" "appendfile:$dir/$p.log" >/dev/null 2>&1 & pids+=($!) done sleep 20 for p in {9050..9059}; do if grep -q '\"type\":\"hello\"' "$dir/$p.log" 2>/dev/null; then echo "== port $p =="; cat "$dir/$p.log" fi done for pid in "${pids[@]}"; do kill "$pid" 2>/dev/null || true; doneWindows PowerShell(同上;探测后会自动杀掉临时进程):powershell$dir = ".jlceda-bridge-discover" Remove-Item -Recurse -Force $dir -ErrorAction SilentlyContinue New-Item -ItemType Directory $dir | Out-Null $procs = foreach ($p in 9050..9059) { Start-Process -PassThru -NoNewWindow websocat -ArgumentList @( "-B","10485760","-q","-t","--no-close","--oneshot", "ws-l:127.0.0.1:$p", "appendfile:$dir/$p.log" ) } Start-Sleep -Seconds 20 $rows = foreach ($p in 9050..9059) { $path = Join-Path $dir "$p.log" if (!(Test-Path $path)) { continue } $helloLine = (Get-Content $path | Select-String -Pattern '"type":"hello"' | Select-Object -First 1).Line if (!$helloLine) { continue } $hello = $helloLine | ConvertFrom-Json $proj = $hello.project [PSCustomObject]@{ port = $p project = $(if ($proj.name) { $proj.name } elseif ($proj.friendlyName) { $proj.friendlyName } else { '' }) projectUuid = $proj.uuid appVersion = $hello.app.version } } $rows | Sort-Object port | Format-Table -AutoSize $procs | ForEach-Object { try { $_.Kill() } catch {} }兜底:用户也可以在 EDA 里打开查看该窗口端口。MCP Bridge -> Status扫描结果就是各端口收到的;拿到目标端口后,把后续示例里的hello改成对应端口即可。ws-l:127.0.0.1:9050如果扫描结果全空:通常是端口被占用(上一次 websocat 未退出)。Windows 可先执行再重试。taskkill /IM websocat.exe /F注意:如果扩展处于重连 backoff(上一次连接失败后会等几秒再重试),这种 pipeline 可能出现“只看到printf | websocat没有hello”。response
处理方式:改用交互式模式(等出现后再粘贴发送),或等几秒后重试一次。hello
jlc.*tools.callMETHOD_NOT_FOUND: tools.callprintf '%s\n' '{"type":"request","id":"1","method":"tools.call","params":{"name":"jlc.bridge.ping","arguments":{}},"closeAfterResponse":true}' \
| websocat -B 10485760 -t --no-close --oneshot ws-l:127.0.0.1:9050 -hello.projecthello.server.porttools.calleda.invokesch_SelectControl.getAllSelectedPrimitives_PrimitiveIdschematic.listComponentsallSchematicPages:falseresult.itemsschematic.listTextsresult.itemsprimitiveId ∈ selectedIdsitems$1N*schematic.listWires { nets:[...] }可选更快:只要“选区摘要”时,可直接(单次调用返回选区 mixed primitives;见eda.invoke sch_SelectControl.getAllSelectedPrimitives),避免docs/02-region-read.md。list* + 过滤
printf '%s\n' \
'{"type":"request","id":"1","method":"ensureSchematicPage"}' \
'{"type":"request","id":"2","method":"eda.invoke","params":{"path":"sch_SelectControl.getAllSelectedPrimitives_PrimitiveId","jsonSafe":{"maxArrayLength":2000}}}' \
'{"type":"request","id":"3","method":"schematic.listComponents","params":{"allSchematicPages":false}}' \
'{"type":"request","id":"4","method":"schematic.listTexts","closeAfterResponse":true}' \
| websocat -B 10485760 -t --no-close --oneshot ws-l:127.0.0.1:9050 -为什么这一段不用:tools.call会回tools.call+data(重复),大图纸更容易超限;RPC 返回更小、更稳。toolResult
9050node.exepackages/mcp-servernetstat -ano | findstr :9050
tasklist /fi "pid eq <PID>"taskkill /IM websocat.exe /Fdocs/01-region-select.mddocs/02-region-read.mddocs/03-region-edit.mddocs/04-performance.mddocs/05-http-proxy.mddocs/10-rpc-basics.mddocs/11-rpc-document.mddocs/12-rpc-netlist.mddocs/13-rpc-library.mddocs/14-rpc-schematic-edit.mddocs/15-rpc-schematic-apply-ir.mddocs/16-rpc-inspect.mddocs/17-rpc-eda-passthrough.mdjlc.*docs/20-tools-basics.mddocs/21-tools-eda-passthrough.mddocs/22-tools-document-view.mddocs/23-tools-netlist.mddocs/24-tools-library.mddocs/25-tools-schematic-inspect.mddocs/26-tools-schematic-edit.mddocs/27-tools-schematic-ir.mddocs/28-tools-verify.mdjlc-eda-mcp/docs/MCP_TOOLS.mdjlc-eda-mcp/docs/EDA_EXTENSION_RPC.mdjlc-eda-mcp/docs/SCHEMATIC_IR.mdjlc-eda-mcp/docs/PROTOCOL.mdcurl http://127.0.0.1:9151/v1/*/docspackages/mcp-servernode jlc-eda-mcp/packages/mcp-server/dist/cli.js --port 9050 --http --no-mcp说明:WS 侧扩展仍然是 WebSocket 客户端;无论你用不用 HTTP/MCP,都需要一个本机 WS 服务端让扩展连上。