Generic MCP server exposing a scan tool to network (eSCL/AirScan) and USB (WIA/SANE/TWAIN) scanners.
Two well-named tools with comprehensive parameter schemas and detailed descriptions. list_scanners is read-only discovery; scan_document is a complex write operation with 8 parameters, all typed and described. Descriptions are 150 - 400 chars, within the 10 - 1024 baseline. Tool annotations (readOnlyHint, destructiveHint, openWorldHint) are present and correct. Main gaps: no output schema documentation, no pagination support, limited error recovery guidance, and no validation of enum-like parameters (source, color_mode, output_format) via formal JSON Schema enums.
List all scanners reachable from this machine. Discovers network scanners over mDNS (eSCL/AirScan) and local USB scanners via the platform driver stack (WIA on Windows, SANE on Linux/macOS). Returns a JSON array of scanners with their ``id`` (pass this to ``scan_document``), ``name``, ``backend``, ``connection`` type and supported ``sources``.
Scan a document and return it so Claude can read it. Args: scanner_id: Which scanner to use (from ``list_scanners``). If omitted and exactly one scanner is found, that one is used; if several are found, an error lists them. source: ``auto`` | ``platen`` (flatbed glass) | ``adf`` (document feeder) | ``adf-duplex`` (feeder, both sides). resolution: DPI (150 fast, 300 documents, 600 fine). Default 300. color_mode: ``color`` | ``gray`` | ``lineart`` (1-bit black & white). output_format: ``png`` | ``jpeg`` | ``pdf``. PDF is best for multi-page archives; images let Claude view the page inline. save_dir: Folder to save the scan in. Defaults to ~/Scans (or $SCANNER_MCP_SAVE_DIR). return_image: If true and the output is an image, the page images are returned inline so Claude can read the document directly. Ignored for PDF. ocr: If true, also OCR each page to text (requires Tesseract + pytesseract). Returns a summary plus, when applicable, inline page images and/or OCR text.
Output schemas not documented. scan_document returns a list with inline MCPImage objects and a summary dict, but no formal schema is provided. LLMs cannot plan downstream operations or extract fields reliably.
Enum parameters (source, color_mode, output_format) lack formal JSON Schema enum constraints. Descriptions list valid values as backtick-quoted strings, but LLMs may hallucinate alternatives. Use 'enum' in schema.
Error messages are raised as ValueError/RuntimeError but lack recovery guidance. E.g., 'invalid source' does not suggest valid options or next steps. Follow pattern:recovery-guide to guide LLM retry.
list_scanners returns all scanners without pagination or limit. If many scanners are discovered, response could be large. Add limit/offset parameters and document result cap.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | <=2025-11-25 | v2 |
scan_document has optional scanner_id with auto-selection fallback, but error message for multiple scanners is not shown in code. Ensure error includes list of available scanner IDs for LLM to choose from.