Gemini CLI

Gemini CLI hooks: settings.json, BeforeTool, AfterTool, exit codes and /hooks

How do I set up hooks in Gemini CLI?

Add a hooks object to .gemini/settings.json (project) or ~/.gemini/settings.json (user). Each event, such as BeforeTool or AfterTool, holds a list of groups with a matcher and a hooks array of command hooks. A hook gets JSON on stdin and replies with JSON on stdout. Exit 0 with a deny decision, or exit 2 with a reason on stderr, blocks the action. Use /hooks panel to see what is loaded.

Compare: hooks in every AI coding agent →

Gemini CLI settings change often

Get one email a week when a setting, flag or permission rule changes, checked against the vendor docs.

Where hooks are configured

Gemini CLI reads hooks from these places, highest precedence first:

  • Project: .gemini/settings.json in the current directory.
  • User: ~/.gemini/settings.json.
  • System: /etc/gemini-cli/settings.json.
  • Extensions: hooks that installed extensions define.

Example: check every file write

.gemini/settings.json

{
  "hooks": {
    "BeforeTool": [
      {
        "matcher": "write_file|replace",
        "hooks": [
          {
            "name": "security-check",
            "type": "command",
            "command": "$GEMINI_PROJECT_DIR/.gemini/hooks/security.sh",
            "timeout": 5000
          }
        ]
      }
    ]
  }
}
  • type: required. Only "command" is supported today.
  • command: the shell command to run.
  • name: optional. Used in logs and by /hooks enable and /hooks disable.
  • timeout: optional, in milliseconds. The default is 60000 (60 seconds).
  • A group can set "sequential" to run its hooks one after another instead of in parallel.

Hook events

  • SessionStart and SessionEnd
  • BeforeAgent and AfterAgent
  • BeforeModel and AfterModel
  • BeforeToolSelection
  • BeforeTool and AfterTool
  • PreCompress
  • Notification

How matchers work

  • BeforeTool and AfterTool: the matcher is a regex tested against the tool name, such as "write_.*".
  • Lifecycle events: the matcher is an exact string, such as "startup".
  • "*" or an empty string matches everything.
  • Built-in tools use names like read_file and run_shell_command. MCP tools are named mcp_<server_name>_<tool_name>.

Input, output and exit codes

Every hook gets JSON on stdin with session_id, transcript_path, cwd, hook_event_name and timestamp, plus fields for its event. Stdout must contain only the final JSON object. If that JSON is invalid, Gemini CLI defaults to allow.

  • Exit 0: success. Stdout is parsed as JSON. The docs prefer this for all logic, including intentional blocks.
  • Exit 2: system block. The action is aborted and stderr is the reason.
  • Any other code: a non-fatal warning. The action goes ahead with the original parameters.
  • decision: "allow" or "deny" ("block" also works), with reason as the feedback when you deny.
  • continue: false stops the agent loop. stopReason is shown to the user.
  • systemMessage: a message shown to the user.
  • hookSpecificOutput: event fields such as additionalContext or a rewritten tool_input for BeforeTool.

Manage hooks with /hooks

  • /hooks panel shows the configured hooks.
  • /hooks enable-all and /hooks disable-all toggle every hook.
  • /hooks enable <name> and /hooks disable <name> toggle one hook.

Gemini CLI fingerprints project hooks. If a hook's name or command changes, for example after a git pull, it is treated as a new, untrusted hook and you are warned before it runs.

Get Gemini CLI settings changes by email

When a setting, flag or permission rule in this guide changes, it goes in the weekly AgentAtlas update, checked against the vendor docs. One email a week.

Sources

More on Gemini CLI

More Gemini CLI guides

Other guides

