Summary
The MCP server fails to load SSH server configurations from .env because index.js hardcodes the .env path relative to __dirname (the module directory), while config-loader.js documents process.cwd() as the default path. These two paths are almost never the same in real deployments.
Environment
- mcp-ssh-manager version: 3.2.0
- Node.js: v22.17.1
- OS: Linux Ubuntu 25.10
- npm install -g mcp-ssh-manager
Steps to Reproduce
- Install mcp-ssh-manager globally via npm
- Create
~/.env with valid SSH server config:
SSH_SERVER_MYHOST_HOST=myhost.example.com
SSH_SERVER_MYHOST_USER=root
SSH_SERVER_MYHOST_PORT=22
SSH_SERVER_MYHOST_KEYPATH=/home/user/.ssh/id_rsa
- Run
ssh-manager server list → servers are listed correctly ✅
- Start the MCP server:
node /path/to/mcp-ssh-manager/src/index.js
- Observe:
⚠️ No SSH server configurations found / Loaded 0 SSH server configurations from null
Root Cause
In src/index.js (line ~167):
// Load environment variables (for backward compatibility)
const envFilePath = path.join(__dirname, '..', '.env');
dotenv.config({ path: envFilePath });
// Load SSH server configuration
configLoader.load({
envPath: envFilePath, // ← hardcoded to module dir, NOT process.cwd()
...
})
__dirname resolves to .../node_modules/mcp-ssh-manager/src/, so envFilePath becomes .../node_modules/mcp-ssh-manager/.env — a path that never exists in a global npm install.
Meanwhile, config-loader.js correctly defaults to process.cwd():
async load(options = {}) {
const {
envPath = path.join(process.cwd(), '.env'), // ← correct default
...
}
}
But this default is never used because index.js always passes the hardcoded __dirname-based path.
Additionally, configLoader.load() is called without await — it uses .then() — so the MCP server initializes before servers are loaded. The warning No SSH server configurations found fires from the synchronous init path, not from the resolved promise.
Expected Behavior
The MCP server should find .env in process.cwd() (the directory Claude Code is started from), consistent with what config-loader.js documents and what ssh-manager server add uses (~/.env = home directory).
Suggested Fix
Option A — Use process.cwd() consistently in index.js:
const envFilePath = path.join(process.cwd(), '.env');
Option B — Fall back to os.homedir() if process.cwd()/.env does not exist:
const cwdEnv = path.join(process.cwd(), '.env');
const homeEnv = path.join(os.homedir(), '.env');
const envFilePath = fs.existsSync(cwdEnv) ? cwdEnv : homeEnv;
Option C — Use the same path as ssh-manager server add writes to (~/.env):
const envFilePath = path.join(os.homedir(), '.env');
Workaround
Until fixed, create a symlink:
ln -sf ~/.env ~/.nvm/versions/node/v22.17.1/lib/node_modules/mcp-ssh-manager/.env
Summary
The MCP server fails to load SSH server configurations from
.envbecauseindex.jshardcodes the.envpath relative to__dirname(the module directory), whileconfig-loader.jsdocumentsprocess.cwd()as the default path. These two paths are almost never the same in real deployments.Environment
Steps to Reproduce
~/.envwith valid SSH server config:ssh-manager server list→ servers are listed correctly ✅node /path/to/mcp-ssh-manager/src/index.js⚠️ No SSH server configurations found/Loaded 0 SSH server configurations from nullRoot Cause
In
src/index.js(line ~167):__dirnameresolves to.../node_modules/mcp-ssh-manager/src/, soenvFilePathbecomes.../node_modules/mcp-ssh-manager/.env— a path that never exists in a global npm install.Meanwhile,
config-loader.jscorrectly defaults toprocess.cwd():But this default is never used because
index.jsalways passes the hardcoded__dirname-based path.Additionally,
configLoader.load()is called withoutawait— it uses.then()— so the MCP server initializes before servers are loaded. The warningNo SSH server configurations foundfires from the synchronous init path, not from the resolved promise.Expected Behavior
The MCP server should find
.envinprocess.cwd()(the directory Claude Code is started from), consistent with whatconfig-loader.jsdocuments and whatssh-manager server adduses (~/.env= home directory).Suggested Fix
Option A — Use
process.cwd()consistently inindex.js:Option B — Fall back to
os.homedir()ifprocess.cwd()/.envdoes not exist:Option C — Use the same path as
ssh-manager server addwrites to (~/.env):Workaround
Until fixed, create a symlink: