Servidor MCP de OCR de pasaportes para agentes de IA

Dale a un asistente la capacidad de leer un pasaporte, un documento de identidad o un documento de viaje, y de recibir campos estructurados, no un bloque de texto. El servidor habla Model Context Protocol de dos formas: por stdio, instalado desde npm y lanzado por tu cliente como un comando, o por Streamable HTTP, alojado en mcp.doc.cheap. En ambos casos es un cliente ligero de la API HTTP pública: no guarda ningún dato propio.

npx -y @doc-cheap/mcp

Publicado como @doc-cheap/mcp en npm y como cheap.doc/mcp en el registro oficial de MCP; el código fuente está en el espejo público en GitLab.

Aparece en el registro oficial de MCP, Smithery, cursor.directory, npm.

Qué recibe tu agente

Esta es la diferencia que importa. Una herramienta de OCR que devuelve una página de texto le da al modelo algo que volver a analizar, y un modelo al que se le pide volver a analizar una fecha acabará inventándose una. Esta herramienta devuelve los campos ya separados:

  • El titular: nombres, apellidos, fecha de nacimiento, sexo, nacionalidad.
  • El documento: tipo, país, Estado emisor, número, serie, fecha de expedición, fecha de vencimiento, si está vencido y cuántos días quedan.
  • Cada campo encontrado, cada uno con su propia confianza, leído por separado de la zona de lectura mecánica (MRZ) y de la zona visual impresa, para que el modelo pueda ver que las dos lecturas coinciden en lugar de suponerlo.
  • La zona de lectura mecánica con un veredicto (superada, fallida o ausente) junto con el motivo y las propias líneas.
  • Un resumen de una línea que el asistente puede mostrarte mientras trabaja.

Los fallos llegan como una línea legible en un bloque de error, nunca como un resultado vacío y silencioso: el asistente puede actuar en consecuencia y mostrártelo. Un rechazo de la API conserva la redacción de la propia API, su código de error y el enlace a la página que lo explica.

Instálalo en tu cliente

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

un comando, desde el directorio del proyecto

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, o .cursor/mcp.json en un proyecto

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

VS Code

.vscode/mcp.json – ojo: va anidado bajo servers, no bajo 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 en el espacio de trabajo, o ~/.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, con un clic

El enlace de instalación del propio cliente. Pide confirmación y muestra el comando y la lista de argumentos antes de escribir nada.

Añadir a Kiro

  • Reinicia el cliente después de añadir el bloque. Es el cliente quien inicia el servidor, así que solo recoge una configuración o un entorno modificados al arrancar de nuevo.
  • Sin DOC_CHEAP_API_KEY, el servidor recurre a la clave pública del sandbox: los escaneos se ejecutan dentro de su cupo gratuito y no hay saldo que consultar. Es la forma más rápida de verlo funcionar.
  • Ajustes opcionales: DOC_CHEAP_DOCS_BASE (adónde enlazan los resultados de búsqueda), DOC_CHEAP_DOCS_DIR (qué copia de la documentación se consulta) y DOC_CHEAP_IMAGE_ROOT (consulta las protecciones más abajo).

O conéctate al servidor alojado

Las mismas tres herramientas están alojadas en https://mcp.doc.cheap/mcp mediante Streamable HTTP, así que un cliente que se conecta a una URL no necesita instalar nada. Sin inicio de sesión: envía tu clave como X-Doc-Cheap-Api-Key o como Authorization: Bearer (si envías ambas, gana la cabecera con nombre propio), o no envíes ninguna y se usará la clave pública del sandbox. El servidor alojado no puede leer archivos de tu máquina, así que recibe la imagen en base64 o como una URL https.

https://mcp.doc.cheap/mcp

Claude Code

un comando

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"
      }
    }
  }
}

En Claude Desktop y en claude.ai, añádelo en Settings, Connectors, como conector personalizado con la URL https://mcp.doc.cheap/mcp; sin clave, funciona con la clave del sandbox.

Las tres herramientas

