create_cad_document is the primary MCP tool for building 3D geometry. It accepts a structured JSON description of parts and operations and returns an IR document that can be inspected, exported, or opened in the browser.
Input Schema
{
"parts": [...],
"assembly": { ... },
"format": "compact" | "json"
}
partsPartInput[]requiredArray of part definitions. Each part must have a name and a geometry source (one of primitive, extrude, revolve, sweep, or loft), plus optional operations and material.
assemblyAssemblyInputoptionalOptional assembly definition containing instances and joints. When present, the tool creates part definitions, places instances, and builds the kinematic chain. Scene roots are replaced by the assembly representation.
formatstringoptionalOutput format: compact (default, ~5x smaller) or json (verbose, human-readable). Compact is recommended for all MCP workflows since it saves tokens.
Part Definitions
A part is defined by its geometry source plus an optional chain of operations.
Primitive-Based Part
{
"name": "plate",
"primitive": {
"type": "cube",
"size": { "x": 100, "y": 60, "z": 5 }
},
"operations": [...],
"material": "aluminum"
}
primitive.typestringrequiredPrimitive type: cube, cylinder, sphere, or cone.
primitive.sizeVec3optionalCube dimensions in mm. Cube corner sits at origin, extends to (size.x, size.y, size.z).
primitive.radiusnumberoptionalRadius for cylinder, sphere, or cone (bottom radius if radius_bottom is not specified).
primitive.heightnumberoptionalHeight for cylinder and cone, along +Z axis.
primitive.segmentsnumberoptionalFacet count for curved surfaces. Default 32.
primitive.radius_bottomnumberoptionalBottom radius for cone. Defaults to radius.
primitive.radius_topnumberoptionalTop radius for cone. 0 for a pointed cone.
Extrude-Based Part
{
"name": "bracket",
"extrude": {
"sketch": {
"plane": "xy",
"shape": { "type": "rectangle", "width": 50, "height": 30, "centered": true }
},
"height": 10
},
"material": "steel"
}
extrude.sketchSketchInputrequiredSketch profile to extrude. See Sketch Input below.
extrude.heightnumberoptionalExtrusion height in mm. Direction is normal to the sketch plane.
extrude.directionVec3optionalCustom extrusion direction vector. Overrides height and default normal direction.
Revolve-Based Part
{
"name": "bowl",
"revolve": {
"sketch": {
"plane": "xz",
"shape": {
"type": "polygon",
"points": [{"x": 5, "y": 0}, {"x": 15, "y": 0}, {"x": 15, "y": 10}, {"x": 5, "y": 10}]
}
},
"axis": "z",
"angle_deg": 360
}
}
revolve.axisstring | Vec3optionalAxis of revolution: "x", "y", "z", or a custom {x, y, z} vector. Default "z".
revolve.axis_offsetnumberoptionalOffset of the axis from the origin, perpendicular to the axis direction.
revolve.angle_degnumberoptionalRevolution angle in degrees. Default 360 (full revolution).
Sweep-Based Part
{
"name": "spring",
"sweep": {
"sketch": {
"shape": { "type": "circle", "radius": 2 }
},
"path": { "type": "helix", "radius": 10, "pitch": 5, "height": 50 }
}
}
sweep.pathPathInputrequiredSweep path. Either a line segment ({type: "line", start: Vec3, end: Vec3}) or a helix ({type: "helix", radius, pitch, height}).
sweep.twist_degnumberoptionalTwist angle applied over the sweep length, in degrees.
sweep.scale_startnumberoptionalScale factor at the start of the sweep.
sweep.scale_endnumberoptionalScale factor at the end of the sweep. Different from scale_start creates a tapered shape.
Loft-Based Part
{
"name": "transition",
"loft": {
"sketches": [
{ "at": {"x": 0, "y": 0, "z": 0}, "shape": {"type": "rectangle", "width": 20, "height": 20} },
{ "at": {"x": 0, "y": 0, "z": 30}, "shape": {"type": "circle", "radius": 10} }
]
}
}
loft.sketchesSketchInput[]requiredTwo or more sketch profiles at different positions. The loft interpolates between them.
loft.closedbooleanoptionalIf true, connects the last profile back to the first (for closed-loop lofts).
Sketch Input
Sketch input defines a 2D profile on a plane.
planestringoptionalSketch plane: "xy" (default), "xz", or "yz".
atVec3optionalSketch plane origin. Default {x: 0, y: 0, z: 0}.
shapeobjectrequiredThe sketch shape. One of rectangle, circle, or polygon.
Rectangle Shape
{ "type": "rectangle", "width": 50, "height": 30, "centered": true }
widthnumberrequiredheightnumberrequiredcenteredbooleanoptionalIf true, centered at the sketch origin. If false (default), corner at origin.
Circle Shape
{ "type": "circle", "radius": 10 }
radiusnumberrequiredPolygon Shape
{ "type": "polygon", "points": [{"x": 0, "y": 0}, {"x": 10, "y": 0}, {"x": 5, "y": 8}], "closed": true }
pointsVec2[]requiredclosedbooleanoptionalClose the polygon by connecting the last point to the first. Default true.
Operations
Operations are applied in order to the part's base geometry. Each operation modifies the result of the previous one.
Boolean Operations
{ "type": "difference", "primitive": { "type": "cylinder", "radius": 3, "height": 10 }, "at": "center" }
typestringrequiredBoolean type: "union", "difference", or "intersection".
primitivePrimitiverequiredThe tool shape for the boolean operation.
atPositionSpecoptionalPosition of the tool shape. See Position Specification below.
Hole
A convenience operation that creates a cylindrical difference along Z.
{ "type": "hole", "diameter": 5.5, "at": { "x": 25, "y": 15 } }
diameternumberrequiredHole diameter in mm.
depthnumberoptionalHole depth in mm. Omit for a through-hole (auto-sized to extend through the part).
atPositionSpecoptionalHole center position. Default is "center".
Transforms
{ "type": "translate", "offset": { "x": 50, "y": 0, "z": 0 } }
{ "type": "rotate", "angles": { "x": 0, "y": 0, "z": 45 } }
{ "type": "scale", "factor": { "x": 2, "y": 2, "z": 1 } }
Patterns
{ "type": "linear_pattern", "direction": {"x": 1, "y": 0, "z": 0}, "count": 5, "spacing": 20 }
{ "type": "circular_pattern", "axis_origin": {"x": 0, "y": 0, "z": 0}, "axis_dir": {"x": 0, "y": 0, "z": 1}, "count": 6, "angle_deg": 360 }
Features
{ "type": "fillet", "radius": 2 }
{ "type": "chamfer", "distance": 1 }
{ "type": "shell", "thickness": 2 }
radiusnumberoptionalFillet blend radius in mm. Default 1.
distancenumberoptionalChamfer distance in mm. Default 1.
thicknessnumberoptionalShell wall thickness in mm. Default 2.
Position Specification
Operations that accept an at parameter support three formats:
Absolute coordinates. An object with x, y, z fields: {"x": 25, "y": 15, "z": 0}.
Named positions. A string referencing a computed position on the base primitive's bounding box:
"center"-- center of the bounding box"top-center"-- center of the top face (max Z)"bottom-center"-- center of the bottom face (min Z)
Percentage coordinates. An object with percentage strings: {"x": "50%", "y": "50%"}. Percentages are relative to the base primitive's bounding box, where 0% is the minimum and 100% is the maximum.
Assembly
The optional assembly block defines a multi-body model with kinematic joints.
Instances
{
"instances": [
{ "id": "base-1", "part": "Base", "position": {"x": 0, "y": 0, "z": 0} },
{ "id": "arm-1", "part": "Arm" }
]
}
idstringrequiredpartstringrequiredparts array).namestringoptionalpositionVec3optionalrotationVec3optionalJoints
{
"joints": [
{
"id": "shoulder",
"parent": "base-1",
"child": "arm-1",
"type": "revolute",
"axis": "z",
"parent_anchor": {"x": 0, "y": 0, "z": 50},
"child_anchor": {"x": 0, "y": 0, "z": 0},
"limits": [-90, 90],
"state": 0
}
]
}
idstringrequiredparentstring | nullrequirednull for world-grounded.childstringrequiredtypestringrequired"fixed", "revolute", "slider", "cylindrical", "ball".axisstring | Vec3optional"x", "y", "z", or a custom vector. Default "z".parent_anchorVec3optionalchild_anchorVec3optionallimits[number, number]optionalstatenumberoptionalGround
groundstringoptionalInstance ID of the fixed reference part. Required for forward kinematics.
Return Value
The tool returns a text response containing the IR document in the requested format. For compact format (default), the response is the compact IR text. For json format, it is a pretty-printed JSON document.
The returned document can be passed directly to inspect_cad, export_cad, or open_in_browser.
Example
{
"parts": [
{
"name": "Bracket",
"primitive": { "type": "cube", "size": {"x": 50, "y": 30, "z": 5} },
"operations": [
{ "type": "hole", "diameter": 5.5, "at": {"x": 10, "y": 15} },
{ "type": "hole", "diameter": 5.5, "at": {"x": 40, "y": 15} },
{ "type": "fillet", "radius": 2 }
],
"material": "aluminum"
}
]
}
This creates a 50x30x5mm aluminum bracket with two M5 clearance holes and 2mm fillets on all edges.