Skip to main content
Glama
@devrobotlabs/visionapi-mcp

@devrobotlabs/visionapi-mcp

Official
by devrobotlabs

@devrobotlabs/visionapi-mcp

MCP server for the Vision API. Point Claude Code, Claude Desktop, Cursor or any other MCP host at a folder of scans and ask for the invoices — no integration to write, no API key in generated code, no contract paraphrased from memory.

You: pull the totals out of every invoice in ~/inbox and put them in a CSV

Claude: [vision_analyze × 7]
        Done — 7 invoices, 14 credits. Three had no PO number; I left those cells empty.

Install

Nothing to install. Add it to your host's config and it runs via npx.

Claude Code — claude mcp add visionapi --env VISION_API_KEY=sk_live_... -- npx -y @devrobotlabs/visionapi-mcp ~/inbox

Claude Desktop — claude_desktop_config.json:

{
  "mcpServers": {
    "visionapi": {
      "command": "npx",
      "args": ["-y", "@devrobotlabs/visionapi-mcp", "/Users/me/inbox"],
      "env": { "VISION_API_KEY": "sk_live_..." }
    }
  }
}

Cursor — .cursor/mcp.json, same shape:

{
  "mcpServers": {
    "visionapi": {
      "command": "npx",
      "args": ["-y", "@devrobotlabs/visionapi-mcp", "."],
      "env": { "VISION_API_KEY": "sk_live_..." }
    }
  }
}

VS Code — .vscode/mcp.json:

{
  "servers": {
    "visionapi": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@devrobotlabs/visionapi-mcp", "${workspaceFolder}"],
      "env": { "VISION_API_KEY": "sk_live_..." }
    }
  }
}

Get a key at app.visionapi.io/dashboard/keys. New accounts get 50 credits, no card.

The host config blocks live in this README rather than in an examples/ directory — a departure from the nine client libraries, and a deliberate one. A snippet that exists only in a README cannot drift from a runnable script nobody runs.

Related MCP server: receiptconverter-mcp

Which directories it can read

Every positional argument is a directory the server may read files from. With none given, the process working directory is the only root — which is the safe default, because MCP hosts launch a stdio server with the project directory as its cwd.

This matters more than it may look. The server holds a live spending credential and runs with your filesystem permissions, so it can read anything your shell can. Asking it for the raw text of ~/Documents/passport.jpg is a working way to get that document's contents into a model's context and into whatever transcript your host keeps. The allowlist is what stops a confused or manipulated agent doing that by accident.

Paths are resolved with realpath on both sides before being compared, so a symlink inside an allowed directory cannot point out of it.

--allow-any-path turns the allowlist off entirely. It warns on stderr at startup and you should have a reason.

Tools

Tool

What it does

Cost

vision_analyze

Structured fields out of one image or PDF

1 credit an image, 2 a PDF page

vision_ask

Up to 5 plain-language questions about one file

1 credit an image, 1 a PDF page

vision_detect

What is this file? Ranked presets, no extraction

1 credit per 5 calls

vision_list_presets

The preset catalogue

free

vision_get_preset

Every field one preset returns

free

vision_credits

Balance and buckets

free

vision_get_task

Status/result of a queued task

free

The three that spend credits are annotated readOnlyHint: false, so a host that auto-approves read-only tools will still stop and ask before one of them runs.

The catalogue is also exposed as resources — visionapi://presets and visionapi://presets/{name} — for hosts that prefer them. Tools are the primary surface, because resource support is uneven across hosts.

Output

Responses are rendered for a model to read, not dumped as JSON. A 37-field invoice preset over a document that fills twelve of them comes back as a table plus one Not found in this document (25): … line, rather than as twenty-five repetitions of {"value":null,"confidence":"low"} — three to four times smaller, and easier to act on.

Nothing is lost in the process. Every tool takes a format:

  • markdown (default) — the rendering above.

  • compact_json — the same information as data, with _not_found and _low_confidence arrays. For when the agent will parse rather than read.

  • json — the API response verbatim. What to reach for when writing real HTTP code against the contract.

Confidence is printed only when it is not high, so (mid) and (low) stand out and the common case costs nothing to read.

Long documents

Leave mode at auto. The API kills a synchronous request at 60 seconds; the server then re-submits it to the queue and polls, reporting progress to your host as it goes. You are charged once, because the timed-out attempt released its reservation in full.

Pass mode: "async" up front for anything over roughly ten pages, and pages: "1-5" to sample a long document cheaply — you are charged for selected pages only.