Las tres herramientas que publica el servidor MCP
HerramientaQué haceQué devuelveComportamiento que declara
scan_document Recognise a passport or ID documentReconoce la imagen de un documentoEl resultado estructurado completo, más el resumen de una líneaNo es de solo lectura: puede consumir un crédito. No es destructiva. Es idempotente cuando envías una clave de idempotencia, y solo entonces. De mundo abierto: la respuesta viene de un servicio remoto.
check_balance Check remaining creditsLee el uso de la cuentaEl saldo y los contadores del periodo actualDe solo lectura y de mundo abierto: las cifras son la situación de la cuenta en vivo.
search_docs Search the doc.cheap API documentationBusca en la documentaciónLas secciones que coinciden, con títulos, enlaces y fragmentos, sin conexiónDe solo lectura y de mundo cerrado: el corpus es la copia de la documentación que se distribuye junto al servidor, así que la misma consulta da la misma respuesta sin ninguna red.
  • scan_document recibe la imagen como image_base64, image_path o image_url, y las mismas opciones que una llamada directa, entre ellas expect_country, return_portrait, reference e idempotency_key.
  • search_docs lee una copia de la documentación distribuida junto al servidor, así que responde sin ninguna red; eso significa que el agente puede consultar el vocabulario de campos o un código de error sin gastar una llamada.
  • check_balance necesita una clave con una cuenta detrás. Con la clave pública del sandbox dice claramente que no hay saldo, en lugar de responder con ceros que parezcan una lectura.
  • Cada herramienta declara un esquema de salida y devuelve contenido estructurado que lo cumple, así que un agente puede usar los campos sin analizar texto.
  • Cada página de la documentación es también un recurso que el agente puede leer, y cuatro prompts (leer un documento a JSON, comprobar una fecha de vencimiento, escanear un lote, explicar un código de error) inician las tareas habituales en un solo paso.

Cuánto cuesta

$0.01 por documento reconocido. Tarifa plana, para todas las cuentas, a cualquier volumen: un solo número y nada que negociar. Un documento solo se cobra cuando se ha reconocido: un escaneo que no encuentra nada, no puede leer la imagen o no puede identificar el tipo responde con su veredicto y no cuesta nada. Cada resultado indica cuál fue, así que siempre queda claro, para el agente y para ti, si esa llamada gastó algo.

Antes de tener una cuenta: la clave pública del sandbox ejecuta 10 documentos reconocidos gratis por dirección IP en total, con un máximo de 10 solicitudes por hora sea cual sea la respuesta, y al registrarte se suman 20 créditos. Un crédito es un centavo, y un centavo es un documento.

El reconocimiento tarda unos 275 ms de mediana en producción, y cada resultado incluye sus propios tiempos, así que un bucle de agente puede presupuestar con una cifra real.

Qué informa el servidor

Por defecto, el servidor no informa de nada a ningún sitio: el envío de fallos está desactivado salvo que configures tú mismo un destino, y sin él la biblioteca de seguimiento ni siquiera se carga.

Dos protecciones que conviene conocer

El servidor se ejecuta en tu máquina con tus privilegios, y sus argumentos los elige un modelo. Por eso dos de ellos están acotados:

Los archivos locales están desactivados hasta que abras un directorio

image_path se niega a hacer nada hasta que DOC_CHEAP_IMAGE_ROOT indique un directorio, y le dice al asistente que envíe image_base64 en su lugar. Con la variable definida, tanto el directorio como el archivo solicitado se resuelven siguiendo los enlaces simbólicos antes de comprobar que uno contiene al otro; se rechazan tanto un segmento .. como un enlace que apunte hacia fuera, y una ruta relativa se toma desde ese directorio y no desde donde el cliente haya iniciado el proceso. Una ruta fuera de la raíz y una ruta que no existe dan el mismo mensaje: uno distinto para cada caso respondería a «¿existe este archivo?» para cualquier ruta de tu máquina.

Las imágenes remotas deben ser https públicas

El servidor descarga image_url, así que el esquema debe ser https: y el host debe resolverse solo a direcciones públicas de internet: se rechazan los rangos de loopback, privados, de enlace local, de NAT de operador (CGNAT), de multidifusión y reservados, incluidas sus formas mapeadas en IPv6. Una sola respuesta no pública rechaza toda la URL. Las redirecciones se siguen a mano, como máximo tres saltos, y cada salto se vuelve a comprobar. El cuerpo tiene un límite de 25 MB, contado a medida que llega y no tomado de una cabecera.

image_base64 no tiene ninguna de estas restricciones, porque quien llama ya tiene los bytes; por eso cada rechazo anterior remite a esa opción.

Lee la guía