@upstash/context7-mcp 2.2.2 → 2.2.3
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/dist/index.js +51 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -197,7 +197,7 @@ server.registerTool("query-docs", {
|
|
|
197
197
|
|
|
198
198
|
You must call 'Resolve Context7 Library ID' tool first to obtain the exact Context7-compatible library ID required to use this tool, UNLESS the user explicitly provides a library ID in the format '/org/project' or '/org/project/version' in their query.
|
|
199
199
|
|
|
200
|
-
Do not call
|
|
200
|
+
Workflow: call first without researchMode. If that doesn't answer the question, retry with researchMode: true. Do not call each tool more than 3 times per question.`,
|
|
201
201
|
inputSchema: {
|
|
202
202
|
libraryId: z
|
|
203
203
|
.string()
|
|
@@ -205,6 +205,10 @@ Do not call this tool more than 3 times per question.`,
|
|
|
205
205
|
query: z
|
|
206
206
|
.string()
|
|
207
207
|
.describe("The question or task you need help with. Be specific and include relevant details. Good: 'How to set up authentication with JWT in Express.js' or 'React useEffect cleanup function examples'. Bad: 'auth' or 'hooks'. The query is sent to the Context7 API for processing. Do not include any sensitive or confidential information such as API keys, passwords, credentials, personal data, or proprietary code in your query."),
|
|
208
|
+
researchMode: z
|
|
209
|
+
.boolean()
|
|
210
|
+
.optional()
|
|
211
|
+
.describe(`Retry the query with deep research: spins up sandboxed agents that read the actual source repos and runs a live web search, then synthesizes a fresh answer. Set true on retry if you weren't satisfied with the first answer and want a more thorough one. Requires an API key. You can get one free at https://context7.com.`),
|
|
208
212
|
},
|
|
209
213
|
annotations: {
|
|
210
214
|
readOnlyHint: true,
|
|
@@ -212,16 +216,46 @@ Do not call this tool more than 3 times per question.`,
|
|
|
212
216
|
openWorldHint: true,
|
|
213
217
|
idempotentHint: true,
|
|
214
218
|
},
|
|
215
|
-
}, async ({ query, libraryId }) => {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
219
|
+
}, async ({ query, libraryId, researchMode }, { sendNotification, _meta }) => {
|
|
220
|
+
// Emit periodic progress notifications while the upstream call is in flight.
|
|
221
|
+
// MCP clients that opt into resetTimeoutOnProgress (e.g. opencode) reset their
|
|
222
|
+
// request timer on each notification, which keeps long-running tools (notably
|
|
223
|
+
// researchMode) alive past the SDK's default 60s wall-clock timeout. Clients
|
|
224
|
+
// that don't pass a progressToken simply never see these, so behavior is unchanged.
|
|
225
|
+
const progressToken = _meta?.progressToken;
|
|
226
|
+
let progressInterval;
|
|
227
|
+
if (researchMode && progressToken !== undefined) {
|
|
228
|
+
let progress = 0;
|
|
229
|
+
progressInterval = setInterval(() => {
|
|
230
|
+
progress += 1;
|
|
231
|
+
sendNotification({
|
|
232
|
+
method: "notifications/progress",
|
|
233
|
+
params: {
|
|
234
|
+
progressToken,
|
|
235
|
+
progress,
|
|
236
|
+
message: "Researching documentation...",
|
|
237
|
+
},
|
|
238
|
+
}).catch(() => {
|
|
239
|
+
// Notifications are best-effort; swallow transport errors so the tool
|
|
240
|
+
// call itself isn't aborted by a notification write failure.
|
|
241
|
+
});
|
|
242
|
+
}, 20_000);
|
|
243
|
+
}
|
|
244
|
+
try {
|
|
245
|
+
const response = await fetchLibraryContext({ query, libraryId, researchMode }, getClientContext());
|
|
246
|
+
return {
|
|
247
|
+
content: [
|
|
248
|
+
{
|
|
249
|
+
type: "text",
|
|
250
|
+
text: response.data,
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
finally {
|
|
256
|
+
if (progressInterval)
|
|
257
|
+
clearInterval(progressInterval);
|
|
258
|
+
}
|
|
225
259
|
});
|
|
226
260
|
async function main() {
|
|
227
261
|
const transportType = TRANSPORT_TYPE;
|
|
@@ -309,9 +343,14 @@ async function main() {
|
|
|
309
343
|
clientInfo: extractClientInfoFromUserAgent(req.headers["user-agent"]),
|
|
310
344
|
transport: "http",
|
|
311
345
|
};
|
|
346
|
+
// Use SSE responses for tool calls (enableJsonResponse: false). The SDK then
|
|
347
|
+
// flushes response headers immediately after parsing the request rather than
|
|
348
|
+
// buffering until the tool returns. This is required for long-running tools
|
|
349
|
+
// (e.g. researchMode) because some MCP HTTP clients cap the underlying fetch
|
|
350
|
+
// at 60s waiting for headers, even though the per-tool timeout is much higher.
|
|
312
351
|
const transport = new StreamableHTTPServerTransport({
|
|
313
352
|
sessionIdGenerator: undefined,
|
|
314
|
-
enableJsonResponse:
|
|
353
|
+
enableJsonResponse: false,
|
|
315
354
|
});
|
|
316
355
|
res.on("close", () => {
|
|
317
356
|
transport.close();
|