mirror of
https://github.com/upstash/context7.git
synced 2025-06-26 23:50:04 +00:00
feat: replace env vars with CLI arguments, remove dotenv and add commander
This commit is contained in:
parent
1042650638
commit
2e6c9a6c6b
@ -25,12 +25,8 @@ COPY package.json ./
|
|||||||
# Install only production dependencies
|
# Install only production dependencies
|
||||||
RUN npm install --production --ignore-scripts
|
RUN npm install --production --ignore-scripts
|
||||||
|
|
||||||
# Set default environment variables for HTTP mode
|
|
||||||
ENV MCP_TRANSPORT=http
|
|
||||||
ENV PORT=8080
|
|
||||||
|
|
||||||
# Expose HTTP port
|
# Expose HTTP port
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
# Default command
|
# Default command using CLI flags
|
||||||
CMD ["node", "dist/index.js"]
|
CMD ["node", "dist/index.js", "--transport", "http", "--port", "8080"]
|
||||||
|
43
README.md
43
README.md
@ -420,28 +420,6 @@ Add this to your Roo Code MCP configuration file. See [Roo Code MCP docs](https:
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## 🔧 Environment Variables
|
|
||||||
|
|
||||||
The Context7 MCP server supports the following environment variables:
|
|
||||||
|
|
||||||
- `DEFAULT_MINIMUM_TOKENS`: Set the minimum token count for documentation retrieval (default: 10000)
|
|
||||||
|
|
||||||
Example configuration with environment variables:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"mcpServers": {
|
|
||||||
"context7": {
|
|
||||||
"command": "npx",
|
|
||||||
"args": ["-y", "@upstash/context7-mcp"],
|
|
||||||
"env": {
|
|
||||||
"DEFAULT_MINIMUM_TOKENS": "6000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔨 Available Tools
|
## 🔨 Available Tools
|
||||||
|
|
||||||
Context7 MCP provides the following tools that LLMs can use:
|
Context7 MCP provides the following tools that LLMs can use:
|
||||||
@ -453,7 +431,7 @@ Context7 MCP provides the following tools that LLMs can use:
|
|||||||
- `get-library-docs`: Fetches documentation for a library using a Context7-compatible library ID.
|
- `get-library-docs`: Fetches documentation for a library using a Context7-compatible library ID.
|
||||||
- `context7CompatibleLibraryID` (required): Exact Context7-compatible library ID (e.g., `/mongodb/docs`, `/vercel/next.js`)
|
- `context7CompatibleLibraryID` (required): Exact Context7-compatible library ID (e.g., `/mongodb/docs`, `/vercel/next.js`)
|
||||||
- `topic` (optional): Focus the docs on a specific topic (e.g., "routing", "hooks")
|
- `topic` (optional): Focus the docs on a specific topic (e.g., "routing", "hooks")
|
||||||
- `tokens` (optional, default 10000): Max number of tokens to return. Values less than the configured `DEFAULT_MINIMUM_TOKENS` value or the default value of 10000 are automatically increased to that value.
|
- `tokens` (optional, default 10000): Max number of tokens to return. Values less than the default value of 10000 are automatically increased to 10000.
|
||||||
|
|
||||||
## 💻 Development
|
## 💻 Development
|
||||||
|
|
||||||
@ -469,6 +447,25 @@ Build:
|
|||||||
bun run build
|
bun run build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Run the server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun run dist/index.js
|
||||||
|
```
|
||||||
|
|
||||||
|
### CLI Arguments
|
||||||
|
|
||||||
|
`context7-mcp` accepts the following CLI flags:
|
||||||
|
|
||||||
|
- `--transport <stdio|http|sse>` – Transport to use (`stdio` by default).
|
||||||
|
- `--port <number>` – Port to listen on when using `http` or `sse` transport (default `3000`).
|
||||||
|
|
||||||
|
Example with http transport and port 8080:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun run dist/index.js --transport http --port 8080
|
||||||
|
```
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Local Configuration Example</b></summary>
|
<summary><b>Local Configuration Example</b></summary>
|
||||||
|
|
||||||
|
6
bun.lock
6
bun.lock
@ -5,7 +5,7 @@
|
|||||||
"name": "context7-mcp",
|
"name": "context7-mcp",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.12.0",
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
||||||
"dotenv": "^16.5.0",
|
"commander": "^14.0.0",
|
||||||
"zod": "^3.24.2",
|
"zod": "^3.24.2",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -114,6 +114,8 @@
|
|||||||
|
|
||||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||||
|
|
||||||
|
"commander": ["commander@14.0.0", "", {}, "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA=="],
|
||||||
|
|
||||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||||
|
|
||||||
"content-disposition": ["content-disposition@1.0.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg=="],
|
"content-disposition": ["content-disposition@1.0.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg=="],
|
||||||
@ -134,8 +136,6 @@
|
|||||||
|
|
||||||
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
||||||
|
|
||||||
"dotenv": ["dotenv@16.5.0", "", {}, "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg=="],
|
|
||||||
|
|
||||||
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
||||||
|
|
||||||
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
|
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
"lint": "eslint \"**/*.{js,ts,tsx}\" --fix",
|
"lint": "eslint \"**/*.{js,ts,tsx}\" --fix",
|
||||||
"lint:check": "eslint \"**/*.{js,ts,tsx}\"",
|
"lint:check": "eslint \"**/*.{js,ts,tsx}\"",
|
||||||
"start": "MCP_TRANSPORT=http node dist/index.js"
|
"start": "node dist/index.js --transport http"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -34,7 +34,7 @@
|
|||||||
"homepage": "https://github.com/upstash/context7#readme",
|
"homepage": "https://github.com/upstash/context7#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.12.0",
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
||||||
"dotenv": "^16.5.0",
|
"commander": "^14.0.0",
|
||||||
"zod": "^3.24.2"
|
"zod": "^3.24.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
43
src/index.ts
43
src/index.ts
@ -6,27 +6,34 @@ import { z } from "zod";
|
|||||||
import { searchLibraries, fetchLibraryDocumentation } from "./lib/api.js";
|
import { searchLibraries, fetchLibraryDocumentation } from "./lib/api.js";
|
||||||
import { formatSearchResults } from "./lib/utils.js";
|
import { formatSearchResults } from "./lib/utils.js";
|
||||||
import { SearchResponse } from "./lib/types.js";
|
import { SearchResponse } from "./lib/types.js";
|
||||||
import dotenv from "dotenv";
|
|
||||||
import { createServer } from "http";
|
import { createServer } from "http";
|
||||||
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
||||||
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
||||||
import { parse } from "url";
|
import { parse } from "url";
|
||||||
|
import { Command } from "commander";
|
||||||
|
|
||||||
// Load environment variables from .env file if present
|
const DEFAULT_MINIMUM_TOKENS = 10000;
|
||||||
dotenv.config();
|
|
||||||
|
|
||||||
// Get DEFAULT_MINIMUM_TOKENS from environment variable or use default
|
// Parse CLI arguments using commander
|
||||||
let DEFAULT_MINIMUM_TOKENS = 10000;
|
const program = new Command()
|
||||||
if (process.env.DEFAULT_MINIMUM_TOKENS) {
|
.option("--transport <stdio|http|sse>", "transport type", "stdio")
|
||||||
const parsedValue = parseInt(process.env.DEFAULT_MINIMUM_TOKENS, 10);
|
.option("--port <number>", "port for HTTP/SSE transport", "3000")
|
||||||
if (!isNaN(parsedValue) && parsedValue > 0) {
|
.allowUnknownOption() // let MCP Inspector / other wrappers pass through extra flags
|
||||||
DEFAULT_MINIMUM_TOKENS = parsedValue;
|
.parse(process.argv);
|
||||||
} else {
|
|
||||||
console.warn(
|
const cliOptions = program.opts<{
|
||||||
`Warning: Invalid DEFAULT_MINIMUM_TOKENS value provided in environment variable. Using default value of 10000`
|
transport: string;
|
||||||
);
|
port: string;
|
||||||
}
|
}>();
|
||||||
}
|
|
||||||
|
// Transport configuration
|
||||||
|
const TRANSPORT_TYPE = (cliOptions.transport || "stdio") as "stdio" | "http" | "sse";
|
||||||
|
|
||||||
|
// HTTP/SSE port configuration
|
||||||
|
const CLI_PORT = (() => {
|
||||||
|
const parsed = parseInt(cliOptions.port, 10);
|
||||||
|
return isNaN(parsed) ? undefined : parsed;
|
||||||
|
})();
|
||||||
|
|
||||||
// Store SSE transports by session ID
|
// Store SSE transports by session ID
|
||||||
const sseTransports: Record<string, SSEServerTransport> = {};
|
const sseTransports: Record<string, SSEServerTransport> = {};
|
||||||
@ -166,15 +173,15 @@ ${resultsText}`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const transportType = process.env.MCP_TRANSPORT || "stdio";
|
const transportType = TRANSPORT_TYPE;
|
||||||
|
|
||||||
if (transportType === "http" || transportType === "sse") {
|
if (transportType === "http" || transportType === "sse") {
|
||||||
// Get initial port from environment or use default
|
// Get initial port from environment or use default
|
||||||
const initialPort = process.env.PORT ? parseInt(process.env.PORT, 10) : 3000;
|
const initialPort = CLI_PORT ?? 3000;
|
||||||
// Keep track of which port we end up using
|
// Keep track of which port we end up using
|
||||||
let actualPort = initialPort;
|
let actualPort = initialPort;
|
||||||
const httpServer = createServer(async (req, res) => {
|
const httpServer = createServer(async (req, res) => {
|
||||||
const url = parse(req.url || "").pathname;
|
const url = new URL(req.url || "", `http://${req.headers.host}`).pathname;
|
||||||
|
|
||||||
// Set CORS headers for all responses
|
// Set CORS headers for all responses
|
||||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user