Understanding the revit-mcp and revit-mcp-plugin Relationship: Server-Add-in Architecture
The revit-mcp repository provides the MCP server that runs outside Revit, while revit-mcp-plugin is the Revit add-in that executes inside Revit; together they form a client-server bridge that translates AI tool calls into Revit API commands via TCP socket communication.
The mcp-servers-for-revit/revit-mcp repository implements a Model Context Protocol (MCP) server that exposes Revit functionality to AI assistants. Understanding the relationship between revit-mcp and revit-mcp-plugin is essential for architects and developers building automated workflows, as these two components must run simultaneously to enable AI-driven Revit automation.
What is revit-mcp? The MCP Server Component
revit-mcp is the MCP server that operates as a standalone Node.js/TypeScript process outside of the Revit environment. Its primary responsibilities include:
- Tool Registration: Dynamically registering MCP tools such as
get_current_view_info,send_code_to_revit, andget_selected_elementsviasrc/tools/register.ts - Server Initialization: Creating an
McpServerinstance and connecting transport layers insrc/index.ts - Connection Management: Maintaining TCP socket connections to the Revit plugin through
src/utils/ConnectionManager.tsandsrc/utils/SocketClient.ts
The server acts as the intermediary between AI assistants (clients) and the Revit application, translating natural language requests into structured JSON-RPC commands.
What is revit-mcp-plugin? The Revit Add-in Component
revit-mcp-plugin is the Revit add-in (plugin) that runs inside the Revit process as a compiled .NET assembly. This component provides the execution environment for Revit API calls and includes:
- SocketService: A TCP listener service that accepts connections on
localhost:8080(configurable) - CommandManager: Routes incoming JSON-RPC requests to appropriate command handlers
- CommandExecute: Executes the actual Revit API calls within the Revit context (e.g., creating walls, modifying elements, retrieving view data)
Because Revit uses a single-threaded apartment (STA) model for API access, the plugin must marshal all API calls to Revit's main thread, making the in-process add-in architecture necessary for safe Revit automation.
How revit-mcp and revit-mcp-plugin Communicate
The relationship between revit-mcp and revit-mcp-plugin relies on a TCP socket-based JSON-RPC protocol that enables bidirectional communication between the external server and the internal Revit process.
Connection Management and SocketClient
In src/utils/ConnectionManager.ts, the server implements a connection wrapper that manages the lifecycle of the TCP connection:
// src/utils/ConnectionManager.ts (simplified)
import { RevitClientConnection } from './SocketClient.js';
export async function withRevitConnection<T>(
callback: (client: RevitClientConnection) => Promise<T>
): Promise<T> {
const client = new RevitClientConnection('localhost', 8080);
try {
await client.connect();
return await callback(client);
} finally {
await client.disconnect();
}
}
The SocketClient.ts file implements the actual JSON-RPC client that serializes requests and deserializes responses:
// src/utils/SocketClient.ts (conceptual)
export class RevitClientConnection {
private socket: net.Socket;
private pendingRequests: Map<string, Deferred<any>> = new Map();
async sendCommand(method: string, params?: any): Promise<any> {
const id = generateRequestId();
const request = {
jsonrpc: "2.0",
method: method,
params: params || {},
id: id
};
this.socket.write(JSON.stringify(request) + '\n');
// Wait for response with matching ID
return this.pendingRequests.get(id).promise;
}
}
JSON-RPC Protocol Implementation
When an AI assistant invokes a tool, the server sends a JSON-RPC 2.0 request to the plugin:
{
"jsonrpc": "2.0",
"method": "get_current_view_info",
"params": {},
"id": "1697845123456"
}
The plugin's CommandManager routes this to the appropriate handler, executes the Revit API call, and returns:
{
"jsonrpc": "2.0",
"result": {
"viewName": "Level 1",
"viewType": "FloorPlan",
"id": 123456
},
"id": "1697845123456"
}
Code Flow: From AI Tool Call to Revit API Execution
Understanding the complete relationship between revit-mcp and revit-mcp-plugin requires tracing the execution path from tool registration to API execution.
Tool Registration on the Server
In src/tools/register.ts, the server dynamically imports and registers all available tools:
// src/tools/register.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { registerGetCurrentViewInfoTool } from "./get_current_view_info.js";
import { registerSendCodeToRevitTool } from "./send_code_to_revit.js";
export function registerTools(server: McpServer) {
registerGetCurrentViewInfoTool(server);
registerSendCodeToRevitTool(server);
// ... other tools
}
Tool Implementation with Connection Handling
The get_current_view_info tool demonstrates how the server uses withRevitConnection to communicate with the plugin:
// src/tools/get_current_view_info.ts (simplified)
import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { withRevitConnection } from "../utils/ConnectionManager.js";
export function registerGetCurrentViewInfoTool(server: McpServer) {
server.tool(
"get_current_view_info",
"Get current view info",
{}, // schema
async (_args, _extra) => {
const result = await withRevitConnection(async client => {
return await client.sendCommand("get_current_view_info");
});
return {
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
};
}
);
}
Dynamic Code Execution Tool
The send_code_to_revit tool allows AI assistants to execute arbitrary C# code within Revit:
// src/tools/send_code_to_revit.ts (conceptual)
server.tool(
"send_code_to_revit",
"Send C# code to execute in Revit",
{
code: z.string().describe("C# code to execute"),
parameters: z.array(z.any()).optional()
},
async (args, _extra) => {
return await withRevitConnection(async client => {
return await client.sendCommand("execute_code", {
code: args.code,
parameters: args.parameters || []
});
});
}
);
Key Files and Implementation Details
The relationship between revit-mcp and revit-mcp-plugin is implemented through specific files in both repositories:
| File | Component | Purpose |
|---|---|---|
src/index.ts |
revit-mcp | Entry point that creates McpServer and initializes the transport |
src/tools/register.ts |
revit-mcp | Dynamically imports and registers all MCP tools |
src/utils/ConnectionManager.ts |
revit-mcp | Manages TCP connection lifecycle to the plugin |
src/utils/SocketClient.ts |
revit-mcp | Implements JSON-RPC client protocol over TCP sockets |
src/tools/send_code_to_revit.ts |
revit-mcp | Tool implementation for dynamic C# code execution |
| SocketService | revit-mcp-plugin | TCP listener service running inside Revit |
| CommandManager | revit-mcp-plugin | Routes incoming commands to appropriate handlers |
| CommandExecute | revit-mcp-plugin | Executes Revit API calls within the Revit process context |
According to the README in the revit-mcp repository, the server "is the server side (providing Tools to AI), and you need to use revit-mcp-plugin (driving Revit) in conjunction."
Summary
-
revit-mcp is the external MCP server that registers AI tools and manages protocol communication; it runs as a standalone Node.js process.
-
revit-mcp-plugin is the internal Revit add-in that executes within the Revit process, hosting a TCP socket service to receive and execute commands.
-
The two components communicate via JSON-RPC over TCP (default port 8080), with
ConnectionManagerandSocketClienthandling the client side and the plugin'sSocketServicehandling the server side. -
Tool registration occurs in
src/tools/register.ts, while actual Revit API execution happens inside the plugin'sCommandExecutecomponent, ensuring thread-safe access to Revit's single-threaded API.
Frequently Asked Questions
Does revit-mcp work without revit-mcp-plugin installed?
No. The revit-mcp server cannot execute any Revit operations without the plugin running inside Revit. When you invoke tools like get_current_view_info or send_code_to_revit, the server attempts to connect to localhost:8080 where the plugin's SocketService listens. If the plugin is not loaded in Revit, the connection fails and the tool returns an error indicating that Revit is not accessible.
Can I run multiple instances of revit-mcp connecting to different Revit sessions?
Currently, the architecture supports one active connection per revit-mcp server instance because ConnectionManager maintains a single RevitClientConnection to localhost:8080. To control multiple Revit sessions simultaneously, you would need to run separate revit-mcp server instances configured to connect to different TCP ports, with each Revit instance running a plugin instance listening on the corresponding port.
What protocol do revit-mcp and revit-mcp-plugin use to communicate?
The components communicate using JSON-RPC 2.0 over raw TCP sockets. The SocketClient.ts implementation in revit-mcp serializes requests with jsonrpc, method, params, and id fields, while the plugin's CommandManager deserializes these requests, routes them to CommandExecute, and returns JSON-RPC response objects containing either a result or error field.
Is the revit-mcp-plugin code available in the same repository?
No. The revit-mcp-plugin is maintained as a separate repository. The revit-mcp repository (the one analyzed here) contains only the server-side TypeScript code. According to the README, users must download and install the revit-mcp-plugin separately, build it as a Revit add-in, and load it into Revit before starting the revit-mcp server.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →