Lineart is the default because most scans are documents; at 600 dpi and above it switches to colour, on the assumption that high-resolution capture means artwork rather than paperwork. One parameter overrides either default, and every job leaves a manifest and an event log on disk, so a partial run is inspectable rather than lost.
A Node server over Linux SANE. It selects a scanner, runs the job, writes pages and a manifest into an inbox directory, and returns typed status rather than scanimage output.
- Connected scanners discovered with backend details, and one device's SANE options — list_devices, get_device_options
- A scan job started with resolution from 50 to 1200 dpi, colour mode, source (Flatbed, ADF or ADF Duplex), duplex, page size and a document-break policy — start_scan_job
- Auto-selection when you omit the device: it prefers ADF and duplex and avoids camera backends
- Job state and artifact counts, cancellation, and recent jobs filtered by state — get_job_status, cancel_job, list_jobs
- A job's manifest.json and its events.jsonl log — get_manifest, get_events
- Carrier-sheet detection that writes a cropped derivative per affected page while keeping the raw one
- JSON Schema-validated inputs with deterministic typed outputs
Linux with SANE's scanimage, and optionally scanadf, plus tiffcp or ImageMagick convert for multipage assembly. Node 22. Run npx -y scan-mcp over stdio with INBOX_DIR set to where artifacts should land. scan-mcp --http serves the streamable HTTP transport on port 3001 by default, with no authentication of its own, so keep it on a network you control.
One command — npx scan-mcp
