diff --git a/package-lock.json b/package-lock.json index f74d323..aa60f5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "@programcomputer/nasa-mcp-server", - "version": "1.0.12", + "version": "1.0.13", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@programcomputer/nasa-mcp-server", - "version": "1.0.12", + "version": "1.0.13", "license": "ISC", "dependencies": { "@anthropic-ai/sdk": "", "@modelcontextprotocol/sdk": "^1.9.0", "axios": "", "cors": "", - "dotenv": "", + "dotenv": "^17.2.0", "express": "", "zod": "" }, @@ -2706,9 +2706,9 @@ } }, "node_modules/dotenv": { - "version": "16.4.7", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", - "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", "license": "BSD-2-Clause", "engines": { "node": ">=12" diff --git a/package.json b/package.json index 354124c..2512a7d 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "@modelcontextprotocol/sdk": "^1.9.0", "axios": "", "cors": "", - "dotenv": "", + "dotenv": "^17.2.0", "express": "", "zod": "" }, diff --git a/src/index.ts b/src/index.ts index 8383bc6..e4f43f5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,8 +18,10 @@ import { resources, addResource as addResourceCore, Resource } from './resources // Load environment variables with enhanced setup setupEnvironment(); -// Also load with standard dotenv for compatibility -dotenv.config(); +// Also load with standard dotenv for compatibility. +// quiet: true suppresses dotenv v17+'s startup banner, which is written to +// stdout and would corrupt the stdio JSON-RPC stream (breaks the MCP client). +dotenv.config({ quiet: true }); // Keep a reference to the server for notifications let serverInstance: Server | null = null; diff --git a/src/utils/api-client.ts b/src/utils/api-client.ts index 94f7819..838ed92 100644 --- a/src/utils/api-client.ts +++ b/src/utils/api-client.ts @@ -3,10 +3,13 @@ import dotenv from 'dotenv'; import path from 'path'; import { transformParamsToHyphenated } from './param-transformer'; -// Try to load environment variables from .env file with absolute path -dotenv.config(); +// Try to load environment variables from .env file with absolute path. +// quiet: true suppresses dotenv v17+'s "injecting env" banner, which is +// written to stdout and would corrupt the stdio JSON-RPC stream (this module +// is imported by index.ts, so these calls run during server startup). +dotenv.config({ quiet: true }); // Also try with explicit path as fallback -dotenv.config({ path: path.resolve(process.cwd(), '.env') }); +dotenv.config({ path: path.resolve(process.cwd(), '.env'), quiet: true }); // NASA API Base URLs export const NASA_API_BASE_URL = 'https://api.nasa.gov'; @@ -28,7 +31,7 @@ export async function nasaApiRequest( if (!apiKey) { try { const envPath = path.resolve(process.cwd(), '.env'); - dotenv.config({ path: envPath }); + dotenv.config({ path: envPath, quiet: true }); apiKey = process.env.NASA_API_KEY; } catch (error) { console.error('Error loading .env file:', error); @@ -124,7 +127,7 @@ export async function jplApiRequest( // If other JPL endpoints require a key but it's missing, try loading .env try { const envPath = path.resolve(process.cwd(), '.env'); - dotenv.config({ path: envPath }); + dotenv.config({ path: envPath, quiet: true }); apiKey = process.env.NASA_API_KEY; if (apiKey) { paramsToSend.api_key = apiKey; diff --git a/src/utils/env-setup.ts b/src/utils/env-setup.ts index bf28223..d9d2d7c 100644 --- a/src/utils/env-setup.ts +++ b/src/utils/env-setup.ts @@ -39,24 +39,26 @@ export function setupEnvironment() { const rootEnvPath = path.join(currentDir, '.env'); const distEnvPath = path.join(currentDir, 'dist', '.env'); - // First try standard .env loading - dotenv.config(); - + // First try standard .env loading. + // quiet: true suppresses dotenv v17+'s startup banner ("injecting env…"), + // which is printed to stdout and would corrupt the stdio JSON-RPC stream. + dotenv.config({ quiet: true }); + // If running from dist, also try parent directory if (currentDir.includes('dist')) { const parentEnvPath = path.join(currentDir, '..', '.env'); if (fs.existsSync(parentEnvPath)) { - dotenv.config({ path: parentEnvPath }); + dotenv.config({ path: parentEnvPath, quiet: true }); } } - + // Also try explicit paths if (fs.existsSync(rootEnvPath)) { - dotenv.config({ path: rootEnvPath }); + dotenv.config({ path: rootEnvPath, quiet: true }); } - + if (fs.existsSync(distEnvPath)) { - dotenv.config({ path: distEnvPath }); + dotenv.config({ path: distEnvPath, quiet: true }); } // Ensure dist directory has a copy of .env