fusion-cad-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| FUSION_CAD_CORPUS_DIR | No | Directory where the Fusion API corpus is stored. If not set, defaults to ~/.fusion-cad/corpus/ |
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 |
|---|---|
| doc_stateA | Summary of the active Fusion document: design_type (parametric/direct), bodies/sketches/features count, units, dirty flag, components, parameters, timeline. A direct design returns parameters_count and timeline_count as None, listed in result.unavailable. |
| list_open_docsA | List recently-open documents in Fusion. |
| list_projectsA | List all projects (hubs / folders) the user can see. |
| search_docsB | Fuzzy-search documents by name. Optional project scope. |
| open_docA | Open a document by name (fuzzy). Optional project scope. |
| saveA | Save the active document. Untitled docs are refused by Fusion; use save_as instead. |
| save_asA | Save the active document to a new path. Fusion's MCP may still require initial save via UI. |
| closeA | Close the active document. confirm must be 'save', 'discard', or 'prompt'. Never auto-pick save vs discard for dirty docs; surface the choice to the user. |
| undoA | Undo the last |
| redoB | Redo the last |
| add_parametersA | Add user parameters idempotently. Existing names are skipped, not overwritten. Each def: {name, expression, units?, comment?}. Reserved math names (sin/cos/pi/e/sqrt/etc) are rejected at validation time because Fusion will silently bind expressions to the math function. |
| update_parameterA | Update one user parameter's expression. Returns before/after values. |
| list_parametersA | List all user parameters with resolved values, expressions, units, comments. |
| create_sketchB | Create a new sketch on a principal plane. plane in {xy, xz, yz}. name must be unique. |
| add_lineA | Add a single line to a sketch. p1, p2 are [x, y] in mm. |
| add_rectangleA | Add a rectangle to a sketch. kind in {center, corner, 3pt}. Returns line_indices for the 4 edges. center: p1=center point, p2=corner. corner: p1, p2 are opposite corners. 3pt: p1, p2 define one edge, p3 sets the other edge direction. |
| add_circleA | Add a circle. kind=center_radius needs center+radius_mm. kind=3pt needs p1+p2+p3. Returns circle_index for later reference. |
| add_polygonB | Add a regular polygon. sides >= 3. Inscribed (default) means vertices lie on the radius. |
| add_geometric_constraintB | Apply a geometric constraint. kind in {horizontal, vertical, parallel, perpendicular, coincident, tangent, equal, concentric, fix, midpoint, symmetric}. entities is a list of entity refs like 'line:0', 'line:0:start', 'circle:1:center', or 'origin'. |
| add_dimensionA | Add a dimension with an expression. kind in {distance_h, distance_v, distance, angle, radial, diameter}. Parameter-name expressions ('body_width', 'length / 2') work AND propagate when the param changes (gotchas.md G9, verified 2026-05-31). Use literal mm only when you want a baked value. entities depends on kind: distance_h / distance_v / distance: 2 point refs (e.g. ['line:0:start', 'line:0:end']) angle: 2 line refs radial / diameter: 1 circle or arc ref |
| assert_profilesA | Check that the sketch has the expected number of closed profiles. Returns ok=False if not. Use after building a sketch to catch self-intersecting polygons (which return profiles=2 silently). |
| probe_sketch_dimensionsA | Dump every dimension in a sketch with parameter name, expression, value, and entity-attachment coordinates. Use this to identify which literal-named dim (e.g. Per-dim payload: dim_class, param_name, expression, value_mm, unit, entity_one, entity_two. Entity descriptors include point/start/end/center coords in mm so you can match dims to specific lines/circles/ellipses. |
| edit_sketch_dimensionA | Change a sketch dimension's expression by parameter name (e.g. Triggers design.computeAll() before returning. After calling this, run
On dim_not_found, the response includes the available dimensions in the sketch so the agent can correct course without another tool call. Args:
sketch: Sketch name (will search root + every sub-component).
dim_name: Parameter name of the dimension (use |
| add_ellipseA | Add an ellipse defined by center + major-axis endpoint + minor-axis endpoint. All in mm. |
| add_arcB | Add an arc. kind in {3pt, center_start_end, center_start_sweep}. 3pt: p1, p2, p3. center_start_end: center, start, end. center_start_sweep: center, start, sweep_radians (positive = CCW). |
| add_splineB | Add a fitted spline through a list of [x, y] points (mm). Optionally closed. |
| extrudeA | Extrude a sketch profile into a feature. operation: new_body | join | cut | intersect | new_component extent_kind: distance (needs expression) | symmetric (needs expression) | all_positive | all_negative direction: positive | negative (for distance kind) participants: body names to operate on (for cut/join/intersect) Returns feature_name + bodies_added. |
| fillet_edges_by_geometryA | Fillet edges of a body by geometric filter (no UI selection needed). parallel_to: x | y | z | any — only edges parallel to that axis (or all). radius: expression like 'corner_r' or '8 mm'. min_length_mm: optional minimum edge length filter (skips tiny rounding edges). |
| chamfer_edges_by_geometryC | Chamfer edges of a body by geometric filter. kind: equal (one distance) | two_dist (needs distance2) | dist_angle (needs angle). |
| mirror_featureB | Mirror a feature or body across a plane. plane: xy | xz | yz | . |
| pattern_rectangularB | Rectangular pattern. x_axis / y_axis: x | y | z | . x_distance / y_distance: total-extent expressions like '40 mm' or '4 * pitch'. |
| pattern_circularB | Circular pattern around an axis. axis: x | y | z | . |
| combineC | Boolean combine. operation: join | cut | intersect. keep_tools: preserve tool bodies after op. |
| revolveB | Revolve a sketch profile around an axis. axis: x | y | z | extent_kind: full (360deg) | angle (needs angle expr) operation: new_body | join | cut | intersect | new_component |
| shellA | Hollow out a body. face_normals_to_remove is a list of [nx, ny, nz] for faces to remove (e.g. [[0, 0, 1]] removes the top face). Empty / omitted = closed shell. direction: inside | outside | both. |
| add_holeA | Add a hole on the body's top face (max-Z, +Z normal). kind: simple | counterbore (needs cbore_diameter + cbore_depth) | countersink (needs csink_diameter + csink_angle). position_mm: [x, y, z] — x/y locate on the top face; z is informational. extent_kind: all | distance (needs depth_expression). |
| rebuild_featureA | Rebuild a feature whose downstream references are stale (G10) by capturing its inputs, deleting it, and re-creating from the current sketch. Supported feature classes: ExtrudeFeature (DistanceExtent, ProfilePlaneStart
or OffsetStart, 1 or N profiles in the same sketch). This is the most
common G10 case — a feature that got Returns structured
Profile matching: when the original sketch has more than one profile, picks the new profile whose area is closest to the captured original area. Falls back to profile[0] if no area was captured. Failure mode warning: if delete succeeds but recreate fails (e.g., sketch name changed, multiple profiles spread across sketches), the response sets ok=false and includes a WARNING field instructing the agent to undo via Fusion's undo and try again manually. Args: feature_name: Name of the feature to rebuild. Walks root + every sub-component. component_name: Optional hint for disambiguation. Chain pattern: edit_sketch_dimension -> audit_feature_health -> for each broken extrude in features list, rebuild_feature -> audit_feature_health. |
| move_bodyA | Move a body via a Move feature (parametric in the timeline). Provide translation_mm (mm) and/or rotation (axis + angle_deg). |
| ribA | NOT SCRIPTABLE in the current Fusion API: RibFeatures is a read-only
collection (no createInput/add), so this always returns the structured
error |
| bodies_to_componentsA | Convert root-level bodies into named components, preserving world position. mapping is {body_name: new_component_name}. Multi-body designs need this before joint/motion work — Fusion's joints operate on components, not bodies. |
| move_componentA | Move an occurrence by translation (mm) and/or rotation (axis + angle deg).
rotation_origin_mm defaults to [0, 0, 0] (world origin) if omitted.
Breaks the occurrence's ground-to-parent flag if set (otherwise the move
silently reverts). Check |
| ground_componentA | Set the ground flag on an occurrence (lock its world position). |
| unground_componentB | Clear the ground flag on an occurrence. |
| create_rigid_groupA | Lock 2+ components together as a rigid group (they move as one). |
| create_contact_setC | Create a contact set for physics / motion analysis between 2+ bodies. |
| interference_checkA | Run an interference analysis on 2+ bodies or occurrences. Returns per-pair interference volume in mm^3. Empty pair list = no interference. |
| set_joint_limitsA | Set min/max/rest values on an existing joint by name.
Values are expressions: angles for revolute (e.g. '45 deg'), distances for slider.
rest_value is the NEW May 2026 snap-back position. Pass None to leave any field unset.
Limits bind to rotationLimits when the motion has one, else slideLimits
(cylindrical joints get rotation limits). The response echoes back what
Fusion actually stored under |
| drive_jointA | Drive an existing joint to a target value.
value is an expression: angle for revolute, distance for slider, etc.
Tries jointMotion attributes in order: rotation, slide, roll, pitch, yaw.
Fusion silently ignores drives beyond the joint's limits; check |
| create_jointA | Create a Joint between two entity-handle origins. Joint origins are specified as entity handles (kind:path:token). Supported kinds: face (planar OR cylindrical/conical), edge (uses MiddleKeyPoint), vertex (uses Point), point (sketch point). Get handles from list_body_entities for face/edge/vertex, or use the sketch tools' returned handles for sketch points. motion_type: one of rigid, revolute, slider, cylindrical, ball.
axis: x | y | z, relative to the first joint geometry's local frame. For typical face-normal rotation (hinge pin coming out of the face) use z. offset_mm: optional ValueInput expression for lateral offset between the two geometries. A snap hinge typically needs a few mm here to hold the gap between mating flanges. Preserved across user-param changes (unlike Move-based positioning). angle_deg: optional initial angle (revolute / cylindrical). name: optional joint name in the timeline. Returns {ok, joint_name, joint_token, motion_type, axis, offset_mm, angle_deg}. Use joint_name for downstream drive_joint / set_joint_limits calls. Errors:
|
| create_construction_planeA | Create a construction plane. kind in {offset, midplane, at_angle, 3_points}. offset: base_plane + offset expr (e.g. 'thickness') midplane: plane_a + plane_b (between two existing planes) at_angle: axis + base_plane + angle expr (e.g. '30 deg') 3_points: p1, p2, p3 each as [x, y, z] in mm Plane / axis names default to principals: 'xy', 'xz', 'yz' / 'x', 'y', 'z'. |
| create_construction_axisA | Create a construction axis. kind in {2_points, normal_to_face_by_geometry}. 2_points: p1, p2 each as [x, y, z] in mm normal_to_face_by_geometry: body name + face_normal [nx, ny, nz] (finds the face whose normal matches) |
| create_construction_pointA | Create a construction point at explicit [x, y, z] coordinates (mm). |
| delete_constructionA | Delete a construction plane / axis / point by name. |
| list_body_entitiesA | Enumerate faces / edges / vertices of a body and return their handles. This is the bridge between name-addressing (bodies) and handle-addressing (sub-entities). kinds: subset of [face, edge, vertex]. Defaults to all three. face_normal_filter: [nx, ny, nz] — only faces matching that normal (e.g. [0, 0, 1] for top). edge_parallel_to: x | y | z — only axis-parallel edges. min_edge_length_mm: filter out short edges (typical use: skip fillet runouts). Returns face/edge/vertex lists, each with handle, index, and geometric info. Use the returned handles in measure, fillet_edges, chamfer_edges, project_to_sketch, etc. |
| measureA | Measure between two entities using their handles (from list_body_entities or tool returns). kind: distance (min distance + nearest points) | min_distance (value only) | angle. |
| find_mesh_using_rayA | NEW May 2026: cast a ray and return MeshBody objects intersected. origin_mm: ray origin [x, y, z] in mm. direction: ray direction [dx, dy, dz] (any magnitude; will be normalized by Fusion). component_name: optional component to scope the search; omit for whole root. |
| ray_collision_with_meshA | NEW May 2026: cast a ray against ONE MeshBody, return all intersection points. mesh_handle: handle of a mesh body (e.g. from find_mesh_using_ray or list_body_entities). |
| fillet_edgesB | Fillet specific edges by handle (UI-selection style). edge_handles: list from list_body_entities (kinds=['edge']). radius: expression like 'corner_r' or '8 mm'. |
| chamfer_edgesC | Chamfer specific edges by handle. kind: equal | two_dist (needs distance2) | dist_angle (needs angle). |
| project_to_sketchA | Project entities (by handle) onto a named sketch. Useful for cut-extrudes that reference body geometry. |
| bounding_boxA | Return mm bbox + extents for a body (by name) or all bodies if name omitted. Walks root + every occurrence. |
| volumeA | Return volume in cm^3 and mm^3 for a body (by name) or all bodies if name omitted. |
| massB | Return mass (kg), material name, density, and volume for a body or all bodies. Material is whatever the body has been assigned; uses Fusion's physical-properties calc. |
| center_of_massA | Return center of mass in mm world coordinates for a body or all bodies. |
| audit_feature_healthA | Sweep the feature tree (root + every sub-component) and report features whose healthState != 0. Call this after ANY tool that edits sketch geometry, user parameters, or features. If summary.failed > 0 (state 2 or 3) or summary.warning > 0 (state 1), the BREP may look healthy via the API while Fusion's UI shows a stale cached display. See gotchas G10/G11. Args: component_name: Restrict the audit to features in this component (still recurses into its sub-components). Default: root + all. include_healthy: Include healthy features (state 0) in the features list. Default False — only broken features are returned. Returns envelope.result = { ok, summary: {total, healthy, warning, failed}, features: [{path, component, name, classType, healthState, healthLabel, isSuppressed, errorOrWarningMessage}, ...] } |
| screenshotB | Capture a PNG screenshot of the active viewport. Returns base64 image in envelope.image. direction: one of current, front, back, bottom, top, left, right, iso-* (4 variants). Fusion handles fit-view internally for named directions. |
| set_viewA | Orient the viewport to a named direction. Optionally fit to view. Use when you want to change camera without capturing a screenshot. |
| screenshot_compare_with_markerA | Capture before/after screenshots from the same camera by rolling the
timeline marker to Use this to give yourself or the user a clean visual diff of a change you just made — much more convincing than describing the change in words when the geometric delta is subtle. Same camera both shots so the comparison is honest. Restore semantics: if anything fails after the marker is moved, this tool
attempts to roll back to the original position before returning. The
Args: before_marker_position: Timeline marker position to capture as the "before" state. Must be in [0, timeline.count]. Use 0 for the initial empty state, or the index just before a specific feature. direction: One of: current, front, back, bottom, top, left, right, iso-bottom-left/right, iso-top-left/right. Defaults to iso-top-right. width, height: Optional image dimensions in pixels. transparent: PNG transparency. Default True. anti_aliasing: Smooth edges. Default True. Returns envelope.result = { before_image: {data: , mime_type: "image/png"}, after_image: {data: , mime_type: "image/png"}, before_marker, after_marker, direction } |
| find_apiA | Search the local Fusion API help corpus. Returns top-N matches as {slug, title, namespace, kind, url, is_preview, introduced, snippet}. Use this BEFORE writing a script that touches an unfamiliar method or class. Filters: kind: 'object' | 'member' | 'manual' | etc — restrict to one page type namespace: substring match on namespace (e.g. 'Fusion', 'CAM', 'core') |
| find_patternA | Search patterns.md (verified Fusion MCP patterns and helpers) by intent. Use when looking for the canonical idiom for a common operation (constrained rectangle, fillet by geometry, screenshot fit-view, etc). |
| find_toolA | Search this server's own tool reference (tools.md) by intent or symptom. Returns the matching sections: signatures, exact enum values, return keys, and error codes. Use this to look up how to call a tool instead of guessing at arguments, and to check what an error code means. Works with Fusion closed. |
| find_gotchaA | Search gotchas.md (known failure modes) by symptom or keyword. Use when something behaves unexpectedly: check here for the documented cause
|
| exportA | Export geometry to a file. format in {stl, 3mf, step, iges, obj, f3d, sat, smt}. path: absolute path (relative + '..' + Windows reserved names rejected). body: optional body name. If omitted, exports the whole root component. STEP/IGES/SAT/SMT/F3D always export the whole design (ignore body). refinement: low | medium | high — applies to STL and OBJ mesh quality. units: mm | cm | m | inch — STL/OBJ only. |
| import_geometryA | Import geometry from a file into the active design. format in {step, iges, sat, smt, f3d}. path: absolute path to an existing file. Returns counts of bodies and occurrences added to the root component. |
| executeA | Raw Python passthrough. The script must define |
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 75 tools
The tool set is mostly distinct: sketch primitives, feature operations, joint tools, and inspection tools each have clear targets. The main ambiguity risk is the four find_* lookup tools and the handle-based vs geometry-based fillet/chamfer variants, but their descriptions disambiguate them. No two tools appear to do the same job.
Naming is readable and consistently snake_case, but conventions are mixed: add_* for sketch primitives and parameters, create_* for sketches/joints/construction, bare verbs (extrude, shell, save, measure), and noun phrases (bounding_box, doc_state, center_of_mass). This inconsistency, especially add vs create, prevents a higher score.
75 tools is far beyond the well-scoped 3-15 range and exceeds the 50+ extreme threshold. While Fusion CAD is a broad domain, the surface is too large for an agent to navigate efficiently and includes several auxiliary meta-tools (find_api, find_pattern, find_tool, find_gotcha, screenshot_compare_with_marker) that bloat the count.
Core modeling workflows are covered: sketching, constraints, dimensions, extrude/revolve/shell/hole, fillet/chamfer, patterns, joints, measurement, export/import, and parameters. However, there are notable gaps: no list_bodies/list_joints/list_sketches, no delete_body/delete_feature/delete_sketch (only delete_construction), no create_document, and no general feature editing. The raw execute passthrough mitigates these, but the dedicated surface is incomplete.