MCP server providing tools for PDF accessibility enhancement, including LaTeX processing, figure extraction, AI-powered alt-text generation, PDF structure tagging, and veraPDF validation for PDF/UA and PDF/A compliance.
This server has 10 tools with mostly complete schemas and descriptions, but exhibits several critical gaps that prevent it from reaching higher tiers. All tools have descriptions and input schemas visible in src/mcp_server.py. However, 3 tools (generate_alt_text, extract_figures, add_latex_alt_text) have inconsistent parameter descriptions or missing required field guidance. Output schemas are entirely undocumented, no tool specifies what structure it returns. Error handling is present but generic (no recovery guidance). The tool names are well-chosen (verb_noun pattern), but descriptions average ~130 chars, which is acceptable but could be more LLM-optimized. Parameters lack consistency: some have enums/defaults, others are free-form strings inviting hallucination. The server exposes file paths as strings, which is appropriate for a file-processing domain, but path validation and resolution logic is in http_server.py, not in tool descriptions. Critical missing element: NO documented output schemas.
Add alt-text to a specific figure in the PDF and save the result.
Add alt-text to figures in a LaTeX file. Updates \includegraphics commands with [alt=...] parameter.
Add accessibility preamble to a LaTeX file. Injects hyperref, axessibility, and PDF metadata packages.
Add basic structure tags to an untagged PDF. Creates document structure tree with document role.
Analyze a LaTeX file for accessibility features. Checks for hyperref, axessibility package, preamble settings, figures, and PDF metadata fields.
Analyze a PDF for accessibility status. Returns info about tags, structure, figures, and existing alt-text.
Extract all figures/images from a PDF. Returns figure metadata and can optionally save images to disk.
NO OUTPUT SCHEMAS DOCUMENTED. Zero tools specify what structure they return. This is a critical gap forcing LLMs to guess what fields exist in responses.
generate_alt_text has NO required parameters (all optional via empty 'required' array). At least one of 'image_path' or 'image_base64' must be provided, but schema does not enforce this. LLMs may call with no arguments and receive unclear errors.
generate_alt_text parameter descriptions lack actionable constraints. 'image_base64' is described as 'Base64-encoded image data (alternative to image_path)' but does not specify: (a) no maximum size documented, (b) image format restrictions not stated, (c) mutual exclusivity not formally declared in schema.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 57 | <=2025-11-25 | v2 |
| 2026-03-09 | D | 57 | 2025-03-26+ | v1 |
Generate alt-text for a specific figure using AI. Can use image data or a saved image file.
Get an accessibility guide for making PDFs and LaTeX documents accessible. Returns formatted tutorial content.
Validate PDF/UA compliance using veraPDF. Returns detailed report with failure statistics and MorphMind Accessibility Score.
extract_figures 'save_to' parameter has no validation guidance in description. Should specify: (a) must be a writable directory, (b) will create subdirectories if needed, (c) what happens if directory doesn't exist. Currently the LLM has no way to know if it should pre-create the directory.
add_latex_alt_text 'figure_alt_texts' parameter uses a bare object type without specifying the key format. Description says 'Mapping of figure filenames to alt-text (e.g., {'figure1.pdf': 'alt text'})' but does not clarify: (a) exact filename matching required?, (b) case-sensitive?, (c) what if filename not found in LaTeX?
Error handling is minimal. No tool description includes recovery guidance. Example: if add_alt_text fails with 'figure_index out of range', should the error suggest calling extract_figures first?
validate_pdfua 'profile' parameter has a default ('ua1') but description does not explain when to use ua2 vs 1a vs 1b vs 2a, etc. LLM cannot reason about which profile suits the user's intent without guidance.