@upstash/context7-mcp 1.0.31 → 1.0.32
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 -1
- package/dist/lib/api.js +29 -23
- package/dist/lib/utils.js +0 -17
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-

|
|
1
|
+

|
|
2
2
|
|
|
3
3
|
[](https://cursor.com/en/install-mcp?name=context7&config=eyJ1cmwiOiJodHRwczovL21jcC5jb250ZXh0Ny5jb20vbWNwIn0%3D) [<img alt="Install in VS Code (npx)" src="https://img.shields.io/badge/Install%20in%20VS%20Code-0098FF?style=for-the-badge&logo=visualstudiocode&logoColor=white">](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%7B%22name%22%3A%22context7%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40upstash%2Fcontext7-mcp%40latest%22%5D%7D)
|
|
4
4
|
|
package/dist/lib/api.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { generateHeaders } from "./encryption.js";
|
|
2
2
|
import { ProxyAgent, setGlobalDispatcher } from "undici";
|
|
3
3
|
import { DOCUMENTATION_MODES } from "./types.js";
|
|
4
|
-
import { maskApiKey } from "./utils.js";
|
|
5
4
|
const CONTEXT7_API_BASE_URL = "https://context7.com/api";
|
|
6
5
|
const DEFAULT_TYPE = "txt";
|
|
7
6
|
/**
|
|
@@ -23,27 +22,36 @@ function parseLibraryId(libraryId) {
|
|
|
23
22
|
};
|
|
24
23
|
}
|
|
25
24
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* @param
|
|
25
|
+
* Parses error response from the Context7 API
|
|
26
|
+
* Extracts the server's error message, falling back to status-based messages if parsing fails
|
|
27
|
+
* @param response The fetch Response object
|
|
28
|
+
* @param apiKey Optional API key (used for fallback messages)
|
|
29
29
|
* @returns Error message string
|
|
30
30
|
*/
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
31
|
+
async function parseErrorResponse(response, apiKey) {
|
|
32
|
+
try {
|
|
33
|
+
const json = (await response.json());
|
|
34
|
+
if (json.message) {
|
|
35
|
+
return json.message;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// JSON parsing failed, fall through to default
|
|
40
|
+
}
|
|
41
|
+
// Fallback for non-JSON responses
|
|
42
|
+
const status = response.status;
|
|
43
|
+
if (status === 429) {
|
|
44
|
+
return apiKey
|
|
45
|
+
? "Rate limited or quota exceeded. Upgrade your plan at https://context7.com/plans for higher limits."
|
|
46
|
+
: "Rate limited or quota exceeded. Create a free API key at https://context7.com/dashboard for higher limits.";
|
|
47
|
+
}
|
|
48
|
+
if (status === 404) {
|
|
49
|
+
return "The library you are trying to access does not exist. Please try with a different library ID.";
|
|
50
|
+
}
|
|
51
|
+
if (status === 401) {
|
|
52
|
+
return "Invalid API key. Please check your API key. API keys should start with 'ctx7sk' prefix.";
|
|
46
53
|
}
|
|
54
|
+
return `Request failed with status ${status}. Please try again later.`;
|
|
47
55
|
}
|
|
48
56
|
// Pick up proxy configuration in a variety of common env var names.
|
|
49
57
|
const PROXY_URL = process.env.HTTPS_PROXY ??
|
|
@@ -78,8 +86,7 @@ export async function searchLibraries(query, clientIp, apiKey) {
|
|
|
78
86
|
const headers = generateHeaders(clientIp, apiKey);
|
|
79
87
|
const response = await fetch(url, { headers });
|
|
80
88
|
if (!response.ok) {
|
|
81
|
-
const
|
|
82
|
-
const errorMessage = createErrorMessage(errorCode, apiKey);
|
|
89
|
+
const errorMessage = await parseErrorResponse(response, apiKey);
|
|
83
90
|
console.error(errorMessage);
|
|
84
91
|
return {
|
|
85
92
|
results: [],
|
|
@@ -123,8 +130,7 @@ export async function fetchLibraryDocumentation(libraryId, docMode, options = {}
|
|
|
123
130
|
const headers = generateHeaders(clientIp, apiKey, { "X-Context7-Source": "mcp-server" });
|
|
124
131
|
const response = await fetch(url, { headers });
|
|
125
132
|
if (!response.ok) {
|
|
126
|
-
const
|
|
127
|
-
const errorMessage = createErrorMessage(errorCode, apiKey);
|
|
133
|
+
const errorMessage = await parseErrorResponse(response, apiKey);
|
|
128
134
|
console.error(errorMessage);
|
|
129
135
|
return errorMessage;
|
|
130
136
|
}
|
package/dist/lib/utils.js
CHANGED
|
@@ -58,20 +58,3 @@ export function formatSearchResults(searchResponse) {
|
|
|
58
58
|
const formattedResults = searchResponse.results.map(formatSearchResult);
|
|
59
59
|
return formattedResults.join("\n----------\n");
|
|
60
60
|
}
|
|
61
|
-
/**
|
|
62
|
-
* Masks an API key by showing only the first 10 characters and last 4 characters.
|
|
63
|
-
* This prevents full API keys from being exposed in logs while maintaining some
|
|
64
|
-
* identifiability for debugging.
|
|
65
|
-
*
|
|
66
|
-
* @param apiKey The API key to mask
|
|
67
|
-
* @returns Masked API key string (e.g., "ctx7sk-abc...xyz1") or "[NO-API-KEY]" if no key provided
|
|
68
|
-
*/
|
|
69
|
-
export function maskApiKey(apiKey) {
|
|
70
|
-
if (apiKey.length <= 14) {
|
|
71
|
-
// If the key is too short to mask meaningfully, just show first part
|
|
72
|
-
return apiKey.substring(0, 7) + "...";
|
|
73
|
-
}
|
|
74
|
-
const firstPart = apiKey.substring(0, 10);
|
|
75
|
-
const lastPart = apiKey.substring(apiKey.length - 4);
|
|
76
|
-
return `${firstPart}...${lastPart}`;
|
|
77
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@upstash/context7-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.32",
|
|
4
4
|
"mcpName": "io.github.upstash/context7",
|
|
5
5
|
"description": "MCP server for Context7",
|
|
6
6
|
"repository": {
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsc && chmod 755 dist/index.js",
|
|
49
|
-
"test": "echo \"
|
|
49
|
+
"test": "echo \"No tests yet\"",
|
|
50
|
+
"typecheck": "tsc --noEmit",
|
|
50
51
|
"lint": "eslint .",
|
|
51
52
|
"lint:check": "eslint .",
|
|
52
53
|
"format": "prettier --write .",
|