Serveur MCP d’OCR de passeports pour agents IA

Donnez à un assistant la capacité de lire un passeport, une carte d’identité ou un document de voyage – et de recevoir des champs structurés, pas un bloc de texte. Le serveur parle Model Context Protocol de deux façons : via stdio, installé depuis npm et lancé par votre client comme une commande, ou via Streamable HTTP, hébergé sur mcp.doc.cheap. Dans les deux cas, c’est un client léger de l’API HTTP publique : il ne détient aucune donnée propre.

npx -y @doc-cheap/mcp

Publié sous le nom @doc-cheap/mcp sur npm et cheap.doc/mcp dans le registre MCP officiel ; le code source se trouve sur le miroir public sur GitLab.

Référencé sur : le registre MCP officiel, Smithery, cursor.directory, npm.

Ce que reçoit votre agent

C’est la différence qui compte. Un outil d’OCR qui renvoie une page de texte donne au modèle quelque chose à réanalyser, et un modèle à qui l’on demande de réanalyser une date finira par en inventer une. Cet outil renvoie les champs déjà séparés :

  • Le titulaire – prénoms, nom, date de naissance, sexe, nationalité.
  • Le document – type, pays, État émetteur, numéro, série, date de délivrance, date d’expiration, s’il est expiré et combien de jours il reste.
  • Chaque champ trouvé, chacun avec son propre niveau de confiance, lu séparément dans la zone de lecture automatique (MRZ) et dans la zone visuelle imprimée – pour que le modèle puisse voir que les deux lectures concordent, au lieu de le supposer.
  • La zone de lecture automatique avec un verdict : valide, invalide ou absente, avec la raison, et les lignes elles-mêmes.
  • Un résumé d’une ligne que l’assistant peut vous montrer pendant qu’il travaille.

Les échecs reviennent sous la forme d’une ligne lisible dans un bloc d’erreur, jamais d’un résultat vide et silencieux : l’assistant peut agir en conséquence et vous le montrer. Un refus de l’API conserve la formulation de l’API elle-même, son code d’erreur et le lien vers la page qui l’explique.

Installez-le dans votre client

Claude Desktop

claude_desktop_config.json

{
  "mcpServers": {
    "doc-cheap": {
      "command": "npx",
      "args": [
        "-y",
        "@doc-cheap/mcp"
      ],
      "env": {
        "DOC_CHEAP_API_KEY": "sk_live_your_key"
      }
    }
  }
}

Claude Code

une commande, depuis le répertoire du projet

claude mcp add-json doc-cheap '{"command":"npx","args":["-y","@doc-cheap/mcp"],"env":{"DOC_CHEAP_API_KEY":"sk_live_your_key"}}'

Cursor

~/.cursor/mcp.json, ou .cursor/mcp.json dans un projet

{
  "mcpServers": {
    "doc-cheap": {
      "command": "npx",
      "args": [
        "-y",
        "@doc-cheap/mcp"
      ],
      "env": {
        "DOC_CHEAP_API_KEY": "sk_live_your_key"
      }
    }
  }
}

VS Code

.vscode/mcp.json – attention, l’imbrication se fait sous servers, pas sous mcpServers

{
  "servers": {
    "doc-cheap": {
      "command": "npx",
      "args": [
        "-y",
        "@doc-cheap/mcp"
      ],
      "type": "stdio",
      "env": {
        "DOC_CHEAP_API_KEY": "sk_live_your_key"
      }
    }
  }
}

Gemini CLI

~/.gemini/settings.json

{
  "mcpServers": {
    "doc-cheap": {
      "command": "npx",
      "args": [
        "-y",
        "@doc-cheap/mcp"
      ],
      "env": {
        "DOC_CHEAP_API_KEY": "sk_live_your_key"
      }
    }
  }
}

Windsurf

~/.codeium/windsurf/mcp_config.json

{
  "mcpServers": {
    "doc-cheap": {
      "command": "npx",
      "args": [
        "-y",
        "@doc-cheap/mcp"
      ],
      "env": {
        "DOC_CHEAP_API_KEY": "sk_live_your_key"
      }
    }
  }
}

