@upstash/context7-mcp 1.0.2 → 1.0.4

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
@@ -52,7 +52,7 @@ Paste this into your Cursor `~/.cursor/mcp.json` file. See [Cursor MCP docs](htt
52
52
  "mcpServers": {
53
53
  "context7": {
54
54
  "command": "npx",
55
- "args": ["-y", "@upstash/context7-mcp"]
55
+ "args": ["-y", "@upstash/context7-mcp@latest"]
56
56
  }
57
57
  }
58
58
  }
@@ -67,7 +67,23 @@ Add this to your Windsurf MCP config file. See [Windsurf MCP docs](https://docs.
67
67
  "mcpServers": {
68
68
  "context7": {
69
69
  "command": "npx",
70
- "args": ["-y", "@upstash/context7-mcp"]
70
+ "args": ["-y", "@upstash/context7-mcp@latest"]
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ ### Install in VSCode
77
+
78
+ Add this to your VSCode MCP config file. See [VSCode MCP docs](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) for more info.
79
+
80
+ ```json
81
+ {
82
+ "servers": {
83
+ "Context7": {
84
+ "type": "stdio",
85
+ "command": "npx",
86
+ "args": ["-y", "@upstash/context7-mcp@latest"]
71
87
  }
72
88
  }
73
89
  }
@@ -112,7 +128,7 @@ bun run build
112
128
  ### Testing with MCP Inspector
113
129
 
114
130
  ```bash
115
- npx -y @modelcontextprotocol/inspector npx @upstash/context7-mcp
131
+ npx -y @modelcontextprotocol/inspector npx @upstash/context7-mcp@latest
116
132
  ```
117
133
 
118
134
  ## License
package/dist/index.js ADDED
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ import { searchLibraries, fetchLibraryDocumentation } from "./lib/api.js";
6
+ import { formatSearchResults } from "./lib/utils.js";
7
+ const DEFAULT_MINIMUM_TOKENS = 5000;
8
+ // Create server instance
9
+ const server = new McpServer({
10
+ name: "Context7",
11
+ description: "Retrieves up-to-date documentation and code examples for any library.",
12
+ version: "1.0.4",
13
+ capabilities: {
14
+ resources: {},
15
+ tools: {},
16
+ },
17
+ });
18
+ // Register Context7 tools
19
+ server.tool("resolve-library-id", "Required first step: Resolves a general package name into a Context7-compatible library ID. Must be called before using 'get-library-docs' to retrieve a valid Context7-compatible library ID.", {
20
+ libraryName: z
21
+ .string()
22
+ .optional()
23
+ .describe("Optional library name to search for and rerank results based on."),
24
+ }, async ({ libraryName }) => {
25
+ const searchResponse = await searchLibraries(libraryName || "");
26
+ if (!searchResponse || !searchResponse.results) {
27
+ return {
28
+ content: [
29
+ {
30
+ type: "text",
31
+ text: "Failed to retrieve library documentation data from Context7",
32
+ },
33
+ ],
34
+ };
35
+ }
36
+ if (searchResponse.results.length === 0) {
37
+ return {
38
+ content: [
39
+ {
40
+ type: "text",
41
+ text: "No documentation libraries available",
42
+ },
43
+ ],
44
+ };
45
+ }
46
+ const resultsText = formatSearchResults(searchResponse);
47
+ return {
48
+ content: [
49
+ {
50
+ type: "text",
51
+ text: "Available libraries and their Context7-compatible library IDs:\n\n" + resultsText,
52
+ },
53
+ ],
54
+ };
55
+ });
56
+ server.tool("get-library-docs", "Fetches up-to-date documentation for a library. You must call 'resolve-library-id' first to obtain the exact Context7-compatible library ID required to use this tool.", {
57
+ context7CompatibleLibraryID: z
58
+ .string()
59
+ .describe("Exact Context7-compatible library ID (e.g., 'mongodb/docs', 'vercel/nextjs') retrieved from 'resolve-library-id'."),
60
+ topic: z
61
+ .string()
62
+ .optional()
63
+ .describe("Topic to focus documentation on (e.g., 'hooks', 'routing')."),
64
+ tokens: z
65
+ .number()
66
+ .min(DEFAULT_MINIMUM_TOKENS)
67
+ .optional()
68
+ .describe(`Maximum number of tokens of documentation to retrieve (default: ${DEFAULT_MINIMUM_TOKENS}). Higher values provide more context but consume more tokens.`),
69
+ }, async ({ context7CompatibleLibraryID, tokens = DEFAULT_MINIMUM_TOKENS, topic = "" }) => {
70
+ // Extract folders parameter if present in the ID
71
+ let folders = "";
72
+ let libraryId = context7CompatibleLibraryID;
73
+ if (context7CompatibleLibraryID.includes("?folders=")) {
74
+ const [id, foldersParam] = context7CompatibleLibraryID.split("?folders=");
75
+ libraryId = id;
76
+ folders = foldersParam;
77
+ }
78
+ const documentationText = await fetchLibraryDocumentation(libraryId, {
79
+ tokens,
80
+ topic,
81
+ folders,
82
+ });
83
+ if (!documentationText) {
84
+ return {
85
+ content: [
86
+ {
87
+ type: "text",
88
+ text: "Documentation not found or not finalized for this library. This might have happened because you used an invalid Context7-compatible library ID. To get a valid Context7-compatible library ID, use the 'resolve-library-id' with the package name you wish to retrieve documentation for.",
89
+ },
90
+ ],
91
+ };
92
+ }
93
+ return {
94
+ content: [
95
+ {
96
+ type: "text",
97
+ text: documentationText,
98
+ },
99
+ ],
100
+ };
101
+ });
102
+ async function main() {
103
+ const transport = new StdioServerTransport();
104
+ await server.connect(transport);
105
+ console.error("Context7 Documentation MCP Server running on stdio");
106
+ }
107
+ main().catch((error) => {
108
+ console.error("Fatal error in main():", error);
109
+ process.exit(1);
110
+ });
@@ -0,0 +1,62 @@
1
+ const CONTEXT7_API_BASE_URL = "https://context7.com/api";
2
+ const DEFAULT_TYPE = "txt";
3
+ /**
4
+ * Searches for libraries matching the given query
5
+ * @param query The search query
6
+ * @returns Search results or null if the request fails
7
+ */
8
+ export async function searchLibraries(query) {
9
+ try {
10
+ const url = new URL(`${CONTEXT7_API_BASE_URL}/v1/search`);
11
+ url.searchParams.set("query", query);
12
+ const response = await fetch(url);
13
+ if (!response.ok) {
14
+ console.error(`Failed to search libraries: ${response.status}`);
15
+ return null;
16
+ }
17
+ return await response.json();
18
+ }
19
+ catch (error) {
20
+ console.error("Error searching libraries:", error);
21
+ return null;
22
+ }
23
+ }
24
+ /**
25
+ * Fetches documentation context for a specific library
26
+ * @param libraryId The library ID to fetch documentation for
27
+ * @param options Options for the request
28
+ * @returns The documentation text or null if the request fails
29
+ */
30
+ export async function fetchLibraryDocumentation(libraryId, options = {}) {
31
+ try {
32
+ if (libraryId.startsWith("/")) {
33
+ libraryId = libraryId.slice(1);
34
+ }
35
+ const url = new URL(`${CONTEXT7_API_BASE_URL}/v1/${libraryId}`);
36
+ if (options.tokens)
37
+ url.searchParams.set("tokens", options.tokens.toString());
38
+ if (options.topic)
39
+ url.searchParams.set("topic", options.topic);
40
+ if (options.folders)
41
+ url.searchParams.set("folders", options.folders);
42
+ url.searchParams.set("type", DEFAULT_TYPE);
43
+ const response = await fetch(url, {
44
+ headers: {
45
+ "X-Context7-Source": "mcp-server",
46
+ },
47
+ });
48
+ if (!response.ok) {
49
+ console.error(`Failed to fetch documentation: ${response.status}`);
50
+ return null;
51
+ }
52
+ const text = await response.text();
53
+ if (!text || text === "No content available" || text === "No context data available") {
54
+ return null;
55
+ }
56
+ return text;
57
+ }
58
+ catch (error) {
59
+ console.error("Error fetching library documentation:", error);
60
+ return null;
61
+ }
62
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Format a search result into a string representation
3
+ * @param result SearchResult to format
4
+ * @returns Formatted search result string
5
+ */
6
+ export function formatSearchResult(result) {
7
+ return `Title: ${result.title}\n\nContext7-compatible library ID: ${result.id}`;
8
+ }
9
+ /**
10
+ * Format search results into a string representation
11
+ * @param searchResponse The search response to format
12
+ * @returns Formatted search results string
13
+ */
14
+ export function formatSearchResults(searchResponse) {
15
+ if (!searchResponse.results || searchResponse.results.length === 0) {
16
+ return "No documentation libraries found matching your query.";
17
+ }
18
+ const formattedResults = searchResponse.results.map(formatSearchResult);
19
+ return formattedResults.join("\n\n");
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upstash/context7-mcp",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "MCP server for Context7",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",