Revit MCP Python

Un servidor MCP basado en pyRevit para Autodesk Revit, que permite la conexión con cualquier cliente compatible con MCP.

Documentación

Servidor MCP para Revit - Python

Una implementación orientada a pyRevit del Protocolo de Contexto de Modelo (MCP) para Autodesk Revit

¿Cómo?

  • Esta implementación mínima aprovecha el módulo Routes dentro de pyRevit para crear un puente entre Revit y los Modelos de Lenguaje Grande (LLMs).
  • Proporciona una plantilla sencilla para comenzar rápidamente, permitiéndote prototipar e iterar herramientas para dar a los LLMs acceso a tus modelos de Revit.
  • Estas herramientas están diseñadas para ampliarse según tus casos de uso específicos. Eres bienvenido a hacer un fork del repositorio y realizar tus propias contribuciones.
  • Nota: La API de Routes de pyRevit está actualmente en forma de borrador y sujeta a cambios. Carece de mecanismos de autenticación integrados, por lo que deberás implementar tus propias medidas de seguridad para uso en producción.

Baterías Incluidas

Este repositorio está dirigido a:

  • Principiantes en la API de Revit
  • Especialistas en Python que no dominan C#
  • Cualquier persona que quiera prototipar e iterar rápidamente con LLMs y Revit

Contiene:

  • Una implementación completa de Routes para pyRevit
  • Un script mínimo de servidor MCP para conectarse a cualquier cliente compatible con MCP
  • Varios comandos de prueba para que empieces de inmediato

Componentes Clave de la Arquitectura

El sistema se ejecuta como dos servidores separados que trabajan juntos en cadena:

Claude / LLM Client
       |
       |  MCP Protocol (stdio or HTTP)
       v
  main.py  (MCP Server)
       |
       |  HTTP requests (localhost:48884)
       v
  pyRevit Routes  (REST API running inside Revit)
       |
       |  Revit API calls
       v
  Revit Application

main.py es el servidor MCP. Habla el protocolo MCP para que Claude (o cualquier cliente compatible con MCP) pueda llamar a las herramientas. Cuando se llama a una herramienta, main.py la traduce a una solicitud HTTP y la reenvía a Revit.

pyRevit Routes es una API REST ligera que se ejecuta dentro del proceso de Revit. Recibe esas solicitudes HTTP, ejecuta código de la API de Revit (ya que tiene acceso directo a la instancia en ejecución) y devuelve respuestas JSON.

Nunca entran en conflicto porque cumplen roles diferentes, hablan protocolos distintos y escuchan en puertos diferentes.

Nota: Las herramientas de Inicio y Documento (launch_revit, list_revit_installations) son la excepción: se ejecutan completamente en el lado del MCP, usando subprocess para iniciar Revit y luego consultando el endpoint de salud de pyRevit Routes hasta que el puente esté listo.

  1. Servidor MCP (main.py):
  • Construido con FastMCP
  • Maneja la comunicación HTTP con la API de Revit Routes
  • Registra herramientas desde un sistema modular de herramientas
  • Proporciona funciones auxiliares para solicitudes GET/POST/Imagen
  1. Extensión pyRevit (revit-mcp-python.extension/):
  • Contiene la API de Routes que se ejecuta dentro de Revit
  • Registro modular de rutas en startup.py
  • Módulos de rutas individuales en el directorio revit_mcp/
  1. Sistema de Registro de Herramientas (tools/):
  • Organización modular de herramientas por funcionalidad
  • Registro central a través de tools/__init__.py
  • Cada módulo registra sus propias herramientas con el servidor MCP

Herramientas Soportadas

Estado Actual de Implementación

