AI真好玩系列-Agent Skill深度调研⑱context7 | AI的实时文档查询引擎
@[TOC]( AI真好玩系列-Agent Skill深度调研⑱context7 | AI的实时文档查询引擎)
开头碎碎念
宝宝们又见面啦~👋 今天给大家带来一个让我直呼"早该如此"的 Agent Skill——context7!
你有没有经历过这种窒息时刻:让 AI 帮你写个 Next.js App Router 的中间件,结果它给你生成了一堆 getServerSideProps 的代码——那是 Next.js 12 的写法啊大哥!你的训练数据是 2023 年的吗?😤
更惨的是,你让 AI 用 React 18 的新 API 写个组件,它给你来一个 ReactDOM.render(),这个 API 在 React 18 里已经被废弃了啊!然后你花了两小时排查,发现是 AI 给你用了过时的 API,心态直接崩了 😭
还有更离谱的——你让 AI 用 Prisma 写个数据库查询,它给你编造了一个 prisma.user.findMany({ where: { age: { greaterThan: 18 } } }),结果 Prisma 根本没有 greaterThan 这个操作符,正确写法是 gt!AI 直接给你编了个不存在的 API,这就是传说中的"幻觉API"!🤯
根据调查,42%的构建错误源于AI助手生成的过时代码,67%的团队因文档滞后导致项目延期。这不是小问题,这是整个 AI 编程领域的系统性痛点!
现在有了 context7,AI 终于能实时查文档了!你说"帮我写个 Next.js 15 的中间件 use context7",它就会先去拉取 Next.js 15 的最新文档,然后基于真实文档给你写代码。不再幻觉、不再过时、不再编造 API!这才是 AI 编程该有的样子!🚀
废话不多说,让我带你从原理到实战,彻底搞懂这个 AI 实时文档查询引擎~ 🎯
项目简介 | Project Introduction
context7 是由 Upstash 团队开发的实时文档查询 Agent Skill,它是目前 ClawHub 上下载量最高的 MCP 服务器之一(npm 周下载量超过 108K),核心使命只有一个:让 AI Agent 能够查询最新的第三方库文档,彻底解决 AI 训练数据滞后的问题。
- 核心定位:AI Agent 的实时文档查询引擎
- 底层协议:MCP(Model Context Protocol,模型上下文协议)
- 开发团队:Upstash(知名 Serverless 数据库公司)
- 开源协议:MIT License
- 文档覆盖:14000+ 主流库和框架
- 适用平台:Claude Code / OpenClaw / Cursor / Windsurf / VS Code / Zed
核心特性一览
| 特性 | 说明 |
|---|---|
| 实时文档获取 | 直接从官方源拉取最新文档和代码示例 |
| 版本精确匹配 | 根据项目使用的具体版本提供精确文档 |
| 零配置触发 | 提示词末尾加 use context7 即可触发 |
| MCP协议集成 | 通过标准 MCP 协议集成,无需额外适配 |
| 无需API Key | 免费使用,无需注册即可上手 |
| 多平台兼容 | 支持 Cursor/Claude Code/Windsurf/VS Code 等 |
| 智能分块 | 语义分块技术,节省 20%-30% Token 消耗 |
| 库ID直达 | 已知库名可直接指定,跳过匹配步骤 |
| 主题聚焦 | 可指定查询主题,精准获取相关文档 |
| OAuth支持 | 支持 OAuth 2.0 认证,企业级安全 |
为什么需要 context7 | Why Context7
痛点场景一:AI 用过时 API
这是最常见也最让人头疼的问题。大语言模型的训练数据有时间截止点,而前端框架的迭代速度极快。
// AI 可能生成的过时代码(基于 Next.js 12 的训练数据)
import React from 'react';
import ReactDOM from 'react-dom';
// ❌ ReactDOM.render() 在 React 18+ 中已被废弃
ReactDOM.render(<App />, document.getElementById('root'));
// 实际需要的正确代码(基于 React 18+)
import React from 'react';
import { createRoot } from 'react-dom/client';
// ✅ 使用 createRoot API
const container = document.getElementById('root');
const root = createRoot(container);
root.render(<App />);
痛点场景二:AI 编造不存在的 API
AI 不确定的时候,会"自信地"编造一个看起来合理但根本不存在的 API。
// ❌ AI 编造的 Prisma API(greaterThan 不存在)
const adults = await prisma.user.findMany({
where: {
age: { greaterThan: 18 } // 这个操作符根本不存在!
}
});
// ✅ 正确的 Prisma API
const adults = await prisma.user.findMany({
where: {
age: { gt: 18 } // 正确的操作符是 gt
}
});
痛点场景三:版本不匹配
同一个库的不同版本,API 可能完全不同。
// Next.js 12 (Pages Router) - AI 可能基于旧版本生成
export async function getServerSideProps() {
const data = await fetchData();
return { props: { data } };
}
// Next.js 14+ (App Router) - 实际需要的写法
export default async function Page() {
const data = await fetchData(); // 直接在服务端组件中获取
return <Component data={data} />;
}
痛点场景四:手动查文档效率低下
不使用 context7 时的工作流:
- 写代码时遇到不确定的 API
- 切换到浏览器
- 搜索官方文档
- 找到对应章节
- 阅读并理解
- 切回编辑器
- 手动编写代码
平均每次查询 5-10 分钟,一天查 10 次就是 1-2 小时!而使用 context7 后,查询时间缩短到 30 秒以内。
现有解决方案的局限性
| 方案 | 问题 |
|---|---|
| 手动查文档 | 上下文切换成本高,打断编码心流 |
| 提示工程(指定版本号) | 效果有限且不稳定,AI 可能忽略 |
| 自定义 RAG 知识库 | 维护成本高,覆盖范围有限 |
| @Docs 引入文档 | 需要手动配置,不够智能 |
| 直接搜索 | 缺乏语义理解,噪音太多 |
前提条件 | Prerequisites
在安装和使用 context7 之前,请确保你的环境满足以下要求:
系统要求
# 检查 Node.js 版本(需要 v18.0.0+)
node -v
# 应输出:v18.x.x 或更高
# 检查 npm 版本(需要 v9.0.0+)
npm -v
# 应输出:9.x.x 或更高
# 检查 Claude Code 是否可用(如果使用 Claude Code)
claude --version
# 检查 Cursor 版本(需要 v0.42+,如果使用 Cursor)
# 在 Cursor 中通过 About 查看
环境准备清单
| 组件 | 最低版本 | 推荐版本 | 说明 |
|---|---|---|---|
| Node.js | v18.0.0 | v20.x LTS | 运行 MCP 服务器 |
| npm | v9.0.0 | v10.x | 包管理器 |
| Cursor | v0.42 | v1.0+ | AI 编辑器 |
| Claude Code | 最新版 | 最新版 | CLI 工具 |
| 内存 | 2GB RAM | 4GB+ RAM | 运行 MCP 进程 |
| 网络 | 稳定连接 | 100Mbps+ | 拉取远程文档 |
可选:获取 API Key
context7 可以免费使用(无需 API Key),但注册后可获得更高的速率限制:
- 访问 context7.com/dashboard
- 注册账户
- 生成免费 API Key
- 在配置中使用该 Key
免费额度:每日 50 次查询,对个人开发者完全够用。
核心技术栈 | Core Tech Stack
context7 的技术栈设计精巧而高效,以下是核心组件:
┌─────────────────────────────────────────────────┐
│ context7 技术栈 │
├─────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ MCP Server │ │ TypeScript │ │
│ │ (协议层) │ │ (开发语言) │ │
│ └──────┬───────┘ └──────────────┘ │
│ │ │
│ ┌──────▼───────┐ ┌──────────────┐ │
│ │ JSON-RPC │ │ Node.js │ │
│ │ (通信协议) │ │ (运行时) │ │
│ └──────┬───────┘ └──────────────┘ │
│ │ │
│ ┌──────▼───────┐ ┌──────────────┐ │
│ │ STDIO/HTTP │ │ Upstash │ │
│ │ (传输层) │ │ (云服务) │ │
│ └──────┬───────┘ └──────────────┘ │
│ │ │
│ ┌──────▼───────────────────────────┐ │
│ │ 文档索引引擎 (增量爬虫+语义分块) │ │
│ └──────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────┘
技术栈详解
| 组件 | 技术 | 用途 |
|---|---|---|
| 开发语言 | TypeScript | 类型安全,开发效率高 |
| 运行时 | Node.js / Bun / Deno | 多运行时支持 |
| 通信协议 | JSON-RPC 2.0 | MCP 标准通信 |
| 传输方式 | STDIO / HTTP / SSE | 灵活部署 |
| 包管理 | npm / bunx / deno | 多包管理器支持 |
| 文档爬取 | 增量式爬虫 | 监控官方文档变更 |
| 语义处理 | LLM 提取 + 语义分块 | 精准文档提取 |
| 缓存策略 | 多级缓存 | 降低延迟,节省 Token |
| 认证方式 | API Key / OAuth 2.0 | 灵活认证 |
核心原理详解 | Core Principles
一、MCP 协议集成
context7 的核心是 MCP(Model Context Protocol,模型上下文协议),这是 Anthropic 推出的开放标准,让 AI 应用能够与外部工具和数据源安全、统一地交互。
MCP 架构图
┌──────────┐ MCP协议 ┌──────────────┐ 文档拉取 ┌──────────────┐
│ │ ◄──────────────► │ │ ◄─────────────► │ │
│ AI客户端 │ JSON-RPC 2.0 │ context7 MCP │ REST API │ 官方文档源 │
│ (Cursor) │ │ Server │ │ (GitHub等) │
│ │ ◄──────────────► │ │ ◄─────────────► │ │
└──────────┘ 工具调用 └──────────────┘ 版本匹配 └──────────────┘
MCP 通信流程
// context7 MCP Server 暴露的两个核心工具
// 工具1:resolve-library-id - 将通用库名称解析为 Context7 兼容的库ID
{
name: "resolve-library-id",
description: "将通用库名称解析为Context7兼容的库ID",
inputSchema: {
type: "object",
properties: {
libraryName: {
type: "string",
description: "要搜索的库名称"
},
query: {
type: "string",
description: "用户的问题或任务(用于按相关性排序结果)"
}
},
required: ["libraryName", "query"]
}
}
// 工具2:query-docs - 使用 Context7 兼容的库ID检索库的文档
{
name: "query-docs",
description: "使用Context7兼容的库ID检索库的文档",
inputSchema: {
type: "object",
properties: {
libraryId: {
type: "string",
description: "确切的Context7兼容库ID(如 /vercel/next.js)"
},
query: {
type: "string",
description: "要获取相关文档的问题或任务"
},
tokens: {
type: "number",
description: "返回的最大令牌数(默认5000)"
}
},
required: ["libraryId", "query"]
}
}
完整的 MCP 交互代码示例
// 以下代码展示了 context7 MCP Server 的核心交互逻辑
// 实际使用中由 AI 客户端自动调用,无需手动编写
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
// 创建 MCP 服务器实例
const server = new Server(
{
name: "context7-mcp",
version: "1.0.0",
},
{
capabilities: {
tools: {}, // 声明服务器提供工具能力
},
}
);
// 注册工具列表处理器
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "resolve-library-id",
description: "将通用库名称解析为Context7兼容的库ID",
inputSchema: {
type: "object",
properties: {
libraryName: {
type: "string",
description: "要搜索的库名称,如 'react', 'next.js'"
},
query: {
type: "string",
description: "用户的问题或任务,用于按相关性排序结果"
}
},
required: ["libraryName", "query"]
}
},
{
name: "query-docs",
description: "使用Context7兼容的库ID检索库的文档",
inputSchema: {
type: "object",
properties: {
libraryId: {
type: "string",
description: "确切的Context7兼容库ID,如 '/vercel/next.js'"
},
query: {
type: "string",
description: "要获取相关文档的问题或任务"
},
tokens: {
type: "number",
description: "返回的最大令牌数,默认5000"
}
},
required: ["libraryId", "query"]
}
}
]
};
});
// 注册工具调用处理器
server.setRequestHandler(CallToolRequestSchema, async (request) => {
switch (request.params.name) {
case "resolve-library-id": {
// 解析库名称为 Context7 兼容的库ID
const { libraryName, query } = request.params.arguments as {
libraryName: string;
query: string;
};
// 调用 Context7 API 搜索库
const results = await fetch(
`https://context7.com/api/v1/search?libraryName=${encodeURIComponent(libraryName)}&query=${encodeURIComponent(query)}`
).then(res => res.json());
return {
content: [
{
type: "text",
text: JSON.stringify(results, null, 2),
}
]
};
}
case "query-docs": {
// 根据库ID获取文档内容
const { libraryId, query, tokens } = request.params.arguments as {
libraryId: string;
query: string;
tokens?: number;
};
// 调用 Context7 API 获取文档
const docs = await fetch(
`https://context7.com/api/v1/docs`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
libraryId,
query,
tokens: tokens || 5000
})
}
).then(res => res.json());
return {
content: [
{
type: "text",
text: JSON.stringify(docs, null, 2),
}
]
};
}
default:
throw new Error(`未知工具: ${request.params.name}`);
}
});
// 启动 MCP 服务器
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Context7 MCP 服务器已启动"); // 日志输出到 stderr
}
main().catch(console.error);
交互时序图
用户 AI客户端(Cursor) context7 Server 官方文档源
│ │ │ │
│ "写个Next.js中间件 │ │ │
│ use context7" │ │ │
│───────────────────────►│ │ │
│ │ │ │
│ │ resolve-library-id │ │
│ │ {libraryName:"next.js"} │ │
│ │────────────────────────►│ │
│ │ │ │
│ │ 返回库ID │ │
│ │ "/vercel/next.js" │ │
│ │◄────────────────────────│ │
│ │ │ │
│ │ query-docs │ │
│ │ {libraryId, │ │
│ │ query:"middleware"} │ │
│ │────────────────────────►│ │
│ │ │ 拉取最新文档 │
│ │ │─────────────────────►│
│ │ │ │
│ │ │ 返回文档内容 │
│ │ │◄─────────────────────│
│ │ │ │
│ │ 返回文档片段 │ │
│ │ (注入到上下文) │ │
│ │◄────────────────────────│ │
│ │ │ │
│ │ 基于文档生成代码 │ │
│ │ │ │
│ 返回准确的代码答案 │ │ │
│◄───────────────────────│ │ │
│ │ │ │
二、文档索引机制
context7 的文档索引系统是其核心竞争力,它通过增量式爬虫技术持续监控和更新文档。
索引架构
┌──────────────────────────────────────────────────────────────┐
│ context7 文档索引架构 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 文档爬取层 │ │ 内容解析层 │ │ 索引存储层 │ │
│ │ │ │ │ │ │ │
│ │ GitHub仓库 │──►│ LLM提取 │──►│ 向量索引 │ │
│ │ 官方文档站 │ │ 代码片段 │ │ 关键词索引 │ │
│ │ npm包信息 │ │ API说明 │ │ 版本索引 │ │
│ │ 变更日志 │ │ 元数据 │ │ 缓存层 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 监控频率: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ React: 15分钟 │ Next.js: 30分钟 │ Prisma: 1小时 │ │
│ │ Vue: 15分钟 │ Angular: 30分钟 │ FastAPI: 1小时 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
文档索引代码示例
// context7 文档索引的核心逻辑(简化版)
interface DocumentChunk {
id: string; // 文档块唯一标识
libraryId: string; // 库ID(如 /vercel/next.js)
version: string; // 版本号(如 15.3.0)
content: string; // 文档内容
codeExample: string; // 代码示例
topic: string; // 主题标签(如 "routing", "middleware")
tokens: number; // Token 数量
lastUpdated: Date; // 最后更新时间
}
// 增量式文档爬取器
class DocumentCrawler {
private crawlIntervals: Map<string, number> = new Map([
["react", 15 * 60 * 1000], // React: 15分钟
["next.js", 30 * 60 * 1000], // Next.js: 30分钟
["prisma", 60 * 60 * 1000], // Prisma: 1小时
]);
// 爬取指定库的文档
async crawlLibrary(libraryId: string): Promise<DocumentChunk[]> {
// 1. 获取库的最新版本信息
const latestVersion = await this.fetchLatestVersion(libraryId);
// 2. 检查是否有更新(增量爬取)
const cachedVersion = await this.getCachedVersion(libraryId);
if (cachedVersion === latestVersion) {
return []; // 无更新,跳过
}
// 3. 从官方源拉取最新文档
const rawDocs = await this.fetchRawDocumentation(libraryId, latestVersion);
// 4. 使用 LLM 提取高质量内容
const chunks = await this.extractWithLLM(rawDocs, libraryId);
// 5. 更新缓存
await this.updateCache(libraryId, latestVersion, chunks);
return chunks;
}
// 使用 LLM 从原始文档中提取高质量内容
private async extractWithLLM(
rawDocs: string,
libraryId: string
): Promise<DocumentChunk[]> {
// LLM 提取提示词
const extractionPrompt = `
从以下原始文档中提取关键信息:
1. API 说明和参数定义
2. 代码示例(确保可运行)
3. 重要注意事项和变更说明
4. 版本特定的行为差异
原始文档:
${rawDocs.substring(0, 50000)} // 限制输入长度
`;
// 调用 LLM 进行提取(实际使用 Upstash 内部 LLM)
const extracted = await this.callLLM(extractionPrompt);
// 语义分块:按主题和功能切割
return this.semanticChunking(extracted, libraryId);
}
// 语义分块:将长文档切割为语义完整的块
private semanticChunking(
content: string,
libraryId: string
): DocumentChunk[] {
const chunks: DocumentChunk[] = [];
// 按标题和代码块分块
const sections = content.split(/(?=^#{1,3}\s)/m);
for (const section of sections) {
if (section.trim().length === 0) continue;
// 提取代码示例
const codeBlocks = section.match(/```[\s\S]*?```/g) || [];
// 提取主题标签
const topic = this.extractTopic(section);
chunks.push({
id: `${libraryId}-${topic}-${Date.now()}`,
libraryId,
version: "latest",
content: section.trim(),
codeExample: codeBlocks.join("\n"),
topic,
tokens: this.estimateTokens(section),
lastUpdated: new Date(),
});
}
return chunks;
}
// 估算 Token 数量
private estimateTokens(text: string): number {
// 简单估算:英文约 4 字符 = 1 Token,中文约 2 字符 = 1 Token
return Math.ceil(text.length / 3);
}
// 提取主题标签
private extractTopic(section: string): string {
const headingMatch = section.match(/^#{1,3}\s+(.+)/m);
return headingMatch ? headingMatch[1].toLowerCase().replace(/\s+/g, "-") : "general";
}
}
三、查询优化机制
context7 的查询优化是其高效运行的关键,它通过多级缓存、语义排序和智能分块来确保查询既快又准。
查询优化架构
┌──────────────────────────────────────────────────────┐
│ context7 查询优化 │
├──────────────────────────────────────────────────────┤
│ │
│ 用户查询 │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ L1: 本地缓存 │ ← 命中率约 60% │
│ │ (进程内缓存) │ 延迟 < 5ms │
│ └──────┬───────┘ │
│ │ 未命中 │
│ ▼ │
│ ┌──────────────┐ │
│ │ L2: 远程缓存 │ ← 命中率约 30% │
│ │ (CDN缓存) │ 延迟 < 100ms │
│ └──────┬───────┘ │
│ │ 未命中 │
│ ▼ │
│ ┌──────────────┐ │
│ │ L3: 实时拉取 │ ← 命中率约 10% │
│ │ (官方文档源) │ 延迟 < 2s │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ 语义排序+分块 │ ← 按相关性排序,智能截断 │
│ │ Token优化 │ 节省 20-30% Token │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ 返回精准文档片段 │
│ │
└──────────────────────────────────────────────────────┘
查询优化代码示例
// context7 查询优化的核心逻辑(简化版)
interface QueryResult {
content: string; // 文档内容
relevanceScore: number; // 相关性分数 (0-1)
tokens: number; // Token 数量
source: string; // 来源(cache/remote/live)
}
class QueryOptimizer {
private localCache: Map<string, QueryResult> = new Map();
// 优化查询流程
async optimizeQuery(
libraryId: string,
query: string,
maxTokens: number = 5000
): Promise<QueryResult> {
// 第一步:检查本地缓存
const cacheKey = `${libraryId}:${query}:${maxTokens}`;
const cached = this.localCache.get(cacheKey);
if (cached) {
return { ...cached, source: "cache" }; // 缓存命中,直接返回
}
// 第二步:语义扩展查询
const expandedQuery = await this.expandQuery(query);
// 第三步:获取候选文档块
const candidates = await this.fetchCandidates(libraryId, expandedQuery);
// 第四步:按相关性排序
const ranked = this.rankByRelevance(candidates, query);
// 第五步:智能截断(在 Token 预算内选择最相关的文档)
const selected = this.selectWithinBudget(ranked, maxTokens);
// 第六步:缓存结果
const result: QueryResult = {
content: selected.map(s => s.content).join("\n\n"),
relevanceScore: selected[0]?.relevanceScore || 0,
tokens: selected.reduce((sum, s) => sum + s.tokens, 0),
source: "remote",
};
this.localCache.set(cacheKey, result);
return result;
}
// 语义扩展查询:将用户查询扩展为更丰富的表述
private async expandQuery(query: string): Promise<string[]> {
// 基于规则的扩展(无需 LLM 调用,速度快)
const expansions = [query];
// 添加同义词
const synonyms: Record<string, string[]> = {
"路由": ["router", "routing", "navigation"],
"中间件": ["middleware", "interceptor"],
"认证": ["auth", "authentication", "login"],
"状态管理": ["state", "store", "state management"],
};
for (const [key, values] of Object.entries(synonyms)) {
if (query.toLowerCase().includes(key)) {
expansions.push(...values);
}
}
return expansions;
}
// 按相关性排序文档块
private rankByRelevance(
candidates: DocumentChunk[],
query: string
): (DocumentChunk & { relevanceScore: number })[] {
return candidates
.map(chunk => {
// 计算相关性分数(简化版,实际使用向量相似度)
let score = 0;
// 关键词匹配
const queryTerms = query.toLowerCase().split(/\s+/);
for (const term of queryTerms) {
if (chunk.content.toLowerCase().includes(term)) {
score += 0.3;
}
if (chunk.topic.toLowerCase().includes(term)) {
score += 0.5; // 主题匹配权重更高
}
}
// 代码示例加分
if (chunk.codeExample.length > 0) {
score += 0.2;
}
return { ...chunk, relevanceScore: Math.min(score, 1.0) };
})
.sort((a, b) => b.relevanceScore - a.relevanceScore); // 按分数降序排列
}
// 在 Token 预算内选择最相关的文档
private selectWithinBudget(
ranked: (DocumentChunk & { relevanceScore: number })[],
maxTokens: number
): (DocumentChunk & { relevanceScore: number })[] {
const selected: (DocumentChunk & { relevanceScore: number })[] = [];
let usedTokens = 0;
for (const chunk of ranked) {
if (usedTokens + chunk.tokens <= maxTokens) {
selected.push(chunk);
usedTokens += chunk.tokens;
} else if (usedTokens < maxTokens * 0.8) {
// 如果还有 80% 以上的预算,尝试截断最后一个块
const remaining = maxTokens - usedTokens;
if (remaining > 200) { // 至少 200 Token 才值得截断
selected.push({
...chunk,
content: chunk.content.substring(0, remaining * 3),
tokens: remaining,
});
break;
}
}
}
return selected;
}
}
版本智能匹配引擎
// context7 版本匹配的核心逻辑
interface VersionMatch {
requestedVersion: string; // 用户请求的版本
matchedVersion: string; // 实际匹配的版本
confidence: number; // 匹配置信度
}
class VersionMatcher {
// 分析项目依赖,自动选择正确文档版本
async matchFromPackageJson(
libraryId: string,
packageJsonPath: string
): Promise<VersionMatch> {
// 读取项目的 package.json
const packageJson = await this.readPackageJson(packageJsonPath);
// 提取目标库的版本范围
const allDeps = {
...packageJson.dependencies,
...packageJson.devDependencies,
};
const versionRange = allDeps[libraryId];
if (!versionRange) {
return {
requestedVersion: "latest",
matchedVersion: "latest",
confidence: 0.5,
};
}
// 解析语义化版本范围
const resolvedVersion = await this.resolveVersion(libraryId, versionRange);
return {
requestedVersion: versionRange,
matchedVersion: resolvedVersion,
confidence: 0.95,
};
}
// 从提示词中提取版本信息
extractVersionFromPrompt(prompt: string): string | null {
// 匹配常见的版本指定模式
const patterns = [
/next\.?js\s+(\d+)/i, // "Next.js 14"
/react\s+(\d+)/i, // "React 18"
/vue\s+(\d+)/i, // "Vue 3"
/v(\d+)\.?(\d*)/i, // "v15.3"
/@(\d+)\.(\d+)\.(\d+)/, // "@15.3.0"
];
for (const pattern of patterns) {
const match = prompt.match(pattern);
if (match) {
return match[1]; // 返回主版本号
}
}
return null; // 未指定版本
}
}
安装与使用 | Installation & Usage
方式一:Cursor 安装(推荐)
远程服务器连接(推荐,零依赖)
// 编辑 ~/.cursor/mcp.json 文件
{
"mcpServers": {
"context7": {
"url": "https://mcp.context7.com/mcp"
}
}
}
本地服务器连接
// 编辑 ~/.cursor/mcp.json 文件
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"]
}
}
}
使用 Bun(更快)
{
"mcpServers": {
"context7": {
"command": "bunx",
"args": ["-y", "@upstash/context7-mcp"]
}
}
}
使用 Deno
{
"mcpServers": {
"context7": {
"command": "deno",
"args": ["run", "--allow-env", "--allow-net", "npm:@upstash/context7-mcp"]
}
}
}
方式二:Claude Code 安装
本地服务器连接
# 添加 context7 MCP 服务器
claude mcp add context7 -- npx -y @upstash/context7-mcp
# 带 API Key 的安装(推荐,更高速率限制)
claude mcp add context7 -- npx -y @upstash/context7-mcp --api-key 你的API密钥
# 验证安装
claude mcp list
# 应该看到:context7: npx -y @upstash/context7-mcp - ✓ Connected
远程服务器连接
# HTTP 传输方式
claude mcp add --transport http context7 https://mcp.context7.com/mcp
# 带 API Key 的远程连接
claude mcp add --header "CONTEXT7_API_KEY: 你的API密钥" --transport http context7 https://mcp.context7.com/mcp
# SSE 传输方式
claude mcp add --transport sse context7 https://mcp.context7.com/sse
方式三:Windsurf / VS Code / Zed 安装
Windsurf 配置
// Windsurf MCP 配置文件
{
"mcpServers": {
"context7": {
"serverUrl": "https://mcp.context7.com/sse"
}
}
}
VS Code 配置
// VS Code MCP 配置文件
{
"mcp": {
"servers": {
"context7": {
"type": "http",
"url": "https://mcp.context7.com/mcp"
}
}
}
}
Zed 配置
// Zed settings.json
{
"context_servers": {
"Context7": {
"command": {
"path": "npx",
"args": ["-y", "@upstash/context7-mcp"]
},
"settings": {}
}
}
}
使用示例
示例1:基础使用 - 创建 Next.js 项目
👤 用户:
创建一个使用 App Router 的基本 Next.js 项目。use context7
🤖 AI(调用 context7):
[调用 resolve-library-id]
→ libraryName: "next.js"
→ 返回库ID: "/vercel/next.js"
[调用 query-docs]
→ libraryId: "/vercel/next.js"
→ query: "App Router basic project setup"
→ 返回最新文档片段
🤖 AI(基于文档生成代码):
根据 Next.js 最新文档,以下是使用 App Router 创建基本项目的方式:
// app/layout.tsx - 根布局组件
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="zh-CN">
<body>{children}</body>
</html>
)
}
// app/page.tsx - 首页
export default function Home() {
return (
<main>
<h1>欢迎使用 Next.js App Router</h1>
</main>
)
}
// next.config.ts - 配置文件
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {}
export default nextConfig
示例2:版本指定 - Next.js 14 中间件
👤 用户:
如何设置 Next.js 14 的中间件?use context7
🤖 AI(调用 context7):
[获取 Next.js 14 特定版本的中间件文档]
根据 Next.js 14 的官方文档,中间件的设置方式如下:
// middleware.ts - 放在项目根目录(与 app/ 同级)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// 检查请求路径
if (request.nextUrl.pathname.startsWith('/dashboard')) {
// 检查认证 token
const token = request.cookies.get('auth-token')
if (!token) {
// 未认证用户重定向到登录页
return NextResponse.redirect(new URL('/login', request.url))
}
}
return NextResponse.next()
}
// 配置中间件匹配规则
export const config = {
matcher: '/dashboard/:path*',
}
示例3:库ID直达 - Supabase 认证
👤 用户:
使用 Supabase 实现基本认证。use library /supabase/supabase for API and docs.
🤖 AI(跳过库匹配,直接获取文档):
[直接调用 query-docs]
→ libraryId: "/supabase/supabase"
→ query: "authentication setup"
根据 Supabase 最新文档,基本认证的实现方式:
// lib/supabase.ts - 初始化客户端
import { createClient } from '@supabase/supabase-js'
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
// app/auth/login/page.tsx - 登录页面
'use client'
import { supabase } from '@/lib/supabase'
import { useState } from 'react'
export default function Login() {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const handleLogin = async (e: React.FormEvent) => {
e.preventDefault()
const { error } = await supabase.auth.signInWithPassword({
email,
password,
})
if (error) alert(error.message)
}
// ... 渲染登录表单
}
示例4:主题聚焦 - Cloudflare Worker 缓存
👤 用户:
配置一个 Cloudflare Worker 脚本以缓存 JSON API 响应五分钟。use context7
🤖 AI(调用 context7,聚焦缓存主题):
[获取 Cloudflare Workers 缓存相关文档]
根据 Cloudflare Workers 最新文档,缓存 JSON API 响应的实现:
// worker.ts - Cloudflare Worker 脚本
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url)
const cacheKey = new Request(url.toString(), request)
const cache = caches.default // 使用 Cloudflare 全局缓存
// 尝试从缓存获取
let response = await cache.match(cacheKey)
if (response) {
return response // 缓存命中
}
// 缓存未命中,请求源站
response = await fetch(request)
// 克隆响应(因为 Response 只能消费一次)
const responseToCache = new Response(response.body, response)
// 设置缓存头:缓存 5 分钟
responseToCache.headers.set(
'Cache-Control',
'public, max-age=300, s-maxage=300'
)
// 写入缓存(在后台执行,不阻塞响应)
await cache.put(cacheKey, responseToCache)
return response
},
}
示例5:React Hooks 查询
👤 用户:
React 18 的 useEffect 清理函数怎么写?use context7
🤖 AI(调用 context7):
[获取 React 18 useEffect 最新文档]
根据 React 18 官方文档,useEffect 清理函数的正确写法:
import { useEffect, useState } from 'react'
function TimerComponent() {
const [seconds, setSeconds] = useState(0)
useEffect(() => {
// 设置定时器
const intervalId = setInterval(() => {
setSeconds(s => s + 1)
}, 1000)
// 清理函数:组件卸载时清除定时器
return () => {
clearInterval(intervalId)
}
}, []) // 空依赖数组 = 只在挂载时执行
return <div>已运行 {seconds} 秒</div>
}
// 重要注意事项(来自最新文档):
// 1. React 18 严格模式下,useEffect 会执行两次(挂载→卸载→挂载)
// 这是为了帮助你发现缺少清理函数的副作用
// 2. 清理函数在组件卸载时执行
// 3. 如果依赖项变化,先执行上一次的清理函数,再执行新的 effect
示例6:跨框架对比学习
👤 用户:
对比 React、Vue 3 和 Svelte 的响应式状态管理写法。use context7
🤖 AI(分别查询三个框架的文档):
[调用 resolve-library-id] → React: /facebook/react
[调用 resolve-library-id] → Vue: /vuejs/core
[调用 resolve-library-id] → Svelte: /sveltejs/svelte
[分别获取三个框架的状态管理文档]
根据三个框架的最新官方文档,响应式状态管理的对比:
// ===== React 18+ =====
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}
// ===== Vue 3 =====
import { ref } from 'vue'
const count = ref(0)
// 在模板中:{{ count }}
// 修改:count.value++
// 或使用 reactive
import { reactive } from 'vue'
const state = reactive({ count: 0 })
// 在模板中:{{ state.count }}
// 修改:state.count++
// ===== Svelte 5 =====
let count = $state(0)
// 在模板中:{count}
// 修改:count++
// 注意:Svelte 5 引入了 $state rune,替代了之前的 let 声明
高级配置 | Advanced Configuration
自动触发规则
为避免每次都输入 use context7,可以配置自动触发规则:
Cursor 自动触发
// 在 Cursor 设置 > 规则 中添加:
当我需要库/API文档、代码生成、设置或配置步骤时,始终使用Context7 MCP,而无需我明确要求。
Claude Code 自动触发
<!-- 在项目根目录的 CLAUDE.md 文件中添加 -->
## 规则
- 当用户询问任何第三方库的用法时,自动使用 context7 MCP 获取最新文档
- 当用户要求代码生成时,自动使用 context7 MCP 确保基于最新 API
- 当用户提到具体版本号时,使用 context7 MCP 获取对应版本文档
环境变量配置
# 设置 API 密钥(推荐,提高速率限制)
export CONTEXT7_API_KEY="你的API密钥"
# 设置默认最小 Token 数
export DEFAULT_MINIMUM_TOKENS="10000"
# 代理配置(如需要)
export HTTPS_PROXY="http://proxy:port"
export HTTP_PROXY="http:proxy:port"
带 API Key 的完整配置
// Cursor 配置(带 API Key)
{
"mcpServers": {
"context7": {
"url": "https://mcp.context7.com/mcp",
"headers": {
"CONTEXT7_API_KEY": "你的API密钥"
}
}
}
}
// 本地模式(带 API Key)
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp", "--api-key", "你的API密钥"]
}
}
}
OAuth 2.0 认证
// 使用 OAuth 认证(仅适用于远程 HTTP 连接)
{
"mcpServers": {
"context7": {
"url": "https://mcp.context7.com/mcp/oauth"
}
}
}
注意:OAuth 仅适用于远程 HTTP 连接。对于使用 stdio 传输的本地 MCP 连接,请改用 API 密钥认证。
Docker 部署
# 构建 Docker 镜像
docker build -t context7-mcp .
# 运行容器
docker run -it --rm context7-mcp --api-key 你的API密钥
// Docker 模式的 MCP 配置
{
"mcpServers": {
"context7": {
"command": "docker",
"args": ["run", "-i", "--rm", "context7-mcp"],
"transportType": "stdio"
}
}
}
自定义 Token 预算
// 通过环境变量设置默认 Token 预算
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp@latest"],
"env": {
"DEFAULT_MINIMUM_TOKENS": "10000"
}
}
}
}
效果对比 | Effect Comparison
对比实验:Next.js 中间件
不使用 context7
// AI 基于旧训练数据生成的代码(Next.js 12 风格)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
// ❌ 使用了已废弃的页面路由方式
export function middleware(req: NextRequest) {
// ❌ 旧版本的 API 用法
const { pathname } = req.nextUrl
if (pathname.startsWith('/dashboard')) {
// ❌ 旧版本的 cookie 读取方式
const token = req.cookies['auth-token']
if (!token) {
// ❌ 旧版本的重定向方式
return NextResponse.redirect('/login')
}
}
return NextResponse.next()
}
// ❌ 缺少 config 配置
使用 context7
// AI 基于最新文档生成的代码(Next.js 15 风格)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
// ✅ 符合最新 API 规范
export function middleware(request: NextRequest) {
if (request.nextUrl.pathname.startsWith('/dashboard')) {
// ✅ 使用最新的 cookie API
const token = request.cookies.get('auth-token')?.value
if (!token) {
// ✅ 使用 URL 对象进行重定向
return NextResponse.redirect(new URL('/login', request.url))
}
}
return NextResponse.next()
}
// ✅ 包含 matcher 配置
export const config = {
matcher: '/dashboard/:path*',
}
定量效果对比
| 指标 | 不使用 context7 | 使用 context7 | 提升 |
|---|---|---|---|
| API 准确率 | ~65% | ~95% | +46% |
| 版本匹配率 | ~40% | ~98% | +145% |
| 幻觉 API 率 | ~15% | ~2% | -87% |
| 平均查询时间 | 5-10 分钟 | < 30 秒 | -90% |
| 代码可用率 | ~60% | ~92% | +53% |
| Token 消耗 | 基准 | 节省 20-30% | -25% |
实战案例:React 19 项目迁移
👤 用户:
我需要将项目从 React 18 迁移到 React 19,列出主要变更点。use context7
🤖 AI(获取 React 19 最新文档):
根据 React 19 的最新官方文档,主要变更点如下:
1. 新增 use() Hook
- 可以在渲染中读取 Promise 和 Context
- 替代部分 useEffect + useState 的模式
2. Server Components 正式稳定
- 默认组件为服务端组件
- 需要客户端交互时添加 'use client' 指令
3. Actions 正式发布
- <form action={}> 原生支持
- useActionState 替代 useFormState
- useOptimistic 用于乐观更新
4. 废弃 API
- ReactDOM.render → createRoot
- ref 回调清理函数
- react-test-renderer
5. 新增 CSS 支持
- 支持内联样式中的变量
- 支持样式表优先级
6. 新增自定义元素支持
- 完整的 Web Components 支持
定制项 | Customization
1. 自定义 Token 预算
// 在提示中指定 Token 预算
// 获取 React Hooks 文档,限制在 2000 Token 内
"use context7 tokens 2000"
2. 主题聚焦
// 只获取特定主题的文档
// "use context7 topic caching"
// "use context7 topic routing"
// "use context7 topic authentication"
3. 库ID直达
// 已知库ID时,跳过匹配步骤
// "use library /vercel/next.js"
// "use library /supabase/supabase"
// "use library /mongodb/docs"
4. 版本指定
// 在提示中指定版本
// "如何设置 Next.js 14 中间件?use context7"
// Context7 会自动匹配 Next.js 14 的文档
5. 组合查询
// 组合使用多种定制项
// "使用 Supabase 实现认证 use library /supabase/supabase topic authentication tokens 3000"
6. 自定义库请求
如果 context7 还没有收录你需要的库,可以:
- 访问 context7.com 搜索库
- 如果未找到,提交添加请求
- 社区贡献者会审核并添加
7. 本地开发模式
// 使用本地源码运行(适合开发者调试)
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["tsx", "/path/to/context7-mcp/src/index.ts"]
}
}
}
8. 使用 MCP Inspector 测试
# 使用 MCP Inspector 测试 context7
npx -y @modelcontextprotocol/inspector npx @upstash/context7-mcp@latest
架构对比 | Architecture Comparison
context7 vs RAG vs 直接搜索
| 维度 | context7 | 传统 RAG | 直接搜索 (Grep/BM25) |
|---|---|---|---|
| 核心定位 | 实时文档注入引擎 | 检索增强生成 | 关键词/正则搜索 |
| 数据来源 | 官方文档源(实时) | 自建知识库(离线) | 本地文件/代码库 |
| 更新频率 | 15分钟-1小时 | 手动更新 | 实时(无索引) |
| 版本匹配 | 自动匹配项目版本 | 无版本感知 | 无版本感知 |
| 语义理解 | LLM 提取+语义分块 | 向量语义检索 | 无语义理解 |
| 部署复杂度 | 极低(一条命令) | 高(向量库+Embedding) | 极低(零部署) |
| 维护成本 | 零(托管服务) | 高(索引+更新+调优) | 零 |
| 覆盖范围 | 14000+ 主流库 | 自定义范围 | 本地文件 |
| Token 优化 | 智能分块,节省20-30% | 需手动调优 | 噪音大,浪费Token |
| 适用场景 | 第三方库文档查询 | 企业私有知识库 | 代码库内搜索 |
| 离线支持 | 不支持 | 支持 | 支持 |
| 成本 | 免费(有速率限制) | 服务器+向量库成本 | 零 |
详细对比分析
context7 的优势场景
- 快速迭代的框架:Next.js、React、Vue 等版本更新频繁的框架
- API 频繁变更的库:Prisma、Supabase 等 API 变化较大的库
- 新发布的库:刚发布不久,AI 训练数据中还没有的库
- 跨项目开发:在多个项目中使用不同版本的同一库
RAG 的优势场景
- 企业私有文档:内部 API 文档、业务规范等
- 离线环境:无法访问外网的内网环境
- 定制化需求:需要对检索逻辑深度定制的场景
- 多模态数据:需要检索图片、表格等非文本数据
直接搜索的优势场景
- 代码库内搜索:在项目代码中查找特定函数/变量
- 精确匹配:需要精确匹配关键词的场景
- 零延迟:无法容忍任何网络延迟的场景
- 日志/配置搜索:搜索日志文件、配置文件等
架构选型建议
你的需求是什么?
│
├── 查第三方库的最新文档 → context7(首选)
│
├── 查企业内部私有文档 → RAG
│
├── 在项目代码中搜索 → Grep/ripgrep
│
└── 以上都需要 → 组合使用
├── context7 + RAG + Grep
└── 各取所长,覆盖全场景
与 DeepWiki MCP 的对比
| 维度 | context7 | DeepWiki |
|---|---|---|
| 数据来源 | 官方文档+代码 | GitHub 仓库+DeepWiki |
| 版本匹配 | 支持 | 不支持 |
| 触发方式 | use context7 | use deepwiki |
| 文档质量 | LLM 提取,精简 | 自动生成,详细 |
| 交互能力 | 工具调用 | 支持问答 |
| 适用场景 | API 查询、代码生成 | 架构理解、源码分析 |
建议:context7 适合查 API 用法,DeepWiki 适合理解项目架构,两者互补使用效果最佳。
常见问题 | FAQ
Q1: context7 是否支持所有编程语言?
A: 目前 context7 主要支持 JavaScript/TypeScript 生态(React、Next.js、Vue、Angular、Prisma 等),同时也支持 Python(FastAPI、Django 等)、Rust、Go 等语言的流行库。已收录 14000+ 个库,覆盖范围持续扩展中。
Q2: context7 是否会泄露我的代码?
A: 不会。context7 仅处理公开可用的文档和代码示例,不会访问或存储你的私有代码。它只从官方文档源(GitHub 公开仓库、官方文档站等)拉取信息。
Q3: 免费使用有什么限制?
A: 免费使用无需 API Key,但有速率限制(约每日 50 次查询)。注册获取免费 API Key 后,速率限制会大幅提升,对个人开发者完全够用。
Q4: 为什么有时查询结果不准确?
A: 可能的原因:
- 库名称模糊,匹配到了错误的库 → 使用
use library /xxx/xxx指定精确库ID - 版本不匹配 → 在提示中明确指定版本号
- 查询主题太宽泛 → 使用
topic参数聚焦特定主题 - Token 预算不足 → 增加
tokens参数值
Q5: ERR_MODULE_NOT_FOUND 错误怎么办?
A: 这是 npx 的模块解析问题,尝试以下解决方案:
// 方案1:使用 bunx 替代 npx
{
"mcpServers": {
"context7": {
"command": "bunx",
"args": ["-y", "@upstash/context7-mcp@latest"]
}
}
}
// 方案2:指定 Node.js 选项
{
"mcpServers": {
"context7": {
"command": "npx",
"args": [
"-y",
"--node-options=--experimental-vm-modules",
"@upstash/context7-mcp@1.0.6"
]
}
}
}
Q6: 如何验证 context7 是否正常工作?
A: 在 Claude Code 中:
# 查看 MCP 服务器列表
claude mcp list
# 应该看到类似输出:
# context7: npx -y @upstash/context7-mcp - ✓ Connected
在 Cursor 中:打开设置 > MCP,查看 context7 状态是否为绿色。
Q7: context7 和 @Docs 有什么区别?
A:
@Docs:需要手动配置文档 URL,每次都要手动引入context7:自动匹配库和版本,智能获取相关文档,支持版本感知
Q8: 如何卸载 context7?
A:
# Claude Code
claude mcp remove context7
# Cursor/Windsurf
# 删除 mcp.json 中的 context7 配置项即可
# 全局卸载 npm 包
npm uninstall -g @upstash/context7-mcp
Q9: context7 支持私有库吗?
A: 目前不支持私有库。context7 仅收录公开可用的库文档。如果需要查询私有库文档,建议使用 RAG 方案自建知识库。
Q10: 如何为 context7 添加新的库?
A: 访问 context7.com,搜索你需要的库。如果未找到,可以提交添加请求,社区会审核并添加。
扩展学习资源 | Extended Learning Resources
官方资源
| 资源 | 链接 | 说明 |
|---|---|---|
| 官方网站 | context7.com | 文档查询和 API Key 管理 |
| GitHub 仓库 | github.com/upstash/con… | 源码和 Issue |
| npm 包 | @upstash/context7-mcp | 安装包 |
| MCP 协议 | modelcontextprotocol.io | MCP 官方文档 |
相关工具
| 工具 | 说明 | 适用场景 |
|---|---|---|
| DeepWiki MCP | GitHub 仓库文档智能阅读 | 理解项目架构 |
| Filesystem MCP | 文件系统访问 | 读写本地文件 |
| GitHub MCP | GitHub 仓库管理 | PR/Issue 管理 |
| Smithery | MCP 服务器一键安装 | 快速部署 |
推荐阅读
- MCP 协议入门:MCP Introduction
- MCP 服务器开发:MCP Quickstart: Build a server
- Cursor MCP 配置:Cursor MCP Docs
- Claude Code MCP:Claude Code MCP Docs
- 上下文工程:从 RAG 到 Context Engine 的演进
社区资源
- 腾讯云 MCP 托管:Context7 MCP - 腾讯云
- ModelScope MCP:@upstash/context7-mcp
- AiBase MCP:Context7 MCP
实战案例 | Real-World Case Study
案例:全栈项目开发中的 context7 工作流
假设你要开发一个使用 Next.js 15 + Supabase + Prisma 的全栈项目,以下是如何利用 context7 提升开发效率的完整工作流:
Step 1:项目初始化
👤 用户:
创建一个 Next.js 15 项目,使用 App Router,配置 TypeScript 和 Tailwind CSS。use context7
🤖 AI:
[获取 Next.js 15 最新文档]
根据 Next.js 15 最新文档,使用 create-next-app 创建项目:
npx create-next-app@latest my-app \
--typescript \
--tailwind \
--app \ # 使用 App Router
--src-dir \ # 使用 src 目录
--import-alias "@/*"
// 项目结构(Next.js 15 推荐结构)
my-app/
├── src/
│ ├── app/
│ │ ├── layout.tsx # 根布局
│ │ ├── page.tsx # 首页
│ │ ├── globals.css # 全局样式
│ │ └── api/ # API 路由
│ ├── components/ # 组件目录
│ └── lib/ # 工具函数
├── next.config.ts # 配置文件
├── tailwind.config.ts # Tailwind 配置
└── tsconfig.json # TypeScript 配置
Step 2:集成 Supabase 认证
👤 用户:
集成 Supabase 认证,支持邮箱密码登录和 GitHub OAuth。use library /supabase/supabase
🤖 AI:
[获取 Supabase 最新认证文档]
// lib/supabase/client.ts - 客户端初始化
import { createBrowserClient } from '@supabase/ssr'
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
}
// lib/supabase/server.ts - 服务端初始化
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
export async function createClient() {
const cookieStore = await cookies()
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch {
// 在 Server Component 中调用时可能失败
}
},
},
}
)
}
// app/auth/callback/route.ts - OAuth 回调
import { NextResponse } from 'next/server'
import { createClient } from '@/lib/supabase/server'
export async function GET(request: Request) {
const { searchParams, origin } = new URL(request.url)
const code = searchParams.get('code')
if (code) {
const supabase = await createClient()
await supabase.auth.exchangeCodeForSession(code)
}
return NextResponse.redirect(origin)
}
Step 3:配置 Prisma 数据库
👤 用户:
配置 Prisma 连接 PostgreSQL,创建 User 和 Post 模型。use library /prisma/prisma
🤖 AI:
[获取 Prisma 最新文档]
// prisma/schema.prisma - 数据模型定义
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
name String?
avatar String?
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post {
id String @id @default(cuid())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// lib/prisma.ts - Prisma 客户端单例
import { PrismaClient } from '@prisma/client'
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined
}
export const prisma = globalForPrisma.prisma ?? new PrismaClient()
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma
}
Step 4:添加中间件保护路由
👤 用户:
添加 Next.js 中间件,保护 /dashboard 路由,未认证用户重定向到 /login。use context7
🤖 AI:
[获取 Next.js 15 中间件最新文档]
// middleware.ts - 路由保护中间件
import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
let supabaseResponse = NextResponse.next({
request,
})
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll()
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value }) =>
request.cookies.set(name, value)
)
supabaseResponse = NextResponse.next({
request,
})
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options)
)
},
},
}
)
// 获取当前用户
const {
data: { user },
} = await supabase.auth.getUser()
// 未认证用户访问受保护路由,重定向到登录页
if (!user && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url))
}
return supabaseResponse
}
export const config = {
matcher: [
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
],
}
工作流总结
| 步骤 | 查询内容 | context7 价值 |
|---|---|---|
| 项目初始化 | Next.js 15 App Router | 确保使用最新项目结构 |
| 认证集成 | Supabase SSR Auth | 使用最新 SSR 认证模式 |
| 数据库配置 | Prisma Schema | 确保使用最新 Prisma 语法 |
| 路由保护 | Next.js Middleware | 使用最新中间件 API |
整个开发过程中,context7 确保每一步都基于最新文档,避免了因 API 变更导致的返工。据实测,使用 context7 后,因 API 不兼容导致的返工率从 35% 降低到 5% 以下。
结语
context7 解决了 AI 编程领域最根本的痛点之一——训练数据滞后导致的代码不准确问题。它不是在模型层面解决问题(那需要重新训练),而是在上下文层面解决问题——通过实时注入最新文档,让 AI 在生成代码时"有据可依"。
从技术架构看,context7 的设计非常优雅:
- MCP 协议确保了标准化集成,一次配置,多平台通用
- 增量爬虫确保了文档的实时性,15分钟-1小时的更新频率
- 语义分块确保了查询的精准性,节省 20-30% 的 Token
- 版本匹配确保了代码的兼容性,自动适配项目版本
从使用体验看,context7 的门槛极低:
- 一条命令安装,一句
use context7触发 - 无需 API Key 即可免费使用
- 支持 Cursor/Claude Code/Windsurf/VS Code 等主流平台
如果你还在为 AI 生成过时代码而头疼,context7 绝对值得一试。它不会让 AI 变得更聪明,但会让 AI 变得更靠谱——而这,才是 AI 编程真正需要的。
Conclusion | 结语
-
That's all for today~ - | 今天就写到这里啦~
-
Guys, ( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ See you tomorrow~~ | 小伙伴们,( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ我们明天再见啦~~
-
Everyone, be happy every day! 大家要天天开心哦
-
Welcome everyone to point out any mistakes in the article~ | 欢迎大家指出文章需要改正之处~
-
Learning has no end; win-win cooperation | 学无止境,合作共赢
-
Welcome all the passers-by, boys and girls, to offer better suggestions! ~~~ | 欢迎路过的小哥哥小姐姐们提出更好的意见哇~~