openscad-mcp 0.6.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. openscad_mcp-0.6.1/.claude-plugin/marketplace.json +15 -0
  2. openscad_mcp-0.6.1/.claude-plugin/plugin.json +22 -0
  3. openscad_mcp-0.6.1/.gitignore +199 -0
  4. openscad_mcp-0.6.1/AGENTS.md +56 -0
  5. openscad_mcp-0.6.1/LICENSE +21 -0
  6. openscad_mcp-0.6.1/PKG-INFO +559 -0
  7. openscad_mcp-0.6.1/README.md +509 -0
  8. openscad_mcp-0.6.1/evals/README.md +158 -0
  9. openscad_mcp-0.6.1/mcp-config.json +8 -0
  10. openscad_mcp-0.6.1/pyproject.toml +189 -0
  11. openscad_mcp-0.6.1/skills/openscad-design/SKILL.md +283 -0
  12. openscad_mcp-0.6.1/src/openscad_mcp/__init__.py +28 -0
  13. openscad_mcp-0.6.1/src/openscad_mcp/__main__.py +11 -0
  14. openscad_mcp-0.6.1/src/openscad_mcp/analysis.py +1574 -0
  15. openscad_mcp-0.6.1/src/openscad_mcp/assembly.py +614 -0
  16. openscad_mcp-0.6.1/src/openscad_mcp/camera.py +766 -0
  17. openscad_mcp-0.6.1/src/openscad_mcp/checks.py +837 -0
  18. openscad_mcp-0.6.1/src/openscad_mcp/csgfeatures.py +1426 -0
  19. openscad_mcp-0.6.1/src/openscad_mcp/diagnostics.py +472 -0
  20. openscad_mcp-0.6.1/src/openscad_mcp/geom.py +2395 -0
  21. openscad_mcp-0.6.1/src/openscad_mcp/massprops.py +631 -0
  22. openscad_mcp-0.6.1/src/openscad_mcp/mesh.py +943 -0
  23. openscad_mcp-0.6.1/src/openscad_mcp/parts/28byj-48.scad +229 -0
  24. openscad_mcp-0.6.1/src/openscad_mcp/parts/README.md +114 -0
  25. openscad_mcp-0.6.1/src/openscad_mcp/parts/kw11-3z.scad +196 -0
  26. openscad_mcp-0.6.1/src/openscad_mcp/parts/lazy-susan-4in.scad +189 -0
  27. openscad_mcp-0.6.1/src/openscad_mcp/parts/nema17.scad +196 -0
  28. openscad_mcp-0.6.1/src/openscad_mcp/parts/tcrt5000-module.scad +179 -0
  29. openscad_mcp-0.6.1/src/openscad_mcp/parts_catalog.py +1136 -0
  30. openscad_mcp-0.6.1/src/openscad_mcp/printability.py +1557 -0
  31. openscad_mcp-0.6.1/src/openscad_mcp/reference.py +1666 -0
  32. openscad_mcp-0.6.1/src/openscad_mcp/server.py +5154 -0
  33. openscad_mcp-0.6.1/src/openscad_mcp/threemf.py +710 -0
  34. openscad_mcp-0.6.1/src/openscad_mcp/types.py +201 -0
  35. openscad_mcp-0.6.1/src/openscad_mcp/utils/__init__.py +7 -0
  36. openscad_mcp-0.6.1/src/openscad_mcp/utils/config.py +445 -0
  37. openscad_mcp-0.6.1/src/openscad_mcp/wrappers.py +491 -0
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "openscad-mcp",
3
+ "owner": {
4
+ "name": "Coop",
5
+ "url": "https://github.com/robertcoop"
6
+ },
7
+ "description": "OpenSCAD tooling for AI assistants: rendering, measurement, validation, and export, plus a design skill for 3D-printable parts.",
8
+ "plugins": [
9
+ {
10
+ "name": "openscad-mcp",
11
+ "source": "./",
12
+ "description": "OpenSCAD rendering, measurement, validation, and export as MCP tools, plus the openscad-design skill."
13
+ }
14
+ ]
15
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
+ "name": "openscad-mcp",
4
+ "displayName": "OpenSCAD MCP",
5
+ "version": "0.6.1",
6
+ "description": "Render, measure, validate, and export OpenSCAD models from Claude Code, with a skill that teaches the measure-before-you-look design loop for 3D-printable parts.",
7
+ "author": {
8
+ "name": "Coop",
9
+ "url": "https://github.com/robertcoop"
10
+ },
11
+ "homepage": "https://github.com/robertcoop/openscad-mcp#readme",
12
+ "repository": "https://github.com/robertcoop/openscad-mcp",
13
+ "license": "MIT",
14
+ "keywords": [
15
+ "openscad",
16
+ "cad",
17
+ "3d-printing",
18
+ "mcp",
19
+ "rendering"
20
+ ],
21
+ "mcpServers": "./mcp-config.json"
22
+ }
@@ -0,0 +1,199 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ # ...but src/openscad_mcp/parts/ is the purchased-parts catalog, not a build
21
+ # artifact. It is package data that parts_catalog.py reads at runtime, so it
22
+ # must be tracked and must ship in the wheel.
23
+ !src/openscad_mcp/parts/
24
+ sdist/
25
+ var/
26
+ wheels/
27
+ share/python-wheels/
28
+ *.egg-info/
29
+ .installed.cfg
30
+ *.egg
31
+ MANIFEST
32
+
33
+ # PyInstaller
34
+ # Usually these files are written by a python script from a template
35
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
36
+ *.manifest
37
+ *.spec
38
+
39
+ # Installer logs
40
+ pip-log.txt
41
+ pip-delete-this-directory.txt
42
+
43
+ # Unit test / coverage reports
44
+ htmlcov/
45
+ .tox/
46
+ .nox/
47
+ .coverage
48
+ .coverage.*
49
+ .cache
50
+ nosetests.xml
51
+ coverage.xml
52
+ *.cover
53
+ *.py,cover
54
+ .hypothesis/
55
+ .pytest_cache/
56
+ cover/
57
+
58
+ # Translations
59
+ *.mo
60
+ *.pot
61
+
62
+ # Django stuff:
63
+ *.log
64
+ local_settings.py
65
+ db.sqlite3
66
+ db.sqlite3-journal
67
+
68
+ # Flask stuff:
69
+ instance/
70
+ .webassets-cache
71
+
72
+ # Scrapy stuff:
73
+ .scrapy
74
+
75
+ # Sphinx documentation
76
+ docs/_build/
77
+
78
+ # PyBuilder
79
+ .pybuilder/
80
+ target/
81
+
82
+ # Jupyter Notebook
83
+ .ipynb_checkpoints
84
+
85
+ # IPython
86
+ profile_default/
87
+ ipython_config.py
88
+
89
+ # pyenv
90
+ # For a library or package, you might want to ignore these files since the code is
91
+ # intended to run in multiple environments; otherwise, check them in:
92
+ .python-version
93
+
94
+ # pipenv
95
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
96
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
97
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
98
+ # install all needed dependencies.
99
+ #Pipfile.lock
100
+
101
+ # poetry
102
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
103
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
104
+ # commonly ignored for libraries.
105
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
106
+ #poetry.lock
107
+
108
+ # pdm
109
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
110
+ #pdm.lock
111
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
112
+ # in version control.
113
+ # https://pdm.fming.dev/#use-with-ide
114
+ .pdm.toml
115
+
116
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
117
+ __pypackages__/
118
+
119
+ # Celery stuff
120
+ celerybeat-schedule
121
+ celerybeat.pid
122
+
123
+ # SageMath parsed files
124
+ *.sage.py
125
+
126
+ # Environments
127
+ .env
128
+ .venv
129
+ env/
130
+ venv/
131
+ ENV/
132
+ env.bak/
133
+ venv.bak/
134
+ test-env/
135
+
136
+ # Spyder project settings
137
+ .spyderproject
138
+ .spyproject
139
+
140
+ # Rope project settings
141
+ .ropeproject
142
+
143
+ # mkdocs documentation
144
+ /site
145
+
146
+ # mypy
147
+ .mypy_cache/
148
+ .dmypy.json
149
+ dmypy.json
150
+
151
+ # Pyre type checker
152
+ .pyre/
153
+
154
+ # pytype static type analyzer
155
+ .pytype/
156
+
157
+ # Cython debug symbols
158
+ cython_debug/
159
+
160
+ # PyCharm
161
+ .idea/
162
+
163
+ # VS Code
164
+ .vscode/
165
+ *.code-workspace
166
+
167
+ # macOS
168
+ .DS_Store
169
+
170
+ # Windows
171
+ Thumbs.db
172
+ ehthumbs.db
173
+
174
+ # OpenSCAD specific
175
+ *.scad.bak
176
+ *.stl
177
+ *.3mf
178
+ *.amf
179
+ *.dxf
180
+ *.svg
181
+ *.csg
182
+ renders/
183
+ temp/
184
+
185
+ # Project specific
186
+ /tmp/
187
+ /temp/
188
+ /cache/
189
+ *.png
190
+ *.jpg
191
+ *.jpeg
192
+ *.gif
193
+ !docs/images/**
194
+ test_output/
195
+ # Claude Code / Impeccable local caches
196
+ .impeccable/
197
+
198
+ # Local research notes (not published)
199
+ docs/research/
@@ -0,0 +1,56 @@
1
+ # AGENTS.md
2
+
3
+ Agent brief for the OpenSCAD MCP server. Claude Code should read the richer
4
+ `skills/openscad-design/SKILL.md` instead.
5
+
6
+ A Model Context Protocol server wrapping the OpenSCAD CLI: it renders `.scad` source
7
+ to images, exports meshes, and returns exact geometric measurements. OpenSCAD must be
8
+ installed on the host. Everything is in millimetres; OpenSCAD itself is unitless.
9
+
10
+ ## Tools
11
+
12
+ | Tool | What it does |
13
+ |---|---|
14
+ | `render` | Images. `mode=views\|section\|parts\|compare`. `grounded=true` gives an orthographic render with a stated mm/px scale and drawn annotations. |
15
+ | `measure` | Exact numbers from the exported mesh. `mode=model\|parts\|section\|mass\|probe\|features\|printability\|orientation\|anchors`: bounding box, volume, area, component count, watertightness, point-in-solid probes, holes read off the CSG tree. Also takes an existing STL via `mesh`. |
16
+ | `check` | Relations between named parts of an assembly. `mode=interference\|clearance\|contact\|alignment\|motion\|rules`. Each part is exported separately, so identity survives; `mode=rules` runs a YAML check file and returns an exit code. |
17
+ | `validate` | `mode=syntax\|geometry\|predicates\|includes\|printability`. Diagnostics parsed from stderr, never from the exit code. |
18
+ | `scad_eval` | Evaluates expressions in the design's own parameter space, returning typed values. |
19
+ | `reference` | Shipped engineering data: fits, fasteners, inserts, bearings, magnets, joints, parts, conventions, cheatsheet, dfm, materials. |
20
+ | `export_model` | STL, 3MF, AMF, OFF, NEF3, DXF, SVG, PDF, CSG. `parts=` writes one named-object 3MF. |
21
+ | `check_openscad` | Binary presence, version, capabilities. |
22
+ | `get_libraries` | Libraries installed on this machine, with the exact import line for each. |
23
+ | `get_project_files` | `.scad` files in a directory and their include/use dependency graph. `mode=trace` follows a constant's dependents. |
24
+ | `clear_cache` | Drops the render cache. |
25
+ | `model` | Workspace file CRUD: `action=create\|get\|update\|list\|delete`. `template="part:<id>"` writes a catalogued purchased part. |
26
+
27
+ ## The design loop
28
+
29
+ 1. State units, orientation, datum, and print process first. They are invisible in the source and wrong in half of all first attempts.
30
+ 2. Declare every meaningful dimension as a named variable at the top; derive the rest with expressions.
31
+ 3. Run `validate(mode="syntax")` before anything else. OpenSCAD exits 0 on failed asserts, unknown modules, and missing includes, so the exit code proves nothing.
32
+ 4. Run `measure` before trusting any picture. Numbers decide, pictures confirm; a vision model reads broken geometry as fine.
33
+ 5. Then `render(grounded=true)` with one to three views. More images make counting and comparison worse, not better.
34
+ 6. For assemblies: one module per part, overlap coplanar faces by an epsilon, and take clearances from `reference(topic="fits")` rather than memory. Never union the assembly.
35
+ Then hand the parts to `check` by name: `interference` and `clearance` for fit, `contact` for what should touch, `alignment` for a hole that is off by half a millimetre (interference and clearance both read zero there), `motion` for a sweep, `mass` for weight, centre-of-mass and inertia limits. Every row carries `quality.fn`; a distance inside the tessellation error bound comes back `UNRESOLVED`, so re-run at higher `$fn` rather than believing it. `measure(mode="features")` lists the holes a part cuts, and `reference(topic="parts")` plus `model(action="create", template="part:<id>")` gives you a sourced purchased part with named anchors and a clearance mask instead of guessed dimensions. Freeze the rules in a check file and re-run `check(mode="rules")` after every edit.
36
+ 7. Confirm `measure(mode="parts")` reports the component count you designed, and that `validate(mode="geometry")` returns `mesh_health.manifold == true`. A `null` there means the check did not run, not that it passed.
37
+ 8. Iterate by changing one variable and re-measuring. Use `scad_eval` to check derived expressions before spending a render.
38
+ 9. On every response read `errors`, then `warnings`, then `hints`, then the payload. Check `cached`: a cached result can predate an edit to an included file.
39
+ 10. `export_model` last, once the numbers and the manifold check pass.
40
+
41
+ ## Reading a render
42
+
43
+ The text digest before the image carries the camera eye/center/up, the projection, the
44
+ bounding box, and the scale in mm per pixel. That scale is valid only under
45
+ orthographic projection, which is what `grounded=true` selects. Auto-framed
46
+ (`--viewall`) renders fit the model to the frame, so absolute scale is unknown and a
47
+ 2 mm cube looks identical to a 500 mm one.
48
+
49
+ ## Gotchas
50
+
51
+ Variables are compile-time and scope-final, so assigning inside an `if` or `for` does
52
+ not change the outer value; use `x = cond ? a : b`. `difference()` subtracts every
53
+ child after the first, so order changes the result. 2D and 3D geometry cannot be
54
+ combined without extruding first. A global `$fn` applies to every curve and makes
55
+ exports slow and huge. `import()` needs `convexity=10` or it renders with holes.
56
+ Solids that touch exactly, and any zero-thickness wall, produce non-manifold output.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 quellant
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.