MCP connection
Connect an AI assistant (Claude and others) to accessible-PDF auditing and conversion. A single endpoint, authenticated with your API key.
Prefer to integrate from your own code? The same operations are available in the REST API.
Connection
The server implements Model Context Protocol over HTTP ("streamable HTTP"): a single endpoint that takes JSON-RPC 2.0 messages by POST. It is stateless: it issues no Mcp-Session-Id and the credential travels with every request.
https://pdfaccesible.com/mcphttp (JSON-RPC 2.0, POST)2025-06-18, 2025-03-26, 2024-11-05toolsAdd to Claude Code
claude mcp add --transport http pdfaccesible https://pdfaccesible.com/mcp \
--header "Authorization: Bearer YOUR_API_KEY"
Add to Claude Desktop or other clients
{
"mcpServers": {
"pdfaccesible": {
"type": "http",
"url": "https://pdfaccesible.com/mcp",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}
Supported JSON-RPC methods
| Method | What it does |
|---|---|
initialize | Negotiates the protocol version and returns capabilities, server details and usage instructions. |
notifications/initialized | Client notification once start-up finishes (replies 202 with no body). |
ping | Liveness check. |
tools/list | Catalogue of tools with their input schema. |
tools/call | Runs a tool (name + arguments). |
resources/list · prompts/list | Return empty lists: this server only exposes tools. |
curl example
curl -X POST https://pdfaccesible.com/mcp \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
How it works
Processing takes from seconds to several minutes, so the tools do not block: you request the work first, then check on it or wait for the result.
- The assistant calls
audit_document(report, free) orconvert_document(produces the accessible PDF/A, uses plan quota), with the file or its URL. - The tool answers immediately with the document
id; the server processes it in the background. - With that id,
wait_for_documentwaits until it finishes (the server does the polling) orget_document_statuschecks the progress. - Once finished,
get_document_reportreturns the report anddownload_documentthe PDF/A.
The id has the form YYYYMMDD-HHMMSS-xxxxxx and is the same identifier you see in your customer area.
Authentication
Plan requirement: the API and MCP are included from the Business plan upwards. On a lower plan you cannot create credentials and calls return 403 plan_required. See plans.
Every request carries your API key in the Authorization: Bearer … header; there is no session and no cookies. Create it in My account → API credentials; the details (alternative headers, good practice) are in the API reference.
Authorization: Bearer pdfa_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Rate limits, plan quotas and document retention are the same over MCP as over REST: see them in the API reference.
MCP tools
These are the 9 tools returned by tools/list, exactly as the server publishes them.
The API contract (tools, arguments, response fields and error codes) is in English: a machine consumes it. This table is what the server itself publishes in tools/list.
audit_document · Audit a PDF
Runs an accessibility AUDIT of a PDF against WCAG 2.1/2.2, PDF/UA (ISO 14289) and the European Accessibility Act (Directive (EU) 2019/882). Does not modify the document and does not consume conversion quota. Send a new file (file_base64 or file_url) or an existing document_id. Returns a document id immediately: the work runs in the BACKGROUND, so poll it with get_document_status or block with wait_for_document.
REST equivalent: POST /api/v1/documents (type=audit) · POST /api/v1/documents/{id}/audit
| Argument | Type | Required | Description |
|---|---|---|---|
file_base64 |
string | no | The PDF encoded in base64. Use this, "file_url" or "document_id" (exactly one). |
file_url |
string | no | Public http(s) URL to download the PDF from. Alternative to "file_base64". |
filename |
string | no | Original file name, e.g. "annual-report-2026.pdf". Optional but recommended. |
document_id |
string | no | Process a document that is ALREADY in the account instead of uploading a new file (no need to send the bytes again). |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "audit_document",
"arguments": {
"filename": "annual-report-2026.pdf",
"file_base64": "JVBERi0xLjQK…"
}
}
}
convert_document · Convert a PDF to accessible PDF/A
CONVERTS a PDF into a tagged, accessible PDF/A (PDF/A-2b + PDF/UA-1: semantic structure, reading order, language, metadata and AI-generated alternative text for images). Consumes the plan quota. Send a new file (file_base64 or file_url) or an existing document_id; with document_id it is idempotent — if the document already has an accessible PDF/A, or a conversion is already running, no duplicate work is queued. Runs in the BACKGROUND: use wait_for_document and then download_document.
REST equivalent: POST /api/v1/documents (type=conversion) · PUT /api/v1/documents/{id}/conversion
| Argument | Type | Required | Description |
|---|---|---|---|
file_base64 |
string | no | The PDF encoded in base64. Use this, "file_url" or "document_id" (exactly one). |
file_url |
string | no | Public http(s) URL to download the PDF from. Alternative to "file_base64". |
filename |
string | no | Original file name, e.g. "annual-report-2026.pdf". Optional but recommended. |
document_id |
string | no | Process a document that is ALREADY in the account instead of uploading a new file (no need to send the bytes again). |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "convert_document",
"arguments": {
"filename": "annual-report-2026.pdf",
"file_url": "https://pdfaccesible.com/samples/annual-report-2026.pdf"
}
}
}
get_document_status · Get processing status
Current state of a document: status (queued, processing, done, error), progress percentage, current step and, once finished, the accessibility score, the per-standard breakdown and the download links.
REST equivalent: GET /api/v1/documents/{id}
| Argument | Type | Required | Description |
|---|---|---|---|
document_id |
string | yes | Document id returned when the document was submitted (format YYYYMMDD-HHMMSS-xxxxxx). |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_document_status",
"arguments": {
"document_id": "20260730-120501-a1b2c3"
}
}
}
wait_for_document · Wait until processing finishes
Waits (polling on the server) until the document finishes processing or the timeout elapses, then returns the final status. Saves calling get_document_status in a loop. An audit usually takes 10-60 s; an AI-assisted conversion, 1-5 min. On timeout it returns the current status with a warning instead of an error, so you can simply call it again.
REST equivalent: — (server-side polling; no REST equivalent)
| Argument | Type | Required | Description |
|---|---|---|---|
document_id |
string | yes | Document id returned when the document was submitted (format YYYYMMDD-HHMMSS-xxxxxx). |
timeout_seconds |
integer default: 60 |
no | Maximum time to wait, 5-240 seconds. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "wait_for_document",
"arguments": {
"document_id": "20260730-120501-a1b2c3",
"timeout_seconds": 120
}
}
}
get_document_report · Get the accessibility report
Full report: overall score (the mean of WCAG, PDF/UA and EAA), score per standard and findings with severity and normative reference. If the document was converted, it also includes the result measured on the generated PDF/A and the score improvement.
REST equivalent: GET /api/v1/documents/{id}/report
| Argument | Type | Required | Description |
|---|---|---|---|
document_id |
string | yes | Document id returned when the document was submitted (format YYYYMMDD-HHMMSS-xxxxxx). |
include_findings |
boolean default: true |
no | false = scores and verdicts only, without the list of findings. |
max_findings |
integer default: 15 |
no | Maximum findings per standard (0 = all). Keeps long reports from flooding the conversation; the response reports how many were omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_document_report",
"arguments": {
"document_id": "20260730-120501-a1b2c3",
"max_findings": 10
}
}
}
download_document · Download the PDF
Returns one of the two PDFs of the document: "pdfa" (the generated accessible version) or "original". By default it returns an authenticated download link; with delivery="base64" the file is embedded in the response (only advisable for small files).
REST equivalent: GET /api/v1/documents/{id}/file/{original|pdfa}
| Argument | Type | Required | Description |
|---|---|---|---|
document_id |
string | yes | Document id returned when the document was submitted (format YYYYMMDD-HHMMSS-xxxxxx). |
file |
string (pdfa | original) default: 'pdfa' |
no | Which of the two PDFs of the document. |
delivery |
string (link | base64) default: 'link' |
no | link = authenticated URL (recommended); base64 = embedded content. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "download_document",
"arguments": {
"document_id": "20260730-120501-a1b2c3",
"file": "pdfa",
"delivery": "link"
}
}
}
list_documents · List documents
Lists the documents of the account, newest first, with optional filters by type (audit / conversion) and status, and pagination.
REST equivalent: GET /api/v1/documents
| Argument | Type | Required | Description |
|---|---|---|---|
page |
integer default: 1 |
no | |
per_page |
integer default: 20 |
no | |
type |
string (audit | conversion) | no | Optional filter. |
status |
string (queued | processing | done | error) | no | Optional filter. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_documents",
"arguments": {
"status": "done",
"per_page": 10
}
}
}
delete_document · Delete a document
Permanently deletes a document from the account: the original PDF, the generated PDF/A and the report. Cannot be undone. Documents are deleted automatically after 30 days anyway.
REST equivalent: DELETE /api/v1/documents/{id}
| Argument | Type | Required | Description |
|---|---|---|---|
document_id |
string | yes | Document id returned when the document was submitted (format YYYYMMDD-HHMMSS-xxxxxx). |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "delete_document",
"arguments": {
"document_id": "20260730-120501-a1b2c3"
}
}
}
get_account · Get plan, limits and usage
Subscribed plan, limits (maximum size per document, conversions per month, request rate) and usage for the current month, including how many free conversions are left. Worth checking before processing a batch of documents.
REST equivalent: GET /api/v1/account
No arguments.
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_account",
"arguments": {}
}
}
Errors
Business errors (quota used up, unknown id, invalid PDF) come back as a tool result with isError: true and a JSON {"error":{"code":…,"message":…}}, so the assistant can read them and correct course. Protocol errors (invalid credential, unknown method, rate limit) arrive as a JSON-RPC error.
The full table of codes (quota_exceeded, not_found…) is in the API reference.