Kiro

.kiro/settings/mcp.json dans l’espace de travail, ou ~/.kiro/settings/mcp.json

{
  "mcpServers": {
    "doc-cheap": {
      "command": "npx",
      "args": [
        "-y",
        "@doc-cheap/mcp"
      ],
      "disabled": false,
      "autoApprove": [
        "check_balance",
        "search_docs"
      ],
      "env": {
        "DOC_CHEAP_API_KEY": "sk_live_your_key"
      }
    }
  }
}

Kiro, en un clic

Le lien d’installation du client lui-même. Il demande une confirmation et affiche la commande et la liste des arguments avant d’écrire quoi que ce soit.

Ajouter à Kiro

  • Redémarrez le client après avoir ajouté le bloc. C’est le client qui lance le serveur, qui ne prend donc en compte une configuration ou un environnement modifiés qu’au démarrage suivant.
  • Sans DOC_CHEAP_API_KEY, le serveur se rabat sur la clé publique du sandbox : les scans s’exécutent alors dans son quota gratuit et il n’y a aucun solde à afficher. C’est le moyen le plus rapide de le voir fonctionner.
  • Paramètres facultatifs : DOC_CHEAP_DOCS_BASE (vers où pointent les résultats de recherche), DOC_CHEAP_DOCS_DIR (quelle copie de la documentation interroger) et DOC_CHEAP_IMAGE_ROOT (voir les garde-fous ci-dessous).

Ou connectez-vous au serveur hébergé

Les trois mêmes outils sont hébergés à l’adresse https://mcp.doc.cheap/mcp via Streamable HTTP, si bien qu’un client qui se connecte à une URL n’a rien à installer. Aucune connexion à un compte : envoyez votre clé dans X-Doc-Cheap-Api-Key ou dans Authorization: Bearer – l’en-tête nommé l’emporte si les deux sont envoyés – ou n’en envoyez aucune et la clé publique du sandbox est utilisée. Le serveur hébergé ne peut pas lire les fichiers de votre machine ; il reçoit donc l’image en base64 ou sous forme d’URL https.

https://mcp.doc.cheap/mcp

Claude Code

une commande

claude mcp add --transport http doc-cheap https://mcp.doc.cheap/mcp --header "Authorization: Bearer sk_live_your_key"

Cursor

~/.cursor/mcp.json

{
  "mcpServers": {
    "doc-cheap": {
      "url": "https://mcp.doc.cheap/mcp",
      "headers": {
        "Authorization": "Bearer sk_live_your_key"
      }
    }
  }
}

VS Code

.vscode/mcp.json

{
  "servers": {
    "doc-cheap": {
      "type": "http",
      "url": "https://mcp.doc.cheap/mcp",
      "headers": {
        "Authorization": "Bearer sk_live_your_key"
      }
    }
  }
}

Dans Claude Desktop et sur claude.ai, ajoutez-le dans Settings, Connectors, comme connecteur personnalisé avec l’URL https://mcp.doc.cheap/mcp ; sans clé, il fonctionne avec la clé du sandbox.

Les trois outils

