MCP server for Revit - Python
Provides tools for interacting with Autodesk Revit via pyRevit Routes, enabling agents to query model data, list levels/views/families, place families, export views as images, execute Revit Python code, manage documents, launch Revit, and perform visualization operations.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP server for Revit - Python list all levels in the current Revit model with their elevations"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP server for Revit - Python
A pyRevit-oriented implementation of the Model Context Protocol (MCP) for Autodesk Revit
Related MCP server: Revit MCP Server
Local pairing and Autodesk Marketplace publication
This project is being prepared for Autodesk Marketplace review; it is not yet certified. The review candidate retains all 20 tools, including Python execution. See publication requirements and outstanding gates, privacy information, and security boundaries.
After installing the pyRevit extension, choose MCP > Bridge > Connect in Revit to consent and create an encrypted pairing secret for your Windows user. Choose Disconnect to revoke it. Requests that change models and Python execution show their payload for review in Revit before proceeding. Pairing also permits local Revit discovery and launch. Pairing is shared across Revit instances for the same Windows user; select the correct Routes port before connecting.
The MCP-to-Revit bridge accepts only loopback hosts. Remote VM/LAN HTTP bridges are
rejected. Optional HTTP MCP transports require a paired bearer header; stdio is
the recommended publication transport and needs no token in client configuration.
Do not expose either listener to a network, tunnel or the internet.
How?
This minimal implementation leverages the Routes module inside pyRevit to create a bridge between Revit and Large Language Models (LLMs).
It provides a straightforward template to get started quickly, letting you prototype and iterate tools to give LLMs access to your Revit models.
These tools are designed to be expanded for your specific use cases. You're very welcome to fork the repo and make your own contributions.
Note: The pyRevit Routes API is currently in draft form and subject to change. This extension authenticates its own routes using Windows-user pairing. Other pyRevit routes/extensions remain outside this protection; review pyRevit server binding and the security document.
Batteries Included
This repo is aimed at:
Beginners to the Revit API
Python specialists who aren't versed in C#
Anyone wanting to prototype and iterate quickly with LLMs and Revit
It contains:
A complete Routes implementation for pyRevit
A minimal MCP server script to connect to any MCP-compatible client
Several test commands to get you started right away
Key Architecture Components
The system runs as two separate servers working together in a chain:
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 Applicationmain.py is the MCP server. It speaks the MCP protocol so that Claude (or any MCP-compatible client) can call tools. When a tool is called, main.py translates it into an HTTP request and forwards it to Revit.
pyRevit Routes is a lightweight REST API that runs inside the Revit process. It receives those HTTP requests, executes Revit API code (since it has direct access to the running instance), and returns JSON responses.
They never conflict because they serve different roles, speak different protocols, and listen on different ports.
Note: The Launch & Document tools (
launch_revit,list_revit_installations) are the exception — they run entirely on the MCP side, usingsubprocessto start Revit and then polling the pyRevit Routes health endpoint until the bridge is ready.
MCP Server (
main.py):
Built with FastMCP
Handles HTTP communication with Revit Routes API
Registers tools from modular tool system
Provides helper functions for GET/POST/Image requests
pyRevit Extension (
revit-mcp-python.extension/):
Contains the Routes API that runs inside Revit
Modular route registration in
startup.pyIndividual route modules in
revit_mcp/directory
Tool Registration System (
tools/):
Modular tool organization by functionality
Central registration through
tools/__init__.pyEach module registers its own tools with the MCP server
Supported Tools
Current Implementation Status
Tool Name | Status | Category | Description |
| ✅ Implemented | Status & Connectivity | Check if the Revit-MCP API is active and responding |
| ✅ Implemented | Model Information | Get comprehensive information about the current Revit model |
| ✅ Implemented | Model Information | Get all levels with elevation information |
| ✅ Implemented | View & Image | Export a specific Revit view as an image |
| ✅ Implemented | View & Image | Get a list of all exportable views organized by type |
| ✅ Implemented | Family & Placement | Place a family instance at specified location with custom properties |
| ✅ Implemented | Family & Placement | Get a flat list of available family types (with filtering) |
| ✅ Implemented | Family & Placement | Get a list of all family categories in the model |
| ✅ Implemented | View Information | Get detailed information about the currently active view |
| ✅ Implemented | View Information | Get all elements visible in the current view |
| 🔄 Pending | Element Creation | Create point-based elements (doors, windows, furniture) |
| ✅ Implemented | Visualization | Color elements based on parameter values |
| ✅ Implemented | Visualization | Remove view color overrides |
| ✅ Implemented | Visualization | List category parameters and sample values |
| ✅ Implemented | Code Execution | Execute IronPython code directly in Revit context |
| ✅ Implemented | Launch & Document | Discover all Revit versions installed on the system |
| ✅ Implemented | Launch & Document | Launch Revit, optionally with a file, and poll for readiness |
| ✅ Implemented | Launch & Document | Open a document in running Revit (supports detach and audit) |
| ✅ Implemented | Launch & Document | Close the active document |
| ✅ Implemented | Launch & Document | Save or Save As the active document |
| ✅ Implemented | Launch & Document | Synchronize a workshared document with central |
| 🔄 Pending | Selection Management | Get information about currently selected elements |
| 🔄 Pending | Element Creation | Create line-based elements (walls, beams, pipes) |
| 🔄 Pending | Element Creation | Create surface-based elements (floors, ceilings) |
| 🔄 Pending | Element Management | Delete specified elements from the model |
| 🔄 Pending | Element Management | Modify element properties (instance parameters) |
| 🔄 Pending | Element Management | Reset model by deleting process model elements |
| 🔄 Pending | Annotation | Tag all walls in the current view |
| 🔄 Pending | Integration | Search for available modules/addins |
| 🔄 Pending | Integration | Execute functionality from external modules |


