@upstash/context7-mcp 2.1.7 → 2.2.0
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 +27 -1
- package/dist/index.js +7 -3
- package/dist/lib/api.js +18 -5
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -720,9 +720,35 @@ See [JetBrains AI Assistant Documentation](https://www.jetbrains.com/help/ai-ass
|
|
|
720
720
|
|
|
721
721
|
See [Kiro Model Context Protocol Documentation](https://kiro.dev/docs/mcp/configuration/) for details.
|
|
722
722
|
|
|
723
|
+
[](https://kiro.dev/launch/mcp/add?name=context7&config=%7B%22url%22%3A%22https%3A%2F%2Fmcp.context7.com%2Fmcp%22%2C%22disabled%22%3Afalse%2C%22autoApprove%22%3A%5B%5D%7D)
|
|
724
|
+
|
|
723
725
|
1. Navigate `Kiro` > `MCP Servers`
|
|
724
726
|
2. Add a new MCP server by clicking the `+ Add` button.
|
|
725
|
-
3. Paste the
|
|
727
|
+
3. Paste one of the configurations below:
|
|
728
|
+
|
|
729
|
+
#### Kiro Remote Server Connection
|
|
730
|
+
|
|
731
|
+
```json
|
|
732
|
+
{
|
|
733
|
+
"mcpServers": {
|
|
734
|
+
"Context7": {
|
|
735
|
+
"url": "https://mcp.context7.com/mcp"
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
To use an API key in Kiro, add:
|
|
742
|
+
|
|
743
|
+
```json
|
|
744
|
+
"headers": {
|
|
745
|
+
"CONTEXT7_API_KEY": "YOUR_API_KEY"
|
|
746
|
+
}
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
You can create an API key at [context7.com/dashboard](https://context7.com/dashboard) for authenticated usage and higher rate limits.
|
|
750
|
+
|
|
751
|
+
#### Kiro Local Server Connection
|
|
726
752
|
|
|
727
753
|
```json
|
|
728
754
|
{
|
package/dist/index.js
CHANGED
|
@@ -194,7 +194,7 @@ server.registerTool("query-docs", {
|
|
|
194
194
|
|
|
195
195
|
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
196
|
|
|
197
|
-
|
|
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`,
|
|
198
198
|
inputSchema: {
|
|
199
199
|
libraryId: z
|
|
200
200
|
.string()
|
|
@@ -202,12 +202,16 @@ IMPORTANT: Do not call this tool more than 3 times per question. If you cannot f
|
|
|
202
202
|
query: z
|
|
203
203
|
.string()
|
|
204
204
|
.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."),
|
|
205
|
+
researchMode: z
|
|
206
|
+
.boolean()
|
|
207
|
+
.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 — you can get one free at https://context7.com.`),
|
|
205
209
|
},
|
|
206
210
|
annotations: {
|
|
207
211
|
readOnlyHint: true,
|
|
208
212
|
},
|
|
209
|
-
}, async ({ query, libraryId }) => {
|
|
210
|
-
const response = await fetchLibraryContext({ query, libraryId }, getClientContext());
|
|
213
|
+
}, async ({ query, libraryId, researchMode }) => {
|
|
214
|
+
const response = await fetchLibraryContext({ query, libraryId, researchMode }, getClientContext());
|
|
211
215
|
return {
|
|
212
216
|
content: [
|
|
213
217
|
{
|
package/dist/lib/api.js
CHANGED
|
@@ -2,6 +2,7 @@ import { generateHeaders } from "./encryption.js";
|
|
|
2
2
|
import { Agent, ProxyAgent, setGlobalDispatcher } from "undici";
|
|
3
3
|
import { CONTEXT7_API_BASE_URL } from "./constants.js";
|
|
4
4
|
import { readFileSync } from "fs";
|
|
5
|
+
import tls from "tls";
|
|
5
6
|
/**
|
|
6
7
|
* Parses error response from the Context7 API
|
|
7
8
|
* Extracts the server's error message, falling back to status-based messages if parsing fails
|
|
@@ -39,21 +40,31 @@ const PROXY_URL = process.env.HTTPS_PROXY ??
|
|
|
39
40
|
process.env.http_proxy ??
|
|
40
41
|
null;
|
|
41
42
|
const CUSTOM_CA_CERTS = process.env.NODE_EXTRA_CA_CERTS;
|
|
42
|
-
function
|
|
43
|
-
if (
|
|
43
|
+
export function getDefaultCACertificates() {
|
|
44
|
+
if (typeof tls.getCACertificates === "function") {
|
|
45
|
+
return tls.getCACertificates("default");
|
|
46
|
+
}
|
|
47
|
+
return [...tls.rootCertificates];
|
|
48
|
+
}
|
|
49
|
+
export function loadCustomCACerts(customCACertsPath = CUSTOM_CA_CERTS) {
|
|
50
|
+
if (!customCACertsPath)
|
|
44
51
|
return undefined;
|
|
45
52
|
try {
|
|
46
|
-
|
|
53
|
+
const customCa = readFileSync(customCACertsPath, "utf-8");
|
|
54
|
+
return [...getDefaultCACertificates(), customCa];
|
|
47
55
|
}
|
|
48
56
|
catch (error) {
|
|
49
|
-
console.error(`[Context7] Failed to load custom CA certificates from ${
|
|
57
|
+
console.error(`[Context7] Failed to load custom CA certificates from ${customCACertsPath}:`, error);
|
|
50
58
|
return undefined;
|
|
51
59
|
}
|
|
52
60
|
}
|
|
53
61
|
if (PROXY_URL && !PROXY_URL.startsWith("$") && /^(http|https):\/\//i.test(PROXY_URL)) {
|
|
54
62
|
try {
|
|
55
63
|
const ca = loadCustomCACerts();
|
|
56
|
-
setGlobalDispatcher(new ProxyAgent({
|
|
64
|
+
setGlobalDispatcher(new ProxyAgent({
|
|
65
|
+
uri: PROXY_URL,
|
|
66
|
+
...(ca ? { requestTls: { ca }, proxyTls: { ca } } : {}),
|
|
67
|
+
}));
|
|
57
68
|
}
|
|
58
69
|
catch (error) {
|
|
59
70
|
console.error(`[Context7] Failed to configure proxy agent for provided proxy URL: ${PROXY_URL}:`, error);
|
|
@@ -109,6 +120,8 @@ export async function fetchLibraryContext(request, context = {}) {
|
|
|
109
120
|
const url = new URL(`${CONTEXT7_API_BASE_URL}/v2/context`);
|
|
110
121
|
url.searchParams.set("query", request.query);
|
|
111
122
|
url.searchParams.set("libraryId", request.libraryId);
|
|
123
|
+
if (request.researchMode)
|
|
124
|
+
url.searchParams.set("researchMode", "true");
|
|
112
125
|
const headers = generateHeaders(context);
|
|
113
126
|
const response = await fetch(url, { headers });
|
|
114
127
|
if (!response.ok) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@upstash/context7-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"mcpName": "io.github.upstash/context7",
|
|
5
5
|
"description": "MCP server for Context7",
|
|
6
6
|
"repository": {
|
|
@@ -43,11 +43,12 @@
|
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "^25.0.3",
|
|
46
|
-
"typescript": "^5.8.2"
|
|
46
|
+
"typescript": "^5.8.2",
|
|
47
|
+
"vitest": "^4.0.13"
|
|
47
48
|
},
|
|
48
49
|
"scripts": {
|
|
49
50
|
"build": "tsc && chmod 755 dist/index.js",
|
|
50
|
-
"test": "
|
|
51
|
+
"test": "pnpm exec vitest run",
|
|
51
52
|
"typecheck": "tsc --noEmit",
|
|
52
53
|
"lint": "eslint .",
|
|
53
54
|
"lint:check": "eslint .",
|