Skip to content

A guide for AI agents

This page is part of the Moket skill: it is written for AI agents, which read it as Markdown. Values in angle brackets in the examples stand for ids an agent gets from Moket.

Parts ​

A part is a parametric document: named parameters (expressions with units), an ordered history of features, and the solid bodies the features build. The history rebuilds from the parameters, so a part you build stays editable by hand: build it the way a careful engineer would, with parameters for the sizes that matter and features in a sensible order.

On a part use inspect_document, get_feature, get_sketch, query_geometry, measure and get_selection. Read Working with plans first.

Parameters ​

  • parameter.create with a name and an expression: {"type":"parameter.create","id":"$t","name":"wallThickness","expression":"5 mm"}. Names are identifiers; expressions use units (mm, cm, m, in, ft, deg, rad), other parameters, pi and the functions sqrt, abs, min, max, floor, ceil, round, sin, cos, tan, asin, acos, atan and atan2.
  • parameter.update changes an expression by id. Every feature that reads the parameter follows.
  • Sizes several documents share come from the project's table as project.<name> (see Project parameters); never repeat a number another document owns.

Features ​

feature.create adds a feature after the rollback marker: {"type":"feature.create","id":"$f","featureType":"core.extrude","name":"Base","params":{...}}. Read a feature type with describe_commands before its first use; feature.update replaces all params, so send the complete object from get_feature with your changes.

FeatureWhat it does
core.sketchA 2D sketch on a plane; see Sketches. Prefer the sketch.template plan helper.
core.extrudeExtrudes a sketch's closed regions: operation new (with a new body id), join, cut or intersect (with targets); direction normal, reversed or symmetric; extent through for cuts.
core.revolveRevolves a sketch about a construction line of it, an origin axis or an edge; angle "360 deg" for a full turn.
core.holeHoles at a sketch's points: simple, counterbore or countersink, through or to a depth, tapped with thread.
core.fillet, core.chamferRounds or bevels edges of one body by name.
core.shellHollows a body with open faces and a wall thickness.
core.draftTilts faces by an angle about a neutral plane, for molded parts.
core.sweep, core.loftA profile along a path; a solid through profiles.
core.patternRepeats features linearly or around an axis.
core.mirrorCopies features or bodies across a plane.
core.combineJoin, cut or intersect bodies.
core.planeA construction plane, offset from a plane or a face.
core.thread, core.coil, core.knurlThreads on round faces, springs and coils, knurls.
core.importSolids of a STEP file, made by people only.

feature.delete, feature.rename, feature.suppress and feature.move ({"type":"feature.move","id":<feature>,"after":<feature>}, "after":"start" for first) change the history; timeline.setMarker rolls it back for a look. A feature cannot move before what it uses.

Names of faces and edges ​

Faces and edges are referenced by topological names ({"kind":"face","name":"f(...)"}, {"kind":"edge","name":"e(...)"}) that survive rebuilds: they name the feature and the sketch curve that made each face, not a number. Get them from query_geometry (filter by type, size, position or the feature that made them), measure or get_selection.

In the same plan you can name faces of features you create from their placeholders, in these forms:

  • an extrude's start and end faces: f($base:start), f($base:end); a side face from a sketch line: f($base:side:<line id>) (the template answer lists line ids);
  • an edge between two faces: e(<face>|<face>), the two names sorted.

Never invent any other name or edit one.

Building a part ​

  1. Name it (document.rename) and set its material (document.setMaterial, for mass) in the first plan.
  2. Create the parameters, then the base solid, then the features that cut and add, then the finishing touches (fillets, chamfers) last: a fillet before a cut is often cut away.
  3. Put the origin where the part meets others: the face that sits on the base at Z = 0, a shaft's axis on Z. Assemblies and drawings are easier for it.
  4. Check sizes with measure and add checks to the plan for what the user stated.
