Skip to main content
Glama
sebastiankoukoui

open-mcp-cad

execute_cadwork_command

Execute cwapi3d Python scripts inside Cadwork to read and create 3D geometry, returning structured JSON results.

Instructions

Führt cwapi3d-Python-Code in Cadwork aus und liefert das Ergebnis.

Du (Claude) generierst den Python-Code als String und übergibst ihn hier. Der Code wird im Cadwork-Prozess ausgeführt, wo alle cwapi3d-Module verfügbar sind.

Konvention: Weise das Endergebnis der Variable result zu — sie wird als JSON zurückgegeben. Beispiel: result = ec.get_all_identifiable_element_ids()

Bei Multi-Bridge-Betrieb (mehrere Cadwork-Instanzen parallel): vor Arbeitsbeginn get_document_info aufrufen und den Dokumentnamen prüfen, damit Code nicht in der falschen Datei landet. Ist serverseitig OPEN_MCP_CAD_EXPECT_DOC gesetzt, wird diese Prüfung automatisch erzwungen.

Verfügbare Module (Voll-Namen + Aliase): element_controller (ec) utility_controller (uc) attribute_controller (ac) geometry_controller (gc) file_controller (fc) visualization_controller (vc) material_controller (mc) bim_controller (bc) scene_controller (sc) list_controller (lc) cadwork (cw, Typen) ... weitere via get_cadwork_api_help()

Sicherheit: Imports von os, subprocess, shutil, socket, urllib, requests sowie import sind blockiert (Best-Effort). Datei-Operationen sollten ausschließlich über cwapi3d-Funktionen laufen.

Verifizierte Code-Beispiele liefert get_working_examples() — bei Holzbau- Operationen zuerst dort nachschauen statt zu raten.

Für komplette Konstruktionsdetails (AW-Decken-Anschluss, Ecken, IW-Stoss usw.) gibt es get_detail(): zuerst get_detail(list_types=True) für die Übersicht, dann get_detail(type=..., variant=...) für Code + Detail-Regeln.

Achtung Klassiker: Panels: thickness ist die z_local-Dimension, NICHT die phys. Plattendicke (kann 2700mm Wandhöhe sein). Kerven nur via ec.subtract_elements_with_undo([pfette], [sparren], False) — nie cut_shoulder oder cut_elements_with_overmeasure.

Bei Timeout NICHT blind wiederholen: get_connection_status() sagt, ob der Auftrag noch läuft (dann warten), ob die Verbindung pausiert ist oder ob der Cadwork-Hauptthread hängt. Ein Timeout heisst nicht "nicht ausgeführt".

Args: code: cwapi3d-Python-Code. Endergebnis bitte in result schreiben. description: Kurzer Klartext, WAS der Auftrag baut ("Fensterwand Süd erzeugen"). Wird im Fenster "Open MCP CAD Verbindungen" angezeigt, solange der Auftrag läuft, und landet im Log. Bitte immer setzen — sonst steht dort nur "execute_cwapi3d".

Liefert: {"ok": True, "result": , "stdout": , "vars": [...]} oder Fehlerobjekt mit "error", "message", "details".

