How the Batch Element Creation System Handles Multiple Elements in Revit

The batch element creation system in revit-mcp processes multiple Revit elements in a single RPC call by validating an array of element definitions with Zod schemas, transmitting them through a persistent TCP socket via withRevitConnection, and dispatching the entire payload to Revit using sendCommand for consolidated processing.

The revit-mcp repository implements a Model Context Protocol (MCP) server that enables AI assistants to interact with Autodesk Revit. At the core of this integration lies the batch element creation system, which optimizes BIM workflows by allowing a single request to generate numerous Revit elements—such as walls, doors, floors, and furniture—without establishing separate network connections for each item.

Architecture of the Batch Element Creation System

Zod Schema Validation for Array Inputs

Each creation tool registers itself using server.tool() with a Zod schema that defines the input as an array of objects. In src/tools/create_line_based_element.ts, src/tools/create_point_based_element.ts, and src/tools/create_surface_based_element.ts, the data parameter uses z.array(z.object({ ... })) to enforce that every element definition contains required fields like geometry coordinates, family type IDs, levels, and dimensions.

This schema-driven approach prevents malformed requests from reaching Revit, catching validation errors before any network transmission occurs.

Connection Management with withRevitConnection

The withRevitConnection utility in src/utils/ConnectionManager.ts manages the TCP socket lifecycle to Revit. When a batch tool is invoked, this wrapper:

  • Opens a persistent TCP connection to localhost:8080
  • Waits for the connect event or times out after 5 seconds
  • Executes the provided async operation with an active RevitClientConnection
  • Guarantees disconnection via revitClient.disconnect() after completion, even if errors occur

This pattern ensures that the entire batch array transmits through a single network round-trip rather than opening connections per element.

Implementation in Creation Tools

Line-Based Elements (create_line_based_element.ts)

Located at src/tools/create_line_based_element.ts, this tool handles batch creation of walls, beams, and pipes. The handler receives the validated array and invokes revitClient.sendCommand("create_line_based_element", params), where params is the complete array of line-based definitions. The Revit client processes each entry by calling the appropriate Revit API methods like Wall.Create in a loop, returning a consolidated array of results.

Point-Based Elements (create_point_based_element.ts)

The src/tools/create_point_based_element.ts file manages doors, windows, and furniture placement. Using the same batch pattern, it sends the entire array via sendCommand("create_point_based_element", params) to Revit. Each object in the array specifies insertion points, family type IDs, and host element references, allowing the Revit side to iterate through the batch and instantiate multiple hosted elements efficiently.

Surface-Based Elements (create_surface_based_element.ts)

For floors, ceilings, and roofs, src/tools/create_surface_based_element.ts implements the batch creation workflow. The tool validates an array of boundary definitions—each containing lists of vertices that define closed loops—and transmits them via sendCommand("create_surface_based_element", params). This enables the creation of complex surface systems in a single operation, with Revit processing each boundary loop through the appropriate Floor.Create or Roof.Create methods.

Code Examples

Batch Payload Structure

The following JSON demonstrates a batch request for creating two walls via the line-based element tool:

[
  {
    "name": "Exterior Wall",
    "typeId": 1023,
    "locationLine": {
      "p0": { "x": 0, "y": 0, "z": 0 },
      "p1": { "x": 10000, "y": 0, "z": 0 }
    },
    "thickness": 200,
    "height": 3000,
    "baseLevel": 0,
    "baseOffset": 0
  },
  {
    "name": "Interior Wall",
    "typeId": 1024,
    "locationLine": {
      "p0": { "x": 0, "y": 5000, "z": 0 },
      "p1": { "x": 10000, "y": 5000, "z": 0 }
    },
    "thickness": 150,
    "height": 2800,
    "baseLevel": 0,
    "baseOffset": 0
  }
]

Client Implementation

Invoke the batch creation tool using the Model Context Protocol SDK:

import { McpClient } from "@modelcontextprotocol/sdk/client/mcp.js";

async function createWallsBatch() {
  const client = new McpClient("ws://localhost:8000");
  await client.connect();

  const response = await client.runTool(
    "create_line_based_element",
    [
      // Array of wall definitions
    ]
  );

  console.log("Batch creation result:", response);
  await client.disconnect();
}

Server-Side Processing Flow

The tool handler validates and transmits the batch:

// From src/tools/create_line_based_element.ts
server.tool(
  "create_line_based_element",
  "Create one or more line-based elements",
  { data: z.array(z.object({
      name: z.string(),
      typeId: z.number(),
      locationLine: z.object({
        p0: z.object({ x: z.number(), y: z.number(), z: z.number() }),
        p1: z.object({ x: z.number(), y: z.number(), z: z.number() })
      }),
      thickness: z.number(),
      height: z.number(),
      baseLevel: z.number(),
      baseOffset: z.number()
    })) 
  },
  async (args) => {
    const params = args.data;
    const response = await withRevitConnection(
      (revitClient) => revitClient.sendCommand("create_line_based_element", params)
    );
    return { 
      content: [{ 
        type: "text", 
        text: JSON.stringify(response, null, 2) 
      }] 
    };
  }
);

The withRevitConnection wrapper ensures the socket is live, then forwards the entire array (params) to the Revit client in a single command.

Summary

  • The batch element creation system in revit-mcp uses Zod array schemas to validate multiple element definitions in a single request, preventing malformed data from reaching Revit.
  • The withRevitConnection utility in src/utils/ConnectionManager.ts manages a persistent TCP socket, ensuring the entire batch transmits through one network round-trip rather than opening connections per element.
  • Creation tools in src/tools/create_line_based_element.ts, src/tools/create_point_based_element.ts, and src/tools/create_surface_based_element.ts dispatch validated arrays via sendCommand, allowing the Revit client to process elements in a loop and return consolidated results.
  • This architecture minimizes latency, reduces network overhead, and provides atomic batch operations for complex BIM workflows.

Frequently Asked Questions

What is the maximum number of elements that can be created in a single batch request?

The revit-mcp server does not enforce a hard limit on batch size within its own validation logic; however, practical limits depend on the Revit client's memory capacity and the complexity of the geometry being created. Extremely large batches (thousands of elements) may cause Revit to become unresponsive or timeout, so it is recommended to batch operations into manageable chunks of 100-500 elements depending on element complexity.

How does the system handle partial failures when creating multiple elements?

When the Revit client processes a batch, it iterates through each element definition and attempts creation individually. If specific elements fail (for example, due to invalid geometry or missing family types), the Revit client typically continues processing the remaining items and returns an array containing both successful element IDs and error messages for failed entries. The MCP server wraps this consolidated response into a JSON text message, allowing callers to identify which specific array indices succeeded or failed.

Can different element types be mixed in a single batch request?

No, each creation tool is specialized for a specific geometric category. The create_line_based_element tool handles only walls, beams, and pipes; create_point_based_element handles only doors, windows, and furniture; and create_surface_based_element handles only floors, ceilings, and roofs. While you cannot mix line-based and point-based elements in a single tool call, you can issue multiple parallel or sequential batch requests to different tools to achieve mixed-element workflows.

What happens if the Revit connection drops during a batch operation?

The withRevitConnection utility in src/utils/ConnectionManager.ts implements a timeout mechanism (5 seconds) and error handling that guarantees socket cleanup. If the connection drops during transmission or while waiting for a response, the promise rejects with a connection error, the socket is forcibly disconnected, and the MCP server returns an error response to the client. The batch operation is atomic from the MCP server's perspective—if the connection fails, no partial results are returned, and the client must retry the entire batch.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →