Skip to content

Releases: getmcpm/cli

v0.3.2 — Cross-platform paths and security hardening

06 Apr 10:25
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

What's fixed

Cross-platform config paths (TODO #4)

Cursor and Windsurf store MCP configs in home-relative directories on all platforms — including Windows. The previous code incorrectly routed them through `%APPDATA%`, causing silent detection failures for Windows users with Cursor or Windsurf installed.

Client macOS Linux Windows (before) Windows (now)
Claude Desktop `~/Library/Application Support/Claude/` `~/.config/Claude/` `%APPDATA%\Claude\` `%APPDATA%\Claude\` ✓
Cursor `~/.cursor/` `~/.cursor/` `%APPDATA%\.cursor\` ✗ `~/.cursor/` ✓
VS Code `~/Library/Application Support/Code/User/` `~/.config/Code/User/` `%APPDATA%\Code\User\` `%APPDATA%\Code\User\` ✓
Windsurf `~/.codeium/windsurf/` `~/.codeium/windsurf/` `%APPDATA%\.codeium\windsurf\` ✗ `~/.codeium/windsurf/` ✓

Security hardening

  • APPDATA traversal guard: `%APPDATA%` is now validated as an absolute Windows path via `path.win32.isAbsolute()` before use. Relative or traversal values (e.g. `../../etc`) fall back to homedir. Regression test added.
  • Consistent clientId validation: `mcpm install --client ` now validates the client name against the known list before casting, matching the pattern used in other commands. Unknown client names fail fast with a clear error listing valid values.

Tests

822 tests passing.

v0.3.1 — Bug fixes for stack files

06 Apr 08:32
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Bug fixes

Two bugs found during end-to-end testing of the v0.3.0 stack files feature:

Fixed: mcpm lock failing with `latest` version alias

mcpm export generates version: latest for servers without a pinned version. mcpm lock then couldn't resolve it because semver.valid('latest') returns null, causing "No versions available" errors.

The fix: resolveVersion() now handles "latest" as a first-class alias that returns the highest semver version from the available list.

Fixed: mcpm remove crashing with "Unexpected end of JSON input"

When a client config file was 0 bytes (e.g., VS Code creates an empty mcp.json on first run), BaseAdapter.readRaw() called JSON.parse("") which throws. The fix treats empty/whitespace-only files the same as missing files, returning {}.

Tests

821 tests passing. Two regression test cases added for each fix.

v0.3.0 — Stack Files (Compose for MCP)

05 Apr 18:00
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Stack Files — docker-compose for MCP servers

Declare your project's MCP servers in mcpm.yaml, lock versions with trust snapshots, and let every team member replicate the setup with one command.

mcpm export > mcpm.yaml    # dump current setup
mcpm lock                  # resolve versions + trust snapshot
mcpm up                    # install everything
mcpm diff                  # compare installed vs declared

New Commands

Command Description
mcpm export Export installed servers as an mcpm.yaml stack file
mcpm lock Resolve semver ranges, run trust assessment, write mcpm-lock.yaml
mcpm up Batch install from mcpm.yaml with trust policy enforcement
mcpm diff Compare installed state vs mcpm.yaml + lock file

Trust Policy

Stack files include a policy: block that gates mcpm up. If a server's trust score drops below the threshold, installation is blocked.

version: "1"
policy:
  minTrustScore: 60
  blockOnScoreDrop: true
servers:
  io.github.domdomegg/filesystem-mcp:
    version: "^1.0.0"

Key Features

  • Semver resolution — caret (^1.0.0) and tilde (~1.2.0) ranges resolved against the MCP registry
  • Trust snapshots — lock file captures trust score at lock time; mcpm up detects score drops using normalized percentages (works even when MCP-Scan availability differs across machines)
  • Parallel resolution — registry fetches and trust scans run concurrently per server
  • Per-server error isolation — one server failing doesn't block others
  • CI modemcpm up --ci exits nonzero on trust violations or missing env vars
  • Profile supportmcpm up --profile dev installs only servers tagged for that profile
  • Strict modemcpm up --strict --yes removes servers not in mcpm.yaml
  • Env var resolution — process.env → .env file → default → interactive prompt
  • URL servers — direct HTTP remotes supported (Cursor only, warns for other clients)
  • MCP toolmcpm_up exposed via mcpm serve for AI agent access

Security

  • Path traversal protection on MCP tool input
  • Prototype poisoning protection in .env parser
  • Single backup snapshot before batch writes
  • Secrets never exported in mcpm.yaml (keys only, values omitted)
  • All file writes use mode 0o600

Stats

  • 816 tests, 80%+ line coverage
  • 8 commits since v0.2.2

Full Changelog: v0.2.2...v0.3.0

v0.2.2 — security hardening (CSO audit fixes)

05 Apr 06:53
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Security fixes

Findings from a full CSO audit, all resolved:

  • Health-check command allowlist (HIGH) — spawn() in health checks now validates the command against an allowlist (npx, uvx, docker, node, python) before execution. Prevents RCE if a config file was tampered with after install.

  • MCP tool input constraints (MEDIUM) — Added Zod bounds on all MCP server tool inputs: query max 200 chars, description max 1000 chars, limit max 100, minTrustScore range 0-100 on all schemas. Prevents oversized payloads and trust-gate bypass via negative values.

  • Client ID validation in MCP server (MEDIUM) — resolveClients now validates --client against CLIENT_IDS allowlist before the as ClientId cast, matching the pattern already used in CLI commands.

  • Doctor command allowlist (MEDIUM) — execCheckDefault now restricts which commands can be passed to which/where.

  • Warning listener fix (MEDIUM) — Removed removeAllListeners("warning") which was suppressing Node.js security warnings. Now uses an additive filter for the cli-table3 noise only.

  • Always validate server name (LOW) — handleInstall now validates the server name unconditionally, even when called from handleSetup with pre-resolved entries.

Install / upgrade

npm install -g @getmcpm/cli@0.2.2

Full changelog: v0.2.1...v0.2.2

v0.2.1 — version display fix

05 Apr 06:31
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Fix

  • mcpm --version now shows the correct version. Previously the version was hardcoded in source. Now it's injected from package.json at build time via tsup define, so CI's tag-based version always matches what the user sees.

Install / upgrade

npm install -g @getmcpm/cli@0.2.1

For the full feature release notes (disable/enable, aliases, completions), see v0.2.0.

v0.2.0 — disable/enable, aliases, and shell completions

05 Apr 06:17
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

What's new

New commands

  • mcpm disable <name> — Disable an MCP server across all (or a specific) client without removing it from config. The server stays in your config file but won't be loaded by the client.

  • mcpm enable <name> — Re-enable a previously disabled server.

  • mcpm alias — Create short aliases for long server names. mcpm alias fs io.github.domdomegg/filesystem-mcp lets you use fs in future commands. Stored in ~/.mcpm/aliases.json.

  • mcpm completions <shell> — Generate tab-completion scripts for bash, zsh, and fish. Pipe into your shell config for instant command/option completion.

Improvements

  • mcpm list now shows server status — Each server displays as active or disabled in a new Status column, so you can see at a glance what's running.

  • --client flag on disable/enable — Target a specific client (--client cursor) instead of toggling across all detected clients.

Security hardening

  • MCP server tool path allowlist and health check environment sandboxing (#1)
  • Client ID validation before type casts (rejects unknown --client values with clear error)
  • Strict alias name validation: alphanumeric + hyphens only, max 64 chars, blocks __proto__/constructor/prototype
  • --remove path validates alias names before filesystem operations

Internal

  • Shared toggle.ts handler eliminates duplication between disable/enable (single-pass config read per client)
  • 739 tests (up from 687), all passing
  • Updated docs: README, ARCHITECTURE.md, CLAUDE.md

Install / upgrade

npm install -g @getmcpm/cli@0.2.0

Full changelog: v0.1.3...v0.2.0

v0.1.3

30 Mar 10:35
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Full Changelog: v0.1.2...v0.1.3

v0.1.2

30 Mar 08:19
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Full Changelog: v0.1.1...v0.1.2

v0.1.0 — Initial Release

30 Mar 03:30

Choose a tag to compare