Guides

Can Claude Code design hardware? A working repo, from datasheet to delivered parts

A practical workflow for engineers using Claude Code on a hardware repo, with KiCad, CadQuery, a BOM, and parts ordered through an MCP server you approve.

Most engineers assume a coding agent is useless on a hardware repo because hardware is not code. The schematic is binary-ish, the CAD lives in a GUI, the datasheet is a PDF, and the parts come from a web shop. What is there for an agent to do?

More than you think, if you lay the repo out so the agent can read it. KiCad 8 and 9 projects are plain text. CadQuery and OpenSCAD parts are scripts. A datasheet is a file the agent can open. A BOM is a CSV. And since the parts supplier can now be a tool the agent calls, the loop closes: design, check, price, order, with you approving the last step.

This guide walks through that loop with Claude Code. It is honest about where the model fails, because it does fail, in specific and predictable ways.

What a hardware repo looks like to an agent

Claude Code reads files and runs commands. Everything it cannot read as text is invisible to it. So the first job is a layout where the important things are text.

my-device/
  CLAUDE.md                 # how to work in this repo (below)
  hardware/
    board/                  # KiCad project: .kicad_pro, .kicad_sch, .kicad_pcb
    mech/
      bracket.py            # CadQuery (or build123d / OpenSCAD) parametric parts
      out/                  # exported STEP / STL, gitignored
  firmware/
    platformio.ini          # or ESP-IDF / Zephyr manifest, Arduino sketch
    src/
  docs/
    datasheets/             # PDFs the design depends on, committed
    decisions.md            # why we picked what we picked
  bom/
    bom.csv                 # one line per part: ref, value, footprint, MPN, qty
    stock.csv               # what is already on the shelf

Three choices matter here.

KiCad over a binary EDA format. KiCad's files are S-expressions, so the agent can grep a net name, find which pin it lands on, and diff the schematic between commits. If your team uses Altium or EasyEDA, export a BOM CSV and keep that in the repo; the agent works with the export.

Scripted CAD over a GUI model for parts you expect to iterate. A bracket written in CadQuery or build123d is a Python file. The agent can change a wall thickness, rerun the script, and export a STEP. A Fusion or SolidWorks model stays the source of truth for the assembly; export STEP from it and commit the export.

Datasheets in the repo. Not a link, the file. The agent cannot follow a vendor link that lands on a cookie wall, and a committed PDF is pinned to the revision you designed against.

A CLAUDE.md for a hardware project

Claude Code reads CLAUDE.md at the start of every session. For a software repo it holds build commands and style rules. For hardware it holds the things that a new engineer would otherwise learn by breaking something.

# my-device

Battery-powered sensor node: ESP32-S3 module, LiPo charger, 3 sensors on I2C,
one TMC2209 stepper driver for the shutter. Enclosure is a two-part 3D print
with an aluminum bracket.

## Where things are
- hardware/board/: KiCad 9. Open with KiCad, never edit the .kicad_pcb by hand.
- hardware/mech/: CadQuery scripts. `python hardware/mech/bracket.py` writes
  STEP and STL to hardware/mech/out/.
- docs/datasheets/: the datasheet revisions this design was checked against.
- bom/bom.csv: the ordering BOM. One line per part, columns:
  ref, value, footprint, mpn, manufacturer, qty, notes.

## Rules
- Every part in bom.csv needs a manufacturer part number (MPN). "generic" is
  not an MPN. If you cannot find one, write TODO in the mpn column and tell me.
- Do not change a footprint without telling me which pads moved.
- Pin assignments come from docs/datasheets/, not from memory. Quote the page.
- Schematic checks: `kicad-cli sch erc hardware/board/board.kicad_sch`.
- Mechanical checks: run `python tools/meshcheck.py hardware/mech/out/*.stl`
  after every export. Watertight or it does not ship.
- Units are millimeters. Threads are ISO metric. Clearance holes per ISO 273
  medium unless the file says otherwise.
- Ordering goes through the Next Everything MCP server. You may scan, search
  and quote. You do not check out. I open the payment link myself.

Two things in that file do most of the work. "Pin assignments come from the datasheet, not from memory" forces the model to open the PDF before it writes a net. And the ordering rule draws the line between what the agent may do alone and what needs a human.

Getting the model to read a datasheet

Claude Code can open a PDF in the repo and read it page by page. What you ask for decides whether the answer is useful.

A bad prompt: "What is the pinout of the TMC2209?" The model may answer from training data, which could be a different package or an old revision.

A better prompt:

Open docs/datasheets/TMC2209_datasheet_rev1.09.pdf. Find the pin table for the
QFN-28 package and reproduce it as a Markdown table: pin number, name, type
(power, input, output, bidirectional), one-line function. Cite the page number.
Then list every pin whose function depends on a strapping resistor.

