* fix(cli): write the API key as an Authorization header
Codex resolves a server's auth mode by checking only for
`bearer_token_env_var` or a header literally named `Authorization`
(`auth_status_before_discovery` in codex-rs/rmcp-client/src/auth_status.rs,
mirrored in `create_transport` in rmcp_client.rs). The custom
`CONTEXT7_API_KEY` header matched neither, so Codex fell through to any OAuth
credential stored for the same server name and URL and refreshed it during
startup. A dead refresh token then failed the server with `invalid_grant`
before the API key was ever sent, and re-running setup could not recover it
because setup writes config.toml and never touches the credential store.
The hosted endpoint accepts both header forms, so existing configs keep
working.
Two places keep the legacy header deliberately: the plugin .mcp.json files
default to `${CONTEXT7_API_KEY:-}`, and the server rejects `Bearer` with an
empty token while treating a missing header as anonymous; and `env` blocks in
stdio configs, where the name is an environment variable rather than a header.
* fix(plugins): send the API key via the Authorization header
The Claude and Copilot plugin configs default to `${CONTEXT7_API_KEY:-}`, and
both plugins document that an unset key still works over the anonymous tier.
The Bearer form cannot express that: the server rejects `Bearer` with an empty
token while treating an empty or missing Authorization header as anonymous.
The raw-key form satisfies both states. It is genuinely parsed rather than
ignored, verified by an invalid raw key being rejected, so a set key still
authenticates while an unset one falls back to anonymous as documented.
Once the server treats an empty-token Bearer as no header, these can move to
the `Bearer <key>` form used everywhere else.
* refactor(cli): narrow the Codex OAuth probe and trim its surface
Only `oauth` proves a stored credential exists. `not_logged_in` also covers
"no credential, server merely advertises OAuth", which is the normal state for
anyone who never logged in, so treating it as stale told most users their
config held a credential it did not.
Collapse the module to the two functions the call site needs, derive nothing
from a hand-maintained status list, and skip the subprocess entirely when the
server is not already in Codex's config. Drop the probe timeout to 1.5s and
kill with SIGKILL so it is a real ceiling rather than an intent, since the
result is only an advisory hint.
Lock the plugin manifests' raw-key form behind a test, so normalizing them to
`Bearer` for consistency with the CLI fails loudly instead of silently
breaking anonymous access.
* refactor(cli): drop the Codex OAuth cleanup note
The note existed because re-running setup could not rescue a stuck user. The
Authorization header change in this same branch makes it rescue them: Codex
never reads the stored credential once that header is present, so the
credential is inert and the hint only offered cosmetic cleanup.
Removing it drops a subprocess spawn from a user-facing path and a dependency
on the shape of `codex mcp get --json`, an external contract this repo does not
pin. The reason the header name matters moves to `withHeaders`, where the
decision is encoded.
Context7 Plugin for Claude Code
Context7 solves a common problem with AI coding assistants: outdated training data and hallucinated APIs. Instead of relying on stale knowledge, Context7 fetches current documentation directly from source repositories.
What's Included
This plugin provides:
- MCP Server - Connects Claude Code to Context7's documentation service
- Skills - Auto-triggers documentation lookups when you ask about libraries
- Agents - A dedicated
docs-researcheragent for focused lookups - Commands -
/context7:docsfor manual documentation queries
Installation
Add the marketplace and install the plugin:
claude plugin marketplace add upstash/context7
claude plugin install context7@context7-marketplace
API Key (Recommended)
Without an API key, the plugin connects anonymously and shares the anonymous rate limits. To use your own plan, create an API key in the Context7 dashboard and export it as an environment variable before launching Claude Code:
# e.g. in ~/.zshrc or ~/.bashrc
export CONTEXT7_API_KEY="your-api-key"
The plugin's MCP server configuration picks up CONTEXT7_API_KEY automatically. Restart Claude Code after setting it, then verify the key is being used by checking your usage in the dashboard.
Available Tools
resolve-library-id
Searches for libraries and returns Context7-compatible identifiers.
Input: "next.js"
Output: { id: "/vercel/next.js", name: "Next.js", versions: ["v15.1.8", "v14.2.0", ...] }
query-docs
Fetches documentation for a specific library, ranked by relevance to your question.
Input: { libraryId: "/vercel/next.js", query: "app router middleware" }
Output: Relevant documentation snippets with code examples
Usage Examples
The plugin works automatically when you ask about libraries:
- "How do I set up authentication in Next.js 15?"
- "Show me React Server Components examples"
- "What's the Prisma syntax for relations?"
For manual lookups, use the command:
/context7:docs next.js app router
/context7:docs /vercel/next.js/v15.1.8 middleware
Or spawn the docs-researcher agent when you want to keep your main context clean:
spawn docs-researcher to look up Supabase auth methods
Version Pinning
To get documentation for a specific version, include the version in the library ID:
/vercel/next.js/v15.1.8
/supabase/supabase/v2.45.0
The resolve-library-id tool returns available versions, so you can pick the one that matches your project.