CLI_Revit

Harness MCP eficiente en tokens para automatización de Revit/BIM: búsqueda y ejecución de más de 160 scripts en lugar de exponer herramientas individualmente.

Documentación

CLI Revit / Sin Tool

Repositorio mínimo para operar Revit con la menor intermediación posible entre el LLM y la API.

Qué es este repositorio

CLI_Revit es un harness local de automatización para Revit.

Más concreto:

  • conecta un agente o LLM con un modelo abierto en Revit
  • permite descubrir, parametrizar y ejecutar scripts BIM reutilizables
  • expone una superficie shell-first por revit_cli.py y una superficie MCP por mcp_server.py
  • mantiene una capa mínima de intermediación entre el agente y la API de Revit

No es solo un plugin, ni solo una librería, ni solo un servidor MCP. El MCP es una interfaz de acceso más; el núcleo del repositorio es el harness de ejecución y automatización sobre Revit.

Quickstart

Requisitos mínimos:

  • Revit 2023/2024/2025 instalado (para RevitAPI.dll/RevitAPIUI.dll)
  • .NET SDK o Visual Studio 2022/Build Tools + .NET Framework 4.8 targeting pack
  • Python 3.8+ x64
  • pip install websocket-client mcp

Pasos:

# 1. compilar e instalar el plugin de Revit (detecta version instalada)
cd plugin
build_all_versions.bat
cd ..

# 2. abrir Revit con un documento activo
#    el plugin RevitAgent levanta el servidor WebSocket solo, en ws://localhost:18789

# 3. verificar conexion
python revit_cli.py doctor
python revit_cli.py ping

# 4. primer comando real
python revit_cli.py search "muros"
python revit_cli.py show get_elementos
python revit_cli.py run get_resumen_modelo --params-json "{\"detalle\":\"minimo\"}"

Si ping responde DOWN: Revit no está abierto, el .addin no quedó instalado, o falta configurar PYTHONNET_PYDLL — detalle completo en plugin/README.md.

Para usarlo desde un agente en vez de la shell (Claude Code, OpenCode, o cualquier cliente MCP): el repositorio ya trae .mcp.json y mcp_server.py listos, ver sección "Uso desde Claude Code" más abajo.

Harness vertical, no genérico

Mismo patrón que un harness genérico (Claude Code, OpenCode, dsh): loop de agente + intermediación mínima entre decisión y ejecución + feedback estructurado para verificar. La diferencia es el alcance:

  • un harness genérico decide su dominio por prompt/contexto
  • este harness tiene el dominio hardcodeado en el protocolo: catálogo de scripts, convención get_/crear_/modificar_, contrato RESULTADO: OK|WARN|ERROR

Por eso se expone vía MCP y no como plugin nativo de cada harness general: el harness vertical se mantiene una sola vez en este repositorio, y cualquier harness general lo consume como cliente MCP sin reescritura.

Mapa rápido

  • docs/INICIO_BIM.md: puerta de entrada para una sesión de modelado BIM del agente
  • README.md: guía del repositorio y estado actual de desarrollo
  • docs/DESARROLLO_REPO.md: guía para continuar el repositorio por capacidades BIM, no por acumulación de scripts
  • docs/CAPACIDADES_BIM.md: matriz corta de capacidades cubiertas, parciales, ausentes y prioridades activas
  • docs/SCRIPTS_BASE.md: núcleo operativo del repositorio y reglas para tocar scripts base
  • hints.md: libreta operativa corta y corregible
  • CONTRIBUTING.md: criterio de aceptación de PRs y convenciones de scripts
  • LICENSE / NOTICE / AUTHORS: licencia Apache-2.0 y créditos
  • revit_cli.py: entrypoint shell-first para buscar y correr scripts
  • revit_client.py: cliente WebSocket mínimo para ejecutar Python raw
  • plugin/: add-in C# local de Revit (RevitAgentPlugin) para compilar e instalar el servidor WebSocket

Criterio de diseño

La regla central de este repositorio es simple:

  • cada tarea BIM debe consumir la menor cantidad de tokens posible para llegar a una respuesta buena
  • los tokens deben ir a leer estado real del modelo, decidir y verificar
  • no deben ir a contexto inflado, routing local, wrappers redundantes o documentación larga

