KEEP IT HANDS-ON functional ~ tested 2026-07-04
// sandboxed in macOS (host) · aarch64 ·install log · why not fully functional: stdio transport fully verified: tools/list returned two well-annotated tools, resolve-library-id and query-docs both returned real source-cited documentation from the live backend, nonexistent-tool and invalid-library-id error paths returned clean structured responses, resources/list and prompts/list returned declared empty arrays, and the hallucinated-argument alias rewrite was confirmed by passing the wrong parameter names and still getting correct docs. The project test suite passes 12 of 12. What could not be verified: the streamable-http transport crashes on startup with a fatal error demanding Upstash Redis credentials (UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN) that the README never mentions, so self-hosted HTTP mode is non-functional without those undocumented env vars. The remote backend behavior under rate limits was not load-tested. ·functional log

Context7

by Upstash (abdush) · https://github.com/upstash/context7 · MIT · v3.2.2 · updated 2026-07-04

A focused two-tool MCP server with a clever hallucinated-arg repair layer, verified end-to-end against its live backend.

4 / 5
quality 4/5
documentation 4/5
setup 4/5
value 5/5
ecosystem fit 5/5
// bottom line

Context7 is the most-installed documentation MCP server in the ecosystem, and it earns that position. The stdio transport works end-to-end against the live backend, the two tools return real source-cited code, and a hidden alias-rewriting layer silently fixes the argument names LLMs hallucinate. The warts are real but narrow: self-hosted HTTP mode crashes on an undocumented Redis dependency, the registry manifest lags the published package by a major version, and the test suite covers everything except the two tools the server exists to provide.

install via one-command setup (Cursor, Claude Code, OpenCode)
$npx ctx7 setup
install via npm (stdio MCP server)
$npm install -g @upstash/context7-mcp
run via npx (no install)
$npx -y @upstash/context7-mcp

install if

  • Cursor, Claude Code, Cline, Roo Code, Windsurf, or VS Code users who write code against libraries that change fast. The two-tool flow delivers current, version-specific, source-cited snippets instead of the stale or hallucinated APIs in a model's training data, and the install is one command.
  • Teams whose agents keep producing code for the wrong package version. Context7's version pinning (mention the version in the prompt, or use the /org/project/version ID format) directly addresses version drift.
  • Anyone building a custom agent that needs a documentation retrieval tool. The Vercel AI SDK adapter (@upstash/context7-tools-ai-sdk) and the TypeScript SDK (@upstash/context7-sdk) let you call the same backend outside an MCP client.

What It Does

Context7 is an MCP server from Upstash that fetches up-to-date, version-specific documentation and code examples for programming libraries and frameworks, and drops them directly into an agent's context. It exposes exactly two tools: resolve-library-id (turns a library name like "Express" into a Context7-compatible ID like /expressjs/express) and query-docs (retrieves ranked, source-cited documentation for that ID). The server speaks both stdio and streamable-http, ships a CLI (ctx7), a TypeScript SDK, a Vercel AI SDK adapter, and a pi.dev extension, and is the backing service behind the "use context7" prompt convention popular in Cursor and Claude Code. The audience is any developer whose agent writes code against stale, hallucinated, or version-wrong library APIs.

The Good

Both tools return real, current, source-cited documentation from the live backend. Calling resolve-library-id with libraryName="Express" returned five ranked matches with Context7 IDs, snippet counts (815 for /expressjs/express), source-reputation labels (High), benchmark scores (78.22), and available versions (v5.1.0, 4_21_2, v5.2.0). Following up with query-docs on /expressjs/express for "how to set up authentication with JWT" returned five code blocks pulled from github.com/expressjs/express, each tagged with its exact source path (_autodocs/9-router.md, _autodocs/7-errors.md, express/examples/auth/index.js). The snippets matched the query and covered routing, authorization-header middleware, and role-based route protection.

A hidden alias-rewriting layer silently repairs the argument names that LLMs hallucinate. The source (src/index.ts, lines 305-357) installs a transport onmessage hook that rewrites common hallucinations to the canonical schema keys before Zod validation runs: libraryID becomes libraryId, question becomes query, and context7CompatibleLibraryID or libraryName become libraryId on query-docs calls. I verified this by calling query-docs with the deliberately wrong names libraryID (capital D) and question, and the server returned correct Express middleware documentation instead of a validation error. This is a robustness feature most MCP servers lack, and it directly addresses the failure mode where an LLM echoes phrasing from a tool description instead of the literal parameter name.

MCP spec compliance is thorough, not minimal. Both tools carry full annotations: readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, plus title fields and the newer execution.taskSupport: "forbidden". Resources and prompts are explicitly declared (returning empty arrays via registerCapabilities), so resources/list and prompts/list answer cleanly instead of throwing method-not-found. The stdio entry point rejects incompatible flag combinations on startup (--port with stdio, --api-key with http) with a clear message and a nonzero exit, rather than silently ignoring them.

