@upstash/context7-mcp 4.0.0 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -5
- package/dist/index.js +10 -7
- package/dist/lib/api.js +9 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# Context7 MCP - Up-to-date Code Docs For Any Prompt
|
|
6
6
|
|
|
7
|
-
[](https://context7.com) [](https://context7.com) [](https://www.npmjs.com/package/@upstash/context7-mcp) [](./LICENSE)
|
|
8
8
|
|
|
9
9
|
[](./i18n/README.zh-TW.md) [](./i18n/README.zh-CN.md) [](./i18n/README.ja.md) [](./i18n/README.ko.md) [](./i18n/README.es.md) [](./i18n/README.fr.md) [-purple>)](./i18n/README.pt-BR.md) [](./i18n/README.it.md) [](./i18n/README.id-ID.md) [](./i18n/README.de.md) [](./i18n/README.ru.md) [](./i18n/README.uk.md) [](./i18n/README.tr.md) [](./i18n/README.ar.md) [](./i18n/README.vi.md)
|
|
10
10
|
|
|
@@ -1621,10 +1621,6 @@ Stay updated and join our community:
|
|
|
1621
1621
|
- [AICodeKing: "Context7 + Cline & RooCode: This MCP Server Makes CLINE 100X MORE EFFECTIVE!"](https://www.youtube.com/watch?v=qZfENAPMnyo)
|
|
1622
1622
|
- [Sean Kochel: "5 MCP Servers For Vibe Coding Glory (Just Plug-In & Go)"](https://www.youtube.com/watch?v=LqTQi8qexJM)
|
|
1623
1623
|
|
|
1624
|
-
## ⭐ Star History
|
|
1625
|
-
|
|
1626
|
-
[](https://www.star-history.com/#upstash/context7&Date)
|
|
1627
|
-
|
|
1628
1624
|
## 📄 License
|
|
1629
1625
|
|
|
1630
1626
|
MIT
|
package/dist/index.js
CHANGED
|
@@ -282,14 +282,17 @@ async function main() {
|
|
|
282
282
|
// no session store. The handler serves modern (2026-07-28) traffic natively
|
|
283
283
|
// and 2025-era traffic through its stateless legacy fallback, which answers
|
|
284
284
|
// GET/DELETE (session operations) with 405.
|
|
285
|
-
//
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
//
|
|
289
|
-
//
|
|
290
|
-
//
|
|
285
|
+
// keepAliveMs: 0 disables SSE keepalive heartbeats. Every tool here is a
|
|
286
|
+
// millisecond vector query (p100 ~28s), so no legitimate exchange needs a
|
|
287
|
+
// heartbeat to stay alive — but a hung exchange kept "alive" by heartbeats
|
|
288
|
+
// can never be reaped by the gateway's stream idle timeout. A batch
|
|
289
|
+
// carrying a request plus its own notifications/cancelled produces exactly
|
|
290
|
+
// that: per spec the cancelled request gets no response, the SDK transport
|
|
291
|
+
// then never closes the stream, and with heartbeats it survived until the
|
|
292
|
+
// gateway's 1200s hard cap (the 2026-08-11 outage). Silent hangs instead
|
|
293
|
+
// go idle and the gateway reaps them at streamIdleTimeout (300s).
|
|
291
294
|
const mcpHandler = createMcpHandler(() => createMcpServer(), {
|
|
292
|
-
|
|
295
|
+
keepAliveMs: 0,
|
|
293
296
|
onerror: (error) => console.error("MCP handler error:", error),
|
|
294
297
|
});
|
|
295
298
|
// Without onerror, request-conversion / handler.fetch throws are answered
|
package/dist/lib/api.js
CHANGED
|
@@ -3,6 +3,13 @@ import { Agent, ProxyAgent, setGlobalDispatcher } from "undici";
|
|
|
3
3
|
import { CONTEXT7_API_BASE_URL } from "./constants.js";
|
|
4
4
|
import { readFileSync } from "fs";
|
|
5
5
|
import tls from "tls";
|
|
6
|
+
/**
|
|
7
|
+
* Ceiling on a single Context7 API call. Without a signal a stalled backend
|
|
8
|
+
* call rides undici's ~300s default before failing. 60s is generous for these
|
|
9
|
+
* vector queries: p99.9 is ~3.2s, and no request exceeded 30s across a full
|
|
10
|
+
* day of production traffic.
|
|
11
|
+
*/
|
|
12
|
+
const API_TIMEOUT_MS = 60_000;
|
|
6
13
|
/**
|
|
7
14
|
* Parses error response from the Context7 API
|
|
8
15
|
* Extracts the server's error message, falling back to status-based messages if parsing fails
|
|
@@ -99,7 +106,7 @@ export async function searchLibraries(query, libraryName, context = {}) {
|
|
|
99
106
|
url.searchParams.set("query", query);
|
|
100
107
|
url.searchParams.set("libraryName", libraryName);
|
|
101
108
|
const headers = generateHeaders(context);
|
|
102
|
-
const response = await fetch(url, { headers });
|
|
109
|
+
const response = await fetch(url, { headers, signal: AbortSignal.timeout(API_TIMEOUT_MS) });
|
|
103
110
|
readPromptSignal(response, context);
|
|
104
111
|
if (!response.ok) {
|
|
105
112
|
const errorMessage = await parseErrorResponse(response, context.apiKey);
|
|
@@ -127,7 +134,7 @@ export async function fetchLibraryContext(request, context = {}) {
|
|
|
127
134
|
url.searchParams.set("query", request.query);
|
|
128
135
|
url.searchParams.set("libraryId", request.libraryId);
|
|
129
136
|
const headers = generateHeaders(context);
|
|
130
|
-
const response = await fetch(url, { headers });
|
|
137
|
+
const response = await fetch(url, { headers, signal: AbortSignal.timeout(API_TIMEOUT_MS) });
|
|
131
138
|
readPromptSignal(response, context);
|
|
132
139
|
if (!response.ok) {
|
|
133
140
|
const errorMessage = await parseErrorResponse(response, context.apiKey);
|