mcpField
R
RFP Hub

RFP Hub

本地服务
github.com金融数据21 天前更新

关于 RFP Hub

RFP Hub 是用于查找 Ethereum 生态资助机会并可选提交申请的 MCP 服务。搜索和读取无需凭据;提交需配置凭据,并在写入前经过独立的人为审批。

主要功能

  1. 01按条件搜索资助机会
  2. 02获取完整机会记录
  3. 03无需凭据即可匿名搜索
  4. 04提交须经终端审批

适用场景

  1. 01查找资助、赏金或黑客松
  2. 02查看资助机会的完整详情
  3. 03准备提交内容供人工审核

MCP 相关

向 MCP 客户端提供搜索和读取工具;配置凭据后还会提供提交工具。每项待提交内容都须由人员在终端审批后才会写入。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"the-rfp-hub-rfp-hub": {
"command": "npx",
"args": [
"-y",
"@the-rfp-hub/mcp"
],
"env": {
"RFPHUB_API_BASE": "<RFPHUB_API_BASE>",
"RFPHUB_API_KEY": "<RFPHUB_API_KEY>"
}
}
}
}
启动命令npx -y @the-rfp-hub/mcp
需要配置的环境变量
RFPHUB_API_BASEBase URL of the RFP Hub API. Defaults to https://api.rfpsear.ch. The origin of this URL is bound into every write approval.
RFPHUB_API_KEY密钥RFP Hub API credential. Needed ONLY to submit; searching and fetching are anonymous and never send it. Setting it is what registers the write tool at all: without it tools/list returns two tools. The key must carry the write scope and must not carry publish; the server checks that before its first submission, so a submission waits for a reviewer's decision.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@the-rfp-hub/mcp0.1.4

工具

2

收录的工具列表 · 更新于 2 周前

参数类型必填说明
qstring否在标题、摘要和说明中进行全文搜索。
pageinteger否从 1 开始的页码。
sortenum否排序键;默认值为 nextDeadlineAt,即最早的、仍在未来的固定截止日期。没有此类截止日期的条目排在最后。nextDeadlineAt | opensAt | postedAt | updatedAt | createdAt
limitinteger否每页结果数,范围为 1 到 25。默认值为 10。
orderenum否排序方向。默认值为升序。asc | desc
statusarray否仅限这些状态之一:upcoming、open、closed、archived。
categoryarray否类别。多个值之间为 OR 关系。
maxAwardnumber否奖励或预算上限,以主要货币单位计。
minAwardnumber否奖励或预算下限,以主要货币单位计。
ecosystemarray否生态系统名称,例如 Optimism、Base。多个值之间为 OR 关系。
fundingTypearray否仅限这些资助类型之一:grant、hackathon、bounty、accelerator、vc_fund、rfp。
organizationstring否组织 slug。匹配运营组织或赞助组织。
deadlineAfterstring否RFC 3339 时间点。仅包含最早的即将到来的固定截止时间不早于该时间点的条目。没有即将到来的固定截止时间的条目(滚动申请项目、所有截止时间均已过或根本没有截止时间)会被此筛选器排除。
deadlineBeforestring否RFC 3339 时间点。仅包含最早的即将到来的固定截止时间不晚于该时间点的条目。没有即将到来的固定截止时间的条目会被此筛选器排除。

详细介绍

@the-rfp-hub/mcp

一个用于 RFPSear.ch 的 Model Context Protocol 服务——可从任意 MCP 客户端搜索以太坊生态系统中的资金机会(资助、黑客松、悬赏、加速器、VC 基金、RFP),并可选择提交一项,且人工审批步骤在工具通道之外进行。采用 MIT 许可证。

搜索是匿名的:无需凭据、无需账户,除了客户端配置项外无需进行任何配置。 只有在提交时才需要凭据,并且仅当明确开启提交功能时才需要。


通过 Agent 提交

如果 Agent 只需搜索和获取信息,请跳过本节:按下文安装服务,无需凭据。若要允许其提交:

  1. 登录部署的 API keys 页面——托管 Hub 使用 https://rfpsear.ch/keys,本地或预发布前端则使用 /keys。该页面上的 MCP 卡片会为下文准备安全权限范围。
  2. 选择 read 和 write,保持关闭 publish,然后生成密钥。这是安全的做法:提交内容会被保存并等待审核,而不会立即显示。
  3. 密钥出现时将其复制。密钥仅显示一次。页面还会显示应填入 RFPHUB_API_BASE 的确切 API 来源地址。
  4. 配置下文与客户端无关的 stdio 连接,然后在客户端的私有 MCP 环境中,将来源地址填入 RFPHUB_API_BASE,并将密钥填入 RFPHUB_API_KEY。切勿将密钥放入提示词、工具参数或 shell 命令中。
  5. 重启客户端。此时 tools/list 会包含 submit_opportunity;首次调用会检查密钥权限范围并仅生成预览,写入操作仍需经过终端审批。

API keys 页面是交接入口:它会创建凭据,并在新标签页中链接回此处,因此配置客户端时,一次性密钥仍会显示。


安装

与客户端无关的连接

RFPSear.ch MCP 不依赖模型提供商或客户端。它是一个本地 stdio 服务:客户端启动一个进程,通过标准输入发送 MCP 消息,并从标准输出读取消息。服务不知道启动它的是哪个模型、供应商或主机。

每个兼容客户端都使用相同的连接约定:

设置值
传输方式stdio
命令npx
参数-y、@the-rfp-hub/[email protected]
搜索和获取无需环境变量;会提供两个匿名只读工具。
提交将 RFPHUB_API_BASE 和 RFPHUB_API_KEY 添加到服务进程的私有环境中;之后会提供写入工具。

客户端为这些字段使用的名称可能不同,但进程和环境保持不变。请优先使用仅供用户本人访问的配置或密钥输入;切勿将密钥提交到代码仓库。添加或轮换密钥后,请重启客户端。

上面的确切软件包版本号是有意指定的。npm 版本不可变;@latest 则不是,而 MCP 服务是 Agent 使用你的权限运行的代码。请固定版本,并有意为之地升级。

等效客户端示例

这些只是适配相同连接约定的配置,并非独立集成。匿名搜索和获取时,请省略环境变量区块。

Claude Code
claude mcp add --transport stdio rfp-hub -- npx -y @the-rfp-hub/[email protected]

# project-scoped instead of user-scoped — writes .mcp.json in the repo
claude mcp add --scope project --transport stdio rfp-hub -- npx -y @the-rfp-hub/[email protected]

这些命令会安装匿名搜索和获取功能。若要启用提交,请使用 Claude 的本地或用户配置,将 RFPHUB_API_BASE 和 RFPHUB_API_KEY 添加到服务的私有环境中;共享项目的 .mcp.json 中不要放入密钥。

项目范围的服务(--scope project)会显示为“待审批”,直到在该目录中以交互模式运行一次 claude。无头模式(CI、脚本、claude -p)需要使用 claude -p ... --mcp-config .mcp.json --strict-mcp-config 加载服务,无需执行交互步骤。

Claude Desktop 和 Cursor

在 claude_desktop_config.json 或 .cursor/mcp.json 中使用根键 mcpServers:

{
  "mcpServers": {
    "rfp-hub": {
      "command": "npx",
      "args": ["-y", "@the-rfp-hub/[email protected]"],
      "env": {
        "RFPHUB_API_BASE": "https://api.rfpsear.ch",
        "RFPHUB_API_KEY": "rfph_…"
      }
    }
  }
}
VS Code

在 .vscode/mcp.json 中使用根键 servers:

{
  "servers": {
    "rfp-hub": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@the-rfp-hub/[email protected]"],
      "env": {
        "RFPHUB_API_BASE": "https://api.rfpsear.ch",
        "RFPHUB_API_KEY": "${input:rfphub-key}"
      }
    }
  },
  "inputs": [
    {
      "type": "promptString",
      "id": "rfphub-key",
      "description": "RFPSear.ch API key",
      "password": true
    }
  ]
}
Codex CLI
codex mcp add rfp-hub -- npx -y @the-rfp-hub/[email protected]

