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