From 57466b4ba2df49e9f4df3e37deda5ad2e053b1dc Mon Sep 17 00:00:00 2001 From: nova Date: Fri, 13 Mar 2026 11:22:06 +0100 Subject: [PATCH] Initial commit: CadQuery MCP Server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - server.py: FastMCP-Server mit render_stl, preview_png, list_models - README.md: Ausführliche Installationsanleitung (DE) - .gitignore: Schließt .venv, STL/PNG-Ausgaben und Cache aus Stack: cadquery 2.7.0, mcp 1.26.0, cq-editor 0.6.2, Python 3.13 Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 21 ++++ README.md | 363 +++++++++++++++++++++++++++++++++++++++++++++++++++++ server.py | 123 ++++++++++++++++++ 3 files changed, 507 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 server.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d768d09 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# Python +.venv/ +__pycache__/ +*.pyc +*.pyo +*.egg-info/ + +# Generierte Dateien +*.stl +*.step +*.svg +*.png +mcp_server.log + +# IDE +.vscode/ +.idea/ + +# OS +Thumbs.db +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..49cc80c --- /dev/null +++ b/README.md @@ -0,0 +1,363 @@ +# CadQuery MCP Server + +Ein MCP-Server (Model Context Protocol), der Claude ermöglicht, parametrische +3D-Modelle direkt über CadQuery-Python-Code zu erstellen und als STL-Dateien zu exportieren. +Zusätzlich ist CQ-editor als GUI-Vorschau-Tool integriert. + +--- + +## Inhaltsverzeichnis + +1. [Voraussetzungen](#1-voraussetzungen) +2. [Installation](#2-installation) +3. [Claude Desktop einbinden](#3-claude-desktop-einbinden) +4. [CQ-editor starten](#4-cq-editor-starten) +5. [Verwendung in Claude](#5-verwendung-in-claude) +6. [Projektstruktur](#6-projektstruktur) +7. [Fehlerbehebung](#7-fehlerbehebung) + +--- + +## 1. Voraussetzungen + +| Anforderung | Version | Hinweis | +|---|---|---| +| Windows 10/11 | 64-Bit | Getestet auf Windows 11 | +| Python | ≥ 3.10 | [python.org](https://www.python.org/downloads/) – „Add to PATH" aktivieren | +| Claude Desktop | aktuell | [claude.ai/download](https://claude.ai/download) | +| Git | optional | Für Versionsverwaltung | + +> **Hinweis:** Python 3.13 wird vollständig unterstützt (CadQuery 2.7.0 liefert fertige Wheels). + +--- + +## 2. Installation + +### 2.1 Projektverzeichnis anlegen + +```powershell +mkdir C:\Users\\Documents\Claude\cadquery +cd C:\Users\\Documents\Claude\cadquery +``` + +### 2.2 Python Virtual Environment erstellen + +```powershell +python -m venv .venv +``` + +Das erzeugt einen isolierten Python-Interpreter unter `.venv\`. + +### 2.3 CadQuery, MCP-Server und CQ-editor installieren + +```powershell +.venv\Scripts\pip install cadquery mcp[cli] cq-editor +``` + +Installierte Pakete (Auswahl): + +| Paket | Version | Zweck | +|---|---|---| +| `cadquery` | 2.7.0 | Parametrisches CAD in Python (OpenCASCADE) | +| `cadquery-ocp` | 7.8.1 | OpenCASCADE Python-Bindings | +| `mcp` | 1.26.0 | Model Context Protocol SDK (FastMCP) | +| `cq-editor` | 0.6.2 | GUI-Editor mit Live-Vorschau (PyQt5) | + +> **Downloadgröße:** ca. 150 MB (cadquery-ocp ~52 MB, PyQt5-Qt5 ~50 MB, casadi ~51 MB) +> Bei Verbindungsunterbrechung einfach erneut ausführen – pip setzt den Download fort. + +### 2.4 Installation prüfen + +```powershell +.venv\Scripts\python -c "import cadquery as cq; print('cadquery', cq.__version__)" +# Ausgabe: cadquery 2.7.0 + +.venv\Scripts\python -c "import cq_editor; print('cq-editor OK')" +# Ausgabe: cq-editor OK +``` + +### 2.5 Test-STL erzeugen + +```powershell +.venv\Scripts\python -c " +import cadquery as cq +from cadquery import exporters +from pathlib import Path + +output = Path.home() / '3d-models' +output.mkdir(exist_ok=True) +result = cq.Workplane('XY').box(20, 20, 10) +exporters.export(result, str(output / 'test_box.stl')) +print('OK:', output / 'test_box.stl') +" +``` + +Die STL-Datei wird in `C:\Users\\3d-models\` gespeichert. + +--- + +## 3. Claude Desktop einbinden + +### 3.1 Konfigurationsdatei öffnen + +``` +%APPDATA%\Claude\claude_desktop_config.json +``` + +Unter Windows typischerweise: +``` +C:\Users\\AppData\Roaming\Claude\claude_desktop_config.json +``` + +### 3.2 CadQuery-Server eintragen + +Den folgenden Block in `"mcpServers"` einfügen: + +```json +{ + "mcpServers": { + "cadquery": { + "command": "C:\\Users\\\\Documents\\Claude\\cadquery\\.venv\\Scripts\\python.exe", + "args": ["C:\\Users\\\\Documents\\Claude\\cadquery\\server.py"] + } + } +} +``` + +> **Wichtig:** `` durch den tatsächlichen Windows-Benutzernamen ersetzen. +> Backslashes müssen in JSON doppelt escapt werden (`\\`). + +Vollständiges Beispiel mit OpenSCAD-Server: + +```json +{ + "mcpServers": { + "openscad": { + "command": "C:\\Users\\thors\\Documents\\Claude\\openscad-mcp\\.venv\\Scripts\\python.exe", + "args": ["C:\\Users\\thors\\Documents\\Claude\\openscad-mcp\\server.py"] + }, + "cadquery": { + "command": "C:\\Users\\thors\\Documents\\Claude\\cadquery\\.venv\\Scripts\\python.exe", + "args": ["C:\\Users\\thors\\Documents\\Claude\\cadquery\\server.py"] + } + } +} +``` + +### 3.3 Claude Desktop neu starten + +Nach dem Speichern der Config muss Claude Desktop **vollständig neu gestartet** werden. +Die MCP-Tools erscheinen dann automatisch in der Werkzeugliste. + +--- + +## 4. CQ-editor starten + +CQ-editor ist ein Qt-basierter GUI-Editor mit Live-3D-Vorschau. + +### Starten über die Kommandozeile + +```powershell +# Direkt über die installierte Executable: +C:\Users\\Documents\Claude\cadquery\.venv\Scripts\cq-editor.exe + +# Alternativ über Python: +.venv\Scripts\python -m cq_editor +``` + +### Startskript (optional) + +Für einfacheres Starten kann eine Datei `start-cq-editor.bat` im Projektverzeichnis +angelegt werden: + +```batch +@echo off +C:\Users\\Documents\Claude\cadquery\.venv\Scripts\cq-editor.exe +``` + +### Workflow mit CQ-editor + +1. CQ-editor starten +2. CadQuery-Code im Editor schreiben +3. **F5** drücken → Live-Vorschau rechts aktualisiert sich +4. Datei → Export → STL zum Speichern + +--- + +## 5. Verwendung in Claude + +### 5.1 Verfügbare MCP-Tools + +Nach dem Neustart von Claude Desktop stehen drei Tools zur Verfügung: + +#### `mcp__cadquery__render_stl` +Führt CadQuery-Python-Code aus und exportiert eine STL-Datei. + +``` +Parameter: + code : str – CadQuery-Python-Code + filename : str – Ausgabedateiname (Standard: "model.stl") +``` + +#### `mcp__cadquery__preview_png` +Exportiert eine SVG-Vorschau des Modells. + +``` +Parameter: + code : str – CadQuery-Python-Code + filename : str – Ausgabedateiname (Standard: "preview.png") +``` + +#### `mcp__cadquery__list_models` +Listet alle STL-Dateien im Output-Verzeichnis auf. + +### 5.2 Code-Konventionen + +Der MCP-Server erkennt das CadQuery-Ergebnis auf zwei Wegen: + +**Option A — `show_object()` aufrufen (empfohlen, CQ-editor-kompatibel):** +```python +import cadquery as cq + +result = cq.Workplane("XY").box(20, 20, 10) +show_object(result) +``` + +**Option B — Variable `result` verwenden:** +```python +import cadquery as cq + +result = cq.Workplane("XY").box(20, 20, 10) +# "result" wird automatisch erkannt +``` + +### 5.3 Beispiele + +**Einfacher Quader:** +```python +import cadquery as cq + +result = cq.Workplane("XY").box(30, 20, 10) +show_object(result) +``` + +**Zylinder mit Bohrung:** +```python +import cadquery as cq + +result = ( + cq.Workplane("XY") + .cylinder(height=30, radius=15) + .faces(">Z") + .hole(10) +) +show_object(result) +``` + +**Parametrisches Modell:** +```python +import cadquery as cq + +breite = 40 +hoehe = 20 +tiefe = 10 +radius = 3 + +result = ( + cq.Workplane("XY") + .box(breite, tiefe, hoehe) + .edges("|Z") + .fillet(radius) +) +show_object(result) +``` + +**Assembly (Baugruppe):** +```python +import cadquery as cq + +box = cq.Workplane("XY").box(20, 20, 10) +zylinder = cq.Workplane("XY").cylinder(15, 5) + +asm = ( + cq.Assembly() + .add(box, name="basis", loc=cq.Location((0, 0, 0))) + .add(zylinder, name="zapfen", loc=cq.Location((0, 0, 10))) +) +show_object(asm) +``` + +### 5.4 Output-Verzeichnis + +STL-Dateien werden gespeichert in: +``` +C:\Users\\3d-models\ +``` + +Diesen Pfad kann man über die Umgebungsvariable `CADQUERY_OUTPUT_DIR` überschreiben. + +--- + +## 6. Projektstruktur + +``` +cadquery/ +├── .venv/ # Python Virtual Environment (nicht ins Git) +├── server.py # MCP-Server (FastMCP) +└── README.md # Diese Datei +``` + +### server.py – Übersicht + +``` +_run_cadquery(code) Führt CadQuery-Code aus, fängt show_object() ab +render_stl(code, fn) Tool: exportiert STL über cadquery.exporters +preview_png(code, fn) Tool: exportiert SVG-Vorschau +list_models() Tool: listet STL-Dateien in OUTPUT_DIR +``` + +--- + +## 7. Fehlerbehebung + +### „Kein CadQuery-Objekt gefunden" + +Der Server konnte kein Ergebnis aus dem Code extrahieren. + +**Lösung:** Am Ende des Codes explizit `show_object(result)` aufrufen oder das Ergebnis +in eine Variable namens `result` speichern. + +### STL-Datei wird nicht erstellt + +- Output-Verzeichnis prüfen: `C:\Users\\3d-models\` +- Schreibrechte auf das Verzeichnis prüfen + +### Claude Desktop zeigt keine MCP-Tools + +1. `claude_desktop_config.json` auf korrekte Pfade und JSON-Syntax prüfen +2. Claude Desktop vollständig beenden (Taskleiste → Rechtsklick → Beenden) +3. Claude Desktop neu starten + +### Download bricht ab (cadquery-ocp / PyQt5-Qt5) + +Beide Pakete sind ca. 50 MB groß. Bei Abbruch einfach wiederholen: + +```powershell +.venv\Scripts\pip install cadquery mcp[cli] cq-editor --retries 5 +``` + +### CQ-editor startet nicht + +```powershell +# Fehlerausgabe anzeigen: +.venv\Scripts\python -m cq_editor +``` + +Häufige Ursache: Fehlende Qt-Laufzeitbibliotheken → Visual C++ Redistributable +installieren: [aka.ms/vs/17/release/vc_redist.x64.exe](https://aka.ms/vs/17/release/vc_redist.x64.exe) + +--- + +## Lizenz + +MIT License — freie Nutzung, Modifikation und Weitergabe erlaubt. diff --git a/server.py b/server.py new file mode 100644 index 0000000..d929af4 --- /dev/null +++ b/server.py @@ -0,0 +1,123 @@ +""" +CadQuery MCP Server +Ermöglicht Claude, CadQuery-Python-Code auszuführen und STL-Dateien zu erzeugen. +""" + +import os +import sys +import tempfile +import base64 +import traceback +from pathlib import Path +from mcp.server.fastmcp import FastMCP +import cadquery as cq +from cadquery import exporters + +OUTPUT_DIR = Path(os.environ.get("CADQUERY_OUTPUT_DIR", Path.home() / "3d-models")) +OUTPUT_DIR.mkdir(parents=True, exist_ok=True) + +mcp = FastMCP("cadquery") + + +def _run_cadquery(code: str) -> cq.Workplane: + """Führt CadQuery-Code aus und gibt das Ergebnis zurück.""" + captured = {} + + def show_object(obj, name="result", options=None): + captured["result"] = obj + + def show(obj, name="result", options=None): + captured["result"] = obj + + namespace = { + "cq": cq, + "cadquery": cq, + "show_object": show_object, + "show": show, + } + + exec(code, namespace) # noqa: S102 + + if "result" in captured: + return captured["result"] + + # Letzte Variable suchen, die ein Workplane oder Shape ist + for val in reversed(list(namespace.values())): + if isinstance(val, (cq.Workplane, cq.Shape, cq.Assembly)): + return val + + raise ValueError( + "Kein CadQuery-Objekt gefunden. " + "Bitte 'show_object(result)' am Ende des Codes aufrufen " + "oder das Ergebnis in eine Variable namens 'result' speichern." + ) + + +@mcp.tool() +def render_stl(code: str, filename: str = "model.stl") -> str: + """ + Rendert CadQuery-Python-Code als STL-Datei für den 3D-Drucker. + + Args: + code: Gültiger CadQuery-Python-Code + filename: Dateiname für die STL-Ausgabe (z.B. "halter.stl") + + Returns: + Pfad zur erzeugten STL-Datei oder Fehlermeldung + """ + if not filename.endswith(".stl"): + filename += ".stl" + + output_path = OUTPUT_DIR / filename + + try: + result = _run_cadquery(code) + exporters.export(result, str(output_path)) + size_kb = output_path.stat().st_size // 1024 + return f"STL erfolgreich erstellt: {output_path}\nDateigröße: {size_kb} KB" + except Exception as e: + return f"Fehler beim Rendern:\n{traceback.format_exc()}\nBitte CadQuery-Code prüfen." + + +@mcp.tool() +def preview_png(code: str, filename: str = "preview.png") -> str: + """ + Rendert eine PNG-Vorschau des CadQuery-Modells. + + Args: + code: Gültiger CadQuery-Python-Code + filename: Dateiname für die PNG-Ausgabe + + Returns: + Base64-kodiertes PNG-Bild oder Fehlermeldung + """ + if not filename.endswith(".png"): + filename += ".png" + + svg_path = OUTPUT_DIR / filename.replace(".png", ".svg") + output_path = OUTPUT_DIR / filename + + try: + result = _run_cadquery(code) + exporters.export(result, str(svg_path)) + size_bytes = svg_path.stat().st_size + return f"SVG-Vorschau erstellt: {svg_path} ({size_bytes} Bytes)\n(PNG-Konvertierung erfordert zusätzliche Abhängigkeiten)" + except Exception as e: + return f"Fehler beim Rendern der Vorschau:\n{traceback.format_exc()}" + + +@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()