kernelCAD
com.kernelcad/kernelcadVersion 0.17.1CAD in ChatGPT and Claude: editable parts, STEP/STL/drawings, in-chat 3D, automatic checks.
Status
Responds69 msAnswered our handshake without sign-in.- Last checked
- Nov 14, 2026, 14:03 UTC
- Latency
- 69 ms
- Remotes responding
- 1 of 1
- Sign-in
- No sign-in
- Hosting
- EU hosting detected (detected, not a legal statement)
- Registry data as of
- Nov 14, 2026, 21:12 UTC
Data from the official MCP Registry, checked by run.zero. How we check
Connect
Streamable HTTP
https://mcp.kernelcad.com/mcpResponds69 msNo sign-in
Claude Code
claude mcp add --transport http kernelcad https://mcp.kernelcad.com/mcpClaude Desktop and claude.ai
Settings > Connectors > Add custom connector
Name: kernelcad
Remote MCP server URL: https://mcp.kernelcad.com/mcpCursor
{
"mcpServers": {
"kernelcad": {
"url": "https://mcp.kernelcad.com/mcp"
}
}
}VS Code
code --add-mcp '{"name":"kernelcad","type":"http","url":"https://mcp.kernelcad.com/mcp"}'Built your own server? run.zero hosts MCP servers on European infrastructure.
Tools
81 tools
Read-only | Idempotent | Open world | ||
|---|---|---|---|---|
add_connectorUse this when you need to add a mate connector to a part. Durably insert `<partBinding>.connector(name, { type, origin, axis?, normal? })` before the final top-level return. Use the part binding returned by add_part. Returns modified source plus diagnostics from re-evaluation. Side-effect-free. | No | No | Yes | No |
add_constraintUse this when you need to add a sketch constraint to a list. Append one validated sketch constraint to a constraint list. Side-effect-free: pass { constraints, constraint } and receive the updated list. | No | No | Yes | No |
add_curveUse this when you need a freeform/organic 3D curve — a body feature line, brow, spine rail, or curve bridge between panel boundaries — authored as a Curve3D into the user's .kcad.ts immediately before the last top-level return. One authoring path, selected by `kind`:
- 'nurbs' — insert a `nurbsCurve(controlPoints, opts?)` declaration. Pass `controlPoints` as a Vec3[] (mm, at least 2 points). Optional NURBS knobs: `degree` (default 3), rational `weights`, explicit `knots`, `closed`.
- 'hermite' — insert a `hermiteG2(a, b)` declaration: a quintic Hermite curve interpolating two endpoints with matching positions, tangents, and (optional) curvatures — bridges two curves with G2 continuity. Each endpoint is `{ point: Vec3, tangent: Vec3, curvature?: Vec3 }` in mm; tangent magnitude ~ chord length; curvature defaults to [0,0,0] (G1-only).
The returned binding has type Curve3D (peer to Shape / Surface) — consume it via `add_variable_sweep` (spine input), `add_surface({ kind: 'boundary' })` (boundary curve), or downstream Curve3D-accepting features. Returns the modified code + diagnostics from re-evaluating. Side-effect-free. Each kind fails closed on its own missing required params. | No | No | Yes | No |
add_featureUse this when you need to insert a new feature line into a script. Insert a new feature line into a kernelCAD script before the last top-level return statement. Returns the modified code as text plus diagnostics from re-evaluating the result. Direct editing is authored here too: use `body.deleteFace(faces)` to heal a removed-face opening, or `body.replaceFace(faces, { origin, normal })` for a parallel planar replacement; the runtime refuses any result that does not pass its single-solid BRepCheck gate. Primitives that accept faceLabels (box, cylinder, extrudeRect, extrudeCircle, extrudePolygon, extrudeRoundedRect) can receive `opts.faceLabels` in the inserted code — use `lookup_api` to see `featureKindFaceLabels` for the full value schema. | No | No | Yes | No |
add_mateUse this when you need to author a mate-graph relationship into the source, selected by `relation` (default 'mate'):
- 'mate' — a typed mate between two connectors ({ name, a, b, type, pose?, limitsDeg?, limitsMm? }).
- 'coupling' — couple a driven mate to a source mate by ratio ({ driven, source, ratio, offset? }).
- 'transmission' — a physical drive path across mates ({ name, kind, sourceMate, drivenMates, path, ... }).
All durably edit source and need { code, assembly_binding }. Params other than `relation` are forwarded verbatim; each relation fails closed on its own missing required params. | No | No | Yes | No |
add_partUse this when you need to add a part to an assembly. Durably insert `const <binding> = <assembly>.part(partName, shapeExpression, opts?)` before the final top-level return in a kernelCAD source string. Returns modified source plus diagnostics from re-evaluating it. Side-effect-free: caller persists the returned source. | No | No | Yes | No |
add_path_segmentUse this when you need a freeform/organic 2D outline — an eyewear brow, ergonomic grip, sneaker midsole, or body silhouette — by appending a curved segment to an existing PathBuilder chain on the named `chain_anchor` variable. The call is injected at the END of the chain, immediately before any `.close()`. One segment kind, selected by `kind`:
- 'spline' — `.spline(points, opts?)`: interpolates through every `points` waypoint (Vec2[] mm, >= 2 entries; points[0] must match current pen position). Optional `tension`, and `startTangent`/`endTangent` 2D direction vectors that constrain the first-derivative direction at the endpoints (magnitude normalised internally). Use for organic 2D outlines (eyewear brow, ergonomic handle, sneaker midsole).
- 'nurbs' — `.nurbsSegment(controlPoints, opts?)`: explicit B-spline net (Vec2[] mm, >= degree+1 entries; controlPoints[0] must match pen; pen ends at controlPoints[N-1]). Optional `degree` (default 3), rational `weights` (strictly positive), explicit `knots` (length = controlPoints.length + degree + 1).
- 'hermite' — `.hermiteG2(a, b)`: each endpoint `{ point: Vec2, tangent: Vec2, curvature?: Vec2 }` in mm (a.point must match pen; pen ends at b.point). `curvature` defaults to [0,0] (G1); pass matching curvatures for G2 blends. Tangent magnitude is the first derivative (~ chord length), NOT unit length.
Returns the modified code + diagnostics from re-evaluating. Side-effect-free. Each kind fails closed on its own missing required params. | No | No | Yes | No |
add_pattern_featureUse this when you need to repeat a feature in a pattern. Insert a Shape.patternLinear / .patternCircular / .patternGrid / .patternCurve call into a kernelCAD script before the last top-level return. Pass structured args (kind + the matching spec object). Curve patterns use equal arc-length intervals along a 3D polyline; instances keep the seed orientation. Returns the modified code plus diagnostics from re-evaluating. Side-effect-free. The pattern feature is a single editable unit; pattern-instance face refs resolve via `<sourceId>_pattern_<i>` on the pattern feature's lineage. Geometric note: pattern is implemented as cumulative boolean union of transformed source copies — additive features (boxes, ribs, fins, spokes) pattern cleanly; patterning a subtractive feature (hole, cutout) only preserves the per-instance void when adjacent bodies are disjoint. | No | No | Yes | No |
add_surfaceUse this when you need an organic, freeform, or swept shape — a body shell, panel, fairing, ergonomic curve, lens, or sculpted form — authored as a NURBS Surface into the user's .kcad.ts, OR when you need to finish surfaces into a watertight solid or taper faces for moldability. One authoring/finishing path, selected by `kind`:
- 'nurbs' — insert a nurbsSurface(...) / surfaceFromCurves(...) call. Pass either { controls, degree, weights?, knots?, periodic? } for direct construction, OR { section_sketch_ids } for skinning. Weights are honored: supply rational weights to build exact circles/cylinders/spheres/conics (the surface becomes rational); omit weights for a non-rational surface.
- 'patchFamily' — insert a nurbsPatchFamily(...) solid built from degree-5+ shared-knot NURBS caps. Pass { controls, degree, split_direction, extrusion, split_knot? }. This requests G4 only at the two internal NURBS cap seams; evaluation reports the measured class per seam, and does not label a seam G4 unless the D0–D4 instrument passes.
- 'planeBlend' — insert planeBlendSurface(railA, railB, { normalA, normalB, handleLengthMm? }) for two corresponding, equally oriented, straight parallel rails on planar supports. This is a separate G2 blend construction, not an OCCT fillet. Pass rail_a_binding / rail_b_binding (declared Curve3D variables) and unit support normals. Sew the returned patch with both support surfaces; the measured achieved class belongs to those joined seams.
- 'boundary' — insert a surfaceFromBoundary([c1,c2,c3,c4], opts?) call: one NURBS face through 4 boundary Curve3D refs (bottom, right, top, left in loop order; adjacent endpoints must coincide within 1e-6 mm).
- 'trim' — insert a `<surface>.trimTo(<by>)` or `<surface>.split(<by>)` call. Pass `surface_binding` (the Surface variable name), `by_binding` (the cutter Surface variable name; Shape/Curve3D cutters are deferred to a later slice), and `op: 'trim'` (keep the largest imprinted piece) or `op: 'split'` (return both | No | No | Yes | No |
add_textUse this when you need to author text into a kernelCAD script before the last top-level return. One authoring path, selected by `mode`:
- 'sketch' — insert a sketch.text(...) call. The emitted sketch is chainable: pair with subsequent .extrude(...) / cut(...) edits to land an engraved or raised text feature.
- 'emboss' — insert a `<shape>.embossText({...})` chained call onto an existing Shape `target`. Use for engraved brand text on faces (Ray-Ban temple, CE mark, model number). `depth > 0` raises text out of the face; `depth < 0` engraves text into the face. Lowers via replicad drawText → sketchOnFace → extrude → fuse|cut.
Default font is the runtime-bundled Liberation Sans. Side-effect-free; returns the modified code plus diagnostics from re-evaluating. Each mode fails closed on its own missing required params. | No | No | Yes | No |
add_variable_sweepUse this when you need an organic swept solid whose cross-section changes along its length — a tapering body, horn, bottle, handle, ring band, fairing, or duct — authored as a variable-section sweep along a spine. Inserts `variableSweep(spine, sections, opts?)` into the .kcad.ts `code` immediately before the last top-level return (an empty `code` starts a new script that returns the sweep). Spine: EITHER `spine_points` ([[x,y,z], ...] in mm, interpolated with spline3d; `spine_closed: true` closes the loop for a ring) OR `spine_binding` (an existing Curve3D / Sketch / Vec3[] variable). Each section: `t` in [0, 1] plus a profile — inline `radius` (circle) or `width` + `height` (rectangle), or `profile_binding` (an existing Sketch); profiles are centred on the spine and turned to face along it. Sections are strictly increasing in t, first t=0, last t=1 (omit t on every section to space them evenly). On a closed spine t=1 is the seam and reuses the t=0 profile. Example: { code, spine_points: [[0,0,0],[0,10,30],[0,0,60]], sections: [{ t: 0, radius: 8 }, { t: 0.5, radius: 10 }, { t: 1, radius: 4 }] }. Returns the modified code, diagnostics from re-evaluating it, and `sweep` { volumeMm3, bbox } measured from the built solid (ok:false when the sweep built nothing). The lowerer measures NURBS station seams for C1/C2 requests; C2 targets at least G2 and emits a warning with the achieved class if missed. The result is a Shape binding: return it, or chain `.union(...)` etc. via add_feature. Orientation is not exposed by this MCP tool until runtime orientation support is wired. Side-effect-free. | No | No | Yes | No |
add_workspace_targetUse this when you need to declare a reachability target for a connector. Durably insert `<assembly>.workspace(connectorRef, { reachable, toleranceMm? })` before the final top-level return. Workspace targets are checked by solvedModel validation/review pose-envelope gates. Returns modified source plus diagnostics from re-evaluation. | No | No | Yes | No |
apply_surface_blendUse this to author and evaluate a fillet or chamfer on a kernelCAD Shape. It inserts Shape.fillet(radius, selector, { continuity: G1 }), Shape.fillet({ start, end }, selector, { continuity }), or Shape.chamfer(distance, selector), then returns the patched source and evaluation diagnostics. Constant-radius OCCT fillets expose measured G1 only; G2, G3, and G4 are refused because their support seams remained G1 in the tested mode/tolerance sweep. A linear two-station radius_profile uses the NURBS constrained route on one selected edge and reports its measured result; the planar fixture measured G2, while requests above or outside measured support pairs can downgrade with feature.fillet.continuity-not-applicable. Selectors accept EdgeSelector syntax, including canonical edge refs/query strings, EdgeQuery objects, or { face: canonical name, face label, or face query }. This authors a blend operation but does not extract blend-surface NURBS poles. | No | No | Yes | No |
blockout_assemblyUse this when you have a list of parts with bounding boxes and positions (from a layout, spreadsheet, another tool or a sketch) and need an evaluable placeholder assembly script. Pass parts as { name, bboxMm:[x,y,z], positionMm:[x,y,z], rotationDeg?, anchors? } in mm; positionMm locates the bbox lower corner and anchors are named points in assembly coordinates. Optional connections [{ from, to }] reference anchors as "part.anchor" (including built-ins origin, bbox_center, bbox_x_min..bbox_z_max) and become fastened mates that express connectivity intent only; no wire or route geometry is generated. Returns the script (corner-anchored box solids with named connectors) plus warnings. It reads no files and cuts nothing; refine the solids with add_part/add_feature afterwards. | No | No | Yes | No |
capture_animationCapture a saved model animationView timeline or turntable as a downloadable MP4. Use file: "project:<slug>"; inline code, GIF and PNG-sequence output are not supported on this hosted server. Limits: 60 seconds, 60 fps, 1800 frames, 200 MiB. Turntable width/height are even and at most 2048; timeline frames are 1920×1080. Returns downloads[].url with a 24-hour expiry; local_only links can expire earlier on restart. A completed capture with collisions remains ok:true, verified:false. This is rendered CAD, without synchronized electronics playback, audio, or video editing. | No | No | No | Yes |
design_loopUse this when the goal is complex / production / enclosure / gearbox / robot-arm / multi-body, or when you need evaluate→review/verify→revise until green. PREFERRED over one-shot evaluate_script+open_in_studio for Adam-level parts. Runs a CAD design loop over attempt scripts: review_cad each attempt, continue past functional attempts with unresolved warnings, return repair prompts (nextActionPrompt) plus structured revisionAssist (suggestedPatches / autoApplied.suggestedCode for repairable feature failures; cookbook steers for stacked-primitive toys). Stop on ok or convergence.escalate. To pick among N alternative candidates for one goal without a judge, pass them all as attempts with consensus:true (geometric medoid selection). Optionally write a Studio build record JSON. | No | No | Yes | No |
dfm_reviewUse this when you need a manufacturability (DFM) report before printing or machining a part: returns a pass/fail checklist, no dfmSpec(...) needed. Pass { file | code } and optional processes (default ['fdm', 'cnc']). FDM 3D printing checks: fdm.overhangs (unsupported overhang steeper than max_overhang_deg, default 45° from vertical), fdm.bridging (bridges over max_bridge_mm, default 10), fdm.min-wall (walls under 2 × nozzle_mm, default 0.4 mm nozzle), fdm.min-hole (holes under 5 × nozzle), fdm.min-pin (warn), fdm.bed-fit (printer profile bed, default generic-fdm), fdm.bed-contact (warn). CNC 3-axis milling checks: cnc.undercuts (surface unreachable from approach_axes, default ['+z']; list several axes for several setups) and cnc.internal-corner-radius (sharp internal corners and fillets smaller than the end-mill radius, tool_diameter_mm default 6). Returns { ok, verdict: 'pass'|'fail', checks: [{ id, process, part, status: 'pass'|'fail'|'warn', summary, value?, limit? }], fdm?, cnc?, diagnostics }. Settings from the script's dfmSpec({ process: 'fdm' }) are used as defaults; call options win. For the script-declared gates (clearance, voids, channels) use verify({ check: 'dfm' }). | No | Yes | Yes | No |
diff_geometryUse this when you need to know WHAT MATERIAL changed between two versions of a model, not just how much. The deeper sibling of diff_scripts: a volume delta alone is ambiguous (a boss that grew and a pocket that deepened report the same magnitude, and a part that only moved reports zero), so this tool answers it with geometry instead of pixels. Baseline is { baseFile } or { baseCode }; the revised side is either another script ({ file } or { code }) or the SAME script re-lowered with { params } overrides — a bag of declared param() name -> new value, which is the one-script form a parameter sweep actually asks for. Bodies pair by name and fall back to declaration-order positional pairing; anything left over is listed in `unmatched` and raises diff.body.unmatched. Per matched body it returns addedMm3 = volume(revised - base), removedMm3 = volume(base - revised), commonMm3 = volume of the overlap from boolean intersection, exact bbox with min/max/extent deltas, face / edge / hole count deltas (hole counts reuse the cylindrical-hole detector), maxDeviationMm (two-sided discrete Hausdorff distance between the two surfaces), and a `verdict` — identical | moved | resized | topology-changed, precedence topology-changed > resized > moved > identical. Branch on the verdict; cite the numbers. Optional { render: true } also writes an overlay PNG (added green, removed red, unchanged material as a translucent ghost; the scene is a re-runnable .kcad.ts over lossless BREP sidecars) through the render_preview pipeline and fails open (the numeric diff is still returned) when that pipeline is unavailable. Read-only — never touches the active session. | No | Yes | No | Yes |
diff_scriptsUse this when you need to see exactly what changed between two script versions. Structured geometric delta between two versions of a kernelCAD script — a baseline ({ baseFile } or { baseCode }) and a revision ({ file } or { code }). Returns agent-readable JSON: per-part added/removed/renamed/changed (volume mm³ + exact bbox deltas, numbers matching inspect({ of: 'part-stats' })), total interference-volume delta with per-pair detail, mate-graph changes (added/removed/changed mates incl. type, connectors, pose, limits), and param changes (value/min/max). Single-shape scripts diff as one "(root)" pseudo-part; a `return [a, b]` multi-body script diffs per body as "body[0]", "body[1]". An error that still leaves geometry (e.g. a skipped fillet) is listed under base/revised.errors beside the diff. Use after editing a script to verify exactly what changed physically before re-rendering. On a hosted server pass both versions inline: { baseCode: 'return box(10, 10, 10);', code: 'return box(10, 10, 12);' } (base_code/old_code/before and revised_code/new_code/after are accepted as aliases). Read-only — never touches the active session. | No | Yes | Yes | No |
drawing_to_cadUse this when the reference for a part is a 2D engineering drawing PDF (orthographic views with dimensions), not a photo. Deterministic, no vision model: reads the vector linework (stroke width, dash) and positioned text; classifies visible / hidden / center / dimension / extension lines; reads the title block scale, units and projection symbol; identifies front / top / side views by projection alignment (third- or first-angle); ties dimension text to its lines (⌀, R, 4×, ±, THRU, depth). Dimension values win over measured lengths. Rebuilds the part as the view silhouette extruded by the depth an orthogonal view shows, or a turned part revolved from its half-silhouette, plus holes from ⌀ circles with THRU or hidden-line depth. Returns `script` — a `.kcad.ts` with role-named params (width, thickness, holeDia, hole1X, dia1, step1Length …) — and `ledger`, an assumption ledger where stated dimensions are `visible`, symmetry-derived positions `inferred`, defaults `assumed` and an unstated depth `missing`; a dimension that disagrees with the linework keeps its value and records the disagreement as an open fact. With verify (default) the script is evaluated, re-projected through the svg-drawing view stage and compared: `fidelity.verdict` is match | partial | mismatch | failed with per-axis extents, hole diameters and per-view silhouette IoU. Pass `out` to write the script and its `<stem>.ledger.json` (resolve open facts with resolve_assumptions, then set_param). A scanned (raster-only) page fails with reference.drawing.raster-only — use trace_from_image for those. Hosted: give the file as an https:// URL, a data: URI (base64, max 25 MB) or "asset:<id>" from request_upload (when the file is on the user's device). | No | No | No | Yes |
erc_runRun an electrical rule check (ERC) on a schematic and return structured diagnostics — the KiCad ERC step, over MCP.
CHECKS: duplicate reference designators; net endpoints naming an unknown component or pin; unconnected pins (ignoring hidden power pins and explicit no-connects); single-pin nets; driver conflicts (two outputs on one net); power_in pins with no power_out source; input pins with no driver; no-connect markers on connected or non-existent pins; incomplete differential pairs; empty nets.
INPUT: `schematic` (same shape as netlist_export), `ignore` (optional array of rule codes to suppress, e.g. ["erc.net-single-pin"]), `treatUnspecifiedAsPassive` (optional; when true an "unspecified" pin counts as passive for the input-not-driven check).
OUTPUT: { ok, counts: { error, warn, info }, diagnostics: [{ code, severity, message, hint?, locus: { component?, pin?, net? }, nextAction? }], checked: { components, nets, pins } }. `ok` is true when there are zero errors. Diagnostics use the same shape as kernelCAD geometry diagnostics, sorted error → warn → info, deterministically. | No | Yes | Yes | No |
estimate_assembly_manufacturingPrepare an indicative estimate and durable manufacturing checklist for a whole CAD assembly, including mixed materials and processes. The server reads material and sheet thickness from CAD, multiplies BOM quantities by batchQuantity, selects supported processes, checks live supplier offers, and reports any missing prices or blockers. This creates only a draft estimate. It does not send an order, charge the customer, or start checkout. Sign in to estimate private saved projects; source code and public projects can be estimated as a guest. | No | No | Not declared | Yes |
evaluate_scriptRun a script and check the built model against its declared requirements. A full result has buildOk for geometry availability and ok for overall acceptance: a failed or not-evaluated requirement makes ok:false while retaining built geometry for inspection. Full local builds return viewerUrl: a live Studio link reused and updated on later full builds in the same MCP process. Hosted builds return viewerMode: hosted and viewerHint pointing to open_in_studio; they do not start a loopback viewer. Full evaluations return step evidence: build validity, volume and before/after local PNG paths in one shared iso frame. Snapshots require PW_CDP_URL for an existing browser; unavailable captures report an explicit error. Run a kernelCAD .kcad.ts script and report pass/fail + feature count + diagnostics + sceneSummary (BREP validity, volume in mm³, face count, bounding size in mm). When the scene is assembly-built (assembly().part(...) → .model()/.solvedModel()), also returns a parts summary { count, names } AND runs the mechanism-truth gate by default: the `mechanism` field reports real/broken/unverified and a broken mechanism (disconnected components / mechanism.orphan-part, self-collision, fastened drift, dof-mismatch) makes ok:false with the failures in diagnostics, as does a mate connector more than 6 mm outside its part bounding box (assembly.mechanical.connector-not-in-solid, the same error review_cad reports) — a mechanism (any mate or joint) needs every part linked by connectors + mates/joints (axis+revolute for shafts/hinges/gears; frame+fastened for rigid; or arm.revolute/.prismatic/.ball/.fixed). A plain multi-part assembly with no mates (base + lid, print layout) is independent bodies and passes. Pass { skipMechanismCheck: true } to opt out (e.g. a deliberately free part next to a mechanism). An animation or drive on a fastened joint (mechanism.motion-on-fixed-joint) is broken: animate a revolute/prismatic mate pose. For a model with moving joints or motion intent, ` | No | No | No | Yes |
evaluate_sdfUse this when you need to sample a signed-distance field at a point. Sample the signed distance from an in-script sdf.* field at a 3D point. Returns { distance, inside, aabb, kind }. Distance is in mm; negative = inside the surface, 0 = exactly on the surface, positive = outside. Use this to verify SDF composition before calling sdf.materialize (which is the expensive step). The script must bind the SdfField via sdf.bind('<name>', field) and pass that name as fieldName. Hint: pass either { file } or { code }, plus { fieldName, point: [x,y,z] }. | No | Yes | Yes | No |
execute_cookbookUse this when you need evaluate_script (and optionally open_in_studio) for an industry / cookbook demo in ONE step — after lookup_cookbook for industry demos, prefer execute_cookbook when you need evaluate+Studio together; empty lookup is not a stop (freehand-author instead). Resolves a cookbook snippet by `id` or BM25 `query` (same ranking as lookup_cookbook), evaluates its body via evaluate_script with bounded vendor timeouts, and returns explicit status with stage resolve|evaluate|open_in_studio. Pass openInStudio:true to publish the same script via open_in_studio after a green full evaluate (hosted MCP). dryRun:true is the fast capture-only path — it is NOT evidence the cookbook builds a solid or is safe to publish; finish with dryRun:false (default) before claiming success or opening Studio. | No | No | No | Yes |
explode_viewUse this when you need an ordered exploded-view plan for an assembly. Supply parts as {name,center:[x,y,z],size:[x,y,z]} in mm. Optional assembly_order sets the sequence; missing order falls back to input part order, and unlisted/unknown order refs are reported. Choose mode axis (default) or radial; axis follows the requested direction, radial moves parts away from the assembly centroid. The result includes ready-to-paste param_declarations, animation_tracks and reverse_animation_tracks for animationView(), part_transforms for existing shapes, and script_fragment. cameraPlan gives framing guidance. | No | Yes | Yes | No |
exportUse this when you need to export geometry to a file. One exporter, selected by `target`:
- target:'model' — export the script geometry to one file. Pass { file | code }, a required { output_path }, and { format }. Supported formats: stl (binary STL mesh), step (BREP CAD interchange), dxf (2D cut file for laser / waterjet / CNC: a flat part — plate, panel, extruded profile, in any orientation — exports its outline and holes in its own plane with exact arcs and circles; a sheet-metal part or a returned Region exports its flat pattern; a flat or sheet-metal part also returns sheet { thickness_mm, bend_count }, which a shop needs and the DXF does not carry; options.section { axis: "x"|"y"|"z", at } exports the cross-section of any part in world coordinates (plans, profiles); a multi-part model (cut list) writes all parts side by side on output_path, one layer per part, plus parts/<part>.dxf per part (reported in part_files; options.layout 'sheet' writes the combined sheet only); any other part fails with export.dxf.non-planar), 3mf (slicer-friendly mesh: one named object per part, colours as core-spec basematerials named by the part's engineering material; options.arrange 'plate' packs parts on the bed at Z=0 without overlap (options.orient puts each part's largest flat face down), 'assembled' keeps them together as one multi-part object for multi-colour prints; options.slicer 'bambu' | 'orca' | 'prusa' adds that slicer's per-object name + filament-slot sidecar — slot N is the Nth distinct colour/material), options.infill { fromFea: '<study>' | true, bands?, pattern? } = stress-graded FDM infill (requires the local CalculiX + gmsh toolchain; without it the export fails with fea.solver.unavailable): solves the feaStudy and writes modifier volumes, each with its own infill density (Orca/Bambu format by default; options.slicer 'prusa' writes PrusaSlicer's format instead, since the two are not interchangeable); the result carries infill { bands, saving, images }), gcode (in | No | No | No | Yes |
fab_packUse this when the user wants to get a part made: packages the fabrication files into one directory plus a zip, and returns links to public instant-quote pages. Pass { file | code } and output_dir; optional scope ('part', default — one script's files; 'bom' — the whole assembly's BOM: per-part single-body files, per-part drawings, bom.csv/json and vendor handoff texts; 'workshop' — part pack plus cut-list CSV/JSON, DXF flats.zip, and dfm_review JSON sidecar), name (default 'part'), formats (default step, stl, 3mf, pdf-drawing, bom-csv; add 'dxf' for flat/sheet; workshop also cut-list-csv/json, dfm-json, flats-zip), tolerance (requested absolute mm for mesh exports; this runtime currently refuses it before writing), and processes ('3d-print' | 'cnc' | 'sheet-cut') to filter links (bom: also narrows which fabricated rows are packed). Each file is written by the export tool, so its gates apply; a format that fails is reported in files[] and the rest still ship. Also writes manifest.json and README.txt. quote_links lists JLC3DP, JLCCNC, PCBWay, Xometry, SendCutSend and Craftcloud with the pack file to upload to each. One body per file: multi-body files are rejected by every shop. DXF is written only for flat or sheet-metal parts. The McMaster handoff text carries part numbers only, because McMaster quantities are packs and pack sizes are not in the catalog yet. These are plain web pages: nothing is uploaded or ordered. The user opens the link and uploads the file. Run dfm_review first if you have not.
Hosted server: pack files are written on the kernelCAD server and returned in downloads[].url; nothing is uploaded to a fabrication service. | No | No | No | Yes |
fea_summaryUse this when you need a structural check's context without paying for a solve. Read-only: returns the stored summary of a previous run_fea (pass the same `output_dir`), whether the CalculiX + gmsh toolchain is available on this machine (with the install command when it is not; run_fea then uses its in-process voxel solver — toolchain.default_solver says which), and the FEA material table with real E / Poisson / yield numbers so a grade is chosen against data rather than from memory. Never meshes, solves, or writes. | No | Yes | Yes | No |
fetch_partFetch one bundled catalog part. Prefer `await lib.standard.nema17()` and `await lib.standard.bearing608()` — they are offline and do not download remote STEP. A lookup that cannot finish fails within 45s with errorCode parts.lookup.timeout. Do not retry in parallel. | No | Yes | Yes | Yes |
find_partSearch the bundled parts catalog (offline). For a NEMA-17 motor write `await lib.standard.nema17()`; for a 608 bearing write `await lib.standard.bearing608()`. Do not fan out parallel lookups and do not pass partsBaseUrl unless you set source:"remote". Remote lookups fail within 45s with errorCode parts.lookup.timeout instead of hanging. | No | Yes | Yes | Yes |
fit_planeUse this when you need to fit an orthogonal least-squares plane to XYZ point-cloud data. Returns centroid, deterministic unit normal, signed point residuals, RMS residual and maximum absolute residual. Accepts points already parsed by the caller from scan data or mesh vertices. Computes parameters only; it does not create a surface body. Requires at least three non-collinear finite points. | No | Yes | Yes | No |
flatten_patternUse this when you need the unfolded flat pattern of a bent sheet-metal part. Return the unfolded 2D flat-pattern of a bent sheet-metal Shape as a Region (outer polyline + holes + bend lines + sketch plane). Any number of parallel bends; crossing bends need corner relief. Pass { file } or { code }; optional { featureId } to pick a specific Shape. | No | Yes | Yes | No |
get_assetFetch one public catalogue asset by slug. Read-only. No sign-in and no API key.
A built-in kit/id returns the free editable downloads.source (.kcad.ts), studio_url, thumbnail_url, license, and published params and presets. params lists each declared control with its name, type, default, label, units, numeric range or choices. Dependent choicesBy maps constrain valid combinations. Download the source with plain GET and use its declared parameter names when editing.
Visual scene kits include usage.evaluate_script and usage.render_preview options to build or preview geometry without mechanism checks. This does not verify mechanical behavior. Manufacturing assets retain the default checks.
For community slugs, returns the search fields plus params (the knob schema), presets, rig, and public download paths.
Parameter values use each control's declared unit. Geometry stats.size_m and stats.origin_y are metres, Y up.
RIG: each rig entry is a named pivot. type "rotate" has range in degrees; type "slide" has range in metres; axis is the pivot's local x, y or z.
license is the SPDX id to keep with the asset. The download paths are public catalogue routes. Call get_asset_pack for a short-lived signed zip URL. Do not send an API key. | No | Yes | Not declared | Yes |
get_asset_packReturn a short-lived signed URL for a catalogue asset zip (mesh, params, licence). Read-only. No sign-in.
The URL is already signed. Fetch it with GET. Do not send an API key or an Authorization header. It expires quickly; read expires_at. Share download_url with the user.
Units in the pack follow the catalogue: metres, Y is up. A rig, when present, names pivots of type rotate (degrees) or slide (metres).
If the publisher stored no pack, the result is { ok: false, error: "not_stored" }. | No | Yes | Not declared | Yes |
get_latest_renderRender a project's current model server-side and return it as an inline image so you can SEE what you built. Prefer open_in_studio for the happy path — it already includes an iso PNG preview in the same publish result when previewDelivered is true. Use this tool for a different `view`, a contact sheet (`view:"all"`), or when you only have a slug and are not publishing. Call with that `slug` to inspect whether the build looks right. CRITICAL — the image is rendered from the MODEL on the server; it does NOT reflect the user's Studio camera, zoom, or screen. NEVER ask the user to rotate, zoom, pan, move the camera, close a slider, or change their view to help you see — you cannot affect their screen and it cannot affect this render. To see a different angle, call this tool again with a different `view`. By DEFAULT (omit `view`, or `view:"all"`) it returns a CONTACT SHEET of all six canonical views in one labeled image — a 3×2 grid, top row [iso, front, right], bottom row [back, left, top] — so you can judge the model from every side regardless of its orientation (e.g. to find which side has the doors). Pass a single `view` (iso/front/back/left/right/top) for one large render of that angle. DETERMINISTIC: the same model + view always returns the same bytes — identical bytes are NOT a stale/lagging snapshot. If you changed the model, push it with open_in_studio FIRST, then re-render to see the change. The image is always current and never a blank capture. Colors and shading match Studio (same palette / base-material color). The slug is the capability: no OAuth for public/unlisted; private projects require the owner signed in. The PNG is base64-inlined as a real image block by default; pass `paths_only: true` for metadata only. No renderable geometry or a mesh failure → { ok: false, error, hint }, never a blank image. error "mesh_timeout" means the model took too long to build for a preview; the source is not wrong (it still exports) — do not rewrite it to fix the render. | No | Yes | Not declared | No |
get_model_meshReturn the raw per-feature triangle mesh (positions/indices/normals) of a project by slug. Pass version for an exact immutable revision; omission reads the current model. The result echoes slug and version. For the in-chat 3D viewer widget to render geometry; delivered over the MCP Apps bridge. The slug is the capability: public/unlisted need no OAuth; private requires the owner signed in. This tool returns geometry without publishing a mesh, preview or animation artifact. | No | Yes | Not declared | Yes |
get_projectUse this when you need to reopen a saved project or browse what the user has saved — it fetches a kernelCAD Studio project, or lists the signed-in user's saved projects. Pass `slug` (from a /p/<slug> link or a prior listing) to fetch that project's full .kcad source and metadata — then edit and open_in_studio with the same slug so the user's open tab updates live. Private projects require their owner's OAuth connection. OMIT `slug` to list the signed-in user's saved projects (most recently updated first); that listing mode requires the OAuth connection and does NOT paint — prefer list_my_projects to find a project to continue. Read-only: this tool never shows a viewer (only open_in_studio does, once per response). Paint phases: projectSaved/meshReady reflect fetch state; viewerPainted stays false. Use open_in_studio (with code) to publish+paint — do NOT call get_model_mesh or get_latest_render for interactive paint. | No | Yes | Not declared | Yes |
get_project_revisionFetch the exact immutable .kcad source and parameters captured at a prior `open_in_studio` version. Use this to read-after-write verify a release: pass the returned `slug` and `version`, then hash or inspect the returned source. Public/unlisted projects use the slug as capability; private projects require the owner's OAuth connection. | No | Yes | Not declared | Yes |
get_selectionUse this when you need to read the human/agent selection in a local Studio session. Returns one clicked face or edge (or null), with current-generation mesh-local shapeIndex/kind/id and creating featureId. During a rebuild selection is null with “selection pending rebuild” until Studio uniquely verifies the face; ambiguous or deleted faces are cleared. Inspect the current shape before authoring a fillet. Requires a running local Studio opened on the same script; hosted sessions are not supported. | No | Yes | Yes | Yes |
hardware_packPlan one device across KernelCAD and LabWired. Read-only: returns companion tool names, project/revision links, the electronics-to-mechanics handoff, and a device review link for API clients. The viewer uses Order as its only purchase action. Use for robots, enclosures, PCB mounts or any hardware with electronics and mechanical parts. Optional slug resolves an accessible saved KernelCAD project; pass version to pin an immutable CAD revision, otherwise its current revision is used. Optional labwired_project/labwired_revision preserves its electronics reference. No purchase, payment, account linking, source upload or companion authorization is performed. | No | Yes | Not declared | Yes |
import_stepUse this when the user wants to start from their own STEP, IGES, native OCCT BREP, STL, OBJ, PLY, 3MF, glTF or GLB file (a part they designed elsewhere, a vendor model). Give exactly one source: url (a public https direct-download link), upload (a file the user attached in ChatGPT), or content_base64 (raw bytes, small files only). Max 50 MB. The format is detected from the bytes or file name (or pass format: 'step' | 'iges' | 'brep' | 'stl' | 'obj' | 'ply' | '3mf' | 'gltf' | 'glb'). STEP, IGES and BREP produce exact B-rep solids; IGES uses OCCT's reader and the shared topology repair pass, while BREP is OCCT's native serialization. A CAD file that does not produce a valid solid fails; it is never replaced by a mesh. STL is imported as faceted geometry. OBJ, PLY, 3MF, glTF and GLB stay source meshes. Writes the file and a starter <name>.kcad.ts into output_dir (default: a fresh temp dir), evaluates it, and returns { ok, format, model_path, script_path, code, bbox, import_report }. The report gives representation, exact_solid, mesh_fallback, repair_required, solid_count, face_count, and triangle_count. Native CAD importers fail if they do not produce an exact solid; they never substitute a mesh. Every mesh format is reported as source-mesh, not as a CAD fallback. Pass script_path as { file } to evaluate_script, add_feature, dfm_review, export and the other tools, or edit code to build on the body. Source meshes are display-only triangle geometry. Use STEP, IGES or BREP when exact CAD topology is required. A non-watertight STL is refused unless allow_open is true. | No | No | Yes | Yes |
inspectUse this when you need to read facts about a model. One reader, selected by `of`:
- 'assembly' — physical assembly inventory (parts, bboxes, connectors, mates, disconnected solids).
- 'robot' — URDF/SDFormat export preview (links, joints, planning groups, end-effectors, issues).
- 'step' — inspect an imported STEP file: solid tree, exact bbox/volume, analytic planar/cylindrical faces, hole axes, and conservative hole/pocket/boss/slot/round candidates with per-feature status/confidence.
- 'brep' — the same recognition report for a native OCCT BREP file, including BRepCheck validity per solid.
- 'shape' — volume / surfaceArea / bbox for one feature ({ feature_id? }).
- 'mass' — mass, centre of mass, centroidal inertia tensor (inertia6 + 3x3 inertiaMatrix), principalMoments/principalAxes, symmetry flags, and optionally the radius of gyration about an arbitrary axis ({ feature_id?, density?, gyration_axis? }); density in kg/m^3, defaults to 1000 (water).
- 'features' — features captured by the script (kind, id, params, transforms, suppression).
- 'assemblies' — assembly intent (assemblies, parts, connectors, joints).
- 'topology' — canonical face names + edge count for a feature ({ feature_id? }).
- 'edges' — edges of a shape with optional EdgeQuery ({ feature_id?, query? }); returns @kc[...] refs.
- 'face-edges' — boundary edges of a named canonical face ({ feature_id?, face_name }).
- 'faces' — faces of a shape with optional FaceQuery ({ feature_id?, query? }); returns @kc[...] refs.
- 'face-labels' — user-applied labels visible in the script.
- 'mates' — declared mates and limits. code/file captures the supplied source atomically. Optional query:{poses} adds solution from the mate solver and makes ok reflect convergence. evaluationEvidence binds exact source bytes and query inputs.
- 'constraints' — sketch constraints captured by the script.
- 'part-stats' — bundled parts-catalog statistics.
- 'bend-table' — sheet-metal bend table for a flattened pattern.
- 'params' | No | Yes | Yes | Yes |
inspect_nurbsEvaluate supplied kernelCAD code or a file to capture an authored NURBS curve (nurbsCurve/spline3d). Returns degree, distinct knots and multiplicities, poles, weights, rational and uniformWeights flags, hasNonUnitWeights, and parameter range. Defaults to the last captured curve in that script; pass feature_id to choose one. The source may load referenced assets. Reports authored curve data, not exact geometry-derived B-rep edge/face NURBS; surface extraction and blending are not supported. Does not update the active MCP session or write a project. | No | Yes | Yes | Yes |
lookup_apiLook up the kernelCAD script API by query (symbol or keywords) and/or section. Results contain exact runtime signatures and are bounded and paginated. Omit query and section for a compact first page and section index. Continue with next_offset as offset and the same query/section. Use query to request full descriptions of matching entries. intent is telemetry, not a search query. | No | Yes | Yes | No |
lookup_authoring_skillReturn the kernelcad-authoring skill — conventions for writing .kcad.ts scripts (API surface, parameters, evaluation contract, common pitfalls) — in sections.
Call with NO arguments first: you get the quick-start (units, axes, the return rule, the rules that prevent most failures, the intent → API routing table, the "Before you finish" checklist) and an index of every section with a one-line summary (under 16k chars). Then pull what you need: `{ section: "<id>" }` returns one section (e.g. "top-level-functions", "materials", "dfm-gates-print-readiness"); `{ query: "fillet after subtract" }` returns the best-matching sections. `{ section: "all" }` returns the full ~140k-char skill (SKILL.md plus its reference files) — only if your client accepts large responses.
Clients that list resources can also read `kernelcad://skills/authoring` (the SKILL.md core).
OUTPUT: { uri, mimeType, mode, text, sections? } — `mode` is index | section | search | all | not-found. | No | Yes | Not declared | No |
lookup_cookbookUse this when you need a canonical pattern snippet for a CAD task. Search the kernelCAD cookbook for canonical pattern snippets. Returns top-k snippets matching the natural-language query, ranked by BM25 over title/tags/keywords/trigger. Use when you need a canonical pattern for fillet-after-subtract, non-overlapping booleans, sketch-to-extrude flows, etc. Returns empty if no snippet scores above the relevance floor — proceed without cookbook help in that case. | No | Yes | Yes | No |
lookup_diagnosticsUse this when you need the kernelCAD 26-code diagnostic catalogue with hint templates. Tiny one-shot call; useful for an agent that wants to pre-populate retry strategies. Hints are also inline on every emitted diagnostic — this tool just gives you the canonical list up front. | No | Yes | Yes | No |
mesh_booleanUse this when the user wants to union, subtract, or intersect two imported triangle mesh solids (STL, OBJ, or 3MF). Supports union, subtract (A minus B) and intersect. Pass each operand as { file } on the MCP server or { data } with base64 mesh bytes; formats are detected or may be specified. Returns volume in mm³, triangle count and a binary STL as data_base64; pass that payload to import_step to continue modeling. Inputs must be closed, consistently oriented 2-manifold meshes. Open, non-manifold, or invalid meshes return an error. This computes mesh geometry and does not create an editable B-rep feature tree. | No | No | Yes | No |
mesh_summaryMesh a kernelCAD .kcad.ts source server-side and return a COMPACT geometry summary — overall bounds plus, per feature, its id, kind, triangle count, and bounding box.
Use this to INSPECT a model's geometry without a viewer: confirm a part is the size/shape you expect, see how many triangles each feature contributes, or check that every feature produced geometry. This runs the full server-side OCCT pipeline (the same one the Studio renderer uses), so it evaluates modern sources (assembly, path, .material, …) that the legacy client worker cannot.
INPUT: `source` (required) the .kcad.ts script text; `fileName` (optional) a label for diagnostics; `params` (optional) a map of parameter-name → number overrides applied before meshing (stateless slider recompute).
OUTPUT: { ok, bounds, featureCount, features: [{ id, kind, triangleCount, bbox: { min:[x,y,z], max:[x,y,z] } }], failedFeatureIds, diagnostics }. `ok` is true when every feature meshed; `failedFeatureIds` lists features that failed to compile (and `ok` is then false). Raw vertex/index/normal arrays are NEVER returned — this is a summary only. To SEE the rendered model, call open_in_studio (includes PNG preview + viewer); use get_latest_render only for alternate views. | No | Yes | Not declared | No |
mesh_to_featuresUse this when you are handed an STL, OBJ or 3MF of a mostly prismatic mechanical part (plate, bracket, spacer, flange, housing block) and need an EDITABLE kernelCAD model of it rather than a faceted lib.fromSTL import. Deterministic, measured, self-verifying: it welds and checks the mesh, segments planes and cylinders, picks the extrusion axis, slices each band and fits exact lines / arcs / circles, snaps near-round values (each snap recorded), then emits a readable .kcad.ts with named param()s — a revolve for concentric round stacks, extruded profiles otherwise, .hole()/.holes() for through, blind and counterbored bores (axial and side-drilled), .cutout() for pockets, .fillet() for constant-radius edge blends (radius measured on the sharp edge, edges grouped by radius and picked with the shortest exact edge query), boolean subtractions for what no drilling feature can reach. It then EVALUATES that script and compares it with the mesh: volume IoU (column ray casting) and symmetric surface deviation (max + RMS), over up to 4 refinement passes. Returns { script, ledger, fidelity: { maxDeviationMm, rmsMm, volumeIoU, verdict: faithful | approximate | failed, thresholds }, unmatchedRegions, features, passes }. A fillet or sharp reading is kept by which measures better; variable-radius blends and chamfers are reported, not forced. The verdict is computed from the numbers — faithful needs IoU >= minIoU AND max deviation <= maxDeviationMm AND a watertight mesh AND no unmatched region. Freeform surfaces, tilted planes and side bosses are listed in unmatchedRegions (reference.mesh.freeform-region-unmatched), never silently dropped. The ledger uses fact ids equal to param names, so resolve_assumptions on the written <out>.ledger.json yields paramOverrides for set_param. Pass { out } to write the script and ledger; the mesh itself is never modified. Hosted: give the file as an https:// URL, a data: URI (base64, max 25 MB) or "asset:<id>" from request_upload (when the file is on | No | Yes | No | Yes |
netlist_exportBuild the electrical netlist from a schematic — the flat connectivity of every component pin and net, the way KiCad's netlist export works.
Use this to turn a schematic description into machine-readable connectivity: which pins share a net, what each component connects to, and which pins are left unconnected. Feed the result to erc_run for rule checking, or to a BOM/PCB step.
INPUT: `schematic` — { title?, components: [{ reference, value?, footprint?, libpart?, unit?, dnp?, pins: [{ pin, pinFunction?, pinType?, hiddenPower? }] }], nets: [{ name, netClass?, diffPairPartner?, endpoints: [{ component, pin }] }], noConnects?: [{ component, pin, reason? }] }. Field names follow KiCad's netlist vocabulary (reference, value, footprint, libpart, unit, pin, pinType) so a KiCad .net file maps onto it directly.
OUTPUT: { title?, nets: [{ name, netClass?, endpoints, components, diffPairPartner? }], components: [{ reference, value?, footprint?, libpart?, unit?, dnp?, pinCount, pinNets }], pins: [{ component, pin, net|null, pinFunction?, pinType }], stats: { components, nets, pins, unconnectedPins } }. `pinNets` maps each pin to its net name, or null when unconnected. Deterministic: the same schematic always yields the same order. | No | Yes | Yes | No |
netlist_queryAsk a net-level question about a schematic: what connects to what.
MODES (`query`):
• "net" — the full membership of one net (`net` required).
• "pin" — which net a component pin is on (`component` + `pin` required).
• "component" — every net a component touches (`component` required).
• "shares" — do two pins share a net (`component`+`pin` and `otherComponent`+`otherPin`).
• "unconnected" — every pin with no net.
• "summary" — counts only.
INPUT: `schematic` (same shape as netlist_export) plus the mode selector and its arguments.
OUTPUT: { query, found, ... } — for "net", the net with its endpoints; for "pin", the net name or null; for "component", the list of nets and the pin→net map; for "shares", a boolean; for "unconnected", the list of pins; for "summary", the stats. | No | Yes | Yes | No |
open_in_studioSave the model as a kernelCAD project AND show it: persists a project revision, returns the interactive Studio viewer (MCP Apps / ChatGPT outputTemplate), and includes a PNG preview in the SAME tool result (image content + previewUrl when available). For a new private model pass new_project:true, privacy:"private" over an authenticated connection. Private models return an owner-only Studio link without public preview, mesh or animation artifacts. For an update, pass expected_version from your read to refuse overwriting a newer revision. Decide electronics actions from the user request at render time: pass show_electronics:true only when electronics are relevant. Default false for mechanical-only models such as mugs. This is an agent decision, not geometry or linked-PCB detection. Use hardware_pack for optional LabWired context. ONE VIEWER PER PROJECT PER RESPONSE: every call renders a new viewer card. Do all validation with evaluate_script first, then call open_in_studio exactly once, after validation succeeds; reuse the returned URL, revision and preview, and never call it again after a successful result in the same response. Re-calling with unchanged code for the same project returns that revision instead of writing a new one. A heavy model can answer status:"running" (code tool.still-running) before the client times out; that is NOT a success: call open_in_studio again with exactly the same arguments, which joins the running save and returns its result. CONTINUE, DO NOT DUPLICATE: to change a model you already saved, pass `project: '<slug>'` from the last result (or from list_my_projects) — this adds a revision to that project. Without `project`, the save goes to the project this chat already saved, or to your project with the same title (case, punctuation and v2/rev3/(1) ignored) from the last 24 h. Views, poses, colours and options of one design are revisions of ONE project — keep the same title and slug. Pass `new_project: true` only when the user wants a sepa | No | No | Not declared | Yes |
order_partOrder the part made: creates the production request and returns a pay_url for the user. Propose the manufacturing method from the user's words and the part, pass it as method with a one-line reason. The price is the real maker price; never invent or send one. Tell the user the card is only held, and a person confirms the final price before charging. If the result is status "pricing", the price is still being worked out: call again in a few seconds. | No | No | Not declared | Yes |
price_partStart or read the real price for making the part. Cheap. Returns status "ready" with estimate_cents and summary, or "pricing" while the makers are asked (call again in a few seconds). Creates nothing and charges nothing. | No | Yes | Not declared | Yes |
project_curveUse this when you need to wrap a 2D closed curve onto a 3D face. Insert a `<shape>.projectCurve({ source, face, scaleMode? })` chained call into a kernelCAD script. The `source` is the structured `{ kind: "sketchCommands", commands: [...] }` wire format the runtime API accepts. Wraps the curve onto the face along the face normal; pair with `.extrude(d)` / `.cut(...)` for raised or engraved logos on curved bodies. Open-wire projection (`asEdge: true`) is not implemented and is rejected at edit time. Side-effect-free; returns modified code plus diagnostics. | No | No | Yes | No |
queryUse this when you need to resolve or inspect topology against a script's lowered geometry. Pass the script as `code` (inline; works on a hosted server) or `file`. Selected by `mode` (default 'evaluate'):
- 'evaluate' — list the faces a Query matches ({ query }). Pass expect:'unique' to assert exactly-one.
- 'resolve' — resolve one ref to one face ({ ref }).
- 'lineage' — the creating/modifying history of a face ({ ref }; feature_id defaults to the last feature).
Query forms (faces only; edge/vertex kinds return query.unsupported-entity-type):
- a bare face label: 'top', 'bottom', 'left', 'right', 'front', 'back', or a hole/cutout slot like 'wall'.
- @kc[<feature-id>/face/<label>] — feature ids are the ones refs print, e.g. '@kc[box_1/face/top]', '@kc[hole_1/face/wall]'.
- @kcq[face(<filter>, ...)] — filters AND together: createdBy("box_1"), withLabel("top"), geometryType(PLANE|CYLINDER|CONE|SPHERE|TORUS|BSPLINE_SURFACE), closestTo([x,y,z]) or closestTo([x,y,z], k), containsPoint([x,y,z]); combine with union(a, b), intersection(a, b), subtraction(a, b). Example: '@kcq[face(geometryType(CYLINDER), closestTo([0,0,10]))]'.
Each matched face comes back with its canonical @kc ref, centroid, normal and area. | No | Yes | Yes | No |
ray_pickUse this when you need the faces a ray hits in a local Studio model, nearest first, with points, distances, and normals. Inputs are model units (mm); direction is normalized. Requires the local Studio URL and session token for the same script, reads the current model generation, and returns a set_selection argument object with every hit. feature_id must identify a displayed terminal shape; intermediates have no current viewer shapeIndex. Intersections use the viewer per-face tessellation, so curved-surface points and normals are mesh approximations. | No | Yes | Yes | No |
remove_featureUse this when you need to remove a feature line from a script. Remove a single line from a kernelCAD script identified by a substring match. Returns the modified code plus diagnostics from re-evaluating. Refuses to remove the line containing the return statement. Side-effect-free. | Yes | No | No | No |
render_previewUse this when you need to LOOK at a kernelCAD model — render its script to deterministic PNG views for visual self-check (the visual half of the evaluate → render → inspect → fix loop), with NO studio or dev server required. Pass { code } (inline source) or { file } (a .kcad.ts path), exactly one. Renders the canonical engineering views (front, right, top, iso — pass { views } for a subset, e.g. ["iso"] for fastest iteration) plus an optional { pose: "<az>,<el>" } arbitrary camera angle (degrees; az=0,el=0 is front, +az rotates CCW around +Z, +el lifts the camera). NO STUDIO / DEV-SERVER REQUIRED: a prebuilt static player (dist/headless-player) is served from an ephemeral local port automatically; a running studio dev server is used as fallback, and { base_url } forces one. The only environment dependency is playwright chromium (npx playwright install chromium). Pass { focus } or { hide } (arrays of feature ids or assembly part names, mutually exclusive) to isolate parts — same semantics as `kernelcad render --focus/--hide`. Pass { section: { axis, position, flip? } } to cut a cross-section and inspect INTERIOR geometry (wall thickness, internal pockets, whether a bore runs through) rather than only the outer shell. Pass { explode: { factor, mode? } } to pull a multi-part assembly apart (mode: "mate-axis" default, or "radial") using the same mesher as `kernelcad render --explode` — requires assembly.model()/solvedModel(). PNGs are written to { out_dir } (default: a fresh temp session directory) and returned as absolute paths with per-view camera descriptions (kernelCAD is Z-up). Mechanism truth runs first, same protocol as `kernelcad render`: a broken mechanism still renders but every tile is watermarked MECHANISM BROKEN (KERNELCAD_RENDER_STRICT=1 refuses instead); read { mechanism, mechanism_failure_codes }. The probe runs full BREP interference sweeps and can dominate latency on large assemblies — pass { no_mechanism_check: true } for fast iteration (the preview t | No | No | No | Yes |
repair_scriptUse this when evaluate_script reported an error and you want the fix applied rather than described. Takes the candidates why_did_this_fail derives for a diagnostic, applies them one at a time, re-evaluates after each, and keeps the first that clears the diagnostic without introducing new errors. Never edits outside the repair region (failing feature statement + its input statements + the param() lines it reads) — an out-of-region patch is refused with tool.repair.out-of-region. Returns the repaired source in `new_code` (the caller persists it), a unified `diff`, and before/after health maps. Pass { file? | code?, diagnostic?: '<id>'|'first-error', strategy?: 'apply-first'|'try-all'|'dry-run', max_attempts?: number }. | No | No | Yes | No |
report_needUse this when the user needed something kernelCAD does not have, so the gap is recorded instead of papered over. kind: asset (search_assets returned coverage none or poor: the catalog does not model it), capability (a tool cannot do what was needed), output (a tool answered, but not with what was needed), docs (a tool description did not say how to use it). One short sentence in `need`; name the tool in `tool` when one fell short. Stores no personal data beyond your account id when signed in. Then tell the user plainly what is missing. | No | No | No | No |
request_assembly_quoteSubmit a manufacturing quote request after the user has reviewed and explicitly approved the checklist and every displayed warning. KernelCAD staff will confirm the final itemized price. This sends the request for human review and does not charge the customer or start checkout. | No | No | Not declared | Yes |
request_uploadUse this when the user has a photo, PDF drawing, STEP, STL, DXF, SVG or 3MF file on their device and you need it in a kernelCAD tool (trace_from_image, drawing_to_cad, mesh_to_features, inspect of:"step", or lib.fromSTEP / fromSTL / fromDXF / fromSVG / referenceImage in a script). Do not ask the user to paste the file as text or base64, and do not type coordinates from an image by hand. Returns a one-time `uploadUrl` (valid 30 minutes) and an `asset` reference. Give the user the link; after they say the upload is done, pass the `asset` value ("asset:<id>") as the file argument, for example trace_from_image({ imageUrl: "asset:<id>" }) or lib.fromSTEP("asset:<id>"). If the file is already at a public https:// URL, pass that URL instead. On clients that support MCP URL elicitation the upload page opens for the user directly and the call returns once the file is stored (status "uploaded"); then use the asset right away without asking the user anything. | No | No | Not declared | No |
resolve_assumptionsUse this when you need to confirm or override the open facts in an assumption ledger from trace_from_image (missing scale, inferred/assumed values) before committing geometry built from a reference photo. Reads the persisted `<model>.ledger.json` at `ledgerPath`, applies each resolution — `{ id, confirm: true }` to accept a fact as-is, or `{ id, value }` to override it — rewrites the ledger file, and returns the updated ledger plus `paramOverrides` (factId -> value) to feed straight into `set_param`. Pair with the `kernelcad-from-reference` skill. | No | No | Yes | No |
review_cadRun a deterministic mechanism-fitness review on supplied kernelCAD code or a file. It performs a full evaluation, replaces the active MCP session model on success, and clears that session if evaluation fails. The script may load referenced assets. The review validates the assembly/mate graph and connector placement, samples declared mate limits, optionally checks interference at sampled poses, and reports connector workspace bounds, fitness findings, and a repair mode (none, local-fix, parameter-tune, or topology-redesign). Runs within timeBudgetMs (default 90 s); stages that do not fit are listed in skippedStages and were not checked. Hosted: lib.fromSTEP / fromSTL / meshFromSTL / fromDXF / fromSVG and referenceImage take a direct string literal or a const bound to one (computed expressions are unsupported). They accept "asset:<id>" (from request_upload), an https:// URL or a data: URI as the path. | No | No | No | Yes |
review_paint_peek_latestReturn the newest brush-painted review packet from a Studio session. After sharing a /p/<slug> link, the user can open it in the browser and paint marks over the 3D viewport to give visual feedback. Call this tool with the `slug` from that link to see the strokes — screenshot + mask + struck part names plus an optional one-line note and intent tags (e.g. "too thick", "missing", "wrong angle") describing WHAT is wrong — and act on the feedback. The slug is the capability: no OAuth required when passing `slug`; private projects require the owner to be signed in. Omit `slug` to fetch your own latest packet from your signed-in account (requires OAuth). By default returns short-lived signed Storage URLs for the screenshot + mask + meta.json plus the struck part names — small and context-friendly. Pass `paths_only: false` to also base64-inline the PNGs for clients that cannot fetch the signed URLs over HTTP. | No | Yes | Not declared | No |
run_feaUse this when you need to know whether a part will hold a load. Runs a linear-static structural study and returns evidence — peak von Mises stress (MPa), peak displacement (mm), the minimum safety factor against the material yield (taken away from the clamp-singular edges of the fixed faces; the raw clamp-edge peak is reported separately as peakAtSupportMPa), per-region hot spots named by @kc[...] face ref, mesh trust flags, an equilibrium residual, and (CalculiX only) stress-heatmap PNG paths.
The study is EITHER declared in the script with `shape.feaStudy({ material, fixed, loads, meshSize?, minSafetyFactor? })` OR passed on the call against the shape the script returns: { code: 'return box(100, 20, 10);', material: 'aluminum-6061', fixed: { atX: 0 }, loads: [{ faces: { atX: 100 }, force: [0, 0, -200] }] }. Faces are a FaceQuery ({ atX | atY | atZ, byNormal: 'Z', ofSurfaceType, near: [x,y,z], ... }; with near it names the ONE matching face nearest the point), a face label ('top', 'bottom', 'left', 'right', 'front', 'back'; it must name ONE face — after a boolean 'top' can be several, which is an error listing them) or an @kc[...] ref. Force is the TOTAL [Fx, Fy, Fz] in N on those faces (a scalar force + direction is accepted). Materials: mild-steel, aluminum-6061, pla, petg, abs, nylon (aliases steel, aluminum), or { E, nu, yield } in MPa.
Solver (`solver`, default 'auto'): CalculiX + gmsh quadratic tets when that toolchain is installed; otherwise the built-in in-process voxel solver (8-node incompatible-mode bricks), which needs nothing installed and is marked summary.solver 'in-process-voxel' with trust.meshTrusted false — an estimate (accurate for prismatic bending, approximate at curved faces and notches), never a verified pass. solver: 'calculix' fails up front with fea.solver.unavailable and the install command when the toolchain is absent.
Also: `study` (a declared study name; default the last), `output_dir` (keeps the deck / summary JSON), `mesh_size` (mm, | No | No | No | Yes |
search_assetsSearch the public kernelCAD asset catalogue of published models. This is not find_part (screws, bearings, NEMA). Read-only. Anonymous callers are allowed. Do not send an API key.
Use source:"library" for the free built-in model library. Search its titles, tags or kit IDs, and download editable .kcad.ts from downloads.source. Library slugs are kit/id. For community projects use source:"community". With no source, an empty or unavailable community search falls back to the library for supported filters.
Library supports q, category (kit or manufacturing), tags, license, triangle bounds, kit, limit and cursor. Its default order is kit/id; use sort:"triangles" for descending complexity. Rig, IK, latest and remixed are community metadata.
For category:"kit", usage gives explicit evaluate_script and render_preview options for visual scene geometry. These skip mechanism checks and leave mechanical behavior unverified. Keep the checks enabled for manufacturing or engineering verification.
Each community row has slug, title, license (SPDX, always present), category, tags, kit, stats, has_rig, has_ik, ik_type, remix_count and thumbnail_url.
UNITS: stats.size_m is {x, y, z} in metres. Y is up. stats.origin_y is the model origin height in metres. stats.triangles is the triangle count.
RIG: has_rig means the asset has named moving parts. Pass rig:true to keep only those. get_asset returns rig as { <name>: { type: "rotate" or "slide", axis: "x"|"y"|"z" (local), range: [min, max] (degrees for rotate, metres for slide), node } }. has_ik / ik_type mark an inverse-kinematics target. ik is "any", "arm" or "legs".
FILTERS, all optional: q (title, tags and description), category, tags (every listed tag must match), license (SPDX id), min_triangles, max_triangles, rig (true = moving parts only), ik ("any"|"arm"|"legs"), kit, sort ("latest"|"triangles"|"remixed"), cursor (next_cursor from the previous page), limit (1-100, default 24).
Only public, gallery-listed assets with a redistributab | No | Yes | Not declared | Yes |
send_to_printerUse this when you need to upload a .gcode file (e.g. written by export with target: "model", format: "gcode") to a real network printer and, by default, start the print. protocol: 'octoprint' (POST /api/files/local with an X-Api-Key), 'moonraker' (Klipper's POST /server/files/upload), or 'bambu-lan' (Bambu Lab LAN-mode: FTPS implicit-TLS upload on port 990 as user 'bblp' with the printer's LAN access code, then an MQTT print-start command on port 8883 — requires access_code and, unless start_print is false, serial). bambu-lan uploads a .gcode.3mf print project (the printer prints 3MF projects, not bare G-code): the G-code goes in as Metadata/plate_1.gcode, inside the model 3MF from export format '3mf' when model_3mf_path is given (use options { arrange: 'plate', slicer: 'bambu' } so the printer shows the same named, coloured parts), else inside a minimal 3MF shell; the file name always ends in .3mf ('part.gcode' -> 'part.gcode.3mf'). Optional printer (a bundled profile id, the same ids as the export 3mf/gcode options.printer) is checked against protocol before anything is read or sent: an unknown id is refused with the list of valid ids, 'bambu-lan' needs a Bambu Lab profile and a Bambu Lab profile needs 'bambu-lan'. Pass { dry_run: true } to validate connectivity/authentication only, without uploading or starting a print. Never logs or echoes api_key/access_code. | Yes | No | No | Yes |
set_paramUse this when you need to edit a param() default value in a kernelCAD script. Returns the modified code as text plus diagnostics from re-evaluating the result. Caller persists the new code via standard file-write tools (this tool has no side effects). With preview: true it builds the edit in a scratch session instead and returns the diff_geometry summary plus the requirements-ledger and S1 binding diffs (which requirements flip, which margins shrink, which selectors moved or re-bound), without touching the active session, source, revision or caches. A preview whose revised build fails returns ok:false and no diff. Inspect after.requirementsOk to see whether the edit preserves declared intent; preview.ok only says the preview could be computed. | No | No | Yes | No |
set_scene_returnUse this when you need to set how the script returns its assembly. Replace the final top-level return statement with `return <assembly>.model();` or `return <assembly>.solvedModel(poses, options?);`. Use solvedModel for mate-authored mechanisms so FK and validation run. Returns modified source plus diagnostics from re-evaluation. | No | No | Yes | No |
set_selectionUse this when you need to replace the shared local Studio face/edge selection, or clear it with selection:null. The viewer highlights the pick on its next sync (300 ms). Does not edit geometry. Pass model_generation from get_selection; writes from an older generation are rejected. Use only current shape indices. Requires a local Studio session. | No | No | Yes | Yes |
solve_matesSolve the mate graph and get part poses. Pass code/file for an atomic source-bound solve, or omit both to use the active assembly. Returns { ok, status, poses, iterations?, evaluationEvidence? } where each pose is a serialized Transform ({ translation, rotateAxis, rotateDeg }). Optional poses overrides mate pose values by mate name. Supplied source is captured once, consumed within this call and released after solving. | No | Yes | Yes | No |
solve_sketchUse this when you need to solve a 2D sketch constraint set. Solve a 2D sketch constraint set. Side-effect-free: pass { entities, constraints } and receive solved entities plus the original constraints. Entities are POINT, LINE, and CIRCLE records; constraints use the kernelCAD constraint vocabulary. | No | Yes | Yes | No |
sweep_toleranceUse this when you need to know where and why a design breaks across a tolerance/dimension range, not just whether it builds at one nominal value. Declares one or more param() names with a { values: [...] } list or a { min, max, steps } range (number params are bisected; choice/string params are evaluated as discrete points), re-evaluates the script once per cartesian-product combination (capped at 64 combos — exceeding it truncates to the first 64 and emits kinematic.sweep-tolerance.combo-cap-exceeded), and measures every requirement in the S2 ledger (script require(), dfmSpec, gated FEA, mechanical intent) plus the standard gates on each combo: interference, mounting-hole diameter agreement, and joint-axis binding (all three default on); reachability only when gates.reachable names a tip_link + target. After the coarse grid it bisects each numeric pass/fail transition down to boundaryTolerance and reports the boundary value, the failing side, and the binding requirement/gate names (e.g. "wall fails below 1.840 mm; binding: wall"). Returns per-combo verdicts, firstFailure per gate, firstRequirementFailure per requirement, boundaries[], and a coverage statement that says "checked at N points plus boundaries", never "proven". | No | Yes | Yes | No |
trace_from_imageUse this when you need to trace a reference image into normalized waypoints. Trace pixel-space features from a reference photo into normalized [0..1] waypoints the agent can map to mm via a known scale anchor and feed to path().spline / path().nurbsSegment. Three backends are dispatched behind the scenes: `opencv` (deterministic; uniform-bg silhouette only), `vision-llm` (vision model; named points/cluttered backgrounds; needs a configured vision endpoint), and `hybrid` (opencv silhouette + LLM-labeled named points). Default backend is `auto`. Per-feature confidence is reported. Pair with the `kernelcad-trace-from-image` skill for the conversion-to-mm pipeline. Hosted: give the file as an https:// URL, a data: URI (base64, max 25 MB) or "asset:<id>" from request_upload (when the file is on the user's device). | No | No | Yes | Yes |
verifyUse this when you need to check a design against a rule set. One verifier, selected by `check`:
- 'assembly' — static assembly review ({ file | code }, or the session evaluate_script left): mate validator, default-pose interference, joint topology, mechanical plausibility. ok:false with `blocking[]` exactly when review_cad's blocking rules fire on these findings; review_cad also sweeps joint ranges and runs physics.
- 'urdf' — structural validity of a .urdf file ({ urdf_path }).
- 'dfm' — print-readiness gates declared by dfmSpec() ({ file | code }).
- 'dfm-preflight' — sheet-metal flat pattern vs a job-shop's ordering rules ({ vendor, material, thicknessIn|thicknessMm, ... }). Returns the vendor's catalog source pages as `sources`; when `disclosure` is present, show it with those links.
- 'assembly-path' — continuous straight-line removal of each assembly part along ±X/±Y/±Z and optional world-space directions. Returns valid directions, blocking parts and one of three states (removable / blocked / unknown); sequence peels the directional blocking graph and reverses it into a build sequence with a model stamp. Fastened-mate and fixed-connect clusters become subassemblies: each is planned recursively inside and installed as one unit at the top level (`Step.subassembly`). Remaining valid orders use deterministic heuristics (subassemblies first, outside-in, fewest reorientations, fewest tool changes); stuck sets get a budgeted blocking-reduction partition and a sampling fallback whose paths are labelled found-by-search, never proven. A fastener with a fastened-mate `fastener` declaration (axis, pitch, optional tool envelope) is tested along its helical path and reported `motion: helical`; a press/snap `fit` declaration becomes a `requires-force` step, never simulated. A modelled driver/socket/hex-key envelope swept along the approach axis adds `toolBlocked` { fastener, blockers } and a failing S2 ledger entry; unmodelled tools add nothing. Threaded fasteners without me | No | Yes | Yes | No |
why_did_this_failUse this when you need to trace why a feature failed. Walk the upstream chain of a failing feature. Returns the diagnostics of the requested feature plus the diagnostics of every upstream feature in topological order (the requested feature is the last entry). Per-code hints are inline on every diagnostic — call lookup_diagnostics for the full catalogue. Pass { file?, code?, feature_id? }. | No | Yes | Yes | No |
write_bomUse this to merge a supplied handoff BOM with optional KernelCAD catalog parts, MPNs and pricing, write a local CSV, and return Sheets-ready rows. Pass exactly one of handoff, handoff_json or handoff_path. The default output is a new file under artifacts/bom; an explicit output_path selects another allowed destination. Existing files are preserved unless overwrite:true, which replaces the destination. This tool makes no Google API calls. | Yes | No | No | Yes |
Details
- Registry status
- Active
- Published
- Oct 27, 2026
- Updated
- Oct 27, 2026
- Categories (suggested)
- Design and mediaSuggested categories are assigned automatically from the registry text and may be wrong. Verified operators can correct them.
- GDPR
- Not declared