=== BEKANNTE PROBLEME + WORKAROUNDS ===

  • Reine Berechnungen NICHT ueber die Bridge - blockiert UI und Timeout: Python-Berechnungen lokal mit bash_tool ausfuehren.

  • cut_element_with_plane erzeugt Artefakt-Vertex wenn Schnittebene auf Elementkante liegt: Element mit Ueberstand erstellen (15-20mm ueber die Schnittlinie hinaus), dann cut_element_with_plane, dann mit stretch_start/end_facet auf die exakte Laenge kuerzen.

  • cut_element_with_plane behaelt die ANTI-Normal-Seite: Formel: dot(punkt, normal) < distance = Punkt bleibt. Normal immer IN Richtung des Materials zeigen das ENTFERNT werden soll.

  • Material-Zuweisung im selben Batch wie Erstellung funktioniert nicht zuverlaessig: Material IMMER in einem separaten execute_cadwork_command-Aufruf zuweisen.

  • stretch_start/end_facet wirkt bei vertikalen Elementen in Z, nicht X/Y: Fuer Y/X-Positionsaenderung vertikaler Elemente: ec.move_element() statt stretch.

  • Bridge-Timeouts bei grossen Operationen fuehren zu Duplikaten: Kleinere Batches (max 15-20 Elemente pro Schleife). Nach Timeout: Inventar pruefen bevor man wiederholt.

  • cadwork.ifc_predefined_type() Konstruktor funktioniert nicht: Bestehenden Predefined Type holen: pt = bc.get_ifc_predefined_type(existing_eid), modifizieren, zuruecksetzen.

  • create_rectangular_panel_vectors: width und thickness sind NICHT was man denkt: Liegende Platte (XY-Ebene): width=Dicke(Z), thickness=Breite(Y). Vertikale Wandplatte (XZ): width=Dicke(Y), thickness=Hoehe(Z). IMMER mit Vertex-Check verifizieren!

  • create_rectangular_beam_vectors: Startpunkt ist Mitte Querschnitt am ANFANG, length geht AB dort: Startpunkt-Z bei vertikalen Staedern = UK (nicht Mitte!). Startpunkt-X/Y bei horizontalen Schwellen = Anfang + Mitte des Querschnitts.

  • Vertex-Anzahl ist KEIN zuverlaessiger Indikator fuer Bearbeitungen: Visuell pruefen oder spezifische Koordinaten an der Auflagerstelle vergleichen.

  • Bridge-Timeout: Rechtsklick in Cadwork-Viewport kann Bridge wieder freigeben: Bei Bridge-Timeout: Rechtsklick ins Cadwork-Viewport, dann 30 Sekunden warten.

  • p1=START ist der HAEUFIGSTE wiederholte Fehler - trotz Dokumentation!: CHECKLISTE vor JEDEM create:

  • stretch_start/end_facet wirkt NUR in xl-Richtung (Laengenachse)!: Fuer Width: gc.set_width_real([id], neuer_wert). Fuer Height: gc.set_height_real(). Beide aendern symmetrisch um Mitte, ggf. move_element noetig.

  • slice_elements_with_plane: IDs aendern sich nach Schnitt - neu suchen!: Nach jedem Schnitt: get_all_identifiable_element_ids() aufrufen und Elemente ueber Filter neu identifizieren.

  • Verschachtelte Funktionen (def in def) verursachen NameError in Bridge: Keine verschachtelten Funktionen verwenden. Alle Werte als Parameter uebergeben oder Code flach schreiben.

  • join_elements hat keine Wirkung - solder_elements verwenden: Immer solder_elements statt join_elements verwenden.

  • set_width_real / set_height_real aendert symmetrisch um Mitte: Nach set_width_real: Versatz berechnen (delta_width/2) und mit ec.move_element korrigieren.

  • cut_shoulder / cut_heel_shoulder / cut_double_shoulder frieren die Bridge ein (modale Dialoge): cut_shoulder NICHT ueber execute_cadwork_command aufrufen. Versaetze stattdessen mit cut_element_with_plane (Doppelschraege moeglich) selbst konstruieren, oder manuell in Cadwork. Falls Bridge haengt: Dialog bestaetigen (Default 30/0/W) oder Plugin neu starten.

  • cut_element_with_plane kann keinen innenliegenden Ausschnitt (Fenster) erzeugen: Innenliegende Oeffnungen (Fenster) via solder_elements (C-/Rahmen-Form aus Teilplatten) ODER via subtract mit durchstechendem Element.

  • Bridge-exec: Funktionen UND Generator-Ausdruecke sehen keine Top-Level-Variablen: Code FLACH schreiben: keine Helfer-Funktionen, keine lambdas, keine Comprehensions/genexpr die eigene Variablen referenzieren. Werte inline berechnen oder als Parameter uebergeben (Funktion ohne freie Variablen).

  • cut_elements_with_overmeasure hat bei einfachen Durchdringungen keinen Effekt: Fuer gezielte Schnitte cut_element_with_plane oder subtract verwenden.

  • Bridge liefert nach Timeout veraltete Antwort (Response-Desync): In jeden wichtigen Aufruf einen eindeutigen Marker ins result schreiben (z.B. result={'marker':778899,...}) und pruefen ob er zurueckkommt. Stimmt der Marker nicht -> Antwort verwerfen, Aufruf wiederholen. Nach Timeout zuerst Inventar via ec.get_all_identifiable_element_ids() pruefen bevor weitergebaut wird.

  • cut_double_tenon wirkungslos ohne Katalog - friert aber NICHT ein; Zapfen via Endtyp GEHT: Bevorzugt: Zapfen via endtype_controller.set_endtype_id_end(balken_id, 376683). Vorhandene IDs holen mit etc.get_existing_tenon_ids(). Fallback ohne Katalog: Zapfen geometrisch mit 4x subtract (je eine Wange einzeln) bauen. ACHTUNG: cut_*_lap (Blattungen) NICHT ungeprueft aufrufen - nutzen 'current 3D options' und koennten wie cut_shoulder Dialoge oeffnen.

  • stretch nimmt nur den Laengsanteil; doppelschraege Facette wird beim Stretchen plattgebuegelt: Verbreitern/Hoehe aendern: gc.set_width_real / gc.set_height_real (symmetrisch um Mitte). Reine Laenge symmetrisch: gc.set_length_real. Einseitig nur in Laengsachse: stretch_start/end_facet. Doppelschraege am Ende NICHT per stretch nachfuehren - neu schneiden (cut_element_with_plane).

  • ec.solder_elements gibt eine LISTE zurueck, nicht eine ID: sid = sol[0] if isinstance(sol,(list,tuple)) else sol. Danach Attribute auf sid setzen. Bei Crash nach Solder: Ist-Stand scannen (Solder lief), nicht blind wiederholen.

  • IFC2x3-Typ setzen via cadwork.ifc_2x3_element_type(); Getter braucht TYP-OBJEKT nicht ID: Setzen: t=cadwork.ifc_2x3_element_type(); t.set_ifc_member(); bc.set_ifc2x3_element_type([eid],t). Lesen: bc.get_ifc2x3_element_type_display_string(bc.get_ifc2x3_element_type(eid)). Verfuegbare Setter: set_ifc_member/plate/covering/beam/column/wall/slab/footing/building_element_part/proxy u.a.

  • Katalog/JSON-eingebettete Code-Strings NUR per Skript schreiben, nie Edit-Tool: Code-Strings immer per Python-Skript schreiben (json.dump), nie mit dem Edit-Werkzeug. Nach dem Schreiben json.load-Validierung dass alle Details intakt sind. Vollstaendigen Funktions-Code INLINE einbetten (Server kann tools/ nicht importieren).

  • move_element bei Timeout oft trotzdem ausgefuehrt -> relativ nachschieben verdoppelt: Nach Timeout NIE relativ nachschieben. Ist-Position auslesen und ABSOLUT zielen: delta=ziel-aktuell; ec.move_element([id], point_3d(delta,0,0)). Marker im result zum Erkennen alter Antworten.

  • Katalog-Varianten NIE per Box-Kopie aus gedumpten w/h/l/p1 ableiten: Varianten aus dem KORRIGIERTEN Builder regenerieren, nie per Box-Kopie. Ausklinkung IMMER per Volumen (gc.get_volume bzw. offline _exp-Split-Volumen) pruefen, nie per Bounding-Box. Regressionstest: tools/_eck_12varianten_test.py (Eck2 volumen-vollstaendig korrekt 351/0).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