json
{
  "summary": "Mounting plate 100 x 60 x 8 with four M5 clearance holes",
  "steps": [
    {
      "label": "Name, material and parameters",
      "commands": [
        { "type": "document.rename", "name": "Mounting plate" },
        { "type": "document.setMaterial", "material": "aluminum-6061" },
        {
          "type": "parameter.create",
          "id": "$width",
          "name": "width",
          "expression": "100 mm"
        },
        {
          "type": "parameter.create",
          "id": "$depth",
          "name": "depth",
          "expression": "60 mm"
        },
        {
          "type": "parameter.create",
          "id": "$thickness",
          "name": "thickness",
          "expression": "8 mm"
        },
        {
          "type": "parameter.create",
          "id": "$inset",
          "name": "holeInset",
          "expression": "10 mm"
        }
      ]
    },
    {
      "label": "Plate, its top face at Z = 0",
      "commands": [
        {
          "type": "sketch.template",
          "id": "$outline",
          "name": "Outline",
          "template": {
            "kind": "rectangle",
            "width": "width",
            "depth": "depth",
            "plane": { "kind": "origin", "plane": "XY" }
          }
        },
        {
          "type": "feature.create",
          "id": "$base",
          "featureType": "core.extrude",
          "name": "Plate",
          "params": {
            "sketch": "$outline",
            "operation": "new",
            "body": "$plate",
            "distance": "thickness",
            "direction": "reversed"
          }
        }
      ]
    },
    {
      "label": "Four holes 10 mm in from the edges",
      "commands": [
        {
          "type": "sketch.template",
          "id": "$corners",
          "name": "Hole centers",
          "template": {
            "kind": "points",
            "points": [
              {
                "x": "-(width / 2 - holeInset)",
                "y": "-(depth / 2 - holeInset)"
              },
              { "x": "width / 2 - holeInset", "y": "-(depth / 2 - holeInset)" },
              { "x": "width / 2 - holeInset", "y": "depth / 2 - holeInset" },
              { "x": "-(width / 2 - holeInset)", "y": "depth / 2 - holeInset" }
            ],
            "plane": { "kind": "origin", "plane": "XY" }
          }
        },
        {
          "type": "feature.create",
          "id": "$holes",
          "featureType": "core.hole",
          "name": "Mounting holes",
          "params": {
            "sketch": "$corners",
            "targets": ["$plate"],
            "type": "simple",
            "diameter": "5.5 mm",
            "extent": "through"
          }
        }
      ]
    }
  ],
  "checks": [
    {
      "label": "Plate volume",
      "quantity": "volume",
      "a": { "kind": "body", "body": "$plate" },
      "min": 47200,
      "max": 47280
    }
  ]
}

A turned part is a profile revolved about its axis. Draw half of its outline on the XZ plane with the axis on Z:

json
{
  "summary": "Shaft Ø20 x 60 stepping down to Ø15 x 40",
  "steps": [
    {
      "label": "Shaft",
      "commands": [
        { "type": "document.rename", "name": "Stepped shaft" },
        { "type": "document.setMaterial", "material": "steel" },
        {
          "type": "sketch.template",
          "id": "$half",
          "name": "Half profile",
          "template": {
            "kind": "profile",
            "corners": [
              { "x": "0 mm", "y": "0 mm" },
              { "x": "10 mm", "y": "0 mm" },
              { "x": "10 mm", "y": "60 mm" },
              { "x": "7.5 mm", "y": "60 mm" },
              { "x": "7.5 mm", "y": "100 mm" },
              { "x": "0 mm", "y": "100 mm" }
            ],
            "plane": { "kind": "origin", "plane": "XZ" }
          }
        },
        {
          "type": "feature.create",
          "id": "$turn",
          "featureType": "core.revolve",
          "name": "Shaft",
          "params": {
            "sketch": "$half",
            "axis": { "kind": "axis", "axis": "Z" },
            "angle": "360 deg",
            "direction": "normal",
            "operation": "new",
            "body": "$shaft"
          }
        }
      ]
    }
  ]
}

Holes ​

A hole drills against its sketch plane's normal from the sketch's points: from XY down (-Z), from XZ toward +Y, from YZ toward -X, from a face into the body. Sketch the points on the face the hole starts from ("plane":{"kind":"face","ref":{"kind":"face","name":<name>}}), any face of any orientation, and the hole goes into the body; no offset plane is needed. From a plane outside the body facing away from it, set "flip": true. A hole that reaches no body fails with HOLE_MISSES_BODY.

  • Clearance holes for screws: M3 3.4 mm, M4 4.5 mm, M5 5.5 mm, M6 6.6 mm, M8 9 mm (medium fit).
  • Tapped holes: "thread":{"standard":"iso-coarse","size":"M4"} drills the tap drill (3.3 mm for M4) and puts a cosmetic thread on the wall; give a depth a little longer than the screw's engagement. A lead screw's nut: {"standard":"iso-trapezoidal","size":"Tr12x3"} (drilled to 9 mm), with starts and leftHanded as the screw has them. Bought trapezoidal nuts (DIN 103 hex, the T8 flanged nut) are in find_standard_part.
  • Counterbores and countersinks take their diameter and depth or angle (countersinkDiameter, countersinkAngle).
  • Patterns of holes: the points of one sketch, or core.pattern over the hole feature.

Fillets, chamfers and finishing ​

  • core.fillet and core.chamfer take edges of one body by name: find them with query_geometry (for example the edges of the top face, or the edges of a given length) and pass {"kind":"edge","name":<name>} for each.
  • Fillet and chamfer last. A shell fails when the wall is as thick as a fillet radius or more (SHELL_THICKER_THAN_FILLET): shell before filleting, or keep the wall thinner.
  • Mirror copies extrudes, revolves and holes across a plane, and the copies follow the originals (mode features); fillets and chamfers alone cannot be mirrored (MIRROR_EMPTY): mirror the feature they sit on, then fillet the copy. Mode bodies mirrors whole bodies.

