内容
# signrequest-mcp-worker
[SignRequest](https://signrequest.com) 电子签名 API 以 **远程 MCP 服务器** 的形式公开,运行为 **Cloudflare Worker**(可流式传输的 HTTP + SSE)。构建于 [`agents`](https://github.com/cloudflare/agents) `McpAgent` 上。
它公开了 **32 种工具** 用于文档签名工作流程 — 创建和发送签名请求,跟踪,取消/提醒,删除,附加文件,读取文档,模板,事件和团队 — 以及企业额外功能,这些功能是原始 API 所缺乏的:一次性签名者摘要,**整个团队的活动汇总**,**批量发送**,平面字段提取,批量 + 自动分页读取,有限轮询和安全的无需电子邮件的签名链接生成器。工具定义位于 [`src/tools.ts`](src/tools.ts) 中,SignRequest REST 客户端位于 [`src/signrequest.ts`](src/signrequest.ts) 中;两者都是传输无关的,因此每个构建都共享相同的工具界面。
此仓库提供了 **从同一代码部署两个版本**:
| Worker | 认证 | 使用它 | 入口 |
|--------|------|--------|-------|
| **`signrequest-mcp`** | 静态 bearer token | Claude Code,Claude Desktop,程序化 | [`src/index.ts`](src/index.ts) · [`wrangler.jsonc`](wrangler.jsonc) |
| **`signrequest-mcp-oauth`** | OAuth 2.1(单用户 passphrase) | **Claude.ai web** 自定义连接器 | [`src/oauth.ts`](src/oauth.ts) · [`wrangler.oauth.jsonc`](wrangler.oauth.jsonc) |
> **状态:** 两个部署版本都经过类型检查,捆绑和部署干净。机密通过 `wrangler secret put` 设置,并且 **从不** 提交到此仓库。
---
## 目录
- [架构](#架构)
- [端点](#端点)
- [认证](#认证)
- [工具](#工具)
- [SignRequest API覆盖](#signrequest-api覆盖)
- [配置](#配置)
- [部署](#部署)
- [验证](#验证)
- [测试](#测试)
- [连接客户端](#连接客户端) — [Claude Code](#claude-code) · [Claude Desktop](#claude-desktop) · [Claude Web](#claude-web) · [程序化](#程序化)
- [OAuth worker(Claude.ai web)](#oauth-worker-claudeai-web)
- [注意事项](#注意事项)
- [项目布局](#项目布局)
---
## 架构
```
客户端 bearer worker (src/index.ts)
Claude Code / Desktop / curl ── Authorization: Bearer <MCP_AUTH_TOKEN> ──┐
│
Claude.ai web ── OAuth 2.1 (passphrase) ── oauth worker (src/oauth.ts) ──┤
▼
SignRequestMCP (McpAgent, Durable Object)
• registerTools(server, client) ← tools.ts
• SignRequestClient ← signrequest.ts
│
Authorization: Token <SIGNREQUEST_TOKEN>
▼
SignRequest REST API v1
```
- **`McpAgent` + Durable Object.** MCP 会话状态存储在 Cloudflare Durable Object(SQLite 支持,迁移 `v1`)中。两个 worker 都将其绑定为 `MCP_OBJECT` → `SignRequestMCP` 类。
- **共享工具层。** `registerTools()` 和 `SignRequestClient` 是普通的 TypeScript,没有 Worker 特定的导入,因此 bearer worker,OAuth worker 和本地 stdio 构建都共享它们。
- **`src/ai-stub.ts`** 将 `agents` 的未使用的可选 `ai` peer 依赖项从 bundle 中别名出来。
---
## 端点
Bearer worker (`signrequest-mcp`):
| 方法 | 路径 | 认证 | 目的 |
|--------|----------------|--------|------------------------------------------|
| `GET` | `/` | 无 | 健康检查 → `signrequest-mcp worker: ok` |
| `POST` | `/mcp` | Bearer | MCP 流式 HTTP(现代客户端) |
| `GET` | `/sse` | Bearer | MCP SSE(旧客户端) |
OAuth worker (`signrequest-mcp-oauth`) — 参见 [OAuth worker](#oauth-worker-claudeai-web)。
---
## 认证
**Bearer worker** 由 **共享 bearer token** (`MCP_AUTH_TOKEN`) 控制:失败关闭(无机密 → 所有 401),恒定时间比较,SignRequest token 从不离开 Worker。适合程序化使用,`mcp-remote`,Claude Code/Desktop。
**OAuth worker** 实现 **OAuth 2.1**(PKCE + 动态客户端注册)通过 [`@cloudflare/workers-oauth-provider`](https://github.com/cloudflare/workers-oauth-provider),由单个共享 **passphrase** (`APP_PASSPHRASE`) 控制在 consent 屏幕上 — 这是 Claude.ai web 接受的唯一模型。
---
## 工具
所有工具都调用外部服务(`openWorldHint: true`)。“发送电子邮件”表示 SignRequest 分派真正的签名电子邮件。
### 创建和发送
#### `signrequest_quick_create`
创建文档 **和** 发送签名请求,一次调用 — 最常见的入口点。*写入 · 发送电子邮件.*
| 字段 | 类型 | 备注 |
|-------|------|-------|
| *文档源* | — | 恰好一个 `file_from_url`,`file_from_content`(+ `file_from_content_name`),或 `template` |
| `file_from_url` | 字符串(url) | 公共 URL SignRequest 下载 — 优选于除小文件以外的任何文件 |
| `file_from_content` | 字符串 | base64 文件内容 — 仅限小文件 |
| `file_from_content_name` | 字符串 | 文件名 **带** 扩展名,例如 `contract.pdf`;如果设置了 `file_from_content`,则必填 |
| `template` | 字符串(url) | 模板资源 URL,基于该模板创建文档 |
| `signers` | Signer[] | **必填**,最少 1 个 — 参见 [Signer](#signer-object) |
| `from_email` | 字符串(电子邮件) | 发送者;必须属于令牌的团队;默认为 `SIGNREQUEST_FROM_EMAIL` |
| `from_email_name`,`subject`,`message` | 字符串 | `message` 允许有限的 HTML(`a,b,i,em,strong,ul,ol,li,blockquote,code,abbr,acronym`) |
| `send_reminders` | 布尔值 | 自动提醒未签名的签名者 |
| `who` | `m` \| `o` \| `mo` | `m`=仅我,`o`=仅其他人,`mo`=两者 |
| `external_id`,`name`,`events_callback_url` | 字符串 | 您的参考 ID · 显示名称 · 文档的 webhook URL |
| `disable_emails` | 布尔值 | 禁止 SignRequest 状态电子邮件(嵌入式签名者 = 完全静默) |
| `dry_run` | 布尔值 | 预览 **将** 被电子邮件通知;不创建/发送任何内容 |
#### `signrequest_create_document`
创建文档 **而不** 发送它。返回一个带有 `url`/`uuid` 的文档,您可以稍后传递给 `signrequest_send`。*写入 · 不发送电子邮件。* 接受上述文档源字段以及 `external_id`,`name`,`events_callback_url`。
#### `signrequest_send`
为 **现有** 文档发送签名请求。*写入 · 发送电子邮件。* 字段:`document`(资源 URL,**必填**),`signers`(**必填**),`from_email`,`from_email_name`,`subject`,`message`,`send_reminders`,`who`。
### 跟踪和管理
| 工具 | 目的 | 输入 | 类 |
|------|---------|-------|-------|
| `signrequest_get` | 获取一个签名请求 — 状态,签名者,谁已签名/拒绝/查看 | `uuid` | 只读 |
| `signrequest_list` | 列出签名请求(最近的优先) | `page?`,`external_id?` | 只读 |
| `signrequest_cancel` | 取消请求;未签名的签名者失去访问权限。仅当尚未完全签名/拒绝 | `uuid` | **破坏性**,幂等 |
| `signrequest_resend` | 重新发送签名电子邮件给尚未签名的签名者(`dry_run?` 预览) | `uuid`,`dry_run?` | 写入 · 发送电子邮件 |
### 文档和模板
| 工具 | 目的 | 输入 | 类 |
|------|---------|-------|-------|
| `signrequest_get_document` | 获取文档 — 转换状态,签署的 PDF URL,安全哈希,签名日志(`compact?` = 精简摘要) | `uuid`,`compact?` | 只读 |
| `signrequest_list_documents` | 列出文档(最近的优先) | `page?`,`external_id?` | 只读 |
| `signrequest_delete_document` | **永久删除** 文档及其签名请求和存储的文件 | `uuid` | **破坏性** |
| `signrequest_list_templates` | 列出模板;使用模板的资源 URL 作为上面的 `template` | `page?` | 只读 |
| `signrequest_get_template` | 获取一个模板 — 它的字段和资源 URL | `uuid` | 只读 |
| `signrequest_search_documents` | 快速搜索 — 按 `signer_emails`,`q`,`name`,`status` 过滤(无盲分页) | 过滤器 | 只读 |
### 事件和团队
| 工具 | 目的 | 输入 | 类 |
|------|---------|-------|-------|
| `signrequest_list_events` | 列出 webhook 交付日志(已签名/拒绝/查看…),用于审计 | `page?` | 只读 |
| `signrequest_get_event` | 获取一个事件,UUID | `uuid` | 只读 |
| `signrequest_list_teams` | 列出令牌可以访问的团队 | `page?` | 只读 |
| `signrequest_list_team_members` | 列出可访问团队的成员 | `page?` | 只读 |
### 附件
| 工具 | 目的 | 输入 | 类 |
|------|---------|-------|-------|
| `signrequest_add_document_attachment` | 将额外文件附加到文档(`file_from_url` 或 base64)— 不是签名字段 | 文档 + 文件源 | 写入 |
| `signrequest_list_document_attachments` | 列出文档附件 | `page?` | 只读 |
| `signrequest_get_document_attachment` | 获取一个附件,UUID | `uuid` | 只读 |
> 签名者**收集的**附件不是一个单独的工具 — 它们通过 `signrequest_get` 内联返回签名者对象(连同签名者的填充 `inputs`)。
### 高级助手和安全
这些工具将原始端点组合成一个调用 — 它们编码了“查找 **已签名** 文档,读取其填充字段”的逻辑,因此调用者不必遍历 `signrequest.signers[].inputs[]` 或猜测哪个人的文档是真实的。
| 工具 | 目的 | 输入 | 类 |
|------|---------|-------|-------|
| `signrequest_whoami` | 令牌健康检查 — 确认 API 令牌有效;返回团队和成员 | — | 只读 |
| `signrequest_get_signer_summary` | **一次性状态**:查找签名的文档并返回状态,签署的 PDF URL,`embed_url` 和填充字段为平面 `{external_id: value}` 映射 | `email`,`name_contains?` | 只读 |
| `signrequest_get_document_fields` | 文档的填充值作为平面 `{external_id: value}` 映射 + 紧凑的签名者 | `uuid`,`signer_email?` | 只读 |
| `signrequest_get_signed_pdf` | 新鲜(时间有限)的签署 PDF + 签名日志 URL | `uuid` | 只读 |
| `signrequest_get_signing_link` | 签名者的嵌入式签名链接(`embed_url`) | `uuid`,`signer_email?` | 只读 |
| `signrequest_get_documents` | 批量获取最多 50 个文档为 **紧凑** 摘要(更少的往返,更少的上下文) | `uuids[]` | 只读 |
| `signrequest_create_embedded_signing_links` | **安全链接生成器** — 为每个签名者强制 `disable_emails` + 嵌入式签名并返回每个 `embed_url`;**不会发送电子邮件** | 文档源 **或** `document`,`signers[]` | 写入 · 无电子邮件 |
**安全标志:** `quick_create` / `send` / `resend` 接受 `dry_run`(预览 **将** 被电子邮件通知,发送内容);`quick_create` 接受 `disable_emails`;`get_document` 接受 `compact`。
### 活动规模和运营
构建在 API 之上,具有有限的并发性,自动分页和轮询 — 用于团队范围的工作流和大型帐户。
| 工具 | 目的 | 输入 | 类 |
|------|---------|-------|-------|
| `signrequest_campaign_status` | **团队汇总** — 为许多人运行签名者摘要(有限并发性)并返回聚合计数和人均状态/字段。一次调用驱动跟踪仪表盘。 | `emails[]`,`name_contains?`,`concurrency?` | 只读 |
| `signrequest_bulk_send` | **批量活动** — 将相同的模板/文件发送给许多收件人(每个请求);每个收件人结果,`dry_run` 和一个 `embedded` 开关(无电子邮件,返回 `embed_urls`) | `template`/`file_from_url`,`recipients[]`,… | 写入 |
| `signrequest_list_all_documents` | 自动分页的文档紧凑列表(无手动分页) | `cap?`,`external_id?` | 只读 |
| `signrequest_list_template_fields` | 发现模板的可填充 `external_id`s / 预填充标签 | `uuid` | 只读 |
| `signrequest_wait_until_signed` | 有限轮询直到已签名/拒绝/取消(≤25s);对于长时间等待使用 webhooks/events | `uuid`,`timeout_seconds?`,`interval_seconds?` | 只读 |
### 操作模式
- **只读部署。** 设置 `MCP_READONLY=true`,工作者仅注册 **只读工具** — 无 `quick_create`/`send`/`bulk_send`/`cancel`/`delete`,它们从不出现在 `tools/list` 中。适合报告/仪表盘连接器。
- **审计轨迹。** 每个状态更改的 API 调用都会记录(`[signrequest-mcp] POST /signrequests/` — 方法 + 路径,仅限 PII),通过 `wrangler tail` 可见。
- **弹性。** 幂等 GET 重试 `429`/`5xx`,带 `Retry-After` 感知回退;写入永远不会自动重试,以避免重复创建/发送或其他惊喜。
### 签名者对象
由 `signrequest_quick_create` 和 `signrequest_send` 使用:
| 字段 | 类型 | 备注 |
|-------|------|-------|
| `email` | 字符串(电子邮件) | **必填** |
| `first_name`,`last_name` | 字符串 | |
| `order` | int | 签名顺序;较低的优先签名。发送者始终为 `0` |
| `language` | 字符串 | `en, en-gb, nl, fr, de, da, fi, hu, it, no, pl, pt, es, sv`。**不支持希伯来语。 |
| `force_language` | 布尔值 | |
| `message` | 字符串 | 签名者特定消息 |
| `redirect_url` | 字符串(url) | 签名后重定向 |
---
## SignRequest API 覆盖
MCP 涵盖 **二十个** SignRequest v1 API 端点 — 文档签名工作流程 + 模板、事件和团队的读取访问权限。下面的 20 个基本工具与 [`src/signrequest.ts`](src/signrequest.ts) 中的方法 1:1 映射;7 个 **高级助手** 组合这些相同的端点(例如搜索 → 获取 → 字段提取):
| 工具 | SignRequest 端点 |
|------|----------------------|
| `signrequest_quick_create` | `POST /signrequest-quick-create/` |
| `signrequest_create_document` | `POST /documents/` |
| `signrequest_send` | `POST /signrequests/` |
| `signrequest_get` | `GET /signrequests/{uuid}/` |
| `signrequest_list` | `GET /signrequests/` |
| `signrequest_cancel` | `POST /signrequests/{uuid}/cancel_signrequest/` |
| `signrequest_resend` | `POST /signrequests/{uuid}/resend_signrequest_email/` |
| `signrequest_get_document` | `GET /documents/{uuid}/` |
| `signrequest_list_documents` | `GET /documents/` |
| `signrequest_delete_document` | `DELETE /documents/{uuid}/` |
| `signrequest_list_templates` | `GET /templates/` |
| `signrequest_get_template` | `GET /templates/{uuid}/` |
| `signrequest_list_events` | `GET /events/` |
| `signrequest_get_event` | `GET /events/{uuid}/` |
| `signrequest_list_teams` | `GET /teams/` |
| `signrequest_list_team_members` | `GET /team-members/` |
| `signrequest_add_document_attachment` | `POST /document-attachments/` |
| `signrequest_list_document_attachments` | `GET /document-attachments/` |
| `signrequest_get_document_attachment` | `GET /document-attachments/{uuid}/` |
| `signrequest_search_documents` | `GET /documents-search/` |
**仍未公开**(存在于 SignRequest v1 API,暂时省略):
- **签名者收集的附件** 作为独立资源 — 通过 `signrequest_get` 内联返回签名者对象(文档附件本身 *支持*,上面)
- **团队写入操作** — 创建/修改团队,从子域获取单个团队,邀请成员
- **API令牌创建/删除** — SignRequest 的 API 仅限列表的令牌(创建/撤销是 Web-UI 仅有的);只读的 `list_api_tokens` 工具可以根据请求添加,但它返回机密令牌值,因此默认省略。 还有 **电子签名披露**。
- 独立签名者资源 — SignRequest 没有;签名者数据在签名请求对象内返回(`signrequest_get`)
如果您需要其中任何一个,请在 `SignRequestClient` 中添加一个方法,并在 `registerTools()` 中添加一个工具。如果需要,可以添加一个只读的 `list_api_tokens` 工具,但它返回机密令牌值,因此默认情况下不包含。
客户端(`Authorization: Token <token>`)重试仅幂等 `GET`s(在 `429`/`5xx` 时,指数退火,遵守 `Retry-After`);状态更改 `POST`/`DELETE` 调用 **永远不会** 自动重试,以避免重复创建/发送或其它惊喜。
---
## 配置
通过 `npx wrangler secret put <NAME>`(机密)或 `[vars]` 块(非机密)。添加 `-c wrangler.oauth.jsonc` 以针对 OAuth worker。
| 名称 | Worker | 必需 | 用途 |
|------|--------|----------|---------|
| `SIGNREQUEST_TOKEN` | 两个 | ✅ | 团队范围的 SignRequest API 令牌 |
| `MCP_AUTH_TOKEN` | bearer | ✅ | 共享 bearer 客户端发送为 `Authorization: Bearer <…>` |
| `APP_PASSPHRASE` | oauth | ✅ | OAuth 授权屏幕上的口令短语 |
| `OAUTH_KV` (绑定) | oauth | ✅ | 存储 OAuth 授权/注册的 KV 命名空间 |
| `SIGNREQUEST_FROM_EMAIL` | 两个 | 可选 | 默认发送者,以便调用者可以省略 `from_email` |
| `SIGNREQUEST_BASE_URL` | 两个 | 可选 | 覆盖 API 基址(默认为 `https://signrequest.com/api/v1`) |
| `SIGNREQUEST_MAX_RETRIES` | 两个 | 可选 | 幂等调用的最大重试次数(默认为 `3`) |
| `MCP_READONLY` | 两个 | 可选 | `true` ⇒ 仅注册只读工具(无创建/发送/批量/取消/删除) |
---
## 部署
```bash
npm install
```
<!-- ... (rest of the translation remains the same) -->
# 承载工作者秘密 — 在提示符处粘贴每个值(请勿将其放在命令行上):
```bash
npx wrangler secret put SIGNREQUEST_TOKEN
npx wrangler secret put MCP_AUTH_TOKEN
```
部署:
```bash
npx wrangler deploy
```
生成一个强壮的 `MCP_AUTH_TOKEN`,不带尾部换行符(多余的换行符会破坏恒定时间比较):
```bash
MCP_TOKEN=$(openssl rand -hex 32); printf '%s' "$MCP_TOKEN" | npx wrangler secret put MCP_AUTH_TOKEN; echo "MCP_AUTH_TOKEN=$MCP_TOKEN"
```
首次部署会创建 Durable Object(迁移 `v1`)并打印你的 `https://signrequest-mcp.<subdomain>.workers.dev` URL。有关 OAuth 工作者,请参阅 [OAuth 工作者](#oauth-worker-claudeai-web)。
---
## 验证
```bash
URL="https://signrequest-mcp.<subdomain>.workers.dev"
# 1) 健康检查(无身份验证)→ "signrequest-mcp worker: ok"
curl "$URL/"
# 2) 失败关闭 - 无令牌 → 401
curl -i -X POST "$URL/mcp"
# 3) MCP 初始化(带有令牌)→ JSON-RPC 结果,非 401
curl -X POST "$URL/mcp" \
-H "Authorization: Bearer <MCP_AUTH_TOKEN>" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'
```
---
## 连接客户端
### Claude 代码
```bash
claude mcp add --transport http --scope user signrequest \
https://signrequest-mcp.<subdomain>.workers.dev/mcp \
--header "Authorization: Bearer <MCP_AUTH_TOKEN>"
claude mcp list # → signrequest: … (HTTP) - ✓ 已连接
```
### Claude 桌面版
Claude 桌面版使用 stdio,因此使用 [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) 桥接远程服务器。将其添加到 `claude_desktop_config.json`(macOS: `~/Library/Application Support/Claude/`)并完全重启应用程序:
```jsonc
{
"mcpServers": {
"signrequest": {
"command": "npx",
"args": [
"mcp-remote",
"https://signrequest-mcp.<subdomain>.workers.dev/mcp",
"--header", "Authorization: Bearer <MCP_AUTH_TOKEN>"
]
}
}
}
```
> 如果在桌面应用程序中,裸 `npx` 无法解析(通常在使用版本管理器安装 Node 时),请使用 `which npx` 获取的绝对路径。
### Claude 网页
**承载** 工作者无法添加到 Claude.ai 网页(其连接器 UI 需要 OAuth,没有静态令牌字段)。请改用 **`signrequest-mcp-oauth`** 部署:
1. 部署它并设置其秘密 - 参见 [OAuth 工作者](#oauth-worker-claudeai-web)。
2. 在 Claude.ai → **设置 → 连接器 → 添加自定义连接器** 中,输入 MCP URL:`https://signrequest-mcp-oauth.<subdomain>.workers.dev/mcp`
3. Claude.ai 自动发现 OAuth(动态客户端注册)并将你发送到同意屏幕。输入你的 **通行短语** 以授权。
### 编程方式
任何 HTTP MCP 客户端都有效 - 发送 `Authorization: Bearer <MCP_AUTH_TOKEN>` 和 `Accept: application/json, text/event-stream` 到 `POST /mcp`。
---
## OAuth 工作者(Claude.ai 网页)
`signrequest-mcp-oauth` 是同一个 MCP 服务器,由 OAuth 2.1 提供程序提供支持,通过单个共享通行短语进行控制。路由:
| 路由 | 目的 |
|-------|---------|
| `GET /` | 健康检查(无身份验证) |
| `GET`/`POST` `/authorize` | 通行短语同意屏幕 |
| `/token`, `/register`, `/.well-known/oauth-*` | OAuth 端点(由提供程序处理) |
| `POST /mcp`, `GET /sse` | MCP 传输,OAuth 保护 |
与承载工作者一起部署:
```bash
# 一次性:创建提供程序需要的 KV 命名空间,然后将其 ID 置于 wrangler.oauth.jsonc 中
npx wrangler kv namespace create signrequest-mcp-oauth # → { "binding": ..., "id": "<粘贴到 kv_namespaces>" }
# 秘密(在提示符处粘贴;-c 选择 OAuth 工作者):
npx wrangler secret put SIGNREQUEST_TOKEN -c wrangler.oauth.jsonc
npx wrangler secret put APP_PASSPHRASE -c wrangler.oauth.jsonc
npx wrangler deploy -c wrangler.oauth.jsonc
```
`APP_PASSPHRASE` 关闭失败 - 如果未设置,则同意屏幕拒绝每次尝试。然后按照 [Claude 网页](#claude-web) 中的说明在 Claude.ai 中添加连接器。
---
## 测试
```bash
npm run typecheck # tsc --noEmit(严格)
npm test # vitest — 客户端(重试/退避/分页,无重试 POST),帮助程序,签名者摘要
npm run smoke # 对已部署的工作者进行实时烟雾测试(设置 MCP_URL + MCP_TOKEN)
```
CI( [.github/workflows/ci.yml](.github/workflows/ci.yml) )在每次推送和 PR 时运行类型检查 + 测试。客户端可以使用模拟的 `fetch` 进行完全单元测试(可注入的 `backoffBaseMs` 保持重试测试快速);纯帮助程序和签名者摘要组合针对固定数据进行测试。
## 注意事项
- **仅限现有令牌。** SignRequest 由 Box 拥有,处于维护模式;这假设您已经拥有一个可用的团队 API 令牌。
- **无希伯来语** 在签名者电子邮件/UI 语言中(参见 [签名者对象](#signer-object))。
- **单用户 OAuth。** OAuth 工作者通过一个共享的通行短语进行控制 - 适合个人连接器,不适合多租户。如果您需要每用户身份,请将同意处理程序替换为真正的 IdP(GitHub/Google/等)。
- **依赖版本。** `agents@^0.14.5` + `@modelcontextprotocol/sdk@^1.29.0` + `zod@^4`(SDK 接受 zod 3 或 4);`npm audit` 是干净的。`ai`/`react` 是 `agents` 的必需对等依赖,但从未导入到 Worker 包中。
---
## 项目布局
```
src/
index.ts 承载工作者入口 - 路由,承载门控,McpAgent/Durable 对象
oauth.ts OAuth 工作者入口 - OAuthProvider + 通行短语同意 + McpAgent
tools.ts registerTools() - 32 个工具定义 + Zod 模式 + 帮助程序(共享)
signrequest.ts SignRequestClient - 无依赖 REST 客户端,仅限 fetch,mapLimit/分页(共享)
ai-stub.ts 将未使用的 `ai` 对等依赖项从包中排除
tests/ vitest 单元测试(客户端重试/退避/分页,帮助程序,签名者摘要)
vitest.config.ts 测试配置(解析 NodeNext .js 指定为 .ts)
scripts/smoke.mjs 对已部署的工作者进行烟雾测试(npm run smoke)
.github/workflows/ci.yml CI - 推送/PR 时进行类型检查 + 测试
wrangler.jsonc 承载工作者配置(signrequest-mcp)
wrangler.oauth.jsonc OAuth 工作者配置(signrequest-mcp-oauth)- 添加 OAUTH_KV
package.json 依赖项(SDK ^1.29.0,agents ^0.14.5,zod ^4,workers-oauth-provider,wrangler,vitest)
```
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器