最近,Context7这个MCP有点火,网上到处都在说 "Context7 Solves LLMs' Biggest Flaw" , "Context7 Will Change AI Coding" , "Context7 Makes Cursor 10x Smarter" 。所以这个玩意真的这么神奇么,底层到底是个啥?
Context7是啥
根据官方描述,Context7将 最新的 、 特定版本的文档及代码片段 等信息直接放到prompt中,大模型可参考最新的信息来编写代码,而不会受到过期知识的影响。
所以简单来说,Context7就是让大模型在回答问题前,强制搜一下最新的信息,补充一下上下文,然后再根据补充后的信息进行输出。(那不就是一个web search嘛)
简单尝试
安装步骤就不写了,可以参考 github.com/upstash/con…
问个简单的问题,React19中新推出了useOptimistic(具体这个API是干啥的不重要),对比一下是否使用Context7对结果的影响。
- 不使用Context7:Claude3.7认为这个API是React18中还在实验性的Hook。(当然了,Claude3.7训练完成的时候这个Hook还在实验中)
- 使用Context7:Claude3.7经过了两次MCP调用后,查到这是在React19中的Hook。
对于这个问题,显然使用了Context7之后,大模型给的答案更新。(虽然这个Hook在React18实验版和React19里的用法差不多,预期也不会对结果产生很大影响,但是可能对于其他迭代较快的语言或者框架来说,获取更新的知识意味着大模型能更好的帮我们解决问题,毕竟信息肯定越新越好)
浅看下代码
浅看一下Context7 MCP的代码,其主要提供了两个tool
resolve-library-id:先让大模型判断下需要查询哪个library,在返回结果里找到最相关的library id。(内部主要是调用了API接口查询,再格式化返回给大模型)
server.tool(
"resolve-library-id",
`Resolves a package/product name to a Context7-compatible library ID and returns a list of matching libraries.`,
{
libraryName: z
.string()
.describe("Library name to search for and retrieve a Context7-compatible library ID."),
},
async ({ libraryName }) => {
// 调用API查询最相关的library
const searchResponse = await searchLibraries(libraryName);
// ... 省略多个异常处理
// 格式化处理
const resultsText = formatSearchResults(searchResponse);
return {
content: [
{
type: "text",
text: `Available Libraries (top matches):
----------
${resultsText}`,
},
],
};
}
);
实际大模型调用的输入输出如下:
// 输入
{
`libraryName`: `React`
}
// 输出
Available Libraries (top matches):
Each result includes:
- Library ID: Context7-compatible identifier (format: /org/repo)
- Name: Library or package name
- Description: Short summary
- Code Snippets: Number of available code examples
- Trust Score: Authority indicator
For best results, select libraries based on name match, trust score, snippet coverage, and relevance to your use case.
----------
- Title: React-XR
- Context7-compatible library ID: /pmndrs/xr
- Description: 🤳 VR/AR for react-three-fiber
- Code Snippets: 68
- Trust Score: 9.6
----------
- Title: React95
- Context7-compatible library ID: /react95/react95
- Description: A React components library with Win95 UI
- Code Snippets: 18
- Trust Score: 7.8
----------
- Title: React
- Context7-compatible library ID: /reactjs/react.dev
- Description: The React documentation website
- Code Snippets: 2059
- Trust Score: 9
----------
- Title: React Flow
- Context7-compatible library ID: /xyflow/xyflow
- Description: React Flow | Svelte Flow - Powerful open source libraries for building node-based UIs with React (https://reactflow.dev) or Svelte (https://svelteflow.dev). Ready out-of-the-box and infinitely customizable.
- Code Snippets: 21
- Trust Score: 9.5
----------
// ...以下省略更多内容
可以看到,在查询React相关的library时,API会返回多个相关的内容,包含Title、library ID、Description、Code Snippets、Trust Score。大模型可从返回的多个相关library中,找一个和用户提问最相关的,记录下library ID(在本Case中,大模型会记录/reactjs/react.dev),再继续调用下一个工具。
get-library-docs:根据library ID和用户查询的关键词,查询相关的代码片段
server.tool(
"get-library-docs",
"Fetches up-to-date documentation for a library. You must call 'resolve-library-id' first to obtain the exact Context7-compatible library ID required to use this tool.",
{
context7CompatibleLibraryID: z
.string()
.describe(
"Exact Context7-compatible library ID (e.g., 'mongodb/docs', 'vercel/nextjs') retrieved from 'resolve-library-id'."
),
topic: z
.string()
.optional()
.describe("Topic to focus documentation on (e.g., 'hooks', 'routing')."),
tokens: z
.preprocess((val) => (typeof val === "string" ? Number(val) : val), z.number())
.transform((val) => (val < DEFAULT_MINIMUM_TOKENS ? DEFAULT_MINIMUM_TOKENS : val))
.optional()
.describe(
`Maximum number of tokens of documentation to retrieve (default: ${DEFAULT_MINIMUM_TOKENS}). Higher values provide more context but consume more tokens.`
),
},
async ({ context7CompatibleLibraryID, tokens = DEFAULT_MINIMUM_TOKENS, topic = "" }) => {
// Extract folders parameter if present in the ID
let folders = "";
let libraryId = context7CompatibleLibraryID;
if (context7CompatibleLibraryID.includes("?folders=")) {
const [id, foldersParam] = context7CompatibleLibraryID.split("?folders=");
libraryId = id;
folders = foldersParam;
}
// 根据topic,查询相关代码片段
const documentationText = await fetchLibraryDocumentation(libraryId, {
tokens,
topic,
folders,
});
if (!documentationText) {
return {
content: [
{
type: "text",
text: "Documentation not found or not finalized for this library. This might have happened because you used an invalid Context7-compatible library ID. To get a valid Context7-compatible library ID, use the 'resolve-library-id' with the package name you wish to retrieve documentation for.",
},
],
};
}
return {
content: [
{
type: "text",
text: documentationText,
},
],
};
}
);
实际大模型调用的输入输出如下:
// 输入
{
`topic`: `useOptimistic`,
`tokens`: 4000,
`context7CompatibleLibraryID`: `/reactjs/react.dev`
}
// 响应
TITLE: Initializing useOptimistic Hook in Component - JavaScript
DESCRIPTION: Imports the `useOptimistic` hook and demonstrates its basic usage within a functional React component (`AppContainer`), showing how to define the `updateFn` to merge the current state with an optimistic value. Requires importing `useOptimistic` from 'react'.
SOURCE: https: // github.com / reactjs / react.dev / blob / main / src / content / reference / react / useOptimistic.md#_snippet_1
LANGUAGE: js
CODE:
```
import { useOptimistic } from 'react';
function AppContainer() {
const [optimisticState, addOptimistic] = useOptimistic(
state,
// updateFn
(currentState, optimisticValue) => {
// merge and return new state
// with optimistic value
}
);
}
```
----------------------------------------
TITLE: Implementing Optimistic Form Updates with useOptimistic - React/JavaScript
DESCRIPTION: Demonstrates a full implementation of optimistic UI updates using `useOptimistic` for sending messages via a form. It shows how to update the UI immediately upon submission (`addOptimisticMessage`), reset the form, perform the asynchronous action (`sendMessageAction`) using `startTransition`, and manage the state with `useState`. Requires `react`, `useOptimistic`, `useState`, `useRef`, `startTransition`, and a message delivery action.
SOURCE: https: // github.com / reactjs / react.dev / blob / main / src / content / reference / react / useOptimistic.md#_snippet_2
LANGUAGE: js
CODE:
```
import { useOptimistic, useState, useRef, startTransition } from "react";
import { deliverMessage } from "./actions.js";
function Thread({ messages, sendMessageAction }) {
const formRef = useRef();
function formAction(formData) {
addOptimisticMessage(formData.get("message"));
formRef.current.reset();
startTransition(async () => {
await sendMessageAction(formData);
});
}
const [optimisticMessages, addOptimisticMessage] = useOptimistic(
messages,
(state, newMessage) => [
{
text: newMessage,
sending: true
},
...state,
]
);
return (
<>
<form action={formAction} ref={formRef}>
<input type="text" name="message" placeholder="Hello!" />
<button type="submit">Send</button>
</form>
{optimisticMessages.map((message, index) => (
<div key={index}>
{message.text}
{!!message.sending && <small> (Sending...)</small>}
</div>
))}
</>
);
}
export default function App() {
const [messages, setMessages] = useState([
{ text: "Hello there!", sending: false, key: 1 }
]);
async function sendMessageAction(formData) {
const sentMessage = await deliverMessage(formData.get("message"));
startTransition(() => {
setMessages((messages) => [{ text: sentMessage }, ...messages]);
})
}
return <Thread messages={messages} sendMessageAction={sendMessageAction} />;
}
```
实际Context7的Server端在/reactjs/react.dev文档中找到了和useOptimistic相关的代码片段,并标明TITLE、DESCRIPTION、SOURCE、LANGUAGE、CODE,大模型可根据文档返回的内容,来决定代码具体的使用方式。
小结:Context7 MCP中主要有两个方法
resolve-library-id:查找某个技术栈/框架对应的文档IDget-library-docs:根据文档ID和具体topic,查询相关的代码片段和说明
在调用MCP后,大模型有了更新更准确的文档说明,再返回给用户
文档如何切片
从Context7 MCP端的代码来看,其本质和web search功能差不多,强制让大模型在回答问题前,先查询一下最新的文档。为了让查询的效果更好,Context7的Server端维护了文档切片索引。
从context7.com/ 可以看到,其官方维护了10000+个library的文档切片,大家也可以手动添加贡献github仓库,官方会从仓库中提取.md等相关说明文件,解析其中的代码片段,构建索引,方便后续的查询。
我们手动查一下刚刚使用的useOptimistic试试
可以看到每个代码片段会对应有来源(也就是library官方仓库里的md文件)。并为每一个代码片段加上对应的描述。
在实际使用时,Server还会给每个代码片段添加Trust Score,来标识此代码的置信度。虽然官方没说这个值是怎么算出来的,推测有可能和代码相关度、仓库活跃度、文档完整性等多个方面加权得到。(即使后面这个值的算法有修改,大家也不用重新安装MCP)
由此可见,Context7查询准确的前提是:对应的 Github 仓库里得有 md 说明文档,如果一个框架只有代码实现,但没有使用文档,那Context7也无能为力了。
总结
Context7 通过文件类型过滤和切片机制,将 GitHub 上的文档转换为代码片段集合。其切片机制综合考虑了文件大小、文档结构和代码块分布,在保持语义完整性的同时,实现了高效的内容分块和索引。
Context7 MCP强制大模型在回答问题前,先查找相关主题最新的代码片段,并填充到上下文,综合用户问题,提供更准确、更新的代码辅助体验。
参考文档