# Context7 MCP: Setup for Claude Code, Codex and Cursor, and Where It Falls Short

> Context7 MCP setup for Claude Code, Codex, Cursor and Octomind, tested October 2026: measured token costs, what the API key changes, and where it falls short.

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](https://github.com/upstash/context7) 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](/blog/playwright-mcp-vs-cli). 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](https://code.claude.com/docs/en/mcp) 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](https://context7.com/docs/resources/troubleshooting). The remote server needs nothing installed. I ran these with Claude Code 2.1.287 in a scratch home directory:

```bash
claude mcp add --scope user context7 -- npx -y @upstash/context7-mcp@4.1.1
claude mcp list
```

Expected output:

```text
Added stdio MCP server context7 with command: npx -y @upstash/context7-mcp@4.1.1 to user config
...
context7: npx -y @upstash/context7-mcp@4.1.1 - ✔ Connected
```

Drop `@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](https://github.com/upstash/context7) suggests so you don't have to ask every time.

**To use an API key with the hosted server**, the [Context7 client guide](https://context7.com/docs/resources/all-clients) gives this form:

```bash
claude mcp add --scope user --header "Authorization: Bearer YOUR_API_KEY" --transport http context7 https://mcp.context7.com/mcp
```

That 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](https://github.com/upstash/context7/issues/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](https://context7.com/docs/clients/claude-code) 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:

```bash
claude mcp remove context7 -s user
```

It 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](https://context7.com/docs/clients/codex).** I ran this with Codex CLI 0.160.0:

```bash
codex mcp add context7 -- npx -y @upstash/context7-mcp@4.1.1
```

It printed `Added global MCP server 'context7'.` and wrote:

```toml
[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp@4.1.1"]
```

**To keep the key out of the file**, use the hosted server and let Codex read the token from your environment:

```bash
codex mcp add context7 --url https://mcp.context7.com/mcp --bearer-token-env-var CONTEXT7_API_KEY
```

That 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](https://developers.openai.com/codex/mcp). This block parsed cleanly in `codex mcp get context7 --json`:

```toml
[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp@4.1.1"]
env_vars = ["CONTEXT7_API_KEY"]
startup_timeout_sec = 40
```

The server reads `CONTEXT7_API_KEY` from its environment, and an `--api-key` flag wins if you pass both ([Context7 developer guide](https://context7.com/docs/resources/developer)). 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](https://cursor.com/docs/context/mcp) resolve `${env:NAME}` in the `url` and `headers` fields, which lets you reference the key instead of pasting it:

```json
{
	"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](https://context7.com/docs/clients/cursor) 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:

```toml
# ~/.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](/docs/usage/07-mcp-tools)). 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](https://context7.com/docs/search-api) call keyless requests "for testing only" and rate-limit them by IP address.

Prices from the [Context7 plans page](https://context7.com/plans), 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:

```text
/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.8
```

The unpinned answer is correct for Next.js 16, which [deprecated the middleware file convention and renamed it to proxy](https://nextjs.org/docs/app/api-reference/file-conventions/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/…` or `blob/v15.1.8/…`), so a stray is easy to spot.
- **Pick from the listed versions.** `resolve-library-id` returns 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.md` or `CLAUDE.md` such as `For Next.js docs, use Context7 library ID /vercel/next.js/v15.1.8` stops 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](/blog/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](https://github.com/upstash/context7/issues/552), [troubleshooting](https://context7.com/docs/resources/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](https://github.com/upstash/context7/issues/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](https://github.com/upstash/context7/issues/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](https://github.com/upstash/context7/issues/3167))                                                                                        |
| `401 Unauthorized`                                                            | Wrong or revoked key                                                                      | Check that the key starts with `ctx7sk` ([API guide](https://context7.com/docs/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](https://context7.com/docs/howto/private-sources)). Parsing is billed at $5 per million tokens ([plans page](https://context7.com/plans)), and private libraries are never refreshed automatically, so someone has to click refresh after each docs change ([Keeping Libraries Fresh](https://context7.com/docs/library-updates)). 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](/blog/octocode-mcp-setup-claude-cursor) (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](https://context7.com/docs/library-updates)). 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](https://github.com/idosal/git-mcp)                        | 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](https://docs.devin.ai/work-with-devin/deepwiki-mcp) | No                    | Free for public repos                                | 3 / 367                                     | Questions about how a public repo is built       |
| [Ref](https://docs.ref.tools/usage/pricing)                        | 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](https://github.com/MicrosoftDocs/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.txt` first, 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 `maxTokenBudget` parameter 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](https://context7.com/docs/security/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](https://context7.com/docs/security/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](https://octomind.run)** — 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.