Getting Started
Installing uv:
Refer to ./README_UV.md
Installing the Extension on Revit
Activate pyRevit Routes
In Revit, navigate to the pyRevit tab
Open Settings
Go to
Routes> activateRoutes ServerpyRevit will start listening on porthttp://localhost:48884/
Install from pyRevit:
In Revit, navigate to the pyRevit tab
Open Extensions
Select the MCP Server for Revit Python Extension > Install extension
Select location, default is
%APPDATA%\Roaming\pyRevit\ExtensionsEnable and wait for pyRevit to reload. Restart Revit if necessary.
Manual Installation on a custom directory:
Clone the repo in a custom location:
git clone https://github.com/mcp-servers-for-revit/mcp-server-for-revit-pythonAdd
.extensionto the root folder nameIn Revit, navigate to the pyRevit tab
Open Settings
Under "Custom Extensions", add the path to the
.extensionfolderSave settings and reload pyRevit (you might need to restart Revit entirely)
Testing Your Connection
Once installed, test that the Routes API is working:
Choose MCP > Bridge > Connect in Revit, then run this authenticated check from the exact candidate directory (a browser request has no pairing header and is denied):
uv run --frozen python -c "import anyio; from main import revit_get; print(anyio.run(revit_get, '/status/'))"If successful, you should see a response like:
{"status": "active", "health": "healthy", "revit_available": true, "document_title": "your_revit_filename", "api_name": "revit_mcp"}
The Routes Service will now load automatically whenever you start Revit. To disable it, simply remove the extension path from the pyRevit settings.
Using the MCP Client
Testing with the MCP Inspector
The MCP SDK includes a handy inspector tool for debugging:
mcp dev main.pyThen access http://127.0.0.1:6274 in your browser to test your MCP server interactively.
Transport Modes
The MCP server supports multiple transport modes for different use cases:
Flag | Transport | Endpoints | Use Case |
(none) | stdio | stdin/stdout | Claude Desktop / Claude Code default |
| SSE only |
| Legacy clients |
| HTTP only |
| Modern HTTP clients |
| Both | All above | Maximum compatibility |
Running with combined transport (recommended for HTTP):
uv run --frozen main.py --combinedAfter pairing, this starts the authenticated server on http://127.0.0.1:8000 with both SSE and streamable-HTTP endpoints available.
The following unpaired requests return HTTP 401. HTTP clients must include the header returned by revit_mcp.pairing.authorization_headers(); prefer stdio to avoid copying a secret into client configuration.
Testing the endpoints:
# Test streamable-http
curl -X POST http://localhost:8000/mcp
# Test SSE
curl http://localhost:8000/sseConnecting to Claude Desktop
The simplest way to install your MCP server in Claude Desktop:
mcp install main.pyOr for manual installation:
Open Claude Desktop → Settings → Developer → Edit Config
Add this to the
mcpServerssection:
{
"mcpServers": {
"Revit Connector": {
"command": "uv",
"args": [
"run",
"--frozen",
"mcp",
"run",
"/absolute/path/to/main.py"
]
}
}
}For HTTP transport mode, the following URL-only example must also be accompanied by the paired Authorization header in a client that supports it:
{
"mcpServers": {
"Revit Connector": {
"url": "http://localhost:8000/mcp"
}
}
}Connecting to Claude Code
claude mcp add -s user "Revit-Connector" -- uv run --frozen mcp run /absolute/path/to/main.pyCreating Your Own Tools
The modular architecture of this project makes adding functionalities relatively simple. The provided LLM.txt file also gives your language model the necessary context to get started right away.
The process involves three main parts:
Part 1: Create the Route Module in Revit
Create a new Python file within the revit-mcp-python.extension/revit_mcp/ directory (e.g., revit_mcp/your_module.py). This module will contain all the related functions you want to expose.
# 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.")Part 2: Create the MCP Tool Module
Create the corresponding tools for the MCP server in the tools/ directory (e.g., tools/your_tools.py). This module will use the revit_get and revit_post helpers from 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)Part 3: Register Your New Modules
1. Register the Route Module
Open revit-mcp-python.extension/startup.py and add your new route registration function.
# 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)))
raise2. Register the Tool Module
Open tools/__init__.py and add your new tool registration function.
# 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_serverRoadmap
This is a work in progress and more of a demonstration than a fully-featured product. Future improvements could include:
Creating a Client inside Revit
Implementing compatibilities with other language Models
Authentication and security enhancements
More advanced Revit tools and capabilities
Better error handling and debugging features
Benchmarking with local models
Documentation and examples for common use cases
...
Contributing
Contributions are welcome! Feel free to submit pull requests or open issues for any bugs or feature requests. Feel free to reach out to me if you have any questions, ideas
Available Tools
33 toolsalign_viewports_across_sheetsCDestructive
Aligns viewports on target sheets to a reference sheet, ignoring annotation extents.
Inputs: main_sheet_number (required), align_legend, align_titleblock, apply_crop_scope_box, +1 more. Returns: result
auto_calibrate_gridsCDestructive
Matches PDF drawing coordinates to Revit grids and returns calibration points, scale and error.
Inputs: page_number (required), method, pdf_path, level_name, +1 more. Returns: result
batch_create_footings_and_wallsCDestructive
Creates footings, walls and strip footings from parsed foundation data using project types.
Inputs: level_name (required), walls, dry_run, source_tag, +8 more. Returns: result
batch_create_structural_framing_and_columnsCDestructive
Creates structural columns then beams in one transaction after preflight checks.
Inputs: beams (required), columns (required), level_name (required), force, +8 more. Returns: result
batch_create_structural_slabsCDestructive
Creates structural slabs and cuts openings in one transaction.
Inputs: slabs (required), level_name (required). Returns: result
batch_create_structural_walls_and_foundationsCDestructive
Creates shear walls, pile caps and pad/strip footings in one transaction.
Inputs: level_name (required), pile_caps, shear_walls, pad_footings, +2 more. Returns: result
check_duplicatesCDestructive
Scans columns, beams, walls, footings and slabs for duplicated or overlapping elements.
Inputs: no named parameters. Returns: result
clear_colorsBDestructive
Removes view color overrides from elements in a category.
Inputs: category_name (required). Returns: result
close_documentADestructive
Closes the active Revit document, optionally saving changes.
Inputs: save. Returns: result
color_splashCDestructive
Applies view color overrides to elements grouped by a parameter value.
Inputs: category_name (required), parameter_name (required), use_gradient, custom_colors. Returns: result
execute_revit_codeADestructive
Executes supplied IronPython code in Revit with the Windows user's permissions after review in Revit; code can access model data, files and network services.
Inputs: code (required), description. Returns: result
finalize_and_join_structureBDestructive
Joins geometry of columns, walls, beams and slabs on a level in structural priority order.
Inputs: level_name (required). Returns: result
generate_visual_qa_overlayCDestructive
Overlays modelled elements on the source PDF page and returns the image for visual QA.
Inputs: level_name (required), page_number (required), pdf_path, grid_step_mm, +5 more.
get_current_view_elementsBRead-only
Lists elements visible in the active view, with optional level and location information.
Inputs: limit, include_levels, include_location. Returns: result
get_current_view_infoARead-only
Reads the active view's properties and settings.
Inputs: no named parameters. Returns: result
get_revit_model_infoARead-only
Reads project metadata, element counts, rooms, views, sheets, warnings and linked-model information.
Inputs: no named parameters. Returns: result
get_revit_statusARead-only
Reads bridge health and active document availability.
Inputs: no named parameters. Returns: result
get_revit_viewBRead-only
Exports a named model view as a PNG image.
Inputs: view_name (required).
launch_revitBDestructive
Starts an installed Revit version, optionally opens a model file, and checks bridge readiness.
Inputs: timeout, version, language, file_path. Returns: result
list_category_parametersBRead-only
Lists element parameters and sample values for a category.
Inputs: category_name (required). Returns: result
list_familiesBRead-only
Lists loaded family types with optional name filtering.
Inputs: limit, contains. Returns: result
list_family_categoriesARead-only
Lists categories of loaded families.
Inputs: no named parameters. Returns: result
list_levelsARead-only
Lists model levels and their elevations.
Inputs: no named parameters. Returns: result
list_revit_installationsARead-only
Lists installed Revit versions and their executable locations.
Inputs: no named parameters. Returns: result
list_revit_viewsARead-only
Lists exportable model views grouped by view type.
Inputs: no named parameters. Returns: result
modify_or_delete_elementsBDestructive
Deletes or moves listed elements to fix issues found during visual QA.
Inputs: delete_ids, move_vectors_mm. Returns: result
open_documentBDestructive
Opens a specified Revit document, optionally auditing or detaching it from central.
Inputs: file_path (required), audit, detach. Returns: result
parse_pdf_foundation_planCDestructive
Extracts shear walls, pile caps, piles and pad/strip footings from a vector PDF plan in Revit coordinates (mm).
Inputs: page_number (required), pdf_path, level_name, pdf_grid_pt1, +6 more. Returns: result
parse_pdf_structural_planCDestructive
Extracts columns, beams, slabs and openings from a vector PDF plan in Revit coordinates (mm).
Inputs: page_number (required), pdf_path, level_name, pdf_grid_pt1, +8 more. Returns: result
place_familyCDestructive
Places a loaded family instance at specified coordinates and sets requested properties.
Inputs: family_name (required), x, y, z, +4 more. Returns: result
save_documentBDestructive
Saves the active document in place or to a specified new file.
Inputs: file_path. Returns: result
sync_with_centralCDestructive
Synchronizes the active workshared model with central using requested relinquish options.
Inputs: comment, compact, relinquish_all. Returns: result
undo_lastADestructive
Undoes the last committed action in the active Revit document.
Inputs: no named parameters. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 33 tools
Most tools target distinct Revit operations, but several boundaries are blurry: get_revit_status vs get_revit_model_info, list_revit_views vs get_revit_view, and especially multiple batch creation tools for walls, footings, and foundations. Descriptions help, but an agent could still misselect among the structural batch tools or between generic and specialized operations.
Most tool names use snake_case with an action-oriented verb and clear object, such as open_document, save_document, list_levels, and batch_create_structural_slabs. There are minor deviations and long compound names like modify_or_delete_elements and finalize_and_join_structure, but the overall convention is readable and predictable.
At 33 tools, the surface is heavy for a single MCP server and exceeds the typical well-scoped range. Several highly specialized batch creation and QA tools could likely be consolidated or parameterized, making the set harder for an agent to navigate.
The server covers a broad Revit structural workflow: launch, document lifecycle, model inspection, views, families, PDF parsing, batch creation, duplicate checking, visual QA, modification, and geometry joining. Minor gaps remain around broader editing operations such as parameter updates or sheet/view creation, but execute_revit_code provides an escape hatch.
Related MCP Connectors
Convert Revit files to XKT, IFC, or DWG and query BIM data via natural language.
Unified AEC tools: ACC, Revit, Navisworks, Twinmotion, and APS from one endpoint.
AI Hub for AEC — 50+ 3D formats, clash detection, ACC integration via Autodesk Platform Services.
Connect your AI assistant to Blender for 3D modeling, Geometry Nodes, materials, lighting, animation, rendering and export. Inspect real scenes and viewport images, refine the result and restore checkpoints. OAuth connects your chat to Blender Bridge Desktop on an online Windows 10/11 x64 computer running Blender 4.2+. The chat can run on another device. Requires an active Blender Bridge account; 7-day trial available. AI model access is separate.
Related MCP Servers
- AlicenseAqualityFmaintenanceAllows AI to interact with Autodesk Revit via the MCP protocol, enabling retrieval of project data and automation of tasks like creating, modifying, and deleting elements.1365 npm477MIT
- AlicenseBqualityNot gradedmaintenanceAllows AI assistants to interact with Autodesk Revit through the MCP protocol, enabling the AI to create, modify, and delete elements in Revit projects.1565 npm1-
- AlicenseAqualityFmaintenanceEnables AI to interact with Revit via MCP, allowing data retrieval and element creation, modification, and deletion.1365 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables AI clients to interact with Autodesk Revit for building design, editing, analysis, clash detection, MEP, interop, documentation, and model persistence via 48 tools.MIT