Früher oder später lädt jemand das Foto eines Reisepasses in einen Chat mit einem Assistenten und bittet ihn, „einfach das Formular auszufüllen“. Ein universelles Vision-Modell wird es versuchen. Vielleicht trifft es sogar den Namen. Was es nicht tut: Ihnen sagen, ob die Prüfziffern der maschinenlesbaren Zone gestimmt haben, Datumsangaben jedes Mal im selben Format liefern oder „Das konnte ich nicht lesen“ sagen, statt zu raten.
Genau für diese Lücke eignet sich ein Tool. Das Model Context Protocol lässt einen Agenten eines aufrufen. Dieser Beitrag zeigt, wie Sie Claude Desktop, Claude Code, Cursor und anderen Clients ein Tool zur Dokumentenerkennung geben, was der Agent zurückbekommt, wie Sie die Kosten begrenzen und worüber Sie nachdenken sollten, bevor Sie einen Agenten überhaupt auf Ausweisdokumente ansetzen.
Dies ist der Blog von doc.cheap, der API hinter dem hier verwendeten MCP-Server. Der Server steht unter MIT-Lizenz, und die Fragen zur Einrichtung gelten für jedes Tool dieser Art.
Was der Agent bekommt
Der Server ist @doc-cheap/mcp auf npm (MIT, Node 20 oder neuer) und stellt drei Tools bereit:
| Tool | Was es tut | Verbraucht Credits? |
|---|---|---|
scan_document |
Erkennt einen Reisepass, Personalausweis oder Führerschein auf einem Foto oder Scan und liefert das strukturierte Ergebnis | Ja, nur wenn ein Dokument erkannt wird |
check_balance |
Liest das verbleibende Guthaben und die Zähler des laufenden Monats | Nein (nur lesend) |
search_docs |
Durchsucht offline die mit dem Server gebündelte API-Dokumentation | Nein (nur lesend) |
Jedes Tool hat einen Titel, eine Beschreibung (bei den zwei Tools, die den Kontostand betreffen, mit Preisangabe) und die MCP-Verhaltenshinweise, die ein Client liest, bevor er entscheidet, ob er Sie zuerst fragt: scan_document ist als nicht nur lesend markiert, die anderen beiden als nur lesend. Der Server sendet außerdem Anweisungen, die das Modell vor jedem Aufruf liest und die sagen, was er erkennt und was ein Aufruf kostet. Zusätzlich zu den Tools gibt es vier Prompts (scan_document_to_json, check_document_expiry, batch_scan, explain_error), und jede Dokumentationsseite ist als nur lesbare Ressource verfügbar, etwa doccheap://docs/reference/fields.
scan_document antwortet mit dem vollständigen Ergebnis als strukturiertem JSON plus einer einzeiligen Zusammenfassung, zum Beispiel:
Scan 01a0af18-cd8d-7a61-9f2d-4c7b8e105da3: recognized · passport (GRC) · PARADEIGMA ELENI SOFIA · billed · 684 ms
(Eine erfundene Musterinhaberin aus der Dokumentation.) Das JSON dahinter enthält die Inhaberin, die Dokumentennummer und Datumsangaben in ISO 8601, jedes Feld mit einer Konfidenzstufe, die MRZ-Zeilen mit dem Urteil passed / failed / absent und ein Flag billed. Auf diese Struktur kommt es an: Der Agent muss keine Pixel deuten, er liest Felder.
Installation: der lokale Server
Jeder der folgenden Clients startet den Server mit npx. Ist kein Schlüssel gesetzt, nutzt er den öffentlichen Sandbox-Schlüssel, der insgesamt 10 kostenlos erkannte Dokumente pro IP-Adresse und höchstens 10 Anfragen pro Stunde erlaubt. Das reicht zum Ausprobieren. Eine Registrierung bringt 20 Gratis-Credits; danach kostet ein erkanntes Dokument $0.01.
Claude Desktop, Cursor und Windsurf lesen denselben Block, jeweils in claude_desktop_config.json, ~/.cursor/mcp.json und ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"doc-cheap": {
"command": "npx",
"args": ["-y", "@doc-cheap/mcp"],
"env": { "DOC_CHEAP_API_KEY": "sk_live_your_key" }
}
}
}
Lassen Sie die Zeile env weg, um mit dem Sandbox-Schlüssel zu arbeiten.
Claude Code:
claude mcp add-json doc-cheap '{"command":"npx","args":["-y","@doc-cheap/mcp"],"env":{"DOC_CHEAP_API_KEY":"sk_live_your_key"}}'
VS Code:
code --add-mcp '{"name":"doc-cheap","command":"npx","args":["-y","@doc-cheap/mcp"]}'
Gemini CLI und Kiro verwenden denselben Block mcpServers in ihren eigenen Einstellungsdateien; der MCP-Leitfaden nennt jeden Pfad. Starten Sie den Client nach der Änderung neu: Der Server übernimmt eine geänderte Umgebung nur bei einem frischen Start.
Installation: der gehostete Server
Wenn Ihr Client sich mit einer URL verbindet, statt einen Befehl zu starten, stehen dieselben drei Tools unter https://mcp.doc.cheap/mcp per Streamable HTTP bereit, ohne Login. Der Schlüssel kommt in einen Header, X-Doc-Cheap-Api-Key oder Authorization: Bearer (werden beide gesendet, gilt der benannte Header); ohne Schlüssel wird der Sandbox-Schlüssel verwendet.
Claude Code:
claude mcp add --transport http doc-cheap https://mcp.doc.cheap/mcp --header "Authorization: Bearer sk_live_your_key"
Cursor:
{
"mcpServers": {
"doc-cheap": {
"url": "https://mcp.doc.cheap/mcp",
"headers": { "Authorization": "Bearer sk_live_your_key" }
}
}
}
In Claude Desktop und claude.ai fügen Sie ihn unter Settings → Connectors als benutzerdefinierten Connector mit dieser URL hinzu.
Der gehostete Server sieht keine Dateien auf Ihrem Rechner. Dort nimmt scan_document das Bild deshalb als image_base64 oder als öffentliche image_url entgegen.
Lokale Dateien und URLs sind bewusst eingezäunt
Ein Tool-Argument wählt ein Modell, und ein Modell lässt sich zu manchem überreden. Deshalb liest der lokale Server keine beliebigen Pfade:
image_pathist deaktiviert, bis SieDOC_CHEAP_IMAGE_ROOTauf ein Verzeichnis setzen. Pfade werden zuerst über Symlinks aufgelöst, und..oder ein Link, der aus dem Verzeichnis hinausführt, wird abgewiesen. Eine fehlende Datei und eine Datei außerhalb des erlaubten Bereichs bekommen dieselbe Meldung, sodass sich mit dem Tool nicht ausforschen lässt, ob eine Datei existiert.image_urlmusshttps:sein, darf nur zu öffentlichen Adressen auflösen (Loopback-, private, Link-Local- und ähnliche Bereiche werden abgewiesen), folgt höchstens drei Weiterleitungen, wobei jeder Schritt erneut geprüft wird, und ist auf 25 MB begrenzt.
Wenn Sie schon einmal ein Tool zum Lesen von Dateien an einen Agenten angebunden haben, vergleichen Sie es mit dieser Liste. „Das Modell wird nur vernünftige Pfade übergeben“ ist keine Sicherheitsgrenze.
Die Kosten begrenzen
Zwei Eigenschaften machen den Einsatz durch Agenten berechenbar:
- Nur erkannte Dokumente werden abgerechnet. Ein Aufruf wird berechnet, wenn der Dokumenttyp bestimmt und tatsächlich Daten extrahiert wurden: eine MRZ, deren Prüfziffern stimmen, mindestens fünf gedruckte Felder oder ein korrekt dekodierter Barcode. Kein Dokument gefunden, ein unlesbares Bild, ein nicht unterstützter Typ, ein interner Fehler oder ein Timeout kosten nichts. Das Flag
billedim Ergebnis sagt jedes Mal, was davon eingetreten ist. Mit dem Sandbox-Schlüssel wird überhaupt nichts berechnet, und das Flag sagt dann, ob derselbe Scan mit einem Live-Schlüssel abgerechnet worden wäre. - Retries lassen sich kostenlos machen.
scan_documentakzeptiert einenidempotency_key; bei einem Live-Schlüssel liefert eine Wiederholung mit demselben Schlüssel das gespeicherte erste Ergebnis, statt erneut abzurechnen. Ein Retry ohne Schlüssel ist ein zweiter Scan. Eine Wiederholung liefert das gespeicherte Ergebnis zurück, daher gilt: entwederretain_hours: 0oder wiederholbare Retries.
In der Praxis:
- Lassen Sie den Agenten vor einem Stapel
check_balanceaufrufen. Die eigenen Anweisungen des Servers sagen dem Modell, das zu tun, und der Promptbatch_scantut es als Erstes. Mit dem Sandbox-Schlüssel ist das Guthabennull, und das Tool meldet, dass es kein Guthaben gibt, statt Nullen anzuzeigen. - Genehmigen Sie nur die lesenden Tools automatisch. Die Konfiguration von Kiro unterstützt zum Beispiel
"autoApprove": ["check_balance", "search_docs"]. Lassen Siescan_documenthinter einer Bestätigungsabfrage, denn dieses Tool verbraucht Guthaben. - Lassen Sie den Agenten nachschlagen.
search_docsarbeitet offline mit der gebündelten Dokumentation, sodass die Frage „Was bedeutetunsupported_document?“ nichts kostet und nicht vom Gedächtnis des Modells abhängt.
Datenschutz: Fragen, die Sie vorher klären sollten
Ausweisdokumente gehören zu den sensibelsten Daten überhaupt, und ein Agent bringt weitere Beteiligte in den Ablauf. Hier steht, was auf der Seite der API gilt und was von Ihrer Einrichtung abhängt.
Auf der Seite der API (laut Dokumentation):
- Das hochgeladene Bild wird für die Dauer der Anfrage im Arbeitsspeicher gehalten und nie dauerhaft gespeichert.
- Das Erkennungsergebnis wird aufbewahrt, damit es später erneut abgerufen werden kann, für einen im Konto eingestellten Zeitraum (24 Stunden, 7 Tage, 30 Tage oder ein Jahr). Die Voreinstellung für ein neues Konto ist ein Jahr. Pro Aufruf schreibt
retain_hours: 0überhaupt keine Zeile, und auchscan_documentakzeptiertretain_hours. Wenn der Agent die Antwort nur einmal braucht, setzen Sie es. - Die Verarbeitung findet in der Europäischen Union statt. Die Daten werden nicht zum Trainieren von Modellen verwendet.
return_portrait: falselässtimages.main_photoweg, den Ausschnitt mit dem Foto der Inhaberin oder des Inhabers. Der Ausschnitt der ganzen Seite kommt weiterhin zurück, ebenso die blasse zweite Abbildung des Gesichts, die manche Dokumente in die Seite drucken.
Auf Ihrer Seite:
- Das Ergebnis landet im Kontext des Modells. Was
scan_documentzurückgibt (Namen, Nummern, Datumsangaben), steht nun in der Unterhaltung und wird von dem LLM-Anbieter verarbeitet, der Ihren Client betreibt, zu dessen Bedingungen. Das ist jedem MCP-Tool eigen und nicht spezifisch für dieses. - Wie das Bild übertragen wird, ist entscheidend. Mit
image_pathauf dem lokalen Server liest der Server die Datei und sendet sie direkt an die API. Mitimage_base64stehen die Bildbytes in den Tool-Call-Argumenten des Modells. Wenn die Pixel aus dem Kontext des Modells herausbleiben sollen, verwenden Sie ein eingezäuntes lokales Verzeichnis. - Das ist Erkennung, keine Verifizierung. Die Gruppe
authenticityim Ergebnis lautetnot_checked. Eine bestandene MRZ-Prüfung bedeutet, dass die Zone gelesen wurde und in sich stimmig ist, nicht, dass das Dokument echt ist. Es gibt keinen Liveness-Check und keinen Gesichtsabgleich. Wenn Ihr Anwendungsfall KYC ist, ist das ein Input, nicht die Entscheidung. - Verwenden Sie während der Entwicklung synthetische Dokumente. Muster und generierte MRZs reichen, um alles anzubinden.
Eine kurze Sitzung
Ist der Server installiert, genügt ein Prompt wie „Lies diesen Passscan und sag mir, ob er in den nächsten sechs Monaten abläuft“ mit einem angehängten synthetischen Muster. Ein gut funktionierender Agent ruft scan_document auf, liest document.expiry_date und document.days_remaining aus dem Ergebnis und antwortet anhand dieser Felder statt anhand seines Eindrucks vom Bild. Kommt der Scan als unreadable zurück, sollte er das sagen und um ein besseres Foto bitten, und berechnet wurde Ihnen dafür nichts.
Dieses letzte Verhalten ist der eigentliche Grund, hier ein Tool zu verwenden: Der Agent bekommt ein ausdrückliches „konnte nicht gelesen werden“, statt der Versuchung ausgesetzt zu sein, eine Lücke zu füllen.
Links
- MCP-Seite mit dem Snippet für jeden Client: https://doc.cheap/mcp
- Vollständiger Leitfaden: https://doc.cheap/docs/guides/use-the-mcp-server
- Quellcode (MIT): https://gitlab.com/doccheap/ocr-mcp
- npm: https://www.npmjs.com/package/@doc-cheap/mcp
Wenn Sie etwas damit bauen oder einen Client finden, bei dem die Konfiguration oben nicht funktioniert, schreiben Sie an admin@doc.cheap.
Jede Aussage über doc.cheap und seinen MCP-Server wurde am Code überprüft.