该命令会安装匿名搜索和抓取功能。要提交申请,请编辑 ~/.codex/config.toml(或受信任项目的 .codex/config.toml),并将下方的私有环境变量表添加到服务条目中。将两个值替换为 API 密钥页面上显示的准确来源和一次性密钥,然后重启 Codex。此配置遵循官方 Codex MCP 配置。

[mcp_servers.rfp-hub]
command = "npx"
args = ["-y", "@the-rfp-hub/[email protected]"]

[mcp_servers.rfp-hub.env]
RFPHUB_API_BASE = "https://api.rfpsear.ch"
RFPHUB_API_KEY = "rfph_…"

配套技能

funding-search 是一项只读 Agent 技能,用于指导客户端如何有效使用此服务的搜索和抓取工具。它不包含在此 npm 软件包中——而是从代码仓库安装,具体通过客户端支持的以下任一渠道:

npx skills add The-RFP-Hub/the-rfp-hub --skill funding-search
claude plugin marketplace add The-RFP-Hub/the-rfp-hub

或者手动将技能目录复制到 .claude/skills/、.agents/skills/(Codex)或 .gemini/skills/。


配置

两个环境变量和一个标志。变量用于机密信息——绝不能放在 argv 中,因为机器上的每个进程都能读取它——或用于部署身份。其他所有配置都是标志或固定常量,因此运行此服务无需环境管理员提供任何信息。

变量默认值作用
RFPHUB_API_BASEhttps://api.rfpsear.ch指定要连接的部署。必须是不带路径的来源;除回环地址外,必须使用 https。该来源会绑定到每项写入审批。
RFPHUB_API_KEY(无)凭据,仅在提交申请时需要。读取时绝不会发送。设置此变量才会注册写入工具:若未设置,tools/list 会返回两个工具,并且不存在可供遭到污染的搜索结果调用的写入工具。
标志默认值作用
--state-dir <dir>~/.rfphub存放审批记录、速率限制计数器和审计日志的位置。必须具有写入权限。任何模式下均可使用,并且服务与 rfphub-mcp approve 必须指定同一目录。

每个请求的截止时间固定为 20 秒,包含标头和正文。此值不可配置:操作员能够延长的截止时间,也意味着停滞的目标可以让工具调用一直等待。

RFPHUB_API_BASE 会在启动时检查,早于任何预览的创建;以下四种形式会被直接拒绝:

  • 除 127.0.0.1、[::1] 或 localhost 以外的任何地址使用纯 http:——写入请求携带 Bearer 凭据,而由人类审批来源并不能让明文传输变得安全;
  • URL 中包含用户名或密码——它们会出现在此服务写入的每条诊断信息中(出于同样的原因,任何错误消息都不会重复此变量的值);
  • 包含路径、查询参数或片段——审批绑定的是来源,因此主机之后部分不同的两个地址会生成相同的审批,却指向不同的端点;
  • 不是绝对 http/https URL 的任何形式。

https://api.rfpsear.ch、https://api.rfpsear.ch/、https://api.rfpsear.ch:443 和 https://API.rfpsear.ch 指向同一目标,并生成同一个审批 ID。端口 444 或不同的主机则代表不同目标,并生成不同的 ID。

轮换密钥意味着必须重启服务。 配置只在启动时读取一次,而且凭据指纹是审批绑定的五项内容之一。客户端 env 区块中替换的密钥要等到进程下次启动时才会传递给此进程;在此之前,预览仍绑定旧指纹,而使用新密钥提交会因不匹配而遭拒。使用新密钥创建预览前,请先重启。

密钥应放在客户端的 env 区块中。绝不能放进提示词,也绝不能作为工具参数——没有任何工具提供可用于传入密钥的参数,并且有测试对此进行了断言。

{
  "mcpServers": {
    "rfp-hub": {
      "command": "npx",
      "args": ["-y", "@the-rfp-hub/[email protected]"],
      "env": {
        "RFPHUB_API_KEY": "rfph_…"
      }
    }
  }
}

密钥必须具有 write 权限,且不得具有 publish 权限;此服务会在首次提交前检查这一点。publish 密钥会被拒绝,因为获批的提交会立即上线。


工具

search_opportunities (读取)

筛选条件:q、fundingType[]、status[]、ecosystem[]、category[]、organization、minAward、 maxAward、deadlineAfter、deadlineBefore、sort、order、page、limit(上限为 25)。未知参数会报错,绝不会被当作无效筛选条件而悄悄忽略。

每条结果都包含 id、命名空间、标题、资助类型、状态、运营组织、生态系统、格式化后的资助金额行、下一个固定截止日期,以及两个外链 URL。

它不会返回 description 或 summary。 这是有意为之,也是此服务最重要的安全特性:这两个字段是发布者可控制的最长自由文本,面向你的 Agent 的指令可能就藏在其中,而二十条这样的内容会占据大部分上下文窗口。只有在确实需要文本内容时,才按 id 请求完整记录。

fetch_opportunity (读取)

以 RFP Hub Standard 文档的形式完整返回一条记录,包含在 { notice, opportunity, links } 信封中。该文档在结构上未经修改——没有移除或添加任何字段,也没有更改任何值——唯一例外是,每条出站消息(包括本次)中,任何形似 API 密钥的值都会被替换为删减标记。除此之外,它并非字节级完全相同:传输过程中会对其进行解析并重新序列化,因此键的顺序和空白字符由传输过程决定。

submit_opportunity (写入——仅在配置密钥后注册)

需要进行两次调用,中间由用户操作。请参阅下一节。

提交结果保留 API 的 isListed 值,作为编辑偏好,并新增 isPubliclyVisible,作为实际可见性信号。只有当 reviewStatus 为 approved 且 isListed 为 true 时,记录才会公开可见;isListed: true 的待审核记录仍须等待审核。


提交与审批步骤

1. call submit_opportunity { document }
     → checks the key's scope, validates locally, writes nothing, returns:
       { status: "pending", approvalId: "<64 hex>", preview: {...}, instruction: "..." }

2. a person runs, in their own terminal:
     npx @the-rfp-hub/[email protected] approve <approvalId>
     → prints the destination, the credential fingerprint, the operation, the protocol
       revision and the whole document, then asks for confirmation

3. call submit_opportunity { document, approvalId }
     → claims the approval (single-use), POSTs, returns the result

rfphub-mcp pending 会列出正在等待处理的内容。rfphub-mcp revoke <id> 会删除一条记录。

审批绑定的内容

审批不只是“这份文档已获批准”。其 id 是根据五项内容计算出的哈希值,approve 会在询问前逐一列出:

目标位置RFPHUB_API_BASE 的规范源
凭据密钥 SHA-256 的前 8 个十六进制字符——绝不是密钥本身,也不是密钥的前缀
操作submit_opportunity
协议此服务所使用的 MCP 修订版本
文档对文档的规范形式计算出的 SHA-256

任意一项发生变化,审批就不再适用,拒绝信息会指出哪一项发生了变化。针对暂存环境授予的审批不能用于生产环境。密钥轮换后,基于该密钥授予的审批会被拒绝,因为绑定的是密钥指纹。

审批为单次使用,请求发出前会通过原子重命名将其占用,且绝不会恢复——超时后也一样。如果提交结果不明确,在进行其他操作前,先检查 GET /v1/me/opportunities(公开读取接口会隐藏等待审核的条目)。待处理预览会在生成 15 分钟后过期;批准预览后,会开启一个新的 15 分钟提交窗口。

它的作用——以及它的作用边界

它的作用。 批准操作会完全离开 MCP 通道。任何工具响应都不会携带批准密钥,因此模型无法从自己的上下文中读出密钥,并在同一轮中使用它。批准操作会成为终端前的一项刻意操作:屏幕会准确显示写入目标以及所用凭据。