Costs and failures

Failures cost nothing. Every non-2xx releases the credit reservation in full, so a failed call is safe to correct and repeat and there is no cleanup to do. The tool descriptions say so, which is why an agent using this server behaves sensibly after an error instead of either giving up or retrying something that cannot work.

Two errors carry advice that is worth knowing yourself:

Error

What it means

insufficient_credits

Retrying cannot help — the balance does not change on its own. Top up.

too_many_tasks

Your own async tasks are at the plan's cap. It clears when one of them finishes, not on a timer — so sleeping and retrying blocks the very thing you are waiting for.

Environment

Variable

Required

Purpose

VISION_API_KEY

for billable tools

Your key. The catalogue tools work without it.

VISION_API_URL

no

Override the API base URL. Rarely needed.

A missing key does not stop the server starting: it warns on stderr, tools/list still works, and the first billable call returns a message naming the fix. A server that refuses to start tells the user only that something is broken.

Development

npm install
npm run typecheck
npm test          # 37 offline tests — no key, no network
npx @modelcontextprotocol/inspector node ./dist/cli.js ~/some/dir

npm install --no-save ../node to test against a local build of the client. Not npm install ../node — that rewrites package.json to "file:../node", and that manifest is what gets published.

MIT licensed.

Available Tools

7 tools
vision_analyzeExtract structured data from an image or PDFA

Extract structured data from ONE image or PDF (JPEG, PNG, WebP, TIFF, PDF — detected by magic bytes, the extension is ignored).

Cost: 1 credit per image, 2 per selected PDF page. Failures cost NOTHING — every non-2xx releases the reservation in full, so a failed call is safe to fix and repeat, and there is no cleanup to do.

Choose ONE way to say what you want:

  • preset — a catalogue name, or "auto" to have the API classify the file first, for free. "auto" is the right default when you do not already know the document type. Do not call vision_list_presets just to guess a preset; the classifier is better at it and free.

  • schema — your own fields, {"field_name": "what to extract"}. The description IS the prompt: "the invoice number exactly as printed, without the #" extracts better than "invoice number". A schema can be passed alongside a preset to add fields to it.

  • schema_name — a schema saved in the account's dashboard. Not combinable with the others.

Reading what comes back:

  • Fields the document did not carry are NOT printed as values — they are listed at the end under "Not found". A preset always defines every one of its fields, so an absent value means "this document does not have it", never "the call failed".

  • A "(mid)" or "(low)" after a value is its confidence; no marker means high. Decide deliberately what to do with a low-confidence number rather than treating it as fact.

  • Never hardcode a preset's field names from memory. Call vision_get_preset first if the names are going into code.

Long documents: leave mode at "auto". The server kills a synchronous request at 60 seconds; this tool then re-submits it to the queue and polls, and you are charged exactly once because the timed-out attempt refunded itself. Pass mode:"async" up front for anything over ~10 pages.

One file per call. To process a folder, call this once per file — and if you get too_many_tasks, wait for your own in-flight tasks rather than sleeping.

Inputs: mode, pages, detail, format, +10 more.

vision_askAsk questions about an image or PDFA

Ask up to 5 plain-language questions about ONE image or PDF and get answers with a verdict.

Cost: 1 credit per image, and 1 per selected PDF page — half what extraction costs on a PDF, because the answer does not scale with the page. The questions themselves are free: asking five costs exactly what asking one costs. Failures cost NOTHING.

Reach for this over vision_analyze when the answer is a judgement rather than a field — "is this signed?", "does the delivery address match the billing address?", "is anyone wearing safety equipment?". Reach for vision_analyze when you want values you will store or compute with; asking for a total and then parsing the prose is slower, dearer and less reliable than extracting it.

Reading what comes back: branch on verdict, never on the prose.

  • "yes" / "no" — the images settle it.

  • "uncertain" — a yes/no question the images genuinely do not settle. Treat it as missing information, not as a "no".

  • "n-a" — the question was not a yes/no question; the answer is in the prose. Each verdict carries a confidence, shown as "(mid)" or "(low)"; no marker means high.

Answers are at document level, not per page. Long documents behave exactly as in vision_analyze — leave mode at "auto", or pass "async" up front past ~10 pages.

Inputs: questions (required), mode, pages, detail, +5 more.

vision_creditsVision API credit balanceA
Read-only

The account's credit balance and its per-bucket breakdown.

Free — no credits consumed.

