# How the tag_walls Tool Implements Automatic Wall Tagging in Revit

> Discover how the tag_walls tool automates wall tagging in Revit. Learn about its MCP server implementation, parameter validation, and TCP connection for seamless Revit client communication.

- 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 `tag_walls` tool in the revit-mcp repository implements automatic wall tagging by registering an MCP server tool that validates parameters, manages a TCP connection to Revit via `withRevitConnection`, and dispatches a `tag_walls` command to the Revit client.**

The `tag_all_walls` tool provides a server-side utility for the Model Context Protocol (MCP) that enables AI assistants to request automatic wall tagging for the active Revit view. This implementation demonstrates a clean separation between API definition, connection lifecycle management, and Revit-specific business logic.

## Architecture Overview of the tag_walls Implementation

The implementation follows a four-layer architecture that ensures reliable communication between the MCP server and the Revit application:

1. **Tool Registration Layer** – Defines the JSON schema and parameter validation using Zod
2. **Connection Management Layer** – Handles TCP socket lifecycle via `withRevitConnection`
3. **Command Dispatch Layer** – Sends the `tag_walls` command to the Revit client
4. **Response Handling Layer** – Processes success and error states for MCP framework consumption

## Tool Registration and Schema Definition

In [`src/tools/tag_all_walls.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/tools/tag_all_walls.ts), the tool registers with the MCP server using a descriptive name and Zod-based schema validation. The schema defines two optional parameters that control tagging behavior:

- **`useLeader`** (boolean, defaults to `false`) – Determines whether leader lines extend from tags to walls
- **`tagTypeId`** (string) – Specifies a custom tag family ID for specialized wall tags

```typescript
server.tool(
  "tag_all_walls",
  "Create tags for all walls in the current active view. Tags will be placed at the middle point of each wall.",
  {
    useLeader: z.boolean().optional().default(false),
    tagTypeId: z.string().optional()
  },
  async (args, extra) => {
    // Handler implementation
  }
);

```

## Connection Lifecycle Management

The tool delegates network communication to `withRevitConnection` from [`src/utils/ConnectionManager.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/utils/ConnectionManager.ts). This utility manages the complete lifecycle of a TCP socket connection to the Revit client:

- Creates a `RevitClientConnection` instance
- Enforces a 5-second connection timeout
- Guarantees connection cleanup via automatic disconnection
- Executes the provided async operation only after successful connection establishment

```typescript
import { withRevitConnection } from "../utils/ConnectionManager.js";

async (args, extra) => {
  return await withRevitConnection(async (revitClient) => {
    // Command execution within managed connection
  });
}

```

## Command Dispatch to Revit

Within the connection callback, the tool constructs and dispatches the `tag_walls` command. The Revit client (running as an add-in outside this repository) receives the command and executes the actual tagging logic in the active view.

```typescript
const params = {
  useLeader: args.useLeader,
  tagTypeId: args.tagTypeId
};

const response = await revitClient.sendCommand("tag_walls", params);

```

The response handling distinguishes between successful execution and error states, returning structured content that the MCP framework renders appropriately:

```typescript
if (response.success) {
  return {
    content: [{ type: "text", text: JSON.stringify(response.data) }]
  };
} else {
  return {
    content: [{ type: "text", text: `Error: ${response.message}` }],
    isError: true
  };
}

```

## Complete Implementation Example

To register and use the `tag_all_walls` tool in an MCP server implementation:

```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { registerTagAllWallsTool } from "./src/tools/tag_all_walls.js";

const server = new McpServer();
registerTagAllWallsTool(server);
await server.start();

```

Client-side invocation via the MCP SDK:

```typescript
import { Client } from "@modelcontextprotocol/sdk/client/index.js";

const client = new Client({ name: "revit-client", version: "1.0.0" });

const result = await client.callTool({
  name: "tag_all_walls",
  arguments: {
    useLeader: true,
    tagTypeId: "Wall Tag - Generic"
  }
});

```

## Summary

The `tag_walls` tool implementation demonstrates a robust pattern for Revit automation through the Model Context Protocol:

- **Clean separation of concerns** between tool definition ([`src/tools/tag_all_walls.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/tools/tag_all_walls.ts)), connection management ([`src/utils/ConnectionManager.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/utils/ConnectionManager.ts)), and Revit execution
- **Type-safe parameter validation** using Zod schemas for `useLeader` and `tagTypeId` options
- **Reliable network handling** via `withRevitConnection` with automatic timeout and cleanup
- **Extensible architecture** that allows additional Revit commands to follow the same pattern

## Frequently Asked Questions

### What parameters does the tag_all_walls tool accept?

The tool accepts two optional parameters: `useLeader` (boolean, defaults to `false`) controls whether leader lines extend from tags to walls, and `tagTypeId` (string) specifies a custom tag family ID for specialized wall tags. Both parameters are validated using Zod schema validation before being sent to Revit.

### How does the tool communicate with the Revit application?

The tool uses a TCP socket connection managed by `withRevitConnection` in [`src/utils/ConnectionManager.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/utils/ConnectionManager.ts). This utility creates a `RevitClientConnection`, enforces a 5-second connection timeout, executes the command, and guarantees cleanup by disconnecting after the operation completes. The actual `tag_walls` command is then dispatched to the Revit client add-in.

### Where is the actual wall tagging logic implemented?

The server-side code in [`src/tools/tag_all_walls.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/src/tools/tag_all_walls.ts) only handles API registration and command dispatch. The actual Revit API logic that creates tags at wall midpoints runs in the Revit client add-in, which receives the `tag_walls` command via the TCP connection. This separation keeps the MCP server stateless and Revit-agnostic.

### Can I extend this pattern for other Revit elements?

Yes, the architecture supports extension for doors, windows, or other categories. You would create a new file in `src/tools/` following the [`tag_all_walls.ts`](https://github.com/mcp-servers-for-revit/revit-mcp/blob/main/tag_all_walls.ts) pattern: register the tool with a Zod schema, use `withRevitConnection` for the TCP lifecycle, and dispatch a new command name (e.g., `tag_doors`) to the Revit client. The connection management and response handling code remains identical.