Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
MCP_CAD_USE_MOCKNoSet to '1' to use the mock SolidWorks client for development on non-Windows platforms.0

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
get_active_part_infoA

Return metadata about the currently active SolidWorks part.

Includes the part name, whether it has been modified since open, the list of features with their dimensions, and the list of solid bodies (typically one per part; multi-body parts have several). Use this to inspect what's in the current part before suggesting modifications, and to discover the body names you need for extrude_cut's target_bodies / reference_name arguments.

modify_dimensionA

Change a single dimension on a feature in the active part or assembly.

Args: feature_name: Exact name of the feature, e.g. "Boss-Extrude1" — or a mate name ("Distance1") when an ensamble is active. dimension_name: Exact name of the dimension within the feature, e.g. "D1". new_value_mm: New value in millimeters (degrees for angle dims, including angle mates).

Returns the updated feature state.

list_dimensionsA

Descubre qué dimensión mover — lista TODAS las cotas del documento activo.

El paso de descubrimiento para edición conversacional ("hazlo 5mm más largo", "cambia el barreno a Ø8"): enumera cada dimensión alcanzable — de operaciones Y de croquis — con su path exacto ("D1@Saliente-Extruir1"), valor actual y unidades. Para mapear lenguaje a la cota correcta, cruza el VALOR hablado con los valores listados (el largo de 80 → la cota que vale 80); en empate, desambigua por owner_type o pregunta. Luego pasa owner/name verbatim a modify_dimension. Read-only.

Returns: {count, dimensions: [{path, owner, owner_type, name, value, units("mm"|"deg")}]}. Con un ensamble activo lista las cotas de mates (D1 de distance/angle; owner_type "mate_distance"/"mate_angle") — las cotas internas de componentes requieren abrir la pieza. Caveat (COM): cotas renombradas fuera de D1..Dn no aparecen; una cota angular de croquis se reporta como longitud en mm.

get_active_assembly_infoA

Return metadata about the currently active SolidWorks assembly.

Includes assembly name, modified flag, active configuration, all configurations, components (top-level only — no sub-assembly recursion), and existing mates. Call this before any mate / suppression / configuration operation so the LLM knows what entities exist.

insert_componentA

Insert a part or sub-assembly into the active assembly at the given XYZ.

IMPORTANT (mate-or-incomplete): insert_component alone does NOT finish the job. The FIRST component in an assembly is auto-fixed, but every subsequent component needs ≥1 mate (concentric / coincident / distance, or the composites stack_components / add_mate_by_face_position) before the assembly is valid. An assembly with floating components is wrong even if the iso view looks placed correctly. If you can't identify mating entities at insert time, call get_active_assembly_info first or ASK the user — don't push a floating component. See ASSEMBLY_DESIGN.md for the full SKELETON → MATE PLAN → INSERT+MATE → VERIFY loop.

Args: file_path: Absolute path to the .sldprt or .sldasm to insert. x_mm, y_mm, z_mm: Insertion point in mm (assembly frame). config_name: Specific source-document configuration to use; empty string uses the source's currently-active configuration.

Returns the inserted component's instance metadata.

Related: add_concentric_mate, add_coincident_mate, add_distance_mate, stack_components (3 mates in one call for stacked pairs), add_mate_by_face_position (no-entity-name convenience).

move_componentA

Mover componente — set a component's pose (drag-equivalent).

Sets the component's assembly-frame position (and optionally its 3x3 rotation, row-major) via IComponent2.Transform2, then rebuilds. Use it to stage a component at its EXACT pose before creating mates — angle and distance mates have two solutions each and capture the branch nearest the creation-time pose, so posing first then mating (see place_and_mate) eliminates the mirror-flip failure mode.

Args: component_name: Instance name from get_active_assembly_info. origin_mm: [x, y, z] target position of the part origin (mm). rotation_rows: Optional 9 row-major 3x3 rotation entries; None keeps the current rotation.

