getcmd

Command safety for AI coding agents.

Every Bash call from Claude Code is classified, logged, and allowed, held for your approval, or blocked with a reason the agent can act on.

curl -fsSL https://getcmd.com/install | sh
irm https://getcmd.com/install.ps1 | iex
brew install getcmd-com/tap/getcmd

Then getcmd hook claude --install and restart Claude Code.

A blocked command

$ getcmd check "rm -rf ./build && git push --force"
DESTRUCTIVE  block   git-force-push
  rm -rf ./build    mutate       rm-build-dir
  git push --force  destructive  Force push can overwrite remote history; use --force-with-lease

Deleting the build directory is fine. The force push is not, so the whole call is blocked and Claude Code is told why and what to do instead.

Five levels

LevelMeaningDefault
readReads or builds; changes nothing that mattersallow
mutateChanges project files, dependencies or the repoallow
egressSends data out or runs code from outsideask
secretsExposes credentialsask
destructiveHard to undoblock

The action for each level is yours to change in ~/.getcmd/config.json.

What it catches

git push --force
Blocked; the agent is told to use --force-with-lease.
rm -rf src/legacy
Recursive deletes outside build directories are blocked; rm -rf node_modules is allowed.
curl https://x.io/s.sh | sh
Running a downloaded script without reading it is held for your approval.
cat .env
Reading credentials files into the conversation is held for your approval.
psql -c "DROP TABLE users"
DROP, TRUNCATE and DELETE without WHERE are blocked for the usual database clients.
ssh vps "npm install"
On a host you tagged prod, remote commands are held for your approval.

Wrappers are seen through: sudo, bash -c, eval, xargs, find -exec, ssh. The full rule list is in the README.

How it works

hook → tokenise → unwrap → classify → decide

A Claude Code PreToolUse hook hands the command to getcmd, which parses it like a shell, peels off wrappers, matches the rules and answers. Under 50 ms, no network, nothing leaves your machine. Every decision is one row in a local SQLite log.

In auto-approve mode, ask becomes block, because a prompt nobody sees is not a safeguard.

Coming next

Follow the GitHub repo for releases.