@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 CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # Context7 MCP - Up-to-date Code Docs For Any Prompt
6
6
 
7
- [![Website](https://img.shields.io/badge/Website-context7.com-blue)](https://context7.com) [![smithery badge](https://smithery.ai/badge/@upstash/context7-mcp)](https://smithery.ai/server/@upstash/context7-mcp) [![NPM Version](https://img.shields.io/npm/v/%40upstash%2Fcontext7-mcp?color=red)](https://www.npmjs.com/package/@upstash/context7-mcp) [![MIT licensed](https://img.shields.io/npm/l/%40upstash%2Fcontext7-mcp)](./LICENSE)
7
+ [![Website](https://img.shields.io/badge/Website-context7.com-blue)](https://context7.com) [![NPM Version](https://img.shields.io/npm/v/%40upstash%2Fcontext7-mcp?color=red)](https://www.npmjs.com/package/@upstash/context7-mcp) [![MIT licensed](https://img.shields.io/npm/l/%40upstash%2Fcontext7-mcp)](./LICENSE)
8
8
 
9
9
  [![繁體中文](https://img.shields.io/badge/docs-繁體中文-yellow)](./i18n/README.zh-TW.md) [![简体中文](https://img.shields.io/badge/docs-简体中文-yellow)](./i18n/README.zh-CN.md) [![日本語](https://img.shields.io/badge/docs-日本語-b7003a)](./i18n/README.ja.md) [![한국어 문서](https://img.shields.io/badge/docs-한국어-green)](./i18n/README.ko.md) [![Documentación en Español](https://img.shields.io/badge/docs-Español-orange)](./i18n/README.es.md) [![Documentation en Français](https://img.shields.io/badge/docs-Français-blue)](./i18n/README.fr.md) [![Documentação em Português (Brasil)](<https://img.shields.io/badge/docs-Português%20(Brasil)-purple>)](./i18n/README.pt-BR.md) [![Documentazione in italiano](https://img.shields.io/badge/docs-Italian-red)](./i18n/README.it.md) [![Dokumentasi Bahasa Indonesia](https://img.shields.io/badge/docs-Bahasa%20Indonesia-pink)](./i18n/README.id-ID.md) [![Dokumentation auf Deutsch](https://img.shields.io/badge/docs-Deutsch-darkgreen)](./i18n/README.de.md) [![Документация на русском языке](https://img.shields.io/badge/docs-Русский-darkblue)](./i18n/README.ru.md) [![Українська документація](https://img.shields.io/badge/docs-Українська-lightblue)](./i18n/README.uk.md) [![Türkçe Doküman](https://img.shields.io/badge/docs-Türkçe-blue)](./i18n/README.tr.md) [![Arabic Documentation](https://img.shields.io/badge/docs-Arabic-white)](./i18n/README.ar.md) [![Tiếng Việt](https://img.shields.io/badge/docs-Tiếng%20Việt-red)](./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
- [![Star History Chart](https://api.star-history.com/svg?repos=upstash/context7&type=Date)](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
- // responseMode "sse" keeps responses streaming: headers flush immediately
287
- // after parsing the request rather than buffering until the tool returns.
288
- // This is required for long-running tools because some MCP HTTP clients cap
289
- // the underlying fetch at 60s waiting for headers, even though the per-tool
290
- // timeout is much higher.
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
- responseMode: "sse",
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upstash/context7-mcp",
3
- "version": "4.0.0",
3
+ "version": "4.0.2",
4
4
  "mcpName": "io.github.upstash/context7",
5
5
  "description": "MCP server for Context7",
6
6
  "repository": {