Nombre de la HerramientaEstadoCategoríaDescripción
get_revit_status✅ ImplementadoEstado y ConectividadVerificar si la API de Revit-MCP está activa y respondiendo
get_revit_model_info✅ ImplementadoInformación del ModeloObtener información completa sobre el modelo de Revit actual
list_levels✅ ImplementadoInformación del ModeloObtener todos los niveles con información de elevación
get_revit_view✅ ImplementadoVista e ImagenExportar una vista específica de Revit como imagen
list_revit_views✅ ImplementadoVista e ImagenObtener una lista de todas las vistas exportables organizadas por tipo
place_family✅ ImplementadoFamilia y ColocaciónColocar una instancia de familia en una ubicación especificada con propiedades personalizadas
list_families✅ ImplementadoFamilia y ColocaciónObtener una lista plana de tipos de familia disponibles (con filtrado)
list_family_categories✅ ImplementadoFamilia y ColocaciónObtener una lista de todas las categorías de familia en el modelo
get_current_view_info✅ ImplementadoInformación de VistaObtener información detallada sobre la vista actualmente activa
get_current_view_elements✅ ImplementadoInformación de VistaObtener todos los elementos visibles en la vista actual
create_point_based_element✅ ImplementadoCreación de ElementosCrear elementos basados en puntos (puertas, ventanas, mobiliario)
color_splash✅ ImplementadoVisualizaciónColorear elementos según valores de parámetros
execute_revit_code✅ ImplementadoEjecución de CódigoEjecutar código IronPython directamente en el contexto de Revit
list_revit_installations✅ ImplementadoInicio y DocumentoDescubrir todas las versiones de Revit instaladas en el sistema
launch_revit✅ ImplementadoInicio y DocumentoIniciar Revit, opcionalmente con un archivo, y consultar hasta que esté listo
open_document✅ ImplementadoInicio y DocumentoAbrir un documento en Revit en ejecución (admite desacoplar y auditar)
close_document✅ ImplementadoInicio y DocumentoCerrar el documento activo
save_document✅ ImplementadoInicio y DocumentoGuardar o Guardar Como el documento activo
sync_with_central✅ ImplementadoInicio y DocumentoSincronizar un documento compartido con el central
get_selected_elements🔄 PendienteGestión de SelecciónObtener información sobre los elementos actualmente seleccionados
create_line_based_element🔄 PendienteCreación de ElementosCrear elementos basados en líneas (muros, vigas, tuberías)
create_surface_based_element🔄 PendienteCreación de ElementosCrear elementos basados en superficies (pisos, techos)
delete_elements🔄 PendienteGestión de ElementosEliminar elementos especificados del modelo
modify_element🔄 PendienteGestión de ElementosModificar propiedades de elementos (parámetros de instancia)
reset_model🔄 PendienteGestión de ElementosRestablecer el modelo eliminando elementos del modelo de proceso
tag_walls🔄 PendienteAnotaciónEtiquetar todos los muros en la vista actual
search_modules🔄 PendienteIntegraciónBuscar módulos/complementos disponibles
use_module🔄 PendienteIntegraciónEjecutar funcionalidad de módulos externos

Claude listing model elements in the Desktop interface

Claude getting a view in the Desktop interface

Comenzando

Instalando uv:

Consulta ./README_UV.md

Instalando la Extensión en Revit

Activar pyRevit Routes

  1. En Revit, navega a la pestaña pyRevit
  2. Abre Configuración
  3. Ve a Routes > activa Routes Server pyRevit comenzará a escuchar en el puerto http://localhost:48884/

Instalar desde pyRevit:

  1. En Revit, navega a la pestaña pyRevit
  2. Abre Extensiones
  3. Selecciona la Extensión MCP Server for Revit Python > Instalar extensión
  4. Selecciona la ubicación, el valor predeterminado es %APPDATA%\Roaming\pyRevit\Extensions
  5. Habilita y espera a que pyRevit se recargue. Reinicia Revit si es necesario.

Instalación Manual en un directorio personalizado:

  1. Clona el repositorio en una ubicación personalizada:
    git clone https://github.com/mcp-servers-for-revit/mcp-server-for-revit-python
    
  2. Agrega .extension al nombre de la carpeta raíz
  3. En Revit, navega a la pestaña pyRevit
  4. Abre Configuración
  5. En "Extensiones personalizadas", agrega la ruta a la carpeta .extension
  6. Guarda la configuración y recarga pyRevit (puede que necesites reiniciar Revit por completo)

Probando tu Conexión

