Skip to content

MCP server and Custom GPT setup

This page describes the two transports we expose for the accessible-document toolchain β€” a Custom GPT Action (OpenAPI) and a real MCP HTTP server β€” and how to wire each one up.

Both transports delegate to the same tool registry (workers/api/src/mcp/registry.ts). Adding a new capability means dropping a new module into workers/api/src/mcp/tools/ and registering its operations. Neither transport needs to change.

Tools available today (21 total)

PDF tools

Tool namePurpose
pdf_convertStart conversion of a PDF into accessible HTML + accessible PDF + PDF/UA-1 conformance report. Source can be a public URL (fileUrl) or base64-encoded bytes (fileBytes).
pdf_statusPoll progress (HTML + PDF + conformance readiness).
pdf_resultFetch all deliverables (HTML inline preview, signed download URLs, inline conformance summary).
pdf_conformanceStandalone PDF/UA-1 conformance report. Useful for ACR / VPAT flows.
pdf_getHtmlFetch the full accessible HTML (no truncation). Use before pdf_editHtml to locate the exact text to edit.
pdf_editHtmlApply find/replace edits to the HTML and automatically regenerate the accessible PDF + conformance report. Preferred remediation path for alt text, heading levels, decorative-image marking, table headers, language, link text, etc.

URL scanning tools

Tool namePurpose
url_scanStart a multi-variant axe-core + WCAG scan of a live URL (desktop, optional dark, mobile). Supports multi-page crawl via crawl block. Returns a jobId.
url_statusPoll scan progress. For crawl parents, returns aggregate page counts.
url_resultFull scan result: violations by variant, VPAT criteria + score, CMS/platform hint. For crawl parents, returns per-page summary + aggregate.
url_conformanceVPAT conformance slice only (criteria, summary, score) + platform hint.
url_getHtmlFetch the rendered HTML for one variant (desktop / dark / mobile).
url_editHtmlApply find/replace edits to the captured HTML; persists remediated copy.
url_rescanRe-enqueue the same URL after a fix is deployed.
url_getScreenshotFull-page JPEG screenshot of a scan variant (inline image on MCP; base64 JSON on OpenAPI).
url_altTextBatchBulk alt-text review: classifies every <img>, attaches AI suggestions, returns CMS-specific fix guidance.

ACR / VPAT generation tools

Tool namePurpose
acr_queueReturn WCAG criteria needing human review, with AI pre-grades (verdict + confidence + reasoning).
acr_decideRecord one verdict (supports / partial / does-not / na) on a criterion.
acr_stateOverall progress: total, auto-decided, human-decided, remaining queue.
acr_generateTwo-call protocol: collect signoff details, then compose + download signed ACR HTML + PDF.
acr_altTextReportTwo-call protocol: same as acr_generate but produces the alt-text remediation report instead of the full ACR.
acr_getScreenshotCropped per-element screenshot for a WCAG criterion in the ACR queue (inline image on MCP; base64 JSON on OpenAPI).

Custom GPT (OpenAPI Action)

Canonical endpoint base: https://api.theaccessible.org/api/gpt

Legacy endpoint https://api-pdf.theaccessible.org/api/gpt continues to work for existing PDF-only GPT installs and will not be removed. The canonical spec is now at api.theaccessible.org.

Authentication: X-API-Key: <your key> (issue from the dashboard β†’ Settings β†’ API keys).

Set up:

  1. Open https://chat.openai.com/gpts/editor, create a new GPT.
  2. Configure β†’ Actions β†’ β€œImport from URL” β†’ https://pdf.theaccessible.org/openapi.yaml (also reachable at /.well-known/openapi.yaml). Source of truth: workers/api/src/openapi/spec.ts.
  3. Authentication β†’ API Key β†’ Custom header X-API-Key.
  4. See docs/CUSTOM-GPT-PUBLICATION.md for the full system prompt covering all 21 tools.

PDF route paths

OperationMethodPath
pdf_convertPOST/convert
pdf_statusGET/status/{fileId}
pdf_resultGET/result/{fileId}
pdf_conformanceGET/conformance/{fileId}
pdf_getHtmlGET/pdf/html/{fileId} (also /html/{fileId} for compat)
pdf_editHtmlPOST/pdf/html/{fileId}/edit (also /html/{fileId}/edit for compat)

URL route paths

OperationMethodPath
url_scanPOST/url/scan
url_statusGET/url/status/{jobId}
url_resultGET/url/result/{jobId}
url_conformanceGET/url/conformance/{jobId}
url_getHtmlGET/url/html/{jobId}/{variant}
url_editHtmlPOST/url/html/{jobId}/{variant}/edit
url_rescanPOST/url/rescan/{jobId}
url_getScreenshotGET/url/screenshot/{jobId}/{variant}
url_altTextBatchPOST/url/altText/{jobId}

ACR route paths

OperationMethodPath
acr_queueGET/acr/queue/{jobId}
acr_decidePOST/acr/decide
acr_stateGET/acr/state/{jobId}
acr_generatePOST/acr/generate
acr_altTextReportPOST/acr/altTextReport
acr_getScreenshotGET/acr/screenshot/{jobId}/{criterionId}

Screenshot endpoints note

url_getScreenshot and acr_getScreenshot return the image as base64-encoded JPEG bytes in the data field of the JSON response. On the MCP transport these are additionally returned as inline MCP image content. Custom GPT Actions receive the JSON with embedded base64 β€” this is adequate for ChatGPT to render images inline.

MCP HTTP server

Endpoint: https://api.theaccessible.org/api/mcp (also accepts POST to /api/mcp/rpc).

Transport: streamable-HTTP, JSON-RPC 2.0 over POST. Methods supported: initialize, tools/list, tools/call, ping.

Auth: Authorization: Bearer <api-key>. Use the same API-key value issued for the OpenAPI route.

Discovery: GET /.well-known/oauth-protected-resource returns the resource-server metadata (no auth required).

Connecting from Claude Desktop

{
"mcpServers": {
"theaccessible": {
"url": "https://api.theaccessible.org/api/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer YOUR_API_KEY_HERE"
}
}
}
}

Quick test

Terminal window
curl -s https://api.theaccessible.org/api/mcp \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq

Legacy api-pdf.theaccessible.org endpoints

api-pdf.theaccessible.org/api/mcp and /api/gpt/* continue to work. Any existing DXT installs or GPT installs pointing at the old host keep working indefinitely. The canonical host for new installs is api.theaccessible.org.

Sending file bytes directly

For clients that have the PDF in-hand and don’t want to expose it via a public URL, pdf_convert accepts a base64-encoded fileBytes argument in place of fileUrl. Provide exactly one of the two; supplying both or neither is a 400.

// Native MCP via tools/call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "pdf_convert",
"arguments": {
"fileName": "report.pdf",
"fileBytes": "JVBERi0xLjcKJ..."
}
}
}

Adding future tools

Add a file workers/api/src/mcp/tools/new-tool.ts that:

  1. Defines its zod input schemas.
  2. Registers operations on the shared registry.
  3. Imports it from mcp/bootstrap.ts.

Then add corresponding routes to mcp/transports/openapi-routes.ts and update workers/api/src/openapi/spec.ts. The MCP transport picks the tool up automatically via tools/list.