I asked the Context7 MCP server for a Next.js middleware that checks a JWT cookie and redirects to /login. Three seconds later it handed back clean code from the official Next.js docs, built around a function called proxy. Every snippet came from the canary branch, where Next.js 16 renamed middleware to proxy. A Next.js 15 project expects middleware instead, so the agent would have written the wrong convention with the authority of official documentation.
That isn't a reason to skip Context7. It's the most useful thing I learned setting it up, and none of the five top-ranking pages for it mention it.
The short answer: Context7 is Upstash's hosted index of library documentation, served to your agent through an MCP server with two tools, resolve-library-id and query-docs. Add it to Claude Code with claude mcp add context7 -- npx -y @upstash/context7-mcp, or point any MCP client at https://mcp.context7.com/mcp. It works without an API key; a free key gives you 1,000 calls a month. In my run the tool schemas cost 1,058 tokens and one lookup returned about 2,400 tokens of docs. Put the version in the library ID, because an unpinned ID answers for the newest release.
What is Context7, and what does its MCP server return?
Context7 is a documentation service, not a model or a search engine. Upstash parses library docs into titled code and prose snippets, and the MCP server lets your agent look them up by library and question. The server is MIT-licensed and had 62,600 GitHub stars on October 2, 2026. The parts that do the work, the API backend, the parser and the crawler, are private, as the Context7 README states in its disclaimer.
I measured it on October 2, 2026: @upstash/context7-mcp 4.1.1 on macOS with Node 22, no API key. A short Python script spoke JSON-RPC over stdio (initialize, tools/list, then three real tool calls). Tokens are counted with o200k_base, the same method as our Playwright MCP vs CLI measurement. Claude's tokenizer gives different absolute numbers.
| Step | What came back | Tokens | Time |
|---|---|---|---|
tools/list | resolve-library-id (646) and query-docs (410) | 1,058 | — |
Server instructions (sent at initialize) | Use for library, API and CLI questions; not for refactoring or review | 126 | — |
resolve-library-id for "Next.js" | 5 candidates; /vercel/next.js lists 16 version entries, newest v16.2.9 | 537 | 1.9 s |
query-docs on /vercel/next.js | 5 snippets, all from canary | 1,881 | 3.0 s |
query-docs on /vercel/next.js/v15.1.8 | 5 snippets: 4 from v15.1.8, 1 from canary | 2,482 | 3.2 s |
A full lookup costs about 2,400 tokens of context. That's resolve plus query, and it's a fair price for an API you would otherwise get from the model's memory. Two details make it cost more than the table suggests. The unpinned answer repeated one 302-token code block verbatim, so 16% of it was a duplicate. And both tool descriptions allow the model up to three calls of each tool per question, so a hard question can run six calls.
The 1,058 schema tokens matter less in Claude Code than elsewhere. Its MCP documentation says tool search is on by default: MCP tools are deferred and loaded when Claude looks for them. Clients that load every tool upfront send those 1,058 tokens with each request.
How to set up Context7 MCP in Claude Code
One command adds the local server; claude mcp list proves it connected. The local server needs Node.js 20 or newer, per the Context7 troubleshooting guide. The remote server needs nothing installed. I ran these with Claude Code 2.1.287 in a scratch home directory:
claude mcp add --scope user context7 -- npx -y @upstash/[email protected]
claude mcp listExpected output:
Added stdio MCP server context7 with command: npx -y @upstash/[email protected] to user config
...
context7: npx -y @upstash/[email protected] - ✔ ConnectedDrop @4.1.1 to track the latest release; I pinned it so the numbers above stay reproducible. --scope user makes the server available in every project; without it, Claude Code writes to local scope for the current project only.
Then add use context7 to a prompt, or put a one-line rule in CLAUDE.md telling the agent to use Context7 for library and API questions, which is what the Context7 README suggests so you don't have to ask every time.
To use an API key with the hosted server, the Context7 client guide gives this form:
claude mcp add --scope user --header "Authorization: Bearer YOUR_API_KEY" --transport http context7 https://mcp.context7.com/mcpThat writes the key into ~/.claude.json in plain text. In a shared project .mcp.json, Claude Code expands ${VAR} in headers, so you can write Bearer ${CONTEXT7_API_KEY} instead. Every teammate then needs the variable set.
When it's missing, Claude Code warns in claude mcp list and sends the unexpanded text, and because an Authorization header is present it also skips its OAuth fallback, so the server answers 401. The official plugin hit the same wall with an empty header in issue #3167 (September 2026).
The Context7 Claude Code plugin is the no-key route. Run /plugin marketplace add upstash/context7 and then /plugin install context7@context7-marketplace. Restart, open /mcp, pick Context7 and sign in through the browser. The Context7 Claude Code page notes the plugin ignores CONTEXT7_API_KEY, so on SSH or CI hosts use the claude mcp add form instead.
To undo, which I also ran:
claude mcp remove context7 -s userIt printed Removed MCP server context7 from user config. If you used npx ctx7 setup --claude, run npx ctx7 remove --claude instead, since setup also writes a rule and a skill.
How to add Context7 to Codex
codex mcp add writes the server into ~/.codex/config.toml, which the Codex CLI, desktop app and IDE extension share, per the Context7 Codex page. I ran this with Codex CLI 0.160.0:
codex mcp add context7 -- npx -y @upstash/[email protected]It printed Added global MCP server 'context7'. and wrote:
[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/[email protected]"]To keep the key out of the file, use the hosted server and let Codex read the token from your environment:
codex mcp add context7 --url https://mcp.context7.com/mcp --bearer-token-env-var CONTEXT7_API_KEYThat writes bearer_token_env_var = "CONTEXT7_API_KEY", and codex mcp list then shows the server with Bearer token auth. For the local server, forward the variable and give npx time to download on first start. Codex's default startup timeout is 10 seconds, according to the Codex MCP docs. This block parsed cleanly in codex mcp get context7 --json:
[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/[email protected]"]
env_vars = ["CONTEXT7_API_KEY"]
startup_timeout_sec = 40The server reads CONTEXT7_API_KEY from its environment, and an --api-key flag wins if you pass both (Context7 developer guide). Context7's own Codex snippet uses startup_timeout_ms = 20_000; the current Codex docs name the setting startup_timeout_sec.
There's also a plugin with a documentation skill and browser sign-in: codex plugin marketplace add upstash/context7, then codex plugin add context7@context7-marketplace, then a new thread.
In Codex Cloud, add Context7 to the environment's tools and enable internet access for that environment, as the same page explains. To undo, codex mcp remove context7 printed Removed global MCP server 'context7'.
How to add Context7 to Cursor
Cursor reads ~/.cursor/mcp.json for every project and .cursor/mcp.json for one. I don't have Cursor installed, so this section is docs-only. The Cursor MCP docs resolve ${env:NAME} in the url and headers fields, which lets you reference the key instead of pasting it:
{
"mcpServers": {
"context7": {
"url": "https://mcp.context7.com/mcp",
"headers": { "Authorization": "Bearer ${env:CONTEXT7_API_KEY}" }
}
}
}Without a key, drop the headers line. You can also add it from Cursor Settings → Tools & MCP → New MCP Server, and Cursor needs a restart after config changes.
Cursor Cloud Agents ignore that file. They use servers added in the Cloud Agent UI. The Context7 Cursor page recommends a header named Context7-API-Key there, because Cursor's proxy can drop header names with underscores. When that happens, a valid key looks like no key and you get the anonymous quota error.
To undo, delete the context7 entry. If you used npx ctx7 setup --cursor, run npx ctx7 remove --cursor.
How to add Context7 to Octomind
Octomind is ours, and it takes Context7 as one TOML file. Octomind is an MCP client for stdio and Streamable HTTP servers. Files named mcp-*.toml in its config directory load after everything else, so a separate file keeps the server easy to remove. I validated this one with Octomind 0.55.2:
# ~/.local/share/octomind/config/mcp-context7.toml
[[mcp.servers]]
name = "context7"
type = "http"
url = "https://mcp.context7.com/mcp"
headers = { Authorization = "Bearer {{ENV:CONTEXT7_API_KEY}}" }
timeout_seconds = 30
tools = []
auto_bind = ["developer:general"]octomind config --validate returned Configuration is valid., and octomind config --show listed context7 HTTP: https://mcp.context7.com/mcp. auto_bind attaches the server to the developer:general role. Inside a session, /mcp list and /mcp health confirm it connected.
You may not need the file at all: Octomind's built-in tap ships Context7 as the devdocs capability, which switches on in developer-domain sessions when a message matches a docs-lookup trigger such as "find the docs for this library". It runs the server locally through npx; write your own entry when you want the hosted server, a version you chose, or a tool filter.
Mind one trap: if CONTEXT7_API_KEY is unset, a server whose header references it can't connect. For anonymous use, delete the headers line. Octomind then tries MCP authorization discovery and OAuth if the server asks for it (MCP tools reference). To undo, delete the file.
Do you need a Context7 API key?
Not to try it: my three calls worked with no key, no account and no cost. You need a key when the anonymous limit starts biting, when you want private repositories, or when a team needs shared policies. Context7 doesn't publish the anonymous quota. Its Search API docs call keyless requests "for testing only" and rate-limit them by IP address.
Prices from the Context7 plans page, checked October 2026:
| No key | Free (account + key) | Pro | |
|---|---|---|---|
| Price | $0 | $0 | $10 per seat per month |
| API calls | IP rate limit, number not public | 1,000 a month; then blocked, with 20 bonus calls a day | 2,000 per seat a month, then $5 per 1,000; never blocked |
| Private repos | No | No | Yes, parsing billed at $5 per 1M tokens |
Worked example. A lookup is two calls when the agent resolves the library first, and one when you hand it the ID. The free 1,000 calls cover about 500 two-call lookups a month, roughly 25 per working day. If the model uses its full allowance of three calls per tool, a question costs six calls and the same quota covers about 166 questions.
On Pro, one developer making 3,000 two-call lookups a month uses 6,000 calls: 4,000 over the seat's allowance, so $20 in overage plus the $10 seat, $30 for the month. Pro allowances are per seat and don't pool, so one heavy user is billed for overage even when teammates use nothing.
Keys look like ctx7sk-… and are shown once when you create them in the dashboard. npx ctx7 setup can create one for you through an OAuth device flow, which also works over SSH. Clients that implement MCP OAuth can skip keys entirely by pointing at https://mcp.context7.com/mcp/oauth; that endpoint works only for remote connections.
Pin the version, or Context7 answers for the newest release
The version lives in the library ID: /vercel/next.js means the default branch, and /vercel/next.js/v15.1.8 means that tag. Here's the same question asked both ways in my run:
/vercel/next.js → export default async function proxy(req: NextRequest) 5 of 5 snippets from canary
/vercel/next.js/v15.1.8 → export default async function middleware(req: NextRequest) 4 of 5 snippets from v15.1.8The unpinned answer is correct for Next.js 16, which deprecated the middleware file convention and renamed it to proxy. It's wrong for anything older. Pinning fixed four snippets out of five; the fifth still came from canary.
The decision rule: pin whenever your lockfile is behind the library's default branch. Three habits make that cheap:
- Read the
Source:line. In my results every snippet carried a link whose path names the branch or tag (blob/canary/…orblob/v15.1.8/…), so a stray is easy to spot. - Pick from the listed versions.
resolve-library-idreturns what Context7 has indexed. Next.js had 16 entries on October 2, 14 of them release tags, so choose the closest tag at or below your version. - Write the IDs down once. A line in
AGENTS.mdorCLAUDE.mdsuch asFor Next.js docs, use Context7 library ID /vercel/next.js/v15.1.8stops the agent from resolving on every question.
Pinned IDs also let you drop a tool. If your stack is fixed and the IDs are in your instructions, expose only query-docs: 410 schema tokens instead of 1,058. In Codex that's enabled_tools = ["query-docs"], which parsed in my run; in Octomind it's tools = ["query-docs"] on the server entry. For a broader take on when a tool belongs in a server and when a shell command will do, see MCP vs CLI vs Skills.
Context7 MCP errors and their fixes
Most failures are a slow local start or a request that reached Context7 without its key. These are the ones the issue tracker and client docs keep returning to:
| Symptom | Cause | Fix |
|---|---|---|
Claude Code: Failed to reconnect to context7, logs show a 30000 ms timeout | Local npx start too slow, or an old Node.js | Use Node.js 20+, remove and re-add the server, or switch to the hosted HTTP server (#552, troubleshooting) |
Codex on Windows: failed to start: program not found or request timed out | npx needs cmd (or the full npx.cmd path) and SystemRoot; startup defaults to 10 s | command = "cmd", args = ["/c", "npx", "-y", "@upstash/context7-mcp"], env = { SystemRoot="C:\\Windows" }, longer startup timeout (#575) |
Monthly quota exceeded. Create a free API key … | The request arrived anonymous: no key, or the client dropped the header | Send the key as Authorization: Bearer …; in Cursor Cloud use Context7-API-Key (#2145) |
Claude Code: AUTH_HEADER_REJECTED (HTTP 401) | An empty or unexpanded Authorization header switched off the OAuth fallback | Set the variable, or remove the header and sign in through /mcp (#3167) |
401 Unauthorized | Wrong or revoked key | Check that the key starts with ctx7sk (API guide) |
404 library not found | Malformed or guessed ID | Run resolve-library-id first; IDs look like /owner/repo or /owner/repo/version |
Some guides, including a few client entries on Context7's own setup page, send the key in a header named CONTEXT7_API_KEY. The README's form is Authorization: Bearer, and underscore header names are exactly what Cursor's cloud proxy drops. To check reachability before blaming your client, the troubleshooting guide suggests curl https://mcp.context7.com/ping, which should return {"status": "ok", "message": "pong"}.
When Context7 isn't enough, and what to use instead
Context7 covers public libraries well. It struggles with three things: private code, your own codebase, and libraries few people request.
Private and internal libraries. Private sources (GitHub, GitLab, Bitbucket, other Git hosts, Confluence, OpenAPI specs) need Pro or Enterprise, and only Owners and Admins can add them (private sources guide). Parsing is billed at $5 per million tokens (plans page), and private libraries are never refreshed automatically, so someone has to click refresh after each docs change (Keeping Libraries Fresh). Teams that can't send docs to a hosted service need Enterprise on-premise.
Your own codebase. Context7 indexes documentation, not your repository. For "where is this function called" or "how does our auth work", use code search: grep is enough on a small repo, and Octocode (also ours) adds semantic search, code signatures and a knowledge graph over MCP. Its graphrag tool builds a live tree-sitter graph without an index.
Freshness on less popular libraries. Context7 refreshes a library when someone requests it and its docs are older than a threshold: 1 day for the top 100 libraries, 15 days for the top 1,000, 30 for the top 5,000 and 45 for the rest (Keeping Libraries Fresh). The refresh runs in the background while that first request gets the old copy, so a niche library can answer from docs more than six weeks old. Logged-in users can trigger a manual refresh.
The alternatives, checked October 2, 2026, with tool schemas measured the same way as above (tools/list only, no tool calls):
| Option | Key needed | Price | Tools / schema tokens | Best for |
|---|---|---|---|---|
| Context7 MCP | No (key raises quota) | Free 1,000 calls/mo; Pro $10/seat | 2 / 1,058 | Popular libraries with version tags |
Context7 CLI + find-docs skill | No | Same quotas | 0 tools; skill 198 until used, 1,651 loaded | Agents that have a shell |
| GitMCP | No | Free, Apache-2.0, self-hostable | 5 / 612 generic, 4 / 475 per repo | One GitHub repo with a good llms.txt or README |
| DeepWiki MCP | No | Free for public repos | 3 / 367 | Questions about how a public repo is built |
| Ref | Yes | Free 200 one-time credits; Pro $50/mo, 6,000 credits | Not measured (needs a key) | Private repos and PDFs, trimmed page reads |
| Microsoft Learn MCP | No | Free | 3 / 972 | Azure, .NET and other Microsoft docs |
- Pick GitMCP when the library lives in one GitHub repo and you want no account at all. It serves
llms.txtfirst, then AI-optimized docs, then the README, and stores no queries. - Pick DeepWiki to understand an unfamiliar public codebase rather than look up an API. It's the cheapest schema here; private repos need a Devin account.
- Pick Ref for private docs and PDFs under one key. It's the only option here with no keyless tier.
- Pick a vendor's own docs server when one vendor is most of your stack. Microsoft Learn's endpoint also has an experimental
maxTokenBudgetparameter that caps search responses. - Pick the Context7 CLI and skill over the MCP server when your agent has a shell and docs lookups are occasional. The skill's description costs about 198 tokens until it's used.
Where Context7 falls short (honest version)
Treat the docs it returns as untrusted input. The README says libraries are community-contributed and Upstash can't guarantee their accuracy or security. Upstash runs a classifier for prompt injection and malware patterns over indexed content (data safety), which lowers the risk without removing it.
Your questions leave the machine. The model writes a query that goes to Context7, and the tool descriptions tell it to leave secrets out. Upstash says your prompt and code are never sent. The queries themselves go to OpenAI, Gemini or Anthropic models for reranking and are stored anonymously for benchmarking; only Enterprise can turn storage off (data privacy).
You can't self-host the free service. The MCP server is open source, but the index behind it isn't, so offline or air-gapped use means Enterprise on-premise.
Octomind isn't a ctx7 setup target. The setup tool's agent list covers nine clients, from Claude Code and Cursor to Codex and Gemini CLI, but not Octomind. Beyond the built-in capability, you write the TOML yourself, and a header that references an unset variable stops the server from connecting, so keyless and keyed setups need different files.
My measurement is narrow. One library, three calls, one tokenizer, one day. Treat the token numbers as the right order of magnitude for a framework like Next.js, not a constant.
Get Octomind — drop Context7 in as one TOML file and run it on any model.
FAQ
Is Context7 free?
Yes, for public libraries. Keyless use works but is rate-limited by IP address, and a free account with an API key gets 1,000 calls a month. Pro costs $10 per seat per month with 2,000 calls per seat, then $5 per 1,000 calls, and adds private repositories (prices checked October 2026).
Do I need a Context7 API key?
No, the Context7 MCP server answers without one. You need a key when you hit the anonymous quota ("Monthly quota exceeded"), want private repositories, or need team policies. Pass it as an Authorization: Bearer header to the hosted server, or as CONTEXT7_API_KEY to the local one.
Does Context7 send my code to Upstash?
According to Upstash's privacy docs, no. Only the search query your agent writes and the library name are sent. Those queries are reranked with third-party models and stored anonymously for benchmarking unless you're on Enterprise.
What's the difference between the Context7 plugin, the MCP server and the CLI skill?
The MCP server gives your agent two tools, resolve-library-id and query-docs. The Claude Code plugin connects to the hosted server with browser sign-in and no key; the Codex plugin does the same and adds a documentation skill. The CLI mode installs a find-docs skill that runs ctx7 commands in a shell, with no MCP server at all.
What are the best Context7 alternatives?
GitMCP and DeepWiki are free and keyless, good for single GitHub repositories and for understanding a codebase. Ref needs a key but handles private repos and PDFs. Vendor servers such as Microsoft Learn MCP cover one ecosystem's official docs. For your own code, use a code-search MCP such as Octocode rather than a docs index.