Una vez instalado, prueba que la API de Routes esté funcionando:

  1. Abre tu navegador web y ve a:

    http://localhost:48884/revit_mcp/status/
    
  2. Si tiene éxito, deberías ver una respuesta como:

    {"status": "active",
     "health": "healthy",
     "revit_available": true,
     "document_title": "your_revit_filename",
     "api_name": "revit_mcp"}
    

El Servicio de Routes se cargará automáticamente cada vez que inicies Revit. Para deshabilitarlo, simplemente elimina la ruta de la extensión de la configuración de pyRevit.

Usando el Cliente MCP

Probando con el Inspector MCP

El SDK de MCP incluye una práctica herramienta de inspección para depuración:

mcp dev main.py

Luego accede a http://127.0.0.1:6274 en tu navegador para probar tu servidor MCP de forma interactiva.

Modos de Transporte

El servidor MCP admite múltiples modos de transporte para diferentes casos de uso:

BanderaTransporteEndpointsCaso de Uso
(ninguna)stdiostdin/stdoutPredeterminado de Claude Desktop / Claude Code
--sseSolo SSE/sse, /messages/Clientes heredados
--streamable-httpSolo HTTP/mcpClientes HTTP modernos
--combinedAmbosTodos los anterioresMáxima compatibilidad

Ejecutando con transporte combinado (recomendado para HTTP):

uv run --with "mcp[cli]" main.py --combined

Esto inicia el servidor en http://127.0.0.1:8000 con endpoints SSE y HTTP transmisible disponibles.

Probando los endpoints:

# Test streamable-http
curl -X POST http://localhost:8000/mcp

# Test SSE
curl http://localhost:8000/sse

Conectando a Claude Desktop

La forma más sencilla de instalar tu servidor MCP en Claude Desktop:

mcp install main.py

O para instalación manual:

  1. Abre Claude Desktop → Configuración → Desarrollador → Editar Config
  2. Agrega esto a la sección mcpServers:
{
  "mcpServers": {
    "Revit Connector": {
      "command": "uv",
      "args": [
        "run",
        "--with",
        "mcp[cli]",
        "mcp",
        "run",
        "/absolute/path/to/main.py"
      ]
    }
  }
}

Para el modo de transporte HTTP, configura Claude Desktop con:

{
  "mcpServers": {
    "Revit Connector": {
      "url": "http://localhost:8000/mcp"
    }
  }
}

Conectando a Claude Code

claude mcp add -s user "Revit-Connector" -- uv run --with "mcp[cli]" mcp run /absolute/path/to/main.py

Creando Tus Propias Herramientas

La arquitectura modular de este proyecto hace que agregar funcionalidades sea relativamente simple. El archivo LLM.txt proporcionado también le da a tu modelo de lenguaje el contexto necesario para comenzar de inmediato.

El proceso involucra tres partes principales:

Parte 1: Crear el Módulo de Ruta en Revit

Crea un nuevo archivo Python dentro del directorio revit-mcp-python.extension/revit_mcp/ (por ejemplo, revit_mcp/your_module.py). Este módulo contendrá todas las funciones relacionadas que deseas exponer.

# In revit-mcp-python.extension/revit_mcp/your_module.py

# -*- coding: UTF-8 -*-
"""
Your Module for Revit MCP
Handles your specific functionality.
"""
from pyrevit import routes, revit, DB
import json
import logging

# Standard logger setup
logger = logging.getLogger(__name__)

