Skip to main content
Glama

get-element-html

Retrieve HTML content of a specific element and its children using a CSS selector. Choose to include outer HTML or return only inner HTML for precise element inspection.

Instructions

Retrieves the HTML content of a specific element and its children

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
includeOuterNoIf true, includes the selected element's outer HTML; otherwise returns only inner HTML (default: false)
selectorYesCSS selector of the element to inspect

Implementation Reference

  • Main handler function that executes the get-element-html tool logic. Uses Playwright to evaluate JavaScript for retrieving element HTML with optional outerHTML, depth limiting, and text-only modes.
    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 schema defining input parameters for the get-element-html tool: selector (required), includeOuter (optional boolean), depth (optional integer).
    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 -->') },
  • Registration of the 'get-element-html' tool using server.tool() within the registerBrowserTools function, including description, input schema, and handler reference.
    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 }; } } );
  • Helper function getContextForOperation used by get-element-html to retrieve the active browser page context, handling contextId or defaulting to most recent.
    const getContextForOperation = (contextId?: string): BrowserStatus => { let contextInstance; if (contextId) { contextInstance = contextManager.getContext(contextId); if (!contextInstance) { return { isStarted: false, error: { content: [ { type: 'text', text: `Browser '${contextId}' not found. Use 'list-browsers' to see available browsers or 'start-browser' to create one.` } ], isError: true } }; } } else { contextInstance = contextManager.getMostRecentContext(); if (!contextInstance) { return { isStarted: false, error: { content: [ { type: 'text', text: 'No active browsers found. Use \'start-browser\' to create a browser first.' } ], isError: true } }; } } // Note: contextInstance.page is now always defined (never null) return { isStarted: true, page: contextInstance.page }; };

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