它的作用边界。 这并非针对同时持有 shell 和文件系统访问权限、且二者属于同一操作系统用户的 Agent 的安全边界。编码 Agent 通常同时持有这两种权限。此类 Agent 可以在伪终端中运行此 CLI,也可以直接写入批准文件;0600/0700 权限无法阻止它,因为它就是该用户。不应将这里的任何内容理解为“模型无法批准”。

如果你需要真正独立的安全边界,可选方案不在此软件包范围内:由宿主应用程序提供批准 UI、为 Agent 进程分配独立的操作系统身份,或使用 Agent 无法访问的签名密钥。请参阅 adr/0012。


错误

每种失败都带有以下七种代码之一。

代码含义
tool_not_found没有此工具。禁用提交后,写入工具确实不会注册。
invalid_input参数或文档未通过验证。架构验证失败时会逐字段报告。
policy_denied配置或 API 授权拒绝了请求:没有凭据、密钥缺少 write 权限或带有 publish 权限,或已达到待提交数量上限。
rate_limited超出本地的分类预算,或触发了 API 自身的限流。
confirmation_required文档已预览,但尚未批准。未发送任何内容。
confirmation_invalid批准不适用于此请求:已过期、已使用,或绑定到不同的目标、凭据、协议或文档。未发送任何内容。
exec_failedAPI 失败、无法访问、返回的内容不是 JSON,或超过 1 MB。

响应超过 1 MB 时会直接失败,而不是截断,并且读取响应正文时就会应用大小上限,因此即使响应极大,内存消耗也有上限。半份 JSON 文档并不是较短的答案,而是错误的答案;请缩小请求范围。

如果无法确定提交结果,会明确说明。 请求发出后,唯一明确的结果是带代码的 4xx——API 已读取请求、作出决定,并拒绝了它。其他情况都会报告为可能已提交,而不会当作普通失败,并会指向 GET /v1/me/opportunities:

  • 连接中断,或响应正文在传输过程中停止;
  • 响应正文不是 JSON,或超过大小上限;
  • 5xx,无论响应正文格式多么完整——API 会先提交记录,然后才执行更多操作,因此响应时出现服务器错误,完全可能意味着记录已经存在;
  • 2xx,但响应正文不是提交结果——例如空的 200、{},或来自非此 API 的响应;
  • 3xx(见下文)。

以上所有情况都会消耗这次批准。

提交操作绝不会跟随重定向——但未跟随的重定向仍意味着结果不确定。 文档和凭据绝不会重新发送到此服务尚未解析、且无人批准的主机;批准会绑定到目标源,因此若继续发送到其他位置,就会消耗一项针对其他位置作出的决定。但未跟随不等于未写入:POST/Redirect/GET 是服务确认刚创建内容的常见方式,因此遇到 3xx 时会报告为可能已提交,并注明目标位置,让你知道请求原本会被发送到哪里。

参数会根据已发布的架构进行验证,格式错误的调用也会返回与其他情况相同的代码。未知参数会报错,而不会被当作一个悄无声息地不起作用的筛选条件。


本地状态

所有内容都位于状态目录下——--state-dir,默认为 ~/.rfphub——目录权限为 0700,文件权限为 0600。

--state-dir 优先于操作系统对当前用户主目录的认定。 在这种认定不可靠的场景中,请传入此参数:容器、服务账户、systemd 单元或启动代理可能没有主目录,可能有一个只读主目录,也可能与其他身份共用主目录。本服务宁可拒绝,也不会猜测——见下文。

{
  "mcpServers": {
    "rfp-hub": {
      "command": "npx",
      "args": ["-y", "@the-rfp-hub/[email protected]", "--state-dir", "/var/lib/rfphub"]
    }
  }
}

请向审批命令传入相同的目录。 服务会在其中写入预览,而 rfphub-mcp approve 会从中读取;如果目录不同,pending 将不会显示任何内容,而真正的预览却在别处等待。此服务打印的所有供人运行的命令,只要指定了此参数,就都会附带该参数——包括预览的 instruction、收到未审批的提交时显示的拒绝信息,以及 rfphub-mcp --state-dir /var/lib/rfphub pending 中的 approve 命令——并会进行 shell 引号处理,因此路径中有空格也能直接粘贴。

