Revit MCP: Read data from Active document
Jun 2026I have used MCP to expose some of the revit api to LLM so that it can talk to it.

Overview
Revit MCP is a desktop assistant that lets you talk to an Revit model in plain language. Instead of clicking through menus or writing one: off scripts, you describe what you want, and the app decides which tools to call against the active document.
The stack is split across two runtimes on purpose:
- WPF (.NET 8) hosts the UI and Gemini integration
- Revit add-in (.NET Framework 4.8) talks to the Revit DB API inside the Revit main thread.
The bridge between those two is Named Pipe
I have exposed some ( three ) APIs through MCP Server. Those are
- GetWallLength
public object GetWallLength(string wallId) { var id = new ElementId(long.Parse(wallId)); var wall = _doc.GetElement(id) as Wall; if (wall == null) return new { error = "Wall not found" }; var lengthInternal = wall.get_Parameter(BuiltInParameter.CURVE_ELEM_LENGTH).AsDouble(); var lengthMm = UnitUtils.ConvertFromInternalUnits(lengthInternal, UnitTypeId.Millimeters); var lengthM = UnitUtils.ConvertFromInternalUnits(lengthInternal, UnitTypeId.Meters); return new { wall_id = wallId, length_mm = System.Math.Round(lengthMm, 2), length_m = System.Math.Round(lengthM, 3) }; }
- GetFloorArea
public object GetFloorArea(string levelName) { var level = new FilteredElementCollector(_doc) .OfClass(typeof(Level)) .Cast<Level>() .FirstOrDefault(l => l.Name == levelName); if (level == null) return new { error = $"Level '{levelName}' not found" }; var floors = new FilteredElementCollector(_doc) .OfClass(typeof(Floor)) .Cast<Floor>() .Where(f => f.LevelId == level.Id) .ToList(); var totalArea = floors .Sum(f => f.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED).AsDouble() * 0.0929); return new { level = levelName, area_sqm = System.Math.Round(totalArea, 2) }; }
- ListRoomsByLevel - which is way easier as you only have to write one LINQ...
var rooms = new FilteredElementCollector(_doc) .OfClass(typeof(SpatialElement)) .OfType<Room>() .Where(r => r.Level?.Name == levelName) .Select(r => new { name = r.Name, number = r.Number, area_sqm = System.Math.Round(r.Area * 0.0929, 2) }) .ToList();
Full Request Flow
User types prompt in WPF UI ↓ GeminiService.SendPromptAsync() ↓ HTTPS Google Gemini API (gemini-2.5-flash) ↓ tool_use: open_revit_document McpClientService.CallToolAsync() ↓ stdio (MCP protocol) RevitMCP.Server.exe ↓ named pipe (RevitMCPPipe) RevitMCP.Addin (inside Revit.exe) ↓ Revit DB API Real Revit data (.rvt file) ↑ JSON result Back through pipe → MCP server → Gemini ↑ tool_result Gemini reasons, calls more tools if needed ↑ final text answer ResponseText shown in WPF UI
2 cents and conclusion
It took me 12 days to build this while I was automating Revit workflows. As a new-generation engineer, I thought, "Why not build AI projects?"
They are very simple and easy to do in my openion. I think this is way simpler than automating Revit workflows and writing those LINQs, yet it will still be considered a very good project for a resume. Haha.
This is my first blog post and I hope to write more in the future. let's see if I can keep this up or it dies like my other projects. chop chop !!!