En la práctica eso significa:

  • cliente a Revit chico y obvio
  • scripts explícitos y reutilizables
  • hints cortos en vez de una capa de tools
  • pocas piezas base, no catálogos grandes de variantes

Fórmula de trabajo:

leer poco -> decidir bien -> mutar chico -> verificar -> guardar solo la regla util

Guía de uso

En una sesión nueva:

  1. leer docs/INICIO_BIM.md
  2. leer hints.md
  3. correr python revit_cli.py doctor
  4. ir a README.md solo si hace falta contexto del repositorio o decisiones de arquitectura
  5. hacer una lectura mínima real del modelo antes de mutar

Reglas de trabajo:

  • si ya existe un script útil, buscarlo y correrlo con PARAMS
  • si el pedido es una variante chica, ajustar el script existente antes de crear otro
  • crear un script nuevo solo cuando abre una capacidad reutilizable de verdad
  • no guardar un script nuevo para una decisión puntual de modelado
  • si el pedido admite varias soluciones BIM razonables y el criterio no está dicho, consultar antes de fijar una variante permanente

Uso rápido

La idea de revit_cli.py no es reemplazar al LLM sino evitar que tenga que reescribir Python completo para cada consulta.

Ejemplos:

python revit_cli.py doctor
python revit_cli.py ping
python revit_cli.py search "resumen del modelo"
python revit_cli.py show get_elementos
python revit_cli.py run get_resumen_modelo --params-json "{\"detalle\":\"minimo\"}"
python revit_cli.py run crear_muros --params-json "{\"segmentos_m\":[[[0,0],[5,0]]],\"nivel_inicial\":\"Nivel 1\",\"altura_default_m\":3.0}"

Launcher local único para Codex

Si vas a usar Codex con modelo local desde este repositorio, el entrypoint pasa a ser:

.\codex-local.ps1 -Model qwen
.\codex-local.ps1 -Model gemma

Launchers equivalentes para otros CLIs locales:

.\hermes-local.ps1 -Model qwen
.\opencode-local.ps1 -Model qwen

Nota:

  • hermes-local.ps1 exige contexto mínimo de 65536; qwen3-coder-30b-q4 y gemma4-26b-a4b-q4km quedan configurados para ese objetivo en los launchers locales.

Reglas del launcher:

  • vive en CLI_Revit, no depende de proj-agent-local
  • resuelve los GGUF en C:\Users\fmg\local_models
  • resuelve llama-server.exe en C:\Users\fmg\local_models\llama.cpp\llama-server.exe
  • si hace falta, permite override por PROJ_AGENT_MODEL_PATH, PROJ_AGENT_LLAMA_SERVER_EXE o .codex/local-model-paths.json

Para elegir un perfil exacto sin usar alias:

.\codex-local.ps1 -Profile qwen3-coder-30b-q4
.\codex-local.ps1 -Profile gemma4-26b-a4b-q4km

Uso desde Claude Code

Ahora el repositorio también incluye un servidor MCP local para que Claude pueda usar los scripts existentes sin salir del flujo normal del proyecto.

Archivos:

  • mcp_server.py: servidor MCP sobre stdio que reutiliza revit_cli.py y revit_client.py
  • .mcp.json: configuración de proyecto para Claude Code
  • .claude/settings.json: permisos preaprobados solo para herramientas seguras de descubrimiento y consulta

Flujo mínimo:

  1. tener Revit abierto con el plugin RevitAgent levantado
  2. abrir este repositorio desde Claude Code
  3. aprobar el servidor revit-agent cuando Claude detecte .mcp.json
  4. usar herramientas MCP como search_scripts, show_script y run_script

Notas cortas:

  • el catálogo completo de scripts/ queda oculto detrás de search_scripts, show_script y run_script
  • las tools MCP aceptan timeout y max_output_bytes; si una salida supera el límite, el plugin devuelve preview y guarda la salida completa en .revit_cli/artifacts
  • el plugin acepta requests paralelas desde CLI/MCP/WebSocket, pero las ejecuta en cola FIFO dentro del hilo principal de Revit
  • el server carga el catálogo al iniciar; si agregas scripts nuevos, reinicia Claude o vuelve a cargar el servidor
  • los tools de mutación no quedaron preautorizados en .claude/settings.json; la idea es mantener permisos conservadores sobre el modelo
  • run_script ejecuta cualquier script por nombre o ruta relativa sin inflar el catálogo visible de tools