codeYes
descriptionNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and exceeds it. It discloses timeout behavior, bridge freezes (cut_shoulder), response desyncs with marker workaround, side effects like solder_elements returning a list, and restrictions on embedded functions or generators. It even explains that timeouts do not mean the command was not executedhare. The return format and error object are fully specified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely long, dominated by a massive 'BEKANNTE PROBLEME + WORKAROUNDS' list. It is well-structured with bullets and sections, and nearly every point is actionable.g., p1=START checklist, cut_shoulder dangers, vertical element stretch behavior. However, it is far from concise and could overwhelm an agent with edge cases that apply only in specific situations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a highly complex, side-effect-prone tool with no output schema, the description is remarkably complete. It covers module availability, security restrictions, result conventions, return structure, known pitfalls, and recovery strategies. An agent has all needed information to invoke the tool correctly and to handle failures gracefully.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero property descriptions, so the description must compensate entirely. It does: 'code: cwapi3d-Python-Code. Endergebnis bitte in `result` schreiben.' and 'description: Kurzer Klartext... Bitte immer setzen.' It also includes a concrete example (result = ec.get_all_identifiable_element_ids()) and explains where description is displayed, fully covering both parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise verb-resource statement: 'Führt cwapi3d-Python-Code in Cadwork aus und liefert das Ergebnis.' It explicitly defines the agent's role ('Du generierst den Python-Code als String') and differentiates from siblings by referencing alternatives like get_working_examples, get_detail, and bash_tool for other tasks. The tool's identity as a code-execution bridge is unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use and when-not-to-use guidance: 'Reine Berechnungen NICHT ueber die Bridge... mit bash_tool ausfuehren.' It routes users to get_working_examples() for verified patterns fiirst, to get_detail() for construction details, and to get_connection_status() after timeouts. It also dictates sequencing (e.g., material assignment must be a separate call), making selection and invocation unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.