def register_your_routes(api):
    """Register all your routes with the API."""

    # ---- Example 1: A GET request for reading data ----
    @api.route('/your_endpoint/', methods=["GET"])
    def get_project_title(doc):
        """Gets the project title from the Revit model."""
        try:
            value = doc.Title
            return routes.make_response(data={"status": "success", "data": value})
        except Exception as e:
            logger.error("Get project title failed: {}".format(str(e)))
            return routes.make_response(data={"error": str(e)}, status=500)

    # ---- Example 2: A POST request for modifying the model ----
    @api.route('/modify_model/', methods=["POST"])
    def modify_model(doc, request):
        """Handles POST requests for modifying the Revit model."""
        try:
            data = json.loads(request.data) if isinstance(request.data, str) else request.data

            # Use a transaction for all model modifications
            t = DB.Transaction(doc, "Modify Model via MCP")
            t.Start()

            try:
                element_id = data.get("element_id")
                new_value = data.get("new_value")
                element = doc.GetElement(DB.ElementId(int(element_id)))
                param = element.LookupParameter("Comments")
                param.Set(new_value)

                t.Commit()
                return routes.make_response(data={"status": "success", "result": "Element modified."})

            except Exception as tx_error:
                if t.HasStarted() and not t.HasEnded():
                    t.RollBack()
                raise tx_error

        except Exception as e:
            logger.error("Modify model failed: {}".format(str(e)))
            return routes.make_response(data={"error": str(e)}, status=500)

    logger.info("Your custom routes were registered successfully.")

Parte 2: Crear el Módulo de Herramientas MCP

Crea las herramientas correspondientes para el servidor MCP en el directorio tools/ (por ejemplo, tools/your_tools.py). Este módulo usará los ayudantes revit_get y revit_post de main.py.

# In tools/your_tools.py
# -*- coding: utf-8 -*-
"""Your tools for the MCP server."""

from mcp.server.fastmcp import Context
from .utils import format_response

def register_your_tools(mcp, revit_get, revit_post, revit_image=None):
    """Register your tools with the MCP server."""

    # ---- Tool for the GET request ----
    @mcp.tool()
    async def get_revit_project_title(ctx: Context) -> str:
        """
        Retrieves the title of the currently open Revit project.
        """
        response = await revit_get("/your_endpoint/", ctx)
        return format_response(response)

    # ---- Tool for the POST request ----
    @mcp.tool()
    async def modify_revit_element_comment(
        element_id: int,
        new_value: str,
        ctx: Context = None
    ) -> str:
        """
        Modifies the 'Comments' parameter of a specific element.

        Args:
            element_id: The ID of the element to modify.
            new_value: The new comment to apply to the element.
        """
        payload = {"element_id": element_id, "new_value": new_value}
        response = await revit_post("/modify_model/", payload, ctx)
        return format_response(response)

Parte 3: Registrar Tus Nuevos Módulos

1. Registrar el Módulo de Ruta

Abre revit-mcp-python.extension/startup.py y agrega tu nueva función de registro de ruta.

# In revit-mcp-python.extension/startup.py

# ... (other imports)
# Import the registration function from your new module
from revit_mcp.your_module import register_your_routes

def register_routes():
    """Register all MCP route modules"""
    api = routes.API('revit_mcp')
    try:
        # ... (existing route registrations)

        # Register your new routes (this registers all functions inside)
        register_your_routes(api)

        logger.info("All MCP routes registered successfully")
    except Exception as e:
        logger.error("Failed to register MCP routes: {}".format(str(e)))
        raise

2. Registrar el Módulo de Herramientas

Abre tools/__init__.py y agrega tu nueva función de registro de herramientas.

# In tools/__init__.py

# ... (other tool imports)
# Import the registration function from your new tool module
from .your_tools import register_your_tools

def register_tools(mcp_server, revit_get_func, revit_post_func, revit_image_func):
    """Register all tools with the MCP server"""

    # ... (existing tool registrations)
    # Register your new tools (this registers all tools inside)
    register_your_tools(mcp_server, revit_get_func, revit_post_func, revit_image_func)

    return mcp_server

Hoja de Ruta

Esto es un trabajo en progreso y más una demostración que un producto completamente funcional. Las mejoras futuras podrían incluir:

  • Crear un Cliente dentro de Revit
  • Implementar compatibilidades con otros modelos de lenguaje
  • Mejoras de autenticación y seguridad
  • Herramientas y capacidades de Revit más avanzadas
  • Mejor manejo de errores y funciones de depuración
  • Evaluación comparativa con modelos locales
  • Documentación y ejemplos para casos de uso comunes
  • ...

Contribuciones

¡Las contribuciones son bienvenidas! No dudes en enviar solicitudes de extracción o abrir problemas para cualquier error o solicitud de función. No dudes en contactarme si tienes preguntas o ideas.