3d-modeling
Skill4 starsChanged 10 months agoMITView on GitHub
Generate 3D printable models using MichelangeloCC. Creates STL files from natural language descriptions through build123d CAD operations. Use this skill when the user wants to create 3D models, generate STL files, or design objects for 3D printing.
3 other projects use a version of this.
Adopted by
Most recently taken up by
- codeonym-oss/design-skillstheir own version, first seen Oct 20, 2026
- jasonkneen/tiny-world-buildertheir own version, first seen Oct 8, 2026
- codeonym-org/codeonym-arch-designtheir own version, first seen Sep 25, 2026
Other versions3 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 3
- jasonkneen/tiny-world-builder★ 1.6ksame name
- codeonym-org/codeonym-arch-design★ 0same name
- codeonym-oss/design-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repositoryOne other file it gives its agents.
- CLAUDE.mdCLAUDE.md
The file
Show its rules and text
We split this skill into the rules it gives an agent
38 rules. 0 are common, 22 are distinctive, and 16 are very specific to this project.
0
Common
Most of the 3 edited versions we read keep these.
22
Distinctive
This author's own choices. Worth a look.
16
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 12
When the user asks you to create a 3D model:
- Distinctive: line 15
Design: - Create model using build123d operations
- Very specific: line 16
Save: - Write the Python script to a .py file
- Very specific: line 17
Preview: - Run mcc preview model <script.py> to visualize
- Very specific: line 18
Validate: - Run mcc validate mesh <script.py> to check printability
- Very specific: line 19
Export: - Run mcc export stl <script.py> -o <output.stl> when ready
- Very specific: line 23
When running in an interactive session started with mcc session, you have a streamlined workflow:
- Distinctive: line 41
Verify: - Check for Python errors before proceeding (see below)
- Very specific: line 43
Export: when satisfied: mcc export stl model.py -o output/model.stl --quality high
- Very specific: line 49
After saving model.py, you MUST check for errors:
- Distinctive: line 56
If the command shows any errors (NameError, SyntaxError, TypeError, etc.):
- Distinctive: line 60
Only then: ask the user for feedback
- Distinctive: line 72
Keep parameters at the top of the file for easy adjustment
- Very specific: line 73
Use the existing model.py structure - don't create new files unless necessary
- Distinctive: line 74
Check the browser preview after each change before asking for feedback
- Very specific: line 75
When finished, always export to output/ folder with high quality
- Distinctive: line 91
Always create Python scripts following this pattern:
- Distinctive: line 297
Default to 3mm minimum wall thickness for strength
- Distinctive: line 298
Add 0.2mm tolerance for mating/sliding parts (holes, slots)
- Distinctive: line 299
Add 0.1mm tolerance for press-fit parts
- Distinctive: line 300
Use fillets (2-3mm) on stress concentration areas
- Distinctive: line 301
Consider print orientation: overhangs should be < 45 degrees
- Distinctive: line 302
Add draft angles (1-2 degrees) for parts that need to release from molds
- Very specific: line 305
Use loft() and sweep() for smooth organic forms
- Very specific: line 306
Use splines (Spline()) for natural curves
- Very specific: line 307
Consider using make_hull() for organic boundaries
- Very specific: line 311
Use shell() to create hollow parts
- Distinctive: line 313
Add screw bosses (cylinders with holes) for assembly
- Distinctive: line 315
Add ventilation slots if needed for electronics
- Distinctive: line 392
If the preview shows "Error loading model", check the terminal for the actual Python error.
- Very specific: line 459
Check for non-manifold geometry (run mcc validate mesh --verbose)
- Distinctive: line 460
Verify boolean operations completed (no floating geometry)
- Very specific: line 461
Use mcc repair auto for automatic fixes
- Distinctive: line 543
Run validation frequently to catch floating parts early:
- Very specific: line 549
Look for the DISCONNECTED_PARTS error message.
- Distinctive: line 550
Check your boolean operations (+, -, &)
- Distinctive: line 551
Verify parts overlap where they should connect
- Distinctive: line 552
Make sure all components are combined into the final model
“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
3D Model Generation with MichelangeloCC
You are an expert 3D modeler using the MichelangeloCC library built on build123d. Generate precise, printable 3D models from user descriptions.
Core Workflow
When the user asks you to create a 3D model:
- Understand - Clarify dimensions, tolerances, and intended use if not specified
- Design - Create model using build123d operations
- Save - Write the Python script to a
.pyfile - Preview - Run
mcc preview model <script.py>to visualize - Validate - Run
mcc validate mesh <script.py>to check printability - Export - Run
mcc export stl <script.py> -o <output.stl>when ready
Interactive Session Mode
When running in an interactive session started with mcc session, you have a streamlined workflow:
Session Context
- Working directory: The session folder (e.g.,
session_20260110_143052/) - Model file:
model.py- This is the main file to edit - Preview: Browser is already open at
http://localhost:8080showing live preview - Output folder:
output/- Place exported STL files here - tmux session: Running inside tmux (detach with
Ctrl+B, D, reattach withtmux attach)
How It Works
The browser shows a live 3D preview of model.py. When you edit and save model.py, the viewer automatically reloads and displays the updated model. This enables rapid iteration without manual refresh.
The file watcher detects all types of file changes including atomic writes (temp file + rename), so preview updates work reliably regardless of how the file is saved.
Session Workflow
- Read the current
model.pyto understand the starting template - Modify
model.pybased on the user's request - Wait - The browser automatically shows the updated model
- Verify - Check for Python errors before proceeding (see below)
- Ask the user for feedback and iterate
- Export when satisfied:
mcc export stl model.py -o output/model.stl --quality high
CRITICAL: Verify Model Before Review
NEVER ask the user to review a model without first verifying it loads correctly.
After saving model.py, you MUST check for errors:
# Run this after every save to check for Python errors
python model.pyIf the command shows any errors (NameError, SyntaxError, TypeError, etc.):
- Read the error message - it tells you exactly what's wrong
- Fix the issue in
model.py - Run
python model.pyagain to verify the fix - Only then ask the user for feedback
Common errors to watch for:
NameError: name 'Scale' is not defined→ Usescale()function insteadSyntaxError→ Check for missing colons, parentheses, quotesTypeError→ Check function arguments match expected typesAttributeError→ Check method/property names are correct
The browser showing "Error loading model" means Python failed. Always check terminal output.
Best Practices in Session Mode
- Make small, incremental changes - easier to debug if something goes wrong
- Keep parameters at the top of the file for easy adjustment
- Use the existing model.py structure - don't create new files unless necessary
- Check the browser preview after each change before asking for feedback
- When finished, always export to
output/folder with high quality
Session Commands
# Export final model (run from session folder)
mcc export stl model.py -o output/model.stl --quality high
# Validate before export
mcc validate mesh model.py --verbose
# Get model info
mcc info model.pyModel Script Structure
Always create Python scripts following this pattern:
"""
Model: [Name]
Description: [Brief description]
Author: Claude Code
Units: mm (millimeters)
"""
from build123d import *
from michelangelocc import MichelangeloModel, ModelMetadata
# === Parameters ===
# Define all dimensions as variables at the top for easy modification
length = 50.0 # mm
width = 30.0 # mm
height = 10.0 # mm
# === Model Construction ===
# Use build123d algebra mode (preferred for most operations)
part = Box(length, width, height)
part -= Cylinder(5, height) # Subtract a hole
# For complex operations, use builder mode:
# with BuildPart() as builder:
# Box(length, width, height)
# with Locations((0, 0, height)):
# Cylinder(5, 10, mode=Mode.SUBTRACT)
# part = builder.part
# === Export ===
model = MichelangeloModel(
part=part,
metadata=ModelMetadata(
name="model_name",
description="Description of the model",
units="mm"
)
)Build123d Quick Reference
Primitive Shapes
Box(length, width, height) # Rectangular prism
Cylinder(radius, height) # Cylinder
Sphere(radius) # Sphere
Cone(bottom_radius, top_radius, height) # Cone or truncated cone
Torus(major_radius, minor_radius) # Donut shapeBoolean Operations (Algebra Mode)
part1 + part2 # Union (combine shapes)
part1 - part2 # Subtraction (cut)
part1 & part2 # IntersectionPositioning and Rotation
Pos(x, y, z) * shape # Translate
Rot(x, y, z) * shape # Rotate (degrees around each axis)
Pos(10, 0, 0) * Rot(0, 0, 45) * Box(5, 5, 5) # CombinedScaling (Non-Uniform)
# Use the scale() FUNCTION - NOT a Scale() class with * operator
scaled = scale(Sphere(10), by=(1, 0.5, 0.5)) # Scale Y and Z to 50%
# Uniform scaling
scaled = scale(Box(10, 10, 10), by=2) # Double size in all directions
# In BuildPart mode:
with BuildPart() as bp:
Sphere(10)
scale(by=(1.5, 1, 0.8)) # Scale current part in place
part = bp.part
# Combined with positioning:
part = Pos(0, 0, 5) * scale(Sphere(10), by=(1, 0.5, 0.5))Mirroring
# Use the mirror() FUNCTION - NOT a Mirror() class
mirrored = mirror(Box(10, 10, 10), about=Plane.XZ) # Mirror about XZ plane
# In BuildPart mode (adds mirrored copy):
with BuildPart() as bp:
Box(10, 10, 10)
mirror(about=Plane.YZ) # Creates symmetric part
part = bp.partEdge Operations
fillet(part.edges(), radius) # Round all edges
fillet(part.edges().filter_by(Axis.Z), radius) # Round vertical edges only
chamfer(part.edges(), distance) # Bevel edges2D to 3D Operations
# Extrude a 2D shape
with BuildPart() as p:
with BuildSketch():
Rectangle(width, height)
Circle(radius) # Adds to sketch
extrude(amount=depth)
# Revolve around axis
with BuildPart() as p:
with BuildSketch(Plane.XZ):
with BuildLine():
Polyline([(0, 0), (10, 0), (10, 20), (0, 20)])
revolve(axis=Axis.Z, revolution_arc=360)
# Loft between profiles
loft([profile1, profile2, profile3])
# Sweep along path
sweep(section=circle_profile, path=spline_path)Sketching (2D Shapes)
with BuildSketch() as s:
Rectangle(width, height)
Circle(radius)
RegularPolygon(radius, n_sides)
Text("Label", font_size=10)Selection and Filtering
part.edges() # All edges
part.faces() # All faces
part.vertices() # All vertices
# Filter by axis
part.edges().filter_by(Axis.Z) # Edges parallel to Z
part.faces().filter_by(Axis.Z) # Faces perpendicular to Z
# Sort and select
part.edges().sort_by(Axis.Z)[-1] # Topmost edge
part.faces().sort_by(Axis.Z)[0] # Bottom face
# Filter by position
part.edges().filter_by(lambda e: e.center().Z > 5)Common Patterns
Hole Pattern (Grid)
for i in range(rows):
for j in range(cols):
part -= Pos(i * spacing, j * spacing, 0) * Cylinder(hole_r, height)Hole Pattern (Circular)
import math
for i in range(num_holes):
angle = i * (360 / num_holes)
x = radius * math.cos(math.radians(angle))
y = radius * math.sin(math.radians(angle))
part -= Pos(x, y, 0) * Cylinder(hole_r, height)Shell (Hollow Part)
# Open top face
top_face = part.faces().sort_by(Axis.Z)[-1]
part = shell(part, amount=-wall_thickness, openings=[top_face])Fillet Specific Edges
# Fillet only top edges
top_edges = part.edges().filter_by(lambda e: e.center().Z > height/2)
part = fillet(top_edges, radius)Counterbore Hole
# Through hole
part -= Cylinder(hole_diameter/2, height)
# Counterbore
part -= Pos(0, 0, height - counterbore_depth) * Cylinder(counterbore_diameter/2, counterbore_depth)Text Embossing/Engraving
with BuildSketch(part.faces().sort_by(Axis.Z)[-1]):
Text("LABEL", font_size=8)
extrude(amount=0.5) # Emboss (raised)
extrude(amount=-0.5) # Engrave (recessed)Design Guidelines
For Mechanical Parts
- Default to 3mm minimum wall thickness for strength
- Add 0.2mm tolerance for mating/sliding parts (holes, slots)
- Add 0.1mm tolerance for press-fit parts
- Use fillets (2-3mm) on stress concentration areas
- Consider print orientation: overhangs should be < 45 degrees
- Add draft angles (1-2 degrees) for parts that need to release from molds
For Organic/Artistic Shapes
- Use
loft()andsweep()for smooth organic forms - Use splines (
Spline()) for natural curves - Consider using
make_hull()for organic boundaries - Higher polygon count is acceptable for artistic pieces
For Enclosures/Cases
- Use
shell()to create hollow parts - Standard wall thickness: 2-3mm
- Add screw bosses (cylinders with holes) for assembly
- Include snap-fit features with 0.3mm interference
- Add ventilation slots if needed for electronics
Units and Tolerances
- Always use millimeters (mm) as the base unit
- Typical 3D printer accuracy: 0.1-0.2mm
- Minimum feature size: 0.4mm (nozzle dependent)
- Layer height typical: 0.1-0.3mm
CLI Commands Reference
# Create new project from template
mcc new my_project --template mechanical
# Preview in browser (with hot-reload)
mcc preview model ./model.py
# Validate for 3D printing
mcc validate mesh ./model.py --verbose
# Export to STL
mcc export stl ./model.py -o ./model.stl --quality high
# Get model info
mcc info ./model.py
# Preview existing STL
mcc preview stl ./model.stl
# Repair broken mesh
mcc repair auto ./broken.stl -o ./fixed.stlQuality Settings for Export
| Quality | Tolerance | Use Case |
| draft | 0.1mm | Quick preview, large models |
| standard | 0.01mm | Most 3D printing |
| high | 0.001mm | Fine detail, small parts |
| ultra | 0.0001mm | Maximum precision |
Common Mistakes to Avoid
Invalid Transformation Operators
CRITICAL: These transformation classes DO NOT exist as * operators:
# WRONG - These will cause "Error loading model"
Scale(1, 0.5, 0.5) * Sphere(10) # NameError: Scale not defined
Mirror() * Box(10, 10, 10) # NameError: Mirror not defined
Transform(...) * shape # Not availableONLY these work with the * operator:
Pos(x, y, z) * shape # Translation - VALID
Rot(x, y, z) * shape # Rotation - VALID
Pos() * Rot() * shape # Combined - VALIDFor scaling and mirroring, use FUNCTIONS:
scale(shape, by=(x, y, z)) # Correct way to scale
mirror(shape, about=Plane.XZ) # Correct way to mirrorTesting Incrementally
Build models step by step to catch errors early:
- Create basic shape → save → check preview works
- Add one transformation → save → verify no errors
- Add boolean operations → save → check geometry
- Add details → save → validate before export
If the preview shows "Error loading model", check the terminal for the actual Python error.
Reference Working Examples
ALWAYS reference these examples when creating similar models. All examples are tested and working - copy patterns from them.
Location: .claude/skills/3d-modeling/examples/
Mechanical Parts
| Example | Key Patterns | Use When |
gear.py | Parametric design, involute curves, derived dimensions, conditional features | Gears, parametric mechanical parts |
bracket.py | Edge filtering, hole patterns, fillets, try/except for complex ops | Mounting brackets, structural parts |
enclosure.py | Shell/offset for hollow parts, mating tolerances, snap-fit lid | Boxes, cases, enclosures |
Household Items
| Example | Key Patterns | Use When |
hook.py | Curved profiles, countersunk holes, load-bearing joints | Hooks, hangers, wall mounts |
phone_stand.py | Angled surfaces (Rot), cable routing holes, stability design | Stands, holders, angled parts |
vase.py | Loft between profiles, easing functions, organic curves | Vases, organic shapes, smooth forms |
Functional Prints
| Example | Key Patterns | Use When |
keychain.py | Text embossing, thin features, ring holes, RectangleRounded | Keychains, tags, labels, thin parts |
Quick Pattern Reference
Shell/Hollow a part:
# From enclosure.py - use offset() with openings
top_face = part.faces().sort_by(Axis.Z)[-1]
offset(amount=-wall_thickness, openings=[top_face])Angled geometry:
# From phone_stand.py - use Rot() for angles
angled_part = Rot(angle, 0, 0) * partText embossing:
# From keychain.py - use Text in BuildSketch
with BuildSketch(top_face):
Text("LABEL", font_size=8)
extrude(amount=1.0) # Positive = emboss, negative = engraveCountersunk holes:
# From hook.py - two-step: through hole + countersink
Cylinder(hole_diameter/2, thickness) # Through hole
Pos(0, 0, 0) * Cylinder(countersink_diameter/2, countersink_depth) # CountersinkMating parts tolerance:
# From enclosure.py - subtract clearance from mating dimension
clearance = 0.3 # mm - for easy fit
inner_size = outer_size - 2 * wall - 2 * clearanceError Handling
If validation fails:
- Check for non-manifold geometry (run
mcc validate mesh --verbose) - Verify boolean operations completed (no floating geometry)
- Use
mcc repair autofor automatic fixes - For severe issues, use
mcc repair auto --aggressive
Common issues:
- NOT_WATERTIGHT: Mesh has holes - check boolean operations
- DEGENERATE_FACES: Zero-area triangles - simplify geometry
- SELF_INTERSECTION: Overlapping faces - check boolean order
- DISCONNECTED_PARTS: Floating geometry - see section below
Avoiding Floating Parts
Floating or disconnected parts are a common issue that makes models unprintable. The validator will report DISCONNECTED_PARTS if your model has separate geometry that isn't connected.
Common Causes
- Boolean operations that don't intersect
# WRONG - cylinder is outside the box, creates floating geometry box = Box(20, 20, 20) hole = Pos(50, 0, 0) * Cylinder(5, 20) # Too far away! result = box - hole # Subtraction has no effect, but may create artifacts - Components with gaps
# WRONG - parts don't touch, will be disconnected base = Box(50, 50, 10) top = Pos(0, 0, 15) * Box(30, 30, 10) # Gap of 5mm! result = base + top # Creates two separate parts - Multiple shapes without union
# WRONG - shapes are created but not combined part1 = Box(20, 20, 10) part2 = Pos(0, 0, 10) * Cylinder(10, 15) # Missing: result = part1 + part2 model = MichelangeloModel(part=part1, ...) # Only uses part1!
Best Practices
- Always union multi-part objects
# RIGHT - explicit union creates single connected solid base = Box(50, 50, 10) pillar = Pos(0, 0, 10) * Cylinder(10, 30) result = base + pillar # Union creates one connected part - Ensure parts overlap for unions
# RIGHT - parts overlap slightly to ensure solid connection base = Box(50, 50, 10) top = Pos(0, 0, 9) * Box(30, 30, 10) # Overlaps by 1mm result = base + top # Creates single watertight solid - Position holes within solid bounds
# RIGHT - hole is inside the box box = Box(50, 50, 20) # Hole at center, ensure it goes through hole = Cylinder(5, 20) # Same height as box result = box - hole # Clean subtraction - Verify dimensions before boolean ops
# Calculate positions based on part dimensions base_height = 10 pillar_height = 30 pillar_radius = 8 base = Box(50, 50, base_height) # Position pillar to start at top of base (with 1mm overlap) pillar = Pos(0, 0, base_height - 1) * Cylinder(pillar_radius, pillar_height) result = base + pillar
Validation During Development
Run validation frequently to catch floating parts early:
mcc validate mesh model.py --verboseLook for the DISCONNECTED_PARTS error message. If it appears:
- Check your boolean operations (+, -, &)
- Verify parts overlap where they should connect
- Make sure all components are combined into the final model
The preview viewer will also show a warning banner if disconnected parts are detected.
Example: Complete Workflow
# 1. User asks for a gear
# 2. Generate the model script (gear.py)
# 3. Preview it
mcc preview model ./gear.py
# 4. Validate
mcc validate mesh ./gear.py --verbose
# 5. If issues, repair
mcc repair auto ./gear.py -o ./gear_fixed.py
# 6. Export final STL
mcc export stl ./gear.py -o ./gear.stl --quality high
# Model is ready for slicing and printing!Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

