Skip to main content
Glama
jomon003

PlayMCP Browser Automation Server

by jomon003

getElementHierarchy

Retrieve the hierarchical structure of webpage elements to analyze parent-child relationships and DOM organization for web automation tasks.

Instructions

Get the hierarchical structure of page elements with parent-child relationships

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
selectorNoCSS selector for root element (default: 'body')
maxDepthNoMaximum depth to traverse (-1 for unlimited, default: 3)
includeTextNoInclude text content of elements (default: false)
includeAttributesNoInclude element attributes (default: false)

Implementation Reference

  • The primary handler function that implements the getElementHierarchy tool logic by evaluating JavaScript in the browser to traverse and build the DOM element hierarchy.
    async getElementHierarchy(
      selector: string = 'body', 
      maxDepth: number = 3, 
      includeText: boolean = false, 
      includeAttributes: boolean = false
    ): Promise<any> {
      try {
        if (!this.isInitialized()) {
          throw new Error('Browser not initialized');
        }
        
        this.log('Getting element hierarchy', { selector, maxDepth, includeText, includeAttributes });
        
        const hierarchy = await this.state.page?.evaluate((args: {
          selector: string, 
          maxDepth: number, 
          includeText: boolean, 
          includeAttributes: boolean
        }) => {
          const { selector, maxDepth, includeText, includeAttributes } = args;
          
          function getElementInfo(element: Element) {
            const info: any = {
              tagName: element.tagName.toLowerCase(),
              id: element.id || undefined,
              className: element.className || undefined,
              children: []
            };
            
            if (includeText && element.textContent) {
              // Get only direct text content, not from children
              const directText = Array.from(element.childNodes)
                .filter(node => node.nodeType === Node.TEXT_NODE)
                .map(node => node.textContent?.trim())
                .filter(text => text)
                .join(' ');
              if (directText) {
                info.text = directText;
              }
            }
            
            if (includeAttributes && element.attributes.length > 0) {
              info.attributes = {};
              for (let i = 0; i < element.attributes.length; i++) {
                const attr = element.attributes[i];
                if (attr.name !== 'id' && attr.name !== 'class') {
                  info.attributes[attr.name] = attr.value;
                }
              }
            }
            
            return info;
          }
          
          function traverseElement(element: Element, currentDepth: number): any {
            const elementInfo = getElementInfo(element);
            
            if (currentDepth < maxDepth || maxDepth === -1) {
              const children = Array.from(element.children);
              elementInfo.children = children.map(child => 
                traverseElement(child, currentDepth + 1)
              );
            } else if (element.children.length > 0) {
              elementInfo.childrenCount = element.children.length;
            }
            
            return elementInfo;
          }
          
          const rootElement = document.querySelector(selector);
          if (!rootElement) {
            throw new Error(`Element not found: ${selector}`);
          }
          
          return traverseElement(rootElement, 0);
        }, { selector, maxDepth, includeText, includeAttributes });
        
        this.log('Element hierarchy retrieved');
        return hierarchy;
      } catch (error: any) {
        console.error('Get element hierarchy error:', error);
        throw new BrowserError('Failed to get element hierarchy', 'Check if the selector exists');
      }
    }
  • The Tool object definition including name, description, and detailed inputSchema for parameter validation in the MCP protocol.
    const GET_ELEMENT_HIERARCHY_TOOL: Tool = {
      name: "getElementHierarchy",
      description: "Get the hierarchical structure of page elements with parent-child relationships",
      inputSchema: {
        type: "object",
        properties: {
          selector: {
            type: "string",
            description: "CSS selector for root element (default: 'body')"
          },
          maxDepth: {
            type: "number",
            description: "Maximum depth to traverse (-1 for unlimited, default: 3)"
          },
          includeText: {
            type: "boolean",
            description: "Include text content of elements (default: false)"
          },
          includeAttributes: {
            type: "boolean",
            description: "Include element attributes (default: false)"
          }
        },
        required: []
      }
    };
  • src/server.ts:533-533 (registration)
    Registration of the getElementHierarchy tool in the main tools object passed to the MCP server capabilities.
    getElementHierarchy: GET_ELEMENT_HIERARCHY_TOOL,
  • src/server.ts:760-770 (registration)
    MCP server request handler (switch case) that dispatches calls to the controller's getElementHierarchy method and formats the response.
    case 'getElementHierarchy': {
      const hierarchy = await playwrightController.getElementHierarchy(
        args.selector as string || 'body',
        args.maxDepth as number || 3,
        args.includeText as boolean || false,
        args.includeAttributes as boolean || false
      );
      return {
        content: [{ type: "text", text: JSON.stringify(hierarchy, null, 2) }]
      };
    }

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/jomon003/PlayMCP'

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