Skip to main content
Glama

ai_element_filter

Filter Revit model elements by category, type, visibility, or spatial location to retrieve detailed information for analysis and query answering.

Instructions

An intelligent Revit element querying tool designed specifically for AI assistants to retrieve detailed element information from Revit projects. This tool allows the AI to request elements matching specific criteria (such as category, type, visibility, or spatial location) and then perform further analysis on the returned data to answer complex user queries about Revit model elements. Example: When a user asks 'Find all walls taller than 5m in the project', the AI would: 1) Call this tool with parameters: {"filterCategory": "OST_Walls", "includeInstances": true}, 2) Receive detailed information about all wall instances in the project, 3) Process the returned data to filter walls with height > 5000mm, 4) Present the filtered results to the user with relevant details.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dataYesConfiguration parameters for the Revit element filter tool. These settings determine which elements will be selected from the Revit project based on various filtering criteria. Multiple filters can be combined to achieve precise element selection. All spatial coordinates should be provided in millimeters.

Implementation Reference

  • The execution handler for the 'ai_element_filter' MCP tool. It extracts parameters, connects to Revit using withRevitConnection, sends an 'ai_element_filter' command with the parameters to the Revit client, and returns the JSON-stringified response or an error message.
    async (args, extra) => {
      const params = args;
    
      try {
        const response = await withRevitConnection(async (revitClient) => {
          return await revitClient.sendCommand(
            "ai_element_filter",
            params
          );
        });
    
        return {
          content: [
            {
              type: "text",
              text: JSON.stringify(response, null, 2),
            },
          ],
        };
      } catch (error) {
        return {
          content: [
            {
              type: "text",
              text: `Get element information failed: ${error instanceof Error ? error.message : String(error)
                }`,
            },
          ],
        };
      }
    }
  • Zod schema for the input 'data' parameter of the 'ai_element_filter' tool, defining optional filters such as category, element type, family symbol ID, inclusion flags, visibility filter, bounding boxes, and max elements.
    {
      data: z.object({
        filterCategory: z
          .string()
          .optional()
          .describe("Enumeration of built-in element categories in Revit used for filtering and identifying specific element types (e.g., OST_Walls, OST_Floors, OST_GenericModel). Note that furniture elements may be classified as either OST_Furniture or OST_GenericModel categories, requiring flexible selection approaches"),
        filterElementType: z
          .string()
          .optional()
          .describe("The Revit element type name used for filtering specific elements by their class or type (e.g., 'Wall', 'Floor', 'Autodesk.Revit.DB.Wall'). Gets or sets the name of the Revit element type to be filtered."),
        filterFamilySymbolId: z
          .number()
          .optional()
          .describe("The ElementId of a specific FamilySymbol (type) in Revit used for filtering elements by their type (e.g., '123456', '789012'). Gets or sets the ElementId of the FamilySymbol to be used as a filter criterion. Use '-1' if no specific FamilySymbol filtering is needed."),
        includeTypes: z
          .boolean()
          .default(false)
          .describe("Determines whether to include element types (such as wall types, door types, etc.) in the selection results. When set to true, element types will be included; when false, they will be excluded."),
        includeInstances: z
          .boolean()
          .default(true)
          .describe("Determines whether to include element instances (such as placed walls, doors, etc.) in the selection results. When set to true, element instances will be included; when false, they will be excluded."),
        filterVisibleInCurrentView: z
          .boolean()
          .optional()
          .describe("Determines whether to only return elements that are visible in the current view. When set to true, only elements visible in the current view will be returned. Note: This filter only applies to element instances, not type elements."),
        boundingBoxMin: z
          .object({
            p0: z.object({
              x: z.number().describe("X coordinate of start point"),
              y: z.number().describe("Y coordinate of start point"),
              z: z.number().describe("Z coordinate of start point"),
            }),
            p1: z.object({
              x: z.number().describe("X coordinate of end point"),
              y: z.number().describe("Y coordinate of end point"),
              z: z.number().describe("Z coordinate of end point"),
            }),
          })
          .optional()
          .describe("The minimum point coordinates (in mm) for spatial bounding box filtering. When set along with boundingBoxMax, only elements that intersect with this bounding box will be returned. Set to null to disable this filter."),
        boundingBoxMax: z
          .object({
            p0: z.object({
              x: z.number().describe("X coordinate of start point"),
              y: z.number().describe("Y coordinate of start point"),
              z: z.number().describe("Z coordinate of start point"),
            }),
            p1: z.object({
              x: z.number().describe("X coordinate of end point"),
              y: z.number().describe("Y coordinate of end point"),
              z: z.number().describe("Z coordinate of end point"),
            }),
          })
          .optional()
          .describe("The maximum point coordinates (in mm) for spatial bounding box filtering. When set along with boundingBoxMin, only elements that intersect with this bounding box will be returned. Set to null to disable this filter."),
          maxElements: z
          .number()
          .optional()
          .describe("The maximum number of elements to find in a single tool invocation. Default is 50. Values exceeding 50 are not recommended for performance reasons."),
      })
        .describe("Configuration parameters for the Revit element filter tool. These settings determine which elements will be selected from the Revit project based on various filtering criteria. Multiple filters can be combined to achieve precise element selection. All spatial coordinates should be provided in millimeters."),
    },
  • The registration function 'registerAIElementFilterTool' that registers the 'ai_element_filter' tool on the MCP server using server.tool(), providing the tool name, long description, input schema, and handler function. This function is dynamically called during tool registration in src/tools/register.ts.
    export function registerAIElementFilterTool(server: McpServer) {
      server.tool(
        "ai_element_filter",
        "An intelligent Revit element querying tool designed specifically for AI assistants to retrieve detailed element information from Revit projects. This tool allows the AI to request elements matching specific criteria (such as category, type, visibility, or spatial location) and then perform further analysis on the returned data to answer complex user queries about Revit model elements. Example: When a user asks 'Find all walls taller than 5m in the project', the AI would: 1) Call this tool with parameters: {\"filterCategory\": \"OST_Walls\", \"includeInstances\": true}, 2) Receive detailed information about all wall instances in the project, 3) Process the returned data to filter walls with height > 5000mm, 4) Present the filtered results to the user with relevant details.",
        {
          data: z.object({
            filterCategory: z
              .string()
              .optional()
              .describe("Enumeration of built-in element categories in Revit used for filtering and identifying specific element types (e.g., OST_Walls, OST_Floors, OST_GenericModel). Note that furniture elements may be classified as either OST_Furniture or OST_GenericModel categories, requiring flexible selection approaches"),
            filterElementType: z
              .string()
              .optional()
              .describe("The Revit element type name used for filtering specific elements by their class or type (e.g., 'Wall', 'Floor', 'Autodesk.Revit.DB.Wall'). Gets or sets the name of the Revit element type to be filtered."),
            filterFamilySymbolId: z
              .number()
              .optional()
              .describe("The ElementId of a specific FamilySymbol (type) in Revit used for filtering elements by their type (e.g., '123456', '789012'). Gets or sets the ElementId of the FamilySymbol to be used as a filter criterion. Use '-1' if no specific FamilySymbol filtering is needed."),
            includeTypes: z
              .boolean()
              .default(false)
              .describe("Determines whether to include element types (such as wall types, door types, etc.) in the selection results. When set to true, element types will be included; when false, they will be excluded."),
            includeInstances: z
              .boolean()
              .default(true)
              .describe("Determines whether to include element instances (such as placed walls, doors, etc.) in the selection results. When set to true, element instances will be included; when false, they will be excluded."),
            filterVisibleInCurrentView: z
              .boolean()
              .optional()
              .describe("Determines whether to only return elements that are visible in the current view. When set to true, only elements visible in the current view will be returned. Note: This filter only applies to element instances, not type elements."),
            boundingBoxMin: z
              .object({
                p0: z.object({
                  x: z.number().describe("X coordinate of start point"),
                  y: z.number().describe("Y coordinate of start point"),
                  z: z.number().describe("Z coordinate of start point"),
                }),
                p1: z.object({
                  x: z.number().describe("X coordinate of end point"),
                  y: z.number().describe("Y coordinate of end point"),
                  z: z.number().describe("Z coordinate of end point"),
                }),
              })
              .optional()
              .describe("The minimum point coordinates (in mm) for spatial bounding box filtering. When set along with boundingBoxMax, only elements that intersect with this bounding box will be returned. Set to null to disable this filter."),
            boundingBoxMax: z
              .object({
                p0: z.object({
                  x: z.number().describe("X coordinate of start point"),
                  y: z.number().describe("Y coordinate of start point"),
                  z: z.number().describe("Z coordinate of start point"),
                }),
                p1: z.object({
                  x: z.number().describe("X coordinate of end point"),
                  y: z.number().describe("Y coordinate of end point"),
                  z: z.number().describe("Z coordinate of end point"),
                }),
              })
              .optional()
              .describe("The maximum point coordinates (in mm) for spatial bounding box filtering. When set along with boundingBoxMin, only elements that intersect with this bounding box will be returned. Set to null to disable this filter."),
              maxElements: z
              .number()
              .optional()
              .describe("The maximum number of elements to find in a single tool invocation. Default is 50. Values exceeding 50 are not recommended for performance reasons."),
          })
            .describe("Configuration parameters for the Revit element filter tool. These settings determine which elements will be selected from the Revit project based on various filtering criteria. Multiple filters can be combined to achieve precise element selection. All spatial coordinates should be provided in millimeters."),
        },
        async (args, extra) => {
          const params = args;
    
          try {
            const response = await withRevitConnection(async (revitClient) => {
              return await revitClient.sendCommand(
                "ai_element_filter",
                params
              );
            });
    
            return {
              content: [
                {
                  type: "text",
                  text: JSON.stringify(response, null, 2),
                },
              ],
            };
          } catch (error) {
            return {
              content: [
                {
                  type: "text",
                  text: `Get element information failed: ${error instanceof Error ? error.message : String(error)
                    }`,
                },
              ],
            };
          }
        }
      );
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It describes the tool's intelligent querying nature and provides an example workflow, but lacks critical behavioral details like whether this is a read-only operation, performance implications of different filters, error handling, or what format the returned data takes. The example mentions 'detailed information' but doesn't specify the structure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded with the core purpose, followed by a detailed example that demonstrates practical usage. While the example is lengthy, it serves a clear pedagogical purpose. The description could be slightly more concise by reducing some redundancy in the example explanation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex filtering tool with no annotations and no output schema, the description provides adequate context about what the tool does and includes a helpful example. However, it lacks critical information about the return format, error conditions, performance characteristics, and how multiple filters interact - significant gaps given the tool's complexity and the absence of structured metadata.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the schema already documents all parameters thoroughly. The description adds minimal parameter semantics beyond the schema - it mentions filtering criteria like 'category, type, visibility, or spatial location' which aligns with schema parameters, but doesn't provide additional context about parameter interactions or usage patterns that aren't already in the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose as 'retrieve detailed element information from Revit projects' with specific filtering capabilities (category, type, visibility, spatial location). It distinguishes from siblings like 'get_current_view_elements' by emphasizing comprehensive filtering across the entire project rather than just current view elements.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context about when to use this tool ('to answer complex user queries about Revit model elements') and includes a detailed example workflow. However, it doesn't explicitly state when NOT to use it or mention specific alternatives among the sibling tools for simpler queries.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ideook/revit-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server