Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Descripción del creador (original en inglés)
Compile OpenSCAD, read computed values, preview and measure the mesh, without a GUI.
Estos tres nunca se combinan en una sola puntuación: las opiniones, las mediciones y la popularidad son cosas distintas.
Todavía no escribimos un resumen sencillo para este. Abajo están los datos que leímos del registro.
Elige la app de IA que usas y copia la configuración.
OPENSCAD_WORKSPACE, OPENSCAD_BIN, OPENSCAD_TIMEOUTNecesitas
¿Qué app usas?
Elige tu app arriba. La recordamos, así que la próxima vez el botón dirá “Instalar en …”.
Abre Claude Desktop → Settings → Developer → Edit Config y pega esto en claude_desktop_config.json
{
"mcpServers": {
"cadloop-openscad": {
"command": "uvx",
"args": [
"cadloop"
],
"env": {
"OPENSCAD_WORKSPACE": "your-value",
"OPENSCAD_BIN": "your-value",
"OPENSCAD_TIMEOUT": "your-value"
}
}
}
}Ejecuta esto en tu terminal
claude mcp add cadloop-openscad --env OPENSCAD_WORKSPACE=your-value --env OPENSCAD_BIN=your-value --env OPENSCAD_TIMEOUT=your-value -- uvx cadloopCompleta los valores vacíos antes de ejecutarlo.
Pégalo en .cursor/mcp.json de tu proyecto, o en ~/.cursor/mcp.json
{
"mcpServers": {
"cadloop-openscad": {
"command": "uvx",
"args": [
"cadloop"
],
"env": {
"OPENSCAD_WORKSPACE": "your-value",
"OPENSCAD_BIN": "your-value",
"OPENSCAD_TIMEOUT": "your-value"
}
}
}
}Tu navegador te pide permiso para abrir la app; luego la app muestra la configuración y te pide confirmar. Los valores de las claves quedan vacíos para que los completes tú.
Pégalo en .vscode/mcp.json de tu proyecto
{
"servers": {
"cadloop-openscad": {
"type": "stdio",
"command": "uvx",
"args": [
"cadloop"
],
"env": {
"OPENSCAD_WORKSPACE": "your-value",
"OPENSCAD_BIN": "your-value",
"OPENSCAD_TIMEOUT": "your-value"
}
}
}
}Tu navegador te pide permiso para abrir la app; luego la app muestra la configuración y te pide confirmar. Los valores de las claves quedan vacíos para que los completes tú.
Este se ejecuta en tu computadora, y ChatGPT solo puede conectarse a servidores en internet. Elige otra app.
Tu elección se guarda en una cookie en este dispositivo; no necesitas cuenta.
OPENSCAD_WORKSPACE envOPENSCAD_BIN envOPENSCAD_TIMEOUT envEsta configuración se genera a partir de la ficha del creador en el registro. Si el README dice otra cosa, sigue el README.
Se ejecuta en tu computadora; la lista de herramientas aparece en tu app de IA después de instalarlo.
Revisamos información que cualquiera puede ver; no hemos leído el código. Las revisiones que no aplican no se cuentan. · Revisado el 7 nov 2026
El nombre en el registro se verificó con la cuenta de GitHub richardofortune, dueña del repo
Todavía no hemos leído este repo en GitHub
Todavía no hemos leído este repo en GitHub
Este se ejecuta en tu computadora; no hay endpoint en internet
Se ejecuta en tu computadora y usa ajustes locales en su lugar
Se ejecuta en tu computadora; solo podemos leer listas de herramientas de endpoints en internet
Comparado con todos los servidores activos de esta categoría en el registro. Las estrellas solo cuentan cuando quien lo publica es dueño del repo.
Superó 1 de 1 revisiones básicas aplicables. No hemos leído el código. Antes de agregar una clave o un token, revisa qué acceso pide el servidor y usa una clave que tenga solo los permisos que necesitas.
El registro no indica ninguna clave obligatoria, aunque algunos servidores te piden iniciar sesión la primera vez que los usas.
Se ejecuta en tu computadora. Tu app de IA lo inicia cuando hace falta, y los datos no pasan por los servidores del creador (a menos que el propio servidor llame a un servicio en línea).
El repo de GitHub cambió por última vez –, y la última versión (0.1.0) llegó al registro hace 3 meses.
Las apps compatibles con MCP, como Claude Desktop, Claude Code, Cursor y VS Code. También necesitas Python (uv) en tu computadora.
En la misma categoría: Spec Driven Development, Remote Desktop Commander, Tools MCP
Servidores de la misma categoría hechos por otros creadores, ordenados por estrellas.
Cómo leer una tarjeta:★ Estrellas de GitHubiTres pilares: reseñas · revisiones · usoiActualizado = fecha en que se publicó la última versión en el registroi
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Web production tools for AI agents: contrast, JP text, WebP, JSON-LD, slugs, dates and 40+ more
Copiado tal cual del repo del creador. PopNx MCP no lo ha revisado ni lo respalda. Se quitaron HTML, imágenes y scripts. Los enlaces llevan fuera de este sitio.
A closed loop from parametric source to G-code, with the verification step in the middle that neither the CAD tool nor the slicer can do.
Two MCP servers. A model writes OpenSCAD, compiles it, reads computed values back out, looks at a render, checks it fits the bed, slices it and pulls out the G-code, with every plate proven against the printable area. No GUI at any point.
The verify step in the middle is yours to write. cadloop makes everything around it cheap enough that you get to run it often; it cannot tell you whether the part works.
*Every number in that walkthrough is real output. The failing wheel is a real measurement, not an illustration. How it's built and where each number comes from is in docs/walkthrough.*
setup_printer once, no arguments: which printer is this for
| write .scad | check syntax and references, about a second | echo read computed values without rendering | preview look at it | verify does it actually work <- yours; nothing here does it for you | measure bounding box and volume | check_bed_fit against the printer you set up | slice_model -> .gcode.3mf | extract_gcode -> .gcode
The ordering is the point. check and echo skip geometry evaluation entirely, so they cost a second against models where a full render takes minutes. Pay for the expensive steps only once the cheap ones pass.
Everything from the bed check down is also one call, make_printable, which renders, packs, slices and proves the result on the bed and reports what it did in a screen of text. See the worked example.
pip install cadloop
The only dependency is mcp. Or from a checkout, which is what you want if you intend to run the worked example or the tests — the verify extra is shapely, needed by the example's own checker rather than by cadloop:
git clone https://github.com/richardofortune/cadloop
cd cadloop pip install -e ".[verify]"
Needs OpenSCAD on PATH or at OPENSCAD_BIN, and for slicing, OrcaSlicer, Bambu Studio, ElegooSlicer or Creality Print. They share a CLI, so any of them works, and all four are auto-detected along with the profiles they ship.
No slicer is preferred over another here. setup_printer probes each one it finds and then proves the winner by slicing a 20mm cube with your profiles, so which one you get is decided by which one works on your machine rather than by the order of a list in this repository. Creality Print's CLI is broken headless on macOS today, and that is something this discovers rather than something it asserts, so it corrects itself when upstream ships a fix; see testing status below. SLICER_BIN overrides the choice.
Copy mcp.json into your client's config and fix the paths. Both servers should point at the same workspace directory, which is the only place either one reads or writes.
| Variable | Default | Meaning |
|---|---|---|
OPENSCAD_BIN, SLICER_BIN | auto-detected | binary paths |
OPENSCAD_WORKSPACE, SLICER_WORKSPACE | ~/cad | the sandbox |
SLICER_PROFILE_DIRS | auto-detected | extra profile roots |
CADLOOP_MACHINE | $XDG_CONFIG_HOME/cadloop/machine.json | where the machine record lives |
OPENSCAD_TIMEOUT, SLICER_TIMEOUT | 300, 600 | seconds before a kill |
openscad exposes check, echo, render, measure, preview and workspace file access. preview returns the PNG as an MCP image, so the model can look at what it built rather than inferring from numbers. render returns OpenSCAD's manifold report alongside a bounding box and volume, where simple: yes with a sensible volume count is the signal the mesh is printable.
The two split on what happens to the picture. preview hands it back and keeps nothing; render writes it to the workspace when the output ends in .png, taking the same camera, imgsize, projection and full_render options. Use render when the image is the artefact rather than the answer. Since render also takes source as text rather than a path, the before half of a comparison is git show :model.scad piped straight in — no checkout, no temp file.
slicer exposes setup_printer, machine_info, make_printable, slicer_info, list_profiles, check_bed_fit, slice_model, slice_summary and extract_gcode.
make_printable is the whole chain in one call. Give it a .scad and the parts you want out of it, and it renders each one, measures it, packs what fits onto as few plates as it can, slices them, and then reads the finished G-code back to prove every extruding move lands on the bed. It never edits the model: a part that cannot print as designed is reported, not quietly shrunk or split. The one thing it changes is which plate a part lands on, and turning a part ninety degrees when it will not fit square, which it names in the report. It answers with every fact it established and, in summary, the one screen of text those facts add up to, ending in what to do next.
Call setup_printer() once, with no arguments. It reads what your slicer is already configured with, resolves that to a machine, process and filament profile from one install, proves the combination by slicing a 20mm cube, and remembers it. It reports the printer, the quality and the filament it settled on, and stores nothing at all if the test slice fails. Pass printer, filament or process only to override one of those fields; the rest still come from your slicer's own settings. A profile you name is either used or refused by name, never quietly swapped for a different one.
After that, check_bed_fit and slice_model need no profile arguments, which is the point: a caller cannot supply three profiles that disagree if it supplies none. Explicit arguments still win where you pass them.
machine_info says which printer this workspace is set up for and whether it is still current. The record is a cache, not a source of truth. If the slicer moves, a profile is edited, or the slicer's version changes, every tool that would have used it refuses with the reason instead - ok: null, nothing written - until you run setup_printer again. A setup that no longer matches reality is never used to produce G-code.
Call slicer_info before doing anything unusual: the Orca-family CLI is undocumented, changes between releases, and Creality's fork diverges, so the flag list it reads off your install is more trustworthy than anything assumed. slice_model has an extra_args escape hatch and a dry_run mode.
check_bed_fit is where the two meet. The slicer will emit out-of-bounds G-code without complaining, so this measures the STL, reads printable_area out of the machine profile, and compares. It checks the 45 degree diagonal too, since a part that misses square-on often fits rotated.
Reading printable_area back out is fiddlier than it looks. Stock profiles write it both as a list of "XxY" strings and as one comma-separated string, and most Bambu machines carry no bed of their own at all, inheriting it through inherits from a common base. So the lookup parses both forms and walks the inheritance chain. Of the 473 concrete machine profiles shipped with Creality Print 7.1.1, 469 resolve; the remaining four define no bed anywhere in their chain, and those report ok: null with a reason rather than guessing.
This is the part cadloop does not do for you, and the reason it is a worked example rather than a feature. models/verify_spirograph.py ships beside the model, not inside the package: every project's version of "does it actually work" is different, and none of them generalise. Yours will look nothing like this one.
It runs two checks. For the spirograph the first lays each wheel's pitch curve onto the ring's pitch circle, walks a full circuit, and measures overlap between the two solids at every position. Zero overlap across the whole circuit at some meshing phase is the pass condition. The second checks the parts are not laid on top of each other on the sheet.
$ python models/verify_spirograph.py
part teeth overlap mm2 result 24T 24 0.000000 pass ... trefoil 23 0.000000 pass
14/14 parts mesh cleanly
group volume mm3 ring 23939.8 outer_ring 25652.8 wheels 197113.5 shapes 10078.7 sum 256784.8 sheet 256784.8
no parts overlap on the sheet
The second check is the same idea one level up. A sheet that lays two parts on top of each other still renders as a clean manifold, still fits the bed, and still slices without a word; it just prints as one fused object. So it renders the sheet and each of its groups and compares the union against the sum, which is the only place the collision shows up. It needs OpenSCAD and skips without one; --skip-layout and --skip-mesh run one half alone.
A pen in a wheel of r teeth rolling in a ring of R traces a figure with R / gcd(R, r) lobes, closing after r / gcd(R, r) circuits. The pattern is settled by the tooth counts before any geometry exists, so the checker's --patterns mode reads it straight off the set:
$ python models/verify_spirograph.py --patterns
main ring, 96 teeth part teeth lobes circuits 32T 32 3 1 plain 24T 24 4 1 plain 72T 72 4 3 plain ... trefoil 23 96 23
96 is 2^5 x 3, so it shares factors with most of an even wheel set and a good half of these wheels draw eight lobes or fewer. There is no 48 in the set for this reason: 48 is exactly half of 96, the degenerate ratio whose pen traces an ellipse and nothing else, so it earned no slot. The outer ring, 105 = 3 x 5 x 7, behaves far better, and the trefoil at 23 teeth is coprime to both rings, which is what makes it the richest wheel in the set.
This is worth running before choosing tooth counts rather than after printing them.
This is model-specific by nature, which is the honest lesson. A manifold mesh that fits the bed and slices cleanly can still be a part that does not work. Whatever your equivalent of "does it actually roll" is, it belongs in the loop between preview and measure, and you have to write it yourself.
models/spirograph.scad is the model the loop was built around. A 96 tooth internal ring in a flanged body, an outer ring, eleven circular wheels and three non-circular ones (ellipse, egg, trefoil), all involute geared at module 1.5 with pen holes on a golden-angle spiral.
The non-circular wheels are why the verifier exists. A first attempt used capsule and teardrop outlines built from tangent lines; those looked right, rendered as clean manifolds, and would have sliced without complaint, but the rolling check showed them ploughing 30 to 80 mm² into the ring teeth. A flat section of pitch curve touches the ring at one point and stands proud of it everywhere else. Nothing downstream of CAD would have caught that. The shapes that shipped are smooth convex curves whose radius of curvature stays inside the ring's everywhere.
Taking the whole set from source to plates is two calls, and the first one is only needed once:
setup_printer()
make_printable("spirograph.scad", ["ring", "outer_ring", 24, 30, 32, 36, 40, 45, 52, 56, 63, 72, 80, "ellipse", "egg", "
Solo se muestra el principio; lee el resto en el repo