Skip to main content
Glama

cad_run

Build parametric CAD headlessly from a Python script, override declared parameters, and receive validated STL/STEP geometry, renders, and checks for 3D-print workflows.

Instructions

Build parametric CAD headlessly in OS confinement. Read cad_design first: declare literal P = {...} and build() returning a build123d Shape. Supply script OR script_path; parameters overrides saved named values in one call before derived dimensions. Calls wait for the environment’s exclusive execution slot up to their own deadline and report queue_wait_ms. Each call creates a private immutable subfolder under allowed output_dir, never overwriting previous artifacts. The saved .py and .parameters.json are the recovery checkpoint even after cancellation. Returns independently measured geometry, STL/STEP, six orthographic renders, a perspective view and a contact sheet (with next: read the perspective view before the next change), the closest approach between every pair of solids (bodies), problems, what was checked and not checked, and printed: whatever the script wrote with print(), capped at 4000 characters, so a design can report a number it computed; valid means only that the exported geometry is sound, never that the part fits, holds, moves or prints.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "output_dir": "<output_dir>",
      "name": "<name>"
    },
    "name": "cad_run"
  }
}

Input Schema

NameRequiredDescriptionDefault
modeNosolid returns build123d B-rep with STL/STEP; mesh returns trimesh.Trimesh with STL and an explicit unavailable STEP.solid
nameYesPlain file stem for STL, STEP, Python and parameter artifacts.
finalNoMark the selected result. The protected cad-result.json records this flag and all returned validation; select completed final records after restart and still inspect valid/checks.
inputsNoExplicit named files [{name, path}]. Content-addressed immutable input bundles are reused; snapshot_bytes_added/reused report storage. Only the selected declared bundle is exposed to build() as INPUTS[name]; nested path is declared for remote path policy.
scriptNoPython source declaring literal named P parameters and build() returning a Shape.
output_dirYesExisting allowed directory; a unique immutable run subfolder is created beneath it.
parametersNoOverrides for names already declared in P; saved values are retained.
timeout_msNoTotal queue wait, preparation, execution and inspection deadline. Default 120000 ms; cancellation kills the dispatched process group.
script_pathNoAllowed saved .py checkpoint to rebuild or edit instead of resending script.

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv1.1.94
    • changedOutput schema / anyOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "bodies": {
      -        "description": "Solid mode: near pairs of solids screened on tessellations and measured exactly on the STEP where the screen cannot clear them, against a print-in-place clearance from P.print_in_place_clearance_mm or 0.3 mm (touching or overlap only when P.print_in_place is false); touching or overlapping pairs, pairs under the clearance, pairs only screened, solids below the print plate (Z = 0) or above it with no solid under them that reaches it, and labelled bodies that are not exactly one solid.",
      -        "type": "object"
      -      },
      -      "bounds_mm": {
      -        "items": {
      -          "items": {
      -            "type": "number"
      -          },
      -          "type": "array"
      -        },
      -        "type": "array"
      -      },
      -      "checked": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "checks": {
      -        "additionalProperties": {
      -          "type": [
      -            "boolean",
      -            "null"
      -          ]
      -        },
      -        "type": "object"
      -      },
      -      "completed_at": {
      -        "type": "string"
      -      },
      -      "final": {
      -        "type": "boolean"
      -      },
      -      "input_hashes": {
      -        "additionalProperties": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "input_manifest": {
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "additionalProperties": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "lineage_id": {
      -        "type": "string"
      -      },
      -      "mesh_components": {
      -        "type": "integer"
      -      },
      -      "next": {
      -        "description": "What to do before the next change: look at the perspective render.",
      -        "type": "string"
      -      },
      -      "not_checked": {
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "parameters": {
      -        "type": "string"
      -      },
      -      "printed": {
      -        "description": "The script's own print() output from this run, capped at 4000 characters (build.log keeps the rest). The script's words, not a measurement by the engine.",
      -        "type": "string"
      -      },
      -      "problems": {
      -        "description": "Defects found by the checks that valid does not cover (fused or too-close bodies, a severed body, a solid below the plate or starting in mid-air, pairs not measured). Each kind lists up to eight, then a count of the rest. Empty when none were found, which is not a pass on anything listed in not_checked.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "queue_wait_ms": {
      -        "type": "integer"
      -      },
      -      "renders": {
      -        "additionalProperties": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "result_manifest": {
      -        "type": "string"
      -      },
      -      "script": {
      -        "type": "string"
      -      },
      -      "seconds": {
      -        "type": "number"
      -      },
      -      "size_mm": {
      -        "items": {
      -          "type": "number"
      -        },
      -        "type": "array"
      -      },
      -      "snapshot_bytes_added": {
      -        "type": "integer"
      -      },
      -      "snapshot_bytes_reused": {
      -        "type": "integer"
      -      },
      -      "solid_count": {
      -        "type": "integer"
      -      },
      -      "status": {
      -        "const": "completed",
      -        "type": "string"
      -      },
      -      "step": {
      -        "type": [
      -          "string",
      -          "null"
      -        ]
      -      },
      -      "step_unavailable": {
      -        "type": "string"
      -      },
      -      "step_volume_mm3": {
      -        "type": [
      -          "number",
      -          "null"
      -        ]
      -      },
      -      "stl": {
      -        "type": "string"
      -      },
      -      "units": {
      -        "const": "mm",
      -        "type": "string"
      -      },
      -      "valid": {
      -        "type": "boolean"
      -      },
      -      "volume_mm3": {
      -        "type": [
      -          "number",
      -          "null"
      -        ]
      -      }
      -    },
      -    "required": [
      -      "valid",
      -      "status",
      -      "final",
      -      "completed_at",
      -      "lineage_id",
      -      "result_manifest",
      -      "queue_wait_ms",
      -      "snapshot_bytes_added",
      -      "snapshot_bytes_reused",
      -      "script",
      -      "parameters",
      -      "stl",
      -      "step",
      -      "bounds_mm",
      -      "solid_count",
      -      "checks",
      -      "renders"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "code": {
      -        "enum": [
      -          "cad-uv-missing",
      -          "cad-data-volume-refused",
      -          "cad-setup-busy",
      -          "cad-operation-busy",
      -          "cad-queue-timeout",
      -          "cad-not-ready",
      -          "cad-confinement-unavailable",
      -          "cad-disabled",
      -          "cad-failed"
      -        ],
      -        "type": "string"
      -      },
      -      "message": {
      -        "type": "string"
      -      },
      -      "retryable": {
      -        "type": "boolean"
      -      },
      -      "status": {
      -        "const": "error",
      -        "type": "string"
      -      },
      -      "storage": {
      -        "properties": {
      -          "expected_download_bytes": {
      -            "type": "integer"
      -          },
      -          "expected_installed_bytes": {
      -            "type": "integer"
      -          },
      -          "installed_bytes": {
      -            "type": [
      -              "integer",
      -              "null"
      -            ]
      -          },
      -          "measured_at": {
      -            "type": "string"
      -          },
      -          "measurement": {
      -            "const": "allocated-last-setup",
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "expected_download_bytes",
      -          "expected_installed_bytes",
      -          "installed_bytes",
      -          "measurement"
      -        ],
      -        "type": "object"
      -      },
      -      "suggestion": {
      -        "type": "string"
      -      },
      -      "tool": {
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "status",
      -      "code",
      -      "message",
      -      "tool",
      -      "retryable",
      -      "suggestion"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "bodies": {
      +        "description": "Solid mode: near pairs of solids screened on tessellations and measured exactly on the STEP where the screen cannot clear them, against a print-in-place clearance from P.print_in_place_clearance_mm or 0.3 mm (touching or overlap only when P.print_in_place is false); touching or overlapping pairs, pairs under the clearance, pairs only screened, solids below the print plate (Z = 0) or above it with no solid under them that reaches it, and labelled bodies that are not exactly one solid.",
      +        "type": "object"
      +      },
      +      "bounds_mm": {
      +        "items": {
      +          "items": {
      +            "type": "number"
      +          },
      +          "type": "array"
      +        },
      +        "type": "array"
      +      },
      +      "checked": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "checks": {
      +        "additionalProperties": {
      +          "type": [
      +            "boolean",
      +            "null"
      +          ]
      +        },
      +        "type": "object"
      +      },
      +      "completed_at": {
      +        "type": "string"
      +      },
      +      "final": {
      +        "type": "boolean"
      +      },
      +      "input_hashes": {
      +        "additionalProperties": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "input_manifest": {
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "additionalProperties": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "lineage_id": {
      +        "type": "string"
      +      },
      +      "mesh_components": {
      +        "type": "integer"
      +      },
      +      "next": {
      +        "description": "What to do before the next change: look at the perspective render.",
      +        "type": "string"
      +      },
      +      "not_checked": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "parameters": {
      +        "type": "string"
      +      },
      +      "printed": {
      +        "description": "The script's own print() output from this run, capped at 4000 characters (build.log keeps the rest). The script's words, not a measurement by the engine.",
      +        "type": "string"
      +      },
      +      "problems": {
      +        "description": "Defects found by the checks that valid does not cover (fused or too-close bodies, a severed body, a solid below the plate or starting in mid-air, pairs not measured). Each kind lists up to eight, then a count of the rest. Empty when none were found, which is not a pass on anything listed in not_checked.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "queue_wait_ms": {
      +        "type": "integer"
      +      },
      +      "renders": {
      +        "additionalProperties": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "result_manifest": {
      +        "type": "string"
      +      },
      +      "script": {
      +        "type": "string"
      +      },
      +      "seconds": {
      +        "type": "number"
      +      },
      +      "size_mm": {
      +        "items": {
      +          "type": "number"
      +        },
      +        "type": "array"
      +      },
      +      "snapshot_bytes_added": {
      +        "type": "integer"
      +      },
      +      "snapshot_bytes_reused": {
      +        "type": "integer"
      +      },
      +      "solid_count": {
      +        "type": "integer"
      +      },
      +      "status": {
      +        "const": "completed",
      +        "type": "string"
      +      },
      +      "step": {
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "step_unavailable": {
      +        "type": "string"
      +      },
      +      "step_volume_mm3": {
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "stl": {
      +        "type": "string"
      +      },
      +      "three_mf": {
      +        "description": "When build() returned project_3mf(): the written 3MF project, ready for slice_stl.",
      +        "type": "string"
      +      },
      +      "three_mf_project": {
      +        "description": "When build() returned project_3mf(): base (the edited input alias, or null for a new project), changes, and the written file read back as list_3mf_plates reads it (plates with build_items, parts and filaments; project_filaments).",
      +        "type": "object"
      +      },
      +      "units": {
      +        "const": "mm",
      +        "type": "string"
      +      },
      +      "valid": {
      +        "type": "boolean"
      +      },
      +      "volume_mm3": {
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      }
      +    },
      +    "required": [
      +      "valid",
      +      "status",
      +      "final",
      +      "completed_at",
      +      "lineage_id",
      +      "result_manifest",
      +      "queue_wait_ms",
      +      "snapshot_bytes_added",
      +      "snapshot_bytes_reused",
      +      "script",
      +      "parameters",
      +      "stl",
      +      "step",
      +      "bounds_mm",
      +      "solid_count",
      +      "checks",
      +      "renders"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "code": {
      +        "enum": [
      +          "cad-uv-missing",
      +          "cad-data-volume-refused",
      +          "cad-setup-busy",
      +          "cad-operation-busy",
      +          "cad-queue-timeout",
      +          "cad-not-ready",
      +          "cad-confinement-unavailable",
      +          "cad-disabled",
      +          "cad-failed"
      +        ],
      +        "type": "string"
      +      },
      +      "message": {
      +        "type": "string"
      +      },
      +      "retryable": {
      +        "type": "boolean"
      +      },
      +      "status": {
      +        "const": "error",
      +        "type": "string"
      +      },
      +      "storage": {
      +        "properties": {
      +          "expected_download_bytes": {
      +            "type": "integer"
      +          },
      +          "expected_installed_bytes": {
      +            "type": "integer"
      +          },
      +          "installed_bytes": {
      +            "type": [
      +              "integer",
      +              "null"
      +            ]
      +          },
      +          "measured_at": {
      +            "type": "string"
      +          },
      +          "measurement": {
      +            "const": "allocated-last-setup",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "expected_download_bytes",
      +          "expected_installed_bytes",
      +          "installed_bytes",
      +          "measurement"
      +        ],
      +        "type": "object"
      +      },
      +      "suggestion": {
      +        "type": "string"
      +      },
      +      "tool": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "status",
      +      "code",
      +      "message",
      +      "tool",
      +      "retryable",
      +      "suggestion"
      +    ],
      +    "type": "object"
      +  }
      +]
  2. Addedv1.1.93

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations it discloses queueing ('waits for the environment's exclusive execution slot... report queue_wait_ms'), cancellation semantics ('kills the dispatched process group'), non-overwriting immutable subfolders, and recovery checkpoints surviving cancellation. The closing caveat that 'valid means only that the exported geometry is sound, never that the part fits, holds, moves or prints' is exactly the behavioral framing an agent needs, and nothing contradicts destructiveHint=false / idempotentHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded, but the second half is a single dense run-on enumerating return artifacts, the print() cap, and the validity caveat. Given an output schema exists, that enumeration is partially redundant and could be tightened without losing the high-value caveats.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex, stateful, non-idempotent build tool, the description covers prerequisites, input routes, concurrency and deadline behavior, artifact persistence, checkpoint recovery, and the interpretation limits of 'valid'. With an output schema present, it need not further explain return structure.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3, but the description adds real meaning: 'parameters overrides saved named values in one call before derived dimensions,' script vs script_path as equivalent entry points, and output_dir as the parent of a unique immutable run subfolder. Mode-specific return differences (STEP unavailable for mesh) are left to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence names a specific verb and resource with scope: 'Build parametric CAD headlessly in OS confinement,' and the requirement to 'Read cad_design first' plus the declared P/build() contract makes the operation unmistakable. An agent can tell this is the execution/build step rather than a status or fit-check sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states a prerequisite (read cad_design first), an either/or input route ('Supply script OR script_path'), and a follow-up behavior ('next: read the perspective view before the next change'). What is missing is explicit when-not guidance or routing against visible siblings such as cad_check_fit or cad_status.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.