Returns requested vs post-rebuild pose plus moved (False = the pose did NOT hold: the component is fixed or fully mate-driven — report it, don't assume).

place_and_mateA

Posicionar y matear — pose a component exactly, THEN create its mates.

The branch-safe mating recipe: angle/distance mates are bistable (two solutions; rebuilds can flip to the mirror). Creating each mate while the component already sits at the exact target pose makes the solver capture the intended branch. After the mates, the pose is read back and compared against the request — pose_held=False means a mate pulled the component elsewhere (wrong branch / conflicting mate): fix it, don't trust it.

Args: component_name: Instance name from get_active_assembly_info. origin_mm / rotation_rows: Exact target pose (see move_component). mates: Ordered mate specs, each {"type": "coincident"|"concentric"|"distance"|"angle", "entity1_id": ..., "entity2_id": ..., "component2_name": ..., # the mate partner "align": "ALIGNED"|"ANTIALIGNED", # optional "distance_mm": float, "angle_deg": float} # per type pose_tolerance_mm: Max |Δorigin| per axis for pose_held (default 0.1).

Returns {pose_before, mates, pose_after, pose_held}.

add_concentric_mateA

Mate concéntrico — alinea ejes de dos entidades cilíndricas/cónicas.

Uso típico autopartes: alineación de ejes de barrenos (perno + bocina, bocina + flecha, dos cojinetes en una caja). [en: Add a concentric mate between two cylindrical / conical entities — typical autoparts use is aligning bolt+sleeve, sleeve+shaft, or two bearings in a housing.]

Args: component1_name, component2_name: SW component instance names from get_active_assembly_info (e.g. "bracket_L-1"). entity1_id, entity2_id: SW entity name strings, e.g. "Face@bracket_L-1@assy" (locale-sensitive — copy verbatim from the assembly info response). align: "ALIGNED" or "ANTIALIGNED".

Returns the created mate's metadata.

Related: add_mate_by_face_position (no-entity-name convenience for box-style components), stack_components (3 mates in one call for a fully-constrained stacked pair).

add_coincident_mateB

Mate coincidente — empareja dos entidades planas (caras o planos).

Uso típico autopartes: cara-contra-cara entre brida y placa, plano base de un sub-ensamble contra el plano de montaje del ensamble principal. Mismo formato de argumentos que add_concentric_mate. [en: Add a coincident mate between two planar entities. Typical use: flange-to-plate face contact, sub-assembly base plane against the parent assembly's mounting plane. Same argument shape as add_concentric_mate.]

Related: add_mate_by_face_position (no-entity-name convenience), stack_components (3 mates in one call).

add_distance_mateB

Mate de distancia — fuerza un offset fijo entre dos entidades.

Uso típico autopartes: separación entre placas paralelas, espacio entre dos cojinetes en una flecha, gap controlado entre componentes. [en: Add a distance mate (fixed offset) between two entities. Typical use: parallel plate separation, bearing-to-bearing distance on a shaft, controlled gap between components.]

Args: distance_mm: The fixed distance to enforce, in millimeters. Other args: same as add_concentric_mate.

Returns the created mate's metadata.

Related: add_mate_by_face_position (no-entity-name convenience), stack_components (3 mates in one call for fully-constrained pair).

add_sketch_chamferA

Chaflán de croquis — corta una esquina del croquis con un chamfer a 45° (distancia igual en ambos lados). Reemplaza el vértice donde dos líneas se encuentran con una tercera línea inclinada.

Uso típico CSWA Tool Block: las esquinas del outline llevan chamfers como "5×45°" (= distance_mm=5). Es más limpio que dibujar la línea inclinada a mano.

[en: Sketch chamfer — cuts a sketch corner with a 45° equal-distance chamfer. Replaces the vertex where two sketch lines meet with a third inclined line. Typical for the CSWA Tool Block outline.]

Args: line1_x_mm, line1_y_mm: A point that lies ON the first line. Typically near the corner — SW picks the closest segment. line2_x_mm, line2_y_mm: A point that lies ON the second line. distance_mm: The chamfer distance from the corner along EACH line. A 45° chamfer with distance_mm=14 means each adjacent line is shortened by 14 mm and the corner is connected by a new line at 45°. z_mm: Z-coordinate of the points (default 0 — front-plane sketches).

Returns the chamfer's metadata.

Requires the sketch to be in EDIT mode (just like add_sketch_dimension). The two selected lines must be ADJACENT (share an endpoint), else SW rejects the chamfer.

Gotcha: in this binding ISketchManager.CreateChamfer is not universally reachable. If it fails, the recommended workaround is to draw the chamfer manually using two create_line calls.

Related: chamfer (3D edge chamfer, not sketch corner).

add_sketch_filletA

Redondeo de croquis — redondea una esquina del croquis con un arco tangente de radio dado entre dos líneas adyacentes. Reemplaza el vértice donde dos líneas se encuentran con un arco.

Uso típico CSWA Tool Block: las esquinas internas llevan redondeos "R3" (= radius_mm=3). Más limpio y exacto que dibujar el arco a mano con create_arc.

[en: Sketch fillet — rounds a sketch corner with a tangent arc of the given radius between two adjacent sketch lines. Typical for the CSWA Tool Block rounded corners.]

Args: line1_x_mm, line1_y_mm: A point that lies ON the first line (near the corner — SW picks the closest segment). line2_x_mm, line2_y_mm: A point that lies ON the second line. radius_mm: The fillet radius, in mm. z_mm: Z-coordinate of the points (default 0 — front-plane sketches).

Returns the fillet's metadata.

Requires the sketch to be in EDIT mode. The two selected lines must be ADJACENT (share an endpoint), else SW rejects the fillet.

Related: add_sketch_chamfer (45° corner cut); fillet (3D edge round).

add_sketch_dimensionA

Cota de croquis — agrega una dimensión gobernante (driving dimension) a la entidad de croquis que pasa por el punto (x, y, z) dado. La cota queda nombrada automáticamente "D1@Croquis1", "D2@Croquis1", etc.

Uso típico CSWA: tras dibujar el outline del Tool Block con create_line/create_arc, agregar cotas a los segmentos clave (A=largo total, B=alto total) para luego ligarlas a variables globales y parametrizar el diseño.

[en: Sketch dimension — add a driving dimension to the sketch entity that lies at the given point. Auto-named "D1@", "D2@...", etc. Used to make a sketch parametric so its dimensions can be modified in-place (vía modify_dimension) or linked to a global variable.]

Args: entity_x_mm, entity_y_mm, entity_z_mm: A point in the part frame (mm) that lies ON the sketch entity to dimension (e.g., the midpoint of a sketch line, or a point on a sketch circle's perimeter). SW selects the closest sketch segment to this point. value_mm: The desired dimension value, in millimeters. SW first creates the dim with the entity's current geometric value, then this tool overrides it to value_mm (forcing the geometry to update). text_offset_x_mm, text_offset_y_mm: Where to place the dim text, as an offset from the entity point in mm. Cosmetic only; defaults to (20, 10) for legible callouts.

Returns: the dim's full name (e.g., "D1@Croquis1"), suitable for use with modify_dimension(sketch_name, "D1", new_value_mm) or for binding to a global variable via an equation.

Requires the sketch to be in EDIT MODE — call right after create_sketch / create_sketch_on_face and BEFORE the sketch is closed by extrude_sketch / extrude_cut.

Gotcha: SW infers the dim TYPE from what was selected (line→length, circle→diameter, two lines→angle). If you pass a point that lies on a circle's perimeter, you get a diameter dim. To force a specific type, ensure your entity_point is clearly inside one entity.

add_sketch_relationA

Relación de croquis — agrega una restricción geométrica (horizontal, vertical, coincident, tangent, equal, fix) a uno o dos segmentos del croquis activo. ESTA es la pieza que faltaba para que un croquis quede TOTALMENTE DEFINIDO y no "nade" 1-2 mm cuando SolidWorks resuelve sus relaciones automáticas.

Uso típico CSWA: tras dibujar el outline con create_line/create_arc, fija las aristas planas con 'horizontal'/'vertical' y combínalas con add_sketch_dimension (cotas gobernantes) hasta que el croquis se vuelva negro (totalmente definido). Así A/B/C quedan paramétricas y un cambio es una sola llamada a modify_dimension — sin reconstruir desde cero.

[en: Sketch relation — add a geometric constraint (horizontal/vertical/ coincident/tangent/equal/fix) to one or two segments of the active sketch. This is what makes a sketch FULLY DEFINED so it stops drifting 1-2 mm under SW's auto-relations.]

Args: relation: one of "horizontal", "vertical", "coincident", "tangent", "equal", "fix". horizontal/vertical/fix take 1 point; coincident/ tangent/equal take 2. entity_points_mm: list of [x, y] (or [x, y, z]) points in mm, each lying ON a target sketch segment (the closest segment is picked).

Returns {relation, constraint, sketch_name, points}.

Requires the sketch in EDIT mode (call after the geometry, before extrude_sketch closes it). No rebuild — locked in on the next exit.

Related: add_sketch_dimension (driving cotas); add_sketch_fillet / add_sketch_chamfer (corner geometry).

add_global_variableA

Agregar variable global (ecuación) — declara un parámetro nombrado como "A", "B", "C" que las dimensiones de croquis y de feature pueden referenciar mediante una ecuación. Requisito habitual para piezas paramétricas como el CSWA Tool Block donde A, B, C deben modificarse entre pasos sin reconstruir.

[en: Add a global variable (equation) — declare a named parameter like "A", "B", "C" that sketch and feature dimensions can reference via an equation. Standard requirement for parametric parts like the CSWA Tool Block where A, B, C must change across steps without rebuilding.]

Args: name: Variable name (LHS of the equation). Cannot contain quotes, =, comma, or @. SW convention: short uppercase, e.g. "A", "B". value: The numeric value in the specified units. units: "mm" (default, length), "deg" (angle), or "raw" (dimensionless). SW stores values internally as meters / radians; this argument controls the equation suffix and the internal conversion.

Returns dict with: name, value, units, equation (raw SW string like '"A" = 81mm'), index (0-based position in the equation table).

Binding a dim to this variable: after creating the global, ADD ANOTHER EQUATION whose LHS is the dim name and whose RHS is the variable: add_global_variable("D1@Croquis1", '"A"', units="raw") (Pass an expression string; the equation manager accepts dim-paths on the LHS in addition to variable names.)

To change the value later, use set_global_variable. Do NOT call add_global_variable again with the same name.

Related: set_global_variable (modify existing), modify_dimension (feature dims only, not global vars).

set_global_variableA

Modificar una variable global existente — actualiza el valor de A, B, C después de haberla creado. Todas las dimensiones ligadas (vía ecuación) se reconstruyen automáticamente.

Uso típico CSWA: tras construir el Tool Block con A=10, B=20, C=30, cambia a A=12, B=22, C=32 antes de leer la masa nueva.

[en: Modify an existing global variable — updates the value of A, B, C after creation. All dimensions bound to it (via equation) rebuild automatically.]

Args: name: The existing variable name (must already exist). new_value: New numeric value in the specified units. units: Optional. If omitted, the previously-set units are preserved. Pass "mm" / "deg" / "raw" to change unit type.

Returns the updated GlobalVariable dict.

Raises ValueError if the variable doesn't exist (call add_global_variable first).

add_angle_mateA

Mate de ángulo — fuerza un ángulo fijo entre dos entidades.

Uso típico autopartes: articulaciones de eslabón (cadena, bisagra), posiciones angulares de palancas y brazos, configuraciones rotadas de subconjuntos. Las dos entidades deben ser PLANARES (caras planas o planos de referencia) o EJES — no se puede aplicar un mate de ángulo entre dos caras cilíndricas concéntricas. [en: Add an angle mate (fixed angular offset) between two entities. Typical use: chain-link articulation, hinge angles, lever/arm rotational positions, rotated subassembly configs. Both entities must be PLANAR (planar faces or reference planes) or AXES — angle mates cannot be applied between two concentric cylindrical faces.]

Args: angle_deg: The fixed angle to enforce, in degrees. Positive rotates per SW's right-hand-rule about the inferred axis. Other args: same as add_concentric_mate.

Returns the created mate's metadata (including angle_deg).

Gotcha: if both selected entities are coplanar, SW's solver may reject the mate (over-defined). Choose entities that share a rotation axis but aren't already parallel at angle 0°.

Related: add_mate_by_face_position (no-entity-name convenience for coincident/distance only — angle mates still need entity strings).

set_component_suppressionA

Cambiar el estado de carga de un componente en el ensamble activo.

Uso típico autopartes: suprimir/resolver componentes para crear variantes de configuración (con/sin opcionales), o aligerar grandes ensambles con cientos de tornillería usando estado "lightweight". [en: Set a component's load state in the active assembly. Typical use: suppress/resolve to build configuration variants, or use 'lightweight' on big assemblies with hundreds of fasteners.]

Args: component_name: SW component instance name from get_active_assembly_info. state: One of "suppressed" (hidden, excluded from BOM, not loaded), "resolved" (fully loaded, default), or "lightweight" (graphics only — saves memory in large assemblies, common in autoparts sub-assemblies with 100+ fasteners). config_scope: "this" (active config only — fast), "all" (apply to every configuration in the document), "specific" (apply to configs listed in config_names). config_names: List of configuration names; required when config_scope="specific". Example: ["Sport", "Premium"] to suppress in those trim variants only.

Returns the component's updated state for the active configuration.

set_components_suppressionA

Cambiar el estado de varios componentes en una sola llamada.

Uso típico autopartes: preparación de variantes BOM ("suprime los 8 tornillos que el Base trim no incluye"). Más eficiente que un bucle sobre set_component_suppression — cuando config_scope es "all" o "specific", la implementación cambia de configuración una sola vez por config y aplica todos los componentes en ese contexto. [en: Apply the same suppression state to multiple components in one call. Typical use: trim-variant BOM prep — suppress N fasteners a Base trim doesn't include. Faster than looping set_component_suppression: switches config once per config_scope target instead of once per (component × config) pair.]

Args: component_names: List of SW component instance names from get_active_assembly_info. Must not be empty. All names are validated up-front; if any are missing the call raises before any change is made. state: "suppressed" | "resolved" | "lightweight". Default "suppressed". config_scope: "this" | "all" | "specific". config_names: Required when config_scope="specific".

Returns: Dict with count (number applied), state (the applied state), and components (list of {name, path, suppressed, state}).

set_mate_suppressionA

Suprimir o resolver un mate por nombre.

Casos de uso: desactivar un mate de rama incorrecta antes de recrearlo con place_and_mate (la receta pose→mate), y limpiar tras supresión de componentes. Nota (verificado en vivo 2026-06): en esta versión de SW, suprimir un componente NO marcó sus mates como suprimidos en la enumeración — el snapshot-diff de abajo es barato y cubre versiones donde sí cascada. [en: Suppress or resume a mate by name. Uses: park a wrong-branch mate before recreating it via place_and_mate, and post-component-suppression cleanup. Live note: on this SW version component suppression did NOT flip its mates' suppressed flags; the snapshot-diff below is cheap and covers versions where the cascade does happen.]

Workflow for cascade-aware resume: 1. Snapshot mates BEFORE suppressing the component: before = {m["name"] for m in get_active_assembly_info()["mates"] if m["suppressed"]} 2. Suppress the component, do your work, then resume it. 3. Snapshot mates AFTER: after = {m["name"] for m in get_active_assembly_info()["mates"] if m["suppressed"]} 4. The orphans are after - before. For each, call set_mate_suppression(mate_name, suppressed=False) to restore.

Args: mate_name: SW-assigned mate name from get_active_assembly_info, e.g. "Coincidente7". suppressed: True to suppress, False to resume (resolve).

Returns the mate's metadata with the new suppressed state.

add_mate_by_face_positionA

Crea un mate entre dos componentes usando posiciones de cara.

Conveniencia: en lugar de copiar nombres de entidades sensibles a locale ("Cara<1>@bracket-1@assy"), nombras la cara por su posición relativa en el componente — "top"/"bottom"/"left"/"right"/"front"/ "back". El tool resuelve la cara cuyo normal apunta en el eje pedido. [en: Mate two components by face position — convenience wrapper avoiding locale-sensitive face-index or entity-name handling. Resolves position keywords to the matching face on each component.]

Args: component1_name, component2_name: SW component instance names from get_active_assembly_info, e.g. "Pieza1-5" / "Pieza1-6". face1_position, face2_position: One of "top", "bottom", "left", "right", "front", "back". Interpreted in each component's local coordinate frame: - top = +Y (highest Y face) - bottom = -Y (lowest Y face) - right = +X left = -X - back = +Z front = -Z (the original sketch face for an extrusion in +Z direction). For Pieza-style box parts inserted at default orientation this matches viewport intuition. mate_type: "coincident" (parts touch face-to-face) or "distance" (parts maintain a fixed offset). distance_mm: Required for "distance" mates; ignored for "coincident". align: "ALIGNED" (face normals same direction — parts overlap) or "ANTIALIGNED" (face normals opposite — parts touch). Default "ANTIALIGNED" because that's the typical stacking intent.

Example — stack Pieza1-6 on top of Pieza1-5: add_mate_by_face_position( "Pieza1-5", "top", "Pieza1-6", "bottom", mate_type="coincident", )

stack_componentsA

Apila dos componentes con restricción completa (3 mates en una llamada).

Un solo mate cara-contra-cara solo bloquea UN eje — los componentes quedan libres en los otros dos. Esta herramienta hace tres mates en una sola llamada: las dos caras nombradas se tocan Y los componentes comparten posición en los otros dos ejes. Uso típico: apilar piezas para fixture de ensamble, montar bocina sobre placa, alinear placas paralelas. [en: Fully constrain two components in a stacked arrangement (3 mates in one call). A single face mate locks only ONE axis — this tool creates three so the components are fully positioned: the named faces touch AND positions match on the other two axes.]

Args: component1_name, component2_name: SW component instance names from get_active_assembly_info. face1_position, face2_position: One of "top", "bottom", "left", "right", "front", "back". MUST be on opposite ends of the same axis (e.g., "top" + "bottom", "left" + "right", "front" + "back"). Same-direction pairs or different-axis pairs raise ValueError.

Example — stack Pieza1-A on top of Pieza1-B (A's bottom touches B's top, same X and Z position): stack_components("Pieza1-A", "bottom", "Pieza1-B", "top")

Returns: Dict with mates list of three Mate dicts in creation order: [touching_faces_mate, perp_axis_1_mate, perp_axis_2_mate].

create_configurationA

Crear una configuración nueva en la pieza o ensamble activo.

Una configuración es metadata: comparte la geometría base pero permite variar supresiones de componentes/features y valores de dimensiones. Es la vía v1 para variantes (trim, tamaño, opcionales) sin duplicar archivos. [en: Create a new configuration on the active part or assembly. A configuration is metadata: shares base geometry but lets you vary component/feature suppressions and dimension values — the v1 path for variants without duplicating files.]

Args: name: New configuration name (must be unique; idempotent if it exists). parent: Optional parent configuration name (for derived configs). description: Optional description for the configuration.

Returns the configuration name.

Gotcha (verificado en vivo): crear la configuración la ACTIVA — la config activa ya no es la anterior. Lee active_config antes de confiar en operaciones "scoped" subsecuentes, y reactiva la config original si no querías cambiarte.

Related: build_variant_family (one call to create N configurations that vary suppressions and dimensions — use this when the user asks for "small/medium/large" or "M6/M8/M10" trim variants instead of N separate create_configuration calls).

activate_configurationA

Activar otra configuración del documento activo.

El cambio dispara un rebuild: las supresiones y dimensiones definidas para la configuración objetivo se aplican. Útil para verificar que una variante construida con build_variant_family se ve correcta antes de guardar. [en: Switch the active document to a different configuration. The switch triggers a rebuild — suppressions and dimension values defined for the target config take effect. Useful to verify a variant built with build_variant_family looks right before saving.]

Args: name: Name of the configuration to activate.

Returns the previously-active configuration name.

delete_configurationA

Eliminar una configuración del documento activo.

Es la ÚNICA herramienta de eliminación en el v1 MCP — borrar componentes o features no está expuesto. La supresión cubre la mayoría de los casos legítimos de "haz que esto desaparezca" reversiblemente. Configuration deletion es la excepción porque las configuraciones son pura metadata: borrar no cascada a geometría rota. [en: Delete a configuration from the active document. This is the ONLY deletion tool in the v1 MCP — component and feature deletion are intentionally not exposed; suppression covers most reversible "make this go away" needs. Configurations are the carveout because they're pure metadata — deletion can't cascade into broken geometry.]

Validates up-front that: - The configuration exists. - It is NOT the active configuration (SW would refuse; activate a different one first via activate_configuration). - It is NOT the only configuration in the document.

Use case: cleanup of obsolete trim variants after an ECN deprecates them, or removing test/scratch configurations from an iteration cycle.

Args: name: The configuration to delete.

Returns the deleted configuration name on success.

save_active_documentA

Guardar el documento activo de SolidWorks (pieza, ensamble o dibujo).

Guarda en silencio (sin abrir cuadros de diálogo). Equivalente a Ctrl+S en SW. Solo funciona si el documento ya tiene un nombre de archivo asignado — para guardar una pieza recién creada usa save_as. [en: Save the currently active document silently (no UI dialogs). Equivalent to Ctrl+S. Only works if the document already has a filename — for a fresh, never-saved document use save_as.]

Returns a dict with:

  • name: document title

  • path: filesystem path of the saved document

  • saved: True if save succeeded

  • errors: bitmask of swFileSaveError_e codes (0 if none)

  • warnings: bitmask of swFileSaveWarning_e codes (0 if none)

Raises:

  • SolidWorksError if no document is active.

  • SolidWorksError if the active document has never been saved (no filename). The user must File → Save As in SW first to set a target filename — we don't pop dialogs from this tool. Or call save_as(path) below to set the filename programmatically.

save_asA

Guardar el documento activo a una ruta explícita (Save As).

A diferencia de save_active_document, esta sí funciona con piezas recién creadas que aún no tienen nombre de archivo. Una vez guardadas, los siguientes save_active_document escriben a la misma ruta. [en: Save the active document to an explicit file path. Unlike save_active_document — which only works on docs that already have a filename — save_as handles a fresh, never-saved document and sets its filename in one call. Subsequent save_active_document calls then save back to this same path.]

Args: path: Absolute file path INCLUDING extension. SolidWorks infers the document type from the extension: .SLDPRT parts .SLDASM assemblies .SLDDRW drawings Passing the wrong extension for the active doc type causes SaveAs to fail.

Returns the same dict as save_active_document:

  • name: document title

  • path: filesystem path written to

  • saved: True if save succeeded

  • errors / warnings: 0 (the simpler SaveAs variant doesn't expose these — use save_active_document on a subsequent save if you need the bitmasks).

Common autoparts use: scripted runs that build a part from scratch, save it to a customer-controlled directory, and hand off the path to a downstream step.

Caveats:

  • The parent directory must exist; save_as does NOT mkdir.

  • En Windows en español con OneDrive (la configuración típica del cliente PYME), el escritorio del usuario es C:\Users\<user>\OneDrive\Escritorio, NO C:\Users\<user>\Desktop (esa ruta no existe). Si el usuario dice "guárdalo en el escritorio" sin path explícito, prueba primero la ruta de OneDrive\Escritorio. [en: On Spanish-Windows + OneDrive — the typical PYME setup — the user's Desktop is C:\Users\<user>\OneDrive\Escritorio, not C:\Users\<user>\Desktop (which doesn't exist). When the user says "save it to the Desktop" without an explicit path, try the OneDrive\Escritorio path first.]

Example — save a fresh part: save_as(r"C:\Users\danie\OneDrive\Escritorio\bracket_v1.SLDPRT")

open_documentA

Abrir un documento de SolidWorks existente por ruta absoluta.

Carga un .SLDPRT / .SLDASM / .SLDDRW ya guardado. El tipo se infiere de la extensión y SW lo activa automáticamente — el documento abierto pasa a ser el documento activo que reportan get_active_part_info, list_faces, list_edges, etc. [en: Open an existing SolidWorks document by absolute path. Doc type is inferred from the extension; SW auto-activates the opened doc so the standard "active document" tools (get_active_part_info, etc.) operate on it immediately.]

Úsalo para "modifica esta pieza guardada" — se reabre y se modifica en su lugar, nunca se rehace desde cero.

Args: path: Ruta absoluta al archivo INCLUYENDO la extensión. La extensión determina el tipo: .SLDPRT parts (swDocPART) .SLDASM assemblies (swDocASSEMBLY) .SLDDRW drawings (swDocDRAWING) Cualquier otra extensión → SolidWorksError.

Returns: { "name": str, # title del doc (sin trailing '*') "path": str, # path tal cual lo pasaste "type": "part" | "assembly" | "drawing", "opened": True, "errors": 0, # bitmask placeholder (OpenDoc6 path "warnings": 0, # for these is v1.1) }

Raises: - ValueError si path está vacío. - SolidWorksError si el archivo no existe en disco (mensaje incluye la pista del Escritorio de Spanish-Windows + OneDrive). - SolidWorksError si la extensión no es .SLDPRT/.SLDASM/.SLDDRW. - SolidWorksError si SW devuelve None (archivo corrupto, versión más nueva que la instalación, mismatch tipo↔extensión).

Caveat:

  • Usa ISldWorks.OpenDoc (la variante simple de 2 args), no OpenDoc6. Por eso errors/warnings vienen siempre en 0 — el bitmask completo requiere VARIANT BYREF bajo pywin32 late-binding y está deferido a v1.1. Para "abrió bien o no", basta con "opened": True.

  • Si ya hay un documento con el mismo nombre abierto en SW, SW activa el existente en vez de re-abrir. Comportamiento default de SW — no lo sobreescribimos.

  • En Windows en español con OneDrive, el escritorio del cliente es C:\Users\<user>\OneDrive\Escritorio, NO C:\Users\<user>\Desktop. Si el usuario dice "abre la pieza del escritorio" sin path, usa la ruta de OneDrive\Escritorio.

Example — abrir una pieza guardada y verificar: open_document(r"C:\Users<user>\OneDrive\Escritorio\bracket.SLDPRT") get_active_part_info() # name + saved feature tree (Para refrescar tras una edición externa: close_active_document(force=True) → open_document(...).)

close_active_documentA

Cerrar el documento activo en SolidWorks.

Útil para flujos iterativos (build → save_as → close → new_part → rebuild) que de otra manera dejan ventanas viejas abiertas y hacen que save_as falle por colisión de archivo. Por defecto exige que el documento esté guardado; pasa force=True para descartar cambios sin aviso. [en: Close the active document in SolidWorks. Used in iterative build/save/rebuild flows that otherwise pile up open windows and make save_as collide on the open file. Default refuses to close a dirty doc; force=True discards unsaved changes silently.]

Args: force: False (default) raises if the active document has unsaved changes. True silently discards them — use ONLY when the doc is disposable (e.g., rebuilding from scratch). Distinct verbs under the hood: ISldWorks.CloseDoc for clean docs, ISldWorks.QuitDoc for force-discards.

Returns dict: closed: True if the close succeeded. name: The document title at the time of close (trailing '*' stripped if present). was_modified: Whether the document had unsaved changes at the moment of close (== True only when force=True was needed).

Raises: - SolidWorksError if no active document. - SolidWorksError if the document was dirty and force=False.

Example — canonical iterative-rebuild flow: save_as(r"C:\Users\danie\OneDrive\Escritorio\flecha.SLDPRT") close_active_document() # default: errors if unsaved new_part() # fresh blank # ... rebuild geometry ...

Example — force-close a throwaway probe: close_active_document(force=True)

new_partA

Crear una pieza nueva y vacía en SolidWorks (documento .SLDPRT).

Abre y activa una pieza en blanco desde la plantilla por defecto. Úsalo cuando no haya pieza abierta o quieras empezar desde cero — las demás herramientas de geometría requieren una pieza activa. [en: Create + activate a new empty part. Use when no part is open or you want a fresh start — geometry tools require an active part.]

Returns: {"name": str, "type": "part", "created": True}

Caveat: requiere SolidWorks abierto (NO lanza el proceso). Si no hay plantilla de pieza por defecto, usa la creación legacy. [en: requires SW already running; does not launch it.]

new_assemblyA

Crear un ensamble nuevo y vacío (documento .SLDASM).

Abre y activa un ensamble en blanco desde la plantilla por defecto. Punto de partida para insertar componentes y mates. [en: Create + activate a new empty assembly — the starting point for inserting components and mates.]

Returns: {"name": str, "type": "assembly", "created": True}

Caveat: requiere SolidWorks abierto (NO lanza el proceso). [en: requires SW already running; does not launch it.]

undoA

Deshacer el ÚLTIMO paso de SolidWorks (Ctrl+Z / EditUndo2).

ADVERTENCIA: undo es GRUESO. Deshace el último paso de SolidWorks, que NO necesariamente es tu última llamada de herramienta MCP — una herramienta puede ser varios pasos SW (o ninguno). NO recupera un documento cerrado o perdido (eso se previene guardando pronto). Verifica con capture_views / get_active_part_info después de deshacer; NO encadenes undos a ciegas. [en: WARNING — undo is COARSE. It reverses the LAST SolidWorks step, NOT necessarily your last MCP tool call (one tool can be several SW steps, or none). It CANNOT recover a closed/lost document (save early instead). Verify with capture_views after; do NOT chain blind undos.]

Returns: {"undone": bool, "note": str} — undone=False means there was nothing to undo (reported honestly, not faked).

rollback_to_featureA

Retroceder — mueve la barra de retroceso a JUSTO ANTES de la operación indicada, suspendiéndola (y todo lo posterior) del cálculo. REVERSIBLE: llama rollback_to_end para restaurar. Es la alternativa SIN-BORRADO a eliminar una operación equivocada — la política del repo difiere el borrado, así que aquí nada se destruye.

[en: Roll the feature tree back to just BEFORE the named feature (suspends it + everything after, reversibly). The no-deletion way to 'undo' a wrong feature — call rollback_to_end to restore.]

Args: feature_name: exact feature name, e.g. "Cortar-Extruir1".

Returns {rolled_back_to, rollback_index, suspended_count, ok}.

Related: rollback_to_end (restore); set_component_suppression (the assembly-level reversible equivalent); undo (coarse, NOT reversible).

rollback_to_endA

Restaurar — mueve la barra de retroceso al final, reactivando todas las operaciones que rollback_to_feature haya suspendido.

[en: Roll the feature tree forward to the end, restoring everything a prior rollback_to_feature suspended.]

Returns {rolled_back_to: None, ok}.

create_sketchA

Start a new sketch on a named reference plane.

Args: plane_name: One of "front", "top", "right" (lowercase English), OR the Spanish UI names "Alzado" (Front), "Planta" (Top), "Vista lateral" (Right). Spanish UI names are case-sensitive.

Returns the new sketch's name (e.g., "Croquis5") and the resolved plane name. The sketch is left in EDIT mode — call create_rectangle (and other future primitives) to add geometry, then extrude_sketch to close and turn it into a 3D feature.

Caveat: requires a part document (not assembly). Open a fresh part via SW UI before calling.

edit_sketchA

Reabrir un croquis existente para editarlo (agregar cotas, relaciones, o geometría) SIN reconstruir la pieza desde cero. Tras reabrir, las herramientas add_sketch_dimension / add_sketch_relation / create_line funcionan igual que en un croquis recién creado.

Uso típico CSWA: parametrizaste el Tool Block con cotas A/B/C; para ajustar otra arista, reabre el croquis con edit_sketch, agrega/edita, y sal con la siguiente operación (extrude/etc.) para fijar el cambio.

[en: Reopen an existing sketch for editing (dims, relations, geometry) without rebuilding the part. After reopening, add_sketch_dimension / add_sketch_relation / create_line behave as on a fresh sketch.]

Args: sketch_name: exact sketch name, e.g. "Croquis1".

Returns {name, editing: True}. The sketch stays OPEN — you MUST exit it (extrude_sketch or another sketch-consuming op) to lock the changes in; a rebuild while open will exit it on SW 2026 ES.

Related: create_sketch (new sketch); modify_dimension (drive a named cota without even reopening).

create_rectangleA

Draw a corner-defined rectangle on the active sketch.

Args: x1_mm, y1_mm: One corner of the rectangle in mm (sketch-local). x2_mm, y2_mm: The opposite corner.

The rectangle is added to whatever sketch was started by the most recent create_sketch() call. Returns the rectangle's geometric properties (width and height in mm) for the LLM to verify.

Example — 50mm × 30mm rectangle starting at the origin: create_rectangle(0, 0, 50, 30)

Caveat: requires an active sketch (create_sketch first).

Caveat (paramétrico): el croquis NO es paramétrico. modify_dimension NO puede redimensionar el ancho/alto post-hoc — solo la profundidad de extrusión es paramétrica. Para cambiar el tamaño del rectángulo, reconstruye desde una pieza nueva. [en: Sketch geometry has NO driving dimension — modify_dimension cannot resize the rectangle post-hoc; only extrude depth is parametric. To resize, rebuild from a fresh part.]

Related: build_rectangular_pocket (sketch + cut in one call when the intent is a rectangular pocket — most common autoparts use of this primitive).

create_lineA

Draw a line on the active sketch.

Args: x1_mm, y1_mm: Start point in mm (sketch-local frame). x2_mm, y2_mm: End point.

Returns the line's geometry (endpoints + length). Used as a building block for non-rectangular profiles before extrusion.

Caveat: requires an active sketch (call create_sketch first).

Caveat (paramétrico): el croquis NO es paramétrico. modify_dimension NO puede mover los endpoints ni cambiar la longitud post-hoc — solo la profundidad de extrusión es paramétrica. Para cambiar la línea, reconstruye desde una pieza nueva. [en: Sketch geometry has NO driving dimension — modify_dimension cannot move endpoints or resize length post-hoc; only extrude depth is parametric. To resize, rebuild from a fresh part.]

create_circleA

Draw a circle on the active sketch.

Args: cx_mm, cy_mm: Center point in mm (sketch-local frame). Long-form aliases center_x_mm / center_y_mm accepted (kwarg-only) for parity with the composite tools (add_bolt_circle, build_rectangular_pocket, etc.). Pass one name per axis, not both. radius_mm: Circle radius in mm. Must be positive.

Returns the circle's center and radius/diameter. Common autoparts use: bolt holes, bearing bores, fillet circles before extruding/cutting.

Example — 8.5 mm clearance hole at origin (M8 medium per ISO 273): create_circle(0, 0, 4.25) # or equivalently: create_circle(center_x_mm=0, center_y_mm=0, radius_mm=4.25)

Caveat: requires an active sketch.

Caveat (paramétrico): el croquis NO es paramétrico. modify_dimension NO puede redimensionar el diámetro ni mover el centro post-hoc — solo la profundidad de extrusión es paramétrica. Si el usuario pide "hazlo más grande" o "cámbialo a Ø10", reconstruye desde una pieza nueva. [en: Sketch geometry has NO driving dimension — modify_dimension cannot resize the OD or move the center post-hoc; only extrude depth is parametric. To resize ("make it bigger"), rebuild from a fresh part.]

Related: add_bolt_circle (one call for N holes on a bolt circle — use instead of N create_circle + extrude_cut sequences for typical flange / bracket bolt patterns).

create_arcA

Arco — draw a center-defined arc on the active sketch.

Center + radius + start/end angles. The angle convention is standard math: 0° points along the +X sketch axis, angles grow CCW. The direction flag picks which of the two possible arcs (the short or long way around) gets drawn between the two endpoints.

Args: cx_mm, cy_mm: Arc center in mm (sketch-local frame). Long-form aliases center_x_mm / center_y_mm accepted (kwarg-only) for parity with the composite tools. Pass one name per axis. radius_mm: Arc radius in mm. Must be positive. start_angle_deg: Start angle from the +X sketch axis. Standard math convention (CCW-positive). end_angle_deg: End angle, same convention. Must differ from start_angle_deg (use create_circle for full circles). direction: "ccw" (default) sweeps counter-clockwise from start to end; "cw" sweeps the other way around. Counter- intuitive: for the SAME start/end angles, "ccw" and "cw" produce arcs that sweep opposite ways. Quarter-arc from start=180° to end=90°: "cw" → 90° sweep (natural quarter), "ccw" → 270° sweep (the long way around). If a revolve_sketch after the arc fails, the arc landed on the wrong side — flip direction.

Returns dict with center, radius, angles, direction, computed start/end XY coords, signed sweep angle, and arc length.

Common autoparts use: - Slot end-cap when create_slot doesn't fit (e.g. one-ended slot with custom radius) - 2D fillet between two lines in a sketch (radius = corner fillet, start/end angles set by the line directions) - Curved scraper / handle profiles where the chevron+slant polygon would otherwise approximate

Example — quarter circle, R=10, from +X axis to +Y axis, CCW: create_arc(0, 0, 10, 0, 90) # or equivalently: create_arc(center_x_mm=0, center_y_mm=0, radius_mm=10, start_angle_deg=0, end_angle_deg=90)

Example — rounded slot end at the right side of a horizontal slot (180° arc spanning the slot width = 6mm at x=50): create_arc(50, 0, 3, -90, 90)

Caveat: requires an active sketch (call create_sketch or create_sketch_on_face first).

create_slotA

Draw a straight slot on the active sketch.

The slot is a rounded-rectangle: a rectangle of (length × width_mm) with semicircular end-caps. The center line runs from (x1, y1) to (x2, y2); width_mm is the slot's narrow dimension.

Args: x1_mm, y1_mm: One endpoint of the center line. x2_mm, y2_mm: The other endpoint. width_mm: Slot width (diameter of the round end-caps).

Common autoparts use: adjustable bolt slots in stamped brackets, typically 1× thru 2× the bolt clearance diameter for ±tolerance.

Caveat: requires an active sketch.

Caveat (paramétrico): el croquis NO es paramétrico. modify_dimension NO puede redimensionar el ancho ni mover los endpoints post-hoc — solo la profundidad de extrusión es paramétrica. Para cambiar la ranura, reconstruye desde una pieza nueva. [en: Sketch geometry has NO driving dimension — modify_dimension cannot resize the slot width or move endpoints post-hoc; only extrude depth is parametric. To resize, rebuild from a fresh part.]

create_reference_planeA

Create a reference plane parallel to a default plane or a face.

Two anchoring modes (pass exactly ONE of offset_from / face_centroid_mm):

  1. Default-plane mode — pass offset_from as a default plane name. The new plane is parallel to that source plane, offset by offset_mm.

  2. Face mode (Lote 3 — chained features) — pass face_centroid_mm as a 3-element [x, y, z] from list_faces(). The new plane is parallel to that face, offset along the face's outward normal direction. Use case: anchor a sketch above an angled bracket flange, on a draft surface, or above a previously- extruded boss top.

Args: offset_from: Default plane name — "front" / "top" / "right" (English) or Spanish UI: "Alzado" / "Planta" / "Vista lateral". offset_mm: Signed distance in mm. Positive = along the source plane's normal (or the face's outward normal); negative = opposite. Zero is rejected (would produce a coincident plane). Offsets negativos verificados en vivo (2026-06): ±30 desde "top" producen planos espejo. Para ejes de mate sigue siendo buena práctica el barreno en el origen de la pieza + create_reference_axis("front","right") (cero planos custom). face_centroid_mm: [x, y, z] in mm — face centroid from list_faces().

Returns the new plane's SW-assigned name (e.g., "Plano1"), parent reference, and the signed offset.

Common autoparts use: - Default-plane: rib offsets, fixture-clearance planes, layer references for in-plane mate fixtures. - Face mode: counterbore-on-flange-top, hole pattern offset above an angled bracket flange, layer planes anchored to a previously-extruded surface.

Example — sketch plane 25mm above the Front plane: create_reference_plane("front", 25.0)

Example — sketch plane 10mm above the top of a 50×50×20 block (after list_faces returns the +Z face's centroid): faces = list_faces() top = max( (f for f in faces if f["normal"] and f["normal"][2] > 0.9), key=lambda f: f["centroid_mm"][2], ) create_reference_plane(face_centroid_mm=top["centroid_mm"], offset_mm=10)

Caveat: angled and through-3-points reference planes are still deferred — face + signed offset covers most v1 needs.

create_reference_axisA

Create a reference axis (eje de referencia) at the intersection of two planes — or, where supported, from a single feature reference.

Two ways to call:

  1. Two planes (recommended for v1) — pass both reference_name and reference_2 as plane names. The axis is created at their intersection. Verified live for default-plane combinations (Alzado + Planta, Alzado + Vista lateral, etc.). The most reliable v1 axis source.

  2. Single reference (limited) — pass only reference_name. Currently works for refplane / refaxis feature names, but face/edge names ("Cara@Pieza1") don't resolve in part-document context in this SolidWorks binding. Until face introspection ships, prefer the two-plane path.

World-axis mapping for the two-plane intersection mode. The intersection of two default planes through the origin lies along one of the world axes — which one depends on the pair you pick:

reference_name

reference_2

World axis returned

"front"

"top"

X (left-right)

"front"

"right"

Y (up-down)

"top"

"right"

Z (in-out)

(Spanish UI names map identically: "Alzado"+"Planta" → X, etc.)

For axisymmetric revolves around world X — the standard orientation that build_stepped_shaft and build_revolved_profile assume — use ("front", "top"). This is the same call build_stepped_shaft makes internally (see the construction site at build_stepped_shaft in this file). Picking ("front", "right") instead returns world Y and your revolve will sweep the wrong way around — surface gets rebuilt.

Args: reference_name: Name of the first entity. For two-plane mode, the first plane: "front"/"top"/"right" (English) or "Alzado"/"Planta"/"Vista lateral" (Spanish UI), or a custom "Plano1" from create_reference_plane. reference_2: Name of the second plane for two-plane intersection mode. Same naming rules as reference_name. Pass None for the single-reference mode.

Returns: {"name": "Eje1", "type": "two_plane_intersection" | "from_one_object"}

Use case: define a rotation axis for circular_pattern when you don't have a cylindrical-face name. The intersection of two perpendicular default planes through the origin is a perfectly good axis for any feature centered there.

Example — axis through the part origin (intersection of Front + Top), then 6-instance circular pattern around it: eje = create_reference_axis("front", reference_2="top") circular_pattern(["Cortar-Extruir1"], eje["name"], count=6)

linear_patternA

Pattern (patrón lineal) features in a single straight line.

Repeats one or more existing features along a direction at fixed spacing — the autoparts default for hole rows, fin arrays, and bolt grids. Single-direction only in v1; the second-direction (rectangular grid) variant is deferred since junior designers rarely use it.

Args: feature_names: Names of features to pattern. Pass exact names from get_active_part_info — e.g. ["Cortar-Extruir1"] for a single hole, ["Cortar-Extruir1", "Saliente-Extruir2"] for a hole + boss pair. direction_reference: Name of the entity defining the pattern direction. Easiest source: an "Eje1" name returned by a prior create_reference_axis call. Also accepted: a linear edge name (e.g. "Arista<1>@Pieza1") or a sketch-line name. Names are locale-sensitive. spacing_mm: Distance between consecutive instances in mm. Must be positive. count: Total number of instances INCLUDING the original (must be ≥ 2). For 5 holes total, pass count=5 — the original feature counts as instance #1. reverse: Flip the pattern direction along the reference. Default (False) follows the SW-default direction; pass True if the pattern goes the wrong way.

Returns the new pattern Feature with name (e.g. "LPattern1"), type ("linear_pattern"), and dimensions (D1=spacing, Num=count).

Example — 5 holes spaced 15 mm apart along an existing axis: eje = create_reference_axis("Arista<1>@Pieza1") # use a long edge linear_pattern(["Cortar-Extruir1"], eje["name"], spacing_mm=15.0, count=5)

mirror_featureA

Mirror (simetría) features about a plane or planar face.

Useful for symmetric brackets, mirrored mounting bosses, and any part where you've modeled half and want SW to mirror the rest. ≈50% of autoparts geometry has at least one mirror plane.

Args: feature_names: Names of features to mirror. Pass exact names from get_active_part_info — e.g. ["Cortar-Extruir1"] for a single hole, ["Saliente-Extruir2", "Cortar-Extruir3"] to mirror a boss + a hole together. mirror_plane: Name of the plane or planar face to mirror about. Accepts: - Default plane aliases: "front" / "top" / "right" (English) or "Alzado" / "Planta" / "Vista lateral" (Spanish UI). - User-created reference plane: "Plano1" / "Plano2" etc. (returned by create_reference_plane). - Planar face name: e.g. "Cara<3>@Pieza1" for a flat face. geometry_pattern: When True (default), the mirror is a fast exact-geometry copy. Pass False to make SW recompute each mirrored feature's dimensions from scratch — useful when the source feature uses sketch dimensions that should re-evaluate on the mirrored side.

Returns the new mirror Feature with name (e.g. "Simetría1") and type ("mirror_feature").

Example — mirror a hole pattern about the part's centerline (Front plane in this binding): mirror_feature(["Cortar-Extruir1", "LPattern1"], "front")

circular_patternA

Circular pattern (patrón circular) — repeat features around an axis.

Standard autoparts use: bolt circles on flanges, fan blades, gear teeth blanks, dial markings. Always preceded by a create_reference_axis call to define the rotation axis.

Args: feature_names: Names of features to pattern. Pass exact names from get_active_part_info — e.g. ["Cortar-Extruir1"] for one hole. axis_name: Name of the axis to rotate around. Use the "Eje1"-style name returned by create_reference_axis. count: Total number of instances INCLUDING the original (>= 2). For 6 holes around a bolt circle, pass count=6. total_angle_deg: Total angular span in degrees. Default 360 (full circle, evenly distributed). Pass smaller values for partial arcs (e.g. 180 for a semicircle pattern, 90 for a quarter, 120 for three instances spread over a third turn). equal_spacing: When True (default), total_angle_deg is the total span and instances divide it equally. When False, it's interpreted as the angle BETWEEN consecutive instances — useful for "every 30 degrees, count=N" use cases. reverse: Flip rotation direction (clockwise vs counter-clockwise when viewing along the axis).

Returns the new pattern Feature with name (e.g. "CirPattern1").

Example — bolt circle of 6 evenly-spaced holes around an axis through a hole's center: eje = create_reference_axis("Cara<3>@Cortar-Extruir1") circular_pattern(["Cortar-Extruir2"], eje["name"], count=6)

Example — 3 ribs over the top half of a flange (180° arc, equal spacing): circular_pattern( ["Saliente-Extruir1"], "Eje1", count=3, total_angle_deg=180.0, )

extrude_sketchA

Exit the active sketch and extrude it as a boss (solid) feature.

Args: depth_mm: Extrusion depth in mm (must be positive). end_condition: "blind" (fixed depth — default) or "through_all" (extrudes to the next surface; depth_mm is ignored). reverse_direction: Flip the extrude direction along the sketch plane normal. Default (False) extrudes the SW-default way — for a Front-plane sketch in this binding, that's +Z. Pass True to extrude the opposite way (e.g. -Z from Front).

    Gotcha — face-anchored sketches: after `create_sketch_on_face`,
    the default extrudes INTO the body (toward the inward normal —
    the cut/pocket case). Pass `reverse_direction=True` for raised
    features (hubs, bosses) — the typical intent on top of a face.
merge: If True (default), the new boss merges with any existing
    solid material it touches. Pass False to keep the new
    extrusion as a SEPARATE body — required for back-to-back
    stacks where two extrudes share a face (without merge=False
    on the second one, SW fuses them into one body), and for any
    multi-body workflow where target_bodies needs to address the
    new body independently.

Returns the new Feature with name (e.g., "Saliente-Extruir1"), type ("boss_extrude"), and dimensions. After this call the sketch is closed and the part has a new solid feature.

Caveat: the active sketch must contain at least one closed profile (e.g., a rectangle from create_rectangle). FeatureExtrusion3 fails if the sketch is empty, open, or self-intersecting.

Failure recovery: when extrude_sketch fails (e.g., open profile), the sketch is RE-OPENED automatically — fix the profile with more sketch primitives and retry (otherwise later geometry calls would silently no-op against a closed sketch).

Example — 50×30×5 mm box on the Front plane: create_sketch("front") create_rectangle(0, 0, 50, 30) extrude_sketch(5.0)

Example — back-to-back blocks (one in +Z, one in -Z) from the same Front-plane sketch, kept as TWO separate bodies: create_sketch("front"); create_rectangle(0, 0, 30, 30) extrude_sketch(20.0) # body in +Z create_sketch("front"); create_rectangle(0, 0, 30, 30) extrude_sketch(20.0, reverse_direction=True, merge=False) # body in -Z, separate

Related: build_flange_boss (sketch + extrude in one call). Use revolve_sketch / sweep_sketch / shell_part for true Revolución / Barrer / Vaciar features — don't approximate with stacked extrudes. loft is NOT in v1 (see list_capabilities() for the gap list).

extrude_cutA

Exit the active sketch and cut (subtract) material from the part.

Mirrors the SolidWorks "Cortar-Extruir → Direccion 1" UI panel. Most common autoparts use: drilling bolt holes through a bracket, cutting slots for adjustment, removing material around features.

Args: depth_mm: Cut depth in mm. Required (positive) for end_conditions "blind", "mid_plane", and "offset_from_surface" (per-condition meaning below). Ignored for the others — pass 0.0 (the default).

end_condition: One of:
    - "blind" (default, "Hasta profundidad especificada"): cut a
      fixed depth on ONE side of the sketch plane.
    - "through_all" ("Por todo"): cut through everything on ONE
      side of the sketch plane. Useful for bolt holes when you
      don't know the body thickness.
    - "through_all_both" ("Por todo - Ambos lados"): cut through
      everything on BOTH sides of the sketch plane. Use when the
      sketch sits in the middle of a body.
    - "mid_plane" ("Plano medio"): cut symmetrically about the
      sketch plane. depth_mm is total — split equally per side.
      Common for keyways, oil grooves, symmetric lightening
      pockets in cast housings and shafts.
    - "up_to_next" ("Hasta el siguiente"): cut up to the next
      surface that intersects the cut profile. Useful for cuts in
      multi-wall weldments / housings where the cut should stop
      at the next inner wall. No depth or reference required.
    - "up_to_surface" ("Hasta la superficie"): cut up to a named
      face or reference plane. Requires `reference_name`.
      Live caveat: in SW Spanish 2024 via this binding, FeatureCut4
      with T1=UpToSurface accepts FACE references but rejects
      reference-plane references (returns None even with the plane
      correctly selected at Mark=32). Use a face name (e.g.
      "Cara<2>@Pieza1") for "up_to_surface". For "cut up to a
      reference plane", use "offset_from_surface" with a very
      small offset, which works for both faces and planes.
    - "offset_from_surface" ("Equidistante de la superficie"):
      cut up to an offset distance past a named face. Requires
      `reference_name` AND positive depth_mm. Use `offset_reverse`
      to flip which side of the face the offset goes.
    - "up_to_body" ("Hasta el sólido"): cut up to a named solid
      body. Requires `reference_name` (the body name from
      get_active_part_info "bodies"). Common in multi-body
      weldments and fixture layouts.

reference_name: Locale-sensitive entity name from
    get_active_part_info — face/plane name (e.g. "Cara<2>@Pieza1",
    "Plano1@Pieza1") or solid-body name (e.g. "Saliente-Extruir1").
    Required when end_condition needs a reference; pass None
    otherwise (the tool will reject reference_name on conditions
    that don't accept one — fail loud rather than silently
    ignored).

target_bodies: Feature Scope (alcance de la operación). Pass None
    (default) to let SolidWorks auto-select all bodies the cut
    geometrically intersects. Pass a list of body names to
    restrict the cut to exactly those bodies (the SW UI's
    "Cuerpos seleccionados" mode). Body names come from
    get_active_part_info "bodies". Empty list raises — pass None
    to mean "all".

offset_reverse: Only meaningful for "offset_from_surface" — flips
    which side of the reference face the offset goes. Ignored for
    all other end conditions.

reverse_direction: Flip the cut direction relative to the
    sketch's natural default. The default (False) cuts INTO the
    body for both plane-anchored and face-anchored sketches. Pass
    True when the sketch's orientation breaks that heuristic —
    sketch on a back face, ref plane interior to the body, etc.
    If the result is "FeatureCut4 returned None" with cut
    direction listed as a likely cause, retry with True.

start_condition: Where the cut BEGINS — "sketch_plane" (default) or
    "offset". "offset" starts the cut start_offset_mm off the sketch
    plane, so a sketch on a real outer face can carve a mid-body BAND
    (start_offset_mm = where it begins, depth_mm = its width with
    end_condition="blind") WITHOUT an interior reference plane (which
    silently makes a zombie sketch).
start_offset_mm: Offset (mm, >0) from the sketch plane to the cut
    start; only for start_condition="offset". start_flip picks side.
start_flip: Flip the offset to the other side of the sketch plane.

Returns the new Feature with name (e.g., "Cortar-Extruir1"), type ("cut_extrude"), and dimensions.

Caveat: requires an active sketch AND the sketch geometry must intersect existing solid material. If the sketch is empty/open or misses the body, FeatureCut4 fails.

Failure recovery: same contract as extrude_sketch — on failure the sketch is RE-OPENED so you can fix the profile with more sketch primitives and retry (otherwise later geometry calls would silently no-op against a closed sketch).

Example — M8 clearance hole through a 5mm bracket: create_sketch("front"); create_circle(25, 15, 4.25) extrude_cut(5.0, "blind") Example — in a 2-body part, cut only through the upper boss: extrude_cut(end_condition="through_all", target_bodies=["Saliente-Extruir2"])

Related composites: build_rectangular_pocket (sketch+cut in one call), add_bolt_circle (N holes on a bolt circle), linear_pattern (repeat an existing seed cut).

list_edgesA

Listar aristas — enumerate edges of one or all solid bodies.

Returns one dict per edge with: - index: 0-based per-body. NOT durable across rebuilds. - body_name: which body the edge belongs to. - type: "line" | "circle" | "other" - midpoint_mm: [x, y, z] in mm. DURABLE reference for fillet/chamfer. None for closed-loop edges (full circles) — a circle has no canonical midpoint. For those, pass edge_indices to fillet/chamfer instead of edge_midpoints_mm. Partial arcs (post-fillet corner arcs) and line edges DO have midpoints. - length_mm: edge length in mm (None for closed loops).

Args: body_name: If given, return only edges of that body. Else return edges of every solid body in the active part.

Use case: pre-fillet/pre-chamfer LLM workflow. The LLM enumerates edges, reasons spatially ("the four top edges have z=10mm"), then passes midpoints to fillet() / chamfer().

Caveat: in this SolidWorks binding, edges can't be selected by name string in part-doc context — coordinate matching is the only durable address. Use the midpoint values returned here verbatim; don't recompute them in the LLM.

Example — list every edge in the active part: edges = list_edges() # edges = [{"index": 0, "body_name": "Saliente-Extruir1", # "type": "line", "midpoint_mm": [0, 0, 5], ...}, ...]

list_facesA

Listar caras — enumerate faces of one or all solid bodies.

Mirror of list_edges for faces. Returns one dict per face with: - index: 0-based per-body. NOT durable across rebuilds. - body_name: which body the face belongs to. - type: "planar" | "cylindrical" | "conical" | "spherical" | "other". Informational; addressing is by centroid. - centroid_mm: [x, y, z] in mm — midpoint of the face's bounding box. DURABLE reference for create_sketch_on_face. - area_mm2: face area in mm² (None if SW didn't expose it). - normal: outward normal [nx, ny, nz] for planar faces; None if SW didn't expose it. OMITTED on non-planar faces (token economy — structurally N/A there). - radius_mm, axis, concave: for cylindrical faces only — the geometry-side bore Ø used by verify_build_report; concave True = bore wall, False = outer boss/step face, None = unknown. OMITTED on non-cylindrical faces. - box_mm: axis-aligned bounding box [xmin,ymin,zmin,xmax,ymax, zmax] in mm (None if SW didn't expose it) — lets verify_build_report derive through-vs-blind from geometry (a bore face spanning both ends of the body is a through cut, regardless of the feature-definition read).

Args: body_name: If given, return only faces of that body. Else return faces of every solid body in the active part.

Use case: chained-feature LLM workflow. The LLM lists faces, reasons spatially ("the top face has the largest +Z normal"), passes the centroid to create_sketch_on_face, then sketches and extrudes/cuts on it.

Caveat: per-body face ordering is determined by SW's internal topology and is NOT durable across rebuilds. Re-run list_faces immediately before create_sketch_on_face rather than caching centroids across model edits.

Example — find the top face of a 50x50x20 block (sketched on Front, extruded +Z by 20): faces = list_faces() top = max( (f for f in faces if f["normal"] and f["normal"][2] > 0.9), key=lambda f: f["centroid_mm"][2], ) # top["centroid_mm"] = [25.0, 25.0, 20.0]

describe_featureA

Describir una operación — read a built feature's definition.

Returns {name, type, found, through, depth_mm, internal, source}. Used by verify_build_report to tell a through-hole from a blind one and read its depth. The rich path is the in-process add-in (MCP_CAD_USE_ADDIN, reads the real feature definition); the COM driver degrades to feature-tree dims (through/depth may be None — hole-wizard dims aren't exposed over COM).

Args: feature_name: exact feature name from get_active_part_info (verbatim; locale-sensitive — never translate it).

get_feature_inventoryA

Inventario completo de operaciones — one read of EVERY feature in the tree.

Per feature: name, type, dimensions, plus per-cut detail (kind, through, depth, diameter, internal) and the source of each value ('feature' | 'geometry' | 'addin'). On cuts, unknowns are explicit (through=None over COM, named in unverified); on non-cut features the N/A cut fields are omitted. occluded:true cuts cannot be verified by an iso render — check them with capture_views(section=...) / list_faces.

Also returns bores: a GEOMETRY-FIRST inventory of every cylindrical bore in the solid (Ø, axis, center, through/blind, and split=True when a slot crosses the bore — a clevis/fork, not a solid-hub hole), read from face geometry, not the feature tree. This catches what per-feature detail can't: a split pin hole, a bore shared across features, two bores in one cut.

USE BEFORE modifying any multi-feature part: enumerate every cut, change one, re-call, then confirm feature_count + the OTHER features are unchanged. The inventory is a contract. Read-only.

create_sketch_on_faceA

Croquis sobre cara — start a new sketch on a body face.

Unlike create_sketch (default planes only), this anchors a sketch to a face on an existing body. After this, draw geometry with create_circle / create_rectangle / create_line / create_slot, then close with extrude_sketch / extrude_cut — same as a default-plane sketch.

selector (recommended) — pick the face by INTENT instead of reading list_faces() and copying a centroid, e.g. the top planar face: create_sketch_on_face(selector={"filter": {"geom": "planar", "normal_axis": "+z"}, "sort": {"axis": "z", "dir": "desc"}, "pick": "first"}) Closed schema: filter{geom:planar|cylindrical|conical|spherical|other|any, body, normal_axis:+x/-x/+y/-y/+z/-z, axis:x|y|z + at_mm/tol_mm or min_mm/max_mm, min_area_mm2/max_area_mm2}, sort{axis:x|y|z|area, dir}, pick:all|first|last|int|[int]. Must resolve to EXACTLY ONE face (add pick:'first' or refine if it matches several). Mutually exclusive with face_centroid_mm. The result echoes selector_matched {n, sample_points_mm}.

Args: face_centroid_mm: [x, y, z] coords in mm — the centroid of the target face. Get this from list_faces() — pass the centroid_mm value verbatim. (Omit when using selector.)

Returns: - name: the new sketch's SW-assigned name (e.g., "Croquis5"). - face_centroid_mm: round-trip of the input centroid. - body_name: which body the face belongs to. - sketch_axis_mapping: dict mapping sketch (X, Y) coords to world coords (or None for cylindrical / non-planar faces). Use this to translate sketch-local positions to world coordinates without guessing — closes a real failure mode where the LLM assumed the wrong axis convention and built geometry in the wrong place.

  Schema:
    {
      "sketch_x_world_direction": [x, y, z],  # unit vector
      "sketch_y_world_direction": [x, y, z],  # unit vector
      "sketch_origin_world_mm":  [x, y, z],   # world coords
                                               # of sketch (0,0)
    }

Common autoparts use: counterbore on top of a flange, hole pattern on a bracket's side face, pocket on a sub-face from a previous cut.

Gotcha — extrude direction default after this call: For raised features (hubs, bosses, sello salientes), the next extrude_sketch call needs reverse_direction=True. The default extrudes INTO the body (toward the inward normal — the cut/pocket case). See extrude_sketch's reverse_direction arg.

Gotcha — sketch axis mapping is NOT intuitive on Y-normal faces: For a face with normal +Y or -Y, sketch +Y maps to world ∓Z (opposite sign of the face normal's Y component). Always read sketch_axis_mapping from the response BEFORE drawing geometry whose world position matters — don't assume sketch +Y = world +Z.

Failure modes: - centroid doesn't match any face within 0.01 mm → raises with hint to re-run list_faces. - centroid matches multiple faces → raises listing candidates; tighten the coordinate. - face is hidden / view occluded → IFace2.Select4 returns False; reorient the SW view and retry.

Example — Ø10 hole through the top face of a block: sk = create_sketch_on_face(selector=<top planar face — see above>) # read sk["sketch_axis_mapping"] before placing geometry create_circle(25, 25, 5) extrude_cut(end_condition="through_all")

chamferA

Chaflán — bevel one or more edges (distance + angle).

Edge addressing, the selector schema (recommended), failure modes, and the batch-all-identical-edges-in-ONE-call rule are IDENTICAL to fillet — see its description. E.g. chamfer every hole rim at the top face (z≈10): chamfer(selector={"filter": {"geom": "circle", "axis": "z", "at_mm": 10, "tol_mm": 0.5}}, distance_mm=1.0)

Standard autoparts use: bolt-hole entry chamfers (lead-in for assembly), deburred edges on machined parts, parting-line breaks on cast housings. 45° distance-angle is the autoparts default; distance-distance and vertex chamfers are deferred.

Args: edge_midpoints_mm: Optional. Edge addressing by midpoint (line edges; from list_edges() e["midpoint_mm"]). distance_mm: Chamfer leg length (the distance the chamfer extends along the edge's faces). Must be > 0. Typical autoparts values: 0.3-0.5mm for deburr, 1-2mm for bolt-hole lead-ins. angle_deg: Angle from the reference face. Must be in (0, 90). Default 45° (standard for almost all autoparts chamfers). flip: If True, the angle is measured from the OTHER adjacent face. Useful when the default direction goes the wrong way. edge_indices: Optional. Edge addressing by (body, index) — required for closed-loop circular edges (midpoint_mm is None for those).

Returns the resulting Chaflán feature (name, type="chamfer", dims).

filletA

Redondeo — fillet (round) one or more edges, constant radius.

selector (recommended) — pick edges by INTENT instead of reading list_edges() and guessing an index. A closed-schema dict resolved against the live geometry, e.g. round every circular edge: fillet(selector={"filter": {"geom": "circle"}}, radius_mm=2) or the single largest-radius edge: fillet(selector={"filter": {"geom": "circle"}, "sort": {"axis": "radius", "dir": "desc"}, "pick": "first"}, radius_mm=3) Schema: filter{geom:circle|line|arc|other|any, body, radius_mm/radius_tol_mm, axis:x|y|z + at_mm/tol_mm or min_mm/max_mm}, sort{axis:x|y|z|radius, dir}, pick:all|first|last|int|[int]. Mutually exclusive with edge_* args. The result echoes selector_matched {n, sample_points_mm} so you can sanity-check.

Standard autoparts use: stress relief on cast/forged parts, deburred machined edges, transition radii on stamped reinforcements (ISO 8062 on Schaeffler-style brackets). Constant-radius is the v1 variant — variable-radius and full-round fillets are deferred (rare in autoparts juniors' workflows).

Args (edge addressing — pass exactly ONE of selector / edge_midpoints_mm / edge_indices): edge_midpoints_mm: Optional. List of [x, y, z] midpoints from list_edges() → e["midpoint_mm"] (line / partial-arc edges only). radius_mm: Fillet radius. Must be > 0. Typical autoparts values: 0.5-1mm for machined edge softening, 2-5mm for cast-part transitions, R = 0.5-1.5 × wall_thickness for plastic ribs. tangent_propagation: If True (default), SW propagates the fillet along tangent-continuous neighboring edges. False = strict per-edge (each edge gets a separate filleted region). edge_indices: Optional. List of {"body_name": str, "index": int} from list_edges(), verbatim. Works for ANY edge — required for closed-loop circles (disc rims, hole edges, cylinder tops) where midpoint_mm is None.

Returns the resulting Redondeo feature (name, type="fillet", R1).

Failure modes: - midpoint doesn't match any edge → raises with hint to re-run list_edges() - midpoint matches multiple edges within 0.01mm → raises listing candidates - edge_indices: unknown body or out-of-range index → raises with the available bodies / valid index range - radius exceeds adjacent edge lengths → SW silently rejects; we surface "no new feature" with a hint - body name shifts after first fillet ("Saliente-Extruir1" → "Redondeo1"). When filleting N identical-class edges (e.g. all 4 vertical corner edges of a plate), pass ALL N indices in ONE call. Batching N/2 now + N/2 later addresses the OLD body name on the second call and fails with "no new feature"; recovery is undo + redo as one batch.

Caveat: NOT parametric. Re-radiusing requires deleting the feature and re-running. Parametric edits via modify_dimension on "Redondeo1" → "R1" work for simple cases.

revolve_sketchA

Revolución (saliente por revolución) — revolve a closed sketch around an axis. The standard SolidWorks workflow for turned parts: flechas (shafts), bujes (bushings), bridas (flanges), finiales, insertos torneados — anything spun on a lathe.

Args: axis_name: Name of the axis to revolve around. Pass the "Eje1" name returned by create_reference_axis (typically the intersection of two default planes through the part origin). The axis must lie in the same plane as — or beside — the sketch profile. Profiles that cross the axis raise a SW geometry error. angle_deg: Sweep angle in degrees, in the open interval (0, 360]. Default 360 (revolución completa) covers the standard turned- part case. Partial angles (e.g. 180) are useful for sectores, half-housings, leva-cams. reverse_direction: Flip rotation sense around the axis. Default follows SW's natural sense; flip if the resulting body comes out on the wrong side of the sketch plane. merge: True (default) merges with existing solid material it touches. False keeps the revolve as a separate body (multi-body modeling).

Returns the new Revolución feature (type=boss_revolve, D1=angle_deg).

Caveat: D1 is the sweep ANGLE, not a distance. modify_dimension can update D1 to retune the angle, but the sketch profile dimensions (the turned silhouette itself) are NOT parametric in v1 — same caveat as extrude_sketch (sketch primitives are draw-once-only; resize requires a fresh rebuild).

Example — Ø50mm × 10mm thick disc, full revolution around the Z axis: eje = create_reference_axis("front", reference_2="right") create_sketch("top") create_line(0, 0, 25, 0) # half-radius along +X create_line(25, 0, 25, 10) # thickness along +Y create_line(25, 10, 0, 10) # back-radius create_line(0, 10, 0, 0) # close on the axis revolve_sketch(eje["name"])

revolve_cutA

Cortar por revolución — revolve cut: remove material by sweeping a closed sketch profile around an axis.

Standard autoparts use: ranuras O-ring (O-ring grooves), ranuras de anillo de retención (retaining-ring grooves), asientos de cono (bearing cone seats), inner steps on bujes. Mirror of revolve_sketch but subtractive.

Args: axis_name: Eje name from create_reference_axis. Same constraints as revolve_sketch.axis_name. angle_deg: Angular sweep in (0, 360]. Default 360 — most autoparts revolve cuts are full-circle (annular grooves). reverse_direction: Flip rotation sense around the axis.

Returns the new CortarRevolución feature (type=cut_revolve, D1=angle_deg).

Example — Ø3mm O-ring groove on a Ø20 shaft, 5mm from the end: # shaft already built via revolve_sketch eje = create_reference_axis("front", reference_2="right") create_sketch("front") create_circle(10, 5, 1.5) # 1.5mm-radius cross-section revolve_cut(eje["name"])

shell_partA

Vaciado de pared (shell) — hollow out the body, optionally removing the listed faces to leave openings.

selector (recommended) — pick the open face(s) by INTENT, e.g. leave the top face open: selector={"filter": {"geom": "planar", "normal_axis": "+z"}}. Same face-selector schema as create_sketch_on_face (filter geom/body/normal_axis/axis/area, sort, pick). May match several faces (each becomes an opening). Mutually exclusive with face_centroids_mm.

Junior workflow: "haz un vaciado de 2mm dejando la cara superior abierta" — common for cast housings (carcasas), plastic enclosures (gabinetes), and any hollow case with an opening. SolidWorks shells the entire body to the given wall thickness; faces listed in face_centroids_mm become open holes.

Args: thickness_mm: Espesor de pared (wall thickness) in mm. Must be positive and less than half the smallest body dimension — SW silently rejects thicknesses too large to fit. face_centroids_mm: Faces to leave open. Pass a list of [x, y, z] centroids from list_faces(). None or [] = closed shell (the whole body hollowed, no openings). Each centroid must match a real face within 0.01 mm. outward: False (default) puts the shell wall INSIDE the original surface — the standard "hollow housing" intent. True keeps the shell outside (offset surface outward) — rare; only for special cases.

Returns the new Vaciado feature (type=shell, D1=thickness_mm).

Caveat: shell is destructive of subsequent face-anchored sketches — faces shift to the new offset surfaces. Run shell_part LATE in the feature tree, after all face-anchored boses/cuts are placed.

Example — 2mm-walled cup, 50×50×40 mm with the top open: create_sketch("front") create_rectangle(0, 0, 50, 50) extrude_sketch(40) faces = list_faces() top = max( (f for f in faces if f["normal"][2] > 0.9), key=lambda f: f["centroid_mm"][2], ) shell_part(2.0, face_centroids_mm=[top["centroid_mm"]])

set_materialA

Asignar material — set the material on the active part. Required before get_mass_properties returns a meaningful mass.

Maps to the SolidWorks UI's "Edit Material…" panel. Standard SW system materials work by name; database_path lets shop-specific custom .sldmat libraries override the system DB.

Args: name: Material name as it appears in the chosen library. Common autoparts examples (in the SW system DB): - Aceros: "AISI 1020", "AISI 1045 Steel", "AISI 4140", "Plain Carbon Steel" - Aluminios: "6061-T6 Aluminum", "7075-T6 Aluminum", "AlSi10Mg" (cast / fundición a presión) - Plásticos: "Nylon 6/10", "ABS", "PC High Viscosity" Names are LOCALE-sensitive — Spanish SW installs may use translated names (e.g. "Acero AISI 1045"). If the call raises with "did not apply material", check the SW material list in the current install. database_path: Optional absolute path to a .sldmat material database. None (default) uses the SW system database. Pass a path to load shop-custom alloys (e.g. specific casting recipes, supplier-graded steels not in the system DB). The file must exist and end in .sldmat.

Returns: dict with name, applied (always True on success), previous (the prior material name or None), database (the resolved DB path; "" for system).

Caveat: changing material affects mass / volume / inertia from get_mass_properties (la densidad cambia). It does NOT change geometry — fillets, dimensions, and bodies are unaffected.

Example — quote a turned shaft: set_material("AISI 1045 Steel") props = get_mass_properties() cost_per_kg_mxn = 65.0 quote_mxn = (props["mass_g"] / 1000) * cost_per_kg_mxn

get_mass_propertiesA

Propiedades de masa — read mass, volume, surface area, center of mass, density, and principal moments of inertia for the active part OR assembly (works on both doc types). Read-only.

Returns a dict in mm-native units: - mass_g (float, gramos): total mass in grams. - volume_mm3 (float): total volume in mm³. - surface_area_mm2 (float): total surface area (área superficial) in mm². - center_of_mass_mm (list[float], 3): [x, y, z] of the centro de gravedad in the part frame (mm). - density_kg_per_m3 (float): density (densidad) in kg/m³ — the SW canonical density unit, NOT mm-converted. - principal_moments_g_mm2 (list[float], 3): [Ixx, Iyy, Izz] in g·mm² about the centroid.

Caveat: requires a material to be set on the part for mass to be meaningful. SW's "Default Material" returns mass_g=0 (no density assigned). Call set_material first if the part has no material.

Common autoparts uses: - Cotización (quoting): mass_g × material price/kg. - Lightening pass: measure mass before / after a vaciado, target a mass reduction without dropping below stiffness threshold. - Inertia for dynamic analysis: principal_moments_g_mm2.

Example — quote a turned shaft: set_material("AISI 1045 Steel") props = get_mass_properties() cost = (props["mass_g"] / 1000) * 65.0 # MXN/kg

get_bounding_boxA

Caja envolvente — overall axis-aligned bounding box of the active part OR assembly, in mm. Read-only — does not modify the document.

Returns a dict in mm-native units (part frame): - min_mm (list[float], 3): [x, y, z] of the minimum corner. - max_mm (list[float], 3): [x, y, z] of the maximum corner. - size_mm (list[float], 3): [dx, dy, dz] overall extents (max − min). This is the part's bounding-box footprint. - center_mm (list[float], 3): [x, y, z] box center ((min + max) / 2).

Unions the bounding boxes of every solid body, so multi-body parts report the combined envelope.

Common autoparts uses: - Stock selection: size_mm tells you the minimum bar / plate / billet the part fits in. - Sanity check after a build: confirm the part's overall dimensions match what was intended BEFORE trusting the feature tree (cheap verification, no screenshot needed). - Nesting / fixturing envelope.

Example — verify a plate's footprint: bbox = get_bounding_box() assert abs(bbox["size_mm"][0] - 100) < 0.5 # expected 100mm wide

verify_against_specA

Verifica el TAMAÑO de la pieza construida contra el spec del dibujo.

ADVISORY — el ÚNICO chequeo independiente de verdad-de-tierra en el loop: mide el sólido construido (get_bounding_box) y lo compara numéricamente, con tolerancia, contra las dimensiones que transcribiste del dibujo. Convierte el "se ve bien" visual sin dimensiones en una aserción dura de envolvente — atrapa la clase de error más común e invisible: forma correcta, tamaño equivocado.

Args: expected_size_mm: tres extensiones esperadas [a, b, c] en mm, en CUALQUIER orden (con match_by="sorted"). tolerance_mm: banda mínima por eje (default 0.5mm). tolerance_pct: banda relativa por eje; se usa max(mm, pct). Default 1%. expected_volume_mm3: opcional — chequeo de volumen SOLO de orden de magnitud (nunca cambia el veredicto; evita falsos positivos por chaflanes/redondeos legítimos). Útil para detectar errores de unidades. match_by: "sorted" (default, robusto a orientación) o "positional".

Returns dict: {ok, verdict PASS/FAIL, per_axis (deltas), measured_size_mm, volume?, caveats[], message, bbox}. LEE los caveats: la caja NO ve features en ubicación incorrecta del mismo tamaño, topología incorrecta, ni errores que conservan el envolvente. Es un oráculo entre varios, no la corrección total.

[en: Verify built-part SIZE against the drawing spec. Advisory — the first independent ground-truth check in the loop: measures the solid via get_bounding_box and asserts it against transcribed dims within tolerance, turning a dimensionless visual "match" into a hard envelope assertion. Catches the most common, most invisible failure: right shape, wrong size. Optional volume check is order-of-magnitude only (never flips the verdict). Read the caveats — bbox cannot see wrong-location, wrong-topology, or envelope-preserving errors.]

capture_viewsA

Capturar vistas — render the active part OR assembly to PNG screenshots so you can SEE the model and verify geometry. Read-only.

ADVERTENCIA (privacidad): las capturas se ENVÍAN a la API de Claude. Un screenshot puede mostrar logos, números de parte OEM o geometría confidencial. Decisión de piloto: el cliente usa su propia API key y firma el flujo de datos. Usa esta herramienta consciente de eso. [en: screenshots are SENT to the Claude API; pixels are NOT redacted.]

Cadence — render at CHECKPOINTS and at the END of a build, not after every feature: each call is one image per view (heavy tokens). Between features trust the cheap signals (mutator receipt.feature_count, batch summary); a final render before declaring a part done is mandatory (or bundle it via verify_build_report capture_view_names). Per-feature renders are for debugging a flaky build.

Args: views: subset of ["iso", "front", "top", "right", "trimetric"]. Default (None) = ["iso", "front", "top", "right"]. Unknown view name → ValueError (fail fast, no silent default). with_dims: accepted but a v1 NO-OP (dimension-annotation overlay needs a much larger surface). The param exists so the signature is stable. TODO(with_dims). section: optional {"plane": "front"|"top"|"right" (or Spanish UI name), "offset_mm": float} — render each view through a graphics CUT PLANE so INTERNAL cuts the outer silhouette hides (pockets, banded/saddle cuts, bores) become visible. offset_mm is signed from the standard plane (0 = through origin). Use this to diff against a drawing's SECTION view. Standard projections cannot show an occluded internal cut; for a purely internal feature an iso render proves nothing — also confirm it via list_faces.

Returns a list: one inline image per requested view (Claude sees them directly), followed by a summary dict with the resolved views, the local PNG paths, with_dims, and a privacy note.

Caveat: requires a part open in SolidWorks. Image bytes are NOT name-redacted (see ADVERTENCIA). Temp PNGs live in the OS temp dir and are read lazily when the result is serialized — they are not deleted by this tool.

Example — verify a base plate before drilling: extrude_sketch(25.0) capture_views(views=["iso", "front"]) # eyeball it get_bounding_box() # confirm extents

hole_wizardA

Asistente de barrenos (Hole Wizard) — drill ONE standard ISO Metric hole on a face: tapped (con rosca) or counterbore (refrentado para tornillo socket).

Junior workflow: "agrega un barreno M8 con rosca en esta cara, profundidad 15mm". Tool replaces manual drill-diameter lookup (ISO 273 / ISO 2306) — pass the fastener size and SW reads geometry from its Toolbox database.

Args: hole_type: One of: - 'tap' (rosca): tapped (threaded) hole. Sizes M5–M12. - 'counterbore' (cilindro avellanado / refrentado): for socket-head cap screws (tornillo de cabeza cilíndrica con hueco hexagonal). Sizes M5–M10. size: ISO fastener nominal — 'M5','M6','M8','M10','M12' for tap; 'M5','M6','M8','M10' for counterbore. face_centroid_mm: Face to drill into. Pass a centroid from list_faces() (matched within 0.01mm tolerance). The hole is placed at the face's local origin (where SW positions it by default). end_condition: 'blind' (depth-controlled, depth_mm required) or 'through_all' (passes through the entire body, depth ignored). depth_mm: Hole depth for end_condition='blind'. Required if blind. For tapped holes, this is the FULL hole depth; SW computes thread depth from the toolbox. thread_class: ISO 965 thread tolerance class for tapped holes. Default '6H' (standard internal thread for steel/aluminum brackets). Ignored for counterbore.

Returns dict with name (e.g. 'Taladro roscado M81' or 'Refrentado para tornillo con cabeza hueca de M81' on Spanish-locale SW), type 'hole_wizard', and dimensions {'D1': diameter_mm, 'D2': depth_mm}.

Caveat (v1 limitations):

  1. Requires SOLIDWORKS Toolbox add-in to be loaded. If not, raises a clean error pointing to Herramientas > Complementos.

  2. Single hole per call at the face's centroid. For multi-hole patterns (e.g. 4 corner mounting holes), use add_bolt_circle (clearance) or call hole_wizard once per distinct face. Multi- position via sketch points is deferred to a later batch.

  3. Clearance through-holes are NOT supported in v1 — SW's swWzdHole API path silently rejects all FTI/SSize combinations on this binding. Use add_bolt_circle (clearance, multi-position) or extrude_cut on a sketched circle for clearance holes.

  4. End-face guard: rejects a centroid that isn't on the bbox extreme along the face normal (a stale list_faces centroid), and a post-call bbox-shrink check auto-undos + raises if the hole consumed more than the requested depth — a known HoleWizard5 surprise on the end face of a multi-step shaft. Workaround there: add_drill_pattern or extrude_cut on the end face.

Example — single M8 tap on a 50×50 mounting face: faces = list_faces() top = max((f for f in faces if f['normal'][2] > 0.9), key=lambda f: f['centroid_mm'][2]) hole_wizard('tap', 'M8', face_centroid_mm=top['centroid_mm'], end_condition='blind', depth_mm=15.0)

Example — M6 counterbore for a socket-head cap screw: hole_wizard('counterbore', 'M6', face_centroid_mm=top['centroid_mm'], end_condition='blind', depth_mm=8.0)

sweep_sketchA

Barrido (sweep) — sweep a closed profile sketch along a path sketch to make a boss feature.

Standard autoparts use: tubos (tubes / pipes following a curved path), juntas / empaques (gaskets — closed-loop path), guías de cable (cable routes), cordones de soldadura (weld beads along an edge), perfiles extruidos curvos.

Args: profile_sketch_name: Name of the CLOSED profile sketch (e.g. 'Croquis1' for a circle to make a tube). Created via create_sketch + create_circle / create_rectangle / etc. Must be a closed contour. path_sketch_name: Name of the PATH sketch (e.g. 'Croquis2' for the route the profile follows). Open or closed paths both work. Created via create_sketch + create_line / create_arc / etc. on a plane perpendicular (or tangent) to the profile's plane at the path start. merge: True (default) merges with existing solid material it touches. False keeps the swept body separate (multi-body).

Returns Feature (name='Barrido{n}', type='boss_sweep', dimensions={}). Sweeps don't have parametric D1/D2 in v1 — the geometry is fully driven by the two sketches.

Caveat (v1): the two sketches must already exist as separate features in the tree. Profile and path can't be the same sketch. Advanced options (twist, guide curves, thin-feature, circular- profile shortcut) are NOT exposed in v1; defaults are: follow- path orientation, no twist, no guide curves.

Example — Ø6mm tube along an L-shaped path: # Profile: 6mm-radius circle on Front plane at origin create_sketch('front') create_circle(0, 0, 3) # Croquis1 # Path: L-shape on Top plane create_sketch('top') create_line(0, 0, 0, 50) create_line(0, 50, 50, 50) # Croquis2 sweep_sketch('Croquis1', 'Croquis2')

sweep_cutA

Cortar por barrido — sweep cut: subtract a swept-profile-along- path volume from existing material.

Standard autoparts use: ranuras curvas (curved grooves), canales de aceite (oil channels along a contour), perfiles de fresado (milling tool paths simulated as cuts), recortes ergonómicos siguiendo un perfil.

Args: profile_sketch_name: Closed profile sketch name (e.g. 'Croquis1' for the cross-section of the cut). path_sketch_name: Path sketch name. Must be a different sketch than the profile.

Returns Feature (name='CortarBarrido{n}', type='cut_sweep', dimensions={}).

Caveat (v1): same constraints as sweep_sketch.

Example — 2mm-wide groove following a curved path on a plate: # Profile: 2x4mm rectangle on Front create_sketch('front') create_rectangle(-1, 0, 1, 4) # Croquis1 # Path: arc on the plate's top face, then sweep_cut create_sketch_on_face([...]) create_arc(...) # Croquis2 sweep_cut('Croquis1', 'Croquis2')

build_rectangular_pocketA

Hacer un vaciado rectangular en una sola operación.

Junior workflow: "agrégame un vaciado de 30x20mm centrado en (50, 30) de la cara frontal, 5mm de profundidad". Composes: create_sketch(plane) -> create_rectangle(corners) -> extrude_cut

Args: plane: Sketch plane — "front"/"top"/"right" (English) or "Alzado"/"Planta"/"Vista lateral" (Spanish), or a custom "Plano1" returned by create_reference_plane. center_x_mm, center_y_mm: Center of the pocket in sketch coords. width_mm: Pocket extent in the sketch's X direction. Must be > 0. height_mm: Pocket extent in the sketch's Y direction. Must be > 0. depth_mm: Cut depth. Required positive when end_condition="blind"; ignored when end_condition="through_all". end_condition: "blind" (fixed depth) or "through_all" (through the entire body). Default "blind". reverse_direction: Flip the cut direction. The plane-anchored default cuts toward the SW-default side of the sketch plane; if the parent body sits on the OTHER side the pocket cuts into air and extrude_cut returns None — pass True to correct it (same escape hatch as extrude_cut's reverse_direction). target_bodies: Restrict the cut to these body names (from get_active_part_info "bodies"). None (default) lets SW cut every body the pocket intersects — pass a list to keep a through cut from punching unintended bodies in a multi-body part.

Returns the resulting Cut-Extruir Feature info.

Example — 30x20mm pocket 5mm deep, centered on origin of Front plane: build_rectangular_pocket("front", 0, 0, 30, 20, 5)

build_closed_profileA

Perfil cerrado — construye un croquis a partir de UNA lista ordenada de segmentos (líneas y arcos) en UNA sola llamada, en vez de ~16 create_line/ create_arc sueltas. Valida que el lazo cierre ANTES de tocar SolidWorks (un perfil abierto mata la extrusión silenciosamente), luego dibuja todo y deja el croquis ABIERTO para que añadas cotas/relaciones y extruyas.

Uso típico CSWA Tool Block: pasa el outline completo (lados + chamfers rectos + arcos R10/R20) como segments; el croquis queda listo para add_sketch_relation / add_sketch_dimension / add_sketch_fillet y luego extrude_sketch.

[en: Closed profile — build a sketch from ONE ordered list of segments (lines + arcs) in a single call instead of ~16 separate primitives. Validates the loop closes BEFORE any SW call (an open loop silently kills the extrude), then draws it and leaves the sketch OPEN to constrain.]

Args: plane: sketch plane ("front"/"top"/"right", Spanish aliases, or a reference-plane name). segments: ordered loop. Each item is either {"type":"line", "x1","y1","x2","y2"} or {"type":"arc", "cx","cy","radius_mm","start_angle_deg", "end_angle_deg","direction"("ccw"|"cw", default "ccw")}. Each segment's end must meet the next segment's start. close: if True (default), auto-add a closing line from the last endpoint back to the first start when there's a gap. If False and the loop isn't closed, raises. name_hint: optional; reserved for future naming. Currently unused. exact: if True (default), draw the loop in SolidWorks' exact mode (ISketchManager.AddToDB) — segments land at their exact input coordinates with NO automatic-relation inference, so the profile does NOT drift 1-3 mm (and mass several %) as SW relaxes inferred relations. This is the fix for the CSWA Tool Block drift: a true-arc profile builds at the exact intended bbox and mass instead of drifting by mm and grams. Pass exact=False ONLY if you deliberately want SW to infer horizontal/vertical/tangent relations for later parametric editing (and accept the drift). Best-effort: if the driver can't toggle exact mode it falls back to inference-on. variables: optional dict para coordenadas paramétricas — cualquier coordenada de segmento puede ser un STRING como "A-29" o "B/2" evaluado contra este dict (solo números, variables, + - * / y paréntesis). Variante nueva = misma llamada con otro variables.

Returns {sketch_name, plane, segment_count, closed, vertices}. The sketch is left OPEN — add relations/dimensions, then extrude_sketch.

NOTE: call-count atomic, not SW-transactional — the up-front loop validation is the guardrail against a half-drawn open profile.

Related: create_sketch + create_line/create_arc (the primitives this composes); add_sketch_relation / add_sketch_dimension (constrain it after).

build_revolved_profileB

Build an axisymmetric profile in one safe chain.

Creates a reference axis, builds an exact closed profile, then revolves it. This is the preferred path for turned parts where the sketch profile is already known as ordered line/arc segments. Segment coordinates accept string expressions over variables (e.g. "D/2") — a size variant is the same call with a new variables dict.

build_extruded_closed_profileC

Build an exact closed profile and extrude it as one composite.

Segment coordinates and depth_mm accept string expressions over variables (e.g. depth_mm="C", x2="A-29") — a size variant is the same call with a new variables dict.

build_plate_with_hole_patternB

Build a rectangular plate and drill drawing-grounded through holes.

Use either explicit hole_positions_mm or a bolt circle (bolt_circle_diameter_mm + bolt_count). The rectangle is drawn from (origin_x_mm, origin_y_mm) to (origin_x_mm + width, origin_y_mm + height).

build_flange_bossA

Crear un saliente cilíndrico (con barreno opcional pasante).

Junior workflow: "agrega un saliente de O40mm x 8mm en el centro, con barreno O20mm". Composes a sketch+circle+extrude_sketch for the boss, plus an optional sketch+circle+extrude_cut for the through bore.

Args: plane: Sketch plane the boss sits on. Same name conventions as build_rectangular_pocket. center_x_mm, center_y_mm: Boss center in sketch coords. outer_diameter_mm: Outer diameter of the boss cylinder. > 0. height_mm: Boss extrusion height (positive). bore_diameter_mm: If set, drills a through-bore at the boss centerline. Must be > 0 and < outer_diameter_mm. The bore is colinear with the boss by construction (same sketch plane, same center coords). reverse_extrude: If True, the boss grows opposite the SW-default direction along the sketch plane normal. Useful when the boss should sit on the opposite side of the parent body. bore_target_bodies: Restrict the through-bore to these body names (from get_active_part_info "bodies"). None (default) lets SW cut every body the bore intersects — pass [the boss/parent body] to stop the through_all bore from punching unintended bodies in a multi-body / multi-wall part (the caveat below).

Returns: {"boss": Feature info, "bore": Feature info | None}.

Caveat: the bore (when requested) goes "through_all" so it punches through everything in its path unless bore_target_bodies scopes it. For blind bores, call extrude_cut separately after this composite.

Example — bearing seat O40mm x 8mm with O20mm through-bore on Top plane: build_flange_boss("top", 0, 0, 40, 8, bore_diameter_mm=20)

add_bolt_circleA

Agregar un círculo de pernos — N barrenos en círculo, en una operación.

Composes a single sketch with N circles placed at (cx + r·cos θ, cy + r·sin θ) plus one extrude_cut. Sketch-based (not feature-pattern- based) so it works for any center position — not restricted to origin-centered geometry.

Args: plane: Sketch plane. Same name conventions as other composites. center_x_mm, center_y_mm: Center of the bolt circle in sketch coords. circle_diameter_mm: Diameter of the bolt circle (the imaginary circle the BOLT CENTERS sit on — NOT the individual hole diameter). Must be > 0 and > hole_diameter_mm. hole_count: Total number of holes (3..24 typical). Must be >= 3. hole_diameter_mm: Individual through-hole diameter. Must be > 0 and < circle_diameter_mm. angle_offset_deg: Rotation of the first hole from the +X axis. Default 0 = first hole on the +X side. Useful for aligning bolt patterns to existing geometry. end_condition: "through_all" (default) or "blind" with depth_mm. depth_mm: Required when end_condition="blind". reverse_direction: Flip the cut direction (escape hatch for when the parent body sits on the opposite side of the sketch plane and the holes would cut into air). Same semantics as extrude_cut. target_bodies: Restrict the cut to these body names (from get_active_part_info "bodies"); None lets SW cut every body the holes intersect — pass a list to scope a through pattern in a multi-body part.

Returns the resulting Cut-Extruir Feature info (single feature for all N holes — they share one sketch).

Caveat: NOT parametric. Changing hole_count requires deleting the feature and re-running the composite. For parametric counts use create_reference_axis + circular_pattern (origin-only axes for now).

Example — 6-bolt M8 clearance (8.5mm) on a O60mm bolt circle, Top plane: add_bolt_circle("top", 0, 0, 60, 6, 8.5)

build_variant_familyA

Crear una familia de configuraciones cambiando una sola dimensión.

Junior workflow: "crea las configuraciones Corto/Mediano/Largo con longitudes 80/120/160mm". Composes (create_config + activate + modify_dimension) once per variant + a single save at the end.

Args: feature_name: Name of the feature carrying the dimension (e.g. "Saliente-Extruir1"). Must exist in the active part. dimension_name: Name of the dimension on that feature (e.g. "D1"). Must exist in the feature's dimensions dict. variants: Mapping from configuration name → new dimension value (mm). Non-empty, all values > 0. parent_config: Parent configuration for the new variants (empty = root). Same value passed to create_configuration for each. activate_at_end: Optional name of the variant to activate after creation. None = leave the active config wherever it landed after the loop. Must be a key of variants if provided.

Returns: {"created": [variant names in iteration order], "active_at_end": name | None}.

Caveat: If the loop fails partway through (e.g. modify_dimension raises on variant #2), the part is left with the configurations that were created up to that point. v1 surfaces the error with partial- state info so the user can manually delete_configuration to clean up. Auto-rollback isn't attempted (deletion is deferred by design per CLAUDE.md).

Example — 3-variant length family: build_variant_family( "Saliente-Extruir1", "D1", {"Corto": 80.0, "Mediano": 120.0, "Largo": 160.0}, activate_at_end="Mediano", )

break_all_edgesA

Desbarbar todas las aristas — chamfer every edge (linear and circular by default).

Universal edge-break for autoparts: every machined drawing calls out edge breaks per ISO 13715, every Tier 1 customer requires deburred edges before assembly. This composite implements "achaflana todo" / "desbarbar todo" in one call instead of three (list_edges + filter

  • chamfer).

Args: distance_mm: Chamfer leg length. Default 0.5mm — typical machined-edge deburr. Use 0.3mm for fine deburr or 1.0mm for noticeable lead-ins. angle_deg: Angle from reference face. Default 45° (autoparts standard for ~99% of cases). min_edge_length_mm: Skip linear edges shorter than this. Default 1.0mm — filters tiny sub-edges left over from prior fillet/chamfer features. Circular edges (arc / circle) skip this filter — their length_mm is the chord length and isn't meaningful for the deburr decision. body_name: If given, only chamfer edges of that body. Else enumerate all solid bodies in the active part. include_arcs: If True (default), include arc and circle edges in the chamfer set. Required for round autoparts (rines, cubos, discos de freno, engranes) where every edge is circular. Set False for the legacy linear-only behavior.

Returns: { "feature": {"name": "Chaflán1", "type": "chamfer", "dimensions": {...}}, "edges_chamfered": int, }

Caveat: NOT parametric — re-running with different distance_mm requires deleting the feature first. After break_all_edges runs, the part has many short sub-edges from the chamfer; calling fillet_all_edges next will re-process those unless min_edge_length_mm filters them out. Recommend using only one edge-break tool per part.

Example — standard 0.5mm × 45° deburr on every edge: break_all_edges()

Example — heavy 1mm × 45° on a single body in a multi-body part: break_all_edges(distance_mm=1.0, body_name="Saliente-Extruir2")

Example — strict linear-only deburr (skip circular edges): break_all_edges(include_arcs=False)

fillet_all_edgesA

Redondear todas las aristas — fillet every edge (linear and circular by default).

Universal edge softening for autoparts: cast/forged parts get transition radii (ISO 8062), structural brackets get stress-relief fillets, plastic injection-molded parts need rounded edges. This composite implements "redondea todo" in one call.

Args: radius_mm: Fillet radius. Default 1.0mm — typical machined-edge softening. Use 2-5mm for cast-part transitions, R = 0.5-1.5 × wall_thickness for plastic ribs. tangent_propagation: If True (default), SW propagates the fillet along tangent-continuous neighboring edges, producing one smooth filleted region for rows of co-linear edges. Pass False for strict per-edge fillets (each edge gets its own region). True is what most "redondea todo" intents mean. min_edge_length_mm: Skip linear edges shorter than this. Default 1.0mm. Circular edges (arc / circle) skip this filter — their length_mm is the chord length and isn't meaningful for the softening decision. body_name: If given, only fillet edges of that body. include_arcs: If True (default), include arc and circle edges in the fillet set. Required for round autoparts (rines, cubos, discos de freno, engranes) where every edge is circular. Set False for the legacy linear-only behavior.

Returns: { "feature": {"name": "Redondeo1", "type": "fillet", "dimensions": {...}}, "edges_filleted": int, }

Caveat: NOT parametric — re-radiusing requires deleting the feature. With tangent_propagation=True, SW collapses adjacent edges into one filleted region; the resulting feature may show fewer "branches" than edges_filleted in the SW UI tree.

Example — soften every edge of a bracket at R=1mm: fillet_all_edges()

Example — large R=5mm transition on cast housing, no tangent prop: fillet_all_edges(radius_mm=5.0, tangent_propagation=False)

Example — strict linear-only fillet (skip circular edges): fillet_all_edges(include_arcs=False)

add_drill_patternA

Patrón de barrenos (drill pattern) — drill N holes at specified positions using ISO Metric standards.

Junior workflow: "drill 4 M8 tapped holes in the corners of this plate, 15mm deep". Builds the equivalent of N hole_wizard calls in one go, with bore diameters from ISO 2306 (tap), ISO 273 (clearance), ISO 4762 (counterbore for socket-head cap screws).

Args: hole_type: 'tap' (rosca / threaded), 'clearance' (paso para perno / pass-through), 'counterbore' (refrentado / recess for socket-head cap screws). size: ISO M5–M12 nominal. Tap + clearance accept M5/M6/M8/M10/M12; counterbore accepts M5/M6/M8/M10 (M12 not in v1). positions_mm: List of [x_mm, y_mm] points in the plane/face local frame. Minimum 1 point. No duplicates within 0.01mm. plane: Plane name — 'front'/'top'/'right' (lowercase English), Spanish UI ('Alzado'/'Planta'/'Vista lateral'), or a user-created plane ('Plano1'). Mutually exclusive with face_centroid_mm. face_centroid_mm: Face centroid from list_faces() — mutually exclusive with plane. Use this for face-anchored drilling (e.g. mounting holes on a body's top face). end_condition: 'blind' (depth-controlled, depth_mm required) or 'through_all' (passes through the body, depth ignored). depth_mm: Hole depth for blind. Required if end_condition='blind'. counterbore_depth_mm: CBORE recess depth (only for hole_type= 'counterbore'). Defaults to ISO 4762 head height for the size (M5→5, M6→6, M8→8, M10→10).

Returns dict: feature_names: 1 entry for tap/clearance, 2 for counterbore (the bore + the recess). hole_count: number of holes drilled. hole_diameter_mm: bore diameter (from ISO lookup). counterbore_diameter_mm: only for counterbore (else None). counterbore_depth_mm: actual depth used (else None).

Caveat (v1): holes show as 'Cortar-Extruir' features in the SW feature tree, NOT as 'Taladro roscado' / 'Refrentado' Hole Wizard features. No cosmetic threads (rosca visualization). For a single hole with proper Hole Wizard styling + cosmetic threads, use hole_wizard directly. This composite is for multi-position patterns where hole_wizard's single-hole-per-call limit makes it impractical.

Example — 4× M8 tap holes in a 50x50 plate's corners: add_drill_pattern( 'tap', 'M8', positions_mm=[[10, 10], [40, 10], [10, 40], [40, 40]], plane='front', end_condition='blind', depth_mm=15, )

Example — 2× M6 counterbore on the top face of an existing body: faces = list_faces() top = max((f for f in faces if f['normal'][2] > 0.9), key=lambda f: f['centroid_mm'][2]) add_drill_pattern( 'counterbore', 'M6', positions_mm=[[20, 20], [60, 20]], face_centroid_mm=top['centroid_mm'], end_condition='blind', depth_mm=10, )

build_stepped_shaftA

Flecha escalonada — build a stepped (multi-diameter) cylindrical shaft in one call. Standard turned-part workflow for autoparts: flechas de transmisión, bujes con escalones, poleas, ejes de salida.

Junior workflow: "una flecha de Ø10×20, luego Ø20×30, luego Ø15×15". Composes: create_reference_axis(front, top) -> X axis through origin create_sketch("front") -> profile in XY plane create_line × N -> stepped half-silhouette revolve_sketch(axis_name) -> boss-revolve

Args: diameters_mm: List of step diameters in mm. One per step. Must be 1..20 entries, all > 0. v1 has no taper — each step is a pure cylinder of constant diameter. lengths_mm: List of step lengths in mm. Same length as diameters_mm. All > 0. angle_deg: Sweep angle in (0, 360]. Default 360 = full revolution. Partial angles produce a sector (useful for cams or half-housings). merge: True (default) merges with adjacent solid material. False keeps the shaft as a separate body (multi-body modeling).

Returns dict: name, type, dimensions: Standard Feature info from revolve_sketch (type='boss_revolve', D1=angle_deg). axis_name: The "Eje{N}" reference axis created. Reusable in circular_pattern or further revolve calls. step_count, total_length_mm, max_diameter_mm: Computed metadata for the LLM to verify against intent.

Caveat (v1 orientation): the shaft always grows along the +X world axis from the origin, sketched on the Front plane. To orient differently, use revolve_sketch directly with a custom axis + sketch plane.

Caveat (transitions): each step is a square shoulder (no fillet/chamfer between steps). Post-process with fillet/chamfer on the resulting edges if smoother transitions are needed.

Caveat (no taper): each step is a pure cylinder. For tapered shafts (e.g. transmission shafts with conical sections), use revolve_sketch with a triangular profile section.

Example — 3-step pulley shaft: build_stepped_shaft( diameters_mm=[10, 20, 15], lengths_mm=[20, 30, 15], )

build_threaded_bossA

Saliente roscado — cylindrical boss with a centered tap hole, in one call. Standard autoparts pattern: torres roscadas en carcasas (threaded posts on housings), salientes para tornillos, mounting bosses on stamped/cast brackets, sensor mounts.

Junior workflow: "agrega un saliente roscado M8 en el centro, Ø20mm × 12mm de altura, rosca 10mm". Composes: outer disk -> extrude_sketch (the boss body) tap hole -> extrude_cut (ISO 2306 tap-drill diameter)

Args: plane: Sketch plane — "front"/"top"/"right" (English) or "Alzado"/"Planta"/"Vista lateral" (Spanish), or a custom "Plano1" returned by create_reference_plane. center_x_mm, center_y_mm: Boss center in sketch coords. outer_diameter_mm: Boss OD. Must be > 0 and > tap-drill diameter (the boss must have a wall around the tap). height_mm: Boss extrusion height. Must be > 0. thread_size: ISO Metric — 'M5' | 'M6' | 'M8' | 'M10' | 'M12'. The tap-drill diameter is looked up from ISO 2306 coarse- pitch (M5 → 4.2, M6 → 5.0, M8 → 6.8, M10 → 8.5, M12 → 10.2). thread_depth_mm: Tap depth in mm. Default = 0.8 × height_mm (leaves 20% of the boss as solid base — typical for cast/ machined bosses). Must be ≤ height_mm if blind. end_condition: 'blind' (depth-controlled, default) or 'through_all' (passes through the boss + any material below). reverse_extrude: If True, the boss grows opposite the SW-default direction along the sketch plane normal. Useful when the boss should sit on the opposite side of the parent body. tap_target_bodies: Restrict the tap cut to these body names (from get_active_part_info "bodies"); None lets SW cut every body the tap intersects. Pass [the boss/parent body] to keep a through_all tap from punching unintended bodies below it.

Returns dict: boss: Feature info for the cylinder (type=boss_extrude). tap_hole: Feature info for the tap (type=cut_extrude). thread_size, tap_drill_diameter_mm, thread_depth_mm: echo back the standard data for LLM verification.

Caveat (v1): the tap hole shows as a 'Cortar-Extruir' feature, NOT a 'Taladro roscado' Hole-Wizard feature. No cosmetic threads (rosca visualization). For a Hole-Wizard tap with cosmetic threads, use hole_wizard directly on the boss face after building the boss with build_flange_boss.

Example — M8 threaded boss on top face, Ø20×12mm, 10mm tap: build_threaded_boss('top', 0, 0, 20, 12, 'M8', thread_depth_mm=10)

Example — M6 through-tapped boss for a brass insert: build_threaded_boss('top', 25, 0, 16, 8, 'M6', end_condition='through_all')

build_l_bracketA

Soporte / bracket en L — L-shaped autoparts bracket with bolt holes on each leg, in one call.

Junior workflow: "soporte L para fijar el sensor a la carcasa, 50×80×40mm con 2 barrenos M8 en cada cara". Wraps the extrude-L-profile + face-anchored-cut flow into one call. The most-common stamped autopart in the Mexican PYME shop floor.

Composes: create_sketch("front") + 6×create_line -> L-profile extrude_sketch(width) -> L body create_sketch_on_face × 2 + create_circle×N + extrude_cut × 2 -> bolt holes through each leg

Args: leg1_length_mm: Length of the first leg (vertical leg in the standard orientation). Must be > 2×thickness_mm. leg2_length_mm: Length of the second leg (horizontal leg). Must be > 2×thickness_mm. width_mm: Bracket depth (out-of-page in side view). Must be > 0. thickness_mm: Wall thickness — same for both legs. Default 5mm (typical stamped-steel autopart). leg1_bolt_count: Number of bolt holes through leg 1. 0..6. 0 = no bolts on this leg (one-sided bracket). Default 2. leg2_bolt_count: Same for leg 2. Default 2. bolt_hole_diameter_mm: Through-hole diameter for each bolt. Default 8.5mm = ISO 273 medium fit for M8. bolt_hole_inset_mm: Distance from leg edge to first/last bolt center (mm). Default 15. Constraint: 2×inset + bolt_hole_diameter must fit in each leg's length.

Returns dict: body: Feature info for the L-shape extrude (boss_extrude). leg1_bolts: Feature info for the leg-1 cut, or None if leg1_bolt_count=0. leg2_bolts: Feature info for the leg-2 cut, or None if leg2_bolt_count=0. leg1_length_mm, leg2_length_mm, width_mm, thickness_mm, leg1_bolt_count, leg2_bolt_count: echo back the input dimensions for LLM verification.

Geometry (orientation contract): - L-profile in Front plane (XY): leg1 along +Y, leg2 along +X - Inside corner of L at world (thickness, thickness, 0) - Body extruded +Z by width_mm - Outer face of leg 1 = -X face (X=0); bolts drilled in +X - Outer face of leg 2 = -Y face (Y=0); bolts drilled in +Y

Caveat (no inside fillet): the inside corner of the L is sharp. For stress relief, post-process with fillet on the inside-corner edge (use list_edges to find it) — typical R = 1×thickness.

Example — autoparts wall-bracket 60×80mm × 40 wide × 4mm thick, M6 bolts, 2 per leg: build_l_bracket( leg1_length_mm=60, leg2_length_mm=80, width_mm=40, thickness_mm=4, bolt_hole_diameter_mm=6.6, # M6 ISO 273 )

add_end_keywayA

Cuñero — DIN 6885-style axial keyway cut into a shaft end.

Junior workflow: "agrega un cuñero al extremo izquierdo de la flecha, ancho 6mm, largo 20mm, profundidad 3mm, 5mm adentro del extremo". Operates on the active part — assumes a shaft along world X already exists (typically just built with build_stepped_shaft). Composes: create_reference_plane("top", offset = D/2) -> tangent plane on top of the shaft create_sketch() -> slot sketch create_slot(...) -> keyway profile extrude_cut(depth, reverse_direction=True) -> cut INTO body

CRITICAL — reverse_direction=True is non-obvious here. The default extrude_cut direction goes AWAY from the body for offset-plane sketches: the tangent plane's outward normal is +Y, but the shaft body is below the plane at Y < D/2. reverse_direction=True flips the cut so it removes material going from the plane DOWN into the shaft. Without it the cut is a no-op (cuts empty space above the cylinder).

Args: end: "start" (the X=0 end — keyway sits at axial_offset from the min-X face) or "end" (the far +X end — keyway sits at axial_offset from the max-X face). End position resolved best-effort via get_bounding_box on the active part. diameter_at_end_mm: Diameter of the shaft at the end being cut. Used to compute the tangent-plane offset (= D/2). Must be greater than keyway_depth_mm + 1.0 (need at least 1mm of remaining material below the cut). keyway_width_mm: Slot width perpendicular to the shaft axis. Standard DIN 6885 widths (Ø range → width): Ø6-8 → 3mm, Ø10-12 → 4mm, Ø13-17 → 5mm, Ø18-22 → 6mm, Ø22-30 → 8mm, Ø30-38 → 10mm. Default 5mm (covers Ø13-17). keyway_length_mm: Slot total axial length (including rounded ends). Must be greater than width (slot is rectangle + 2 semicircles; degenerate when length ≤ width). Default 15mm. keyway_depth_mm: Cut depth from the shaft surface inward. Standard ~D/8 for power transmission. Default 2.5mm. axial_offset_from_end_mm: Distance from the shaft end face to the nearest slot edge. Default 5mm (typical clearance for keystock insertion).

Returns dict: cut: Feature info for the extrude_cut (cut_extrude). plane: Plane dict (name, parent_plane, offset_mm) for the tangent reference plane. input echoes (end, diameter_at_end_mm, keyway_*_mm, axial_offset_from_end_mm). keyway_start_x_mm, keyway_end_x_mm: DERIVED — world-X positions of the slot edges. Use these to verify the cut landed where you intended. shaft_bbox_mm: {"min", "max", "size"} — the bbox we resolved the axial position from. Reported so the caller can audit the best-effort end resolution (multi-feature parts — shaft plus flange disk, end cap, etc. — may have bbox X-extremes that aren't the shaft tip). warning: present (string) ONLY if the resolved keyway overlaps the bbox extent — non-fatal, surfaces the question to the caller without raising.

Caveat (orientation): assumes shaft axis = world +X, shaft cross- section centered on Y=Z=0. This matches build_stepped_shaft's contract. For shafts in arbitrary orientation, use the primitive chain (create_reference_plane → create_sketch → create_slot → extrude_cut(reverse_direction=True)) directly.

list_capabilitiesA

Inventario autoritativo de herramientas MCP_CAD — solo nombres.

Las descripciones completas ya viajan en cada tools/list; este catálogo confirma la superficie viva (conteo + nombres) sin duplicar ese contexto.

[en: authoritative live tool inventory, names only. Full descriptions already ship with tools/list — call this to confirm the live surface or an exact tool name without re-paying for the docstrings.]

Returns: {"tool_count": int, "tools": [str, ...]} # alphabetical names

clarify_autoparts_intentA

Devuelve interpretaciones autoparts para un término en español/spanglish.

Phase 2 / Layer 2: cuando un usuario use un término informal de autopartes ('rin', 'buje', 'soporte', 'brida', 'cubo', 'flecha', 'polea', 'tapa', 'caja', 'gancho', 'balero', etc.) y necesites confirmar qué arquetipo geométrico quiere ANTES de proponer un plan, llama esta herramienta para obtener el mapeo curado.

Devuelve:

  • primary_archetype: la interpretación más común

  • alternative_archetypes: otras lecturas razonables

  • typical_dimensions: rangos esperados (mm/grados/conteos)

  • disambiguation_question: pregunta exacta para el usuario

[en: Look up an informal Mexican-Spanish autoparts term and get its curated geometric interpretation — primary archetype + alternatives + typical dim ranges + a ready-to-ask disambiguation question — use it to ground your interpretation when the user's request hinges on an ambiguous term. v1 vocabulary is Mexican-Spanish-specific and fixed in code; v1.1 may make it customer-extensible.]

Args: term: The Spanish / Spanglish term to look up. Case- and accent-insensitive ('Rin', 'rin', 'RIN' all match).

Returns: On match: { "term": str, # canonical spelling "primary_archetype": str, # internal handle "primary_description": str, # Spanish description "alternative_archetypes": [str, ...], "alternative_descriptions": [str, ...], "typical_dimensions": {key: [min, max], ...}, "disambiguation_question": str, "notes": str, "found": True, } On miss: { "term": str, "found": False, "fallback": str, # what to do instead "available_terms": [str, ...], # what IS in the glossary }

Caveat: this v1 vocabulary is Mexican-Spanish autoparts only. Argentine, Brazilian, or Peninsular Spanish usage may differ. Customers wanting their own vocabulary need v1.1 customer-config support.

Caveat: NOT all terms have a clean primary archetype. Generic terms like 'soporte', 'caja', 'balero', 'tornillo', 'rosca' map to 'ambiguous' or 'needs_custom_modeling' — use the disambiguation_question to narrow down.

Example — disambiguating 'rin' before building geometry: intent = clarify_autoparts_intent("rin") # → primary_archetype="wheel_rim", # alternatives=["wheel_hub_disc", "brake_rotor"], # typical_dimensions={od_mm: [330, 560], pcd_mm: [98, 120], ...} # Use the disambiguation_question to confirm the reading with # the user before any geometry runs.

search_part_catalogA

Busca una pieza ESTÁNDAR en catálogos abiertos y juzga su ajuste (search+judge).

Lane de reúso open-resource (docs/OPEN_RESOURCE_LANE.md). Cuando el diseñador pide una pieza estándar (tornillo, tuerca, balero, brida, perfil, conector…) que NO hace falta modelar de cero, resuelve la intención abstracta en candidatos rankeados de 3D ContentCentral / McMaster-Carr / TraceParts — cada uno con su deep-link, formatos, licencia, veredicto nativo-vs-tonto y recomendación insertar-vs-macro.

Modo v1 = DEEP-LINK: NO descarga geometría. Devuelve una URL de búsqueda por recurso; el diseñador descarga el archivo EN SU MÁQUINA. Luego: insertar+matear (place_and_mate / stack_components); si es NATIVA parametrica → editar cotas (list_dimensions / modify_dimension); si es sólido tonto (lo usual en catálogos) y hay que cambiar medidas → regenerar equivalente parametrico con la lane de macros (record_macro_job / run_macro_job).

Constraint #1: SÓLO texto abstracto (tipo, estándar, medida nominal, material) se vuelve consulta saliente — nunca geometría del cliente. Nada de terceros entra al repo; la geometría descargada se queda en el host.

[en: Search open CAD resources for a STANDARD part from abstracted text intent and judge fit (folds search + judge). v1 DEEP-LINK mode downloads NOTHING — it returns ranked candidates with a per-resource search URL, license, native-vs-dumb verdict, and an insert-vs-macro recommendation. The designer fetches the file onto their own machine; the existing geometry tools take over. Only abstracted text leaves the host.]

Args: spec: Structured ABSTRACTED part spec — generic fields only: type ("tuerca hexagonal"), standard ("DIN 934"), size ("M8x1.25"), material ("acero inoxidable A2"), nominal ({dim: value}, echoed back), query (explicit override). Never put customer geometry here. resources: subset of ["3dcontentcentral","mcmaster","traceparts"] (default all; unknown names ignored). top_n: max candidates (default 3). needs_edit: True if the designer will change dimensions — drives the insert-vs-macro recommendation (a dumb catalog .sldprt → macro lane).

Returns: {"query": str, "needs_edit": bool, "count": int, "note": str, "candidates": [{"resource","title","standard","part_number","nominal", "formats","native_vs_dumb","license_class","deep_link","deep_link_note", "fit_verdict","fit_score","recommendation"}, ...]} # ranked by fit_score

Reúso-primero: si hay una carpeta indexada localmente, llama PRIMERO a query_part_library; usa esta herramienta cuando NO exista local y convenga traer un estándar del catálogo abierto.

verify_setupA

Diagnóstico — comprueba que la instalación de MCP_CAD funcione.

Junior workflow: en la primera instalación o cuando algo se ve raro, pregunta a Claude "verify_setup" para obtener un checklist de:

  • El servidor MCP responde y la versión de Python.

  • SolidWorks responde (en modo live) o estamos en modo mock.

  • Hay un documento activo (pieza/ensamble) accesible.

[en: Diagnostic — verify the MCP_CAD installation. Returns a checklist a non-technical customer can scan to confirm everything's wired correctly. Run after install, or when something seems off.]

Returns: { "ok": bool, # overall pass/fail "summary": str, # one-line Spanglish status "checks": [ {"name": str, "ok": bool, "detail": str}, ... ], }

A red check on "Active document" is normal if no part is open — the customer can still confirm the rest of the setup. A red check on "SolidWorks connection" in live mode requires opening SW first.

list_recent_plansA

Devuelve los planes registrados en esta sesión (depuración).

Útil cuando el LLM olvida un id de plan. El registro vive en memoria — se borra al reiniciar el servidor MCP.

[en: Debug aid — assembly plans, compiled feature plans, batch jobs, and macro jobs recorded this session. In-memory only; clears on server restart.]

Returns: {"assembly_plans": [, ...], "feature_plans": [, ...], "batch_jobs": [, ...], "macro_jobs": [, ...]}

record_drawing_specA

Record a structured DrawingSpec (LEGACY/dormant spine — see docs/AUTOMATION_LANE.md).

Advisory only: does NOT mutate SolidWorks. Pins a structured part spec (the LLM's own reading, from any source) so compile_feature_plan_from_drawing_specrun_feature_plan can build it deterministically. Generating a part from a drawing is a legacy path, not the product focus (automation + reuse).

Args: source: Dict with pdf_path, page_number, crop_pdf_pts, render_path, note. interpretation: One-sentence part interpretation. archetype: One of axisymmetric_revolved, extruded_closed_profile, plate_hole_pattern, custom. dimensions: List of {name, value, units, status, source, tolerance, confidence, note}. status is grounded/derived/assumed/missing. features: List of {kind, label, tool, params, source_dimensions, confidence, note}. If tool is set, compile_feature_plan will use it directly; otherwise it emits archetype defaults. internal_features: List of {type, diameter_mm, radius_mm, depth_mm, axis, position_mm, status, note} — the dashed-line bores/grooves/threads to model. type is through_hole/blind_hole/counterbore/countersink/ groove/thread/radius_cut. radius_cut (a swept-arc / scooped cut) uses radius_mm instead of diameter_mm. verify_build_report reconciles each against the built tree to catch silently-dropped or wrong-sized features. views: Optional list of source-view notes/crops. assumptions: Assumptions explicitly chosen by the LLM/user. missing_dimensions: Required dimensions not visible in the source. confidence: Global confidence 0..10. notes: Free-form audit notes.

Returns the stored spec, warnings, expected_size_mm when inferable, and a short build recommendation.

compile_feature_plan_from_drawing_specA

Compile a stored DrawingSpec into an ordered FeaturePlan.

Advisory only: returns MCP tool names + params to execute, but does not mutate SolidWorks. It supports the first PDF archetypes explicitly: axisymmetric_revolved, extruded_closed_profile, and plate_hole_pattern.

execute_batchA

Ejecuta una lista ORDENADA de operaciones de bajo nivel en UNA sola pasada.

Es el primitivo "compila una vez, construye una vez" estilo build123d: en vez de N llamadas sueltas (cada una = un viaje al add-in + un rebuild/redibujo de SolidWorks), envía TODO el lote en una sola llamada. El add-in lo ejecuta in-process con redibujo, árbol de operaciones y reconstrucción SUPRIMIDOS, y hace UNA sola reconstrucción al final. La superficie sigue acotada: cada tool del lote se despacha por el mismo switch de operaciones permitidas — NO puede invocar API arbitraria ni geometría inventada.

[en: Run an ORDERED list of low-level ops in ONE pass — the build123d-style "compile once, build once" primitive. The add-in runs them in-process with redraw/feature-tree/rebuild suppressed and ONE rebuild at the end.]

Args: ops: lista de {"tool": <nombre-de-operación>, "args": {: valor}}. tool debe ser una operación de PROTOCOLO (p.ej. "create_sketch", "create_line", "create_circle", "extrude_sketch", "fillet") — NO un compuesto build_* ni una herramienta de percepción/IO. Los nombres de args deben coincidir EXACTAMENTE con los parámetros de esa operación (p.ej. create_line: x1_mm, y1_mm, x2_mm, y2_mm). No se permiten begin_batch / end_batch / execute_batch dentro del lote. rebuild: si True (default), una reconstrucción al cerrar el lote. verify: "summary" (default) adjunta un chequeo BARATO post-build (feature_count + bbox, SIN render) para verificar sin gastar un capture_views; "none" lo omite. Renderiza tú al final, no por feature.

Semántica TODO-O-NADA: si una operación falla, se revierte el modelo a su conteo de operaciones previo al lote (deshacer) y se reporta el índice/paso que falló — nunca se deja una pieza a medio construir que "parece" correcta.

Devuelve {ok, count, results:[{index,tool,result}], rebuilt, summary?} en éxito, o {ok:false, failed_index, failed_tool, error, rolled_back, applied_before_failure} en fallo. Aprobación humana: esta llamada (aprobada por el diseñador en el cliente MCP) ES la aprobación del lote completo.

build_part_dslA

Construye una pieza desde un script FLUIDO estilo build123d en UNA llamada.

"Compila una vez, construye una vez": escribe la pieza como UNA expresión encadenada; el servidor la compila a una op-list y la ejecuta como un solo lote (mismas garantías que execute_batch — redibujo/reconstrucción diferidos, rollback todo-o-nada, una sola aprobación). NO ejecuta código: solo una gramática CERRADA (Part() + métodos en lista blanca + edges() + literales); cualquier otra cosa se rechaza.

Ejemplos: build_part_dsl("Part().sketch('front').circle(0,0,20).extrude(30)" ".chamfer(edges(geom='circle', sort='z', dir='desc', pick='first'), d=1)") build_part_dsl("Part().sketch('front').rectangle(-30,-20,30,20).extrude(15)" ".fillet(edges(geom='line'), r=2)")

Métodos: sketch(plane), rectangle(x1,y1,x2,y2), circle(cx,cy,r), line(x1,y1,x2,y2), arc(cx,cy,r,start,end,direction='ccw'), extrude(depth, reverse=False), cut(depth=0, through_all=False), fillet(edges(...), r=R), chamfer(edges(...), d=D, angle=45). Multi-feature: encadena varios sketch(plano) en planos por defecto ('front'/'top'/'right'). edges(...): geom/body/axis/at/tol/min/max/radius/sort/dir/pick/scope (scope 'last_feature'/'new' = Select.LAST/NEW). v1: NO sketch-sobre-cara / selectores de cara (usa create_sketch_on_face con selector por separado).

[en: Build a part from a fluent build123d-style script in one call. A closed grammar compiled to the execute_batch op-list and run; no code is executed.]

Args: script: la expresión fluida. dry_run: si True, solo compila y devuelve la op-list (no toca SolidWorks). rebuild: una reconstrucción al cerrar el lote (default True).

Devuelve el resultado de execute_batch + compiled_ops (qué se ejecutó) + summary. DSL inválido -> error claro; cae a execute_batch o tools sueltas.

run_feature_planA

Construye un FeaturePlan compilado en UNA sola pasada (compila una vez, construye una vez).

Flujo recomendado para dibujos/PDF:

  1. record_drawing_spec → fija la lectura.

  2. compile_feature_plan_from_drawing_spec → obtén el plan y MUÉSTRASELO al diseñador (pasos, dimensiones, advertencias).

  3. run_feature_plan(feature_plan_id) → ESTA llamada (aprobada en el cliente MCP) es la aprobación humana del build completo; ejecuta todos los pasos que mutan el modelo dentro de UN solo lote (redibujo/reconstrucción diferidos a una sola reconstrucción al final).

  4. revisa el verify_build_report devuelto + el render final.

[en: Build a compiled FeaturePlan in ONE pass. Show the plan to the designer after compiling; calling this tool (approved in the MCP client) is the single human-in-the-loop approval of the whole build. Mutating steps run inside one batch scope; verification runs once at the end.]

Compuerta de confianza: un plan marcado para "partial_or_handback" NO se construye solo — pasa override_low_confidence=True para forzarlo tras revisar las advertencias. Un plan con dimensiones sin resolver () se rechaza siempre: nunca se inventa una cota.

Compuerta de features internas: si el spec registró barrenos/ranuras punteadas que el plan NO modela (unmodeled_internal_features), se bloquea — pasa override_unmodeled_internal=True para construir sin ellas (flag independiente de override_low_confidence: forzar una no desactiva la otra).

record_assembly_planA

Registra un AssemblyPlan estructurado (SKELETON → lista de partes → plan de mates) ANTES de tocar SolidWorks. Solo asesoría: no muta nada. Muéstrale el plan al diseñador; luego ejecútalo con run_assembly_plan.

Args: intent: Una oración: ¿qué ensamble es? skeleton: {file_path, insert_xyz_mm?, config_name?} — el componente FIJO (primer insert, auto-fijado). Elígelo deliberadamente (base/housing, nunca un tornillo). SIN mates. components: lista ORDENADA de {file_path, insert_xyz_mm?, config_name?, mates: [{tool, params, note?}], confidence?, note?}. Cada componente DEBE traer ≥1 mate (mate-or-incomplete). tool ∈ add_coincident_mate / add_concentric_mate / add_distance_mate / add_angle_mate / add_mate_by_face_position / stack_components / place_and_mate. En params usa '' (la instancia recién insertada) y '' — se sustituyen con los nombres vivos al ejecutar. Prefiere mates por posición/composites (nombres de entidad crudos son sensibles a locale); mates biestables (distance/angle) → envuélvelos en place_and_mate. save_path: .SLDASM para guardar al final ("" = no guardar). use_active_assembly: False → new_assembly primero. confidence: 0–10 global (escala de confianza del plan: ≥6 ejecuta).

Devuelve {assembly_plan_id, plan, warnings, unmated_components, go_recommendation}. Componentes sin mates o params '' BLOQUEAN run_assembly_plan. [en: Record a structured assembly plan — advisory only; review with the designer, then execute via run_assembly_plan.]

run_assembly_planA

Ejecuta un AssemblyPlan registrado: inserta y matea componente POR componente (nunca insertar-todo-y-matear-al-final), con recibo por paso (conteo de componentes/mates vía get_active_assembly_info).

ESTA llamada (aprobada en el cliente MCP) es la aprobación humana del ensamble completo. Los pasos corren secuenciales EN VIVO — no van en execute_batch: los mates necesitan rebuilds reales y el rollback de lote no puede borrar componentes (el borrado está diferido por diseño).

Compuertas: go_recommendation='partial_or_handback' bloquea salvo override_low_confidence=True; componentes sin mates bloquean salvo override_unmated=True (flags independientes — forzar una NO desactiva la otra); '' se rechaza SIEMPRE. place_and_mate con pose_held=False cuenta como fallo del paso. Fallo a medio plan → se DETIENE y reporta estado parcial (qué se insertó, qué se mateó) — NO se borra nada; mitigación sugerida: set_component_suppression.

Verificación final: mates ≥ componentes-1 y sin componentes flotantes; solo si pasa (y hay save_path) se guarda. Devuelve {ok, steps, verification, saved, warnings}. [en: Execute a recorded AssemblyPlan — sequential live insert+mate per component, per-step receipts, stop-and-report on failure (no deletion), final mate-count gate; save only on verified success.]

record_batch_jobA

Registra un BatchJob (UN verbo determinista sobre un conjunto de archivos) y devuelve una VISTA PREVIA EN SECO (old→new por archivo) SIN mutar nada — esa vista previa ES la aprobación humana a escala (no se aprueban 70k archivos uno por uno; se aprueba verbo + alcance + el diff). Revísala; luego ejecútalo con run_batch_job.

Args: intent: Una oración: ¿qué cambio masivo es? fileset: {root, glob?, recurse?, paths?, exclude?, confidence?} — la carpeta (+filtro) o una lista explícita de rutas. Resolver el alcance lee SOLO metadatos de ruta; la geometría no se transmite. operation: {verb, params} — verb ∈ set_custom_property / export_document / force_rebuild / check_interference / get_bom. Ej: {"verb":"set_custom_property", "params":{"name":"Proveedor","value":"ACME","config":""}}. save_after: guardar cada archivo tras un verbo que modifica el documento (p.ej. set_custom_property). export/health/BOM no guardan el origen. continue_on_error: True → un archivo malo no aborta el lote (cada salto se reporta en el manifiesto). out_dir: carpeta ÚNICA para las salidas (export/BOM) y el manifiesto ("" = junto al origen). Una ruta de red aquí dispara una advertencia (la geometría no debe salir del host). confidence: 0–10 del plan (afecta go_recommendation: <6 → handback). preview_cap: máximo de filas en la vista previa.

Devuelve {batch_job_id, matched_files, preview, preview_truncated, warnings, go_recommendation}. [en: Record a batch job + return a dry-run preview — advisory only; review, then run_batch_job.]

run_batch_jobA

Ejecuta un BatchJob registrado: aplica el verbo archivo POR archivo, con recibo por archivo (abierto/op/guardado/cerrado) y un MANIFIESTO COMPLETO — cada archivo saltado se reporta (truncar en silencio es el pecado capital).

ESTA llamada (aprobada en el cliente MCP) es la aprobación humana del lote.

Compuertas (tres niveles, como run_assembly_plan):

  1. go_recommendation='partial_or_handback' bloquea salvo override_low_confidence=True;

  2. advertencias 'risky' (irreversible-sin-guardar / ruta de red) bloquean salvo override_warnings=True (flag INDEPENDIENTE — forzar una no desactiva la otra);

  3. fileset vacío o '' sin resolver → se RECHAZA SIEMPRE. No borra archivos (borrado diferido por diseño). Devuelve {ok, changed, skipped, inspected, failed, manifest, failures, log_path} (los verbos de solo-lectura — rebuild/interference/BOM — cuentan como 'inspected', no 'skipped'). [en: Execute a recorded batch job file by file; complete manifest, every skip reported; read-only verbs counted as 'inspected'; no deletion.]

record_macro_jobA

Registra un MacroJob: código VBA escrito por la IA para ejecutarse vía RunMacro2. CRUZA la restricción #2 (API arbitraria de SolidWorks) a propósito, para cubrir tareas fuera del catálogo de verbos. Solo asesoría: NO ejecuta nada. La REVISIÓN HUMANA de generated_source aquí es la aprobación; luego ejecútalo con run_macro_job.

Args: intent: Una oración: ¿qué hace la macro? generated_source: el cuerpo VBA completo (un Sub main, salvo proc_name). Solo formato .swb (texto plano VBA7). proc_name: el Sub de entrada (por defecto 'main'). provenance: {source_kind?: authored|template|recorded, template_id?, generated_by?, notes?} — para auditoría. confidence: 0–10 (afecta go_recommendation).

Devuelve {macro_job_id, source_preview, line_count, proc_name, warnings, risky, go_recommendation}. '' en el código BLOQUEA run_macro_job. [en: Record an AI-authored VBA macro job — advisory only; reviewing the source IS the approval. Crosses constraint #2 by design.]

run_macro_jobA

Ejecuta un MacroJob registrado: materializa la fuente en un .swb temporal EN EL HOST, lo corre vía RunMacro2 (UserControl=False), reconstruye y borra el temporal. Ejecuta VBA arbitraria (cruza la restricción #2). ESTA llamada (aprobada en el cliente MCP) es la aprobación humana.

Compuertas (cuatro niveles): 0) señales de EGRESO a la red (HTTP/stream/descarga/UNC) → restricción #1, RECHAZO NO ANULABLE (la geometría no sale del host — #1 no está waived, a diferencia de #2);

  1. go_recommendation='partial_or_handback' bloquea salvo override_low_confidence=True;

  2. advertencias 'risky' (siempre incluyen la nota de #2; más señales de sistema de archivos/shell) bloquean salvo override_warnings=True (flag independiente);

  3. '' sin resolver en el código → se RECHAZA SIEMPRE. La fuente que corre se anexa a un log de auditoría en el host (MCP_CAD_MACRO_AUDIT_LOG). El .swb nunca sale del host (VBA es texto). Devuelve {ok, ran, run_error, rebuilt, audit_log, audit_recorded}. [en: Execute a recorded macro job — temp .swb on-host, RunMacro2, rebuild, delete temp; network-egress is a hard non-overridable block (constraint #1); source appended to the on-host audit log.]

verify_build_reportC

Create a structured verification report for the active part.

Extends verify_against_spec: bbox remains the hard envelope check, while mass/volume/feature count/screenshots are advisory evidence in one report.

build_part_indexA

Indexa una carpeta de piezas .SLDPRT en un catálogo LOCAL (PDM-lite).

Abre cada pieza EN SERIE (solo lectura), toma nombre/bbox/masa/inventario de barrenos, la cierra, y guarda todo en mcp_cad_index.sqlite DENTRO de la carpeta — nada sale del equipo (sin red, sin telemetría). Incremental: archivos sin cambios (mtime+tamaño) se saltan; rebuild=True relee todo. Corre con SolidWorks desocupado: abre y cierra documentos.

Args: folder: carpeta raíz (búsqueda recursiva; ignora temporales ~$). rebuild: True relee también los no-modificados. max_parts: tope de archivos por corrida.

Returns: {indexed, skipped_unchanged, removed_stale, failed[], parts, bores, db_path, truncated_at_max_parts}.

query_part_libraryA

Busca piezas parecidas en el catálogo local — '¿ya hicimos algo así?'.

Filtros combinables (AND): texto libre en español (por tokens, ignora acentos; busca en nombre de archivo/pieza/notas), Ø de barreno requerido ± tolerancia, ventana de masa, y envelope [x,y,z] mm donde la pieza debe caber (sin importar orientación). Read-only sobre el índice; corre build_part_index primero en esa carpeta.

Args: folder: carpeta ya indexada. text: p.ej. 'buje balero'. bore_diameter_mm: la pieza debe tener un barreno de este Ø. diameter_tol_mm: tolerancia del Ø. min_mass_g / max_mass_g: ventana de masa. fits_envelope_mm: [x, y, z] del material en bruto disponible. limit: máximo de resultados.

Returns: {count, results: [{filename, path, part_name, bbox_size_mm, mass_g, feature_count, cut_count, bores, notes, indexed_at}]}.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/danielproxd2/MCP_CAD'

If you have feedback or need assistance with the MCP directory API, please join our Discord server