Les trois outils que publie le serveur MCP
OutilCe qu’il faitCe qu’il renvoieComportement déclaré
scan_document Recognise a passport or ID documentReconnaît l’image d’un documentLe résultat structuré complet, plus le résumé d’une lignePas en lecture seule – il peut consommer un crédit. Non destructif. Idempotent si vous envoyez une clé d’idempotence, et seulement dans ce cas. Monde ouvert : la réponse vient d’un service distant.
check_balance Check remaining creditsLit la consommation du compteLe solde et les compteurs de la période en coursLecture seule, et monde ouvert : les chiffres reflètent la situation du compte en direct.
search_docs Search the doc.cheap API documentationCherche dans la documentationLes sections correspondantes, avec titres, liens et extraits – hors ligneLecture seule, et monde fermé : le corpus est la copie de la documentation livrée avec le serveur, si bien que la même requête donne la même réponse sans aucun réseau.
  • scan_document reçoit l’image sous forme d’image_base64, d’image_path ou d’image_url, avec les mêmes options qu’un appel direct, dont expect_country, return_portrait, reference et idempotency_key.
  • search_docs lit une copie de la documentation livrée avec le serveur, il répond donc sans aucun réseau – ce qui veut dire que l’agent peut consulter le vocabulaire des champs ou un code d’erreur sans dépenser d’appel.
  • check_balance a besoin d’une clé rattachée à un compte. Avec la clé publique du sandbox, il indique clairement qu’il n’y a pas de solde, plutôt que de répondre avec des zéros qui ressembleraient à une vraie mesure.
  • Chaque outil déclare un schéma de sortie et renvoie un contenu structuré qui le respecte, si bien qu’un agent peut utiliser les champs sans analyser de texte.
  • Chaque page de la documentation est aussi une ressource que l’agent peut lire, et quatre prompts – lire un document en JSON, vérifier une date d’expiration, scanner un lot, expliquer un code d’erreur – lancent les tâches courantes en une seule étape.

Ce que cela coûte

$0.01 par document reconnu. Tarif unique, pour tous les comptes, quel que soit le volume – un seul chiffre, et rien à négocier. Un document n’est facturé que s’il a été reconnu : un scan qui ne trouve rien, ne peut pas lire l’image ou ne peut pas identifier le type répond avec son verdict et ne coûte rien. Chaque résultat indique de quel cas il s’agit, si bien que l’agent – et vous – savez toujours si cet appel a coûté quelque chose.

Avant d’avoir un compte : la clé publique du sandbox exécute 10 documents reconnus gratuits par adresse IP au total, avec au maximum 10 requêtes par heure quelle que soit leur réponse, et l’inscription ajoute 20 crédits. Un crédit vaut un centime, et un centime vaut un document.

La reconnaissance prend environ 275 ms en médiane en production, et chaque résultat indique ses propres temps, si bien qu’une boucle d’agent peut se budgéter sur un chiffre réel.

Ce que le serveur signale

Par défaut, le serveur ne rapporte rien nulle part : le signalement des erreurs est désactivé sauf si vous configurez vous-même une destination, et sans elle la bibliothèque de suivi n’est même pas chargée.

Deux garde-fous à connaître

Le serveur s’exécute sur votre machine avec vos privilèges, et ses arguments sont choisis par un modèle. Deux d’entre eux sont donc encadrés :

Les fichiers locaux restent inaccessibles tant que vous n’ouvrez pas un répertoire

image_path refuse de faire quoi que ce soit tant que DOC_CHEAP_IMAGE_ROOT ne désigne pas un répertoire, et indique à l’assistant d’envoyer image_base64 à la place. Une fois la variable définie, le répertoire comme le fichier demandé sont résolus en suivant les liens symboliques avant la vérification d’appartenance ; un segment .. et un lien pointant vers l’extérieur sont tous deux refusés, et un chemin relatif part de ce répertoire plutôt que de l’endroit où le client a lancé le processus. Un chemin hors de la racine et un chemin qui n’existe pas donnent le même message – un message différent pour chacun répondrait à la question « ce fichier existe-t-il ? » pour n’importe quel chemin de votre machine.

Les images distantes doivent être en https public

image_url est téléchargée par le serveur, donc le schéma doit être https: et l’hôte doit se résoudre uniquement vers des adresses internet publiques : les plages loopback, privées, link-local, NAT d’opérateur (CGNAT), multicast et réservées sont refusées, y compris leurs écritures mappées en IPv6. Une seule réponse non publique fait refuser toute l’URL. Les redirections sont suivies manuellement, trois sauts au maximum, et chaque saut est vérifié à nouveau. Le corps est plafonné à 25 Mo, comptés à mesure qu’ils arrivent plutôt que d’après un en-tête.

image_base64 ne subit aucune de ces contraintes, puisque l’appelant détient déjà les octets – c’est pourquoi chaque refus ci-dessus renvoie vers cette option.

Lire le guide