Ask for a table, ask for page numbers, ask for the specific package. Then check two or three pins against the PDF yourself. If those match, the rest usually does. If they do not, the model is reading the wrong table, and nothing downstream is trustworthy.

The same pattern works for electrical limits ("absolute maximum ratings, as a table, with the page"), for recommended layouts ("what does the datasheet say about the decoupling capacitor placement for VS"), and for mechanical drawings ("give me the package outline dimensions with tolerances").

Known failure mode: the model confuses similar part families. A pin table for the wrong variant looks exactly as confident as the right one. The page citation is your defense.

Generating a parametric bracket with a review loop

Here is a loop that works for mechanical parts: the agent writes the script, exports, runs a mesh check, and you review the STEP in your CAD viewer before anything is ordered.

The prompt:

Write hardware/mech/bracket.py in CadQuery. An L-bracket: base 40 x 30 mm,
upright 25 mm tall, wall 3 mm, two M3 clearance holes in the base 24 mm apart,
2 mm fillets on the vertical outside edges. All dimensions as named constants
at the top. Export STEP and STL to hardware/mech/out/. Then run
tools/meshcheck.py on the STL and report volume and bounding box.

What the agent should produce, roughly:

import cadquery as cq

T = 3.0                 # wall thickness, mm
L, W, H = 40.0, 30.0, 25.0
HOLE = 3.4              # M3 clearance, ISO 273 medium
PITCH = 24.0            # hole spacing

base = cq.Workplane("XY").box(L, W, T, centered=(True, True, False))
wall = (
    cq.Workplane("XY")
    .box(L, T, H, centered=(True, True, False))
    .translate((0, (W - T) / 2, 0))
)
bracket = (
    base.union(wall)
    .edges("|Z").fillet(2.0)
    .faces("<Z").workplane()
    .pushPoints([(-PITCH / 2, -6.0), (PITCH / 2, -6.0)])
    .hole(HOLE)
)

cq.exporters.export(bracket, "hardware/mech/out/bracket.step")
cq.exporters.export(bracket, "hardware/mech/out/bracket.stl")

And a mesh check that takes seconds to write and catches the most common export problem, a non-manifold or inverted mesh:

# tools/meshcheck.py
import sys, trimesh

for path in sys.argv[1:]:
    m = trimesh.load(path)
    ok = m.is_watertight and m.is_winding_consistent and m.volume > 0
    print(f"{path}: watertight={m.is_watertight} volume={m.volume:.1f} mm3 "
          f"bounds={m.bounds.tolist()} {'OK' if ok else 'FAIL'}")
    if not ok:
        sys.exit(1)

The review loop is: agent writes, agent exports, agent runs the check, you open the STEP. If the holes are on the wrong face, say so in one sentence and let it fix the script. Because the part is parametric, "make the wall 4 mm and move the holes to 26 mm" is a thirty-second change, not a rebuild.

What the agent does not do in this loop is engineering judgment. It does not know that a 3 mm PETG wall will creep under a sustained load, or that the fillet radius should be larger than the printer's nozzle. It will not run a strength calculation unless you give it a tool that does. Treat the script as a drafting aid, and treat the mesh check as a file-format check, not a design check.

Checking the schematic

KiCad ships a command line, which means the agent can run the electrical rules check and read the result instead of guessing.

Run kicad-cli sch erc on hardware/board/board.kicad_sch with --format json.
Group the violations by type. For each unconnected pin, tell me the symbol,
the pin name from the datasheet in docs/datasheets/, and whether leaving it
open is allowed per the datasheet.

For a netlist review, export it and ask targeted questions:

kicad-cli sch export netlist --format kicadxml \
  -o hardware/board/out/netlist.xml hardware/board/board.kicad_sch
From hardware/board/out/netlist.xml: list every net connected to the ESP32-S3
module's strapping pins (GPIO0, GPIO3, GPIO45, GPIO46) and what else is on
each net. Flag anything that could hold a strapping pin at the wrong level
at boot. Use the module datasheet in docs/datasheets/ for which pins those are.

This is where text-based EDA pays off. The agent is not looking at a picture of a schematic; it is reading the same data KiCad reads.

Known failure modes, both common: the model invents a footprint name that is not in your library, and it invents a part that does not exist or has been discontinued. Both are plausible-looking strings. The first shows up when you open the PCB editor and the footprint is missing. The second only shows up when you try to buy the part. The fix for the second is in the ordering step below: a parts tool with live stock answers the question the model cannot.

Writing the BOM

The BOM is the handoff between design and purchasing, and it is the file the model gets wrong most quietly. Ask for it in a fixed shape and make the model show its work.

