内容
# SponsorFinder MCP 服务器
一个无身份验证、只读的远程 [MCP](https://modelcontextprotocol.io) 服务器,允许 AI 助手(Claude、ChatGPT、Cursor 等)检查公司是否持有 **英国** 或 **荷兰** 的工作签证赞助许可。它代理公共 [SponsorFinder](https://sponsorfinder.io) API,将响应塑造成干净的裁决结果,并将上游 API 密钥保存在服务器端,以便客户端无需凭证连接。
[](./LICENSE)
[](https://nodejs.org)
[](https://modelcontextprotocol.io)
## 功能
SponsorFinder 跟踪两个官方政府许可的工作签证赞助商注册:
- **英国** — [英国内政部许可赞助商注册](https://www.gov.uk/government/publications/register-of-licensed-sponsors-workers),每天从英国内政部发布的 CSV 文件中重建。包含路线(例如 Skilled Worker)、评级(A/B)和地点。
- **荷兰** — [IND 公共认可赞助商注册](https://ind.nl/en/public-register-recognised-sponsors),每天检查。列出认可的赞助商及其赞助类型(WORK / EXCHANGE / STUDY / RESEARCH);比英国数据更薄 - 没有路线、评级或地点。
该 MCP 服务器将这些数据暴露为四个工具。它是 **只读** 和 **客户端无身份验证**:上游 `x-api-key` 是服务器端秘密,MCP 客户端永远不会看到。没有 OAuth,没有用户状态,也没有写入工具。
## 工具
| 工具 | 标题 | 功能 |
| --- | --- | --- |
| `check_sponsor_license` | 检查赞助许可 | 主要工具。通过名称(容错)解析公司并返回裁决 - `licensed`、`formerly_licensed`、`ambiguous` 或 `not_found` - 以及路线、评级、地点和注册日期。拒绝对弱匹配进行猜测。 | `company_name`(2-100 个字符,允许输入错误)、`country`(`uk` \| `nl` \| `both`,默认为 `both`) |
| `search_sponsors` | 搜索赞助商注册 | 探索性列表搜索,带有可选筛选器。返回紧凑的列表和总计数。对于一个特定的公司,优先使用 `check_sponsor_license`。 | `query?`、`country`(`uk` \| `nl`,默认为 `uk`)、`city?`(英国)、`route?`(英国)、`sponsor_type?`(荷兰:`WORK` \| `EXCHANGE` \| `STUDY` \| `RESEARCH`)、`limit`(1-20,默认为 10) |
| `get_sponsor_details` | 获取赞助商详情 | 一个组织的完整记录,ID:路线/评级/地点/日期(英国)或赞助类型 + KvK 号码(荷兰)。可选地包括注册变更历史。 | `org_id`(int)、`country`(`uk` \| `nl`,默认为 `uk`)、`include_history`(bool,默认为 `false`) |
| `get_register_info` | 关于赞助商注册 | 注册统计数据、数据新鲜度、术语词汇表和法律免责声明。使用它来解释许可证、路线、评级或赞助类型是什么意思。 | 无 |
每个工具都带有 `readOnlyHint: true` 注解,并返回一个人类可读的文本块和 `structuredContent`,每个都带有数据新鲜度日期和来源说明。
## 示例提示
一旦连接服务器,可以向助手提出以下自然语言问题:
- “谷歌是否持有英国赞助许可?”
- “ASML 是否是荷兰的认可赞助商?”
- “搜索曼彻斯特的英国 Skilled Worker 赞助商。”
- “列出与'shell'匹配的荷兰 WORK 类型赞助商。”
- “B 评级是什么意思?”
**名称匹配说明。** 模糊匹配容忍输入错误(例如 `googel uk`),但需要一个 **相对完整的名称** 来自信地解析 - “Google UK” 或 “Google UK Limited” 清晰地解析,而单个裸词可以匹配许多公司。服务器故意 **拒绝对弱或绑定匹配进行猜测**:它不会无声地选择一个,而是返回一个 `ambiguous` 裁决和候选人列表,并要求用户进行消歧义(或使用正确的 ID 调用 `get_sponsor_details`)。注册的缺席本身就是一个有意义的答案:它意味着公司当前无法赞助该签证类型。
## 使用(托管)
服务器托管在:
```
https://mcp.sponsorfinder.io/mcp
```
**Claude 代码**
```bash
claude mcp add --transport http sponsorfinder https://mcp.sponsorfinder.io/mcp
```
**claude.ai** - 设置 → 连接器 → **添加自定义连接器** → 粘贴上述 URL。无需身份验证。
**ChatGPT** - 设置 → 连接器(或自定义 GPT 操作)→ **添加** 自定义/远程 MCP 连接器并粘贴上述 URL。
任何支持 Streamable HTTP 的 MCP 客户端都可以以相同的方式连接 - 将其指向 `https://mcp.sponsorfinder.io/mcp`。
## 本地运行
**前提条件:** Node.js 24 和 pnpm 11。
```bash
pnpm install
cp .env.example .env
# 然后编辑 .env 并填写:
# SPONSORFINDER_API_BASE 例如 https://api.sponsorfinder.io
# SPONSORFINDER_API_KEY 您的上游 x-api-key(服务器端秘密)
```
运行两个传输之一的监视模式:
```bash
pnpm dev:stdio # stdio 传输(Claude Desktop / Claude Code / MCP Inspector)
pnpm dev:http # Streamable HTTP 在 http://localhost:3001/mcp
```
**将本地 stdio 构建添加到 Claude Code:**
```bash
pnpm build
claude mcp add sponsorfinder -- node dist/entry/stdio.js
```
**使用 MCP Inspector 与任一传输交互检查工具:**
```bash
npx @modelcontextprotocol/inspector
```
## 配置
所有配置均通过环境变量(见 `.env.example`):
| 名称 | 必需 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `SPONSORFINDER_API_BASE` | 是 | - | 上游 SponsorFinder API 的基本 URL,没有尾随斜杠(例如 `https://api.sponsorfinder.io`)。 |
| `SPONSORFINDER_API_KEY` | 是 | - | 上游 `x-api-key` 头值。**服务器端秘密 - 永远不会暴露给 MCP 客户端**、工具输出、错误或日志。 |
| `PORT` | 否 | `3001` | Node 入口的 HTTP 端口(`src/entry/node.ts`)。stdio 和 Cloudflare Workers 忽略。 |
| `UPSTREAM_TIMEOUT_MS` | 否 | `10000` | 上游请求超时,毫秒(通过 `AbortSignal.timeout()` 终止)。 |
`SPONSORFINDER_API_KEY` 是唯一的秘密。MCP 客户端连接无身份验证;密钥仅存在于服务器(Docker 环境变量或 Cloudflare Workers 秘密)中,从不向客户端公开。
## 自托管 / 部署
Web 标准核心在 Node 和 Cloudflare Workers 上运行;只有入口文件不同。
**Docker(主要)** - 镜像 `ghcr.io/alirezahamid/sponsor-finder-mcp`,`Dockerfile` 和 `docker-compose.yml` 中的配置:
```bash
docker compose up -d
```
在 `mcp.sponsorfinder.io` 前面放置一个反向代理(Caddy/nginx),并将 **POST、GET 和 DELETE** 请求传递到 `/mcp`。Streamable HTTP 需要响应 **buffering off**(nginx 中的 `proxy_buffering off;`;Caddy 的默认值是好的)。
**Cloudflare Workers** - `wrangler.jsonc` 中的配置:
```bash
wrangler secret put SPONSORFINDER_API_KEY
pnpm deploy:worker
```
## 开发
| 脚本 | 功能 |
| --- | --- |
| `pnpm typecheck` | 使用 `tsc --noEmit` 进行类型检查。 |
| `pnpm lint` | 使用 ESLint 进行 lint。 |
| `pnpm test` | 运行单元测试(不包括烟雾测试)。 |
| `pnpm test:smoke` | 针对真实的预发布 API 进行集成烟雾测试(需要机密)。 |
| `pnpm build` | 使用 tsup 构建到 `dist/`。 |
| `pnpm check` | 一次执行 `typecheck` + `lint` + `test`。 |
## 分析(可选)
服务器可以通过服务器端 [Measurement Protocol](https://developers.google.com/analytics/devguides/collection/protocol/ga4) 将使用情况报告给 **Google Analytics 4**。由于 MCP 服务器没有浏览器,因此不能运行 GA/GTM JavaScript 标签 - 服务器改为通过 HTTP 发送事件。它适用于 Node 和 Cloudflare Workers。
除非同时设置了 `GA_MEASUREMENT_ID` 和 `GA_API_SECRET`,否则分析 **关闭**。每个工具调用都会发出一个 `mcp_tool_calls` 事件,带有 **分类参数** - `tool`、`status`、`verdict`、`country`、`mcp_client`、`latency_bucket`、`error_kind`。默认情况下,**不会将公司名称或自由文本查询发送到 GA**;如果您选择启用 `CAPTURE_QUERY_NAMES`,则只会将搜索的名称作为 `query` 参数包含(请参见下文)。
设置:
1. 创建一个 GA4 属性(免费)和一个 Web 数据流。
2. 在 **Admin → Data streams → your stream → Measurement Protocol API secrets** 中,创建一个秘密。复制流的 **Measurement ID** (`G-XXXXXXXXXX`) 和秘密值。
3. 设置 `GA_MEASUREMENT_ID` 和 `GA_API_SECRET`(env / Docker / `wrangler secret`)。
4. 在 GA4 中,将上述事件参数注册为 **custom dimensions**(Admin → Custom definitions),以便它们出现在报告中。使用 `GA_DEBUG=true` 在测试期间将事件发送到 GA 的验证端点。
未满足需求分析:设置 `CAPTURE_QUERY_NAMES=true` 会将搜索的公司名称记录到服务器的结构化日志中 **和** 将其作为 GA4 中的 `query` 事件参数发送(注册一个 `query` 自定义维度以查看它)。默认情况下关闭。注意事项:原始名称在 GA 中具有高基数(分桶为 `(other)`),并且具有姓名的查询可能根据 GA 的条款被视为 PII - 私有日志存储通常是这些的更好归宿,您应该在启用之前添加一个隐私政策行。
## 工作原理
服务器是一个薄的无状态代理,具有响应塑形。MCP 客户端通过 stdio 或无状态 Streamable HTTP 连接;一个小的 [Hono](https://hono.dev) 应用程序(带有 `@hono/mcp`)为每个请求构造一个 MCP 服务器,调用 SponsorFinder API 并带有服务器端密钥,使用 zod 验证每个响应(一个契约漂移防护),并将其塑形为一个紧凑的裁决。注册统计数据和筛选值在进程内使用短 TTL 进行缓存。由于核心仅使用 Web 标准 API (`fetch`, `URL`),因此相同的代码在 Node 和 Cloudflare Workers 上运行 - 只有 `src/entry/*` 不同。
```
MCP 客户端(Claude / ChatGPT / Cursor)
│ stdio 或无状态 Streamable HTTP
▼
SponsorFinder MCP 服务器 (Hono + @hono/mcp)
• 4 个只读工具,zod 验证
• 服务器端添加 x-api-key
• 缓存 /status + /filters
│ HTTPS (x-api-key)
▼
SponsorFinder API → 英国英国内政部注册 + 荷兰 IND 注册
```
## 数据和免责声明
数据来自官方的 [英国 gov.uk 许可赞助商注册](https://www.gov.uk/government/publications/register-of-licensed-sponsors-workers) 和 [荷兰 IND 公共认可赞助商注册](https://ind.nl/en/public-register-recognised-sponsors),每天刷新。
该工具 **仅供信息使用,不构成法律建议**。注册数据可能会延迟官方发布,并且许可证并不保证公司会赞助某个特定职位。在做出决定之前,请始终与官方来源进行验证。
## 贡献
问题和拉取请求欢迎在 [github.com/alirezahamid/sponsor-finder-mcp](https://github.com/alirezahamid/sponsor-finder-mcp) 上提出。请在打开 PR 之前运行 `pnpm check`。
> **发布说明:** `server.json` 是官方 MCP 注册表的清单。在运行 `mcp-publisher publish` 之前,请确认确切的 `$schema` URL 与当前的 [registry.modelcontextprotocol.io](https://registry.modelcontextprotocol.io) 文档相符 - 这里固定的模式版本可能已经移动。
## 许可证
[MIT](./LICENSE) © 2026 Alireza Hamid