How to read barcodes and QR codes from scanned documents

Scanned documents defeat text extraction: there is no text layer to read. Barcodes are the exception — the engine’s models detect them in the rasterized image, so a scanned delivery note still yields its tracking number.

Note
The commands and config snippets on this page are for the .NET build of the server, which ships as a Docker image only. Installation and client setup: MCP server for .NET. Other platforms will expose the same tools with their own launch command; everything else on this page applies unchanged.

The prompt

Read the barcodes in these scanned delivery notes and list the values with the file they came from.

extract_barcodes returns the decoded value, the symbology (Code128, QR Code, PDF417, DataMatrix, EAN-13, EAN-8, UPC, Aztec and more), the page, and the position.

Why this matters operationally

The decoded value is usually the join key: the tracking number that links a scan to a shipment, the order reference that links a signed form to a case, the asset tag that links a photograph to an inventory record. Once the agent has it, the document stops being an opaque image and becomes a row you can look up.

For each scan, read the barcode and tell me which order it belongs to.

Narrow by page

Read the barcode on page 1 only.

Scanning every page of a long document for codes is work you can skip when you know where the label is.

What this is not

  • Not OCR. Printed words in a scan remain pixels. If you need the text of a scanned page, that needs an OCR step this server does not provide.
  • Not a trust boundary. A decoded value is data supplied by whoever produced the document. Report it, look it up, cross-check it — do not let an agent act on it unreviewed.
  • Not guaranteed on poor scans. Skewed, low-resolution, or damaged codes may not decode. An empty result is “not found”, which on a bad scan is not the same as “not present”.

Combining with the rest

On a mixed batch — some born-digital, some scanned — let the agent branch:

For each file: try text extraction. If it comes back empty, read the barcodes instead and tell me which files needed that.

The list of files that fell through to barcodes is, incidentally, an inventory of which parts of your archive are scans — useful in its own right when planning an ingestion project (Markdown server has the same blind spot for the same reason).