MCP server that lets Claude generate and render OpenSCAD models to STL files. Includes setup documentation and installation guide. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8.6 KiB
OpenSCAD MCP Server — Installationsanleitung
LLM-gestützte 3D-Modell-Erstellung: Claude generiert OpenSCAD-Code und rendert ihn direkt zu STL-Dateien für den 3D-Drucker.
Voraussetzungen
- Windows 10/11
- Claude Code Desktop App installiert
- Python (Microsoft Store) — bereits installiert auf diesem System
Schritt 1: OpenSCAD installieren
- https://openscad.org/downloads.html aufrufen
- Windows Installer herunterladen und ausführen
- Standardpfad bestätigen:
C:\Program Files\OpenSCAD\
Verifizieren:
"C:\Program Files\OpenSCAD\openscad.exe" --version
Erwartete Ausgabe: OpenSCAD version 2021.01 (oder neuer)
Schritt 2: Projektverzeichnis anlegen
mkdir C:\Users\<USERNAME>\Documents\Claude\openscad-mcp
Schritt 3: Python Virtual Environment erstellen
Wichtig: Den Microsoft Store Python verwenden (
python3.13.exein WindowsApps). Daspython.exeausC:\Users\...\AppData\Local\Programs\Python\Python313\ist ein eingebettetes Python ohne pip und funktioniert nicht. DieWindowsApps\python3.13.exeist ein App Execution Alias — funktioniert nur in interaktiven Shells, nicht als Subprocess von Claude Code. Lösung: Virtual Environment erstellen — das.venv\Scripts\python.exeist eine echte Executable ohne diese Einschränkung.
cd C:\Users\<USERNAME>\Documents\Claude\openscad-mcp
"C:\Users\<USERNAME>\AppData\Local\Microsoft\WindowsApps\python3.13.exe" -m venv .venv
.venv\Scripts\pip install mcp
Verifizieren:
.venv\Scripts\python.exe -c "from mcp.server.fastmcp import FastMCP; print('OK')"
Schritt 4: MCP-Server erstellen
Datei C:\Users\<USERNAME>\Documents\Claude\openscad-mcp\server.py:
"""
OpenSCAD MCP Server
Ermöglicht Claude, OpenSCAD-Code zu rendern und STL-Dateien zu erzeugen.
"""
import subprocess
import tempfile
import os
import base64
from pathlib import Path
from mcp.server.fastmcp import FastMCP
OPENSCAD_PATH = os.environ.get(
"OPENSCAD_PATH",
r"C:\Program Files\OpenSCAD\openscad.exe"
)
OUTPUT_DIR = Path(os.environ.get("OPENSCAD_OUTPUT_DIR", Path.home() / "3d-models"))
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
mcp = FastMCP("openscad")
def _run_openscad(scad_code: str, output_path: Path, extra_args: list = None) -> tuple[bool, str]:
with tempfile.NamedTemporaryFile(suffix=".scad", mode="w", delete=False, encoding="utf-8") as f:
f.write(scad_code)
scad_file = f.name
try:
cmd = [OPENSCAD_PATH, "-o", str(output_path)] + (extra_args or []) + [scad_file]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
output = (result.stdout + result.stderr).strip()
success = result.returncode == 0 and output_path.exists()
return success, output
finally:
os.unlink(scad_file)
@mcp.tool()
def render_stl(code: str, filename: str = "model.stl") -> str:
"""Rendert OpenSCAD-Code als STL-Datei für den 3D-Drucker."""
if not filename.endswith(".stl"):
filename += ".stl"
output_path = OUTPUT_DIR / filename
success, output = _run_openscad(code, output_path)
if success:
size_kb = output_path.stat().st_size // 1024
return f"STL erfolgreich erstellt: {output_path}\nDateigröße: {size_kb} KB\nOpenSCAD-Output: {output or '(kein Output)'}"
else:
return f"Fehler beim Rendern:\n{output}"
@mcp.tool()
def preview_png(code: str, filename: str = "preview.png") -> str:
"""Rendert eine PNG-Vorschau des OpenSCAD-Modells."""
if not filename.endswith(".png"):
filename += ".png"
output_path = OUTPUT_DIR / filename
extra = ["--camera=0,0,0,55,0,25,140", "--imgsize=800,600", "--colorscheme=DeepOcean"]
success, output = _run_openscad(code, output_path, extra_args=extra)
if success:
with open(output_path, "rb") as f:
img_b64 = base64.b64encode(f.read()).decode()
return f"data:image/png;base64,{img_b64}"
else:
return f"Fehler beim Rendern der Vorschau:\n{output}"
@mcp.tool()
def list_models() -> str:
"""Listet alle bisher erstellten 3D-Modelle im Output-Verzeichnis."""
files = list(OUTPUT_DIR.glob("*.stl"))
if not files:
return f"Keine STL-Dateien in {OUTPUT_DIR}"
lines = [f"Modelle in {OUTPUT_DIR}:"]
for f in sorted(files):
size_kb = f.stat().st_size // 1024
lines.append(f" {f.name} ({size_kb} KB)")
return "\n".join(lines)
if __name__ == "__main__":
mcp.run()
Schritt 5: MCP-Server testen
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | .venv\Scripts\python.exe server.py
Erwartete Ausgabe: JSON-Antwort mit "name":"openscad" — Server funktioniert.
Schritt 6: Claude Code Desktop konfigurieren
Wichtig: Es gibt zwei Settings-Dateien. Nur eine davon wird von der Desktop App gelesen:
Datei Gelesen von C:\Users\<USERNAME>\.claude\settings.jsonClaude Code CLI (Terminal) C:\Users\<USERNAME>\AppData\Roaming\Claude\claude_desktop_config.jsonClaude Code Desktop App Da die Desktop App verwendet wird, muss der Eintrag in
claude_desktop_config.json.
Datei öffnen: C:\Users\<USERNAME>\AppData\Roaming\Claude\claude_desktop_config.json
Den mcpServers-Block hinzufügen (Backslashes im Pfad beachten):
{
"mcpServers": {
"openscad": {
"command": "C:\\Users\\<USERNAME>\\Documents\\Claude\\openscad-mcp\\.venv\\Scripts\\python.exe",
"args": ["C:\\Users\\<USERNAME>\\Documents\\Claude\\openscad-mcp\\server.py"]
}
},
"preferences": {
...vorhandene Einstellungen beibehalten...
}
}
Schritt 7: Claude Code neu starten
Vollständig beenden — nicht nur neues Chat-Fenster öffnen:
- Rechtsklick auf Claude-Icon im Systemtray → Quit/Beenden
- Alternativ: Task-Manager →
claude.exebeenden
Dann Claude Code neu starten und einen neuen Chat öffnen.
Verifikation
In einem neuen Chat eingeben:
"Erstelle einen einfachen Würfel 20x20x20mm als test.stl"
Claude sollte automatisch das Tool render_stl aufrufen und eine STL-Datei in
C:\Users\<USERNAME>\3d-models\test.stl erzeugen.
Beispiel-Prompts
Erstelle einen Filamentrollenhalter für 200mm Außendurchmesser, 30mm Achse, als filamenthalter.stl
Erstelle einen Wandhalter für ein 32mm Rohr, Wandstärke 3mm, 2 Schraubenlöcher M4, als rohrhalter.stl
Erstelle eine Box 80x50x30mm mit Deckel und Scharnier, Wandstärke 2mm, als box.stl
Troubleshooting
Server wird nicht geladen (Tools nicht sichtbar)
- Prüfen ob Eintrag in
claude_desktop_config.jsonist (nicht insettings.json) - Claude Code vollständig neu starten (Systemtray → Quit)
- Debug-Log prüfen:
C:\Users\<USERNAME>\.claude\debug\— neueste Datei nachopenscaddurchsuchen
STL-Render schlägt fehl
- OpenSCAD-Pfad prüfen:
"C:\Program Files\OpenSCAD\openscad.exe" --version - Output-Verzeichnis prüfen:
C:\Users\<USERNAME>\3d-models\muss existieren (wird automatisch erstellt)
Python/mcp Import-Fehler
- Virtual Environment neu erstellen (Schritt 3)
- Prüfen:
.venv\Scripts\python.exe -c "from mcp.server.fastmcp import FastMCP; print('OK')"
Dateistruktur
C:\Users\<USERNAME>\
├── AppData\Roaming\Claude\
│ └── claude_desktop_config.json ← MCP-Server Registrierung
├── .claude\
│ └── settings.json ← Claude Code CLI-Settings (nicht relevant)
├── Documents\Claude\openscad-mcp\
│ ├── .venv\ ← Python Virtual Environment
│ │ └── Scripts\python.exe ← Echter Python-Interpreter
│ └── server.py ← MCP-Server Code
└── 3d-models\ ← Ausgabeverzeichnis für STL-Dateien
├── filamenthalter.stl
└── ...
Hintergrund: Warum so kompliziert?
-
Zwei Config-Dateien: Claude Code Desktop liest
claude_desktop_config.json, nicht~/.claude/settings.json. Letzteres ist nur für den CLI-Modus. -
Windows App Execution Aliases:
WindowsApps\python3.13.exeist ein Stub der nur aus interaktiven Shells funktioniert. Als Subprocess von Claude Code schlägt er ohne Fehlermeldung fehl. Ein Virtual Environment erstellt eine echtepython.exeohne diese Einschränkung. -
Eingebettetes Python:
C:\...\Programs\Python\Python313\python.exe(das vompy-Launcher verwendete) hat keinpipund kann nicht für MCP verwendet werden.