MCP tools¶
The server provides 29 tools. Each calls the app's REST API, so it follows the
same behavior as the corresponding action in the UI. Project-specific tools
take a project_id; get_command_catalog and describe_commands do not. See the
command catalog for the payloads accepted by execute_command.
One write path
execute_command is the only tool that changes a project. All other tools
read project data and can be called at any time.
The run_* and slice_* tools submit jobs through the app's job registry and
wait for them to finish. Only one expensive job can run per project. If another
job is already using the project, these tools return {"error": ...} instead
of queueing the request.
When the app refuses a call, a tool returns {"error": ...} instead of
failing. A rate limit also sets rejection: "rate_limited" and
retry_after_s, the seconds to wait before trying again. The error text tells
the per-user MCP command quota apart from the general request limit.
Catalog and execution¶
| Tool | Signature | Returns |
|---|---|---|
get_command_catalog |
() |
Returns a compact index of the commands execute_command accepts, one {type, summary} each. The catalog is versioned with the app, so it shows which commands this deployment supports. |
describe_commands |
(types) |
Returns the full entries for the named commands: the complete description and the payload JSON schema, with nested models under $defs. A name that is not in the catalog comes back with an error. Call it for every command you are about to send, including the step types of a commands.batch. |
execute_command |
(project_id, type, payload) |
Applies one command and returns an accepted status with new_revision, or a rejected status with a structured reason. A rate_limited rejection carries retry_after_s. An invalid_payload rejection carries a hint naming the describe_commands call for the rejected type. The tool fills in project_id automatically and retries once if the revision is stale. |
list_revisions |
(project_id, limit=20) |
Lists the restorable revisions, newest first, each with revision, description, timestamp and actor, plus the current revision. Pass one to the project.restore_revision command to roll back many commands at once. |
commands.batch sends several commands in one execute_command call. They
apply atomically as one revision and one undo step: if a step is rejected,
nothing changes and the rejection names the step. A later step can use an
earlier step's result through a string that is exactly "$<k>.<path>", such
as "$0.id" or "$1.element_ids[0]". Each step counts against the MCP
command quota, and a batch is refused up front when fewer units remain than
it has steps. See the command catalog for an example.
The feature.update.* commands patch a feature. Send its feature_id and only
the fields to change; the others keep their stored values. A number replaces
the expression that drove its field, and null clears a field that can be
empty.
Inspect the model¶
| Tool | Signature | Returns |
|---|---|---|
get_model_tree |
(project_id, part_id=None) |
Returns the assemblies in the project with their parts, sketches, features, rebuild statuses and mates. With part_id, returns only that part and the assembly holding it, which keeps the response small on a large project. |
get_assembly_overview |
(project_id, assembly_id=None) |
Summarizes each assembly's parts (including bounding boxes and feature or instance counts), sub-assembly occurrences and their placements, and composed bounding boxes. Use it first to orient yourself in a multi-part or nested project. |
get_motion_state |
(project_id, assembly_id) |
Returns each joint's current position and travel limits. Angles are in degrees and offsets are in millimetres, measured from where the joint was created. An unbounded limit is null. Call it after assembly.joint.set_value to confirm the mechanism moved. |
get_diagnostics |
(project_id) |
Lists features whose rebuild status is not ok (failed, warning, unresolved_reference or stale) and returns their structured diagnostics. |
get_topology |
(project_id, part_id) |
Returns a part's faces (with ids, surface types, centroids, normals, areas, bounding boxes and cylinder data), edge count and bounding box. Use it to locate geometry to edit. |
find_entities |
(project_id, part_id, entity, ...) |
Finds faces or edges by properties such as surface or curve type, normal, area, length, radius, internal-cylinder status or extreme position. This helps target geometry such as a hole, top face or fillet edge without guessing indices. A filter for the wrong entity type is rejected; for example, cyl_internal cannot be used in an edge query. |
get_sketch |
(project_id, part_id, sketch_id) |
Returns a sketch's plane, its elements with their types and 2D parameters, and its constraints. Each constraint has an id, its type and operands, value, expression, driving, disabled and name. Pass the id to sketch.constraint.toggle to change a dimension in place. |
get_command_log |
(project_id, limit=20) |
Returns recent commands with their type, actor, payload, status, new revision and any rejection. Use it to see what happened or replay a command. |
list_parameters |
(project_id) |
Returns named parameters and their resolved values. |
get_screenshot |
(project_id, view="multiview", width=1024, height=768, ...) |
Renders the model as a PNG. By default, multiview returns a 2×2 orthographic sheet with front, top, right and isometric views. You can request a single view (front, back, top, bottom, left, right or iso) or set the camera with azimuth and elevation. projection (perspective or orthographic), display (shaded-with-edges, transparent or wireframe) a section cut (section on XY, XZ or YZ, with section_offset in mm and section_flip), isolate/hide (part or assembly ids) and zoom are optional. |
Screenshot camera¶
Z points up. The camera looks at the model from the direction
(cos(el)·cos(az), cos(el)·sin(az), sin(el)), with azimuth az and elevation
el in degrees. The named views use the same convention:
| View | Camera position | Azimuth, elevation |
|---|---|---|
front |
+X | 0°, 0° |
right |
+Y | 90°, 0° |
top |
+Z | any, 90° |
iso |
+X +Y +Z | 45°, 35.264° |
back, left and bottom look from the opposite sides. Setting azimuth or
elevation overrides the named view's angle and renders a single view, even
when view is multiview. The display mode and section cut also apply to the
2×2 sheet, which is always orthographic.
isolate renders only the listed parts and hide leaves them out. An assembly
id stands for every part under it. The camera fits whatever stays visible, so an
isolated small part fills the frame, and zoom magnifies that fit about its
centre (2 doubles the size, 0.5 halves it; 0.1 to 50). There is no per-part
transparency: display="transparent" x-rays every visible part and combines
with isolate/hide, for example to look inside one assembly. All three also
apply to the 2×2 sheet.
Resolve reference geometry¶
| Tool | Signature | Returns |
|---|---|---|
get_face_plane |
(project_id, part_id, face_id, world=False, path=None, instance_id=None) |
Returns a planar face's sketch plane as {origin, normal, x_dir}, ready to use as plane_def. Non-planar faces return an error. With world=True, the plane is in the assembly frame at the current pose, for the placement that path and instance_id name (see measure_assembly). |
get_face_axis |
(project_id, part_id, face_id, world=False, path=None, instance_id=None) |
Returns the axis of a cylindrical or conical face as {axis_origin, axis_dir, radius, internal, half_angle?}. When internal is true, the face is a hole. Use the axis for concentric cuts, revolves, circular patterns or mirrors. world, path and instance_id work as for get_face_plane. |
get_part_references |
(project_id, part_id) |
Returns inferred reference geometry: datum planes, axes, holes (through or blind, including counterbore or countersink steps), and recognized fillets and chamfers. Use it to start remodeling an imported STEP part. Reference-only meshes return no inferred references. |
Measure and estimate¶
| Tool | Signature | Returns |
|---|---|---|
measure |
(project_id, part_id, kind, ...) |
For volume, returns volume, surface area and center of mass. For distance, returns the minimum distance between two entities; for angle, it returns the angle between them. Get entity ids from get_topology. |
measure_assembly |
(project_id, entity_a, entity_b) |
Measures two entities where the assembly places them now, across parts and sub-assemblies. An entity is {part_id, kind, id, path?, instance_id?}, where kind is face, edge, datum (the datum feature id) or origin (XY, XZ, YZ, X, Y or Z, without part_id). path lists the sub-assembly occurrence ids from a root down to the part, and instance_id names a part instance. Without them, the part's first placement is used. Returns angle_deg between planes and axes (cylindrical faces, straight edges, datums and origin axes count as axes), the world direction_a/direction_b, parallel, and distance with closest points. For example, a wheel's cylindrical face against the XY origin plane gives its camber, and against YZ its toe (X forward, Z up). |
estimate_spacing |
(project_id, part_id, mode, ...) |
Suggests pattern spacing based on the part's size. linear returns the part's extent and a suggested spacing; circular returns an extent and suggested radius. Treat these values as guidance. |
diff_parts |
(project_id, part_a_id, part_b_id) |
Compares two solids at their local origins and returns added_volume, removed_volume, common_volume, symmetric_difference_volume and match_ratio (1.0 means identical). Use it to compare a parametric remodel with an imported reference. Solids only. |
check_interference |
(project_id, assembly_id=None, part_ids=None, min_clash_volume_mm3=None) |
Tests body pairs at their placed positions, including every occurrence of a reused part. Each pair returns clash (with overlap volume in mm³), expected (an overlap between bodies a mate or joint connects directly), touch (contact, or an overlap within min_clash_volume_mm3), clear (with gap in mm) or failed. Pairs on an assembly's ignore list are not tested; they are counted in summary.ignored and listed under ignored. Add or remove them with the assembly.ignored_pairs.update command, using a pair's assembly_id and key. By default, it checks every root assembly. An empty part_ids list checks nothing. |
Simulation¶
| Tool | Signature | Returns |
|---|---|---|
list_stress_studies |
(project_id, part_id) |
Lists a part's stress studies, including each study's id, name, fixtures and loads. Call this before running a study. |
run_stress_study |
(project_id, part_id, study_id) |
Runs a linear-static study and returns maximum von Mises stress, maximum displacement, minimum factor of safety and maximum stress per face. Define the study first with simulation.create. |
list_flow_studies |
(project_id, part_id) |
Lists a part's flow studies, including each study's id, name, mode, fluid, domain and resolution. Create studies with flow.create. |
run_flow_study |
(project_id, part_id, study_id) |
Runs a flow study and returns scalar results and diagnostics. Both modes return force_n and moment_n_mm; rotation also returns flow_rate_mm3_s and torque_n_mm. A solve takes one to ten minutes, depending on the resolution. This is a design-stage trend tool: under refinement, a rotating body's torque keeps its direction and order of magnitude, but not a precise value. |
See Materials and stress simulation for the workflow these mirror.
Fabrication¶
| Tool | Signature | Returns |
|---|---|---|
list_slice_setups |
(project_id, part_id) |
Returns the project printers and setups available for the part. Create them with slicer.printer.create and slicer.setup.create. Setups apply to parts; there is no assembly-level equivalent. |
slice_part |
(project_id, part_id, setup_id) |
Slices a part and returns layer count, object height, estimated time, filament use in millimetres and grams, per-role breakdowns, warnings and bed placement. Filament settings come from the part's material. If it has no printable material, N3XD uses generic PLA and returns a warning. The layer preview is not included. |