Worth checking before a large batch, so you can tell the user up front that 300 files will not fit in the balance rather than stopping half way through with an insufficient_credits error. Buckets are spent in order: subscription, then rollover, then pack, then welcome.

Inputs: no named parameters. Returns: balance, buckets

vision_detectIdentify what a file is, without extracting itA

Identify what a file IS without paying to extract it: the presets that could handle it, ranked, each with a confidence and a one-line reason.

Cost: 1 credit per 5 calls, whatever the file — detection only ever reads page 1, so a 300-page PDF costs the same as a photo. Four calls in five report 0 credits used.

recommended is exactly what preset:"auto" would run on this file, so you can probe first and trust the answer.

Reach for this when the TYPE is the decision: routing a mixed inbox to different handlers, or refusing to spend two credits a page on a 40-page PDF sight unseen. Do NOT reach for it as a step before every vision_analyze call — if you want the data and do not care which preset produced it, preset:"auto" classifies the same way, for free, in the same request. Using detect first and then analyze is two calls where one would do.

If fallback is true, nothing matched confidently and the recommendation is the generic preset. That is an honest "unknown", and it is worth surfacing to the user rather than extracting against a shape nobody has confirmed.

Inputs: detail, format, file_url, file_path.

vision_get_presetGet a Vision API presetA
Read-onlyIdempotent

The full field list for one preset: every field name, its type, its description, and whether it is always present.

Free — no credits, no API key needed.

This is the ONLY correct source for a preset's field names. Never write one from memory: the catalogue is versioned and a name you remember from another project may not exist here, and a schema built on a guessed name fails at the point where you are parsing the response rather than at the point where you made it up.

Fields marked ★ are present on every response; the rest appear only when the document carries them. A field holding null means the document did not have it, never that the call failed.

Inputs: name (required), format.

vision_get_taskGet a queued Vision API taskA
Read-only

Status, and once finished the result, of a queued task.

Free — no credits consumed. The result was already paid for when the task was submitted.

Call this with the id from a call that was queued — either one you made with mode:"async", or one where polling ran out of time and the answer told you to come back. A task that is still "queued" or "processing" has NOT failed; it is working, and re-submitting the file would be a second charge for the same work.

Results are kept for 7 days. After that only the metadata survives and the file has to be sent again.

Inputs: task_id (required), format, max_chars.

vision_list_presetsList Vision API presetsA
Read-onlyIdempotent

List the preset catalogue: every named schema, with its field count and what it is for.

Free — no credits, no API key needed.

Read this when the user asks what document types are supported, or when you need a preset name to put in code. Do NOT call it to pick a preset before an extraction: preset:"auto" classifies the file server-side for free and is better at it than matching a description by eye, and vision_detect costs a fifth of a credit if you want the ranking. Listing 28 presets to guess one is the expensive path to a worse answer.

The names here are catalogue entries, not field names. Call vision_get_preset before writing any field name into code.

Inputs: format.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.7/5.0

    Scored across 7 tools

    Disambiguation5/5

    Each tool serves a distinct purpose: catalog discovery, preset details, credit balance, extraction, Q&A, detection, and async task retrieval. Even the overlapping detect/analyze pair is explicitly disambiguated with guidance on when each is appropriate, eliminating selection ambiguity.

    Naming Consistency5/5

    All tools follow the vision_<action> pattern, with actions being clear verbs (list, get, analyze, ask, detect, get). The lone exception 'credits' represents a state query but still fits the pattern as a noun-based action. The prefix is consistent and each name clearly signals its function.

    Tool Count5/5

    Seven tools is well-scoped for a vision API server, covering catalog management, extraction, Q&A, detection, credits, and async task handling. Each tool earns its place with no redundancy or bloat, matching the typical range for a focused service.

    Completeness5/5

    The tool set provides full lifecycle coverage: discover presets (list/get), perform operations (analyze/ask/detect), handle async tasks (get_task), and monitor usage (credits). There are no obvious gaps, and any missing features like custom schema management are handled via the dashboard rather than needing tools.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      An MCP server that lets AI assistants read and visually analyze local documents — PDFs, Excel spreadsheets, CSV files, Word documents, PowerPoint presentations, and images.
      4
      50 npm
      48 PyPI
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server that gives your Claude, Cline, or Cursor session the ability to extract text, tables, and metadata from any PDF URL — including scanned PDFs via OCR.
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server that extracts clean text, tables, and structured data from documents, images, code, and audio files, supporting 97 formats with OCR, transcription, and code intelligence.
      MIT