Skip to main content
Glama
yashpreetbathla

MCP Accessibility Bridge

Get Element Properties

get_element_properties

Retrieve accessibility properties and generate multi-framework test selectors for web elements using CSS selectors to support testing and accessibility audits.

Instructions

Given a CSS selector, returns the element's full accessibility properties and multi-framework test selectors (Playwright, Selenium, Cypress, WebdriverIO). Selectors are prioritized: data-testid > stable id > ARIA role > semantic CSS.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
selectorYesCSS selector to identify the element (e.g. "input[type=search]", "#submit-btn").
includeHtmlNoInclude the outer HTML of the element. Default: false

Implementation Reference

  • Main implementation of get_element_properties tool. Finds element via CSS selector, retrieves DOM node info via CDP, gets accessibility tree data, and returns element properties including suggested multi-framework selectors.
    export async function getElementPropertiesHandler(args: {
      selector: string;
      includeHtml?: boolean;
    }): Promise<ReturnType<typeof toolSuccess | typeof toolError>> {
      try {
        const { page, cdpSession } = browserManager.requireConnection();
    
        // 1. Find the element via CSS selector
        const element = await page.$(args.selector);
        if (!element) {
          return toolError(
            `No element found matching selector: "${args.selector}"`
          );
        }
    
        // 2. Get the backend node ID via DOM.describeNode
        const nodeInfo = element.remoteObject();
        const describeResult = await cdpSession.send('DOM.describeNode', {
          objectId: nodeInfo.objectId,
          depth: 0,
        }) as DomDescribeNodeResponse;
    
        const domNode = describeResult.node;
        const backendNodeId = domNode.backendNodeId;
        const tagName = domNode.localName;
        const rawAttributes = domNode.attributes;
    
        // 3. Get the accessibility tree for this specific node
        const axResult = await cdpSession.send('Accessibility.getPartialAXTree', {
          backendNodeId,
          fetchRelatives: false,
        }) as GetPartialAXTreeResponse;
    
        const axNodes = axResult.nodes ?? [];
        const primaryAXNode = axNodes.find((n) => !n.ignored) ?? axNodes[0];
    
        let axSummary = null;
        let suggestedSelectors = null;
    
        if (primaryAXNode) {
          axSummary = cdpAXNodeToSummary(primaryAXNode);
          const name = (primaryAXNode.name?.value as string) ?? '';
          const role = (primaryAXNode.role?.value as string) ?? '';
          suggestedSelectors = buildSelectorFromRawNode(name, role, tagName, rawAttributes);
        }
    
        // 4. Optionally get outer HTML
        let outerHTML: string | undefined;
        if (args.includeHtml) {
          try {
            const htmlResult = await cdpSession.send('DOM.getOuterHTML', {
              backendNodeId,
            }) as DomGetOuterHtmlResponse;
            outerHTML = htmlResult.outerHTML;
          } catch {
            outerHTML = undefined;
          }
        }
    
        return toolSuccess({
          selector: args.selector,
          tagName,
          domAttributes: parseAttributes(rawAttributes),
          backendNodeId,
          accessibility: axSummary,
          suggestedSelectors,
          ...(outerHTML !== undefined && { outerHTML }),
        });
      } catch (error) {
        return toolError(error);
      }
    }
  • Zod schema defining the input parameters for get_element_properties: selector (required CSS selector string) and includeHtml (optional boolean, defaults to false).
    export const getElementPropertiesSchema = {
      selector: z
        .string()
        .describe('CSS selector to identify the element (e.g. "input[type=search]", "#submit-btn").'),
      includeHtml: z
        .boolean()
        .optional()
        .default(false)
        .describe('Include the outer HTML of the element. Default: false'),
    };
  • src/index.ts:90-102 (registration)
    Tool registration in the MCP server that connects 'get_element_properties' tool name with its schema and handler, including title and description.
    // ── get_element_properties ───────────────────────────────────────────────────
    server.registerTool(
      'get_element_properties',
      {
        title: 'Get Element Properties',
        description:
          'Given a CSS selector, returns the element\'s full accessibility properties ' +
          'and multi-framework test selectors (Playwright, Selenium, Cypress, WebdriverIO). ' +
          'Selectors are prioritized: data-testid > stable id > ARIA role > semantic CSS.',
        inputSchema: getElementPropertiesSchema,
      },
      getElementPropertiesHandler
    );
  • Helper utility function that parses DOM attributes from a flat array into a key-value object map.
    function parseAttributes(attrs: string[] | undefined): Record<string, string> {
      const map: Record<string, string> = {};
      if (!attrs) return map;
      for (let i = 0; i + 1 < attrs.length; i += 2) {
        map[attrs[i]] = attrs[i + 1];
      }
      return map;
    }
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. It discloses the return content (accessibility properties and test selectors) and selector prioritization behavior, which is valuable. However, it doesn't mention potential errors (e.g., if selector finds no element), performance characteristics, or authentication needs, leaving gaps for a tool with no annotation coverage.

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

Conciseness5/5

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

The description is a single, well-structured sentence that efficiently conveys the tool's purpose, output, and key behavioral detail (selector prioritization). Every part earns its place with no wasted words, making it easy to parse and front-loaded with essential information.

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?

Given no annotations and no output schema, the description provides good coverage of what the tool returns and its selector behavior. However, for a tool that interacts with a browser (implied by sibling tools), it lacks context on dependencies (e.g., requires an active browser session), error handling, or output format details, which could hinder an agent's ability to use it correctly.

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?

Schema description coverage is 100%, so the schema fully documents both parameters. The description doesn't add any parameter-specific information beyond what's in the schema (e.g., it doesn't explain selector syntax further or clarify 'includeHtml' implications). Baseline 3 is appropriate when the schema does the heavy lifting.

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 specific action ('returns') and the exact resources ('element's full accessibility properties and multi-framework test selectors'), naming four specific frameworks. It distinguishes from siblings like 'get_accessibility_tree' by focusing on a single element's properties rather than the entire tree.

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

Usage Guidelines3/5

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

The description implies usage by specifying 'Given a CSS selector' and mentions selector prioritization, which provides some context. However, it lacks explicit guidance on when to use this tool versus alternatives like 'get_focused_element' or 'get_interactive_elements', and doesn't state any exclusions or prerequisites.

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/yashpreetbathla/mcp-accessibility-bridge'

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