Agent skill

Openscad Design

by RobertCoop in RobertCoop/openscad-mcp

Design, modify, and verify 3D-printable parts and assemblies in OpenSCAD through the openscad-mcp tools.

MITAuto-check passedAgent Workflows

Install Openscad Design

skills CLI
$ npx skills add RobertCoop/openscad-mcp --skill openscad-design -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install RobertCoop/openscad-mcp openscad-design --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/RobertCoop/openscad-mcp.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/openscad-design .claude/skills/openscad-design && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
openscad-design
GitHub stars
149
Token cost
~3.9k tokens
SKILL.md length
1,945 words
Files
1
Skills in repo
1
Repo updated
First seen
Licence
MIT

At a glance

Design, modify, and verify 3D-printable parts and assemblies in OpenSCAD through the openscad-mcp tools.

  • Works in 8 steps: State assumptions before writing code → Declare key dimensions as variables → validate(mode="syntax") first → …
  • The user asks for a bracket
  • SKILL.md covers The loop, Worked example: a box with a lid, Reading a render and Gotchas that bite most often, plus 1 more section
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Openscad Design is an agent skill from RobertCoop/openscad-mcp. Design, modify, and verify 3D-printable parts and assemblies in OpenSCAD through the openscad-mcp tools. Use when the user asks for a bracket, enclosure, adapter, jig, or other parametric part, or wants an existing .scad file changed, measured, fit-checked, or exported for printing.

Its SKILL.md is about 3.9k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Agent Workflows, covering MCP servers. The repository describes itself as: A Model Context Protocol (MCP) server for OpenSCAD 3D modeling and rendering. The licence is MIT.

When your agent uses it

  • The user asks for a bracket
  • Other parametric part
  • Wants an existing .scad file changed
  • Exported for printing

Example prompts

  • “/openscad-design”

Workflow steps

8 steps, taken from the step headings in SKILL.md.

  1. State assumptions before writing code
  2. Declare key dimensions as variables
  3. validate(mode="syntax") first
  4. measure before you trust any picture
  5. render(grounded=true), one to three views
  6. Multi-part designs
  7. Iterate by changing a variable and re-measuring
  8. export_model last

What it can do on your machine

Read from SKILL.md and the folder at commit bde0b23. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are openscad).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Openscad Design loads about 3.9k tokens when it runs. Until then it costs about 75 tokens; SKILL.md has 1,945 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~75
When it runs · the whole SKILL.md, loaded when a task matches
~3.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from RobertCoop/openscad-mcp at commit bde0b23, republished under its MIT licence (© RobertCoop). 1,945 words, ~3,860 tokens.

Download SKILL.mdSave it as .claude/skills/openscad-design/SKILL.md (or your agent's skills folder).
name
openscad-design
description
Design, modify, and verify 3D-printable parts and assemblies in OpenSCAD through the openscad-mcp tools. Use when the user asks for a bracket, enclosure, adapter, jig, or other parametric part, or wants an existing .scad file changed, measured, fit-checked, or exported for printing.
license
MIT

OpenSCAD design loop

One rule sits above the rest: numbers decide, pictures confirm. A render is a low-bandwidth summary of geometry. Vision models routinely rate a broken model as fine, because a missing internal wall, a 0.02 mm gap, or a non-manifold seam looks identical to a correct part at 800x600. Never conclude "that looks right" from an image. Conclude it from measure and validate, then use the image to catch the class of error numbers miss: wrong orientation, a feature on the wrong face, a part that is inside-out.

The loop

1. State assumptions before writing code

Say these out loud in one or two lines, because they are invisible in the source and wrong in half of all first attempts:

  • Units: OpenSCAD is unitless; everything here is millimetres.
  • Orientation: which axis is up, and which face sits on the print bed.
  • Datum: where the origin is. Corner-at-origin and centred-on-origin are both fine, but say which, and keep it consistent across parts of an assembly.
  • Print process: FDM layer height and nozzle width if the user has not said, because they set minimum wall and minimum feature size.
2. Declare key dimensions as variables

Every number that the user might change, or that appears more than once, becomes a named variable at the top of the file. Derive the rest with expressions rather than retyping arithmetic. This is what makes step 6 cheap: an iteration becomes one variable edit, not a search-and-replace through solid geometry.

openscad
wall      = 2.4;   // 3 perimeters at 0.8 mm
inner_x   = 60;
inner_y   = 40;
inner_z   = 25;
clearance = 0.2;   // from reference(topic="fits")
eps       = 0.01;  // coplanar-face overlap
3. validate(mode="syntax") first

Before any render or export. OpenSCAD's exit code is not a success signal: a failed assert(), an unknown module, a missing include, and an unclosed polyhedron all exit 0 while printing to stderr. validate parses that stream. Read errors, warnings, and hints on the response. Fix everything in errors before moving on and read every warning, since "Ignoring unknown module" means a whole feature is silently absent from the geometry you are about to measure.

4. measure before you trust any picture

measure(mode="model") exports the mesh and returns exact numbers: bounding box, dimensions, volume, surface area, component count, watertightness. Compare those against the dimensions you intended. A bounding box 0.4 mm larger than expected is a clearance bug you would never see in a render.

measure also accepts an existing STL through mesh=, so you can measure a file the user already has without re-rendering it.

Modes: model for the whole thing, parts for per-solid numbers and the solid count, section for a cut plane, mass for volume-times-density estimates. The rest — probe, features, printability, orientation, anchors — are in the tool reference at the end.

5. render(grounded=true), one to three views

Only after the numbers agree. Ask for the smallest number of views that answers the open question, usually one isometric plus one orthographic view of the face in question. More images degrade the model's own counting and comparison, so a four-view contact sheet is worse than one well-chosen view, not better.

Modes: views for standard camera positions, section for a cut, parts for per-part colouring, compare for before/after.

6. Multi-part designs
  • One module per part. module lid() { ... }, module body() { ... }, and a separate assembly view that translates them into place. Never one monolithic union.
  • Overlap coplanar faces by epsilon. Two solids that exactly touch along a face or an edge produce a non-manifold result that CGAL drops or reports as not 2-manifold. Add eps so the parts genuinely interpenetrate, and subtract eps on through-holes so the cutter pokes out both sides.
  • Get clearances from reference(topic="fits"), not from memory. Press fit, slip fit, and free fit differ by tenths of a millimetre and the right number depends on the process. Related topics: fasteners, inserts, bearings, magnets, joints, dfm, materials, conventions, cheatsheet.
  • Check the solid count. measure(mode="parts") should report exactly as many components as you designed. Two when you expected one means a part is floating free; one when you expected two means they fused and will print as a single lump.
  • Check manifoldness. validate(mode="geometry") returns mesh_health. Look at mesh_health.manifold: true is good, false names the defect in mesh_health.issue, and null means the check was not performed, which is not the same as passing.
6b. Assemblies: name the parts, then ask check

Once a design has more than one part, stop reasoning from pictures and give the server the parts by name. Every part is exported separately (never unioned), so identity survives and every relation is a number in the assembly frame.

check(scad_file="assembly.scad", mode="interference",
      parts=[{"name": "bracket", "code": "bracket();"},
             {"name": "motor", "code": "motor();", "place": "translate(MOTOR_POS)",
              "ghost": true, "mass_g": 34}])
  • state is clear, contact, or interference. Flush contact is contact, never interference; a sliding pair (a pinion on a plate) that reports contact is the defect, so declare motion on the moving part and use contact with kind="sliding".
  • mode="clearance" gives the exact minimum distance and both closest points; mode="motion" sweeps a part about an axis or along a vector and, for a full turn, adds a certificate that says whether the parts can ever touch.
  • mode="alignment" is the only check that sees a 0.6 mm hole misalignment: interference and clearance both read zero there.
  • rule: mass in a check file limits total mass, centre-of-mass offset from an axis or point, and inertia about an axis, composed from the exported meshes with each part's mass_g, material or density_g_cm3 (PLA if none, flagged).
  • Write coordinates and limits in check files as SCAD expressions of the model's parameters (point: "[BOLT_R, 0, BASE_H]", min_mm: "GAP_MIN"), never as copied numbers: a copied number keeps passing after the parameter changes.
  • Every row carries quality.fn. A distance smaller than the tessellation error bound comes back UNRESOLVED; re-run with quality="high" or an integer $fn.
  • measure(mode="probe") answers "is there material at this point, and whose", ray casts ("does the scanner see the card"), and line-of-sight polylines.
  • measure(mode="features") lists the holes a part cuts (axis, diameter, depth, fit name) straight from the CSG tree, and reference(topic="fits", diameter_mm=3.3) names what a hole is.
  • Freeze the rules in a check file (YAML: frames, quality, parts, checks, model) and re-run check(check_file=..., mode="rules") after every edit; openscad-mcp check file.yaml does the same from a Makefile.

Purchased parts. reference(topic="parts") lists the five sourced entries: 28byj-48, nema17, lazy-susan-4in, kw11-3z (snap-action microswitch) and tcrt5000-module. model(action="create", template="part:28byj-48") writes BOSL2 modules with named anchors, a clearance mask for difference(), and a verify[] list of dimensions to confirm on your own motor. The module names come from the entry, not from the id: 28byj-48 gives part_28byj48(), part_28byj48_mask(), part_28byj48_mount_holes_mask() and part_28byj48_info(). Design the pocket from the part's named numbers, then let check prove it: the mask, not a minkowski() grow, is the pocket; hull() of two poses is wrong for an insertion sweep.

Before printing. measure(mode="printability", orientation=[180,0,0]) gives overhang patches with their unsupported reach, the wall-thickness distribution against the nozzle, islands, and a support estimate. mode="orientation" lists candidates but names no winner; you decide by which faces must look good. validate(mode="printability") turns the facts into findings with thresholds.

Show full SKILL.md (810 more words)Show less
7. Iterate by changing a variable and re-measuring

Change one variable, re-run measure, compare the number to the previous number. That is the whole inner loop. Use scad_eval to check a derived expression in the design's own parameter space before you commit to a render: it evaluates expressions against the file's variables and returns typed results, which is far cheaper than rendering to find out that lid_inner came back undef.

8. export_model last

Export only once the numbers and the manifold check pass. STL for printing, 3MF when you want units and metadata preserved.

Worked example: a box with a lid

1. validate(mode="syntax", scad_content=...)
   -> errors: []   warnings: []   hints: []
      Nothing else runs until errors is empty.

2. reference(topic="fits")
   -> pick the slip-fit clearance for a lid over a box; call it 0.2 mm.

3. scad_eval(scad_content=..., expressions=["outer_x", "lid_inner_x"])
   -> confirm lid_inner_x == outer_x + 2*clearance before rendering anything.
      A typed result of undef here means a variable name is wrong.

4. measure(mode="model", scad_content=...)
   -> bbox and dimensions. Check against the intended outside size.
      Check watertight == true.

5. measure(mode="parts", scad_content=...)
   -> components == 2 (body, lid). If it says 1, the lid fused to the body:
      clearance is zero or negative somewhere.

6. validate(mode="geometry", scad_content=...)
   -> mesh_health.manifold == true. If false, read mesh_health.issue; the usual
      cause is two solids meeting exactly on a face. Add eps and repeat.

7. render(mode="views", grounded=true, views=["isometric"], scad_content=...)
   -> read the digest text before the image: confirm the stated bbox matches
      step 4 and the lid sits on top rather than intersecting.

8. export_model(format="3mf", ...)

What to read in every response, in order: errors, then warnings, then hints (these carry the specific repair advice for the message class OpenSCAD emitted), then the payload. On renders and measurements also check cached. A cached: true response is a previous result replayed; if you edited an included file rather than the top-level source and the flag says cached, the number you are looking at may predate your edit. Force a fresh run or clear_cache before believing it.

Reading a render

Every render arrives as a text digest followed by an image. The digest is the part you reason from. It states the units, the up-axis and handedness, the exact camera eye, center, and up vectors, the projection, the view direction in plain language ("camera looks along +Y; +X is right, +Z is up"), the model's bounding box, and the scale in millimetres per pixel.

  • grounded=true gives orthographic projection and a real scale. The stated mm/px is true everywhere in the frame, so you can measure a feature by counting pixels and multiplying. Annotations and a scale bar are drawn into the image.
  • The mm/px guarantee holds only under orthographic projection. Under the default perspective camera the scale varies across the image and no single number describes it.
  • Auto-framed renders have unknown absolute scale. Anything rendered with --viewall fits the model to the frame, so a 2 mm cube and a 500 mm cube come out pixel-identical. Use those images for shape and topology only. If a question is about size, either read the bbox from the digest or ask for grounded=true.

Gotchas that bite most often

Variables are compile-time, not sequential. OpenSCAD assignments are resolved before evaluation, and the last assignment in a scope wins for the whole scope. This does not work:

openscad
h = 10;
if (tall) { h = 20; }   // does not change h outside the if

Use a conditional expression instead: h = tall ? 20 : 10;. The same rule means you cannot accumulate a value in a for loop; build a list and use a function.

difference() order matters. The first child is the base solid and every later child is subtracted from it. Reordering children silently produces a different shape, and a difference() whose first child is smaller than the rest yields nothing at all. When a model renders empty, check this before anything else.

2D and 3D do not mix. square, circle, polygon, offset, and projection produce 2D geometry. cube, cylinder, sphere, and linear_extrude produce 3D. Combining them in one boolean gives "Mixing 2D and 3D objects is not supported" and an unusable result. Extrude first, then combine.

$fn is a global trap. Left unset, curve resolution comes from $fa and $fs. Setting $fn high at the top of the file applies it to every curved primitive at once, which makes exports slow and huge. Set $fn locally on the primitives that need it, or use the server's quality presets, and remember that $fn on a small hole should be low, not high.

import() needs convexity. Without convexity=10 (or higher for complex shapes), imported meshes render with holes and inverted surfaces in preview even though the geometry is fine. The same applies to linear_extrude of complex profiles and to %import("ref.stl", convexity=10) when ghosting a reference part.

Zero-thickness walls and exact touches. Anything with a dimension of exactly 0, or two solids that share a face precisely, produces geometry CGAL cannot resolve. Epsilon overlaps are not a hack here; they are the correct construction.

Tool reference

ToolUse it for
checkinterference, clearance, contact, alignment, motion, rules over named parts; check files (model, quality, frames, parts, checks); exit codes
validatesyntax, geometry, predicates (+sweep), includes (+BOSL2 lint, autofix), printability
measuremodel, parts, section, mass, probe, features, printability, orientation, anchors; existing STL via mesh
renderviews, section, parts, compare; grounded=true for real scale; look_at, callouts
scad_evaltyped evaluation of expressions in the design's parameter space
referencefits (also by diameter or shaft+bore), fasteners, inserts, bearings, magnets, joints, parts, conventions, cheatsheet, dfm, materials
export_modelSTL, 3MF, AMF, OFF, NEF3, DXF, SVG, PDF, CSG; parts= for a named-object 3MF
model`action=create
check_openscadbinary presence, version, capabilities
get_librarieswhat is installed on this machine, and the exact import line
get_project_files.scad files and their references; mode=trace for a constant's dependents
clear_cachewhen a cached result may predate an edit to an included file

© RobertCoop, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/openscad-design of RobertCoop/openscad-mcp.

Open the folder on GitHubat commit bde0b23

Compare with similar skills

Openscad Design next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Openscad Design compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Openscad Design this skillRobertCoop/openscad-mcp149—~3.9kAutomated safety check: PassMIT
MCP Server Builderanthropics/skills180k63 repos~2.3kAutomated safety check: PassApache-2.0
MCP Server BuildershareAI-lab/learn-claude-code78k4 repos~1.2kAutomated safety check: PassMIT
MCP Integration for Pluginsanthropics/claude-plugins-official38k11 repos~3.1kAutomated safety check: PassApache-2.0
Microsoft Skill CreatorMicrosoftDocs/mcp1.9k3 repos~2.1kAutomated safety check: PassCC-BY-4.0
Crush Configurationcharmbracelet/crush29k—~3.7kAutomated safety check: PassCustom licence

Similar skills

  • MCP Server Builder

    anthropics/skills

    Official

    Guides the design and implementation of Model Context Protocol servers in TypeScript or Python, from tool naming and error messages to evaluation.

    180k GitHub starsUsed in 63 repos~2.3k tokens
    Agent WorkflowsAuto-check passed
  • MCP Server Builder

    shareAI-lab/learn-claude-code

    Walks through building MCP servers in Python or TypeScript that expose tools, resources and prompts to Claude, with templates, registration and testing.

    78k GitHub starsUsed in 4 repos~1.2k tokens
    Agent WorkflowsAuto-check passed
  • MCP Integration for Plugins

    anthropics/claude-plugins-official

    Official

    Explains how to bundle Model Context Protocol servers in a Claude Code plugin, covering config files, stdio, SSE, HTTP and WebSocket server types, and authentication.

    38k GitHub starsUsed in 11 repos~3.1k tokens
    Agent WorkflowsAuto-check passed
  • Microsoft Skill Creator

    MicrosoftDocs/mcp

    Official

    Create agent skills for Microsoft technologies using official documentation.

    1.9k GitHub starsUsed in 3 repos~2.1k tokens
    Agent WorkflowsAuto-check passed
  • Crush Configuration

    charmbracelet/crush

    Explains how to configure the Crush coding agent with crushrc or crush.json, covering providers, models, LSPs, MCP servers, hooks, permissions and config precedence.

    29k GitHub stars~3.7k tokensUpdated today
    Agent WorkflowsAuto-check passed
  • Context Mode Output Sandbox

    mksglu/context-mode

    Routes large command, file, API and browser output through context-mode tools so only the needed result enters the agent's context, instead of dumping it via Bash.

    26k GitHub stars~4.1k tokensUpdated today
    Agent WorkflowsAuto-check passed

Categories

Questions about Openscad Design

What does Openscad Design do?

Design, modify, and verify 3D-printable parts and assemblies in OpenSCAD through the openscad-mcp tools. Openscad Design is an agent skill from RobertCoop/openscad-mcp. Design, modify, and verify 3D-printable parts and assemblies in OpenSCAD through the openscad-mcp tools.

When should I use Openscad Design?

Openscad Design fits situations like: the user asks for a bracket; other parametric part; wants an existing .scad file changed; exported for printing.

How do I install Openscad Design in Claude Code?

Run `npx skills add RobertCoop/openscad-mcp --skill openscad-design -a claude-code`. Or copy the skill folder (skills/openscad-design in RobertCoop/openscad-mcp) into .claude/skills/openscad-design in your project. Claude Code loads it when a task matches its description.

How do I install Openscad Design in Codex?

Run `npx skills add RobertCoop/openscad-mcp --skill openscad-design -a codex`. Or copy the skill folder (skills/openscad-design in RobertCoop/openscad-mcp) into .agents/skills/openscad-design in your project. Codex loads it when a task matches its description.

Can I use Openscad Design in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add RobertCoop/openscad-mcp --skill openscad-design -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/openscad-design, .gemini/skills/openscad-design, .github/skills/openscad-design and .opencode/skills/openscad-design in your project.

What does Openscad Design need to run?

SKILL.md names no scripts, command-line tools or credentials: Openscad Design is instructions for the agent only.

Does Openscad Design access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Openscad Design safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Openscad Design use?

Openscad Design is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Openscad Design use?

About 3.9k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Openscad Design?

Skills that share tags, products or a category with Openscad Design: MCP Server Builder (anthropics/skills, 180k stars), MCP Server Builder (shareAI-lab/learn-claude-code, 78k stars), MCP Integration for Plugins (anthropics/claude-plugins-official, 38k stars) and Microsoft Skill Creator (MicrosoftDocs/mcp, 1.9k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Openscad Design?

RobertCoop (a GitHub user) maintains it in RobertCoop/openscad-mcp, which has 149 GitHub stars. The repository was last updated on September 10, 2026.

Source: RobertCoop/openscad-mcp on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.