{"name":"io.github.mariorojasmz/apolo-cad","slug":"mariorojasmz-apolo-cad","title":null,"description":"Agent-native parametric 3D CAD: model machines, validate them and emit shop drawings","url":"https://mcp.market/server/mariorojasmz-apolo-cad","rating":null,"grade":"B","score":80,"certified":false,"status":"active","category":"ai","tags":["ai"],"presence":{"score":18,"stars":2,"forks":2,"downloads_week":null,"last_push_at":"2026-08-08T23:28:31.000Z","license":"MIT"},"uptime":null,"claimed":false,"transport":"pypi","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/mariorojasmz/apolo-cad","website":"https://github.com/mariorojasmz/apolo-cad","version":"0.1.0","remotes":[],"packages":[{"registryType":"pypi","identifier":"apolo-cad","version":"0.1.0","transport":{"type":"stdio"},"environmentVariables":[{"description":"URL of the running Apolo API server (start it with: apolo)","default":"http://127.0.0.1:8000","name":"APOLO_URL"}]}],"tools":[{"name":"add_agent_note","description":"Añade una nota a la memoria de sesión del agente (tope 30, persiste en el proyecto).","write_action":false,"price_micros":0,"input_schema":null},{"name":"apply_configuration","description":"Aplica una CONFIGURACIÓN guardada: reescribe las variables a los valores de esa variante y regenera el modelo COMPLETO (un solo paso de deshacer). Úsalo para alternar entre variantes de diseño (p. ej. '4m estándar' ↔ '3.2m compacta').","write_action":false,"price_micros":0,"input_schema":null},{"name":"assembly_manual","description":"Genera el MANUAL DE ENSAMBLAJE paso a paso (instructivo de montaje, estilo Inventor/IKEA) en PDF MULTIPÁGINA y lo guarda en `path` (.pdf): portada con la SECUENCIA de montaje + 1 lámina por PASO. Cada paso muestra el render 3D acumulado (las piezas NUEVAS resaltadas a color, lo ya montado en gris fantasma, cámara estable) + la lista de piezas/herraje del paso (con norma) + la instrucción. La secue","write_action":false,"price_micros":0,"input_schema":null},{"name":"auto_group","description":"Auto-agrupa el modelo en SUB-ENSAMBLAJES por subsistema (Estructura, Transmision, Rodillos y tambores, Banda y mesa, Rodamientos, Tornilleria, Guardas…) usando la heurística super-comando → catálogo → palabra clave del nombre. Idempotente (no duplica grupos ni re-agrupa lo agrupado); `dry_run=true` solo PROPONE para revisar antes. Úsalo una vez para poblar un modelo existente; después refina con c","write_action":false,"price_micros":0,"input_schema":null},{"name":"autodetect_connections","description":"Propone uniones de ensamblaje desde la GEOMETRÍA (piezas que apoyan en el piso + pares en contacto por caja envolvente), para poblar la conectividad de un modelo que no la declara. Read-only: confirma las que quieras con run_command(type='ground'|'fasten'). Heurística por AABB (propone, no impone).","write_action":false,"price_micros":0,"input_schema":null},{"name":"calc_report","description":"Genera la MEMORIA DE CÁLCULO (PDF multipágina) y la guarda en `path` (.pdf): portada con BASES DE DISEÑO + índice de verificaciones + VEREDICTO (aprobado/con avisos/no conforme), y una página por verificación con datos de entrada, FÓRMULA, sustitución numérica, criterio de aceptación y FACTOR DE SEGURIDAD (motorización, par, flecha, flexión de eje, pernos, soldaduras, L10, pandeo, vuelco…). Es el","write_action":false,"price_micros":0,"input_schema":null},{"name":"check_assembly","description":"Validación de ensamblaje por CONECTIVIDAD: ¿cada pieza tiene un camino de sujeción hasta el piso? Devuelve las piezas FLOTANTES (caerían bajo gravedad — eje suelto, rodillo sin sujetar, guarda sin tornillo, motor flotando) y las AISLADAS (sin ninguna unión). Determinista, sin motor de física. with_autodetect=True superpone (sin persistir) las uniones detectadas por geometría → responde 'si fijara","write_action":false,"price_micros":0,"input_schema":null},{"name":"check_interference","description":"Interferencias entre sólidos (booleanas OCCT). Con joint_values {junta: valor} comprueba la colisión del mecanismo EN POSE. Con `ids` (feature_ids o NOMBRES DE GRUPO) ACOTA a las parejas donde participa al menos uno de ellos (O(k·n) en vez de O(n²)): valida TU zona de trabajo tras una operación en vez de la máquina entera. Sin `ids` = global.","write_action":false,"price_micros":0,"input_schema":null},{"name":"create_project","description":"Crea y abre un proyecto. template: null | 'transportador' | 'brazo'.","write_action":true,"price_micros":0,"input_schema":null},{"name":"cut_list","description":"Lista de corte de fabricación: piezas a CORTAR (a-medida + catálogo cortable) agrupadas por (material, espesor, ancho, largo) con cantidad y área; totales por material (m²/ml); y cédula de HERRAJE (catálogo no cortable: bisagras/tornillos/ correderas...). Une los sólidos de las uniones (una hoja = 2 largueros). Read-only. El CSV está en GET /api/cutlist.csv.","write_action":false,"price_micros":0,"input_schema":null},{"name":"declare_structure","description":"Auto-declara la ESTRUCTURA real de la máquina (anclajes al piso + uniones de soporte) como comandos PERSISTIDOS, de forma INTELIGENTE (grafo de soporte dirigido): NO fija las piezas que cuelgan sin nada debajo (p. ej. rodillos de retorno). Idempotente (no duplica lo ya declarado). Después, `gravity_test(with_autodetect=False)` es la prueba EXACTA: solo cae lo de verdad suelto. Para corregir, borra","write_action":false,"price_micros":0,"input_schema":null},{"name":"delete_connection","description":"Borra una o VARIAS uniones declaradas por NOMBRE (fijadores o anclajes a tierra) — para corregir el auto-declarado o para cirugías. Pasa `name` (una) o `names` (lote), no ambos. El lote es ATÓMICO (1 undo): si un nombre no existe, no se borra ninguna. Consulta los nombres con get_connections.","write_action":true,"price_micros":0,"input_schema":null},{"name":"delivery_check","description":"LA PUERTA DE SALIDA (V6.9): antes de dar un proyecto por TERMINADO, corre TODA la batería de cierre en UNA llamada y devuelve un SEMÁFORO accionable: {veredicto: VERDE|AMARILLO|ROJO, bloqueantes, avisos, no_aplica, resumen}. Chequeos: interferencias en diseño (exclusiones normales) · sujeción DECLARADA (¿todo tiene camino de carga a tierra? — sin autodetect: cuenta lo que DECLARASTE con ground/fas","write_action":false,"price_micros":0,"input_schema":null},{"name":"drawing","description":"Plano profesional por INTENCIÓN (el moat agente-nativo): UNA spec declara qué quieres y el motor lo dibuja con cotas/cortes/detalles/cajetín pro. spec = {sheet:\"A3\", section:\"x\"/\"y\"/\"z\", detail:{view,u,v,radius,scale}, dims:[ids] (tamaño), datum_dims:[ids] (posición desde la base), bom:true, cutlist:true (tabla DESPIECE con L×A×E por tabla, globos en el alzado — para ENSAMBLAJES, no solo el bbox),","write_action":false,"price_micros":0,"input_schema":null},{"name":"drawing_set","description":"Genera el JUEGO DE PLANOS profesional (PDF multipágina): conjunto con BOM + 1 lámina por pieza ACOTADA + cédula de corte/herraje, y lo guarda en `path` (.pdf). `template`: carpinteria/weldment/chapa/generico. `shaded=true`: el conjunto lleva isométrica SOMBREADA a color (estilo Inventor). Devuelve nº de bytes guardados. ¿DWG para clientes AutoCAD? GET /api/drawingset.dwg = ZIP con un DWG por lámin","write_action":false,"price_micros":0,"input_schema":null},{"name":"drop_test","description":"Simula con FÍSICA (gravedad real, motor MuJoCo) la caída de cajas de 'producto' sobre la escena actual (faja, mesa…) y guarda un GIF animado de la caída en `path`. Cada producto es un dict {w,d,h (mm), x,y,z (mm pose inicial), mass (kg, opcional)}. Devuelve las posiciones de reposo [x,y,z] mm y si el sistema se asentó (settled). Es análisis read-only: NO modifica el modelo.","write_action":true,"price_micros":0,"input_schema":null},{"name":"edit_batch","description":"Edita VARIOS comandos en UN lote ATÓMICO: un solo regenerate y un solo paso de undo (frente a N round-trips + N regenerates de llamar edit_command en bucle). Úsalo al reparametrizar muchas piezas a la vez. edits = [{\"command_id\": \"c38\", \"params\": {...}}, …]. PATCH por defecto (merge=True, superficial: un sub-objeto position/rotation se reemplaza entero); merge=False reemplaza todos los params. Si","write_action":false,"price_micros":0,"input_schema":null},{"name":"edit_command","description":"Edita los parámetros de un comando pasado y regenera (edición paramétrica del historial). Por defecto hace PATCH (`merge=True`): combina con los params actuales, así que basta enviar los campos a cambiar. Merge SUPERFICIAL: un sub-objeto (position, rotation) se reemplaza entero. `merge=False` reemplaza todos los params (los omitidos vuelven a su default). `detail` como en run_command.","write_action":false,"price_micros":0,"input_schema":null},{"name":"engineering_check","description":"Valida el modelo con criterio de ingeniería. Devuelve DOS bloques: `ingenieria` (reglas del transportador: apoyo del paquete, capacidad de rodillo, ancho útil, motorización por CONSTRUCCIÓN — CEMA slider-bed si banda sobre cama / ISO 5048-DIN 22101 si banda sobre rodillos —, par + par de arranque, adherencia del tambor motriz Euler-Eytelwein con la T2 mínima que el tensor debe garantizar, flecha d","write_action":false,"price_micros":0,"input_schema":null},{"name":"export_flat_pattern","description":"Exporta el patrón plano (desplegado) de una chapa metálica a un DXF local para corte láser. feature_id es el id del sólido de la chapa (ver get_scene); debe haberse creado con el comando create_sheet_metal. Soporta las pestañas ricas de V5.5 (multi-pliegue, taladros/recortes en pestañas — proyectados al blank) y K-factor por material (k_factor vacío = tabla según material). ¿DWG? GET /api/sheetmet","write_action":false,"price_micros":0,"input_schema":null},{"name":"export_step","description":"Exporta el modelo a un archivo STEP en la ruta local indicada.","write_action":false,"price_micros":0,"input_schema":null},{"name":"export_stl","description":"Exporta los sólidos VISIBLES como UN STL binario (malla) en la ruta local indicada — para impresión 3D, visores de malla o simuladores externos. `tolerance` = desviación máxima de teselado en mm (menor = más fino y pesado). Para CAD/interop usa export_step (B-rep exacto); el STL es malla aproximada.","write_action":false,"price_micros":0,"input_schema":null},{"name":"fea_assembly","description":"FEA ESTÁTICO LINEAL BONDED de un SUB-ENSAMBLAJE (V7.4): el bastidor SOLDADO completo (N sólidos PEGADOS, nodos compartidos en las interfaces = sin contacto) bajo la carga de diseño, MULTI-MATERIAL, con σ_vm y FS reportados POR PIEZA (la gobernante es la de menor FS). Pasa `group` (nombre de sub-ensamblaje) o `ids` (piezas sueltas + `name`). El empotramiento se DERIVA de los grounds (base de las pa","write_action":false,"price_micros":0,"input_schema":null},{"name":"fea_static","description":"FEA ESTÁTICO LINEAL de UNA pieza (V5.6): malla tet P2 (gmsh) + elasticidad lineal (scikit-fem). Devuelve σ_vm máx (MPa) con su ubicación, desplazamiento máx (mm), FS = σy/σ_vm (criterio: ≥2 estático, <1.2 sobrecargada) y las HIPÓTESIS declaradas; el resumen se GUARDA y entra solo a la memoria de cálculo (con aviso automático si la geometría cambia después). `fixed` y `loads[].selector` son selecto","write_action":false,"price_micros":0,"input_schema":null},{"name":"find_commands","description":"Busca COMANDOS en el log del documento y devuelve filas compactas [{id, type, resumen}] — para encontrar el command_id que quieres editar/borrar SIN deducirlo por aritmética de lotes. Al menos un filtro: - type: tipo exacto ('chamfer', 'create_box', 'add_joint', …). - feature: comandos que CREARON ese sólido o lo REFERENCIAN en sus params (feature/feature_a/b, members, parent/child, selectores…).","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_agent_notes","description":"Lee la memoria de sesión del agente (notas del proyecto).","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_bom","description":"Lista de materiales del modelo actual, agrupada por referencia y longitud (las piezas a-medida idénticas se agrupan e incluyen peso por volumen×densidad). Con `by_group=true` cada fila lleva su sub-ensamblaje y las piezas iguales de grupos distintos salen separadas (subtotales por grupo/instancia — útil a escala).","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_catalog","description":"Catálogo de componentes industriales (perfiles, rodillos, motorreductores, patas, guardas, sensores) con especificaciones y pesos. Es grande (~73 KB); filtra con `category` (p. ej. 'motorreductores', 'tubos_estructurales', 'rodamientos', 'tornilleria', 'tensores_trotadora') y usa `names_only=True` para traer solo ref/name/category (payload ligero).","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_command","description":"Devuelve {type, params} del comando indicado (su estado ACTUAL) para editarlo con edit_command. Usa get_scene para ver los ids (campo 'comando' de cada sólido).","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_command_schemas","description":"Comandos CAD con su JSON Schema de parámetros. Consúltalo antes de run_command/run_batch. Sin argumento lista TODOS (es grande, ~77 KB); pasa `command_type` (p. ej. \"create_belt_conveyor\") para traer SOLO ese schema.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_connections","description":"Uniones de ensamblaje DECLARADAS (persistidas) del documento: fijadores (a↔b) y anclajes a tierra, con sus nombres (para borrarlas con delete_connection). Read-only.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_costing","description":"BOM COSTEADO en USD: cada fila del BOM con costo_ud/costo_total y su FUENTE (precio referencial de catálogo / estimación de hardware peso×material×3 / fabricación a medida peso×material×2.5) + totales por categoría, catálogo vs fabricación y el ÍTEM MÁS COSTOSO. Úsalo para optimizar costos ('¿qué pieza es la más cara?', comparar alternativas) y como base de la cotización. Precios referenciales — c","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_design_guidelines","description":"Criterio de INGENIERÍA que debes aplicar por DEFECTO al diseñar (máquinas, muebles, estructuras, cualquier objeto): el decálogo completo con detalle, CÓMO verificar cada regla en Apolo, cuándo preguntar vs. asumir, y ejemplos por dominio. Las instrucciones del servidor ya traen el resumen; consulta ESTO cuando vayas a diseñar algo no trivial (añadir una guarda, un soporte, un mueble) para no entre","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_dof","description":"Reporte de GRADOS DE LIBERTAD del ensamblaje (análogo 3D del dof/redundantes del croquis): por sólido, cuántos GDL le quedan tras ground/juntas/mates y su estado (fijo | parcial | libre | sobre_restringido) + qué lo restringe. Conteo Grübler determinista. OJO: el conteo es heurístico (no ve redundancia geométrica); un 'sobre_restringido' puede ser redundancia benigna — los conflictos REALES los re","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_expression_grammar","description":"Funciones, constantes, operadores permitidos en los campos '=expr' y las variables del proyecto disponibles. Consúltalo antes de escribir expresiones complejas.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_fit","description":"Límites y análisis de AJUSTE ISO 286 (V5.4) — consúltalo al DISEÑAR un asiento. Con `hole` (H7/G7/JS7/K7/M7/N7/P7…) y `shaft` (g6/h7/js6/k6/m6/n6/p6…): análisis completo del ajuste — juego/transición/apriete con juego_min/max en µm. Con uno solo: sus límites (ei/es µm, lo/hi mm) sobre el nominal. Criterio de asientos: inserto de chumacera UC → eje h7 (desliza; fijan los prisioneros); rodamiento pr","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_groups","description":"GRUPOS / sub-ensamblajes del documento: nombre, padre (anidación), rol, comandos miembro y members faltantes. Los grupos se CREAN con run_command(type='create_group', params={name, members:[command_ids], parent?, role?}) — la membresía es por COMANDO (estable: las instancias nuevas de un patrón editado entran solas) — y se MUEVEN enteros con run_command(type='transform_group', {group, translate, r","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_job","description":"Recoge el resultado de un lote que devolvió un RECIBO {\"job\": id} (run_batch/ edit_batch tardaron más que el presupuesto de espera). Espera hasta `wait_s` segundos (long-poll: responde en cuanto el job termina) y devuelve lo MISMO que habría devuelto el lote (sólidos + `contrato`), o `{\"estado\": \"corriendo\"}` si aún no acaba — vuelve a llamar. El resultado queda CACHEADO: re-preguntar es SIEMPRE s","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_kinematics","description":"Juntas cinemáticas del modelo (nombre, tipo, padre/hijo, eje, límites).","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_mass_properties","description":"Masa (kg), centro de gravedad (mm) y bbox por pieza y del CONJUNTO. Sin `ids` analiza todas las piezas visibles; con ids solo esas (aunque estén ocultas). El catálogo pesa por su ficha (dato de placa); lo a-medida por volumen × densidad del material resuelto. Úsalo para vuelco/equilibrio (¿el COG cae dentro de la base?), repartos de carga y BOM de pesos. Read-only.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_mates","description":"Mates de ensamblaje del documento (uniones persistentes entre piezas).","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_motion","description":"Estudio de movimiento: fotogramas de juntas y duración.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_requirements","description":"BASES DE DISEÑO del proyecto (requisitos guardados: carga_kg, largo/ancho/ alto_paquete_mm, velocidad_m_s, inclinacion_deg, producto, entorno, normativa…). engineering_check y la memoria de cálculo los usan como defaults. Read-only.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_scene","description":"Estado del modelo. Sin argumentos: TODA la escena (sólidos con id/nombre/bbox/volumen/ componente + variables + configuraciones) — cuidado en proyectos grandes. Para trabajar a ESCALA (miles de piezas) usa los filtros y NO vuelques la escena entera: - `summary=true`: entra por aquí — resumen por GRUPO (n_piezas, masa, bbox conjunto, sub-grupos) + «(sin grupo)» + totales + variables. La vista de un","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_stackup","description":"Evalúa las CADENAS DE COTAS (stack-up, V7.3): por cadena da el cierre nominal, el intervalo por PEOR CASO y por RSS (√Σt²), y el veredicto contra el requisito. Incluye las cadenas auto del patrón de pernos (join_bolted = cerrada por construcción). Verifica que la suma de tolerancias cierra el ajuste declarado SIN encadenar N measure. scope = all | declared | auto. Read-only.","write_action":false,"price_micros":0,"input_schema":null},{"name":"get_topology","description":"Caras y aristas de un sólido con su geometría descriptiva (tipo plano/cilíndrico, centro, normal/eje, área; longitud, dirección, radio de aristas). Úsalo para ELEGIR el selector declarativo antes de fillet/chamfer/drill/add_mate: caras por orientación (normal) → 'cara'/'direccion'; aristas largas → 'longitud'; cerca de un punto → 'cerca'. Los 'idx' son solo referencia: la selección sigue siendo de","write_action":false,"price_micros":0,"input_schema":null},{"name":"gravity_test","description":"Simula la GRAVEDAD sobre TODA la máquina (cuerpos rígidos + colisión por casco convexo, motor MuJoCo) y reporta qué piezas SE CAEN y cuáles aguantan. A diferencia del chequeo estático, la FÍSICA decide si una pieza no-sujeta REPOSA sobre algo firme (no cae) o cuelga en el aire (cae) — resuelve \"quién aguanta a quién\". with_autodetect usa el contacto geométrico como estructura sujeta; `exclude` tra","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_projects","description":"Proyectos guardados (SQLite, con autoguardado).","write_action":false,"price_micros":0,"input_schema":null},{"name":"list_revisions","description":"Lista las revisiones (instantáneas restaurables) del proyecto abierto.","write_action":false,"price_micros":0,"input_schema":null},{"name":"measure","description":"Distancia mínima (mm) y puntos más cercanos entre dos sólidos a y b (ids). El gap real deja de ser ensayo-error. Opcional: face_a/face_b = selector declarativo (mode cara/direccion/ longitud/cerca) para medir contra UNA cara concreta. 0 = se tocan o solapan. Read-only.","write_action":false,"price_micros":0,"input_schema":null},{"name":"motion_gif","description":"GIF animado de un estudio de movimiento, ESCRITO a `path` (las tools no devuelven binarios). Cada fotograma se pinta con el mismo motor VTK que render_view, con la cámara FIJA a la unión de todo el recorrido; `pingpong` añade la vuelta (bucle sin salto). COSTO REAL: el teselado no se cachea entre fotogramas (≈ steps × render de la escena) — en modelos grandes usa steps moderados (24-48) y baja siz","write_action":false,"price_micros":0,"input_schema":null},{"name":"near","description":"Consulta espacial por caja envolvente, de más cerca a más lejos. Da EXACTAMENTE uno de: - `point` [x,y,z]: '¿qué pieza hay por aquí?' (combínalo con pick_point). - `feature` (id): '¿qué RODEA a X?' — distancia AABB-AABB al resto, excluyendo X. - `box` [[min_x,min_y,min_z],[max_x,max_y,max_z]]: '¿qué hay en esta REGIÓN?'. `radius` mm (radius=0 con box/feature = solo lo que lo toca) + `limit` (def.","write_action":false,"price_micros":0,"input_schema":null},{"name":"nesting","description":"Optimización de corte (nesting) para minimizar desperdicio. `mode`: \"2d\" (tableros/ vidrio en planchas stock_w×stock_h) o \"1d\" (barras/largueros de largo stock_w). `material` filtra (madera/vidrio/acero...). Devuelve nº de planchas/barras y % de desperdicio; el plano del acomodo está en GET /api/nesting.svg|dxf (mismos params). Read-only.","write_action":false,"price_micros":0,"input_schema":null},{"name":"open_project","description":"Abre un proyecto por id. Devuelve además un `briefing` compacto (V6.5b) para arrancar la sesión en UNA llamada: resumen por GRUPO (n_piezas/masa/bbox) + variables + requisitos + notas del agente + salud (ok/suprimidos) + variantes de diseño. Ya NO hace falta encadenar get_scene(summary)+get_requirements+get_agent_notes al abrir.","write_action":false,"price_micros":0,"input_schema":null},{"name":"pick_point","description":"PÍXEL→3D: 'señala' un punto en un render y obtén qué pieza/cara hay ahí. (u,v) son coordenadas NORMALIZADAS [0,1] de la imagen (0,0 = arriba-izquierda). Devuelve la feature/cara cuyo centro proyectado queda más cerca + su coordenada mundo (snap a geometría con la MISMA cámara del render VTK). Así seleccionas/ubicas apuntando en vez de calcular coordenadas. IMPORTANTE: pasa los MISMOS `view`/`azimu","write_action":false,"price_micros":0,"input_schema":null},{"name":"preview","description":"GHOST: aplica `actions` (mismo formato que run_batch: [{type, params}, …]) sobre una COPIA del documento SIN tocar el modelo real — ensaya una colocación y equivocarte sale gratis (sin escombro de log). Dos modos: - `data=false` (default): devuelve el PNG con los sólidos nuevos resaltados (para VERLO). `labels` rotula ids; `section` ∈ {x,y,z} corta para ver dentro. - `data=true` (V6.5d): devuelve","write_action":false,"price_micros":0,"input_schema":null},{"name":"quotation","description":"Genera la COTIZACIÓN del proyecto (PDF multipágina) y la guarda en `path` (.pdf): resumen económico (catálogo vs fabricación, desglose por categoría, margen %, impuesto % opcional, PRECIO DE VENTA, ítem más costoso, notas comerciales) + detalle de partidas = el BOM costeado completo con la FUENTE de cada precio (referencial de catálogo / estimación). Complemento comercial de calc_report (la memori","write_action":false,"price_micros":0,"input_schema":null},{"name":"redo","description":"Rehace la última operación deshecha.","write_action":false,"price_micros":0,"input_schema":null},{"name":"render_view","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"resolve_expression","description":"Evalúa una expresión (=expr) contra las variables del proyecto SIN modificar nada; devuelve {ok, value} o {ok:false, error}. Para comprobar una fórmula antes de usarla.","write_action":false,"price_micros":0,"input_schema":null},{"name":"restore_revision","description":"Restaura una revisión por id (red de seguridad tras ediciones arriesgadas).","write_action":false,"price_micros":0,"input_schema":null},{"name":"run_batch","description":"Ejecuta un lote ordenado de comandos [{type, params}, …]. Usa '$k' en los campos de id de feature para referenciar el sólido creado por la k-ésima acción del lote. `detail`: \"diff\" (def.) devuelve solo los sólidos creados por el lote + `total_solidos`; \"full\" toda la escena; \"summary\" solo id/nombre. `expect` (CONTRATO, V6.5b) = lista de ASERCIONES estilo verify (distancia/volumen/bbox/ sin_interf","write_action":true,"price_micros":0,"input_schema":null},{"name":"run_command","description":"Ejecuta un comando CAD (ver get_command_schemas). Los campos numéricos aceptan '=expresión' con variables del proyecto. `detail`: \"diff\" (def.) devuelve solo los sólidos nuevos + `total_solidos`; \"full\" toda la escena; \"summary\" solo id/nombre de lo nuevo. El bloque `variables` solo aparece si la operación tocó alguna (o detail=\"full\"); usa get_scene para verlas siempre.","write_action":true,"price_micros":0,"input_schema":null},{"name":"save_configuration","description":"Guarda una CONFIGURACIÓN (variante = tabla de diseño) con los valores ACTUALES de todas las variables del proyecto. Aplícala luego con apply_configuration para saltar el modelo entero a esa variante (un solo undo). Ver las variables con get_scene.","write_action":false,"price_micros":0,"input_schema":null},{"name":"save_revision","description":"Guarda una revisión (instantánea restaurable) del proyecto abierto.","write_action":false,"price_micros":0,"input_schema":null},{"name":"scan_motion","description":"Escanea las COLISIONES de un estudio de movimiento a lo largo del recorrido: muestrea `steps` instantes (FK + interferencia por instante — costo ≈ steps × check_interference posado) y devuelve SOLO los que colisionan, con pares y volumen. Lista vacía = recorrido limpio. Corre esto tras cada cambio del mecanismo; para garantizarlo por CONTRATO en un lote usa `expect` con joint_values. Read-only.","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_color","description":"Color de VISUALIZACIÓN de uno o VARIOS sólidos ('#rrggbb'; None = volver al color automático). Pasa `feature` (uno) o `features` (lote — atómico), no ambos. Solo apariencia del viewport/render — no toca material, BOM ni peso.","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_material","description":"Fija (anula) el material de uno o VARIOS sólidos para el BOM/peso/rayado de sección. Pasa `feature` (uno) o `features` (lote — N piezas en 1 llamada, atómico: un id inexistente no aplica nada), no ambos. material=None vuelve al automático (catálogo o heurística por nombre). Ej.: 'acero', 'aluminio', 'acero inoxidable', 'laton', 'madera', 'vidrio'.","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_motion","description":"Define (o borra, con lista vacía) un ESTUDIO DE MOVIMIENTO con nombre — autoría de cinemática sin salir del MCP (V6.8-C). Fotograma: {\"t\": segundos, \"values\": {junta: valor}} — los valores van ANIDADOS en \"values\" (el formato plano se rechaza) y las juntas se validan contra las declaradas (get_kinematics). OJO FK: una junta mueve solo sus HIJOS declarados — completa un cuerpo rígido multi-pieza co","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_requirements","description":"Guarda las BASES DE DISEÑO del proyecto (reemplaza el dict completo; {} borra). Claves numéricas de convención: carga_kg, largo_paquete_mm, ancho_paquete_mm, alto_paquete_mm, velocidad_m_s, inclinacion_deg, temperatura_c. Texto libre: producto, entorno, normativa, notas. Con esto `engineering_check()` y `calc_report()` funcionan SIN argumentos y validan contra LO PEDIDO. Se persisten con el proyec","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_stackup","description":"Declara una CADENA DE COTAS 1D con nombre (metadato del proyecto, se persiste; lista de eslabones vacía → la borra). Cada eslabón es UNO de: - {nombre, nominal_mm, sentido:±1, tol} — cota literal; nominal_mm acepta '=expr' (sigue a las variables → la cadena se re-verifica al cambiarlas). - {id, eje:x|y|z, sentido:±1, tol?} — mide el BBOX VIVO de esa pieza (auto-actualiza). `tol` es UNA fuente: {\"p","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_variable","description":"Define o actualiza una variable de proyecto (p. ej. L = 2000). Cambiarla regenera todo lo que la usa.","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_vertical","description":"Define el vertical del proyecto ('metalmecanica' | 'carpinteria'), que fija el material por defecto de las piezas a-medida NO reconocidas (acero | madera).","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_visibility","description":"Muestra u oculta un sólido individual (útil para aislar antes de render_view).","write_action":false,"price_micros":0,"input_schema":null},{"name":"set_visibility_bulk","description":"Muestra u oculta varios sólidos a la vez (patrón aislar / mostrar todo).","write_action":false,"price_micros":0,"input_schema":null},{"name":"test_script","description":"Prueba en seco un script build123d en el sandbox: devuelve {ok, volumen_mm3, bbox} o {ok:false, error} SIN tocar el documento. Itera la geometría sin crear/deshacer sólidos.","write_action":false,"price_micros":0,"input_schema":null},{"name":"test_sketch","description":"Prueba en seco un croquis: lo resuelve con el solver (PlaneGCS) y devuelve {ok, residual, diagnostico, dof, redundantes, conflictivas, ...} SIN crear geometría. dof = grados de libertad restantes (0 = totalmente restringido); redundantes/ conflictivas identifican las restricciones culpables por nombre. Soporta tangent/ symmetric/equal_radius/concentric/midpoint/distance_point_line además de los ti","write_action":false,"price_micros":0,"input_schema":null},{"name":"undo","description":"Deshace la última operación.","write_action":false,"price_micros":0,"input_schema":null},{"name":"verify","description":"Verifica en UNA llamada un lote de ASERCIONES numéricas sobre el modelo (READ-ONLY) — declara tus INVARIANTES y compruébalas de golpe en vez de encadenar N measure + aritmética mental. Devuelve {ok, resultados:[{check, ok, actual, esperado}]}. Cada aserción es un dict con `tipo` (y un `nombre` opcional para etiquetarla): - {tipo:\"distancia\", a, b, min?|max?|entre?:[lo,hi]} — gap OCCT entre dos sól","write_action":false,"price_micros":0,"input_schema":null}],"scan":{"score":80,"grade":"B","scanned_at":"2026-09-23T21:41:46.306Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-23T21:41:46.314Z","components":{"code":{"score":20,"max":25,"notes":["156 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":12,"max":15,"notes":["local package, no credentials required"]},"maintenance":{"score":12,"max":15,"notes":["last push 46 days ago"]},"identity":{"score":8,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[{"id":"exec.eval","severity":"medium","component":"code","title":"eval / new Function used","evidence":"apolo_cad-0.1.0/apolo/library/loader.py: … ns[\"math\"] = math return float(eval(expr, {\"__builtins__\": {}}, ns)) def _…"}],"inputs":{"packages":[{"registryType":"pypi","identifier":"apolo-cad","version":"0.1.0","found":true,"license":"MIT","dependencyCount":21,"publishedAt":"2026-08-08T22:56:40.753133Z","repositoryUrl":"https://github.com/mariorojasmz/apolo-cad"}],"repo":{"found":true,"owner":"mariorojasmz","repo":"apolo-cad","archived":false,"pushedAt":"2026-08-08T23:28:31Z","stars":2,"forks":2,"openIssues":0,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/28989883?v=4","ownerCreatedAt":"2017-05-26T21:26:15Z","license":"MIT"},"icon":{"url":null,"source":"none"},"presence":{"stars":2,"forks":2,"downloadsWeek":null,"license":"MIT","lastPushAt":"2026-08-08T23:28:31.000Z","score":18}}}},"grade_history":[],"reviews":[]}