Summary
codebase-memory-mcp uninstall --help does not print help — it performs a real, destructive uninstall: it removes agent configurations (Claude Code, Codex, Gemini, VS Code, Cursor, …), skills, hooks, and deletes the installed binary, then exits 0.
This happened to me on a real machine: I ran uninstall --help to look up the flag for selective removal, and it wiped the tool from all five detected agents and deleted the binary.
Environment
- codebase-memory-mcp 0.9.0 (release binary, UI variant)
- macOS (darwin/arm64)
Reproduction (safe, uses a throwaway HOME)
FAKEHOME=$(mktemp -d)
mkdir -p "$FAKEHOME/.local/bin" "$FAKEHOME/.claude"
echo fake-binary > "$FAKEHOME/.local/bin/codebase-memory-mcp"
echo '{"mcpServers":{"codebase-memory-mcp":{"command":"x"}}}' > "$FAKEHOME/.claude/.mcp.json"
HOME="$FAKEHOME" codebase-memory-mcp uninstall --help
Output:
codebase-memory-mcp uninstall
Claude Code: removed 0 skill(s)
removed MCP config entry
removed PreToolUse + SessionStart + SubagentStart hooks
Removed .../.local/bin/codebase-memory-mcp
Uninstall complete.
Exit code 0. The fake binary is gone and .claude/.mcp.json is emptied — help was never printed.
Root cause
Three compounding issues:
- Subcommand dispatch matches before global
--help — handle_subcommand in src/main.c scans argv positionally, so in uninstall --help the subcommand matches at i=1 and dispatches before the --help check ever sees i=2.
cbm_cmd_uninstall silently ignores unknown flags — src/cli/cli.c#L4087-L4094 only looks for -y/-n (via parse_auto_answer) and --dry-run; anything else — --help, -h, or a typo like --dryrun — falls through to a full uninstall. Note the typo case is arguably worse: uninstall --dryrun performs a real uninstall when the user explicitly asked for a dry run.
- No confirmation gate on the destructive path — the agent-config removal and binary deletion at src/cli/cli.c#L4104-L4137 run unconditionally. The only
prompt_yn is for index deletion. prompt_yn itself fails closed on non-TTY stdin (good), but nothing destructive is behind it — so even uninstall -n ("answer no to everything") removes all configs and the binary.
The same unknown-flag blindness affects the other mutating subcommands: install --help silently rewrites agent configs, and update --help downloads and replaces the binary.
Expected behavior
uninstall --help / install --help / update --help print usage and exit 0 without touching anything.
uninstall <unknown-flag> errors out with usage instead of running.
uninstall asks for confirmation (or requires -y when non-interactive) before removing configs and the binary; -n aborts.
Proposed fix
I have a patch ready and will open a PR referencing this issue shortly:
- a
--help/-h check at the top of cbm_cmd_install, cbm_cmd_uninstall, and cbm_cmd_update that prints per-command usage and exits 0;
- strict flag validation in
cbm_cmd_uninstall (unknown flag → error + usage, exit 1);
- a
prompt_yn confirmation gate in front of the destructive uninstall path (skipped for --dry-run; -y auto-confirms as before, matching the existing scripts/smoke-test.sh phase 6b invocation uninstall --dry-run -y);
- regression tests in
tests/test_cli.c.
Summary
codebase-memory-mcp uninstall --helpdoes not print help — it performs a real, destructive uninstall: it removes agent configurations (Claude Code, Codex, Gemini, VS Code, Cursor, …), skills, hooks, and deletes the installed binary, then exits 0.This happened to me on a real machine: I ran
uninstall --helpto look up the flag for selective removal, and it wiped the tool from all five detected agents and deleted the binary.Environment
Reproduction (safe, uses a throwaway HOME)
Output:
Exit code 0. The fake binary is gone and
.claude/.mcp.jsonis emptied — help was never printed.Root cause
Three compounding issues:
--help—handle_subcommandin src/main.c scans argv positionally, so inuninstall --helpthe subcommand matches ati=1and dispatches before the--helpcheck ever seesi=2.cbm_cmd_uninstallsilently ignores unknown flags — src/cli/cli.c#L4087-L4094 only looks for-y/-n(viaparse_auto_answer) and--dry-run; anything else —--help,-h, or a typo like--dryrun— falls through to a full uninstall. Note the typo case is arguably worse:uninstall --dryrunperforms a real uninstall when the user explicitly asked for a dry run.prompt_ynis for index deletion.prompt_ynitself fails closed on non-TTY stdin (good), but nothing destructive is behind it — so evenuninstall -n("answer no to everything") removes all configs and the binary.The same unknown-flag blindness affects the other mutating subcommands:
install --helpsilently rewrites agent configs, andupdate --helpdownloads and replaces the binary.Expected behavior
uninstall --help/install --help/update --helpprint usage and exit 0 without touching anything.uninstall <unknown-flag>errors out with usage instead of running.uninstallasks for confirmation (or requires-ywhen non-interactive) before removing configs and the binary;-naborts.Proposed fix
I have a patch ready and will open a PR referencing this issue shortly:
--help/-hcheck at the top ofcbm_cmd_install,cbm_cmd_uninstall, andcbm_cmd_updatethat prints per-command usage and exits 0;cbm_cmd_uninstall(unknown flag → error + usage, exit 1);prompt_ynconfirmation gate in front of the destructive uninstall path (skipped for--dry-run;-yauto-confirms as before, matching the existingscripts/smoke-test.shphase 6b invocationuninstall --dry-run -y);tests/test_cli.c.