MCP server
The Accessibility Company exposes a Model Context Protocol (MCP) endpoint so AI coding agents can:
- read your open accessibility issues,
- fetch the selector / failing HTML for a specific issue,
- mark issues as in progress or as inspected-and-dismissed (false positive / by design),
- and verify a fix against one URL in under 30 seconds.
The server is hosted at mcp.theaccessibility.company and speaks the
MCP spec version 2025-03-26
over Streamable HTTP.
Compatible clients: Cursor, Claude Code, Codex CLI, and Factory Droid.
1 — Create a token
Section titled “1 — Create a token”Sign in to the dashboard and open Settings → Integrations → MCP tokens. Click Create token and choose:
| Field | Recommendation |
|---|---|
| Name | Something descriptive — e.g. My laptop / Cursor or CI bot. |
| Scope | Read-only to start. Upgrade to Read + write once you’re sure you want the agent marking issues / running verify scans. |
| Site scope | Account-wide for general use; pick a site if the agent should only see one project. |
| Expiry | Leave blank, or set 30–90 days for laptop tokens you want to rotate. |
Tokens begin with the prefix tac_mcp_ and are 32 hex characters of
entropy. They are shown exactly once — copy the token from the
success dialog and paste it into your MCP client immediately.
Only owners and admins can manage MCP tokens.
2 — Wire the token into your client
Section titled “2 — Wire the token into your client”The token goes in the Authorization header as
Bearer tac_mcp_<your-32-hex>. Each client formats this slightly
differently.
Cursor
Section titled “Cursor”// .cursor/mcp.json (project) or ~/.cursor/mcp.json (global){ "mcpServers": { "tac": { "url": "https://mcp.theaccessibility.company/mcp", "headers": { "Authorization": "Bearer tac_mcp_..." } } }}Claude Code
Section titled “Claude Code”claude mcp add --transport http tac \ https://mcp.theaccessibility.company/mcp \ --header "Authorization: Bearer tac_mcp_..."Codex CLI
Section titled “Codex CLI”[mcp_servers.tac]url = "https://mcp.theaccessibility.company/mcp"headers = { Authorization = "Bearer tac_mcp_..." }Factory Droid
Section titled “Factory Droid”droid mcp add tac https://mcp.theaccessibility.company/mcp \ --type http \ --header "Authorization: Bearer tac_mcp_..."After adding the server, restart your agent so it re-runs
initialize + tools/list.
3 — Available tools
Section titled “3 — Available tools”| Tool | Scope | What it does |
|---|---|---|
tac.listSites | read | Sites in the account (or just the one if site-scoped) with open / critical / serious issue counts. |
tac.listOpenIssues | read | Ranked list of actionable issues. Filters: siteId, ruleId, minImpact, limit, offset. |
tac.getIssueWithFixContext | read | One issue + rule help URL + representative finding (selector, HTML snippet, failure summary) + affected pages + verify hint + agent memory. aiContext carries any dashboard-generated AI summary and before/after fix suggestion; findingsLimit > 0 adds every occurrence’s selector + snippet for template bugs. |
tac.getDecisions | read | The workspace’s accumulated judgement: active ignore ledger + recently-reported fixes. Read this first. |
tac.getComplianceChecklist | read | Per-criterion WCAG checklist state (combined auto + human verdicts) with a progress rollup. Filter by status to pull just failing / needs-review rows. |
tac.markIssueInProgress | write | Flip status to in_progress and record an optional note on the activity timeline. |
tac.markIssueFixed | write | Flip status to fixed_pending_verification after a fix lands (ideally after a passing verify). Only a full re-scan moves an issue to verified — agents can never self-certify. |
tac.markIssueIgnored | write | Persist an issue-level ignore on rule_id + selector_pattern. Reason required; expiry capped at one year out. |
tac.verifyFixAtUrl | write | Run one synchronous scan and return the identity-hash delta + whether the issue’s rule still fires. Rate limited to 10/min/token. |
tac.* tools all return structured JSON results inside an MCP
tools/call envelope. Error codes follow the dispatch contract
(MISSING_TOKEN, INSUFFICIENT_SCOPE, SITE_SCOPE_MISMATCH,
NOT_FOUND, INVALID_INPUT, RATE_LIMITED, INTERNAL_ERROR).
Prompts
Section titled “Prompts”The server also exposes MCP prompts — invoke them from your client’s prompt picker:
| Prompt | Arguments | What it does |
|---|---|---|
fix-next-issue | siteId?, issueKey? | Runs the full remediation loop: decisions → pick issue → fix context → code change → verify → record the fix with provenance. |
compliance-status-report | siteId | Read-only: gathers checklist + open-issue data and writes a grounded compliance posture report. |
4 — Security model
Section titled “4 — Security model”The server enforces defence in depth:
- Transport. TLS terminated at the Cloudflare edge.
- Authentication. Every JSON-RPC
tools/callmust include a validAuthorization: Bearer tac_mcp_<32hex>header. The token is hashed with SHA-256 and looked up server-side; plaintext is never stored. - Site scope. Tokens may be locked to a single site; any tool call
that references a different site returns
SITE_SCOPE_MISMATCH. For tools that don’t take asiteId, the site is resolved from the issue record and the check is enforced server-side. - Account isolation. All reads are scoped to your account; cross-account leakage is structurally impossible.
- URL guards (verifyFixAtUrl). URLs must be
http(s), their hostname must match the site’s base hostname, and private / loopback / link-local addresses are rejected outright. - Scope checks. Each tool declares required scopes; tokens lacking
the scope return
INSUFFICIENT_SCOPE. - Audit log. Every successful tool call writes an audit event with the actor, the tool name, the redacted input, and the token id.
- Owner/admin token creation. Only account owners and admins can mint MCP tokens.
Token rotation from Settings → Integrations is immediate — revoked tokens fail within ~100 ms.
5 — The verify-fix loop
Section titled “5 — The verify-fix loop”The packaged fix-next-issue MCP prompt runs this loop for you; the
manual version using the tools directly:
tac.getDecisions— respect prior by-design / false-positive / wont-fix decisions before doing anything.tac.listOpenIssues— pick the highest-priority issue.tac.getIssueWithFixContext({ issueKey })— read the rule help URL, the representative finding’s selector + HTML snippet, the failing pages, and anyaiContextfix suggestion.tac.markIssueInProgress({ issueKey, note })— flip status.- Write the fix.
tac.verifyFixAtUrl({ issueKey })against one affected URL.- Inspect
expectedFixedSummary.persists:false— the rule no longer fires; calltac.markIssueFixed({ issueKey, fixedBy })with PR / commit provenance and hand off for the full-site re-scan.true— the fix didn’t take; iterate from step 5.
A full-site re-scan is still required to clear all affected pages — kick that off from the dashboard once the representative URL is clean.
6 — Troubleshooting
Section titled “6 — Troubleshooting”| Symptom | Likely cause | Fix |
|---|---|---|
MISSING_TOKEN | The client is calling /mcp without the Authorization header. | Re-check the client config snippet. Many clients require restart after editing the file. |
MALFORMED_TOKEN | Token doesn’t begin with tac_mcp_ or is the wrong length. | You probably pasted a webhook token by mistake. Mint a fresh MCP token from Settings → Integrations. |
TOKEN_REVOKED / TOKEN_EXPIRED | Self-explanatory. | Mint a new token. |
SITE_SCOPE_MISMATCH | Token is locked to one site, but the tool call referenced another site. | Either retarget the call to the locked site, or mint an account-wide token. |
RATE_LIMITED | verifyFixAtUrl token has hit 10 calls / minute. | Wait — the limit resets on a sliding window. Don’t loop on failed verifies. |
/mcp returns 405 on GET | Expected. v1 is Streamable HTTP only. | Use a client that supports Streamable HTTP (all four clients above do). |
7 — Privacy
Section titled “7 — Privacy”Tool inputs are persisted to the audit log for traceability. Long URLs (>256 chars) and long reason strings (>512 chars) are truncated server-side before logging. Token plaintext is never stored or logged — only the SHA-256 hash and the eight-char prefix.