路径内容
pending/<id>.json等待审批的预览,其中包含文档,以便终端打印
approvals/<id>.json已授予的审批
approvals/claimed/<id>.json已用过的审批,不可重复使用。
pending/claimed/<id>.json已由人转为审批的预览
policy-counters.json按类型记录的速率计数器
policy-counters.lock仅在更新计数器时持有
policy-counters.lock.stale.*进程崩溃后遗留、即将清理的锁
audit.log每次调用写入一行 JSON,达到 5 MiB 时轮换
audit.log.1日志的上一代文件
audit.lock仅在轮换日志时持有

权限会经过检查,而不只是尝试设置。 每次使用时,都会对主目录执行 lstat,并要求它是真正的目录——不能是符号链接,也不能是文件——每个状态文件也必须是普通文件,且没有第二个硬链接。对于本服务即将写入的路径,会执行 chmod,设置为 0700/0600,然后读回权限,因为在不支持 POSIX 权限的文件系统上,chmod 即使报告成功,也不能证明权限已生效。

对于本服务即将信任的文件,则会进行验证,绝不修复:已经允许所有人读取的审批文件或计数器文件,或带有第二个硬链接的文件,已经暴露给持有它的任何人;之后收紧权限既无法撤销暴露,也无法让文件中的决定归你所有。读取这些文件时会拒绝操作并返回 policy_denied,直至文件被删除。rfphub-mcp pending 则会直接省略无法确认安全的记录。审计日志是写入而非信任的,因此会进行修复;但如果无法确保路径安全,仍会拒绝写入,并通过同一个文件描述符打开和检查,以防轮换时将权限为默认值的新文件放到追加操作之下。若日志路径是符号链接或不是普通文件,则会拒绝使用,而不会跟随该路径——平台支持时使用 O_NOFOLLOW;所有平台都会在打开前执行 lstat。对于不支持 O_NOFOLLOW 的平台,这也是唯一的防护措施(两步之间存在一个短暂窗口;出现问题时会安全失败并丢弃一行,而不会通过链接写入)。

审计日志有大小上限。 达到 5 MiB 时,会在锁保护下将日志轮换为 audit.log.1,并将之前的日志保留为恰好一代、权限为 0600。轮换失败只会导致无法轮换,不会影响调用,也不会丢弃日志行。

时钟倒退不会带来任何好处。 如果磁盘上的计数器窗口领先于当前窗口——例如发生 NTP 校时、恢复了快照或手动调整了时钟——就会保留存储的计数并继续累加,而不会重置;时间戳位于未来的审批会被视为超出有效窗口。预算会持续保持已用状态,直至实际时间追上,这是限流器的安全处理方式。 速率限制采用失败关闭策略。 如果无法读取或写入计数器存储,则会拒绝调用——无法计数的预算就无法执行。请确保状态目录可写。

计数器在多个进程间保持准确。 检查并递增操作会在锁目录(policy-counters.lock)中运行,因为 MCP 客户端和运行此软件包的终端按设计会共用一个主目录,而未加锁的读改写操作会让两个进程都通过上限为 1 的限制。进程异常退出后遗留的锁会在 5 秒后被解除:通过将其重命名移开,避免两个进程同时解除同一个废弃锁时误删仍在使用的锁。

先预留写入预算,再认领审批。 本地拒绝——例如每日预算已用尽,或未能抢到审批——会退还预算并保留审批,因此无需再次请求他人批准同一份提交。

是否批准取决于你作出答复的时刻,而不是打印预览的时刻。 只有在你确认后,才会通过原子重命名认领预览,因此两个终端批准同一个 id 时只会产生一次批准;如果预览在屏幕上显示期间已被撤销或过期,也会被拒绝。