Error handling is structured and helpful, not a stack trace. Calling a nonexistent tool returns {isError: true, content: [{type: text, text: "MCP error -32602: Tool does_not_exist not found"}]}. Querying an invalid library ID (/nonexistent/fake-lib-xyz) returns a plain-text guidance message: "Library "/nonexistent/fake-lib-xyz" not found. Please check the library ID or your access permissions." The HTTP layer returns spec-correct status codes: 405 on GET requests (with a code comment explaining SSE serves no purpose for this notification-free server), 404 on expired sessions, and RFC 9728 OAuth protected-resource metadata at /.well-known/oauth-protected-resource.

The adoption numbers are real, not vanity. The npm package @upstash/context7-mcp sees 546,432 downloads a week and 3,852,134 a month (npm registry API, week of 2026-06-26 to 2026-07-02). GitHub sits at 58,559 stars, updated the day of review. The README is translated into 15 languages. The npx ctx7 setup flow runs an OAuth handshake, mints an API key, and writes the appropriate client config in one command. The installed package is 26 KB of JavaScript plus a lib/ directory, with 272 transitive dependencies.

The Bad

Self-hosted HTTP mode crashes on startup because of an undocumented hard dependency on Upstash Redis. Running node dist/index.js --transport http --port 3077 (which is exactly what the npm start script does) exits immediately with Fatal error in main(): Error: Upstash Redis credentials are required. Set UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN. The session store (src/lib/sessionStore.ts via src/lib/redis.ts) requires Upstash Redis for HTTP session tracking, but neither the README nor the server.json environmentVariables block mentions these two env vars. The result is that the streamable-http transport is effectively not self-hostable by a third party: you either use the hosted endpoint (https://mcp.context7.com/mcp), or you use stdio. The stdio path, to be clear, works fine without Redis.

The MCP registry manifest (server.json) is stale by a full major version. The committed server.json declares top-level version: "2.0.0" and lists the npm package @upstash/context7-mcp at version: "2.0.2". The actual published npm latest is 3.2.2 (confirmed by npm view and by the running binary's --version). An MCP registry or mcpb consumer that reads this manifest would install 2.0.2, missing whatever landed between 2.0.2 and 3.2.2. This is the exact "stale server.json" defect that signals a metadata release process that has not been re-run since the 2.x line.

The test suite covers everything except the two tools the server exists to provide. vitest run reports 2 test files and 12 passing tests: 10 JWT-validation tests (test/jwt.test.ts) and 2 certificate tests (test/certificate.test.ts). There are zero tests for resolve-library-id, zero for query-docs, zero for the src/lib/api.ts client layer that talks to the Context7 backend, and zero for the alias-rewriting logic that is the server's strongest feature. The headline functionality is unverified by the project's own automation, even though it is what 3.85M monthly downloads depend on.

Release hygiene is weak for a package this large. git tag --list returns nothing, so there is nothing to pin to. SECURITY.md lists only version 1.0.x as supported despite the package being at 3.2.2. There is no CONTRIBUTING.md. The private monorepo root package.json is marked private: true and is not itself published, which is correct, but the absence of any tagged release for a 58K-star project means every npm install resolves a floating latest.

Smoke Test Results

Tested on macOS host (aarch64), Node v24.13.1, npm 11.8.0, pnpm via npx. The published npm package @upstash/context7-mcp@3.2.2 was installed into an isolated directory alongside the official MCP Inspector (@modelcontextprotocol/inspector). The repo source was shallow-cloned separately (36 MB) for the test suite. An isolated npm cache (/tmp/npm-cache-gearscope) was used to avoid the global-cache EACCES failure seen in prior reviews.

Run A. Fresh sandbox, no deps preinstalled

$ cd /tmp/context7-test && npm install @modelcontextprotocol/inspector @upstash/context7-mcp --no-audit --no-fund

added 272 packages in 9s

PASS (install + both bins present: context7-mcp, mcp-inspector)

$ node_modules/.bin/context7-mcp --version

3.2.2

PASS (published version matches source)

$ node_modules/.bin/mcp-inspector --cli --config mcp-config.json --server target --method tools/list

returns 2 tools (resolve-library-id, query-docs) with full schemas + annotations

PASS

Pass rate: 3 of 3. Clean install, correct version, the inspector connects and discovers the tool surface on the first try.

Run B. Sandbox with deps preinstalled

$ node_modules/.bin/mcp-inspector --cli --config mcp-config.json --server target --method tools/call \

--tool-name resolve-library-id --tool-arg query="how to set up authentication with JWT" --tool-arg libraryName="Express"

returns /expressjs/express, 815 snippets, Source Reputation: High, Benchmark Score: 78.22

PASS

$ node_modules/.bin/mcp-inspector --cli ... --method tools/call --tool-name query-docs \

--tool-arg libraryId="/expressjs/express" --tool-arg query="how to set up authentication with JWT"

returns 5 source-cited code blocks from github.com/expressjs/express

PASS

$ node_modules/.bin/mcp-inspector --cli ... --method resources/list

{ "resources": [] }

PASS

$ node_modules/.bin/mcp-inspector --cli ... --method prompts/list

{ "prompts": [] }

PASS

$ cd /tmp/context7-review/packages/mcp && ./node_modules/.bin/vitest run

Test Files 2 passed (2), Tests 12 passed (12)

PASS

Pass rate: 5 of 5. The badge number is 5 of 5. The tools return real documentation against the live backend, empty-but-declared resource and prompt surfaces answer cleanly, and the project test suite is green.

Run C. Functional verification (does it do what it claims?)

$ tools/call --tool-name does_not_exist

{ "content": [{"text": "MCP error -32602: Tool does_not_exist not found"}], "isError": true }

PASS (clean structured error, correct code)

$ tools/call --tool-name query-docs --tool-arg libraryId="/nonexistent/fake-lib-xyz" --tool-arg query="anything"

"Library "/nonexistent/fake-lib-xyz" not found. Please check the library ID or your access permissions."

PASS (graceful, actionable text)

$ tools/call --tool-name query-docs --tool-arg libraryID="/expressjs/express" --tool-arg question="middleware"

returns correct Express middleware docs (alias rewriter repaired libraryID->libraryId, question->query)

PASS (the hallucinated-arg repair layer works)

$ node dist/index.js --transport http --port 3077

Fatal error in main(): Error: Upstash Redis credentials are required. Set UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN.

FAIL (self-hosted HTTP mode cannot start; Redis env vars are undocumented)

Functional pass rate: 3 of 4. The core documentation-retrieval claim is verified, the error paths are verified, and the alias-repair feature is verified. The one failure is the self-hosted streamable-http transport, which is blocked by an undocumented Upstash Redis dependency.

What the runs tell you

The stdio transport is production-ready: install, discover, query, and error handling all work against the live backend with no API key required for basic use, and the alias-rewriting layer makes it tolerant of the argument-name mistakes LLM clients routinely make. The self-hosted HTTP transport does not work out of the box because of the undocumented Redis requirement, so anyone who needs the streamable-http transport should use the hosted https://mcp.context7.com/mcp endpoint rather than running their own. The project's own tests pass but do not cover the two documentation tools.

Setup Walkthrough

  1. Quickest path: run npx ctx7 setup in your project. It authenticates via OAuth, generates an API key, and writes the right config for Cursor, Claude Code, or OpenCode. Pass --cursor, --claude, or --opencode to target a specific client.
  2. For any MCP client that accepts a stdio command, add the server with command npx -y @upstash/context7-mcp (no args, no API key required for low-volume use). For higher rate limits, get a free key at context7.com/dashboard and pass it as --api-key or via the CONTEXT7_API_KEY env var.
  3. To add the always-on behavior, drop a rule in your agent config. Example for Cursor (Settings > Rules) or Claude Code (CLAUDE.md): "Always use Context7 when I need library/API documentation, code generation, setup or configuration steps without me having to explicitly ask."
  4. You can short-circuit the resolve step by naming a library ID directly in your prompt with slash syntax, for example "use library /supabase/supabase for API and docs", and you can pin a version by mentioning it ("How do I set up Next.js 14 middleware? use context7").
  5. Do not attempt to self-host the HTTP transport unless you also provision Upstash Redis and set UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN. The stdio transport has no such requirement.

Alternatives

  1. A web-search MCP server (Brave, Tavily, Exa) - returns raw web pages and blog posts rather than curated, source-cited library documentation. More flexible for general questions, worse for "give me the correct current API for this specific library version." Use web search for breadth, Context7 for authoritative library docs.
  2. The model's built-in training data - free and instant, but stale and frequently wrong for anything released or changed after the training cutoff. Context7's own server instructions tell the agent to prefer the tool "even when you think you know the answer."
  3. Inlining the official docs URL yourself - zero install and fully under your control, but you lose the version-matching, snippet-ranking, and reputation-scoring that Context7 applies server-side, and you do the retrieval work the tool automates.
// review provenance
reviewed by
GearScope
tested
2026-07-04 · macOS (Apple Silicon)
last verified
2026-07-04
depth
HANDS-ON
sponsorship
none, ever
// share this review
// feedback
was this review helpful?

Want the next one?

Five honest reviews and a verdict you can trust. Every Friday. No spam, no affiliate links.