Skip to main content
Glama

get-element-html

Retrieve HTML content of web elements using CSS selectors with configurable depth control for inspecting DOM structure during development.

Instructions

Retrieves the HTML content of a specific element and its children with optional depth control

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
selectorYesCSS selector of the element to inspect
includeOuterNoIf true, includes the selected element's outer HTML; otherwise returns only inner HTML (default: false)
depthNoControl HTML depth limit: -1 = unlimited (default), 0 = text only, 1+ = limited depth with deeper elements shown as <!-- omitted -->

Implementation Reference

  • The handler function that executes the tool logic: waits for the element, evaluates JavaScript to extract HTML (inner/outer) with optional depth limiting using DOM cloning and trimming, constructs response with metadata and HTML content.
    async ({ selector, includeOuter = false, depth = -1 }) => {
      try {
        // Check browser status
        const browserStatus = getContextForOperation();
        if (!browserStatus.isStarted) {
          return browserStatus.error;
        }
    
        // Check if element exists
        await browserStatus.page.waitForSelector(selector, { state: 'visible', timeout: 5000 });
    
        // Get element's HTML content with depth control
        const htmlContent = await browserStatus.page.evaluate(({ selector, includeOuter, depth }: { selector: string; includeOuter: boolean; depth: number }) => {
          const element = document.querySelector(selector);
          if (!element) return null;
          
          // Handle unlimited depth (backward compatibility)
          if (depth === -1) {
            return includeOuter ? element.outerHTML : element.innerHTML;
          }
          
          // Handle text-only mode
          if (depth === 0) {
            return element.textContent || '';
          }
          
          // Handle depth-limited mode with DOM cloning
          const cloned = element.cloneNode(true) as Element;
          
          function trimDepth(node: Element, currentDepth: number) {
            if (currentDepth >= depth) {
              // Replace content with omitted marker
              node.innerHTML = '<!-- omitted -->';
              return;
            }
            
            // Process child elements
            Array.from(node.children).forEach(child => {
              trimDepth(child, currentDepth + 1);
            });
          }
          
          // Start depth counting from appropriate level
          trimDepth(cloned, includeOuter ? 0 : 1);
          
          return includeOuter ? cloned.outerHTML : cloned.innerHTML;
        }, { selector, includeOuter, depth });
    
        if (htmlContent === null) {
          return {
            content: [
              {
                type: 'text',
                text: `Element with selector "${selector}" not found`
              }
            ],
            isError: true
          };
        }
    
        // Result message construction
        const resultMessage = {
          selector,
          htmlType: depth === 0 ? 'textContent' : (includeOuter ? 'outerHTML' : 'innerHTML'),
          depth,
          depthLimited: depth !== -1,
          length: htmlContent.length,
          checkpointId: await getCurrentCheckpointId(browserStatus.page)
        };
    
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(resultMessage, null, 2)
            },
            {
              type: 'text',
              text: htmlContent
            }
          ]
        };
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        Logger.error(`Failed to get element HTML: ${errorMessage}`);
        return {
          content: [
            {
              type: 'text',
              text: `Failed to get element HTML: ${errorMessage}`
            }
          ],
          isError: true
        };
      }
    }
  • Zod input schema defining parameters for the get-element-html tool: selector (required), includeOuter (optional boolean), depth (optional integer >= -1).
      selector: z.string().describe('CSS selector of the element to inspect'),
      includeOuter: z.boolean().optional().describe("If true, includes the selected element's outer HTML; otherwise returns only inner HTML (default: false)"),
      depth: z.number().int().min(-1).optional().describe('Control HTML depth limit: -1 = unlimited (default), 0 = text only, 1+ = limited depth with deeper elements shown as <!-- omitted -->')
    },
  • Direct registration of the 'get-element-html' tool using server.tool(), including description, input schema, and handler function.
    server.tool(
      'get-element-html',
      'Retrieves the HTML content of a specific element and its children with optional depth control',
      {
        selector: z.string().describe('CSS selector of the element to inspect'),
        includeOuter: z.boolean().optional().describe("If true, includes the selected element's outer HTML; otherwise returns only inner HTML (default: false)"),
        depth: z.number().int().min(-1).optional().describe('Control HTML depth limit: -1 = unlimited (default), 0 = text only, 1+ = limited depth with deeper elements shown as <!-- omitted -->')
      },
      async ({ selector, includeOuter = false, depth = -1 }) => {
        try {
          // Check browser status
          const browserStatus = getContextForOperation();
          if (!browserStatus.isStarted) {
            return browserStatus.error;
          }
    
          // Check if element exists
          await browserStatus.page.waitForSelector(selector, { state: 'visible', timeout: 5000 });
    
          // Get element's HTML content with depth control
          const htmlContent = await browserStatus.page.evaluate(({ selector, includeOuter, depth }: { selector: string; includeOuter: boolean; depth: number }) => {
            const element = document.querySelector(selector);
            if (!element) return null;
            
            // Handle unlimited depth (backward compatibility)
            if (depth === -1) {
              return includeOuter ? element.outerHTML : element.innerHTML;
            }
            
            // Handle text-only mode
            if (depth === 0) {
              return element.textContent || '';
            }
            
            // Handle depth-limited mode with DOM cloning
            const cloned = element.cloneNode(true) as Element;
            
            function trimDepth(node: Element, currentDepth: number) {
              if (currentDepth >= depth) {
                // Replace content with omitted marker
                node.innerHTML = '<!-- omitted -->';
                return;
              }
              
              // Process child elements
              Array.from(node.children).forEach(child => {
                trimDepth(child, currentDepth + 1);
              });
            }
            
            // Start depth counting from appropriate level
            trimDepth(cloned, includeOuter ? 0 : 1);
            
            return includeOuter ? cloned.outerHTML : cloned.innerHTML;
          }, { selector, includeOuter, depth });
    
          if (htmlContent === null) {
            return {
              content: [
                {
                  type: 'text',
                  text: `Element with selector "${selector}" not found`
                }
              ],
              isError: true
            };
          }
    
          // Result message construction
          const resultMessage = {
            selector,
            htmlType: depth === 0 ? 'textContent' : (includeOuter ? 'outerHTML' : 'innerHTML'),
            depth,
            depthLimited: depth !== -1,
            length: htmlContent.length,
            checkpointId: await getCurrentCheckpointId(browserStatus.page)
          };
    
          return {
            content: [
              {
                type: 'text',
                text: JSON.stringify(resultMessage, null, 2)
              },
              {
                type: 'text',
                text: htmlContent
              }
            ]
          };
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : String(error);
          Logger.error(`Failed to get element HTML: ${errorMessage}`);
          return {
            content: [
              {
                type: 'text',
                text: `Failed to get element HTML: ${errorMessage}`
              }
            ],
            isError: true
          };
        }
      }
    );
  • src/index.ts:87-92 (registration)
    Top-level call to registerBrowserTools which includes the registration of get-element-html among other browser tools.
    registerBrowserTools(
      server,
      contextManager,
      lastHMREvents,
      screenshotHelpers
    );

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/ESnark/blowback'

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