npm scan-mcpstdioMITupdated 1mo ago
Minimal MCP server for scanner capture (ADF/duplex/page-size), batching, and multipage assembly.
What can you do with scan mcp?
Minimal MCP server for scanner capture (ADF/duplex/page-size), batching, and multipage assembly.
Features
- Small, typed MCP server exposing tools for device discovery and scan jobs
- JSON Schema–validated inputs with deterministic, typed outputs
- Smart device selection (prefers ADF/duplex, avoids camera backends), robust defaults
- Local-first transports: stdio by default to keep everything on-device, optional HTTP for your own network deployments
Note: This package targets Node 22 and Linux SANE backends (scanimage).
Quick Start (local stdio, default)
Add a server entry to your MCP client configuration:
{
"mcpServers": {
"scan": {
"command": "npx",
"args": [
"-y",
"scan-mcp"
],
"env": {
"INBOX_DIR": "~/Documents/scanned_documents/inbox"
}
}
}
}
- This invocation runs over stdio for a privacy-first, single-machine setup.
- Call
start_scan_jobwithout adevice_idto auto-select a scanner and begin scanning. - Artifacts are written under
INBOX_DIRper job:job-*/page_*.tiff,doc_*.tiff,manifest.json,events.jsonl. Whencrop_carrier_sheetsis set and a carrier sheet is detected, apage_*.cropped.tiffderivative is also written per affected page.
Streamable HTTP transport
Prefer to attach the scanner to another machine on your network? scan-mcp also supports the
streamable HTTP transport:
scan-mcp --http
- Default port is
3001; setMCP_HTTP_PORTto override (for exampleMCP_HTTP_PORT=3333 scan-mcp --http). - Binds all interfaces (
::) by default; setMCP_HTTP_HOSTto restrict (for exampleMCP_HTTP_HOST=127.0.0.1when a reverse proxy fronts the server). - HTTP responses use server-sent events (SSE) for streaming tool output; clients such as Claude Desktop and Windsurf support this transport.
- There is currently no authentication; this is intended for internal LAN networking
Install
- Run with npx:
npx scan-mcp(recommended)- The CLI runs a quick preflight check for Node 22+ and required scanner/image tools and prints installation hints if anything is missing.
- See recommended server config above
- Use
npx scan-mcp --httpto launch the streamable HTTP transport when running on another machine. - CLI help:
scan-mcp --help - From source (for development):
npm installnpm run build
- For Cline setup, and other automated agentic installation, see llms-install.md
System Requirements
- Linux with SANE utilities:
scanimage(and optionallyscanadf) - TIFF tools:
tiffcp(preferred) or ImageMagickconvert
Environment Variables
SCAN_MOCK(default:false): mock SANE calls and generate fake TIFFs for testing.INBOX_DIR(default:scanned_documents/inbox): base directory for job runs and artifacts.SCANIMAGE_BIN/SCANADF_BIN(defaults:scanimage/scanadf): override binary paths.TIFFCP_BIN/IM_CONVERT_BIN(defaults:tiffcp/convert): multipage assembly tools.SCAN_EXCLUDE_BACKENDS(CSV): backends to exclude (e.g.,v4l).SCAN_PREFER_BACKENDS(CSV): preferred backends (e.g.,epjitsu,epson2).PERSIST_LAST_USED_DEVICE(default:true): persist and lightly prefer last used device.MCP_HTTP_PORT(default:3001): TCP port for the HTTP transport.
API
Tools
-
list_devices
- Discover connected scanners with backend details.
- Inputs: none.
-
get_device_options
- Get SANE options for a specific device.
- Inputs:
device_id(string): Target device identifier.
-
start_scan_job
- Begin a scanning job; omitting
device_idtriggers auto-selection and default options. - Inputs (all optional unless noted):
device_id(string)resolution_dpi(integer, 50–1200)color_mode(Color|Gray|Lineart): color_mode defaults to Lineart (document-first); at >= 600dpi it defaults to Color, since high-dpi capture usually means artwork/photos where 1-bit destroys information. Pass color_mode explicitly to override either default; high dpi is the only signal used.source(Flatbed|ADF|ADF Duplex)duplex(boolean)page_size(Letter|A4|Legal|Custom)custom_size_mm{width,height}doc_break_policy{type,blank_threshold,page_count,timer_ms,barcode_values}output_format(string, defaulttiff)tmp_dir(string)crop_carrier_sheets(boolean, defaultfalse): detect carrier-sheet leading-edge band and write cropped page derivatives; raw pages are kept
- Begin a scanning job; omitting
-
get_job_status
- Inspect job state and artifact counts.
- Inputs:
job_id(string)
-
cancel_job
- Request job cancellation; best effort during scan loops.
- Inputs:
job_id(string)
-
list_jobs
- List recent jobs from the inbox directory.
- Inputs (optional):
limit(integer, max 100)state(running|completed|cancelled|error|unknown)
-
get_manifest
- Fetch a job's
manifest.json. - Inputs:
job_id(string)
- Fetch a job's
-
get_events
- Retrieve a job's
events.jsonllog. - Inputs:
job_id(string)
- Retrieve a job's
See JSON Schemas in schemas/ for input shapes. Tests assert against these contracts.
How Selection and Defaults Work
Defaults aim for 300dpi, reasonable color mode, and ADF/duplex when available. Full details on scoring and fallbacks live in docs:
- Selection and defaults:
docs/SELECTION.md
Project Layout
src/mcp.ts— MCP server entry and tool registrationsrc/services/*— hardware interface and job orchestrationschemas/— JSON Schemas used for validation and testsdocs/— architecture, conventions, and deep dives
Development
npm run dev(stdio MCP server),npm run dev:http(HTTP transport)make verifyruns lint, typecheck, and tests- Conventions:
docs/CONVENTIONS.mdand architecture indocs/BLUEPRINT.md
Roadmap
Tracking ideas and future improvements are documented in docs/ROADMAP.md.
Install
Add scan mcp to your client. Pick the one you use.
claude mcp add scan-mcp -- npx -y scan-mcpcodex mcp add scan-mcp -- npx -y scan-mcpamp mcp add scan-mcp -- npx -y scan-mcp{
"mcpServers": {
"scan-mcp": {
"command": "npx",
"args": [
"-y",
"scan-mcp"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"scan-mcp": {
"command": "npx",
"args": [
"-y",
"scan-mcp"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
code --add-mcp '{"name":"scan-mcp","command":"npx","args":["-y","scan-mcp"]}'Or add the block manually to `.vscode/mcp.json` under `servers`.
{
"mcpServers": {
"scan-mcp": {
"command": "npx",
"args": [
"-y",
"scan-mcp"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"scan-mcp": {
"command": "npx",
"args": [
"-y",
"scan-mcp"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"scan-mcp": {
"command": "npx",
"args": [
"-y",
"scan-mcp"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"scan-mcp": {
"type": "local",
"command": "npx",
"args": [
"-y",
"scan-mcp"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"scan-mcp": {
"command": {
"path": "npx",
"args": [
"-y",
"scan-mcp"
]
}
}
}
}Add to your Zed `settings.json`.
npx -y scan-mcpRun `goose configure`, choose **Add Extension → Command-line Extension**, and paste this command.
10 tools
scan mcp exposes 10 tools to a connected agent.
- device_id
- (string)
- resolution_dpi
- (integer, 50–1200)
- color_mode
- (`Color` | `Gray` | `Lineart`): color_mode defaults to Lineart (document-first);
- page_size
- (`Letter` | `A4` | `Legal` | `Custom`)
- custom_size_mm
- { `width`, `height` }
- doc_break_policy
- { `type`, `blank_threshold`, `page_count`, `timer_ms`, `barcode_values` }
- output_format
- (string, default `tiff`)
- tmp_dir
- (string)
- crop_carrier_sheets
- (boolean, default `false`): detect carrier-sheet leading-edge band and write cropped page derivatives; raw pages are kept
- job_id
- (string)
Score
77 / 100
Good
- Documentation25/25
- Maintenance19/25
- Trust13/20
- Capability8/15
- Install experience12/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 28 days ago
- Has a release history
- Repository is not archived
- Licensed MIT
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 10 tool(s) documented
- Provides prompt templates
- Provides resources
- 12 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint — no local install
Version history
| Versions | Published |
|---|---|
| 0.3.0Latest | Jul 22, 2026 |