eda_status
Check the bridge: is EasyEDA Pro connected, which editor/extension version, and what project/document/page is active.
waitMs
io.github.zzvllvzz由 GitHub 帳號 zzvllvzz 發布v0.1.0更新於 Nov 14, 2026
Read and draw EasyEDA Pro schematics and PCBs through a bridge extension, with guarded edits.
透過橋接擴充功能讓助理讀取、繪製並匯出 EasyEDA 專業版的電路圖與 PCB,編輯受保護且可回復。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
參照 儲存庫 中的啟動說明。
An MCP server that lets Claude Code (or any MCP client) read and draw schematics and PCBs in EasyEDA Pro.
A tiny extension inside the editor does one thing: it runs the JavaScript the server sends, with access to the eda API, and returns the result. All tool logic lives in the server, so fixes and new tools never require reinstalling the extension.
Edits are guarded: sch_draw and pcb_draw apply a whole batch of operations or nothing, and take the change back by themselves when it shorts two named nets on the schematic or adds a design rule error on the board.
PATH.easyeda-mcp-bridge.eext from the latest release.The extension connects to ws://127.0.0.1:49731 by itself and reconnects when the link drops. The editor gets an MCP menu with Reconnect and Status.
As a plugin, in a Claude Code session:
On Claude Code older than 2.1.275, add the marketplace first:
Then run /reload-plugins or start a new session.
Or from npm, without the plugin:
Or from source:
Other MCP clients: run npx -y easyeda-pro-mcp as a stdio server.
With EasyEDA open, ask Claude to check the EasyEDA connection. eda_status should answer connected with the editor and extension versions and the active project.
eda_status: is the editor connected, versions, active project and sheet, state of the bridge.eda_exec: run JS inside EasyEDA (eda, helpers h, args, console, store).eda_call: call one API method by its path.eda_api: search the API reference built from @jlceda/pro-api-types.sch_read: read a sheet: summary, parts with pins, wires, nets, check (check), overlaps (overlaps), free room (free).sch_draw: a batch of operations on the sheet as one guarded change (see below).sch_export: PDF, PNG, SVG, netlist, BOM to a file.lib_search: find parts in the library by words or LCSC numbers.pcb_read: the board: info, parts with pads, tracks, vias, pours and regions, nets, unrouted connections, DRC.pcb_draw: a batch of operations on the board as one change guarded by DRC.pcb_do: open a board, import changes from the schematic, refill pours, autoroute, remove routing.pcb_export: Gerber, pick and place, BOM, STEP/OBJ, DXF, DSN, IPC-356, IPC-2581, ODB++, PDF and more.The helpers h live in server/helpers.js and are read again on every call, so the file can be edited while the server runs.
sch_draw and pcb_draw apply the list of operations as a whole or not at all.
On the schematic a netlist is taken before and after the change. If nets with different names given by a person merged into one, that is a short: the change is taken back and the report names the nets and the pins. A change in which an operation failed, or an expect ({NET: [pins]}) did not hold, is taken back the same way. After a rollback the netlist is compared with the original and the report says restored: true. allowShorts permits an intended merge. The report always shows what happened to the nets: what got connected, what dropped off, what split, what was renamed.
On the board DRC runs before and after the change. A new error other than a connection that is not routed yet (clearance, short, entering a keep-out) takes the change back. Pours are refilled before the check. allowErrors keeps a change with errors.
trial: true performs the change in the editor, shows the report and takes it back in any case. A rollback restores moved parts, properties, the no-connect mark, wire names and shapes, deleted wires, tracks and vias. Deleted parts, texts and shapes cannot be restored, so a trial run that deletes parts is refused up front.
The guard forbids nothing in advance by geometry: EasyEDA itself decides, and the netlist or DRC judges the result. It gives no false refusals.
The extension runs whatever code the local server sends, with full access to the editor API and your EasyEDA account. Keep that in mind:
127.0.0.1 only. Browsers can open WebSockets to localhost from any site, so the server refuses connections that carry a browser Origin other than EasyEDA's own (https://*.easyeda.com, https://*.lceda.cn). More origins can be allowed with EASYEDA_MCP_ORIGINS, comma separated. Local programs (other sessions of this server, scripts/run.mjs) send no Origin and are accepted, as with any local developer tool.eda_exec can call any editor function, including the ordering ones (placePcbOrder, placeComponentsOrder and similar). The tool description tells the model never to call them.trial: true or on a scratch sheet or project.extension/dist/index.js: the extension, written by hand without a bundler.server/link.mjs: the link to the editor. The first server started owns the port; servers of other Claude sessions go through it. If the first one exits, the next one takes the port.server/index.mjs: MCP over stdio and the tools. Large answers are saved to ~/.easyeda-mcp/out/, the reply carries the beginning and the path.server/api-index.mjs: parses the API typings for search.Environment variables: EASYEDA_MCP_PORT (the port in the extension has to change too), EASYEDA_MCP_OUT, EASYEDA_MCP_ORIGINS.
npm test runs real server processes and the real extension code against a fake eda (test/fake-eda.mjs). It does not check the behaviour of a live EasyEDA.npm run build:ext packs extension/ into easyeda-mcp-bridge.eext (needs Node 20.15 or 22.2 and newer).node scripts/run.mjs draw <ops.json> [--trial] [--no-guard] and node scripts/run.mjs exec <code.js> [args.json] run sch_draw operations or code from a file through the hub of a running server. Useful for generators with hundreds of operations.Updating the extension without the import dialog: if EasyEDA runs with a debugging port (easyeda-pro.exe --remote-debugging-port=9333 --remote-allow-origins=*), a new build can be put into its extension storage directly: npm run build:ext, then node scripts/push-ext.mjs, then restart EasyEDA. The very first install still goes through the import dialog.
Schematic: reading, every sch_draw operation, short protection, trial run and rollback (six scenarios, the sheet came back identical), check, overlaps, free room search, export pdf/png/svg/netlist/bom/view. Load: 260 operations in one call (120 parts, 130 wires, 10 ground symbols) with a check of 130 nets took 100 seconds with the window hidden.
Board (in a scratch project): import from the schematic, moving parts, tracks, vias, a pour with fill, a keep-out region, text, outline, DRC, protection against shorted tracks and entering a keep-out, autorouting, export gerber/pnp/bom/step/dxf/dsn/ipc356/odb/altium/pdf/netlist.
Link: works with the window minimized, recovers after a dropped socket and after the computer sleeps.
Not tested: multilayer boards and blind vias, net classes and differential pairs (available through the raw API), boards and sheets with hundreds of parts, the web editor, macOS and Linux.
top.document from eda_exec and click it there.eda_exec.sch_draw takes its operations inline only; for long lists use scripts/run.mjs. trial and the part op do not return pin coordinates, and the set op cannot mark a part as not placed (DNP).lib_search cuts descriptions at about 120 characters.getAll, getAllPrimitiveId) lags about a second behind wire creation, get(ids) sees them at once. h.draw waits for the update; after the raw API call h.settle(ids).sch_PrimitiveComponent.create stores rotation 90 as 270 and the other way round; modify is correct.sch_PrimitivePin.modify without y flips the sign of the pin's y and the pin flies off the part. Pass the current y.modify throws cmdKey, a wire create throws create failed!, delete silently returns false. A retry a moment later succeeds.create returns the old wire's id.sch_Drc.check returns only the number of findings per severity; the list exists only in the editor panel.pcb_Primitive.getPrimitiveTypeByPrimitiveId always answers undefined; a pour is refilled with the object's rebuildCopperRegion(); importChanges() only opens a confirmation dialog, h.pcb.import presses its button; getPdfFile without content settings never answers; dmt_Project.deleteProject returns false and does not delete the project.getPdfFile does not exist in the editor, getPngFile and getSvgFile never resolve. getExportDocumentFile does all of it.globalThis.__easyedaMcpBridge__, info() shows its state).h.sleep, h.limit, h.settle) run on a timer in a worker: thirty such pauses take 3.3 s. The editor's own timers suffered the same way (netlist 53 s instead of 2 s, creating a part 24 s), so while the window is hidden the helpers move the page's setTimeout and setInterval onto the same worker. With a visible window the timers are native. Turn it off with h.pageTimers(false).MIT. The API reference is built from @jlceda/pro-api-types (Apache-2.0), installed as a dependency.
來源:README.md,提交 a2e1756
Check the bridge: is EasyEDA Pro connected, which editor/extension version, and what project/document/page is active.
waitMsRun JavaScript inside EasyEDA Pro and get the returned value. The code is the body of an async function with `eda` (the EasyEDA extension API), `h` (helpers), `args` (your JSON), `console` (captured) and `store` (object that persists between calls). Use `return` for the result. Do many operations in ONE call with loops instead of many calls. EasyEDA primitives are returned as plain objects built from their getState_* getters; File/Blob results are saved to disk and returned as a path. Nothing is guarded or confirmed: read back what you changed. Schematic y axis points up. Helpers available as `h` inside eda_exec code (all async unless noted): h.ctx() current project/document/schematic/page | h.pages() | h.openPage(uuidOrName) h.parts({pins?, des?, region?:[x1,y1,x2,y2], type?, allPages?}) compact components; h.part("U1") one component with pins h.wires(net?) | h.snapshot({region?, pins?}) parts+flags+wires of the page h.nets() {net:["U1.3",...]} from the native PADS netlist (all pages) | h.net("GND" | "U1.3") | h.checkNets({NET:["U1.3","R2.1"]}) h.lcsc("C1234" | [..]) -> {found:{id:{uuid,libraryUuid}}, missing} h.draw(ops, {trial?, expect?:{NET:[pins]}, allowShorts?, rollback?, guard?, keepGoing?, verbose?}) one change, all or nothing (see sch_draw) ops: {op:"wire",line:[x1,y1,x2,y2,..],net?} {op:"part",lcsc|device,x,y,rot?,des?} {op:"flag",kind:"Ground"|"Power",net,x,y,rot?} {op:"port",dir:"IN"|"OUT"|"BI",net,x,y,rot?} {op:"move",part,x?,y?,rot?} {op:"set",part,props} {op:"nc",pin:"U1.3"} {op:"unname",wire} {op:"rewire",wire,line} {op:"delete",wires?,parts?,others?} {op:"text",x,y,text,size?,rot?} {op:"rect",x,y,w,h} {op:"circle",x,y,r} {op:"line",line:[..]} {op:"attr",part,key:"Designator"|"Name",x?,y?,rot?,visible?} h.netDiff(before, after) what changed between two h.nets() results (shorts, joined, dropped, split, renamed, connected; sync) h.erc({strict?, ui?}) floating pins, single-pin nets, unnumbered and duplicate designators + EasyEDA's ow
argscode必填saveTomaxCharstimeoutMsCall one EasyEDA API method by path, e.g. method 'sch_PrimitiveWire.getAll' with args ['GND']. Shortcut for simple reads and single writes; for anything with loops use eda_exec. Look up signatures with eda_api.
argsmethod必填saveTomaxCharstimeoutMsLook up the EasyEDA Pro extension API (offline, from the official typings; doc comments are in Chinese). `query`: keyword search over method names and docs. `name`: full listing of a class/eda object (sch_PrimitiveWire), an interface, enum or type, or one method with remarks and example (sch_PrimitiveWire.modify). No arguments: overview of all eda.* objects.
namelimitqueryexamplesRead the active schematic page compactly. what: 'summary' (counts, designators, net names of wires), 'parts' (components with pin coordinates), 'wires', 'snapshot' (parts+flags+wires), 'nets' (whole-schematic netlist {net: pins}), 'net' (one net by name or by pin like 'U1.3', needs `net`), 'check' (floating pins, single-pin nets, unnumbered or duplicate designators, EasyEDA's own rule check counts), 'overlaps' (parts, labels and wires lying on each other), 'free' (room for a block of `size` [w,h]: rectangles touching nothing), 'boxes' (the rectangle every object takes). Filter with `des` (designators) or `region` [x1,y1,x2,y2]. Pin x,y is the outer end where a wire attaches.
desnetpinssizewhatcountregionsaveTomaxCharsApply a list of drawing operations to the active schematic page as ONE change: afterwards either all of it is on the page or none of it. The netlist is read before and after (guard): nets with different names that became one net are a short, and a short takes the whole change back, as does a failed op or an `expect` that does not hold; the report says what happened to the nets (connected, joined, dropped, split, renamed) and `restored:true` confirms that the netlist is back to what it was. trial:true does the change, reports, and takes it back in any case (a dry run on the real editor). ops: {op:'wire',line:[x1,y1,x2,y2,...],net?} | {op:'part',lcsc:'C1234'|device:{libraryUuid,uuid},x,y,rot?,mirror?,des?} | {op:'flag',kind:'Ground'|'Power'|'AnalogGround'|'ProtectGround',net,x,y,rot?} | {op:'port',dir:'IN'|'OUT'|'BI',net,x,y,rot?} | {op:'move',part:'R1',x?,y?,rot?,mirror?} | {op:'set',part,props:{designator?,name?}} | {op:'nc',pin:'U1.3'} | {op:'unname',wire:id} | {op:'rewire',wire:id,line} | {op:'delete',wires?:[ids],parts?:[ids|designators],others?:[ids of texts/shapes]} | {op:'text',x,y,text,size?,rot?,color?} | {op:'rect',x,y,w,h} (x,y top left) | {op:'circle',x,y,r} | {op:'line',line:[...]} (drawing line, not a wire) | {op:'attr',part,key:'Designator'|'Name',x?,y?,rot?,visible?,value?} (move or edit a label of a part). Notes: y points up; a wire with `net` gets a visible label; EasyEDA merges a new wire with every wire whose end it touches (reported as merged, the old wire keeps its id); pins touching end to end without a wire are not connected; parts placed without `des` are numbered by EasyEDA (unique across all pages); the netlist also numbers any other 'R?' part of the project; deleted parts cannot be put back by a rollback.
ops必填guardtrialexpectverboserollbackkeepGoingtimeoutMsallowShortsExport from the active schematic to a file and return its path: pdf (look at the real drawing; open the path with the Read tool), png, svg, netlist (PADS text), bom (csv), view (image of what the canvas currently shows; may be stale).
pathformat必填optionstimeoutMsSearch the EasyEDA/LCSC device library by words ('100nF 0402 X7R', 'STM32F103C8T6') or look up LCSC numbers. Returns name, LCSC number, footprint, JLCPCB class (Basic/Extended) and the uuid pair that {op:'part', device:{uuid, libraryUuid}} takes.
lcscpagelimitquerydatasheetRead the active PCB (open one with pcb_do action:'open'). what: 'info' (layers, rule set, outline size, counts), 'parts' (components; pads:true adds pad coordinates and nets), 'tracks', 'vias', 'shapes' (polylines, pours, regions, fills, texts), 'nets' (pads, track length, tracks and vias per net; `net` for one), 'unrouted' (pads still waiting for a connection), 'drc' (design rule check with the list of errors). Coordinates are in mil with y up; unit:'mm' switches to millimetres.
desmaxnetpadsunitwhatlayersaveTomaxCharsApply a list of operations to the active PCB as ONE change. The design rule check runs before and after (guard): a new error other than a not-yet-routed connection (clearance, short, overlap with a keep-out) takes the whole change back, as does a failed op; pours are refilled before judging. trial:true reports and takes it back in any case. Coordinates in mil, y up (unit:'mm' for millimetres); layer by number or name (top, bottom, topsilk, bottomsilk, outline, document, inner1...). ops: {op:'track',net,layer,points:[x1,y1,x2,y2,...],width?} | {op:'via',net,x,y,hole?,dia?} | {op:'move',part:'R1',x?,y?,rot?,layer?} | {op:'place',lcsc|device|footprint,x,y,layer?,rot?,des?} | {op:'set',part,props} | {op:'outline',rect:[x,y,w,h]|points:[...]|circle:[x,y,r]} | {op:'pour',net,layer,rect|points,name?,priority?} | {op:'region',layer,rect|points,rules?} (keep-out) | {op:'fill',layer,rect|points|circle,net?} | {op:'text',layer,x,y,text,size?,width?,rot?} | {op:'line',layer,points,width?} (silkscreen or document line) | {op:'delete',ids:[...]}. A rectangle starts at its top left corner. Components normally come from the schematic (pcb_do action:'import'); deleted shapes, texts and components cannot be put back by a rollback, tracks and vias can.
ops必填unitguardtrialrebuildverboserollbackkeepGoingtimeoutMsallowErrorsWhole-board actions. action: 'open' (open a PCB of the project by `name` or uuid, the first one by default), 'import' (bring the schematic's changes onto the board; lists the changes and applies them, apply:false only lists), 'rebuild' (refill all pours), 'autoroute' (EasyEDA's own router; `props` like {RoutingNets:['A','B'], layers:[1,2], ignoreNets:[...]}), 'unroute' (delete all tracks and vias of `net`, or of every net when none is given).
netnameapplypropsaction必填timeoutMsExport from the active PCB to a file and return its path: gerber (zip for fabrication), pnp (pick and place csv), bom, netlist, step, obj (3D), dxf, dsn (for external routers), ipc356, ipc2581, odb, testpoints, info, altium, pads, view (picture of what the canvas shows). Nothing is ordered: EasyEDA's ordering functions are never called.
pathformat必填optionstimeoutMs已滿足適用檢查項的 90%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
/plugin install easyeda --marketplace zzvllvzz/easyeda-mcp/plugin marketplace add zzvllvzz/easyeda-mcp/plugin install easyeda@easyeda-mcp# macOS, Linuxclaude mcp add easyeda -s user -- npx -y easyeda-pro-mcp# Windowsclaude mcp add easyeda -s user -- cmd /c npx -y easyeda-pro-mcpgit clone https://github.com/zzvllvzz/easyeda-mcpcd easyeda-mcpnpm installclaude mcp add easyeda -s user -- node /absolute/path/to/easyeda-mcp/server/index.mjs