From 2e6c9a6c6b1a9c121f1a0cc4a5a5b1adb61e58ff Mon Sep 17 00:00:00 2001 From: Abdusshh Date: Wed, 11 Jun 2025 14:49:50 +0300 Subject: [PATCH] feat: replace env vars with CLI arguments, remove dotenv and add commander --- Dockerfile | 8 ++------ README.md | 43 ++++++++++++++++++++----------------------- bun.lock | 6 +++--- package.json | 4 ++-- src/index.ts | 43 +++++++++++++++++++++++++------------------ 5 files changed, 52 insertions(+), 52 deletions(-) diff --git a/Dockerfile b/Dockerfile index fabcb29..e4f0049 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,12 +25,8 @@ COPY package.json ./ # Install only production dependencies RUN npm install --production --ignore-scripts -# Set default environment variables for HTTP mode -ENV MCP_TRANSPORT=http -ENV PORT=8080 - # Expose HTTP port EXPOSE 8080 -# Default command -CMD ["node", "dist/index.js"] +# Default command using CLI flags +CMD ["node", "dist/index.js", "--transport", "http", "--port", "8080"] diff --git a/README.md b/README.md index 002c1ff..597b881 100644 --- a/README.md +++ b/README.md @@ -420,28 +420,6 @@ Add this to your Roo Code MCP configuration file. See [Roo Code MCP docs](https: -## 🔧 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 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. - `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") - - `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 @@ -469,6 +447,25 @@ Build: bun run build ``` +Run the server: + +```bash +bun run dist/index.js +``` + +### CLI Arguments + +`context7-mcp` accepts the following CLI flags: + +- `--transport ` – Transport to use (`stdio` by default). +- `--port ` – 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 +``` +
Local Configuration Example diff --git a/bun.lock b/bun.lock index 6e030e8..3812b7d 100644 --- a/bun.lock +++ b/bun.lock @@ -5,7 +5,7 @@ "name": "context7-mcp", "dependencies": { "@modelcontextprotocol/sdk": "^1.12.0", - "dotenv": "^16.5.0", + "commander": "^14.0.0", "zod": "^3.24.2", }, "devDependencies": { @@ -114,6 +114,8 @@ "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=="], "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=="], - "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=="], "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], diff --git a/package.json b/package.json index fbee769..0c8c77c 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "format": "prettier --write .", "lint": "eslint \"**/*.{js,ts,tsx}\" --fix", "lint:check": "eslint \"**/*.{js,ts,tsx}\"", - "start": "MCP_TRANSPORT=http node dist/index.js" + "start": "node dist/index.js --transport http" }, "repository": { "type": "git", @@ -34,7 +34,7 @@ "homepage": "https://github.com/upstash/context7#readme", "dependencies": { "@modelcontextprotocol/sdk": "^1.12.0", - "dotenv": "^16.5.0", + "commander": "^14.0.0", "zod": "^3.24.2" }, "devDependencies": { diff --git a/src/index.ts b/src/index.ts index 23467a6..1a26385 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,27 +6,34 @@ import { z } from "zod"; import { searchLibraries, fetchLibraryDocumentation } from "./lib/api.js"; import { formatSearchResults } from "./lib/utils.js"; import { SearchResponse } from "./lib/types.js"; -import dotenv from "dotenv"; import { createServer } from "http"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js"; import { parse } from "url"; +import { Command } from "commander"; -// Load environment variables from .env file if present -dotenv.config(); +const DEFAULT_MINIMUM_TOKENS = 10000; -// Get DEFAULT_MINIMUM_TOKENS from environment variable or use default -let DEFAULT_MINIMUM_TOKENS = 10000; -if (process.env.DEFAULT_MINIMUM_TOKENS) { - const parsedValue = parseInt(process.env.DEFAULT_MINIMUM_TOKENS, 10); - if (!isNaN(parsedValue) && parsedValue > 0) { - DEFAULT_MINIMUM_TOKENS = parsedValue; - } else { - console.warn( - `Warning: Invalid DEFAULT_MINIMUM_TOKENS value provided in environment variable. Using default value of 10000` - ); - } -} +// Parse CLI arguments using commander +const program = new Command() + .option("--transport ", "transport type", "stdio") + .option("--port ", "port for HTTP/SSE transport", "3000") + .allowUnknownOption() // let MCP Inspector / other wrappers pass through extra flags + .parse(process.argv); + +const cliOptions = program.opts<{ + 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 const sseTransports: Record = {}; @@ -166,15 +173,15 @@ ${resultsText}`, } async function main() { - const transportType = process.env.MCP_TRANSPORT || "stdio"; + const transportType = TRANSPORT_TYPE; if (transportType === "http" || transportType === "sse") { // 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 let actualPort = initialPort; 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 res.setHeader("Access-Control-Allow-Origin", "*");