Skip to main content
Glama

Fit Features to Mesh

mesh_to_features
Read-only

Use this when you are handed an STL, OBJ or 3MF of a mostly prismatic mechanical part (plate, bracket, spacer, flange, housing block) and need an EDITABLE kernelCAD model of it rather than a faceted lib.fromSTL import. Deterministic, measured, self-verifying: it welds and checks the mesh, segments planes and cylinders, picks the extrusion axis, slices each band and fits exact lines / arcs / circles, snaps near-round values (each snap recorded), then emits a readable .kcad.ts with named param()s — a revolve for concentric round stacks, extruded profiles otherwise, .hole()/.holes() for through, blind and counterbored bores (axial and side-drilled), .cutout() for pockets, .fillet() for constant-radius edge blends (radius measured on the sharp edge, edges grouped by radius and picked with the shortest exact edge query), boolean subtractions for what no drilling feature can reach. It then EVALUATES that script and compares it with the mesh: volume IoU (column ray casting) and symmetric surface deviation (max + RMS), over up to 4 refinement passes. Returns { script, ledger, fidelity: { maxDeviationMm, rmsMm, volumeIoU, verdict: faithful | approximate | failed, thresholds }, unmatchedRegions, features, passes }. A fillet or sharp reading is kept by which measures better; variable-radius blends and chamfers are reported, not forced. The verdict is computed from the numbers — faithful needs IoU >= minIoU AND max deviation <= maxDeviationMm AND a watertight mesh AND no unmatched region. Freeform surfaces, tilted planes and side bosses are listed in unmatchedRegions (reference.mesh.freeform-region-unmatched), never silently dropped. The ledger uses fact ids equal to param names, so resolve_assumptions on the written .ledger.json yields paramOverrides for set_param. Pass { out } to write the script and ledger; the mesh itself is never modified. Hosted: give the file as an https:// URL, a data: URI (base64, max 25 MB) or "asset:" from request_upload (when the file is on the user's device).

Input Schema

NameRequiredDescriptionDefault
outNoWrite the emitted script to this .kcad.ts path and the assumption ledger to the sibling .ledger.json.
dataNoMesh bytes as base64 — use when the server cannot see your filesystem.
fileNoPath to a .stl (binary or ASCII), .obj or .3mf mesh. One of file / data is required. Hosted server: cannot read files from your machine — pass `code`, or `project:<slug>` for a saved project. Hosted server: pass an https:// URL, a data: URI, or "asset:<id>" from request_upload — not a path on your machine.
formatNoFormat override; default from the extension or the content.
minIoUNoVolume IoU a faithful verdict requires. Default 0.98.
maxPassesNoRefinement passes, 1–4. Default 4; stops early at the first faithful pass.
maxTrianglesNoRefuse meshes above this triangle count instead of stalling. Default 300000.
maxDeviationMmNoMax surface deviation (mm) a faithful verdict allows. Default max(0.25, 0.1 % of the bbox diagonal).
weldToleranceMmNoVertex weld distance in mm. Default max(1e-4, 1e-6 × bbox diagonal).

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • removedOutput schema / properties
      Removed value: -{
      -  "diagnostics": {
      -    "items": {
      -      "additionalProperties": true,
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  "error": {
      -    "description": "Failure message (failure).",
      -    "type": "string"
      -  },
      -  "errorCode": {
      -    "type": "string"
      -  },
      -  "features": {
      -    "additionalProperties": true,
      -    "description": "Body kind, hole groups, cutouts, boolean remainders, params (success).",
      -    "type": "object"
      -  },
      -  "fidelity": {
      -    "additionalProperties": true,
      -    "description": "Measured fidelity of the returned script (success).",
      -    "properties": {
      -      "maxDeviationMm": {
      -        "description": "Two-sided discrete Hausdorff distance, mesh vs reconstruction.",
      -        "type": "number"
      -      },
      -      "pass": {
      -        "description": "Refinement pass whose script is returned.",
      -        "type": "number"
      -      },
      -      "rmsMm": {
      -        "description": "RMS of the sampled point-to-surface distances.",
      -        "type": "number"
      -      },
      -      "thresholds": {
      -        "additionalProperties": true,
      -        "description": "{ minIoU, maxDeviationMm, approximateIoU } actually applied.",
      -        "type": "object"
      -      },
      -      "verdict": {
      -        "description": "faithful = IoU and deviation within thresholds, watertight mesh, nothing unmatched; approximate = IoU >= 0.85.",
      -        "enum": [
      -          "faithful",
      -          "approximate",
      -          "failed"
      -        ],
      -        "type": "string"
      -      },
      -      "volumeIoU": {
      -        "description": "Volume intersection-over-union by column ray casting.",
      -        "type": "number"
      -      }
      -    },
      -    "required": [
      -      "maxDeviationMm",
      -      "rmsMm",
      -      "volumeIoU",
      -      "verdict"
      -    ],
      -    "type": "object"
      -  },
      -  "ledger": {
      -    "additionalProperties": true,
      -    "description": "AssumptionLedger { facts, unresolvedCount }; dimension fact ids equal the param names (success).",
      -    "type": "object"
      -  },
      -  "mesh": {
      -    "additionalProperties": true,
      -    "description": "Clean-up and watertightness report for the input mesh.",
      -    "type": "object"
      -  },
      -  "notRepresented": {
      -    "items": {
      -      "type": "string"
      -    },
      -    "type": "array"
      -  },
      -  "ok": {
      -    "type": "boolean"
      -  },
      -  "passes": {
      -    "description": "Per-pass tolerances and measured fidelity.",
      -    "items": {
      -      "additionalProperties": true,
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  "reconstructedHoles": {
      -    "description": "Holes the B-rep hole detector finds on the reconstruction.",
      -    "items": {
      -      "additionalProperties": true,
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  "script": {
      -    "description": "The emitted, evaluable .kcad.ts source (success).",
      -    "type": "string"
      -  },
      -  "unmatchedRegions": {
      -    "description": "Surface regions no emitted feature represents: { kind, reason, areaMm2, triangleCount, centroid, bbox }.",
      -    "items": {
      -      "additionalProperties": true,
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  "written": {
      -    "additionalProperties": true,
      -    "description": "{ script, ledger } paths when out was given.",
      -    "type": "object"
      -  }
      -}
    • removedOutput schema / required
      Removed value: -[
      -  "ok"
      -]
  2. Changed1 schema field changed
    • changedInput schema / properties / file / description
      Previous value: -"Path to a .stl (binary or ASCII), .obj or .3mf mesh. One of file / data is required. Hosted server: cannot read files from your machine — pass `code`, or `project:<slug>` for a saved project."New value: +"Path to a .stl (binary or ASCII), .obj or .3mf mesh. One of file / data is required. Hosted server: cannot read files from your machine — pass `code`, or `project:<slug>` for a saved project. Hosted server: pass an https:// URL, a data: URI, or \"asset:<id>\" from request_upload — not a path on your machine."
  3. Changed1 schema field changed
    • changedInput schema / properties / file / description
      Previous value: -"Path to a .stl (binary or ASCII), .obj or .3mf mesh. One of file / data is required."New value: +"Path to a .stl (binary or ASCII), .obj or .3mf mesh. One of file / data is required. Hosted server: cannot read files from your machine — pass `code`, or `project:<slug>` for a saved project."
  4. Added

TDQS

A4.1/5.0
Behavior2/5

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

Behaviourally the description is extremely candid (pipeline stages, deterministic self-verification, verdict thresholds, early stop, refusal above maxTriangles, mesh never modified). However, it explicitly says 'Pass { out } to write the script and ledger', which conflicts with the declared readOnlyHint=true; because that contradiction is material to how an agent judges side effects, the otherwise-rich disclosure is penalised.

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?

Front-loaded with the usage trigger, but the body is one very long sentence piling the whole pipeline, output shape and verdict logic together, plus a dense tail on ledger integration. Every claim is relevant, yet the wall-of-text form makes it harder to scan than it needs to be; bullet or sentence breaks would cost nothing.

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, multi-stage tool this covers what an agent must know: input modes, what is produced, the fidelity verdict definition, failure handling (unmatchedRegions) and the downstream handoff (resolve_assumptions → set_param). An output schema exists, so the enumerated return fields are redundant but the verdict semantics still add real value.

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 100%, so baseline is 3; the description still adds meaning beyond it — `out` writes the script plus a sibling .ledger.json, the ledger's fact ids equal param names so resolve_assumptions yields paramOverrides for set_param, and the file input accepts URL/data URI/asset:<id> on hosted servers. Threshold parameters (minIoU, maxDeviationMm) are also tied to the concrete verdict rule.

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?

States a specific verb+resource (fit features to a triangle mesh and emit an editable kernelCAD script) and scopes it to concrete inputs (STL/OBJ/3MF of mostly prismatic mechanical parts). It explicitly contrasts with the sibling behaviour it is not ('rather than a faceted lib.fromSTL import' / import_step), so an agent can pick it without opening another schema.

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

Usage Guidelines5/5

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

Opens with an explicit trigger ('Use this when you are handed an STL, OBJ or 3MF of a mostly prismatic mechanical part and need an EDITABLE kernelCAD model') and names the excluded case (freeform surfaces, tilted planes, side bosses go to unmatchedRegions). It also tells the agent how to supply input on a hosted server (https URL, data: URI, asset:<id>), which is the real routing decision for this tool.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.