Generate bom/bom.csv from the KiCad schematic. Columns: ref, value, footprint,
mpn, manufacturer, qty, notes. One line per distinct part, refs grouped
(C1,C2,C5). Take MPNs from the schematic fields where present. Where a symbol
has no MPN, do not guess: write TODO in mpn and explain in notes what spec
the part needs (value, tolerance, voltage, package). Do not include DNP parts.
Then compare against bom/stock.csv and add a column "have" with what is
already on the shelf.

The "do not guess" instruction matters more here than anywhere else. A guessed MPN for a 100 nF capacitor is usually harmless. A guessed MPN for a power inductor or a connector is a wrong order.

For the mechanical side, add the fasteners and inserts by hand or from a small table in docs/. A model that can see the CadQuery script knows there are two M3 holes; it does not know whether you want socket head screws, button heads, or heat-set inserts in the mating part. Tell it.

Ordering the parts through an MCP server

Up to here the agent has only read and written files. Ordering needs a tool, and the way to give a coding agent a tool is the Model Context Protocol. If MCP is new to you, MCP in five minutes covers the basics.

Next Everything runs a remote MCP server that prices electronics, PCBs, 3D prints and CNC parts from a project folder. Sign up at nexteverything.io/signup, copy your API key, and register the server once:

claude mcp add --transport http nexteverything https://mcp.nexteverything.io/mcp \
  --header "Authorization: Bearer nx_live_your_key"

Then, in the repo:

Use Next Everything to find all the parts for this project. I want to build 2
of them. Scan the repo with nx_scan_project including mechanical parts, then
quote with the recommended strategy. Show me the picklist. Do not check out.

What happens, tool by tool:

Step Tool What it does
1 nx_scan_project Reads the KiCad project, the CadQuery output and platformio.ini, builds a normalized BOM, resolves each line to an orderable part, flags ambiguous ones
2 nx_search_parts For flagged lines or your questions: live stock and price by MPN, spec or plain description, alternates ranked by compatibility
3 nx_quote Prices the whole build including shipping and duties, recommended or fastest strategy
4 nx_quote_fabrication Instant quote for one STEP, STL, 3MF, DXF or Gerber package, by process and material
5 nx_checkout Creates a payment link. The agent cannot pay
6 nx_track_order Status and tracking numbers for every sub-order

The picklist is the review step. Every line has a price, you untick what you already have from stock.csv, you change quantities, and if a part is out of stock the quote shows a clearly marked replacement that nothing swaps in without your OK. If a minimum order quantity or a price break makes extra pieces cheaper, you are told before you pay. Quotes are valid 24 hours.

Only then do you ask for checkout, open the link, and confirm. The full walkthrough with a KiCad project is in ordering parts for a KiCad project from Claude Code.

One rule: if a tool call fails, the agent should say so and retry, not pretend it got a quote. The server returns clear error codes (a 401 is a wrong key), so a well-behaved agent never has to guess.

What the model gets wrong, and what to do about it

A short list, so you can plan for it instead of discovering it.

Invented footprints. The model writes a footprint name that looks like a KiCad library name and is not in your library. Catch it with ERC and the PCB editor's missing-footprint warning; better, tell it in CLAUDE.md which libraries exist.

Invented or discontinued parts. An MPN that never existed, or one that was obsoleted years ago. Catch it with a live parts search before the BOM is final. This is the single strongest reason to give the agent a parts tool rather than letting it recall part numbers.

No physics. The model will produce a bracket of any thickness you ask for and a trace of any width. It does not check stress, thermal limits, current density or creepage unless you wire up a tool that does, and even then you read the result. Design with what you can buy argues that availability is a design constraint too, and the same applies: the model will not check it unless it has the tool.

Confident wrong reads. A pin table from the wrong package, an absolute maximum from a sibling part. Always ask for page citations and spot-check.

Edits to binary files. Do not let the agent hand-edit .kicad_pcb or a STEP file. Let it edit the script or the schematic and regenerate.

None of these are reasons to skip the agent. They are reasons to build the repo so that each failure has a check: ERC for the schematic, a mesh check for the part, a live stock search for the BOM, and your own eyes on the picklist before the payment link.

The loop, in one place

  1. Lay out the repo so the important things are text: KiCad, scripted CAD, committed datasheets, a CSV BOM.
  2. Write a CLAUDE.md with locations, rules, checks, and the line the agent does not cross.
  3. Ask for datasheet facts as tables with page numbers; spot-check.
  4. Generate parts as scripts; export; mesh check; review the STEP yourself.
  5. Run ERC and netlist questions through kicad-cli, not through a screenshot.
  6. Build the BOM with "do not guess"; fill TODOs with a live search.
  7. Connect a parts tool over MCP, scan, quote, review the picklist, and open the payment link yourself.

If you want to compare how different models handle the same tasks before picking one, the best AI models for hardware engineering in 2026 runs them on the same five jobs. For the ordering step, sign up is free, the docs list every tool, and you pay only for parts in an order you approve.