MCP server for Revit that enables code execution, document management, family placement, color visualization, and model inspection through a Python-based interface to Revit's API
Server has 20 tools with basic descriptions and parameter schemas, but significant gaps in quality. Most tool descriptions are present (194 chars baseline met for some), but many lack actionable detail on WHEN to use them vs similar tools. Parameter schemas are visible but inconsistently documented, some params lack descriptions entirely. No output schemas documented. Error handling is generic (try/except with format_response). Tool naming follows verb_noun convention (execute_, color_, list_, get_, open_, close_, save_, sync_, place_) which is good, but composition issues exist: execute_revit_code is dangerously broad (arbitrary code execution), and several tools (open_document, close_document, save_document) could be better unified. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) visible. Security concern: execute_revit_code accepts arbitrary IronPython with no validation or sandboxing.
Clear color overrides for elements in a category This tool removes all color overrides that have been applied to elements in the specified category, returning them to their default appearance.
Close the active Revit document.
Color elements in a category based on parameter values This tool applies color coding to Revit elements within a specified category based on their parameter values. Elements with the same parameter value will receive the same color.
Execute IronPython code directly in Revit context. The code has access to: - doc: The active Revit document - uidoc: The active UIDocument (use for UI operations like switching the active view) - DB: Revit API Database namespace - revit: pyRevit module - print: Function to output text (returned in response) No transaction is opened automatically. Wrap model-modifying code yourself: t = DB.Transaction(doc, "My change") t.Start() # ... modify model ... t.Commit() For UI operations that cannot run inside a transaction (e.g. switching the active view): all_views = DB.FilteredElementCollector(doc).OfClass(DB.View).ToElements() target = next((v for v in all_views if v.Name == "Level 1"), None) if target: uidoc.ActiveView = target Tips: - Use getattr(element, 'Name', 'N/A') to safely access the Name property - Check elements exist before use: if element: - Use hasattr() for optional properties
execute_revit_code accepts arbitrary IronPython with no input validation, sandboxing, or permission gates. This is a critical security vulnerability, malicious or confused agents could corrupt the Revit model, delete files, or execute system commands.
No output schemas documented for any tool. LLMs cannot plan downstream calls or extract required fields (e.g., does list_families return family_id, family_name, type_name?). This forces agents to guess field names and causes chaining failures.
Many tool descriptions are generic or incomplete. E.g., list_family_categories has no description at all; list_levels says 'Get a list of all levels' but doesn't explain when to call it vs get_current_view_info. Descriptions under 50 chars cannot guide LLM selection.
Inferred effective spec: 2026-07-28+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2026-07-28+ | v2 |
Get elements visible in the currently active view in Revit. Returns per element: element_id, name, category, category_id. Also returns category_counts (always for ALL elements, even if truncated). If the response contains truncated=true, not all elements were returned. Check total_elements vs returned_elements and increase limit if needed.
Get detailed information about the currently active view in Revit. Returns comprehensive information including: - View name, type, and ID - Scale and detail level - Crop box status - View family type - View discipline - Template status
Get comprehensive information about the current Revit model
Check if the Revit MCP API is active and responding
Export a specific Revit view as an image
Launch Revit on this machine, optionally opening a file. Finds installed Revit versions automatically. After launching, polls the pyRevit Routes health endpoint until Revit is ready for MCP tools. For workshared (central model) files, Revit will show its native worksharing dialog on open. Use the open_document tool after launch for more control over worksharing options like detach from central.
Get available parameters for elements in a category This tool helps you discover what parameters are available for coloring by listing all parameters found on elements in the specified category.
Get a flat list of available family types in the current Revit model. Use `contains` to filter by a substring of the family or type name (case-insensitive).
Get a list of all family categories in the current Revit model
Get a list of all levels in the current Revit model
Discover all Revit versions installed on this system. Returns a list of installed Revit versions with their executable paths. Use this to check what's available before calling launch_revit.
Get a list of all exportable views in the current Revit model
Open a Revit document file in the running Revit instance. Supports workshared (central) files with options to detach from central or audit the file on open.
Place a family instance at a specified location in the Revit model
Save the active Revit document. If file_path is omitted, saves the document in place. If file_path is provided, performs a Save As to the new location.
Synchronize the active workshared document with central. Only works with workshared (central model) documents. For non-workshared documents, use save_document instead.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) present. LLMs cannot distinguish safe read-only tools from destructive ones (e.g., close_document with save=true vs save=false). This risks accidental data loss.
Error handling is generic (try/except with format_response). No actionable error messages, no recovery guidance, no categorization of retryable vs fatal errors. An LLM hitting a failure has no idea what to do next.