| guard_shell.py | beforeShellExecution | deny: rm -rf / or ~, disk wipes, fork bombs, curl ... | sh, cat .env, bare printenv. ask: force push, reset --hard, DROP TABLE, terraform destroy, kubectl delete, npm publish, docker system prune, sudo, commands with a secret in them. Everything else is allowed. |
| guard_mcp.py | beforeMCPExecution (failClosed: true) | allow-list of MCP servers by mcp_server_name; unknown servers are denied; write-like tools (create_, delete_, send_, merge_...) ask first; secrets in tool arguments ask first. |
| guard_read.py | beforeReadFile | keeps .env, *.pem, SSH keys, .npmrc, .netrc, *secrets*.json and any file containing an API key or private key out of the model context. .env.example and *.pub stay readable. |
| scan_prompt.py | beforeSubmitPrompt | blocks a prompt that contains an API key, token, private key or a database URL with a password (OpenAI, Anthropic, AWS, GitHub, Stripe, Slack, Google, JWT). The secret itself is never printed. |
| format_on_edit.py | afterFileEdit | runs the first installed formatter for the file (ruff/black, prettier from your node_modules, gofmt, rustfmt). Missing tools are skipped silently. |
| stop_tests.py | stop (loop_limit: 3) | when the agent says it's done, runs your test command; if it fails, the failure tail goes back to the agent as a follow-up so it keeps fixing (max 3 rounds). Off until you set stop.test_command. |
| session_context.py | sessionStart | adds a short briefing to each new chat: git branch, uncommitted files, last commit, a warning on main, and which instruction files (AGENTS.md, CLAUDE.md, rules) to read. |
| audit_log.py | shell, MCP, edits, stop | appends one JSON line per event to .cursor/hooks/logs/audit.jsonl, with secrets redacted and long fields cut. |