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.pyy una superficie MCP pormcp_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_, contratoRESULTADO: 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 agenteREADME.md: guía del repositorio y estado actual de desarrollodocs/DESARROLLO_REPO.md: guía para continuar el repositorio por capacidades BIM, no por acumulación de scriptsdocs/CAPACIDADES_BIM.md: matriz corta de capacidades cubiertas, parciales, ausentes y prioridades activasdocs/SCRIPTS_BASE.md: núcleo operativo del repositorio y reglas para tocar scripts basehints.md: libreta operativa corta y corregibleCONTRIBUTING.md: criterio de aceptación de PRs y convenciones de scriptsLICENSE/NOTICE/AUTHORS: licencia Apache-2.0 y créditosrevit_cli.py: entrypoint shell-first para buscar y correr scriptsrevit_client.py: cliente WebSocket mínimo para ejecutar Python rawplugin/: 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:
- leer
docs/INICIO_BIM.md - leer
hints.md - correr
python revit_cli.py doctor - ir a
README.mdsolo si hace falta contexto del repositorio o decisiones de arquitectura - 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.ps1exige contexto mínimo de65536;qwen3-coder-30b-q4ygemma4-26b-a4b-q4kmquedan configurados para ese objetivo en los launchers locales.
Reglas del launcher:
- vive en
CLI_Revit, no depende deproj-agent-local - resuelve los GGUF en
C:\Users\fmg\local_models - resuelve
llama-server.exeenC:\Users\fmg\local_models\llama.cpp\llama-server.exe - si hace falta, permite override por
PROJ_AGENT_MODEL_PATH,PROJ_AGENT_LLAMA_SERVER_EXEo.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 reutilizarevit_cli.pyyrevit_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:
- tener Revit abierto con el plugin
RevitAgentlevantado - abrir este repositorio desde Claude Code
- aprobar el servidor
revit-agentcuando Claude detecte.mcp.json - usar herramientas MCP como
search_scripts,show_scriptyrun_script
Notas cortas:
- el catálogo completo de
scripts/queda oculto detrás desearch_scripts,show_scriptyrun_script - las tools MCP aceptan
timeoutymax_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_scriptejecuta 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 Revitrevit_cli.py: buscador/runner mínimo para reutilizar scripts existentesdocs/DESARROLLO_REPO.md: criterio de roadmap y foco del repositoriodocs/CAPACIDADES_BIM.md: matriz accionable de capacidades BIM y prioridadesdocs/SCRIPTS_BASE.md: lista de scripts base y criterio de cuidado del núcleoplugin/: código fuente, build e instalación del plugin local de Revithints.md: libreta operativa corta y corregible.revit_cli/: estado local mínimo entre sesiones (last_run.json+history.jsonl)scripts/consulta: lecturas del modeloscripts/creacion: acciones de modeladoscripts/modificacion: ajustes sobre elementos existentes, tags y cambios de documentación en vistasscripts/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 persistentecrear_*: crea elementos nuevos en el modelomodificar_*o verbo de cambio (mover_*,aplicar_*,etiquetar_*,reubicar_*): muta elementos o vistas existentesexportar_*: 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.pypuede aprovecharRevitEditScopeHelpersdel assembly del plugin- el detalle de requisitos (
dotnet,net48,PYTHONNET_PYDLL, Addins por versión) vive enplugin/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.Documentuidoc:Autodesk.Revit.UI.UIDocumentapp: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>, usarList[T]de .NET, nolistde Python FamilySymbol.Activate()debe ocurrir dentro de unaTransactionToElements()conviene envolverlo conlist()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 autopor 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|ERRORoRESULTADO=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.pyprepare-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 doctorvalida conexion, metadata minima y smoke tests de busquedarundeja 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/modificacionyscripts/reportes hints.mdya cumple el rol de memoria operativa corta- la nueva separacion documental deja un punto de entrada BIM (
docs/INICIO_BIM.md) y esteREADMEcomo 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.jsony.revit_cli/history.jsonlpara rastro local minimo de ejecucioneshints.mdpara reglas cortas de alto valorREADME.mdpara 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