@upstash/context7-mcp 2.2.1 → 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 +54 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -160,6 +160,9 @@ IMPORTANT: Do not call this tool more than 3 times per question. If you cannot f
|
|
|
160
160
|
},
|
|
161
161
|
annotations: {
|
|
162
162
|
readOnlyHint: true,
|
|
163
|
+
destructiveHint: false,
|
|
164
|
+
openWorldHint: true,
|
|
165
|
+
idempotentHint: true,
|
|
163
166
|
},
|
|
164
167
|
}, async ({ query, libraryName }) => {
|
|
165
168
|
const searchResponse = await searchLibraries(query, libraryName, getClientContext());
|
|
@@ -194,7 +197,7 @@ server.registerTool("query-docs", {
|
|
|
194
197
|
|
|
195
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.
|
|
196
199
|
|
|
197
|
-
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
|
|
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.`,
|
|
198
201
|
inputSchema: {
|
|
199
202
|
libraryId: z
|
|
200
203
|
.string()
|
|
@@ -205,21 +208,54 @@ Workflow: call first without researchMode. If that doesn't answer the question,
|
|
|
205
208
|
researchMode: z
|
|
206
209
|
.boolean()
|
|
207
210
|
.optional()
|
|
208
|
-
.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
|
|
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.`),
|
|
209
212
|
},
|
|
210
213
|
annotations: {
|
|
211
214
|
readOnlyHint: true,
|
|
215
|
+
destructiveHint: false,
|
|
216
|
+
openWorldHint: true,
|
|
217
|
+
idempotentHint: true,
|
|
212
218
|
},
|
|
213
|
-
}, async ({ query, libraryId, researchMode }) => {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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
|
+
}
|
|
223
259
|
});
|
|
224
260
|
async function main() {
|
|
225
261
|
const transportType = TRANSPORT_TYPE;
|
|
@@ -307,9 +343,14 @@ async function main() {
|
|
|
307
343
|
clientInfo: extractClientInfoFromUserAgent(req.headers["user-agent"]),
|
|
308
344
|
transport: "http",
|
|
309
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.
|
|
310
351
|
const transport = new StreamableHTTPServerTransport({
|
|
311
352
|
sessionIdGenerator: undefined,
|
|
312
|
-
enableJsonResponse:
|
|
353
|
+
enableJsonResponse: false,
|
|
313
354
|
});
|
|
314
355
|
res.on("close", () => {
|
|
315
356
|
transport.close();
|