关于 Open Archives
Open Archives MCP Server 将荷兰 Open Archives 的家谱档案、统计数据、历史天气和文献转录内容提供给研究者及家谱用户。它根据 OpenAPI 规范生成工具,并带有可交互的转录页面查看器。
主要功能
- 01搜索及查看家谱记录
- 02查询档案与记录统计
- 03检索历史天气及人口普查
- 04搜索和浏览文献转录
- 05交互式 IIIF 转录查看器
适用场景
- 01查找出生、死亡和婚姻记录
- 02研究荷兰历史人口普查数据
- 03检索历史文献页面的全文转录
MCP 相关
通过 Streamable HTTP 提供 MCP 工具,涵盖 Open Archives 的记录、统计、天气、普查与转录 API;另有交互式转录查看器工具。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mcp.openarchieven.nl/claude mcp add --transport http coret-openarchieven https://mcp.openarchieven.nl/{"mcpServers":{"coret-openarchieven":{"type":"http","url":"https://mcp.openarchieven.nl/"}}}在 Cursor 中打开{"servers":{"coret-openarchieven":{"type":"http","url":"https://mcp.openarchieven.nl/"}}}在 VS Code 中打开{"mcpServers":{"coret-openarchieven":{"type":"http","url":"https://mcp.openarchieven.nl/"}}}{"mcpServers":{"coret-openarchieven":{"serverUrl":"https://mcp.openarchieven.nl/"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
22| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| lang | enum | 否 | nl | en |
| name | string | 是 | |
| sort | enum | 否 | -6 | -5 | -4 | -3 | -2 | -1 | 1 | 2 | 3 | 4 | 5 | 6 |
| start | integer | 否 | |
| birthplace | string | 否 | |
| eventplace | string | 否 | |
| sourcetype | string | 否 | |
| not_archive | enum | 否 | 0 | 1 |
| number_show | integer | 否 | |
| archive_code | string | 否 | |
| country_code | string | 否 | |
| relationtype | string | 否 |
详细介绍
Open Archives MCP 服务
由 Open Archives OpenAPI 规范生成的生产级混合 MCP + HTTP + SSE 服务。涵盖家谱记录(出生、死亡、婚姻、人口普查)、档案统计、历史天气,以及历史文献的全文页面转录。
用于生成工具的 OpenAPI 源:
../api/openapi.yaml (local)
https://api.openarchieven.nl/openapi.yaml (remote)
概述
一个具备架构感知能力的服务,可自动将 OpenAPI 规范转换为可调用工具,并通过多种传输方式提供服务:
- MCP 远程服务(基于 StreamableHTTP 的 JSON-RPC)
- HTTP JSON API
- 支持自动分页的 SSE 流式传输
- 支持自动分页的分块 HTTP 流式传输
- Redis 缓存(可选)
- 健康检查
视频(荷兰语):通过 MCP 为你的遗产服务提供 AI 助手
与 Claude 配合使用
添加为自定义连接器
提供托管端点,无需安装。
在 claude.ai 或 Claude Desktop 中:
- 打开 设置 → 连接器。
- 点击 添加自定义连接器。
- 输入 URL:
https://mcp.openarchieven.nl/ - 保存,并在出现提示时批准。
无需身份验证——Open Archives 是一个公共数据集。
示例查询
添加连接器后,你可以向 Claude 提问,例如:
- “Johannes Gregorius Marinus Coret 的祖先有哪些?请提供概览,并以 Markdown 格式附上来源引用;如果可能,请提供原始档案的链接,否则请提供 Open Archieven 链接,并用 SVG 绘制家谱树。”
- “Johannes Coret 和 Antonia Uphus 有后代吗?请提供概览,并以 Markdown 格式附上来源引用;如果可能,请提供原始档案的链接,否则请提供 Open Archieven 链接;如果有档案扫描缩略图,也请附上,并用 SVG 绘制家谱树。”
- “请按档案(名称)列出我可以在哪里找到 Coret 家族相关信息的来源类型。请将结果整理成 Markdown 文档,并附上 Open Archieven 搜索页面的链接。如果有 ISIL,请用它替代档案代码。”
- “1953-02-01 阿姆斯特丹的天气如何?”
- “1850 年的人口普查中关于乌得勒支有哪些记载?”
Claude 将调用相应的工具(search_records、show_record、
get_marriages、get_historical_weather、get_census_data 等),
并返回指向
https://www.openarchieven.nl 上对应记录页面的链接。
可自托管
该服务通过 Streamable HTTP 提供 MCP 服务;不提供 stdio 发行版。若要运行 自己的实例:
git clone https://github.com/coret/openarchieven-mcp-server.git
cd openarchieven-mcp-server
npm install
npm run generate # builds generated/tools.json from openapi.yaml
npm run build:viewer # builds dist/viewer.html (the MCP App)
npm start # listens on http://localhost:3001/
将 MCP 客户端指向 http://localhost:3001/(或你自己的公共 URL),操作方式与上文托管端点相同。
核心功能
OpenAPI 自动生成
每个 API 操作都会通过 generate.ts 自动转换为工具。
全部 21 个操作:
| 工具名称 | 描述 |
|---|---|
search_records | 搜索家谱记录 |
show_record | 显示单条家谱记录 |
match_record | 将某人与出生和死亡记录进行匹配 |
get_births_years_ago | 列出 N 年前的出生记录 |
get_births | 查找出生记录 |
get_deaths | 查找死亡记录 |
get_marriages | 查找婚姻记录 |
get_archives | 列出所有档案及其统计信息 |
get_record_stats | 各档案的记录数量 |
get_source_type_stats | 各来源类型的记录数量 |
get_event_type_stats | 各事件类型的记录数量 |
get_comment_stats | 评论数量统计 |
get_family_name_stats | 姓氏出现频率 |
get_first_name_stats | 名字出现频率 |
get_profession_stats | 职业出现频率 |
get_breakdown | 按档案、来源类型、事件类型、地点或年份分组的交叉统计 |
get_historical_weather | KNMI 历史天气 |
get_census_data | 荷兰 1795–1899 年人口普查数据 |
search_transcriptions | 在历史文献页面的转录文本中进行全文搜索 |
browse_transcriptions | 按来源档案、档案编号或目录分层浏览转录文本 |
show_transcription | 按 ID 获取单页转录文本 |
注意: 上游 API 中的
callback(JSONP)参数已从所有工具中排除——它与 MCP/JSON-RPC 上下文无关。
交互式转录查看器(MCP App)
除 21 个自动生成的工具外,服务还注册了一个手写工具——view_transcription——它使用 MCP Apps 扩展(io.modelcontextprotocol/ui),在交互式 IIIF 深度缩放查看器(OpenSeadragon)中打开已转录的页面,并在旁边显示转录文本。
| 工具名称 | 描述 |
|---|---|
view_transcription | 在带有转录文本的 IIIF 深度缩放查看器中打开一个或多个已转录页面(ids: ["NL-SdmGA_1504889_11", …]);可选参数 highlight_term |
- 支持 Apps 的宿主(Claude 网页版/桌面版、付费自定义连接器)会在沙盒 iframe 中渲染查看器(
ui://openarchieven/viewer.html),并直接从转录图像托管站加载图像(CSP 允许列表包含*.transkribus.eu、*.archief.nl、*.archieven.nl、*.memorix.nl)。Transkribus 和 archief.nl iipsrv 服务支持真正的 IIIF 深度缩放;preserve*.archieven.nl缩略图托管站则以平面图像形式渲染。 - 普通宿主会收到完善的回退内容:包含 IIIF/来源 URL 的文本摘要,以及几张内嵌预览图像。
查看器是一个独立的 dist/viewer.html,在构建时通过 npm run build:viewer(vite + vite-plugin-singlefile)打包;它不会列在 REST GET /tools 端点中,只能通过 MCP tools/list 获取。
精确匹配 Schema 的验证
使用实际的 OpenAPI 参数 Schema。验证以下内容:
- 必填参数
- 整数字段
- 数字字段
- 枚举值
- 最小值 / 最大值约束
多种接口
MCP 远程(StreamableHTTP)
POST / ← canonical public endpoint (mcp.openarchieven.nl)
POST /mcp ← local / legacy alias
无状态 JSON-RPC 传输——每个请求都会创建一个新的 MCP 服务实例。
来源验证: 浏览器请求必须来自
claude.ai、claude.com或ALLOWED_ORIGINS中列出的任何域名。没有Origin标头的请求(原生 MCP 客户端、curl、服务到服务请求)会被 接受。未知来源会收到 HTTP 403。
HTTP JSON
GET /tools
POST /tools/:name
SSE 流式传输(自动分页)
GET /events/:name
分块 HTTP 流式传输(自动分页)
POST /stream/:name
发现元数据(/.well-known)
从 well-known/ 提供的静态、可手动编辑的 JSON 文件,内容原样返回:
GET /.well-known/mcp/server-card.json ← SEP-1649 MCP Server Card
GET /.well-known/mcp.json ← alias of the server card
GET /.well-known/agent-card.json ← A2A v0.3 Agent Card
GET /.well-known/agent.json ← alias of the agent card
直接编辑 well-known/mcp-server-card.json 和 well-known/agent-card.json 即可,无需重启(每次请求都会读取文件)。响应的 Content-Type 为 application/json; charset=utf-8,Cache-Control 为 public, max-age=3600。
分页
流式端点(/events/:name、/stream/:name)会自动对支持 start 偏移量的端点结果进行分页:
- 每页将
start增加number_show - 结果耗尽或达到 20 页(安全上限)后停止
- SSE 每 10 秒发送一条
: heartbeat注释,以保持连接
Redis 缓存
可选的 Redis 支持。
如果 Redis 正在运行,上游响应会按工具进行缓存,并根据数据的变动频率设置 TTL:
| 类别 | TTL | 工具 |
|---|---|---|
| 不可变的历史数据 | 永不过期 | get_historical_weather、get_census_data |
| 缓慢变化的元数据 | 7 天 | get_archives |
| 统计聚合数据 | 1 天 | get_record_stats、get_source_type_stats、get_event_type_stats、get_comment_stats、get_family_name_stats、get_first_name_stats、get_profession_stats、get_breakdown |
| 单条记录查询 | 1 天 | show_record、show_transcription |
| 搜索类 | 6 小时 | search_records、match_record、get_births、get_deaths、get_marriages、search_transcriptions、browse_transcriptions |
| 按日期限定 | 下一个 UTC 午夜 | get_births_years_ago |
CACHE_TTL(默认值为 3600)是上表未列出的工具的回退值。
如果 Redis 不可用:
- 服务仍会正常运行(降级模式)
速率限制
上游 API 对每个 IP 限制为每秒 4 个请求。服务会通过令牌桶速率限制器对所有上游调用进行排队(可通过 RATE_LIMIT_RPS 配置)。
健康检查
GET /health
项目文件
generate.ts
server.ts
tsconfig.json
package.json
.env.example
generated/
tools.json
spec.json
要求
- Node.js 18+
- npm
- 可选的 Redis 服务
配置
将 .env.example 复制为 .env,然后进行调整:
cp .env.example .env
| 变量 | 默认值 | 描述 |
|---|---|---|
PORT | 3001 | HTTP 端口 |
OPENAPI_PATH | ../api/openapi.yaml | OpenAPI 规范的路径或 URL |
UPSTREAM_BASE | https://api.openarchieven.nl/1.1 | 上游 API 基础 URL |
RATE_LIMIT_RPS | 4 | 上游每秒请求数 |
REDIS_URL | redis://localhost:6379/5 | Redis 连接 URL(db 5) |
CACHE_TTL | 3600 | 回退缓存 TTL(以秒为单位,用于不在单工具映射中的工具;请参阅Redis 缓存) |
LOG_LEVEL | info | trace debug info warn error fatal |
NODE_ENV | (unset) | 设置为 production 时使用 JSON 日志(默认:美化格式) |
ALLOWED_ORIGINS | (empty) | MCP 端点允许的额外 Origin 标头(以逗号分隔)。始终允许 Claude 域名,以及不带 Origin 标头的请求。 |
安装
npm install
根据 OpenAPI YAML 生成工具
使用本地规范运行:
npx tsx generate.ts
或使用远程 URL:
npx tsx generate.ts https://api.openarchieven.nl/openapi.yaml
预期结果:
Generated 21 tools
Output: generated/tools.json, generated/spec.json
将创建:
generated/tools.json
generated/spec.json
启动服务
npx tsx server.ts
预期启动输出(开发环境 — 美化格式):
[12:00:00] INFO: Open Archieven MCP server started
port: 3001
tools: 21
upstream: "https://api.openarchieven.nl/1.1"
rateLimit: "4 req/s"
redis: "redis://localhost:6379/5"
env: "development"
在生产环境(NODE_ENV=production)中,每条日志行都是一个 JSON 对象。
服务绑定到:
http://0.0.0.0:3001
测试所有功能
1. 健康检查
curl http://localhost:3001/health
预期结果:
{
"ok": true,
"tools": 21,
"redis": false,
"uptime": 1.23
}
2. 列出工具
curl http://localhost:3001/tools
预期结果:
[
"search_records",
"show_record",
"match_record",
"get_births_years_ago",
"get_births",
"get_deaths",
"get_marriages",
"get_archives",
"get_record_stats",
"get_source_type_stats",
"get_event_type_stats",
"get_comment_stats",
"get_family_name_stats",
"get_first_name_stats",
"get_profession_stats",
"get_historical_weather",
"get_census_data",
"search_transcriptions",
"browse_transcriptions",
"show_transcription"
]
3. 调用工具
curl -X POST http://localhost:3001/tools/search_records \
-H "Content-Type: application/json" \
-d '{"name":"Coret"}'
4. 显示单条记录
curl -X POST http://localhost:3001/tools/show_record \
-H "Content-Type: application/json" \
-d '{"archive":"hua","identifier":"E13B9821-C0B0-4AED-B20B-8DE627ED99BD"}'
5. SSE 流式传输
curl -N "http://localhost:3001/events/search_records?name=Coret"
预期流:
event: page
data: {...}
event: page
data: {...}
event: done
data: {}
6. 心跳测试
保持 SSE 连接打开 15 秒以上,预期会定期收到保持连接的行:
: heartbeat
7. 分块 HTTP 流式传输
curl -N -X POST http://localhost:3001/stream/search_records \
-H "Content-Type: application/json" \
-d '{"name":"Coret"}'
预期结果(以换行符分隔的 JSON):
{"query":{...},"response":{"number_found":...,"docs":[...]}}
{"query":{...},"response":{"number_found":...,"docs":[...]}}
8. MCP 初始化
curl -X POST http://localhost:3001/ \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": { "name": "test", "version": "1.0" }
}
}'
9. MCP 列出工具
curl -X POST http://localhost:3001/ \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}'
10. MCP 调用工具
curl -X POST http://localhost:3001/ \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search_records",
"arguments": { "name": "Coret" }
}
}'
Redis 测试
启动 Redis
redis-server
重启 MCP 服务。在 /health 中应看到:
{ "redis": true }
不使用 Redis
停止 Redis 并重启。应看到:
{ "redis": false }
常用命令
API 变更后重新生成
npx tsx generate.ts
重启服务
npx tsx server.ts
运行测试
npm test
测试使用 Node 内置的测试运行器覆盖每个工具的 TTL 策略(cache-ttl.ts),无需额外依赖。覆盖率测试会断言 generate.ts 生成的每个工具都有明确的 TTL 条目,因此在上游 OpenAPI 发生变更后重新运行 npm run generate,即可发现任何需要决定 TTL 的新工具。
故障排除
缺少生成的文件
npx tsx generate.ts
端口已被占用
Linux / macOS:
lsof -i :3001
kill -9 <PID>
Windows:
netstat -ano | findstr :3001
taskkill /PID <PID> /F
Redis 无法连接
不使用 Redis 时,服务也能正常运行。请检查 .env 中的 REDIS_URL。
速率限制错误(429)
上游 API 对每个 IP 的限制为 4 req/s。内置速率限制器会自动对请求排队。如果运行多个服务实例,请降低 RATE_LIMIT_RPS,或使用共享队列。
隐私政策
此服务是对公开 Open Archives API 的轻量代理。它不需要用户 身份验证,也不会自行收集个人数据。
除本节内容外,还适用运营方的完整隐私政策:
数据收集
- 工具参数(例如搜索姓名、档案代码、记录 标识符)由 MCP 客户端提供。
- HTTP 请求元数据——方法、路径、状态代码、延迟和
来源 IP——由托管端点
mcp.openarchieven.nl前方的反向代理 观测。 - 不会收集账户、Cookie、令牌或会话标识符。 此服务在设计上是匿名的。
使用与存储
- 工具参数会通过 HTTPS 原样转发到
https://api.openarchieven.nl/1.1以完成请求,上游响应则返回给调用方。 - 应用日志(工具名称、参数、状态、延迟)通过 pino 写入
stdout。在托管端点上,这些日志是临时的:不会写入磁盘,且会在进程重启时 丢失。设置LOG_LEVEL=warn可禁止记录参数。 - 缓存(可选):配置 Redis 后,上游响应会以
mcp:<tool>:<sorted-params-json>形式的键进行缓存。 缓存仅包含响应正文;不会存储用户标识符。
与第三方共享
不会向上文列出的上游 Open Archives API 以外的任何服务发送数据。没有涉及任何分析、遥测、广告或 可观测性第三方服务。
数据保留
| 数据 | 保留时间 |
|---|---|
| 工具参数和响应 | 应用不会持久化 |
| 应用日志 | 临时(stdout,重启时丢失) |
| Redis 缓存条目 | 按工具设置 TTL(6 小时–7 天;不可变的历史查询永不过期)。参见 Redis 缓存。 |
| 反向代理访问日志 | 按托管服务提供商的标准保留政策 |
安全
MCP 端点会验证每个请求的 Origin 标头,并拒绝未知的浏览器来源(防范 DNS 重绑定)。所有传输均使用
HTTPS。
向客户端展示的外部链接
工具响应中包含指向 https://www.openarchieven.nl 上记录页面的 URL。提交内容声明了以下
允许的链接 URI,因此用户无需逐个确认链接:
https://www.openarchieven.nl
联系方式
如有隐私相关问题或请求,请联系:
- 电子邮箱:
[email protected] - GitHub: 提交 issue
推荐的生产环境升级
- HTTPS 反向代理(nginx / caddy)
- PM2 或 systemd 进程管理器
- 结构化 JSON 日志(pino / winston)
- 请求追踪(OpenTelemetry)
- 如果服务面向公众,则使用身份验证中间件
- 多实例部署时使用共享 Redis
版本
v1.0
为 Open Archives 提供符合 Schema 规范的 OpenAPI 生成 MCP 服务。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。