#3167·context7

[Bug]: context7 Claude Code plugin always fails with HTTP 401 when CONTEXT7_API_KEY is not set

Author: LeXaMeNCreated Sep 9, 2026Updated Sep 17, 2026
Labelsbug

Summary

The official context7 plugin for Claude Code ships an .mcp.json that always sends an Authorization header, defaulting to an empty string when CONTEXT7_API_KEY is unset.

Because the header is present (even though empty), Claude Code considers the server "pre-authenticated" and disables its OAuth fallback. The empty header is then rejected by https://mcp.context7.com/mcp with HTTP 401, and the server can never connect.

Completing the browser OAuth flow does not help: the token is obtained and stored successfully, but it is never attached to the request because the static header takes precedence.

Environment

Item Value
Plugin context7@claude-plugins-official
Claude Code VS Code extension (native extension host)
OS Windows 10 Enterprise LTSC 2021 (19044)
Shell PowerShell 5.1
CONTEXT7_API_KEY not set (process, User and Machine scopes all empty)

Offending configuration

external_plugins/context7/.mcp.json:

{
  "mcpServers": {
    "context7": {
      "type": "http",
      "url": "https://mcp.context7.com/mcp?client=claude-code-plugin",
      "headers": {
        "Authorization": "${CONTEXT7_API_KEY:-}"
      }
    }
  }
}

When CONTEXT7_API_KEY is unset, the :- default expands to an empty string, so the client sends a literal Authorization: header with no value.

Steps to reproduce

  1. Make sure CONTEXT7_API_KEY is not defined in the environment.
  2. Install the plugin: /plugin install context7@claude-plugins-official.
  3. Restart Claude Code.
  4. Observe the MCP connection status.
  5. Run /mcp, select context7, and complete the browser authentication.
  6. Restart Claude Code again.

Expected behaviour

Per the plugin README and plugin.json description, the plugin should "work anonymously out of the box", with CONTEXT7_API_KEY only needed for higher rate limits. Failing that, the OAuth flow offered by /mcp should be able to authenticate the connection.

Actual behaviour

The server never connects. Startup reports:

plugin:context7:context7 (AUTH_HEADER_REJECTED): Server rejected the configured Authorization
header (HTTP 401). Check that the token is valid for this MCP endpoint — OAuth fallback is
disabled when headers.Authorization is set.
Error detail: {"jsonrpc":"2.0","error":{"code":-32001,"message":"Authentication required. Please
authenticate to use this MCP server."},"id":null}

The browser OAuth flow itself succeeds. The callback URL is hit and the page shows:

Connected
Authentication successful
You can close this tab and return to Claude Code.

The callback looks like http://localhost:<port>/callback?code=<redacted>&iss=https%3A%2F%2Fclerk.context7.com&state=<redacted>, so a Clerk-issued token is clearly obtained. Despite that, the next connection attempt fails with the same 401, because the static (empty) Authorization header is still what gets sent.

Root cause

Two issues combine:

  1. ${CONTEXT7_API_KEY:-} produces an empty-but-present header instead of omitting the header.
  2. Claude Code treats any configured headers.Authorization as an explicit opt-out of OAuth, so the stored OAuth token is never used.

Additionally, the endpoint no longer appears to allow anonymous access. It answers Authentication required rather than serving anonymous rate-limited traffic, which contradicts the plugin description.

Working workaround

Disable the plugin and register the same endpoint manually without any headers block, which lets Claude Code use its OAuth flow:

{
  "mcpServers": {
    "context7": {
      "type": "http",
      "url": "https://mcp.context7.com/mcp?client=claude-code"
    }
  }
}

After a restart and one /mcp authentication, both resolve-library-id and query-docs work normally.

Setting a real CONTEXT7_API_KEY from the dashboard before launching Claude Code is also expected to work, since the header is then non-empty.

Suggested fix

  • Ship the plugin .mcp.json without the Authorization header, so OAuth is used by default, and document CONTEXT7_API_KEY as an alternative for users who prefer a static key.
  • Or, if a header-based variant must stay, make it conditional so that no header is emitted when the environment variable is empty.
  • Update the README and plugin.json description if anonymous access is no longer supported by mcp.context7.com.