@akms/mcp-ssh 0.1.4 → 0.1.6

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/lib/cli.js CHANGED
@@ -22,11 +22,12 @@ var DEFAULT_MAX_READ_FILE_BYTES = 2e5;
22
22
  var KEEPALIVE_INTERVAL_MS = 15e3;
23
23
  var SESSION_IDLE_TIMEOUT_MS = 15 * 60 * 1e3;
24
24
  var SESSION_SWEEP_INTERVAL_MS = 6e4;
25
+ var SHUTDOWN_DEADLINE_MS = 5e3;
25
26
  var CWD_MARKER = "__AKMS_SSH_CWD__";
26
27
  var MAX_DIRECTORY_ENTRIES = 1e3;
27
28
  var SERVER_NAME = "akms-mcp-ssh";
28
29
  var PACKAGE_NAME = "@akms/mcp-ssh";
29
- var SERVER_VERSION = "0.1.4";
30
+ var SERVER_VERSION = "0.1.6";
30
31
 
31
32
  // src/_defs/command-rules.ts
32
33
  var CRITICAL_PATH_PATTERN = new RegExp(
@@ -489,6 +490,10 @@ var LEVEL_WEIGHTS = {
489
490
  error: 4
490
491
  };
491
492
  var SECRET_META_KEYS = ["password", "passphrase", "privatekey", "privatekeypath", "secret", "token"];
493
+ var stderrBroken = false;
494
+ process.stderr.on("error", () => {
495
+ stderrBroken = true;
496
+ });
492
497
  function resolveThreshold() {
493
498
  const configured = process.env[LOG_LEVEL_ENV];
494
499
  if (configured == null) {
@@ -512,6 +517,9 @@ function maskMeta(meta) {
512
517
  return masked;
513
518
  }
514
519
  function write(level, message, meta) {
520
+ if (stderrBroken == true) {
521
+ return;
522
+ }
515
523
  const threshold = resolveThreshold();
516
524
  if (threshold === "silent") {
517
525
  return;
@@ -525,8 +533,12 @@ function write(level, message, meta) {
525
533
  if (Object.keys(masked).length > 0) {
526
534
  line += ` ${JSON.stringify(masked)}`;
527
535
  }
528
- process.stderr.write(`${line}
536
+ try {
537
+ process.stderr.write(`${line}
529
538
  `);
539
+ } catch {
540
+ stderrBroken = true;
541
+ }
530
542
  }
531
543
  function createLogger(boundMeta) {
532
544
  return {
@@ -4825,7 +4837,7 @@ async function manageHost(prompter, output, target, entries, name) {
4825
4837
  }
4826
4838
  }
4827
4839
  }
4828
- async function runSetupCommand(options) {
4840
+ async function runConfigCommand(options) {
4829
4841
  const { input, output } = options;
4830
4842
  const targets = options.targets ?? listConfigTargets();
4831
4843
  let target = targets[0];
@@ -5635,12 +5647,11 @@ function createSshMcpServer() {
5635
5647
  }
5636
5648
 
5637
5649
  // src/cli.ts
5638
- var SETUP_COMMAND_NAMES = ["setup", "config"];
5639
5650
  function parseArguments(argv) {
5640
- const parsed = { showHelp: false, showVersion: false, checkOnly: false, setupMode: false };
5651
+ const parsed = { showHelp: false, showVersion: false, checkOnly: false, configMode: false };
5641
5652
  let rest = argv;
5642
- if (argv[0] != null && SETUP_COMMAND_NAMES.includes(argv[0]) == true) {
5643
- parsed.setupMode = true;
5653
+ if (argv[0] === "config") {
5654
+ parsed.configMode = true;
5644
5655
  rest = argv.slice(1);
5645
5656
  }
5646
5657
  for (let index = 0; index < rest.length; index += 1) {
@@ -5674,17 +5685,17 @@ var HELP_TEXT = [
5674
5685
  "",
5675
5686
  "Usage:",
5676
5687
  " akms-mcp-ssh [--check]",
5677
- " akms-mcp-ssh setup [--target <client>]",
5688
+ " akms-mcp-ssh config [--target <client>]",
5678
5689
  "",
5679
5690
  "Commands:",
5680
- " setup Manage the SSH hosts registered in an MCP client's config \u2014",
5691
+ " config Manage the SSH hosts registered in an MCP client's config \u2014",
5681
5692
  " list, add, edit, remove, check, print. Asks plain questions,",
5682
5693
  " so the SSH_* names below never have to be typed.",
5683
5694
  "",
5684
5695
  "Options:",
5685
5696
  " --check Connect to the configured host, report the result, and exit.",
5686
5697
  " Prints the host key fingerprint so it can be pinned.",
5687
- " --target <id> setup: claude-code | codex | claude-desktop | cursor",
5698
+ " --target <id> config: claude-code | codex | claude-desktop | cursor",
5688
5699
  " (default: the first one installed)",
5689
5700
  " -v, --version Print the version and exit",
5690
5701
  " -h, --help Print this help and exit",
@@ -5718,7 +5729,7 @@ var HELP_TEXT = [
5718
5729
  ].join("\n");
5719
5730
  async function runCheckCommand(profile) {
5720
5731
  if (profile == null) {
5721
- process.stdout.write(`No SSH host is registered \u2014 set ${SINGLE_HOST_ENV.HOST} and ${SINGLE_HOST_ENV.USER}, or run: akms-mcp-ssh setup
5732
+ process.stdout.write(`No SSH host is registered \u2014 set ${SINGLE_HOST_ENV.HOST} and ${SINGLE_HOST_ENV.USER}, or run: akms-mcp-ssh config
5722
5733
  `);
5723
5734
  return 1;
5724
5735
  }
@@ -5730,6 +5741,11 @@ async function runCheckCommand(profile) {
5730
5741
  }
5731
5742
  async function main() {
5732
5743
  const _logger = $logger.child({ context: "cli" });
5744
+ if (process.argv[2] === "setup") {
5745
+ process.stderr.write("The setup command has been removed. Use akms-mcp-ssh config.\n");
5746
+ process.exitCode = 1;
5747
+ return;
5748
+ }
5733
5749
  const cliArguments = parseArguments(process.argv.slice(2));
5734
5750
  if (cliArguments.showHelp == true) {
5735
5751
  process.stderr.write(`${HELP_TEXT}
@@ -5741,11 +5757,11 @@ async function main() {
5741
5757
  `);
5742
5758
  return;
5743
5759
  }
5744
- if (cliArguments.setupMode == true) {
5760
+ if (cliArguments.configMode == true) {
5745
5761
  if (process.env[LOG_LEVEL_ENV] == null) {
5746
5762
  process.env[LOG_LEVEL_ENV] = "warn";
5747
5763
  }
5748
- const exitCode = await runSetupCommand({
5764
+ const exitCode = await runConfigCommand({
5749
5765
  input: process.stdin,
5750
5766
  output: process.stdout,
5751
5767
  targetId: cliArguments.targetId
@@ -5761,6 +5777,12 @@ async function main() {
5761
5777
  instance.shutdown();
5762
5778
  process.exit(exitCode);
5763
5779
  }
5780
+ process.on("uncaughtException", (error) => {
5781
+ _logger.error(error, "uncaught exception; the server keeps running");
5782
+ });
5783
+ process.on("unhandledRejection", (reason) => {
5784
+ _logger.error(reason, "unhandled rejection; the server keeps running");
5785
+ });
5764
5786
  let shuttingDown = false;
5765
5787
  const shutdown = (signal) => {
5766
5788
  if (shuttingDown == true) {
@@ -5768,6 +5790,10 @@ async function main() {
5768
5790
  }
5769
5791
  shuttingDown = true;
5770
5792
  _logger.info("shutting down", { signal });
5793
+ setTimeout(() => {
5794
+ _logger.warn("shutdown did not finish in time; exiting anyway", { deadline_ms: SHUTDOWN_DEADLINE_MS });
5795
+ process.exit(0);
5796
+ }, SHUTDOWN_DEADLINE_MS).unref();
5771
5797
  instance.shutdown();
5772
5798
  void instance.server.close().finally(() => {
5773
5799
  process.exit(0);
@@ -5787,7 +5813,8 @@ async function main() {
5787
5813
  _logger.info("mcp server ready on stdio", {
5788
5814
  server: SERVER_NAME,
5789
5815
  version: SERVER_VERSION,
5790
- profile: instance.profile?.name ?? null
5816
+ profile: instance.profile?.name ?? null,
5817
+ pid: process.pid
5791
5818
  });
5792
5819
  }
5793
5820
  main().catch((error) => {