Flujo operativo

Arquitectura mínima:

LLM / cliente
    -> revit_cli.py o revit_client.py
    -> ws://localhost:18789
    -> plugin RevitAgent (C# + Python.NET)
    -> Autodesk.Revit.DB

revit_cli.py es la puerta de entrada normal.

revit_client.py sirve para ejecutar Python raw cuando hace falta control total o para prototipar una pieza nueva antes de volverla script reutilizable.

El transporte WebSocket es compatible con uso concurrente: varios clientes pueden enviar requests a la vez. Revit sigue siendo single-threaded, por lo que el plugin las encola en FIFO y las ejecuta secuencialmente en ExternalEvent. Las respuestas incluyen diagnostics con tiempos de cola/ejecución y bytes de salida.

Archivos principales

  • revit_client.py: cliente WebSocket mínimo hacia Revit
  • revit_cli.py: buscador/runner mínimo para reutilizar scripts existentes
  • docs/DESARROLLO_REPO.md: criterio de roadmap y foco del repositorio
  • docs/CAPACIDADES_BIM.md: matriz accionable de capacidades BIM y prioridades
  • docs/SCRIPTS_BASE.md: lista de scripts base y criterio de cuidado del núcleo
  • plugin/: código fuente, build e instalación del plugin local de Revit
  • hints.md: libreta operativa corta y corregible
  • .revit_cli/: estado local mínimo entre sesiones (last_run.json + history.jsonl)
  • scripts/consulta: lecturas del modelo
  • scripts/creacion: acciones de modelado
  • scripts/modificacion: ajustes sobre elementos existentes, tags y cambios de documentación en vistas
  • scripts/reportes: salidas técnicas persistentes y exportaciones

Regla de nombres

El nombre del script debe reflejar su contrato operativo real, no solo la intención de negocio.

  • get_*: lectura del modelo, sin mutación ni artefacto persistente
  • crear_*: crea elementos nuevos en el modelo
  • modificar_* o verbo de cambio (mover_*, aplicar_*, etiquetar_*, reubicar_*): muta elementos o vistas existentes
  • exportar_*: genera salida externa persistente (PDF, imagen, etc.)
  • generar_reporte_* / generar_memoria_*: genera documento técnico persistente

Si un script mezcla dos contratos, debe partirse o quedar claramente sesgado hacia uno y exponer alias de compatibilidad.

Plugin local

Este repositorio ya incluye el plugin necesario para que el runtime sea autosuficiente:

  • código fuente en plugin/
  • proyecto .NET en plugin/RevitAgentPlugin.csproj
  • build local en plugin/build.bat
  • build multi-version en plugin/build_all_versions.bat
  • documentación operativa en plugin/README.md

Flujo mínimo:

cd plugin
build_all_versions.bat

Si solo necesitas una instalación puntual y build.bat detecta bien tu versión de Revit:

cd plugin
build.bat

Notas cortas:

  • el plugin instala el servidor en ws://localhost:18789
  • editar_boceto_muro.py puede aprovechar RevitEditScopeHelpers del assembly del plugin
  • el detalle de requisitos (dotnet, net48, PYTHONNET_PYDLL, Addins por versión) vive en plugin/README.md

Protocolo raw

Request:

{
  "action": "execute",
  "script": "codigo python aqui",
  "timeout_s": 60,
  "request_id": "opcional",
  "max_output_bytes": 262144,
  "artifact_dir": "C:\\Users\\fmg\\Desktop\\CLI_Revit\\.revit_cli\\artifacts"
}

timeout_s, request_id, max_output_bytes y artifact_dir son opcionales. max_output_bytes usa 256 KB por defecto; si se supera, result/traceback contiene una preview y la salida completa queda como artefacto local.

Response OK:

{
  "status": "ok",
  "request_id": "opcional",
  "result": "stdout capturado o OK",
  "artifacts": [],
  "diagnostics": {
    "elapsed_ms": 12,
    "queue_wait_ms": 2,
    "execution_ms": 5,
    "output_truncated": false
  }
}

Response Error:

{ "status": "error", "error": "mensaje", "traceback": "stacktrace" }

Variables disponibles en cada script:

  • doc: Autodesk.Revit.DB.Document
  • uidoc: Autodesk.Revit.UI.UIDocument
  • app: Autodesk.Revit.ApplicationServices.Application

Reglas del entorno

  • devolver resultados con print(), no por última expresión
  • no usar with Transaction(...); abrir y cerrar la transacción manualmente
  • Revit trabaja en pies decimales; convertir unidades de forma explícita
  • si una API pide IList<T>, usar List[T] de .NET, no list de Python
  • FamilySymbol.Activate() debe ocurrir dentro de una Transaction
  • ToElements() conviene envolverlo con list() antes de usar slicing

Contrato de salida mínima

Para no inflar contexto, la salida de los scripts debe pensarse para decisión operativa, no para narración.

  • python revit_cli.py run ... ahora usa --output-mode auto por default: si detecta *_JSON= o stdout largo, compacta la respuesta.
  • si necesitas ver todo el stdout, usar python revit_cli.py run ... --output-mode raw
  • emitir siempre una línea de estado corta: RESULTADO: OK|WARN|ERROR o RESULTADO=ok
  • emitir métricas clave en mayúsculas: TOTAL_VISTAS, COUNT_FILTRADAS, ELEMENT_IDS, etc.
  • si hace falta detalle estructurado, emitirlo en una sola línea NOMBRE_JSON=...
  • limitar detalle humano con max_detalle; el detalle completo debe quedar opt-in, no por defecto

Regla práctica:

1 linea de estado
+ 3 a 8 metricas utiles
+ 0 o mas payloads *_JSON compactables
+ tablas o detalle solo si cambian una decision

Patrón de transacción:

from Autodesk.Revit.DB import Transaction

txn = Transaction(doc, "Operacion")
txn.Start()
try:
    # cambios
    txn.Commit()
except Exception:
    txn.RollBack()
    raise

Conversiones

  • metros -> pies: valor_m * 3.28084
  • pies -> metros: valor_ft * 0.3048

Verificar conexión

from revit_client import ping
print("Conectado:", ping())

Qué no queremos reconstruir

  • tool_catalog.py
  • prepare-request
  • routing interno
  • RAG o memoria automática compleja
  • un agente de preferencia
  • documentación grande difícil de corregir

Estado del repositorio

Estado actual:

  • el flujo shell-first ya existe y funciona desde revit_cli.py
  • doctor valida conexion, metadata minima y smoke tests de busqueda
  • run deja un rastro local chico en .revit_cli/ para retomar entre sesiones sin inflar el repo
  • el plugin de Revit ya vive dentro de este repo y puede compilarse desde plugin/
  • hay una base amplia de scripts reutilizables en scripts/consulta, scripts/creacion, scripts/modificacion y scripts/reportes
  • hints.md ya cumple el rol de memoria operativa corta
  • la nueva separacion documental deja un punto de entrada BIM (docs/INICIO_BIM.md) y este README como guia viva del repo

Pendiente o criterio vigente:

  • seguir consolidando scripts base en lugar de sumar variantes pequenas
  • verificar en uso real que los scripts mas frecuentes sigan siendo confiables
  • documentar solo lo que cambie decisiones operativas o de arquitectura
  • mantener este repo chico, legible y facil de corregir

Como guardar aprendizaje

  • .revit_cli/last_run.json y .revit_cli/history.jsonl para rastro local minimo de ejecuciones
  • hints.md para reglas cortas de alto valor
  • README.md para decisiones de arquitectura, guia y estado del repo

Si algo no entra en 1 o 2 bullets, probablemente no es un hint. Si un dato solo sirve para recuperar una corrida reciente, probablemente va a .revit_cli/, no a hints.md.

Cierre

Este repo no busca que el LLM "sepa mucho" antes de actuar.

Busca que pueda:

  • leer solo lo necesario
  • elegir una plantilla simple
  • ejecutar contra el modelo real
  • verificar
  • y seguir con el menor costo de tokens por tarea