# Data Flow from AI Tool Call Through MCP to Revit Execution: A Complete Technical Guide

> Understand the seven-stage data flow from AI tool calls to Revit execution via MCP. Learn tool registration, AI requests, handler execution, and Revit add-in processing for seamless integration.

- Repository: [MCP servers for Revit/revit-mcp](https://github.com/mcp-servers-for-revit/revit-mcp)
- Tags: how-to-guide
- Published: 2026-02-16

---

**The data flow from an AI tool call through MCP to Revit execution follows a seven-stage pipeline: tool registration, AI client request, tool handler execution, connection management, JSON-RPC socket communication, Revit add-in processing, and result propagation back to the AI assistant.**

The `revit-mcp` repository implements a Model-Context-Protocol (MCP) server that bridges AI assistants with Autodesk Revit. Understanding this data flow is essential for developers building AI-powered BIM workflows, as it reveals how high-level natural language commands translate into precise Revit API operations.

## The Seven-Stage MCP to Revit Data Flow Architecture

### Stage 1: Tool Registration and Discovery

When the MCP server initializes, the `registerTools` function in [`src/tools/register.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/tools/register.ts) dynamically discovers and exposes all available Revit operations to AI clients.

The registration system scans the `src/tools` directory and imports every module exporting a function prefixed with `register`. Each registration function calls `server.registerTool()` from the MCP SDK, binding a tool name (e.g., `"ai_element_filter"`) to its handler implementation.

```typescript
// src/tools/register.ts
for (const file of toolFiles) {
  const module = await import(`./${file.replace(/\.(ts|js)$/, ".js")}`);
  const registerFn = Object.keys(module).find(
    k => k.startsWith("register") && typeof module[k] === "function"
  );
  if (registerFn) module[registerFn](server);
}

```

### Stage 2: AI Client JSON-RPC Request

When an AI assistant decides to invoke a Revit operation, its MCP client sends a JSON-RPC 2.0 request to the server. The request specifies the tool name and parameters required for the Revit operation.

```typescript
// AI client using the Model-Context-Protocol SDK
const result = await mcpServer.callTool("ai_element_filter", {
  filterCategory: "OST_Walls",
  includeInstances: true
});
console.log("Walls returned:", result);

```

### Stage 3: Tool Handler Execution

The MCP SDK routes the incoming request to the registered tool handler. In [`src/tools/ai_element_filter.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/tools/ai_element_filter.ts), the handler wraps its logic inside `withRevitConnection`, ensuring a valid TCP link to Revit exists before proceeding.

```typescript
// src/tools/ai_element_filter.ts
export function registerAiElementFilterTool(server: McpServer) {
  server.registerTool({
    name: "ai_element_filter",
    description: "Query Revit elements for AI assistants",
    // … schema omitted …
    async handler(params) {
      // Ensure we have a live Revit connection
      return await withRevitConnection(async revitClient => {
        // Forward the request to the Revit add‑in
        return await revitClient.sendCommand("ai_element_filter", params);
      });
    },
  });
}

```

### Stage 4: Connection Management and TCP Handshake

The `withRevitConnection` helper in [`src/utils/ConnectionManager.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/utils/ConnectionManager.ts) manages the lifecycle of the TCP connection to Revit. It instantiates a `RevitClientConnection` targeting `localhost:8080` and implements a 5-second timeout for the initial handshake.

If the socket is not already connected, the manager waits for the TCP handshake to complete before invoking the tool-specific callback with the live client instance.

```typescript
// src/utils/ConnectionManager.ts
export async function withRevitConnection<T>(operation: (c: RevitClientConnection) => Promise<T>) {
  const revitClient = new RevitClientConnection("localhost", 8080);
  // … connect logic (5 s timeout) …
  try {
    return await operation(revitClient);
  } finally {
    revitClient.disconnect();
  }
}

```

### Stage 5: JSON-RPC over TCP Socket Communication

The `RevitClientConnection` class in [`src/utils/SocketClient.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/utils/SocketClient.ts) implements the low-level JSON-RPC 2.0 protocol over TCP. When `sendCommand` is invoked, it:

1. Generates a unique request ID using `generateRequestId`
2. Constructs a JSON-RPC 2.0 payload with `method`, `params`, and `id`
3. Writes the serialized JSON to the TCP socket
4. Stores a callback in `responseCallbacks` keyed by the request ID
5. Returns a promise that resolves when the Revit add-in responds or rejects on error/timeout

```typescript
// src/utils/SocketClient.ts (excerpt)
public sendCommand(command: string, params: any = {}): Promise<any> {
  return new Promise((resolve, reject) => {
    const requestId = this.generateRequestId();
    const payload = { jsonrpc: "2.0", method: command, params, id: requestId };
    this.responseCallbacks.set(requestId, data => {
      const resp = JSON.parse(data);
      resp.error ? reject(new Error(resp.error.message)) : resolve(resp.result);
    });
    this.socket.write(JSON.stringify(payload));
    // … timeout handling …
  });
}

```

### Stage 6: Revit Add-in Execution

On the Revit side (external to this repository but communicating via the established protocol), a dedicated add-in listens on TCP port 8080. Upon receiving the JSON-RPC command, it:

- Parses the method name and parameters
- Executes the corresponding Revit API operation (e.g., filtering elements, creating geometry, modifying parameters)
- Constructs a JSON-RPC response containing either a `result` object or an `error` object
- Sends the response back through the TCP socket

### Stage 7: Result Propagation to AI Client

The response travels back up the chain:

1. The socket listener in [`SocketClient.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/SocketClient.ts) receives the JSON, parses it, and invokes the stored callback from `responseCallbacks`
2. The promise returned by `sendCommand` resolves with `response.result` (or rejects on error)
3. This bubbles up through `withRevitConnection` to the tool handler in [`ai_element_filter.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/ai_element_filter.ts)
4. The MCP server packages the result into the original JSON-RPC response to the AI client
5. The AI assistant receives the structured data and can present results or continue the workflow

## Key Implementation Files in the Data Flow

| Purpose | File Path |
|---------|-----------|
| Server entry point – creates `McpServer` and starts the stdio transport | [`src/index.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/index.ts) |
| Dynamic discovery and registration of all tool modules | [`src/tools/register.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/tools/register.ts) |
| Example AI-focused tool exposing `"ai_element_filter"` | [`src/tools/ai_element_filter.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/tools/ai_element_filter.ts) |
| Helper guaranteeing a live TCP link to the Revit add-in | [`src/utils/ConnectionManager.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/utils/ConnectionManager.ts) |
| Low-level socket wrapper implementing JSON-RPC over TCP | [`src/utils/SocketClient.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/utils/SocketClient.ts) |
| Additional tool implementations following the same pattern | `src/tools/*.ts` (e.g., [`create_line_based_element.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/create_line_based_element.ts), [`operate_element.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/operate_element.ts)) |

## Summary

- **Tool Registration**: The `registerTools` function dynamically discovers and exposes Revit operations via the MCP SDK at server startup.
- **AI Client Communication**: AI assistants invoke tools through JSON-RPC 2.0 requests handled by the MCP server.
- **Connection Management**: The `withRevitConnection` helper ensures a live TCP connection to Revit on `localhost:8080` with a 5-second timeout.
- **Protocol Implementation**: [`SocketClient.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/SocketClient.ts) handles JSON-RPC serialization, request ID generation, and promise-based response handling over TCP.
- **Revit Execution**: The Revit add-in receives commands, executes Revit API operations, and returns structured responses back through the same chain.

## Frequently Asked Questions

### How does the MCP server handle multiple concurrent tool calls to Revit?

Each tool invocation creates its own promise chain through `withRevitConnection`, which manages the TCP socket lifecycle. While the current implementation in [`ConnectionManager.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/ConnectionManager.ts) creates a new `RevitClientConnection` instance per operation, the underlying TCP connection to `localhost:8080` is managed sequentially. For true concurrency, the Revit add-in would need to implement request queuing or the connection manager would need to implement connection pooling.

### What happens if Revit is not running when an AI tool call is made?

The `withRevitConnection` function implements a 5-second connection timeout when attempting to connect to `localhost:8080`. If the TCP handshake fails because Revit is not running or the add-in is not loaded, the connection promise rejects with a timeout error. This error propagates back through the tool handler to the MCP server, which returns a JSON-RPC error response to the AI client indicating that the Revit connection is unavailable.

### Is the communication between MCP and Revit encrypted?

The current implementation in [`src/utils/SocketClient.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/utils/SocketClient.ts) uses a standard Node.js `net.Socket` for TCP communication without TLS/SSL encryption. The connection operates over plain TCP on `localhost:8080`, which is suitable for local development but would require implementation of TLS wrappers or VPN tunnels for production environments where Revit and the MCP server run on separate machines.

### How are tool parameters validated before reaching Revit?

Parameter validation occurs at two levels in the data flow. First, the MCP SDK validates incoming requests against the JSON schema defined in the tool registration (e.g., in `registerAiElementFilterTool`). Second, the Revit add-in performs business logic validation when it receives the JSON-RPC command, ensuring that parameters like element IDs exist and that operations are valid for the current Revit document state. Errors from either validation layer propagate back to the AI client as JSON-RPC error objects.