MCP Server
The AudioEye MCP server (@audioeye/testing-sdk-mcp) is a Model Context Protocol
server that lets an AI coding agent run an accessibility scan against a live page and propose source-level fixes. It
drives a real browser, scans the page with the AudioEye Testing SDK, attaches the JSX source location to each issue
where it can, and exposes the results to your agent as MCP tools.
Use it with MCP-capable coding agents such as Claude Code, Cursor, VS Code, and other hosts that support the Model Context Protocol.
Before you install
Complete the client-credential and package-manager setup in getting started before installing the MCP server. The server is distributed through AudioEye's private registry and is licensed at run time, so you need both your Client ID and Client Token before it will work.
Prerequisites
You will need:
- Node.js
22or24 - an AudioEye Client ID and Client Token (see getting started)
- an MCP-capable host (for example, Claude Code)
- macOS or Linux for full file-write containment (the server also runs on Windows with best-effort containment)
Step 1: Install the server
The MCP server is installed globally rather than as a project dependency. Make sure your package manager is configured
for the @audioeye registry first (see
Step 2 of getting started).
- npm
- yarn
- pnpm
npm install -g @audioeye/testing-sdk-mcp
yarn global add @audioeye/testing-sdk-mcp
pnpm add -g @audioeye/testing-sdk-mcp
This installs the audioeye-mcp command, which your MCP host runs as the server.
Step 2: Register the server with your agent
Register audioeye-mcp with your MCP host and pass your client credentials through the server's env block. This is
the standard way MCP hosts hand secrets to a server, and it keeps the credentials out of command-line arguments (which
can be visible to other processes and leak into shell history).
- Claude Code
- Cursor / VS Code / other hosts
Register the server with the claude mcp add command — no manual JSON editing required:
claude mcp add --env AUDIOEYE_TESTING_SDK_CLIENT_ID='${AUDIOEYE_TESTING_SDK_CLIENT_ID}' --env AUDIOEYE_TESTING_SDK_CLIENT_TOKEN='${AUDIOEYE_TESTING_SDK_CLIENT_TOKEN}' --transport stdio audioeye-mcp -- npx audioeye-mcp
Note the single quotes around the ${...} values: they keep your shell from expanding them, so the literal
references — not your secrets — are written to .mcp.json. A project .mcp.json is usually committed and shared with
your team, so this matters. At launch, Claude Code's
environment-variable expansion
resolves the references from your shell environment. Export the values once (see
getting started):
export AUDIOEYE_TESTING_SDK_CLIENT_ID=your-client-id-here
export AUDIOEYE_TESTING_SDK_CLIENT_TOKEN=your-client-token-here
Most MCP hosts use the same shape — a server entry with a command and an env map. Add audioeye-mcp with your two
credentials in the env block:
{
"mcpServers": {
"audioeye-mcp": {
"command": "audioeye-mcp",
"env": {
"AUDIOEYE_TESTING_SDK_CLIENT_ID": "your-client-id-here",
"AUDIOEYE_TESTING_SDK_CLIENT_TOKEN": "your-client-token-here"
}
}
}
}
You don't have to hardcode the credentials in the env block. If AUDIOEYE_TESTING_SDK_CLIENT_ID and
AUDIOEYE_TESTING_SDK_CLIENT_TOKEN are already exported in your shell profile (~/.zshrc, ~/.bashrc, etc.) or your
CI environment, reference them with ${...} expansion instead — for example "${AUDIOEYE_TESTING_SDK_CLIENT_TOKEN}" —
which keeps the token out of committed files.
If your host does not support environment-variable expansion and you must use literal values, put the configuration in your user-level MCP settings rather than a committed project file, so the token never lands in version control.
After registering the server (or editing the configuration), reload your MCP client so it picks up the new server.
Optional: stop per-tool permission prompts
By default most hosts prompt for permission on every tool call. To allowlist AudioEye's tools in Claude Code, run:
audioeye-mcp setup # writes to ./.claude/settings.json
audioeye-mcp setup --global # or to ~/.claude/settings.json
The command is idempotent. Reload your MCP client afterward.
Step 3: Verify it works
Ask your agent to scan a page. In Claude Code you can use the bundled slash command:
/audioeye-scan https://www.audioeye.com
…or prompt the agent directly: "Use the audioeye_scan tool to scan https://www.audioeye.com and summarize the failures."
A browser window opens, the scan runs, and the agent returns grouped accessibility results. If instead the tool fails
with a license message — for example
Set AUDIOEYE_TESTING_SDK_CLIENT_ID and AUDIOEYE_TESTING_SDK_CLIENT_TOKEN to run the AudioEye testing SDK. or
The AudioEye testing SDK token is invalid or inactive. — your Client ID or Client Token did not reach the server.
Re-check the env block and that the variables are exported in the environment that launched your MCP host. See
How licensing works.
Available tools
The server exposes these tools to your agent:
audioeye_open_browser— launch (or focus) a browser window with a persistent profile, so login state survives between scans.audioeye_scan— run the accessibility scan on the current page, attach a JSX source location to each failing element where possible, and return grouped results with rule metadata.audioeye_get_rule_metadata— look up metadata for rule codes from an earlier scan.audioeye_get_source_context— read the lines around a source location from a previous scan.audioeye_get_a11y_facts— compute assistive-technology facts (accessible name, role, resolved ARIA attributes, nearest landmark) for an element on the current page.audioeye_verify_fix— re-scan after a fix and report whether the targeted failure is resolved.audioeye_close_browser— shut the browser down while preserving the profile.
Bundled slash commands
Hosts that surface MCP prompts (such as Claude Code) expose these automatically:
/audioeye-scan— scan a live URL and summarize the failures. No code edits./audioeye-fix— propose source-level fixes against an existing scan result./audioeye-scan-and-fix— the full flow: scan, summarize, propose fixes (only with your approval), and verify.
When source-level fixes are limited
The MCP server resolves a source location for failing elements in React projects running a development build. In some situations it can report a failure but cannot point to the exact line that authored it:
- Non-React projects (Vue, Svelte, Angular, plain HTML) — failures are reported without a source location.
- Production / minified builds — source mapping is limited unless your build ships source maps.
- CMS-rendered content — alt text, headings, and link names authored in a CMS live in the CMS, not your source, so the fix is a content change.
- React Server Components without
'use client'— server-rendered markup is opaque to the in-browser scan.
In these cases the scan still surfaces the issue; it just cannot always propose a code diff.
Ignoring specific issues
Real pages carry noise you can't fix at source — third-party widgets (Chargebee, Stripe, Intercom), dev-only tooling
(TanStack Router Devtools, React Query Devtools), and runtime-injected vendor iframes. You can suppress these with a
checked-in .audioeye-mcp.json at your repository root. The agent reads it on every scan and filters matching
failures out of the results before it summarizes or proposes fixes.
{
"ignore": [
{
"cssSelectorContains": "footer.TanStackRouterDevtools",
"comment": "Dev-only widget; not shipped to prod."
},
{
"ruleCode": "Iframe_Name_Missing",
"cssSelectorContains": "iframe#cb-master-frame",
"comment": "Vendor SDK iframe — vendor-owned."
},
{
"fileNameContains": "node_modules/",
"comment": "Don't try to patch dependencies."
}
]
}
Each entry under ignore is a matcher with one or more of these optional fields:
| Field | Matches when… |
|---|---|
ruleCode | the failing rule code equals this value exactly |
cssSelectorPrefix | the element's CSS selector starts with this string |
cssSelectorContains | the element's CSS selector contains this string |
fileNamePrefix | the resolved source file path starts with this string |
fileNameContains | the resolved source file path contains this string |
comment | (not a matcher) free-text note explaining why the entry exists |
An entry must specify at least one matcher field. Fields within an entry are AND'd (all must match); separate
entries are OR'd (an issue matching any entry is suppressed). Every scan response reports configPath, totalIgnored,
and per-rule hit counts, so reviewers can audit exactly what was filtered.
The agent manages this file for you: when it notices noise you repeatedly dismiss, it suggests an ignore entry — but
it treats .audioeye-mcp.json like source code and won't write to it without your approval. Because the file is checked
in, the same suppressions apply for every developer and in CI.
By default the server looks for .audioeye-mcp.json (or audioeye-mcp.config.json) by walking up from the workspace
root. Set AUDIOEYE_MCP_CONFIG_PATH to point at a config file in a non-standard location.
Troubleshooting
Scans fail with a license message
If the tool fails with
Set AUDIOEYE_TESTING_SDK_CLIENT_ID and AUDIOEYE_TESTING_SDK_CLIENT_TOKEN to run the AudioEye testing SDK. or
The AudioEye testing SDK token is invalid or inactive., the server could not verify your license. Confirm that:
- the
envblock in your MCP configuration containsAUDIOEYE_TESTING_SDK_CLIENT_IDandAUDIOEYE_TESTING_SDK_CLIENT_TOKEN - if you use
${...}expansion, those variables are exported in the environment that launched your MCP host - your Client Token has not been revoked by a refresh in the portal
See How licensing works for details on the license check and the 24-hour offline window.
The server is not listed in my agent
Reload your MCP client after editing the configuration, and confirm the audioeye-mcp command is on your PATH
(which audioeye-mcp). If the global install did not add it to your PATH, reinstall with your package manager's
global flag and reopen your terminal.
Other issues
For registry, credential, and browser-runtime problems shared with the rest of the SDK, see the main Troubleshooting guide.