Skip to main content
Glama

a11y-toolkit: Keyboard-trap detector

a11y_keyboard
Read-onlyIdempotent

Detects WCAG 2.1.2 keyboard traps by Tab-walking real focus stops in Chromium, testing Escape release for modal cycles, and returning tab stops plus findings.

Instructions

Keyboard-trap detection (2.1.2) with REAL Tab walking in Chromium: up to 60 real tab stops, cycle detection (the modal pattern), then the decisive test — does ESCAPE release the cycle? A modal that cycles and releases on Escape is correct and NOT reported; a cycle Escape cannot leave is a trap (high severity). Returns the full tab stop list too. Requires local Playwright. — Scope: keyboard traps (2.1.2); focus visibility is part of a11y_audit_dom. Returns JSON: {tab_stops, trap_detected, escape_releases, findings}. Run on pages with modals, dialogs or embedded apps; a plain content page has nothing to trap.

Input Schema

NameRequiredDescriptionDefault
urlYesPage URL to Tab-walk (http/https or file://)
langNoOutput language (default en)
browserNoBrowser engine (auto = detect the first available)
max_stepsNomax real Tab presses (60 default)
auth_stateNoPath to a Playwright storage_state JSON (exported session) to Tab-walk behind login

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changedv5.14.0
    • removedInput schema / properties / max_pasos
      Removed value: -{
      -  "description": "max real Tab presses (60 default)",
      -  "type": "integer"
      -}
    • addedInput schema / properties / max_steps
      Added value: +{
      +  "description": "max real Tab presses (60 default)",
      +  "type": "integer"
      +}
  2. Changed1 schema field changedv5.6.0
    • removedInput schema / browser
      Removed value: -{
      -  "description": "Browser engine (auto = detect the first available)",
      -  "enum": [
      -    "auto",
      -    "chromium",
      -    "firefox",
      -    "webkit",
      -    "chrome",
      -    "msedge"
      -  ],
      -  "type": "string"
      -}
  3. Changed1 schema field changedv5.5.0
    • addedInput schema / properties / browser
      Added value: +{
      +  "description": "Browser engine (auto = detect the first available)",
      +  "enum": [
      +    "auto",
      +    "chromium",
      +    "firefox",
      +    "webkit",
      +    "chrome",
      +    "msedge"
      +  ],
      +  "type": "string"
      +}
  4. Changed4 schema fields changedv4.0.0
    • addedInput schema / browser
      Added value: +{
      +  "description": "Browser engine (auto = detect the first available)",
      +  "enum": [
      +    "auto",
      +    "chromium",
      +    "firefox",
      +    "webkit",
      +    "chrome",
      +    "msedge"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / auth_state
      Added value: +{
      +  "description": "Path to a Playwright storage_state JSON (exported session) to Tab-walk behind login",
      +  "type": "string"
      +}
    • addedInput schema / properties / lang / description
      Added value: +"Output language (default en)"
    • addedInput schema / properties / url / description
      Added value: +"Page URL to Tab-walk (http/https or file://)"
  5. Addedv3.3.0

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), yet the description adds substantive runtime context: requires local Playwright, a 60 tab-stop ceiling, and the exact trap-vs-modal decision rule. It also previews the return payload keys, which is more than the annotations give.

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

Conciseness4/5

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

Front-loaded with the criterion number and capability, then the decision rule, then scope. Dense and mostly earning its space, though phrases like 'the decisive test' add dramatic flourish that could be trimmed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-param open-world tool with no output schema, the description supplies the prerequisite (local Playwright), the scope boundary against a sibling, the severity model, and the return shape. An agent has everything needed to decide whether to call it and how to interpret the result.

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 coverage is 100%, so every parameter including url, lang, browser, max_steps and auth_state is already documented. The description mentions Chromium and the 60-stop bound, but that largely restates the schema's own 'max real Tab presses (60 default)' and browser engine entries. Baseline 3 applies 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?

States a specific verb+resource (keyboard-trap detection / 2.1.2) plus the mechanism (real Tab walking in Chromium) and the decisive discriminator (Escape releases the cycle). It also names the bound: focus visibility belongs to a11y_audit_dom, so an agent can separate it from that sibling without opening either schema.

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

Usage Guidelines5/5

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

Gives explicit when-to-use (pages with modals, dialogs or embedded apps) and an explicit when-not (a plain content page has nothing to trap), plus the sibling routing for the adjacent concern. It also states the not-a-bug case — a cycle that Escape releases is correct and NOT reported — which prevents false-positive chasing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.