fusion-electronics-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| FUSION_MCP_LIBRARY | No | Component library (part JSON files). Defaults to the per-user data folder. | |
| FUSION_MCP_TRANSPORT | No | Transport to use: `addin`, `builtin` (Fusion's MCP server), or `auto` (the add-in when it is running, else the built-in server). | auto |
| FUSION_MCP_KEEP_FOCUS | No | Hand keyboard focus back when Fusion takes it. | 1 |
| FUSION_MCP_BUILTIN_URL | No | Fusion's MCP server address. | http://127.0.0.1:27182/mcp |
| FUSION_MCP_SHEET_FRAME | No | Frame for new schematic sheets, in the form `DEVICE@LIBRARY`. | |
| FUSION_MCP_POWER_SYMBOL | No | Power symbol for block schematics (its value is set to each rail's name), in the form `DEVICE@LIBRARY`. | |
| FUSION_MCP_EASYEDA_CACHE | No | EasyEDA footprint cache. Defaults to the per-user data folder. | |
| FUSION_MCP_GROUND_SYMBOL | No | Ground symbol for block schematics, in the form `DEVICE@LIBRARY`. | |
| FUSION_MCP_EASYEDA_INTERVAL_S | No | Minimum seconds between EasyEDA requests. | 15 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_contextB | Which Electronics documents are open in Fusion and which editor is active. |
| list_designsA | Electronics designs and libraries in the active Fusion project's top folder, or in one folder path ('Live tests', 'Parts/Connectors'); folders are not searched recursively (walking a big project's folder tree froze Fusion). |
| open_designB | Open a design (schematic + board) from the active project and make it current. |
| open_libraryC | Open a Fusion library (.flbr) from the active project in the library editor. |
| new_designA | Create a new electronics design with a schematic and a board. With |
| close_designA | Close a design. Refuses if it has unsaved changes unless discard_changes is true. |
| get_board_summaryB | Board size, copper layers, part and net counts, net classes and design-rule highlights. |
| list_partsB | Parts on the board with placement and JLC attributes. |
| get_partB | Everything about one part: board placement, schematic device, attributes, and each pin's net. |
| list_netsB | Nets (merged across schematic sheets) with pin counts and routed length on the board. |
| get_netB | One net: its schematic pins (with direction) and its board routing by layer. |
| get_layer_stackA | The layer stackup: copper and dielectric thicknesses, dielectric constants (Er) and materials.
Read from the open design's Fusion design rules, or from |
| run_drcB | Run Fusion's DRC on the board and return the violations. |
| run_ercA | Run Fusion's ERC on the schematic and return the findings. |
| review_schematicB | Schematic review: offline rules (unconnected power pins, single-pin nets, output conflicts, undriven nets, missing JLC codes, empty values) plus Fusion's ERC. |
| list_diff_pairsB | Differential pairs (by _P/_N style names) with per-side length, skew, width, gap and vias. The skew limit defaults to the design's dpMaxLengthDifference rule. |
| check_length_matchB | Compare routed lengths of a group of nets (e.g. a bus or lanes) against the longest. |
| check_impedanceA | Estimate every differential pair's impedance on its routed layer using the real stackup, and compare with the target. Also flags pairs whose P-N gap is tighter than their net class's copper clearance rule (a common cause of mass DRC errors). Estimates are IPC-2141 closed form, typically within ~10% of a field solver; use a solver or the fab's calculator for sign-off. |
| estimate_impedanceA | Closed-form (IPC-2141) impedance estimate for a hypothetical trace. geometry: microstrip (dielectric_mm = height to the reference plane) or stripline (plane-to-plane). get_layer_stack gives the real thicknesses and Er; check_impedance does this for every routed pair. |
| export_bomB | JLCPCB-format BOM CSV (plus the excluded-parts CSV), generated from the open board. |
| check_gerbersA | Check a CAM output (zip or folder of gerbers + Excellon drills) against the open design: complete layer set (copper count = stackup, mask, silk incl. bottom when the board has bottom text, paste where there are SMD pads, outline, drill), outline size, every drilled hole of the design (pads, vias, holes) present with the right diameter and position and nothing extra, and pad flash counts per layer. Run it on the zip before uploading to the fab. |
| export_cplA | JLCPCB-format pick-and-place (CPL) CSV. JLC places each part with its own (EasyEDA) footprint, whose zero orientation and origin can differ from ours (KiCad-sourced connectors and ICs typically). With jlc_orientation, parts whose footprint data is in the local EasyEDA cache get the derived rotation/offset applied (library JLC-ROTATION / JLC-X-OFFSET / JLC-Y-OFFSET attributes still win); ambiguous derivations are listed for review instead. Never uses the network: fill the cache with check_jlc_orientation(fetch=true). |
| check_jlc_orientationA | Compare each placed part's footprint with the one JLC places it with (EasyEDA's, by the part's JLCPCB code) and derive the CPL rotation/offset that lines them up: pads matched by name (geometry when names differ, flagged ambiguous so a person confirms polarity). fetch=true downloads missing footprints from easyeda.com (the only internet access this server makes: cached forever, >= 15 s between requests); otherwise only the local cache is used. Pads are matched by pin FUNCTION (K/A, FB/EN...) when both footprints name their pins, so a part whose libraries number pads differently is not turned around. |
| add_partB | Place a device (device set + variant name, e.g. 'RES_0603_10K_1%_1/10W') from a Fusion
library into the schematic. The part is forward-annotated onto the board. |
| connect_pinsA | Connect schematic pins into a named net. Pins are PART.PIN or PART.PAD. Each pin gets a short named wire stub with a net label (labels=false to omit), so no wire crosses other parts and every piece of the net is visibly named. Refuses to join two existing nets unless allow_merge is true. |
| rename_netA | Rename a schematic net (all sheets where it has wires). Renaming onto a name that already exists merges the two nets, which is refused unless allow_merge is true. only_segment_with_pin: 'REF.PIN' renames just the wire segment on that pin (e.g. a labelled stub), moving that pin to new_name and leaving the rest of the net as it is; how to swap two pins' nets: rename one stub to a temporary name, the other stub across, then the temporary one. |
| set_part_variantB | Switch a part to another device variant of its device set (how variant-based passive libraries change value; the variant's JLC code and attributes follow). Example variant: '_680R_1%_1/10W'. |
| set_part_valueA | Set a part's value. Only for device sets with user-definable values; for fixed-value library parts (e.g. passives with one variant per value) use set_part_variant instead. |
| label_netsC | Add a net label to every piece of a net that is drawn separately from the rest without a
label (the convention: same net, not visibly connected, must be named). Limit with |
| new_sheetA | Add a schematic sheet with your standard frame and set its headline (sheet description).
|
| move_partA | Move a board part so its origin is at (x, y) mm. |
| rotate_partB | Set a board part's absolute rotation (degrees) and side (bottom=true places it on the bottom). |
| add_viaC | Add a through via on a net at (x, y) mm. The pad diameter follows the design's restring rules. |
| add_traceC | Route a trace through the given points [[x, y], ...] (mm). layer: 'top', 'bottom', 'inner1'.. or a layer number. |
| route_pairA | Route a differential pair as two coupled traces along a centreline you choose. centreline_mm: [[x, y], ...] for the middle of the pair, from near the start pads to near the end pads; use 45-degree bends. Each trace is the centreline offset by (width + gap) / 2 with mitred corners, so the gap holds through bends, plus a short 45-degree fan-in to its pad. Which side is P is set by the start pads. If the end pads are the other way round the result says crossed=true: either approach the end pads from the other direction (no via), or pass a tail for one trace, [[x, y], {"via": [x, y]}, [x, y]], which changes layer at the via. p_head_mm / n_head_mm: explicit path from a trace's start pad to the trunk, for pins the automatic 45-degree fan-in cannot reach cleanly (e.g. through a gap in a pin row). Every 90-degree corner (typically where a trace leaves a pin) becomes two 45-degree bends, chamfer_mm along each leg (0 keeps hard corners). The shorter trace gets rounded bumps until the skew is within max_skew_mm. Nothing is written if the plan has conflicts (copper of other nets, holes, keepouts, the partner trace) or dry_run=true; the plan is returned either way. |
| route_traceA | Route one connection between two pads (PART.PAD, e.g. 'J1.A19' to 'J9.5') the way a person would: straight runs, 45-degree corners (no 90s), around other nets' copper with the design's clearance (or clearance_mm), keepouts and the board edge, ending exactly on the pad centres. layer: 'top' / 'bottom' to prefer one layer, 'any' to let it choose; vias only where needed (allow_vias=false forbids them). dry_run=true (default) returns the plan and a picture without writing; run again with dry_run=false to draw it (checked against the board afterwards). |
| route_netB | Route a whole net with route_trace's router, one airwire at a time, shortest first: each connection starts at a pad still unconnected and ends on the nearer of its partner pad or any copper the net already has (a tap), so the net grows as a tidy tree. Each step is written and checked before the next is planned; stops when the net has no airwires (pours count as copper). dry_run=true (default) plans only the first connection and returns its picture. |
| route_closeB | Route every short connection at once: each airwire up to max_len_mm (local hops: passives to their pins, LED + resistor, bootstrap caps), shortest first, with route_trace's router and no vias by default. widths: {net regex: mm} for power nets (e.g. {"^3V3|^12V|^SW$": 0.5}). Planned one after another on a working copy (each sees the ones before), written as one undo step and checked. Connections it cannot make cleanly are listed and left for later. |
| route_remainingA | The free-router step (after pours, GND vias, close hops, fan-outs and bus lanes): route every connection still unrouted, shortest first, with rip-up and reroute when one is blocked (only traces laid in this run are ever ripped; existing routing stays). Routes are 45-degree, keep clear of connector pin fields, and cost extra to run through other nets' power pours (a via is usually cheaper). widths: {net regex: mm} for power nets. Nets with pours are left to their pours unless include_pour_nets. dry_run=true (default) plans offline and returns a picture; dry_run=false writes it all as one undo step, checked (airwires drop, no layer change without a via). |
| place_clustersA | Place passives around the part they serve, by rule (the user's patterns: pin -> part -> rail
and series parts along the pin's escape, tees too, decaps standing across the column first,
bridges along the package edge, chains such as LED + resistor following the part they hang
off; connector pins at a board edge escape into the board). Main parts (ICs, connectors) and
|
| lay_busA | Lay a bus: one lane per net, side by side along a path you choose ([[x, y], ...], 45-degree
corners), lane 0 on the path and lane i offset i * pitch to the LEFT of travel, each lane
trimmed to the stretch its own pins span. Order |
| set_board_outlineA | Draw a rectangular board outline (Dimension layer 20). New Fusion designs come with a default outline; pass replace=true to remove the existing outline first. |
| add_textA | Add board text, e.g. silkscreen pin labels. layer: top_silk, bottom_silk, top_doc, bottom_doc or a layer number. Vector font; size_mm is the character height and ratio_pct the stroke as % of it (JLC needs >= 1.0 mm text and >= 0.153 mm strokes: the defaults). Bottom layers are mirrored so they read correctly from the bottom. align: center, bottom-left, ... Keep text off pads: fabs clip silk over exposed copper. |
| add_holeB | Add a non-plated hole on the board (e.g. a mounting hole). |
| rip_upA | Remove routed traces and vias (they become unrouted connections again). Polygons/pours are kept, BUT a ripped-up net's pours stay unfilled afterwards (RATSNEST does not refill them on 2705.1.15): avoid ripping up nets that have pours, or re-add their pours after. |
| add_pourA | Add a copper pour (polygon) on a net, e.g. a GND plane. Without points it follows the board outline (inset_mm = 0): the copper-to-edge distance then comes from the design rule for board edge clearance, as EAGLE intends. Note the outline wire is width_mm wide and centred on the vertices, so an inset moves copper only inset - width/2 from the edge. isolate_mm is the clearance to other copper. thermal_width_mm is the width of the thermal-relief spokes joining pads to the pour (Fusion's default is a thin 0.1524 mm; the gap comes from the design rule slThermalIsolate). rank sets priority where pours of different nets overlap on a layer: rank 1 wins and is cut out of higher ranks (e.g. output islands rank 1 inside a rank 3 GND plane). Respects keepouts (add_keepout); filled immediately. |
| list_poursA | Copper pours with their live settings: net, layer, thermal relief width, isolate, rank. |
| set_pour_thermalsA | Set the thermal-relief spoke width of a net's existing pours (all its pours, or one layer). Each pour is picked on its outline with the other copper layers hidden, then the view is restored. |
| add_keepoutA | Circular keepout (e.g. around a mounting hole): no copper on 'top' / 'bottom' and no 'vias' inside it. Pours and the autorouter respect it. Uses EAGLE restrict layers 41/42/43. |
| stitch_viasA | Via stitching for a net's pours: vias on a grid wherever they clear other nets' copper, every pad (no via-in-pad), holes, keepouts and the board edge, using the design's clearance and drill rules. keep_away_mm: {net regex: mm} keeps vias further from some nets' copper, e.g. {"^ETH|^USB_D": 0.6} to keep ground as far from impedance pairs as their pours are. under_parts: refdes regex of parts vias may go under, e.g. "J[0-9]+" for big through-hole connectors: under the body (an overhang to the board edge) but not in the pin field (the pads' box + 2 mm); other parts stay via-free. One call places them all (one undo step). dry_run=true only plans. |
| fanout_padA | Fanout via for one pad: a short trace from the pad to the nearest valid via spot (clear of other nets, every pad, holes, keepouts and the edge; never via-in-pad). Typical uses: connect a GND pad that routing cut off from its pour, or power-pin fanout before autorouting. |
| ground_viasB | A via next to every SMD pad on a plane net (GND by default): a short trace from the pad to the nearest clear via spot (never via-in-pad), tying the pad to the plane on the other layer. Planned one pad at a time so the vias keep clear of each other; all written as one undo step. skip: pads to leave out ('U1.4'). Through-hole pads are skipped (they reach both layers). |
| remove_stubsA | Fix trace stubs. A stub whose loose end lies on a same-net pad (Fusion re-anchors trace ends off-centre when a part rotates) is SNAPPED to the pad centre; a truly dangling end is cut back to the last place something joins the segment (a tap, a via), or the segment is deleted when nothing joins it before its other end. Fusion's DRC does not report every stub (a bus lane's tail past its last tap passes it), so with geometric=true (default) the board's copper is also checked directly. Every change is verified, and the run stops if the number of unrouted connections goes up, so a real connection is never removed. |
| clean_viasA | Delete a net's vias that now violate clearance to a pad (any net) or to another net's copper, e.g. stitching vias left under a part that moved. Run stitch_vias again afterwards to refill. |
| attach_3d_modelA | Give a package in the OPEN library a 3D model from a STEP file. The model is placed in the
footprint's frame (KiCad library models need no offset; pass offset_mm [x, y, z] and
rotation_deg [rx, ry, rz] when a model's origin differs), saved as a 3D package document in
the project's The model must stand on the board: more of it above the board than below (pins may go
through), else nothing is saved and the call fails (allow_below_board=true for a part that
really hangs below, e.g. a through-board connector): fix rotation_deg (KiCad's 3D rotation
signs are the opposite of Fusion's; vendor STEPs are often Y-up and need +90 about X).
If the package already has a 3D model, the new model's file gets a versioned name
(_V2, ...) so the files in |
| list_design_rulesB | Design-rule (.edru) and stackup (.estackup) files shipped with this server for common fab processes (every JLCPCB 4- and 6-layer impedance stackup, and a 2-layer 1.6 mm board; built from JLC's published tables by tools/gen_jlc_stackups.py): copper layers, board thickness, dielectrics (thickness, Er) and the key clearances of each. Fusion cannot load rules from a script: load a .edru in the DRC dialog (Rules > Load; it carries its stackup too) or a .estackup in the Layer Stack Manager. copy_to copies the files into a folder you can reach from Fusion's file dialog (e.g. Downloads). |
| get_design_rulesA | Key design rules of the open board (clearances, minimum width and drill, edge clearance, via restring), read from Fusion's own V2 rules. Warns when they are still Fusion's new-design defaults, which are too loose/tight for most fabs (e.g. 40 mil edge clearance). |
| autorouteA | Route unrouted connections with an autorouter, keeping existing traces (route critical
nets, power and pours first). engine='fusion' runs Fusion's own autorouter and applies its
best variant (most complete, then fewest vias). Without |
| render_boardA | Picture of the board as Fusion has it now (from a fresh export): outline, pads, holes, keepouts, part names, traces (top red solid, bottom blue dashed), vias, pour outlines. highlight_nets: regex of nets to colour and label at their pads. region_mm: [x0, y0, x1, y1] to zoom. plan: a route_pair plan (from dry_run) drawn on top before writing it. Returns the PNG and where it was saved. Needs matplotlib (optional install). |
| routing_statusB | Unrouted connections, unrouted nets, segment and via counts, routed length. |
| score_placementA | Placement quality without routing: ratsnest length (MST per net over pad centres), number of crossing air wires between nets, and the worst nets. Lower is better. Pour nets (GND) are excluded by default. Use it before and after placement changes. |
| suggest_placement_movesA | Ranked single-part moves that lower the placement score (shorter ratsnest, fewer crossings),
searched within radius_mm of each part, inside the board and clear of same-side parts. |
| import_netlist_from_kicadA | Build the schematic of a KiCad board in this design. part_map maps a KiCad refdes OR footprint name to 'DEVICE@LIBRARY' (device = device set + variant), e.g. {"R1": "RES_0402_1K_1%@MY_PASSIVES", "RJ45-TH_RJSAE538402": "CONN_RJ45_2X1_HC-RJ45-059A@MCP Library"}. Mounting holes (no pads) are skipped; add them on the board with add_hole. style="blocks" (default) draws a reviewable schematic: each IC/connector with its passives wired to it (series parts inline, caps and pull-ups hanging off the net, LED/FET drivers stacked), labels only on nets that leave a block, ground and rails as power symbols, blocks packed onto framed sheets. It needs ground_symbol and power_symbol ('DEVICE@LIBRARY'; a power symbol whose net name follows its value, e.g. GPLIB's bars) or FUSION_MCP_GROUND_SYMBOL / FUSION_MCP_POWER_SYMBOL, and frame or FUSION_MCP_SHEET_FRAME for new sheets. pad_map translates KiCad pad names to library pad names where they differ, by refdes or footprint ({"D_SMB": {"1": "C", "2": "A"}}; one-pad parts map themselves). preview_only=true lays it out and writes an HTML preview without drawing it (parts are added once to read their symbols, then removed). Every pin is checked afterwards. style="grid" places parts in rows with a labelled stub on every pin (the old behaviour). dry_run=true reports the plan without changing anything. |
| import_routing_from_kicadA | Copy a KiCad board's tracks, arcs and vias into this board (same frame as import_placement_from_kicad: origin at the board's bottom-left, y up), as one undo step. Run import_placement_from_kicad first so pads line up. nets limits it to those nets; vias=false skips vias. Every segment is checked against the board read back from Fusion. Pours are not copied (use add_pour). Import BEFORE adding pours: with pours on the board Fusion refills them after every via, and 490 vias kept it busy for over 40 minutes (2705.1.15). dry_run=true only counts what would be drawn. |
| import_placement_from_kicadA | Place this board's parts where a KiCad board (.kicad_pcb) has them: position, rotation and side, matched by reference designator. KiCad's frame is converted (origin at the board's bottom-left, y up; bottom parts at angle R become mirrored 180 - R). All moves run in one verified command (one undo step) in Ignore Violators mode, so parts may sit over each other on opposite sides. dry_run=true only reports the moves. Routing is not imported. fit_pads (default): each part is placed so its pads land on the KiCad board's pads (matched by pad name, least squares), not by footprint origin and angle: a Fusion footprint whose origin or pin-1 orientation differs (JLC's SOT-23-6 is turned 180 degrees from KiCad's, a header's origin is pin 1 in one and the centre in the other) still lands right. Parts whose pads sit more than 0.1 mm from KiCad's after the fit are listed under footprint_differs. |
| undoA | Undo the last change in the board or schematic editor. |
| save_designB | Save the active document as a new version in Fusion's cloud. |
| search_libraryC | Search this server's component library (library/parts). |
| create_library_partA | Create a part in this server's component library from a KiCad footprint (.kicad_mod): from
KiCad's own libraries, or JLCPCB's footprint for a part exported with |
| get_library_partB | Full definition of one library part, including metadata (source, maintainer, link). |
| insert_library_partA | Build a library part into the Fusion library open in the library editor. Afterwards call save_design, then close_library, before placing it with add_part (placing from a library that is still open can crash Fusion). Two-pin passives (resistors, capacitors, inductors, ferrites, fuses, crystals, diodes, LEDs, TVS) are drawn with this server's standard symbols, not the symbol the part came with from EasyEDA or KiCad, so every schematic reads the same; set "style": false in the part to keep its own symbol, or name a style ("res", "cap", "cap_pol", "inductor", "ferrite", "fuse", "crystal", "diode", "schottky", "zener", "led", "tvs", "tvs_bidir"). |
| update_from_librariesA | Update the open design from all its libraries (Fusion's 'Update all'): brings in library changes such as attributes (e.g. JLC-ROTATION / JLC-X-OFFSET / JLC-Y-OFFSET) and 3D packages. Save the library and close it first. 'Update all' can leave parts on an old 3D model and report nothing to do (seen when a package's model was replaced). refresh_parts (reference designators, one per device is enough, e.g. ["J3", "J9"]) re-pulls those parts' devices from their library with REPLACE, accepting Fusion's "a different version of device set ... update?" question (every part of that device follows). Returns the attribute changes and every part's 3D model afterwards, listing parts with none. |
| push_3dA | Bring the board's changes into its 3D PCB (creating the 3D PCB the first time, answering Fusion's Push dialog), then check every part's model is on its own side of the board: a top-side part mostly below the board (a model with the wrong up axis) is listed under wrong_side. The first push needs the add-in transport (the built-in server ends a script by cancelling any command still open). |
| check_3d_modelsA | Check the open 3D PCB: every part's height range against the board's, listing parts whose model sits on the wrong side (a top-side part hanging below the board, or the reverse). |
| close_libraryB | Close an open (saved) library document so its parts can be placed. |
| request_design_reviewB | Request a human design review from Groundplane (not connected yet: makes no network calls). |
| get_assembly_quoteB | Get a PCB assembly quote (not connected yet: makes no network calls). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 77 tools
The tool set has several overlapping families—routing (route_trace/route_net/route_close/route_remaining/autoroute), via placement (add_via/stitch_vias/fanout_pad/ground_vias/clean_vias), and schematic checks (run_erc/review_schematic)—so an agent must rely on detailed descriptions to choose correctly. Most tools target distinct resources/actions, but the boundaries between workflow steps are not always self-evident.
All tool names use snake_case and follow a predictable verb_noun or verb_phrase pattern (list_parts, get_net, add_via, route_trace). Minor single-word names (undo, autoroute) and noun phrases (routing_status) are consistent with the overall convention, with no mixed casing or verb styles.
77 tools is far beyond the typical 3–15 range and matches the rubric’s 50+ extreme-mismatch anchor. Although the domain is broad, many tools are granular variants (multiple routers, multiple via placers, three KiCad importers) that could be consolidated with mode parameters, increasing selection cost for an agent.
The surface covers design creation, schematic capture, board layout, routing, pours, DRC/ERC, fabrication exports, library management, 3D, and KiCad import—very comprehensive. However, targeted deletion tools are missing for parts, nets, pours, keepouts, holes, and text, and there is no create-library operation; undo offers rollback but not direct removal.