@akms/mcp-ssh 0.1.5 → 0.1.7
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/CHANGELOG.md +205 -0
- package/README.md +6 -1
- package/lib/cli.cjs +639 -503
- package/lib/cli.cjs.map +1 -1
- package/lib/cli.js +642 -506
- package/lib/cli.js.map +1 -1
- package/lib/index.cjs +18 -3
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +2 -2
- package/lib/index.d.ts +2 -2
- package/lib/index.js +18 -3
- package/lib/index.js.map +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@akms/mcp-ssh`. Dates are `YYYY-MM-DD`.
|
|
4
|
+
|
|
5
|
+
## 0.1.7 — 2026-10-19
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Keep connection check results visible in interactive `config` until Enter is pressed,
|
|
10
|
+
instead of immediately redrawing the menu and scrolling the report out of view.
|
|
11
|
+
Esc goes back and Ctrl+C exits; scripted input needs no additional answer.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Animate checks in `config` and `--check` with a spinner and elapsed time for each phase:
|
|
16
|
+
SSH preparation, the jump host or proxy (when configured), and the target handshake and authentication.
|
|
17
|
+
Completed phases remain visible with success or failure markers and colors.
|
|
18
|
+
- Fit progress lines to the terminal width, use ASCII on legacy Windows consoles, and
|
|
19
|
+
respect `NO_COLOR`. Redirected output and `TERM=dumb` keep plain reports.
|
|
20
|
+
|
|
21
|
+
### Documentation
|
|
22
|
+
|
|
23
|
+
- Include `CHANGELOG.md` in the npm package and document the check display in the README.
|
|
24
|
+
|
|
25
|
+
### Library API
|
|
26
|
+
|
|
27
|
+
- `SshConnection.connect(onProgress?)` can report the `transport` and `host` phases of a new connection attempt.
|
|
28
|
+
|
|
29
|
+
### Verification
|
|
30
|
+
|
|
31
|
+
- Cover report pauses, cancellation, progress timing and cleanup, narrow terminals, and
|
|
32
|
+
phase transitions on successful and failed checks.
|
|
33
|
+
|
|
34
|
+
## 0.1.6 — 2026-10-13
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- Never stay behind when the MCP client dies. The first log line written after stdin ends goes to
|
|
39
|
+
a stderr nobody reads; that EPIPE is now absorbed once and logging stops for good, instead of
|
|
40
|
+
being logged again (the loop that kept `@akms/mcp-db` 0.1.1 alive at 100% CPU). Shutdown also
|
|
41
|
+
has a 5 s deadline (`SHUTDOWN_DEADLINE_MS`) after which the process exits regardless.
|
|
42
|
+
- Keep the server running through an uncaught exception or unhandled rejection raised by one
|
|
43
|
+
session instead of taking every tool of the client down; both are logged.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- The `mcp server ready on stdio` log line carries the process `pid`.
|
|
48
|
+
|
|
49
|
+
### Verification
|
|
50
|
+
|
|
51
|
+
- Add `tests/cli-shutdown.test.ts`: starts the server through `cmd /c` the way Claude Code does
|
|
52
|
+
on Windows, completes the handshake, lets the client die, and expects the server gone within 5 s.
|
|
53
|
+
|
|
54
|
+
## 0.1.5 — 2026-10-13
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
|
|
58
|
+
- **Breaking:** Use `akms-mcp-ssh config` as the only configuration command. The former
|
|
59
|
+
`setup` command now exits with code 1 and a reminder to use `config`.
|
|
60
|
+
- Align CLI help, usage examples and developer documentation with `config`.
|
|
61
|
+
|
|
62
|
+
### Verification
|
|
63
|
+
|
|
64
|
+
- Add CLI regression tests for help, `config --target codex`, rejecting `setup`, and
|
|
65
|
+
the `--check` guidance when no host is configured. Tests use temporary client settings.
|
|
66
|
+
|
|
67
|
+
## 0.1.4 — 2026-10-13
|
|
68
|
+
|
|
69
|
+
### Documentation
|
|
70
|
+
|
|
71
|
+
- Expand the `setup` guide with keyboard controls, Esc behavior, the legacy `config`
|
|
72
|
+
alias, and reconnecting the MCP client after saving.
|
|
73
|
+
- Document release version synchronization across the package files and `SERVER_VERSION`,
|
|
74
|
+
plus tests, build, CLI smoke checks and package inspection before publishing.
|
|
75
|
+
- Clarify the test suite's local network requirements and its coverage of form navigation
|
|
76
|
+
and text editing. Runtime behavior is unchanged.
|
|
77
|
+
|
|
78
|
+
## 0.1.3 — 2026-10-11
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
|
|
82
|
+
- **The host manager is `akms-mcp-ssh setup`.** `config` still opens it, so the name used
|
|
83
|
+
in 0.1.0 – 0.1.2 keeps working, but it is no longer listed in `--help`.
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- **Esc goes back one level everywhere in `setup`.** Inside the settings form, Esc in a
|
|
88
|
+
choice list (authentication, route, private key), a text field or a secret returns to the
|
|
89
|
+
form with the setting unchanged — including the follow-up a choice opened, so Esc at the
|
|
90
|
+
jump-host question also restores the route. Esc at the "Write it?" preview reopens the form
|
|
91
|
+
on the same values. Before, a list opened from the form ignored Esc, and a text field never
|
|
92
|
+
saw it: on macOS / Linux the terminal handed the `ESC` byte over as part of the value.
|
|
93
|
+
- Text fields on a terminal are now a small line editor in raw mode (←/→, Home/End,
|
|
94
|
+
Backspace/Delete, Ctrl+U), which is what makes Esc visible there.
|
|
95
|
+
|
|
96
|
+
## 0.1.2 — 2026-10-11
|
|
97
|
+
|
|
98
|
+
### Changed
|
|
99
|
+
|
|
100
|
+
- **Adding or editing a host opens a settings form** instead of a sequence of questions.
|
|
101
|
+
Every setting is listed with its value; pick one to change it, in any order, as often as
|
|
102
|
+
needed. The cursor then moves to the next setting, so Enter down the list still fills the
|
|
103
|
+
form top to bottom. Settings a choice brings with it (the private key, the jump host) appear
|
|
104
|
+
under it once chosen, empty required settings are marked, and Save moves to the first
|
|
105
|
+
missing one. Test the connection and Save sit below the settings; Save offers a test when
|
|
106
|
+
the values changed since the last one. On a terminal the form redraws in place.
|
|
107
|
+
|
|
108
|
+
## 0.1.1 — 2026-10-11
|
|
109
|
+
|
|
110
|
+
### Changed
|
|
111
|
+
|
|
112
|
+
- **`config` menus are arrow-key lists.** Options are picked with ↑/↓ and Enter instead of
|
|
113
|
+
typing a keyword (`claude-code`, `password`, a menu letter). The hosts are the main menu:
|
|
114
|
+
pick one to edit, check, print or remove it. The private key is chosen from the keys found
|
|
115
|
+
in `~/.ssh`, and the route is one choice (directly / jump host / proxy command / both)
|
|
116
|
+
instead of two yes/no questions. Answered prompts collapse to one `✔ question · answer`
|
|
117
|
+
line. Without a terminal (a pipe, Git Bash's mintty) the lists are numbered instead.
|
|
118
|
+
|
|
119
|
+
## 0.1.0 — 2026-10-11
|
|
120
|
+
|
|
121
|
+
### Added
|
|
122
|
+
|
|
123
|
+
- **`akms-mcp-ssh config`** — an interactive manager for the hosts registered in an MCP
|
|
124
|
+
client's config: list, add, edit, remove, check, print, switch client. It asks plain
|
|
125
|
+
questions instead of `SSH_*` names, tests the connection, offers to pin the host key, and
|
|
126
|
+
writes the entry. Targets Claude Code (user scope, through `claude mcp`), Codex
|
|
127
|
+
(`~/.codex/config.toml`), Claude Desktop and Cursor. `--target <client>` picks one.
|
|
128
|
+
- **Jump host** — `SSH_JUMP_HOST` (with `SSH_JUMP_PORT` / `SSH_JUMP_USER` / `SSH_JUMP_KEY`
|
|
129
|
+
/ `SSH_JUMP_PASSPHRASE` / `SSH_JUMP_PASSWORD` / `SSH_JUMP_HOST_KEY`) connects to a
|
|
130
|
+
bastion first and reaches the target over a forwarded TCP channel, as `ssh -J` does.
|
|
131
|
+
User and key default to the target's.
|
|
132
|
+
- **Proxy command** — `SSH_PROXY_COMMAND` runs a command and speaks SSH over its
|
|
133
|
+
stdin/stdout, as OpenSSH's `ProxyCommand` does; `%h` / `%p` / `%r` expand to the first
|
|
134
|
+
hop. It carries the jump host when both are set, so "cloudflared to the bastion, then
|
|
135
|
+
forward to the target" is one entry.
|
|
136
|
+
- A `SSH_JUMP_*` variable set without `SSH_JUMP_HOST` aborts startup, like every other
|
|
137
|
+
half-formed value.
|
|
138
|
+
- `ssh_list_hosts` shows the route; `--check` prints it along with the jump host's key
|
|
139
|
+
fingerprint.
|
|
140
|
+
|
|
141
|
+
### Changed
|
|
142
|
+
|
|
143
|
+
- `--check` now lets warnings and errors through instead of silencing the log entirely,
|
|
144
|
+
so a missing key file or the proxy command's stderr (a `cloudflared` login prompt) is
|
|
145
|
+
visible where the operator is looking. An explicit `SSH_MCP_LOG_LEVEL` still wins.
|
|
146
|
+
|
|
147
|
+
### Library API
|
|
148
|
+
|
|
149
|
+
- `SshHostProfile` gains `proxyCommand` and `jump` (`SshJumpProfile`); `SshHostSummary`
|
|
150
|
+
gains `viaProxyCommand` and `jump`.
|
|
151
|
+
- `SshConnection.jumpHostKeyFingerprint`.
|
|
152
|
+
- `loadHostProfile(env?)` reads from the given record instead of `process.env` when one
|
|
153
|
+
is passed.
|
|
154
|
+
|
|
155
|
+
## 0.0.3 — 2026-09-28
|
|
156
|
+
|
|
157
|
+
- `package.json` declares `repository`, `homepage` and `bugs` pointing at
|
|
158
|
+
`github.com/alkemic-studio/npm.akms.mcp-ssh`.
|
|
159
|
+
|
|
160
|
+
## 0.0.2 — 2026-08-09
|
|
161
|
+
|
|
162
|
+
First release to reach the registry. `0.0.1` was built but never published, so the
|
|
163
|
+
configuration surface listed under **Removed** never actually shipped — it is recorded
|
|
164
|
+
here because the code carried it right up to this version.
|
|
165
|
+
|
|
166
|
+
### Changed
|
|
167
|
+
|
|
168
|
+
- **Configuration is environment variables only.** A host is declared with plain `SSH_*`
|
|
169
|
+
variables in the MCP client's own server entry — one entry per host. "What is this
|
|
170
|
+
server allowed to do" is now answerable by reading that entry, with no second file to
|
|
171
|
+
find and no precedence order to reason about.
|
|
172
|
+
- Fronting several hosts means several server entries, each carrying its own connection
|
|
173
|
+
and its own guard policy, declared where you read it.
|
|
174
|
+
- `--check` reports the one configured host instead of iterating profiles.
|
|
175
|
+
|
|
176
|
+
### Removed
|
|
177
|
+
|
|
178
|
+
- Every config-file source: the `--config <path>` flag, `SSH_MCP_CONFIG`,
|
|
179
|
+
`~/.akms-ssh.json` and `~/.config/akms-ssh/config.json` — along with the `defaults`
|
|
180
|
+
block, the `hosts` map and the zod schema that validated them.
|
|
181
|
+
- The `target` argument on every tool. With one host there is nothing to select, so the
|
|
182
|
+
model cannot name a machine even in principle.
|
|
183
|
+
- `ssh_reload_config`. Environment variables are fixed for the life of the process, so
|
|
184
|
+
applying a change means restarting the server.
|
|
185
|
+
- `privateKey` (inline key contents), `passphraseEnv` and `passwordEnv`. `SSH_KEY` takes a
|
|
186
|
+
path and `SSH_PASSPHRASE` / `SSH_PASSWORD` are themselves environment variables, so the
|
|
187
|
+
indirection had nothing left to point at.
|
|
188
|
+
- The protected-local-path rule for `.akms-ssh.json`. The files that define the guards are
|
|
189
|
+
now the MCP client configurations (`.mcp.json`, `.claude*`,
|
|
190
|
+
`claude_desktop_config.json`), which stay protected.
|
|
191
|
+
|
|
192
|
+
### Library API
|
|
193
|
+
|
|
194
|
+
- `loadConfig(path?)` → `loadHostProfile()`, returning `SshHostProfile | null`.
|
|
195
|
+
- `createSshMcpServer(options?)` → `createSshMcpServer()`. The instance exposes `profile`
|
|
196
|
+
instead of `config`, and `reloadConfig()` is gone.
|
|
197
|
+
- Dropped the `SshMcpConfig` and `SshMcpServerOptions` types and the `POLICY_INPUT_SCHEMA`
|
|
198
|
+
/ `HOST_INPUT_SCHEMA` / `CONFIG_INPUT_SCHEMA` exports.
|
|
199
|
+
|
|
200
|
+
### Unchanged
|
|
201
|
+
|
|
202
|
+
The guards. Catastrophe rules, `SSH_READONLY`, `SSH_ALLOW_SUDO`, `SSH_ALLOW_COMMANDS`,
|
|
203
|
+
`SSH_DENY_PATTERNS` and `SSH_ALLOWED_PATHS` screen exactly what they did before, at the
|
|
204
|
+
same chokepoint inside `SshConnection.exec` and the SFTP operations. A malformed value
|
|
205
|
+
still aborts startup rather than being ignored.
|
package/README.md
CHANGED
|
@@ -56,6 +56,11 @@ Esc also undoes a choice when pressed in its follow-up question: choosing a jump
|
|
|
56
56
|
|
|
57
57
|
Without an interactive terminal (a pipe, or Git Bash's mintty without winpty), the same menus use numbered choices; enter a number, key or label followed by Enter. After saving, restart the MCP client or reconnect the server from its MCP menu to load the updated entry.
|
|
58
58
|
|
|
59
|
+
On a terminal, checks in `config` and `--check` show animated progress, elapsed time and
|
|
60
|
+
completed phases. After a check in `config`, **press Enter to continue**; Esc goes back and
|
|
61
|
+
Ctrl+C exits. Redirected output stays plain and scripted input needs no extra answer.
|
|
62
|
+
Release notes are in [CHANGELOG.md](CHANGELOG.md).
|
|
63
|
+
|
|
59
64
|
| Client | Config file | How it is written |
|
|
60
65
|
|---|---|---|
|
|
61
66
|
| Claude Code | `~/.claude.json` (user scope) | through `claude mcp add-json … -s user`, never by editing the file |
|
|
@@ -84,7 +89,7 @@ Only entries that launch this package are listed or touched. An edit keeps every
|
|
|
84
89
|
|
|
85
90
|
`SSH_HOST` + `SSH_USER` is the whole minimum, and the **private key stays a file on disk** — only its path goes in the config. Because each server fronts one host, the agent never names it: `ssh_exec({ command: "df -h" })` is a complete call. The server name (`ssh-prod`) is what the agent sees in its tool list, so name it after the host.
|
|
86
91
|
|
|
87
|
-
The server speaks MCP over **stdio**: stdout carries the JSON-RPC stream and all logging goes to stderr. Running it by hand in a terminal only prints the startup line and waits.
|
|
92
|
+
The server speaks MCP over **stdio**: stdout carries the JSON-RPC stream and all logging goes to stderr. Running it by hand in a terminal only prints the startup line and waits. When the client goes away — stdin ends, or the process is simply gone — the server closes its sessions and exits within a few seconds on its own; a stderr nobody reads is never a reason to stay. Its log says `mcp server ready on stdio` with its `pid`, for when one has to be found among a client's processes.
|
|
88
93
|
|
|
89
94
|
## 🗂️ Host configuration
|
|
90
95
|
|