fix(mcp): honor advertised X-Context7-API-Key header (#3091)

* fix(mcp): honor advertised API key header (CTX7-2534)

* chore: add changeset for MCP API key header
This commit is contained in:
Fahreddin Özcan
2026-08-27 12:43:23 +03:00
committed by GitHub
parent 0ff958c9f0
commit 8fa6c6b9d2
3 changed files with 32 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@upstash/context7-mcp": patch
---
Honor the advertised `X-Context7-API-Key` header in HTTP MCP requests.
+1
View File
@@ -355,6 +355,7 @@ async function main() {
const extractApiKey = (req: express.Request): string | undefined => {
return (
extractBearerToken(req.headers.authorization) ||
extractHeaderValue(req.headers["x-context7-api-key"]) ||
extractHeaderValue(req.headers["context7-api-key"]) ||
extractHeaderValue(req.headers["x-api-key"]) ||
extractHeaderValue(req.headers["context7_api_key"]) ||
+26
View File
@@ -135,6 +135,32 @@ describe("OAuth discovery", () => {
});
});
describe("HTTP API key headers", () => {
test("accepts the advertised X-Context7-API-Key header", async () => {
const apiKey = "ctx7sk-advertised-header-test";
const client = new Client({ name: "api-key-header-test", version: "1.0.0" });
await client.connect(
new StreamableHTTPClientTransport(new URL(httpUrl), {
requestInit: { headers: { "X-Context7-API-Key": apiKey } },
})
);
try {
requests.length = 0;
await client.callTool({
name: "query-docs",
arguments: { libraryId: "/vercel/next.js", query: "app router" },
});
const apiCall = requests.find((request) => request.path === "/v2/context");
expect(apiCall?.headers.authorization).toBe(`Bearer ${apiKey}`);
} finally {
await client.close();
}
});
});
describe.each([
["http", "modern"],
["http", "legacy"],