Add disable, enable, completions, and alias commands#2
Merged
Conversation
- `mcpm disable/enable <name>`: toggle servers on/off without removing them by setting `disabled: true` in config entries. Supports --client filter. - `mcpm completions <shell>`: generate shell completion scripts for bash, zsh, and fish with full subcommand and option completions. - `mcpm alias <shortname> <server>`: create short aliases for long server names, stored in ~/.mcpm/aliases.json. Supports --list and --remove. - `mcpm list` now shows disabled/active status column. - Added setServerDisabled() to ConfigAdapter interface and BaseAdapter. - 33 new tests (730 total), all passing. https://claude.ai/code/session_01HVQiPLMxn8TFFcKbSyt42s
- Extract shared handleToggleServer() into toggle.ts, reducing disable.ts and enable.ts from ~124 lines each to ~55 line wrappers - Single-pass config read per client (was reading twice) - Validate --client against CLIENT_IDS before unsafe as ClientId cast - Replace loose alias validation (only blocked / and .) with strict regex /^[\w-]+$/ plus length cap, rejecting shell metacharacters - Block __proto__/constructor/prototype as server names - Validate alias name on --remove path before calling removeAlias() - Add tests: mixed-state toggle, invalid client, empty alias, shell metacharacters, max length, __proto__ server name, remove validation
m1ngshum
added a commit
that referenced
this pull request
Jun 1, 2026
…-disable Applies review findings #1–#5 from the multi-perspective review: - #1/#5: extract the secret→placeholder swap into a single `applyKeychainSecrets()` in keychain.ts (also now the home of `SecretsMode`). install.ts and up.ts both delegate to it, so the "no plaintext secret in config" invariant lives in one place and can't diverge. Drops the duplicated loop + the `storedSecretKeys` array (now a returned count). - #2: guard disable's placeholder warning is now a static import, never throws (advisory scan can't break a successful disable), and surfaces non-ENOENT config-read errors instead of swallowing them. - #3: `up --secrets keychain` only prints the "run mcpm guard enable" notice when a secret was actually stored (threaded via storedCount). - #4: add tests for applyKeychainSecrets, the slash-name keychain-id round-trip, and placeholderEnvKeys (the disable-warning detector). 1088 tests pass; typecheck + build clean.
m1ngshum
added a commit
that referenced
this pull request
Jun 1, 2026
* feat: add `--secrets keychain` to install/up + guard-disable safety Phase 2 of encrypted secrets. Opt-in, default unchanged (plaintext), so no existing flow regresses. - install/up `--secrets keychain`: secret-flagged env vars are stored AES-GCM-encrypted in ~/.mcpm and written into client configs as `mcpm:keychain:server/KEY` placeholders instead of plaintext. Non-secret vars stay inline. mcpm guard resolves the placeholders at launch (Phase 1). Both commands print a "run `mcpm guard enable`" note. - `up --secrets keychain` is rejected under `--ci` (never persist secrets to a CI runner's keychain). - keychain.ts: add deriveKeychainId() — maps slash-containing registry ids (io.github.owner/repo) to a placeholder-safe keychain id. - guard disable: read-only post-disable scan warns when an unwrapped config still references `mcpm:keychain:` placeholders (they only resolve under guard). Never silently rewrites plaintext (security-first). Tests: 9 new (deriveKeychainId, install/up keychain placeholder writes, plaintext no-regression, missing-dep + --ci guards). 1082 pass; coverage 80.85% lines / 87.57% branches. typecheck + build clean. * refactor: address PR review — consolidate keychain swap, harden guard-disable Applies review findings #1–#5 from the multi-perspective review: - #1/#5: extract the secret→placeholder swap into a single `applyKeychainSecrets()` in keychain.ts (also now the home of `SecretsMode`). install.ts and up.ts both delegate to it, so the "no plaintext secret in config" invariant lives in one place and can't diverge. Drops the duplicated loop + the `storedSecretKeys` array (now a returned count). - #2: guard disable's placeholder warning is now a static import, never throws (advisory scan can't break a successful disable), and surfaces non-ENOENT config-read errors instead of swallowing them. - #3: `up --secrets keychain` only prints the "run mcpm guard enable" notice when a secret was actually stored (threaded via storedCount). - #4: add tests for applyKeychainSecrets, the slash-name keychain-id round-trip, and placeholderEnvKeys (the disable-warning detector). 1088 tests pass; typecheck + build clean. * fix(security): injective keychain id + atomic secret store + honest messaging Addresses the dedicated security audit of the secrets feature: - CRIT-1: deriveKeychainId is now injective — sanitized prefix + a sha256 suffix — so names differing only in unsafe chars ("owner/repo" vs "owner_repo") can no longer collide into one secret namespace (cross-server secret confusion/exposure). - MED-1: applyKeychainSecrets persists all of a server's secrets in a single atomic batch (new keychain.setSecrets) BEFORE returning the env written to config — no orphaned half-written secrets if one fails. install/up deps switch from setSecret to setSecrets accordingly. - MED-4: install/up notices no longer overclaim — they state secrets are "encrypted at rest (protects against other-user/offline access, not same-user processes)", matching keychain.ts's documented posture. Tests updated to the batch API + an explicit collision-injectivity test. 1088 pass; typecheck + build clean. Pre-existing guard/keychain findings (full-env forward, event-log sanitization, store write lock, log rotation) are out of scope here and tracked separately.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
This PR adds four new commands to mcpm:
disable <name>– Disables an MCP server across all (or a specific) client config files by setting"disabled": trueon the entry. The server remains in config but won't be loaded by the client.enable <name>– Re-enables a previously disabled MCP server by removing the"disabled": trueflag.completions <shell>– Generates shell completion scripts for bash, zsh, and fish. Users can pipe the output into their shell config to enable tab-completion for mcpm commands and arguments.alias [args...]– Creates short aliases for long MCP server names (e.g.,mcpm alias fs io.github.domdomegg/filesystem-mcp). Aliases are stored in~/.mcpm/aliases.jsonand can be resolved automatically in install, info, remove, enable, and disable commands.The implementation includes:
setServerDisabled()method inBaseAdapterto toggle the disabled flag on server entriesdisabled?: booleanfield inMcpServerEntryinterfacelistcommand to display server status (enabled/disabled)How to test
pnpm testpassespnpm typecheckpassesAll new functionality is covered by unit tests:
src/__tests__/commands/disable.test.ts– Tests for disable commandsrc/__tests__/commands/enable.test.ts– Tests for enable commandsrc/__tests__/commands/completions.test.ts– Tests for completions commandsrc/__tests__/commands/alias.test.ts– Tests for alias commandsrc/__tests__/store/aliases.test.ts– Tests for aliases storeChecklist
https://claude.ai/code/session_01HVQiPLMxn8TFFcKbSyt42s