Claude Code 經 MCP 操作 PCBEditor:實測設計 4 層 ESP32-S3 電路板
I gave Claude a PCB design tool over MCP: here is what it built
Claude Code 經 MCP 操作 PCBEditor,生成 4 層 ESP32-S3 電路板,並從網表找出三項未被 DRC 發現的接線錯誤,再提交精確修改。修正後仍有兩項 USB-C 屏蔽孔間距的 DRC 錯誤,因此 Claude Code 沒有匯出製造檔;實測亦揭示 MCP 問答與檢查流程的缺陷。完整操作流程見 pcbeditor.com/mcp/guide。
I build PCBEditor, a browser PCB tool that designs boards from a description, so read this with that in mind. We have just put an MCP server in front of it, and before writing any docs I wanted to see what an AI assistant actually does with it when nobody is steering. So on 20 October I connected Claude Code to the server, typed one sentence, and let it run without me. The step-by-step version, with every tool and the responses it returns, is at pcbeditor.com/mcp/guide.
The setup
One command adds the server:
claude mcp add --transport http pcbeditor https://api.robodib.com/mcp
Claude Code then sees 16 tools: design_board, get_job, answer_question, edit_board, route_board, run_drc, review_board, get_board, export_board, import_kicad and a few for parts and designs. A design runs as a job on the server: design_board returns a job ID, and get_job waits up to 45 seconds per call for it to move.
What I typed:
Design a 4-layer ESP32-S3 board with USB-C and a LiPo charger.
Claude wrote a spec first
It did not pass my sentence through. Its first design_board call carried a full specification it had written itself. An excerpt:
Charging: single-cell LiPo charger with power path / load sharing so the board runs from USB while charging and from the battery when unplugged (e.g. TI BQ24074, or MCP73831 plus a P-MOSFET and Schottky load-sharing circuit). Charge current about 500 mA, set by resistor. [...] 3.3V rail: low-dropout regulator rated at least 600 mA with low quiescent current (e.g. AP2112K-3.3 or RT9080/ME6211 class) fed from the power-path output
It also asked for ESD protection on the USB lines, a battery-voltage divider to an ADC pin, an RC delay on the enable button, two header rows and a 4-layer stack with a solid ground plane, and it switched on the slower extra quality pass. That is a better brief than most people write, and better than mine.
Then our server tripped five times
The first job ended after 44 seconds with "The run ended without a board." So did the next four. The progress lines showed why: the pipeline had found problems in the circuit and was "Awaiting your choice on the circuit problems before layout...", but that choice never reached Claude as a question. That is a bug in our MCP layer, and it is on our list.
Claude's reaction was the interesting part. It looked up the pin maps of the module and the charger with get_part, rewrote the description naming each charger and USB pin by its library name, and tried again. On the sixth run the question came through:
The circuit cannot work as wired: [...] U2 (LiPo charger with power path) pin 4 (~{CE}) is held high (net VBUS), which keeps U2 shut down: it runs with this pin low; U2 (LiPo charger with power path) pin 6 (EN1) is held low (net GND), which keeps U2 shut down: it runs with this pin high. How should I continue?
Claude answered in its own words with a list of corrections. The server ignored the free text and asked the same question again (bug number two), so Claude picked "Build it with these circuit problems listed" and said it would fix the problems with edits afterwards. The job finished at the 113-second mark: 36 parts, 708 traces, 134 vias, four layers.
Claude read the netlist
Here is where it earned its keep. It called get_board with detail: full, which returns every net with the pads it connects, and compared it with what a BQ24074 power-path charger needs. It found three mistakes that our design-rule check had passed, because they are not copper problems:
- The ESP32-S3 module's 3V3 pin was on its own net, fed through a 1 kΩ resistor (R12) from the 3.3 V rail. In Claude's words, "it would brown out immediately."
- The charger's temperature-sense pin was pulled up to 3V3 through 10 kΩ, which Claude said "would block charging."
- The charger's input-current-limit pin (ILIM) sat on the not-connected net.
I checked all three against the board data it read. They were real.
It also disagreed with one of our checks. The question had said EN1 low "keeps U2 shut down." Claude pointed out that with EN2 high and EN1 low, the BQ24074 takes its input current limit from the ILIM resistor, which is what the design intends, and that setting EN1 high would put the charger in suspend. That matches the EN1/EN2 table in TI's datasheet. Our check was wrong, and Claude kept the pins as they were.
The fixes went in as precise edit_board instructions, pad by pad:
Re-net these pads exactly (pad -> net), then re-route affected nets:
- U1.2 -> 3V3 (module supply pin must be directly on the 3V3 rail). Net U1_3V3 is removed.
The server applied them and rerouted: "pins re-netted: U1.2 → 3V3, U1.4 → SIG_IO4, U2.7 → GPIO2, U2.12 → U2_ILIM, R4.1 → U2_ILIM, R4.2 → GND and 8 more." A second pass wired the header pins the first build had left on the not-connected net. Then it asked review_board to check the charger wiring pin by pin. The review's AI-written part was the least reliable thing in the session: it called the 12 Mbps USB link 480 Mbps and said the charger's exposed pad had no thermal vias, and when Claude asked for four, the server answered that all four were already there.

The board after Claude's fixes, opened in PCBEditor's editor: 35 parts on 73.8 × 54.6 mm, four layers, every net routed. Claude's last edit request is in the chat panel on the right.
Where it stopped
Two design-rule errors would not go away: inner-layer traces passing 0.151 and 0.156 mm from the USB-C connector's shield holes, where the rule is 0.25 mm. Claude tried several edits. Our edit guard threw one away because it "would take DRC errors from 2 to 4". Another came back with "Nothing changed on the board". After the third, Claude stopped and told me:
Two DRC errors remain that the tool wouldn't fix after three attempts, so I haven't exported any fab files.
That is exactly what I want an agent to do with a board that is not ready. export_board would have refused anyway: it will not hand out fab files while there are DRC errors the user has not accepted. But Claude did not try to accept them on my behalf.
Its summary also listed the board size, 73.8 × 54.6 mm against the 60 × 30 mm it had asked for, the loosely coupled USB pair, and a note to check the polarity of my JST battery lead before plugging it in. The whole session took about 18 minutes: 6 design jobs, 9 edits, 25 waits on get_job, and a board I could open in the browser and fix in a few minutes by hand.
What I took away
The split works. Claude was good at the things a language model is good at: writing a brief, reading a netlist against what a datasheet expects, writing exact change requests, and knowing when to stop. The server did the things it should not do: wiring from pin maps, routing, measuring clearances.
Checks pass wrong boards. All three wiring mistakes passed the design-rule check, because DRC measures copper, not intent. The first design_board result even said the board was DRC-clean while the saved board had two errors. If your agent does not read the netlist, you have to.
Our MCP layer has gaps. Circuit-problem stops that do not arrive as questions, free-text answers that are ignored, a check that misread the BQ24074's enable pins, a "DRC-clean" message on a board with two errors, a board larger than asked for. All of these are now on the list, found in one afternoon by letting an agent use the product the way it wanted to.
An agent that refuses to export is a feature. I would rather get "not ready, here is why" than a zip.
If you want to try the same thing, the guide walks through connecting Claude, ChatGPT or Gemini, the first prompt, answering the designer's questions, checking, editing and exporting, with the responses you should expect: pcbeditor.com/mcp/guide.
來源:DEV Community · dev.to