Shell, draft, sweep and loft ​

  • Shell hollows a body: pick the faces to open (none for a closed hollow body) and a wall thickness, inside by default. The inner walls are named f(<shell>:shell:<outer face>).
  • Draft tilts faces (usually the sides) by an angle about a neutral plane, so a molded part comes out along the pull; faces keep their names. Draft before fillets and shell.
  • Sweep moves a closed profile of one sketch along a path: curves of another sketch (lines, arcs and splines joined end to end, drawn so the path starts at the profile) and/or model edges. Sharp corners are mitred; a profile with holes needs a path without sharp corners. A broken path fails with PATH_NOT_CONNECTED naming the gap.
  • Loft builds a solid through two or more profiles in order: one closed region per sketch (sketches on construction planes at different heights) or flat faces of bodies; smooth or ruled. Profiles cannot have holes.

Threads, coils and knurls ​

  • core.thread goes on a cylindrical face: standard iso-coarse, iso-fine, unc or unf, or for lead screws and their nuts iso-trapezoidal (Tr12x3) or acme (1/2-10); the size follows the face unless given (pitch picks among sizes of one diameter: Tr16x4 or Tr16x2); the full face or a length. "starts":"4" makes a multi-start thread (lead = starts x pitch: a 3D printer's Tr8x8(P2) is Tr8x2 with 4 starts) and "leftHanded":true a left-hand one; a screw and its nut must agree on both to stay out of interference. A Tr or ACME nut is drilled to d - P (a tapped hole's thread does it). Cosmetic by default (no geometry change, shown on the face, named in STEP, and a library screw in a tapped hole stays out of interference); "modeled": true cuts the helical groove and is slow. side (internal for a nut or tapped bore, external for a screw) follows the face, so set it only to overrule it. class names the tolerance class and defaults to the usual one: 6g/6H for ISO metric, 2A/2B for UNC and UNF, 7e/7H for Tr, 2G for ACME.
  • core.coil winds a circle, square or triangle around a sketch circle's axis: turns and pitch, height and turns, or height and pitch; taper; ground ends. Springs are coils.
  • core.knurl puts straight or diamond grooves on round faces, cosmetic or modeled (KNURL_HEAVY above 2000 faces).

Configurations ​

Configurations are named variants of one part (sizes, lengths, features built or suppressed): a table whose columns are parameters and features and whose first row is the default; an empty cell takes the default's value. Build the part once with parameters, then add rows instead of copying the part:

  1. configuration.create with the columns ({"kind":"parameter","id":<parameter>}, {"kind":"feature","id":<feature>}) starts the table with a default row of the current values.
  2. configuration.addRow adds a named row with the cells that differ ({"values":{<column id>:"10 mm"}}; placeholders of the same plan work as keys).
  3. The part always is its active row: parameter.update and feature.suppress on a configured column change that row; configuration.activate switches rows.

Export (STEP, STL) builds the active row. For a file of each variant the user exports, switches the row (Part properties > Configuration) and exports again; you can switch it with configuration.activate when the user asks. In an assembly every component has its own row, so switching the part's changes no assembly.

Name rows as the maker or the standard names the sizes (M3 x 8, MGN12H). inspect_document lists the table.

Material and appearance ​

  • document.setMaterial sets every body's material (mass, density); body.setMaterial one body's. Materials: generic, steel, stainless-steel, aluminum-6061, cast-aluminum, cast-iron, brass, bronze, copper, titanium, epoxy-granite, abs, pla, petg, nylon, acetal, oak, nbr (describe_commands on document.setMaterial has the current list).
  • Appearance is not geometry and never rebuilds: document.setAppearance for the whole part, body.setAppearance for a body, body.setFaceAppearance for faces by name; the finest one set wins, and without any each body shows its material's default. Set a material for mass and an appearance for looks.

Pictures ​

get_view_image returns a picture of the open document when the user has turned on Send viewport images to AI; otherwise it says so, and you tell the user where to turn it on if a picture would help. Use it to compare the model with a photo or a sketch the user describes, never instead of measuring.

Imported solids ​

core.import steps are made by people (you cannot upload files): imported bodies have no history, their faces are named i(<step>:<surface>:...) from their geometry and work like any other reference (sketch on them, cut, fillet, shell). Never change an Import step's file or solids; IMPORT_FILE_MISSING, IMPORT_UNREADABLE, IMPORT_NOT_SOLID and IMPORT_PARTIAL are for the user to fix by choosing the file again.

Moket Help