How to allow Cursor to run all commands: Run Everything, allowlist and sandboxHow to allow Claude Code to run all commands: permission modes, allow rules and skip permissionsClaude Code permissions: allow, ask and deny rules, rule syntax and allowed toolsCodex CLI: approval and sandbox modesCursor Privacy Mode: telemetry, training and data retentionClaude Code telemetry and data retention: what is sent and how to turn it offCLAUDE.md: where it goes, how it loads, and how it works with AGENTS.mdClaude Code hooks: format on save, block risky edits, get notifiedClaude Code subagents: create one, limit its tools, and call itAdd MCP servers to Cursor with mcp.json: Keep files out of Cursor with .cursorignore: Configure Codex with config.toml: Add MCP servers to Claude Code (claude mcp add, .mcp.json, scopes): Claude Code custom slash commands and skills (SKILL.md): GitHub Copilot custom instructions: Adding MCP servers to GitHub Copilot: Claude Code settings.json: file locations, precedence, and key settingsClaude Code plugins and marketplaces: install, create, and shareConfiguring OpenCode with opencode.json: Cline Rules: workspace, global, and conditional rulesKiro steering files: .kiro/steering, inclusion modes, and AGENTS.mdZed agent: instruction files, MCP servers, tool permissions, and ACP agentsCursor CLI: install, headless mode, permissions and CIAider: CONVENTIONS.md, .aider.conf.yml and API keysJunie guidelines, MCP and the Action Allowlist: Amp AGENTS.md, settings.json and MCP: Configure Goose extensions, hints, recipes and permissions: Customize OpenHands with skills, AGENTS.md, setup.sh and MCP: Configure Factory Droid CLI: AGENTS.md, settings.json, autonomy, custom droids and MCPConfigure Qwen Code: settings.json, providers, QWEN.md, MCP and approval modesCursor hooks: hooks.json, beforeShellExecution, afterFileEdit and exit codesCursor sandbox: sandbox.json, network allowlist and run modesCursor settings: settings.json, Cursor Settings and the ~/.cursor config filesCursor browser agent: @browser, browser automation and approval modesCursor subagents: .cursor/agents, frontmatter, built-in Explore and BrowserCursor telemetry and OpenTelemetry export (Privacy Mode, OTLP, Analytics API): Cursor rules setup: project, user and Team Rules, .mdc frontmatter, globs and AGENTS.mdClaude Code headless mode: claude -p, --output-format json, --bare and CI flagsClaude Code statusline: custom status bar in settings.json with context %, cost and git branchClaude Code /model: switch models, aliasesClaude Code /cost and /usage: check token spend, usage limits and reduce costsClaude Code VS Code extension: install, shortcuts, settings and /ideCodex AGENTS.md: global, project and override instruction files explainedCodex MCP servers: codex mcp add and [mcp_servers] in config.tomlCodex sandbox modes: read-only, workspace-write, danger-full-access and network accesscodex exec: run Codex non-interactively in scripts and CI with JSON outputCodex skills: create SKILL.md, skill folder locations and $skill invocationcopilot-setup-steps.yml: set up the GitHub Copilot cloudGitHub Copilot CLI permissions: --allow-tool, --deny-tool, --allow-all-tools and trusted directoriesGitHub Copilot custom agents: .github/agents/*.agent.md profiles, tools and frontmatterGitHub Copilot code review settings: automatic PR reviews, rulesets, effort level and approvalsOpenCode MCP Server Setup: Local and Remote Servers in opencode.jsonOpenCode Permissions: Allow, Ask or Deny Bash, Edit and WebfetchOpenCode Custom Agents and Subagents: Markdown Files, Modes and @ MentionsCline MCP Setup: cline_mcp_settings.json for Local and Remote ServersCline Auto Approve and YOLO Mode: Run Commands and Edits Without PromptsCline Skills: SKILL.md Location, Format and Slash Command UseAmp MCP Setup: amp mcp add, amp.mcpServers and Workspace ApprovalAmp AGENTS.md: File Locations, @ Mentions and Glob-Scoped GuidanceAmp Skills: SKILL.md Folders, amp skill add and Search OrderKiro MCP Setup: .kiro/settings/mcp.json, autoApprove and OAuthKiro Hooks: .kiro/hooks JSON, PreToolUse, PostFileSave and StopKiro Permissions: permissions.yaml Allow, Ask and Deny RulesFactory Droid MCP Setup: droid mcp add, mcp.json Locations and /mcpFactory Droid Hooks: hooks.json, PreToolUse Matchers and Exit CodesFactory Droid Custom Droids (Subagents): .factory/droids Markdown FilesJunie MCP Setup: .junie/mcp/mcp.json for CLI and /mcp CommandJunie Brave Mode and Action Allowlist: Auto-Approve Commands in Junie CLIJunie Custom Slash Commands: .junie/commands Markdown Files and Argumentsgoose .goosehints and AGENTS.md: Global and Project Instructionsgoose Permission Modes: GOOSE_MODE auto, approve, smart_approve and chatgoose Recipes: recipe.yaml Format, Parameters and goose run --recipeZed Agent Tool Permissions: Auto-Approve Terminal Commands with tool_permissionsUse Claude, Codex and Gemini CLI in Zed: External Agents and agent_serversZed with Ollama, LM Studio and llama.cpp: Local Model Setup and Context LengthMCP 2026-07-28 Migration Guide: Stateless Protocol, No Sessions, server/discover, MRTR, and SDK v2 UpgradeSubagents and Custom Agents Compared: Claude Code vs Codex vs Cursor vs Gemini CLI vs GitHub CopilotAllow all commands in any AI coding agent: Cursor, Claude Code, Codex, Gemini CLI, Copilot CLI and 7 moreAdd an MCP server to any AI coding agent: Claude Code, Cursor, Codex, Gemini CLI, VS Code and 8 moreSettings file locations for every AI coding agent: Claude Code, Cursor, Codex, Gemini CLI, OpenCode, Qwen Code, Amp and Factory DroidRules and instruction files in every AI coding agent: .cursor/rules, CLAUDE.md, AGENTS.md, GEMINI.md, Copilot instructions and moreGitHub Copilot hooks: .github/hooks/*.json for Copilot CLI and the cloud agentHooks in every AI coding agent: Claude Code, Cursor, Gemini CLI, GitHub Copilot, Kiro and Factory DroidAgent Skills (SKILL.md) in every AI coding agent: Claude Code, Codex, Cline, Amp and OpenHandsHow to deploy a remote MCP server (Streamable HTTP): Cloudflare Workers, Vercel, Railway and moreHeadless mode in every AI coding agent: claude -p, codex exec, gemini -p, Cursor agent -p and copilot -p for scripts and CIClaude Code sandbox: /sandbox, sandbox.enabled, allowedDomains, excludedCommands and strict modeSandbox modes in every AI coding agent: Claude Code, Cursor, Codex and Gemini CLI compared

Reviewed Oct 18, 2026. Settings change often; the linked vendor docs are the source of truth.