护照 OCR MCP 服务器:为 AI 智能体而建
让助手能够读取护照、身份证或旅行证件 – 并拿回结构化字段,而不是一大段文本。该服务器以两种方式使用 Model Context Protocol 通信:经 stdio,从 npm 安装并由您的客户端作为命令启动;或经 Streamable HTTP,托管在 mcp.doc.cheap。无论哪种方式,它都是公开 HTTP API 的一个轻量客户端:自身不保存任何数据。
npx -y @doc-cheap/mcp 以 @doc-cheap/mcp 发布在 npm 上,并以 cheap.doc/mcp 收录于官方 MCP 注册表;源代码位于GitLab 上的公开镜像。
您的智能体会拿回什么
真正重要的区别就在这里。返回一整页文本的 OCR 工具,会把重新解析的工作丢给模型,而被要求重新解析日期的模型,迟早会编造出一个日期。本工具返回的是已经拆分好的字段:
- 持有人 – 名、姓、出生日期、性别、国籍。
- 证件 – 种类、国家、签发国、号码、系列号、签发日期、有效期至、是否已过期,以及剩余天数。
- 找到的每个字段,各自带有置信度,分别从机读区(MRZ)和印刷的视读区读取 – 这样模型能看到两种读取结果是否一致,而不是想当然。
- 机读区及其结论:通过、未通过或不存在,附带原因以及各行原文。
- 一行摘要,助手可以在工作过程中展示给您。
失败会以错误块中一行可读的文字返回,绝不会是悄无声息的空结果:助手可以据此采取行动,并展示给您看。API 的拒绝会保留 API 自己的措辞、错误代码,以及解释该错误的页面链接。
在您的客户端中安装
把这段配置添加到您客户端的 MCP 配置中,然后重启客户端。将 DOC_CHEAP_API_KEY 设置为您自己的密钥;如果不设置,则会改用公开的沙箱密钥。
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
一条命令,在项目目录下执行
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,或项目中的 .cursor/mcp.json
{
"mcpServers": {
"doc-cheap": {
"command": "npx",
"args": [
"-y",
"@doc-cheap/mcp"
],
"env": {
"DOC_CHEAP_API_KEY": "sk_live_your_key"
}
}
}
}VS Code
.vscode/mcp.json – 注意:它嵌套在 servers 下,而不是 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,或 ~/.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"
}
}
}
}- 添加配置后请重启客户端。服务器由客户端启动,因此只有重新启动时才会读取修改后的配置和环境变量。
- 未设置 DOC_CHEAP_API_KEY 时,服务器会退回使用公开的沙箱密钥:扫描在其免费额度内运行,也没有余额可供查询。这是看到它运行起来的最快方式。
- 可选设置:DOC_CHEAP_DOCS_BASE(搜索结果链接指向的位置)、DOC_CHEAP_DOCS_DIR(搜索哪一份文档副本)以及 DOC_CHEAP_IMAGE_ROOT(见下方的防护说明)。
或者连接托管服务器
同样的三个工具也托管在 https://mcp.doc.cheap/mcp,通过 Streamable HTTP 提供,因此通过 URL 连接的客户端无需安装任何东西。无需登录:以 X-Doc-Cheap-Api-Key 或 Authorization: Bearer 发送您的密钥 – 两者同时发送时以前者这个专用请求头为准 – 或者都不发送,此时使用公开的沙箱密钥。托管服务器无法读取您机器上的文件,因此它接收 base64 格式的图像或 https URL。
https://mcp.doc.cheap/mcp Claude Code
一条命令
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"
}
}
}
}在 Claude Desktop 和 claude.ai 中,于 Settings 的 Connectors 下将其添加为自定义连接器,URL 填写 https://mcp.doc.cheap/mcp;不提供密钥时,它使用沙箱密钥运行。
三个工具
| 工具 | 作用 | 返回内容 | 声明的行为 |
|---|---|---|---|
scan_document Recognise a passport or ID document | 识别一张证件图像 | 完整的结构化结果,外加一行摘要 | 非只读 – 它可能扣除一个点数。非破坏性。在您发送幂等键时是幂等的,且仅在那时如此。开放世界:答案来自远程服务。 |
check_balance Check remaining credits | 读取账户的用量 | 余额以及本周期的计数 | 只读,开放世界:这些数字是账户的实时状况。 |
search_docs Search the doc.cheap API documentation | 搜索文档 | 匹配的章节,带标题、链接和摘录 – 离线 | 只读,封闭世界:语料是随服务器一起分发的文档副本,因此在完全没有网络的情况下,同样的查询也会得到同样的答案。 |
- scan_document 通过 image_base64、image_path 或 image_url 接收图像,并接受与直接调用相同的选项,例如 expect_country、return_portrait、reference 和 idempotency_key。
- search_docs 读取随服务器一起分发的文档副本,因此完全无需联网即可回答 – 这意味着智能体可以查阅字段词汇表或错误代码,而不必消耗一次调用。
- check_balance 需要一个背后有账户的密钥。使用公开的沙箱密钥时,它会明确说明没有余额,而不是返回一串看起来像读数的零。
- 每个工具都声明了输出 schema,并返回符合该 schema 的结构化内容,因此智能体无需解析文本即可使用这些字段。
- 文档的每一页同时也是智能体可以读取的资源;另有四个提示词 – 把证件读取为 JSON、检查有效期、批量扫描、解释错误代码 – 可一步启动常见任务。
费用
每份成功识别的证件 $0.01。统一价格,适用于所有账户,不分用量 – 只有一个数字,没有什么需要谈判的。只有被识别出的证件才收费:扫描没有找到任何东西、无法读取图像或无法识别证件类型时,响应会给出相应结论,并且不收费。每个结果都会说明属于哪种情况,因此智能体 – 以及您 – 始终清楚这次调用是否产生了费用。
在您拥有账户之前:公开的沙箱密钥每个 IP 地址总共可免费识别 10 份证件,无论返回什么结果,每小时最多 10 次请求;注册后再增加 20 个点数。一个点数就是一美分,也就是一份证件。
在生产环境中,识别耗时的中位数约为 275 ms,每个结果都带有各自的耗时数据,因此智能体循环可以按真实数字做预算。
服务器会上报什么
默认情况下,服务器不向任何地方报告任何内容:除非您自己设置了上报端点,否则故障上报处于关闭状态;没有端点时,错误追踪库根本不会被加载。
两道值得了解的防护
服务器以您的权限在您的机器上运行,而它的参数由模型选择。因此其中两个参数受到了限制:
在您开放一个目录之前,本地文件一律关闭
在 DOC_CHEAP_IMAGE_ROOT 指定一个目录之前,image_path 拒绝执行任何操作,并提示助手改为发送 image_base64。设置该变量后,目录和所请求的文件都会先解析符号链接,再检查后者是否位于前者之内;包含 .. 的路径段和指向外部的链接都会被拒绝,相对路径以该目录为起点,而不是以客户端碰巧启动进程的位置为起点。根目录之外的路径和不存在的路径返回相同的消息 – 如果两者各不相同,就等于对您机器上的任何路径都回答了“这个文件存在吗?”。
远程图像必须是公网 https
image_url 由服务器下载,因此协议必须是 https:,且主机只能解析到公网地址:环回、私有、链路本地、运营商级 NAT、组播和保留地址段都会被拒绝,包括它们的 IPv6 映射写法。只要有一个非公网的解析结果,整个 URL 就会被拒绝。重定向由服务器手动跟随,最多三跳,每一跳都会重新检查。响应体上限为 25 MB,按实际到达的字节计数,而不是相信请求头中的声明。
image_base64 没有上述任何限制,因为调用方本来就持有这些字节 – 这也是上面每一种拒绝都会建议改用它的原因。
阅读指南
- 使用 MCP 服务器 – 配置、工具、防护,以及客户端显示没有工具时应检查什么(英文)。
- API 文档 – 该服务器作为客户端所调用的 HTTP 接口。
- OpenAPI 规范 – 接口契约本身。
- 先在没有账户的情况下调用 – 同样的识别,在终端中完成。