Context7 源码分析:技术架构、MCP 运行原理与检索链路

This article is extracted from the chat log with AI. Please identify it with caution.

AI 参与说明(Agent:Codex):本文由 Codex 根据 Context7 官方仓库、官方产品文档与固定提交的本地源码协助整理和校验。资料核验于 2026-08-27,源码基线为提交 9a384f0,其中 @upstash/context7-mcp 版本为 4.0.3。本文实际运行了该包的测试套件,79 项测试全部通过;未使用 Pro 私有源,也未部署 Enterprise On-Premise。托管后端、套餐能力和限额会持续变化,涉及购买或生产接入时仍应以实时 Dashboard、Plans 页面和目标版本源码为准。

先说结论#

Context7 的公开仓库不是一套可以从源码完整复刻的 Documentation Retrieval / Retrieval-Augmented Generation(RAG)后端。它更准确的定位是一个开源交付层 monorepo:把同一套 Context7 托管 API 接入 MCP Client、命令行、TypeScript 应用、Vercel AI SDK、Pi 和 OpenCode。真正负责抓取、解析、索引与检索的 API backend、parsing engine 和 crawling engine 没有出现在仓库中,官方也明确说明这些组件是私有实现。开源边界说明

packages/mcp 因而不是一个本地向量数据库,也不在本机执行 embedding、文档切片或 rerank。它是一个很薄但并不简单的 MCP protocol facade:

  1. 向 Agent 暴露 resolve-library-idquery-docs 两个只读工具。
  2. 规范化模型容易写错的参数名,并用 Zod 校验输入。
  3. 从 stdio 或 HTTP 请求中组装认证、客户端身份与 transport context。
  4. 把工具调用转换为托管 API 的两个 GET 请求。
  5. 把搜索结果或文档文本重新包装成 MCP Tool Result。

这意味着“本地运行 Context7 MCP”只是在本地运行协议适配层,默认仍会访问 https://context7.com/api。如果要求源码、文档、embedding 和检索都不离开内网,需要评估官方单独提供的 Enterprise On-Premise,而不是把 npm MCP 包误认为完整自托管方案。API 默认地址 On-Premise 能力边界

1. 分析范围与证据等级#

本文把结论分成两类:

  • 源码可证实:工具名、参数、路由、header、超时、认证分支、错误返回和 package 依赖等,均可直接定位到固定提交。
  • 架构推断:公开 API 后面必然存在搜索与文档检索服务;源码注释把调用称为 vector query 和 reranked context,On-Premise 文档也列出了 parser、indexing pipeline 与 local vector storage。但公开仓库无法证明 Context7 Cloud 具体使用哪一种 vector database、embedding model、chunking algorithm 或 reranker,因此本文不会替官方补齐这些实现细节。API client 注释 On-Premise 组件

一个尤其重要的阅读原则是:以运行源码和 MCP 协商结果为准,不能只看 package README。在这个提交中,packages/mcp/README.md 的 Available Tools 仍写着旧的 get-library-docstopicpage 接口,但源码实际注册的是 query-docs(libraryId, query);集成测试也断言服务端只列出 resolve-library-idquery-docs旧 README 片段 实际工具注册 集成测试断言

2. Monorepo 边界:同一 API 的多种交付形态#

根目录是一个 pnpm workspace,工作区只包含 packages/*;根命令使用 recursive build / test,各 package 独立发布,没有一个共享的“Context7 backend package”。workspace 配置 根 package scripts

目录 / package面向谁运行时边界
packages/mcp / @upstash/context7-mcp任意 MCP Client使用 MCP TypeScript SDK 2.0.0,支持 stdio 与 HTTP;直接请求 Context7 REST API,并不依赖仓库内的 TypeScript SDK。
packages/cli / ctx7人与能执行 shell 的 Agent负责登录、setup、Skills 管理,也可直接执行 library / docs;Node.js 要求为 18 或更高。
packages/sdk / @upstash/context7-sdkTypeScript / JavaScript 应用Context7 class 包装同样的 search / context endpoints,要求 API key,并提供 JSON / text 返回类型。
packages/tools-ai-sdkVercel AI SDK 应用依赖 @upstash/context7-sdk,把两个操作包装成 tool(),另提供带默认两步工作流的 ToolLoopAgent
packages/piPi Coding Agent直接注册两个 Pi tools;API adapter 明确由 MCP 代码精简改写,并未在进程中启动 MCP server。
packages/opencodeOpenCode注入远程 MCP URL 和 skill 路径;有 key 时走 /mcp,无 key 时配置 /mcp/oauth
skills/rules/plugins/各类 Agent Harness分发“何时调用、如何调用”的 instruction layer;它们不是检索引擎,也不等于 transport。

这些边界可以从 package 依赖中得到直接验证:MCP package 依赖 @modelcontextprotocol/server@modelcontextprotocol/node、Express、JOSE、Undici 和 Zod;Vercel AI SDK package 才通过 workspace dependency 使用 @upstash/context7-sdkMCP package manifest AI SDK package manifest

由此还能看出一个有意的差异:MCP server 允许 anonymous access,并把上游失败转成便于 LLM 阅读的文本;TypeScript SDK 则在构造时要求 API key,HTTP non-2xx 会抛出 Context7Error。二者复用的是 wire API,不是同一段 client implementation。MCP API wrapper SDK client SDK HTTP 错误处理

3. High-level 技术架构#

flowchart TD
  U["用户提出 library / API 问题"] --> A["Agent Harness"]
  A --> M["MCP Client"]
  A --> C["ctx7 CLI / TypeScript SDK / AI SDK / Pi"]

  subgraph OSS["公开仓库中的交付层"]
    M -->|"local stdio"| LS["@upstash/context7-mcp 本地进程"]
    M -->|"remote HTTP"| HS["@upstash/context7-mcp HTTP handler"]
    LS --> T["resolve-library-id / query-docs"]
    HS --> T
    C --> R["REST API client"]
    T --> R
  end

  subgraph PRIVATE["未包含在公开仓库中的服务层"]
    R --> S["GET /api/v2/libs/search"]
    R --> Q["GET /api/v2/context"]
    S --> I["API backend / search index"]
    Q --> I
    P["parsing + crawling + indexing pipeline"] --> I
    D["public / private documentation sources"] --> P
  end

  I --> O["候选 library 或相关文档文本"]
  O --> A
  A --> Z["模型结合检索内容生成最终答案"]

图中的关键分界是:MCP server 返回的是检索材料,不是替用户生成最终技术答案。模型仍要选择 library、调用工具、阅读返回内容并组织回答。反过来,library 匹配、snippet search 和 rerank 也不是由模型在 MCP process 内完成,而是委托给 Context7 API。

对 Cloud 部署内部结构,公开源码只能支持到这一步。Enterprise On-Premise 文档展示了 Web App、API server、parser 与 local key-value / vector storage 的组合,但这是 On-Premise 产品说明,不能无证据地等同为 Context7 Cloud 的真实部署拓扑。On-Premise 架构文档

4. packages/mcp 如何启动#

入口文件先用 Commander 解析三个参数:--transport 默认 stdio--port 默认 3000--api-key 可选。它只接受 stdiohttp;HTTP 模式禁止 --api-key,因为认证必须来自每个 HTTP request 的 header;stdio 模式则禁止 --portCLI 参数与互斥校验

4.1 stdio:一个进程、一份初始化状态#

stdio 模式从 --api-keyCONTEXT7_API_KEY 读取 key,并为进程生成一个 UUID 作为 session ID。serveStdio() 接管标准输入输出;MCP initialize 完成后,服务端保存 client name / version。后续工具调用优先读取现代协议 request envelope 中的 client info,旧客户端才回退到 initialize 阶段保存的全局信息。stdio 启动路径 context 合并顺序

这条路径适合 Client 负责拉起子进程的本地集成。它没有 HTTP client IP,但会把固定到进程的 mcp-session-id、API key、client info 与 stdio transport 标识传给上游。

4.2 HTTP:每个请求创建 server,保持无状态#

HTTP 模式用 Express 提供 /mcp/mcp/oauth/ping 与 OAuth discovery routes。核心 MCP adapter 分为两层:

  1. createMcpHandler(() => createMcpServer()) 生成 Web-standard handler。
  2. toNodeHandler() 把它适配为 Node / Express request handler。

源码明确选择 stateless serving:每个请求创建新的 McpServer,不保存 MCP-Session-Id,也没有 session store;现代 2026-07-28 traffic 由 SDK 原生处理,2025-era client 走 stateless legacy fallback。keepAliveMs: 0 则关闭 SSE heartbeat,让挂起的 stream 最终能被 gateway idle timeout 回收。HTTP adapter 与无状态设计

HTTP 请求自己的 apiKey、client IP、User-Agent 与 transport 被放入 AsyncLocalStorage<ClientContext>。工具 handler 执行时再合并 MCP envelope 的 client info;因此并发请求不必依赖可串线的 module-level globals。每请求 context

5. Tool registration:两步工作流不是服务端状态机#

createMcpServer() 用 MCP SDK 的 McpServer 注册 metadata、instructions 和 capabilities。它声明 prompts / resources capabilities,但实际集合为空,使那些无条件执行 list 请求的 Client 收到空数组,而不是 method not found。真正注册的能力只有两个 read-only、idempotent、open-world tools。server 初始化

Tool输入直接动作返回
resolve-library-idlibraryName, queryGET /v2/libs/search候选 ID、描述、snippet 数、reputation、benchmark score 与 versions 的文本列表。
query-docslibraryId, queryGET /v2/context上游返回的纯文本 documentation context。

工具 description 要求先 resolve、再 query;Skills 也重复这条规则。但 query-docs handler 不检查“本 session 是否调用过 resolve”,HTTP 又是无状态的。因此这不是服务端 enforced workflow,而是一份给模型的调用协议:用户已经提供精确 /org/project[/version] 时,可以直接 query;否则依赖模型遵守 instructions。两个 handlers

5.1 参数 alias 是对模型错误的兼容层#

模型有时会照着自然语言描述生成 userQueryquestionlibraryIDcontext7CompatibleLibraryID,而不是 schema 的 canonical keys。源码在 Zod preprocess 阶段复制参数并改写 alias:

  • 所有工具把 userQuery / question 改成 query
  • query-docs 额外把 context7CompatibleLibraryIDlibraryID,甚至 libraryName 改成 libraryId
  • 如果 canonical key 已存在,则 canonical value 优先。

把兼容放在 schema preprocess 中,意味着 stdio、HTTP、modern 和 legacy protocol 都共享同一行为;集成测试正好覆盖这四种组合。alias 实现 端到端 alias 测试

这个设计提高了对 LLM tool call 的容错率,但也说明 schema 不是唯一 contract。做自动化审计或 client generation 时,应以 tools/list 返回的 canonical schema 为准,不要主动依赖 alias。

6. 一次检索请求的源码级链路#

6.1 resolve-library-id#

  1. MCP SDK 解析 Tool Call,Zod preprocess 修正参数并完成校验。
  2. handler 通过 getClientContext(toolCtx) 取得当前 request context。
  3. searchLibraries(query, libraryName, ctx) 构造 GET /api/v2/libs/search,把两个值放入 URLSearchParams。
  4. generateHeaders(ctx) 附带 server version、认证与 client metadata。
  5. 上游返回 JSON;MCP server 只负责格式化。trustScore >= 7 显示为 High,>= 4 显示为 Medium,其余为 Low / Unknown;benchmarkScore、versions 和 source 只在存在时输出。
  6. tool 返回 Available Libraries 文本,让模型自己选择最匹配 ID。

search 请求实现 结果格式化

这里传入 query 的目的不是补充展示文本,而是让托管端按用户意图参与 library ranking。例如输入 React 时,搜索目标究竟是 React 文档、React Native 还是某个同名包,仅靠 library name 不一定足够。真正的 ranking 算法在私有 backend 中,MCP source 没有本地打分代码。

6.2 query-docs#

  1. handler 获取 context 后调用 fetchLibraryContext({ query, libraryId }, ctx)
  2. API client 构造 GET /api/v2/context
  3. 成功时直接读取 response.text(),不解析、重排或压缩内容。
  4. handler 把这段文本放进单个 { type: "text" } content item。

context 请求实现 tool result 包装

因此,MCP 层所谓“retrieval”实质是传递 libraryId + natural-language query,并接收 backend 已整理好的 context。源码没有证明 MCP process 自己执行 semantic search。若返回材料缺失,应该先检查 library ID、version 与 query 粒度,而不是在本地 MCP server 中寻找 vector index。

7. Client context、认证与 telemetry header#

generateHeaders() 会按实际 context 生成这些上游 header:header 生成代码

Header来源 / 目的
X-Context7-Source, X-Context7-Server-Version标识请求来自 MCP server 及其版本。
Authorization: Bearer ...透传 stdio key、HTTP header 中的 key 或 OAuth token。
X-Context7-Client-IDE, X-Context7-Client-Version来自现代 MCP envelope、legacy stdio initialize 或 HTTP User-Agent fallback。
X-Context7-Transport区分 stdiohttp
mcp-session-id仅 stdio process 生成;stateless HTTP 不设置。
mcp-client-ipHTTP 从 X-Forwarded-For / socket 提取后加密;stdio 没有该值。

HTTP 的 /mcp 允许匿名访问;有 credential 时也会继续透传。/mcp/oauth 要求 credential,缺失或 JWT 校验失败会在进入 MCP handler 前返回 HTTP 401 和 JSON-RPC error code -32001。OAuth discovery 通过 WWW-Authenticate/.well-known/oauth-protected-resource 暴露。HTTP auth 分支

JWT validation 支持三条 issuer 路径:Microsoft Entra v2、Context7 Enterprise-Managed Auth(EMA)以及默认 interactive OAuth issuer。Entra 会按 audience 从 Context7 API 取得 tenant / required scope 配置并缓存五分钟,然后用 tenant JWKS 验签;EMA 和普通 OAuth 则使用各自的 remote JWKS。JWT validation

普通 API key 不是 JWT,MCP process 不在本地验证其格式或有效性,只负责透传;最终错误由 API response 体现。HTTP key extraction 接受标准 Authorization,也兼容若干 legacy header spelling。实际配置应优先使用 Authorization: Bearer ...,因为 CLI setup 和官方示例都以它为 canonical form。key extraction setup 生成 Authorization header

7.1 一个自托管时容易忽略的 IP 边界#

HTTP handler 会从 X-Forwarded-For 选择第一个非 private / local IP;找不到 public IP 时回退到列表第一项。之后使用 AES-256-CBC 加密再发给 API。IP 选择

固定提交中 CLIENT_IP_ENCRYPTION_KEY 未设置时会使用源码内的默认常量;自定义 key 若不是 64 位 hex,函数甚至会退回原始 IP。由此得到的工程建议是:自托管 HTTP gateway 时显式设置独立的 32-byte hex key,限制可信 reverse proxy,并在隐私评估中把 client IP 视为会离开 MCP process 的 metadata。IP 加密实现

8. Response 与 error path:失败不一定是 MCP Error#

MCP wrapper 对 Agent 做了一个很有影响的选择:上游 API 错误大多被转换成正常的 text content,而不是 isError: true 的 Tool Result。

失败位置固定提交中的行为
不合法的 transport / 互斥 CLI flag写 stderr 并 process.exit(1)
/mcp/oauth 缺少或无法验证 credentialHTTP 401,JSON-RPC code -32001
API 返回 JSON { message }优先把 message 作为文本。
API 返回 429 / 404 / 401 且没有可解析 message映射为 quota、library not found 或 invalid key 文本。
fetch timeout、DNS 或其他 exceptioncatch 后生成 Error searching... / Error fetching... 文本。
context 成功但 body 为空返回提示用户重新 resolve library ID 的文本。
MCP adapter / Express 外层抛错记录日志;尚未发送 headers 时返回 500、code -32603

每个 API call 使用 AbortSignal.timeout(60_000),MCP wrapper 没有 retry。searchLibraries{ results: [], error } 表示失败,fetchLibraryContext{ data: errorMessage };两个 tool handlers 随后都照常返回 text content。error mapping 与 timeout search / context catch path

对 Agent Harness 的直接影响是:不能只检查 transport 成功或 isError;还要识别 Rate limitedInvalid API keyDocumentation not found 等内容,并明确告诉用户为什么没有拿到文档。官方 find-docs skill 也要求 quota 用尽时不得静默回退到 training data。find-docs error guidance

API response 还可能通过 X-Context7-Auth-Prompt: 1 要求提示 anonymous user 登录。MCP server 把这个信号写到 mutable ClientContext,然后异步发起 form-mode elicitation;它不阻塞 tool result,也不会替用户执行 setup command。由于现代协议与 stateless HTTP 没有相应的 push-style capability,这个 soft prompt 实际只面向声明 elicitation capability 的 2025-era stdio client。prompt signal auth elicitation 边界

9. MCP SDK 在这里承担什么#

@modelcontextprotocol/server@modelcontextprotocol/node 2.0.0 承担 protocol mechanics:server metadata、tool schema derivation、tools/list / tools/call dispatch、stdio serving、modern / legacy HTTP compatibility,以及 Web handler 到 Node handler 的适配。Context7 自己的代码集中在 tool semantics、API bridging、context propagation 与 auth routes。SDK imports SDK 固定版本

能力分层可以概括为:

  • MCP SDK 解决“怎样可靠接收和返回 MCP message”。
  • Context7 MCP package 解决“这两个工具怎样映射到 API、怎样携带 caller context”。
  • Context7 backend 解决“library 怎样匹配、哪些 snippet 与 query 相关”。
  • Agent Harness 解决“何时调用、选哪个结果、怎样把 context 变成最终回答”。

这也解释了为什么换成 CLI、TypeScript SDK 或 Pi extension 后,检索能力依然存在:它们绕过 MCP protocol,但最终仍调用相同的 hosted API。

10. 实际怎么用#

10.1 优先使用 ctx7 setup#

CLI 在固定提交中要求 Node.js 18 或更高;如果选择 local stdio MCP,实际启动的 @upstash/context7-mcp@4.0.3 还要求 Node.js >=20.18.1CLI engine MCP engine

npx ctx7@latest setup

交互流程会让用户选择两种模式:

  • MCP server:默认配置 hosted HTTP;加 --stdio 才改为本地 npm process。
  • CLI + Skills:不注册 MCP server,安装 find-docs skill,让 Agent 调用 ctx7 library / ctx7 docs

需要把配置限定到当前项目时使用 --project;不应在公开仓库写入真实 key。没有显式传入 --api-key--oauth 时,setup 会发起登录并生成 API key;--oauth 只适用于 hosted HTTP,不能与 --stdio 同用。setup mode 与参数 认证与 mode selection HTTP / stdio setup 分支

如果只是快速手动接入 remote MCP,核心配置是:

URL: https://mcp.context7.com/mcp
Header: Authorization: Bearer YOUR_API_KEY

希望 MCP Client 自己完成 OAuth 时,把 URL 改为 https://mcp.context7.com/mcp/oauth;OAuth 只支持 remote HTTP。API key 不应直接写入会提交的 config,优先使用 Agent Harness 的 secret / environment reference 能力。OAuth 使用边界

10.2 不用 MCP:直接走 CLI#

# 第一步:用正式名称和真实意图查 ID
npx ctx7@latest library "Next.js" "How does Route Handler caching work?"

# 第二步:选择输出中的精确 ID,再查一个主题
npx ctx7@latest docs /vercel/next.js "How does Route Handler caching work?"

如果已经知道 ID,可以跳过第一步;如果用户指定版本,应从 resolve output 选择 version-specific ID。需要给脚本消费时加 --json。CLI source 会在 TTY 中显示 spinner,在 pipe / non-TTY 场景输出干净文本。CLI commands 实现 query command

10.3 应用内直接使用 TypeScript SDK#

当调用方本来就是服务端 TypeScript 程序,没必要为了两个 API operation 再引入 MCP:

pnpm add @upstash/context7-sdk@0.3.1
export CONTEXT7_API_KEY='ctx7sk-...'
import { Context7 } from "@upstash/context7-sdk";

const context7 = new Context7();

const candidates = await context7.searchLibrary(
  "How does Route Handler caching work?",
  "Next.js",
  { type: "json" },
);

const selected = candidates[0];
if (!selected) throw new Error("No matching library");

const docs = await context7.getContext(
  "How does Route Handler caching work?",
  selected.id,
  { type: "txt" },
);

console.log(docs);

固定版本的 SDK 默认使用 https://context7.com/api,要求 API key,network exception 使用 exponential backoff retry;HTTP non-2xx 则直接抛 Context7Error,这与 MCP wrapper 的“把错误当文本返回”不同。SDK public methods SDK retry / response path

11. 怎样把 Context7 用好#

Context7 的质量上限不只取决于 index,也取决于调用方是否给出可检索的 query。官方 Skills 与 tool descriptions 反复强调以下实践:context7-mcp skill find-docs query guidance

  1. 先确定 corpus,再检索内容。不知道 ID 时先 resolve;知道 /org/project[/version] 时直接 query。
  2. library name 使用官方拼写Next.jsnextjs 更容易匹配正确项目。
  3. resolve 也要带用户意图libraryName 解决名称,query 帮助候选排序,不要只传一个泛化词。
  4. 一个 query 聚焦一个概念。把 routing、auth、cache 拆开;只有问题本身就在讨论它们的交互时才合并。
  5. 指定版本。只说产品名通常得到当前 indexed version;维护旧项目时应选择 resolve output 中的 version-specific ID。
  6. 优先第一方 source。综合 exact name、description、snippet coverage、Source Reputation 与 Benchmark Score,而不是机械选择结果第一项。
  7. 不要把秘密放进 query。API key、password、credential、个人数据和 proprietary code 都不应作为检索词发送。
  8. 限制重复调用。官方 instruction 建议每个问题对同一工具最多调用三次;失败后解释原因,不要无限改写 query。
  9. 核对来源与适用版本。Context7 返回的是相关材料,不是正确性证明;项目 README 也声明 community-contributed docs 无法保证完整性与安全性。官方 disclaimer

一个好的 Agent prompt 可以直接包含 ID、版本和单一目标:

使用 Context7 的 /vercel/next.js/v15.1.8 文档,查询 Route Handler 中
GET response caching 的当前默认行为。只回答 caching,不展开 auth;给出来源版本。

12. 三个官方 Skills,以及它们与 setup 的关系#

Skills 是 instruction layer,不是新的数据通道。它们解决“Agent 何时想起 Context7、怎样形成高质量参数”;真正的数据仍经 MCP 或 CLI / REST 取得。

Skill作用是否由 ctx7 setup 安装
context7-mcp遇到 library / framework / SDK / API / CLI / cloud service 问题时,指导 Agent 调 resolve-library-idquery-docs;强调官方 source、版本和单主题 query。是,选择 MCP mode 时安装,同时写 MCP config 与 rule。
find-docs不依赖 MCP,指导 Agent 用 npx ctx7@latest librarydocs;包含认证、quota failure 和 query hygiene。是,选择 CLI + Skills mode 时安装,同时写 CLI rule。
context7-cliCLI 的综合操作手册,另外覆盖 Skills registry 的 install / search / suggest / generate / remove 与 setup reference。否;固定提交的 setup 实现只在两种 mode 中安装前两项。

context7-cli skill 总览 setup 输出物说明 MCP skill 安装实现 find-docs 安装实现

setup 实际形成三层配置:

  1. Access layer:MCP config 或可执行的 ctx7 CLI。
  2. Trigger layer:rule 告诉 Agent 哪类问题应自动使用 Context7。
  3. Procedure layer:Skill 规定 resolve、选择候选、query、处理失败的步骤。

只装 MCP config 而没有 rule / skill,工具虽然可用,模型未必主动调用;只装 skill 而没有 MCP 或 CLI/network permission,Agent 知道流程也无法取得文档。理解这三层,比把“安装成功”简化为是否出现两个 tool 更准确。

13. Pro 用户视角:key、private sources、teamspace 与 policies#

首先要区分 API key 和 Pro:API key 不是 Pro 专属。匿名 MCP 可以工作;有 key 时 limit 由 plan 决定,当前用量与 reset window 应从 Dashboard 查看。仓库的 Plans 页面本身只跳转到实时网页,因此本文不写死请求额度或价格。API rate-limit 说明 Plans 跳转页

对 Pro 工作流更有实际影响的是下面四点:

13.1 用 teamspace key 贯穿所有入口#

Dashboard 创建的 key 只显示一次,格式为 ctx7sk-...,可随时 revoke;revoke 后所有依赖该 key 的 request 会立即失败。remote MCP 使用 Authorization: Bearer,stdio 使用 CONTEXT7_API_KEY--api-key,SDK 从 constructor 或环境变量读取。API key 管理

建议按 Agent / environment 分 key,避免开发机、CI 和共享服务共用一个 secret;把 revoke 当作 credential rotation,而不是删除配置后的清理步骤。

13.2 private sources 是 backend capability#

固定提交文档把 private sources 列为 Pro 或 Enterprise 能力,支持 GitHub、GitLab、Bitbucket、generic Git、Confluence 与 OpenAPI。Owner / Admin 可以 add、refresh、remove,Developer 只能查看;可选的 Generate docs 会从源码生成说明。private sources 角色与 parsing config

MCP source 没有 private-repository connector。它只是把同一个 key 和 query 传给 API,所以 private library 是否可见、是否已完成 parsing、调用者是否有权限,全部由 hosted service / teamspace 决定。

13.3 teamspace 是权限与限额的归属边界#

官方文档说明 Pro / Enterprise 才能创建 teamspace,只有 owner 需要付费,受邀成员共享 team limits。角色分为 Owner、Admin、Developer;三者都能创建 API keys,但只有 Owner / Admin 可以管理成员、library access 与 private sources。teamspace 与角色

因此 production setup 不应只问“Agent 有没有 key”,还要问“这个 key 属于哪个 teamspace、由谁 revoke、可检索哪些 source”。

13.4 policies 在检索前生效#

每个使用 teamspace API key 的 search 和 MCP request 都会经过 teamspace policies。Owner / Admin 可以整体开关 public repositories、websites、llms.txt、Confluence、uploaded files、Notion 与 private sources,也可用 verification、trust、freshness 等 quality filters,或改成手工 allowlist。过滤后的 search response 还会设置 searchFilterApplied,MCP formatter 会把提示写进候选结果。Policies 行为 过滤提示格式化

这条链路的架构含义是:policy enforcement 不在本地 Agent,也不在开源 MCP process,而在 API backend。不要把模型“答应只用官方文档”当成 access control;真正的组织级约束应落到 teamspace policies。

13.5 private query 的数据边界#

即使 private source 权限正确,query、client metadata 和检索结果仍参与 hosted request。对“代码和文档绝不能离开环境”的场景,Pro Cloud private sources 与 full On-Premise 不是同一安全边界。官方 On-Premise 文档明确声称 code、documentation 与 embeddings 留在自有基础设施,并提供本地 parsing / indexing pipeline;这属于 Enterprise 方案,应单独做 license、identity、backup 与 network review。On-Premise 定位

14. 设计取舍与源码阅读后的判断#

14.1 做得好的地方#

  • 两个工具维持很小的 public interface,把 library disambiguation 与 content retrieval 分开。
  • 同一 Zod preprocess 覆盖所有 transport 和 protocol era,对 LLM 参数漂移很实用。
  • HTTP 使用 AsyncLocalStorage 隔离 request context,并明确保持 stateless,扩容边界清楚。
  • proxy、custom CA、OAuth discovery、JWT issuer 分流和 client info propagation 都进入了生产路径,而不是只停留在 demo。
  • 集成测试使用真实 build binary、本地 stub API、HTTP / stdio 和 modern / legacy 四种组合,验证的不是单个函数,而是 wire behavior。集成测试范围

14.2 需要调用方理解的代价#

  • “先 resolve 再 query”主要靠 prompt / skill 约束,不是 server-side state validation。
  • API failure 通常仍是 successful Tool Result;监控若只统计 MCP protocol errors,会低估失败率。
  • local MCP 不是 offline mode,默认 API endpoint 仍在 Context7 Cloud。
  • MCP wrapper 与 TypeScript SDK 各自维护 HTTP client,retry、anonymous access 与 error semantics 不一致。
  • package README 在固定提交中存在旧工具名,升级或生成 client 时必须重新看 tools/list 与 source。
  • keepAliveMs: 0 是经历 long-lived hung stream 后的显式运行策略;若把代码部署到不同 gateway,应同时评估 backend timeout、stream idle timeout 和取消语义,不能只照搬单个数值。关闭 heartbeat 的原因

15. 本地复现与验证#

以下命令对应本文锁定的提交;MCP package 要求 Node.js >=20.18.1

git clone https://github.com/upstash/context7.git
cd context7
git checkout 9a384f099011d6299df530fd8d7a22510b2004d5
corepack enable
pnpm install --frozen-lockfile

# 编译 MCP package
pnpm --filter @upstash/context7-mcp build

# unit + integration;integration 会打开本机 loopback port
pnpm --filter @upstash/context7-mcp test

本文环境得到:

Test Files  5 passed (5)
Tests       79 passed (79)

integration suite 会先 build 真实 dist/index.js,再启动本地 stub Context7 API,分别用 Streamable HTTP 与 stdio client、modern 2026-07-28 与 legacy protocol 完成 tool listing、schema、alias、client info 和端到端 request 断言;它不会把测试 query 发给生产 Context7 API。测试 harness 四种组合断言

参考资料#

本文共 10253 字,创建于 Aug 27, 2026

相关标签: Tools, AI, Agent, TypeScript, Github, ByAI