被拒绝的提交也会计量。 调用方需要判断的三种类型是 read、preview 和 commit——分别对应实际发生的工作阶段。attempt 是第四种内部类型:用于滥用控制的计量项,而非工作阶段。每次调用写入工具都会先消耗 1 次额度(每分钟 20 次、每天 400 次),然后才开始任何工作——包括参数在处理程序运行前就被拒绝的调用,因为这种调用最容易重复发起。不断尝试伪造的审批 id、格式错误的参数或超大文档,也无法绕过计量。attempt 额度耗尽绝不会掩盖实际错误:错误参数仍会作为错误参数返回。

审计日志只记录参数键名和字节数,从不记录值。 如果日志存储了值,就会成为每份文档和每个搜索词的第二份副本。日志写入失败绝不会导致调用失败。

默认值:read 每分钟 60 次,preview 每分钟 10 次,commit 每分钟 2 次、每天 5 次,attempt 每分钟 20 次、每天 400 次。


安全说明

  • 凭据仅通过环境变量提供。 没有任何工具会接收凭据;读取操作绝不会发送凭据。
  • 提交的文档中任何位置出现类似密钥的字符串,都会在发出任何请求前被拒绝。 API 会存储收到的文本,因此 description 中的密钥会被持久化,之后才会从回复中 删除——仅对输出进行删除无法解决这个问题。
  • 删除是最后一道防线,而非控制措施。 所有出站内容——文本、结构化内容、 错误消息、审计日志——都会递归扫描是否包含类似密钥的字符串。
  • URL 不会被处理。 此服务绝不会访问任何记录中的 URL,并且每条结果附带的 提示都会告知客户端也不应访问。
  • 所有第三方字符串都有长度限制。 标题最多 140 个字符,生态系统标签最多 40 个字符,且最多 8 个值(行中会注明丢弃了多少个)。标准中的 ecosystems 是开放列表——没有注册表,也没有枚举——因此若不设限,它就会成为存放负载的 显眼位置。
  • 明确说明剩余风险: title、组织名称和生态系统标签都是第三方文本,且确实会 传递给模型。它们会被分隔并标记。标记只是提示,不是控制措施;恶意标题不会因此 变得无害。投影处理——省略 description——才是控制措施。
  • 预览会拒绝 API 也会拒绝的内容。 API 的接收限制(标题 256 个字符、摘要 1 000 个字符、描述 50 000 个字符、顶层数组最多 100 个条目、正文 256 KiB) 会在本地检查,因此不会让任何人批准一个注定无法被接受的提交。数组上限仅适用于 顶层,这与 API 的处理方式完全一致——若在此处检查得更多,就会拒绝 API 原本会 接受的文档。
  • 疑似重复项的标题也是第三方文本。 返回的标题会截断至 140 个字符,并经过 分隔和标记——调用方在写入时最容易采取行动,因此这里采用与搜索结果相同的处理 方式。
  • structuredContent 不是安全边界。 它和其他输出一样会传递给模型。它在此处 用于契约和验证。
  • 每个请求都有截止时间。 如果对端接受连接后不再回应,或只发送部分正文便停止, 20 秒后就会放弃。读取操作会报告此情况,且不会重试。写入操作会将其报告为结果 不明确,因为请求已经发出。
  • 在检查响应正文之前,不会认定 2xx 请求成功。 如果读取响应的正文不符合此 版本已知的格式,就会报错,而不会返回看似合理的空记录;如果写入响应的正文不是 提交结果——包括 204,或此版本尚未支持的 duplicateCheck 值——就会报告 “可能已提交”,并指出可通过 GET /v1/me/opportunities 查询结果。 始终允许包含未知的额外成员:此客户端不负责定义契约。
  • 固定到精确版本,就像上述每个示例所做的那样。这是防止未来任何 npm 软件包 版本的行为不同于你审查过的版本的唯一有效方法。

开发

pnpm --filter @the-rfp-hub/mcp build   # required before the test suite: it drives dist/cli.js
pnpm --filter @the-rfp-hub/mcp test

传输方式在 src/cli.ts 中选择;src/server.ts 注册工具,不了解传输方式。 添加 HTTP 入口点应新建文件,而不是进行重构。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。