# Gemini CLI Administration & Architecture Guide

Gemini CLI is a TypeScript monorepo that implements an AI-powered coding agent for the terminal. It connects to the Gemini family of models via the Google GenAI SDK, wraps model interactions in a tool-calling agent loop, and presents results through a React/Ink terminal UI. The project spans seven packages — a CLI frontend, a core engine, an SDK for programmatic use, an A2A protocol server, a devtools inspector, a VS Code companion extension, and a shared test utilities library.

This guide covers the architecture, configuration internals, deployment, security model, extension system, and operational concerns for administrators, platform engineers, and contributors.

---

## Architecture Overview

### Monorepo Structure

```
google-gemini/gemini-cli/
├── packages/
│   ├── cli/           # Terminal UI (React/Ink), slash commands, config
│   ├── core/          # Agent loop, model client, tools, hooks, sandbox
│   ├── sdk/           # Programmatic agent API (@google/gemini-cli-sdk)
│   ├── a2a-server/    # Agent-to-Agent protocol server (Express + SSE)
│   ├── devtools/      # Chrome DevTools-style inspector
│   ├── vscode-ide-companion/  # VS Code extension for IDE integration
│   └── test-utils/    # Shared test harness, fixtures, mock MCP servers
├── docs/              # User-facing documentation (markdown)
├── schemas/           # JSON Schema for settings.json
├── scripts/           # Build, release, and utility scripts
├── evals/             # Component evaluation tests
├── integration-tests/ # Cross-package integration tests
├── memory-tests/      # Memory leak and regression tests
├── perf-tests/        # Performance benchmarks
└── sea/               # Single Executable Application packaging
```

### Package Dependency Graph

```
cli → core
sdk → core
a2a-server → core
devtools → core (events)
vscode-ide-companion → (standalone)
test-utils → core
```

The `core` package is the foundation. It owns the agent loop, model communication, tool registry, hook system, sandbox management, and configuration. All other packages depend on it.

### Runtime Architecture

```
User Input
    │
    ▼
┌─────────────────────────────────┐
│  CLI (packages/cli)              │
│  React/Ink TUI                   │
│  ├── CommandService              │
│  ├── SlashCommandResolver        │
│  ├── ExtensionManager            │
│  └── LoadedSettings              │
└──────────────┬──────────────────┘
               │
               ▼
┌─────────────────────────────────┐
│  Core (packages/core)            │
│  ├── Config                      │
│  ├── GeminiChat (agent loop)     │
│  │   ├── GeminiClient            │
│  │   ├── BaseLlmClient           │
│  │   └── ContentGenerator        │
│  ├── Scheduler                   │
│  │   ├── Policy Engine           │
│  │   ├── Confirmation Bus        │
│  │   └── Tool Modifier           │
│  ├── HookSystem                  │
│  ├── Tool Registry               │
│  ├── Sandbox Manager             │
│  └── Services                    │
│       ├── ShellExecutionService  │
│       ├── FileDiscoveryService   │
│       ├── GitService             │
│       ├── ModelConfigService     │
│       └── ChatRecordingService   │
└──────────────┬──────────────────┘
               │
               ▼
┌─────────────────────────────────┐
│  Google GenAI SDK                │
│  Gemini API / Vertex AI          │
└─────────────────────────────────┘
```

### Key Architectural Decisions

1. **React/Ink for TUI**: The terminal UI uses React with the Ink renderer, enabling component-based rendering with state management, effects, and context
2. **Event-driven tool execution**: Tools execute through a Scheduler that manages confirmation, policy checks, hooks, and state transitions via an EventEmitter-based message bus
3. **Layered configuration**: Four config scopes (System, SystemDefaults, User, Workspace) merge via deep-merge with more-specific scopes winning
4. **Model routing via strategies**: A `CompositeStrategy` chains multiple routing strategies (ApprovalMode, Classifier, Override, Default, Fallback) to select the optimal model per request
5. **File-based session persistence**: Conversations are stored as JSON files in the project's temp directory, enabling resume, replay, and recording

---

## Component Inventory

### packages/core

The engine. Contains all model communication, tool execution, and agent orchestration logic.

| Component | File | Purpose |
|---|---|---|
| `Config` | `config/config.ts` | Central configuration object. Holds session, model, sandbox, auth, and path settings |
| `GeminiChat` | `core/geminiChat.ts` | Main agent loop. Orchestrates model calls, tool execution, and conversation flow |
| `GeminiClient` | `core/client.ts` | Manages chat sessions with the Gemini API. Handles initialization, history, streaming |
| `BaseLlmClient` | `core/baseLlmClient.ts` | Low-level LLM communication. Handles retries, content generation, JSON generation, embeddings |
| `ContentGenerator` | `core/contentGenerator.ts` | Creates the GenAI client with auth, proxy, and base URL configuration |
| `Turn` | `core/turn.ts` | Represents a single model turn with content parts, tool calls, and metadata |
| `Scheduler` | `scheduler/scheduler.ts` | Manages parallel tool execution, confirmation flow, and state transitions |
| `SchedulerStateManager` | `scheduler/state-manager.ts` | Tracks tool call states through their lifecycle |
| `HookSystem` | `hooks/hookSystem.ts` | Fires lifecycle events and aggregates hook results |
| `HookRegistry` | `hooks/hookRegistry.ts` | Stores and retrieves hook configurations |
| `HookRunner` | `hooks/hookRunner.ts` | Executes hook commands as child processes |
| `HookAggregator` | `hooks/hookAggregator.ts` | Merges results from multiple hooks for the same event |
| `Logger` | `core/logger.ts` | Manages conversation logs, checkpoints, and session persistence |
| `ModelConfigService` | `services/modelConfigService.ts` | Resolves model aliases, applies config overrides, manages model definitions |
| `ShellExecutionService` | `services/shellExecutionService.ts` | Executes shell commands with sandbox wrapping and output capture |
| `FileDiscoveryService` | `services/fileDiscoveryService.ts` | Finds files using ripgrep for fast codebase search |
| `GitService` | `services/gitService.ts` | Git operations: status, diff, log, commit |
| `WorktreeService` | `services/worktreeService.ts` | Manages git worktrees for isolated execution |
| `ChatRecordingService` | `services/chatRecordingService.ts` | Records and replays conversations for testing |
| `LoopDetectionService` | `services/loopDetectionService.ts` | Detects and breaks infinite agent loops |
| `ExecutionLifecycleService` | `services/executionLifecycleService.ts` | Manages execution phases: initialize, run, finalize |
| `SandboxedFileSystemService` | `services/sandboxedFileSystemService.ts` | File operations with sandbox path validation |
| `LocalSandboxManager` | `services/sandboxManager.ts` | Manages Docker/Podman sandbox containers |
| `NoopSandboxManager` | `services/sandboxManager.ts` | Pass-through sandbox for unsandboxed execution |
| `FolderTrustDiscoveryService` | `services/FolderTrustDiscoveryService.ts` | Scans workspace for configurations before trust is granted |
| `PolicyEngine` | `policy/policy-engine.ts` | Evaluates tool calls against policy rules |
| `CoreEventEmitter` | `utils/events.ts` | Typed event bus for internal communication |
| `SimpleExtensionLoader` | `utils/extensionLoader.ts` | Loads and initializes extensions from manifests |
| `SchemaValidator` | `utils/schemaValidator.ts` | JSON Schema validation for settings and configs |
| `CacheService` | `utils/cache.ts` | TTL-based cache with Map or WeakMap storage backends |
| `FileExclusions` | `utils/ignorePatterns.ts` | Manages .gitignore and custom file exclusion patterns |
| `WorkspaceContext` | `utils/workspaceContext.ts` | Resolves and validates workspace directories |

> [!NOTE]
> The `Config` class at `packages/core/src/config/config.ts` is the single most important class in the system. It initializes from `ConfigParameters`, manages auth, model selection, sandbox configuration, tool registry, MCP servers, hook system, and policy engine. Nearly every service receives a `Config` instance.

### packages/cli

The terminal frontend. Owns the React/Ink UI, slash commands, settings loading, and extension management.

| Component | File | Purpose |
|---|---|---|
| `App.tsx` | `ui/App.tsx` | Root React component |
| `LoadedSettings` | `config/settings.ts` | Loads and merges settings across all scopes |
| `ExtensionManager` | `config/extension-manager.ts` | Installs, loads, validates, and manages extensions |
| `ExtensionRegistryClient` | `config/extensionRegistryClient.ts` | Queries the extension registry |
| `LoadedTrustedFolders` | `config/trustedFolders.ts` | Manages folder trust decisions |
| `CommandService` | `services/CommandService.ts` | Registers and dispatches slash commands |
| `SlashCommandResolver` | `services/SlashCommandResolver.ts` | Resolves slash command names to handlers, with conflict detection |
| `BuiltinCommandLoader` | `services/BuiltinCommandLoader.ts` | Loads built-in slash commands |
| `FileCommandLoader` | `services/FileCommandLoader.ts` | Loads TOML-based custom commands from `.gemini/commands/` |
| `SkillCommandLoader` | `services/SkillCommandLoader.ts` | Loads skill-based commands |
| `McpPromptLoader` | `services/McpPromptLoader.ts` | Loads prompts from MCP servers as slash commands |
| `ActivityLogger` | `utils/activityLogger.ts` | Logs session activity events |
| `SessionSelector` | `utils/sessionUtils.ts` | Lists, selects, and deletes sessions |
| `PersistentState` | `utils/persistentState.ts` | Manages persistent UI state across sessions |

> [!IMPORTANT]
> The `ExtensionManager` at `packages/cli/src/config/extension-manager.ts` is a critical class. It extends `ExtensionLoader`, handles installation from npm/local paths, validates manifests, and manages enable/disable state. It enforces that extensions are loaded exactly once per session to prevent resource leaks.

### packages/sdk

Programmatic API for building custom agents on top of the Gemini CLI engine.

| Component | File | Purpose |
|---|---|---|
| `GeminiCliAgent` | `agent.ts` | Creates and resumes agent sessions |
| `GeminiCliSession` | `session.ts` | Manages a single conversation session with streaming |
| `SdkTool` | `tool.ts` | Base class for custom tools |
| `SdkToolInvocation` | `tool.ts` | Represents a single tool invocation with parameters |
| `ModelVisibleError` | `tool.ts` | Error class for errors the model should see |
| `SdkAgentFilesystem` | `fs.ts` | Sandbox-aware file system operations |
| `SdkAgentShell` | `shell.ts` | Shell command execution for SDK agents |

### packages/a2a-server

Agent-to-Agent protocol server. Enables Gemini CLI to act as a backend agent accessible via HTTP/SSE.

| Component | File | Purpose |
|---|---|---|
| `app.ts` | `http/app.ts` | Express app with A2A routes |
| `server.ts` | `http/server.ts` | HTTP server lifecycle |
| `CommandRegistry` | `commands/command-registry.ts` | A2A command registration |
| `InitCommand` | `commands/init.ts` | Initializes agent context |
| `MemoryCommand` | `commands/memory.ts` | Memory operations (show, add, refresh, list) |
| `RestoreCommand` | `commands/restore.ts` | Checkpoint restore |
| `ExtensionsCommand` | `commands/extensions.ts` | Extension management via A2A |

Events are streamed to clients via Server-Sent Events using the `CoderAgentEvent` enum:

- `TextContentEvent`: Text output from the model
- `ToolCallConfirmationEvent`: Tool requiring approval
- `ToolCallUpdateEvent`: Tool execution status
- `StateChangeEvent`: Task state transitions
- `ThoughtEvent`: Model thinking/reasoning
- `CitationEvent`: Source citations

### packages/devtools

Chrome DevTools-style inspector for debugging Gemini CLI sessions.

| Component | File | Purpose |
|---|---|---|
| `DevTools` | `src/index.ts` | EventEmitter-based devtools server |
| `App.tsx` | `client/src/App.tsx` | React client for the inspector UI |

### packages/vscode-ide-companion

VS Code extension that bridges the IDE with Gemini CLI.

| Component | File | Purpose |
|---|---|---|
| `IDEServer` | `src/ide-server.ts` | Local HTTP server for MCP transport |
| `DiffManager` | `src/diff-manager.ts` | Manages file diffs for review |
| `OpenFilesManager` | `src/open-files-manager.ts` | Tracks open files in the editor |

The IDE server exposes MCP endpoints (`POST /mcp`, `GET /mcp`) with CORS protection that only allows connections from `localhost`/`127.0.0.1`.

---

## System Requirements

### Runtime Requirements

| Requirement | Version | Notes |
|---|---|---|
| Node.js | >= 20.0.0 | Required. Checked at startup |
| npm | >= 10 | Ships with Node 20 |
| Git | Any recent | Required for worktrees, checkpointing, git tools |
| Docker or Podman | Optional | Required for container-based sandboxing |

### Build Requirements

| Tool | Version | Notes |
|---|---|---|
| Node.js | >= 20 | Monorepo uses npm workspaces |
| TypeScript | 5.x | Strict mode enabled |
| Vitest | Latest | Test runner |
| React | 18+ | For Ink-based TUI |

### Platform Support

| Platform | Sandbox Options |
|---|---|
| macOS | Docker, Podman, sandbox-exec (seatbelt profiles) |
| Linux | Docker, Podman |
| Windows | Docker, native Windows sandbox |

---

## Configuration Reference

### Settings Schema

The complete settings schema is defined at `schemas/settings.schema.json`. Below is the authoritative reference for all configuration categories.

> [!TIP]
> Reference the JSON schema URL in your settings file for IDE autocompletion: `"$schema": "https://raw.githubusercontent.com/google-gemini/gemini-cli/main/schemas/settings.schema.json"`

### Settings Scope Hierarchy

```
System Settings (GEMINI_CLI_SYSTEM_SETTINGS_PATH)
    ↓ overrides
System Defaults (GEMINI_CLI_SYSTEM_DEFAULTS_PATH)
    ↓ overrides
User Settings (~/.gemini/settings.json)
    ↓ overrides
Workspace Settings (.gemini/settings.json)
```

> [!WARNING]
> Admin policy paths (`adminPolicyPaths`) set at the System scope cannot be overridden by workspace settings. This is the mechanism for enforcing organization-wide security policies.

### General Settings

| Key | Type | Default | Description |
|---|---|---|---|
| `general.vimMode` | boolean | `false` | Enable Vim keybindings |
| `general.preferredEditor` | string | - | Editor for `/editor` command |
| `general.defaultApprovalMode` | enum | `"default"` | `default`, `auto_edit`, `plan` |
| `general.devtools` | boolean | `false` | Enable DevTools inspector |
| `general.enableAutoUpdate` | boolean | `true` | Auto-update checks |
| `general.enableAutoUpdateNotification` | boolean | `true` | Update notifications |
| `general.enableNotifications` | boolean | `false` | Terminal notifications |
| `general.notificationMethod` | enum | `"auto"` | `auto`, `osc9`, `osc777`, `bell` |
| `general.checkpointing.enabled` | boolean | `false` | Git checkpoint snapshots |
| `general.plan.enabled` | boolean | `true` | Enable Plan Mode |
| `general.plan.directory` | string | - | Plan artifacts directory |
| `general.plan.modelRouting` | boolean | `true` | Auto Pro/Flash switching |
| `general.retryFetchErrors` | boolean | `true` | Retry on fetch failures |
| `general.maxAttempts` | number | `10` | Max model request retries (cap: 10) |
| `general.topicUpdateNarration` | boolean | `true` | Structured progress reporting |
| `general.debugKeystrokeLogging` | boolean | `false` | Log keystrokes |
| `general.sessionRetention.enabled` | boolean | `true` | Auto session cleanup |
| `general.sessionRetention.maxAge` | string | `"30d"` | Max session age |
| `general.sessionRetention.maxCount` | number | - | Max sessions to keep |
| `general.sessionRetention.minRetention` | string | `"1d"` | Minimum retention |

### Model Settings

| Key | Type | Default | Description |
|---|---|---|---|
| `model.name` | string | - | Model name override |
| `model.maxSessionTurns` | number | `-1` | Max turns per session (-1 = unlimited) |
| `model.compressionThreshold` | number | `0.5` | Context compression trigger (0.0-1.0) |
| `model.disableLoopDetection` | boolean | `false` | Disable loop detection |
| `model.skipNextSpeakerCheck` | boolean | `true` | Skip speaker check |
| `model.summarizeToolOutput` | object | - | Per-tool output summarization config |

### Model Configuration System

The `modelConfigs` setting controls model aliases, overrides, definitions, ID resolutions, and fallback chains.

**Key model aliases:**

| Alias | Base Model | Purpose |
|---|---|---|
| `chat-base` | - | Base chat config (temperature: 1, topP: 0.95, thinking enabled) |
| `chat-base-2.5` | `chat-base` | Gemini 2.5 thinking budget: 8192 |
| `chat-base-3` | `chat-base` | Gemini 3 thinking level: HIGH |
| `classifier` | `gemini-2.5-flash-lite` | Task complexity classification |
| `prompt-completion` | `gemini-2.5-flash-lite` | Prompt autocomplete |
| `web-search` | `gemini-3-flash-preview` | Google Search integration |
| `web-fetch` | `gemini-3-flash-preview` | URL content fetching |
| `loop-detection` | `gemini-3-flash-preview` | Infinite loop detection |
| `summarizer-default` | `gemini-2.5-flash-lite` | Context summarization |

**Model families and tiers:**

| Model ID | Tier | Family | Preview | Thinking |
|---|---|---|---|---|
| `gemini-3.1-pro-preview` | Pro | gemini-3 | Yes | Yes |
| `gemini-3-pro-preview` | Pro | gemini-3 | Yes | Yes |
| `gemini-3-flash-preview` | Flash | gemini-3 | Yes | No |
| `gemini-3.1-flash-lite-preview` | Flash-Lite | gemini-3 | Yes | No |
| `gemini-2.5-pro` | Pro | gemini-2.5 | No | No |
| `gemini-2.5-flash` | Flash | gemini-2.5 | No | No |
| `gemini-2.5-flash-lite` | Flash-Lite | gemini-2.5 | No | No |

**Fallback chains:**

The system defines three fallback chains (`preview`, `default`, `lite`) that determine retry behavior when a model is unavailable:

- **Preview chain**: `gemini-3-pro-preview` → `gemini-3-flash-preview`
- **Default chain**: `gemini-2.5-pro` → `gemini-2.5-flash`
- **Lite chain**: `gemini-2.5-flash-lite` → `gemini-2.5-flash` → `gemini-2.5-pro`

### UI Settings

| Key | Type | Default | Description |
|---|---|---|---|
| `ui.theme` | string | - | UI theme name |
| `ui.autoThemeSwitching` | boolean | `true` | Auto light/dark switching |
| `ui.terminalBackgroundPollingInterval` | number | `60` | Background color poll interval (seconds) |
| `ui.customThemes` | object | `{}` | Custom theme definitions |
| `ui.hideBanner` | boolean | `false` | Hide startup banner |
| `ui.hideFooter` | boolean | `false` | Hide status footer |
| `ui.hideContextSummary` | boolean | `false` | Hide context info above input |
| `ui.hideWindowTitle` | boolean | `false` | Hide window title |
| `ui.showLineNumbers` | boolean | `true` | Line numbers in chat |
| `ui.showCitations` | boolean | `false` | Show model citations |
| `ui.showModelInfoInChat` | boolean | `false` | Show model name per turn |
| `ui.showUserIdentity` | boolean | `true` | Show signed-in user |
| `ui.showMemoryUsage` | boolean | `false` | Display memory stats |
| `ui.showShortcutsHint` | boolean | `true` | Show "? for shortcuts" |
| `ui.compactToolOutput` | boolean | `true` | Compact file/directory output |
| `ui.dynamicWindowTitle` | boolean | `true` | Status icons in title |
| `ui.showStatusInTitle` | boolean | `false` | Thoughts in title |
| `ui.inlineThinkingMode` | enum | `"off"` | `off` or `full` |
| `ui.useAlternateBuffer` | boolean | `false` | Alternate screen buffer |
| `ui.incrementalRendering` | boolean | `true` | Reduce flicker (needs alt buffer) |
| `ui.useBackgroundColor` | boolean | `true` | Background colors |
| `ui.renderProcess` | boolean | `true` | Ink render process |
| `ui.terminalBuffer` | boolean | `false` | New terminal buffer architecture |
| `ui.showSpinner` | boolean | `true` | Operation spinner |
| `ui.loadingPhrases` | enum | `"off"` | `tips`, `witty`, `all`, `off` |
| `ui.errorVerbosity` | enum | `"low"` | `low` or `full` |
| `ui.escapePastedAtSymbols` | boolean | `false` | Escape pasted @ symbols |
| `ui.hideTips` | boolean | `false` | Hide tips |
| `ui.showCompatibilityWarnings` | boolean | `true` | Terminal warnings |
| `ui.showHomeDirectoryWarning` | boolean | `true` | Home dir warning |
| `ui.collapseDrawerDuringApproval` | boolean | `true` | Collapse drawer on approval |
| `ui.footer.items` | string[] | - | Footer item IDs |
| `ui.footer.showLabels` | boolean | `true` | Footer labels |
| `ui.footer.hideCWD` | boolean | `false` | Hide working directory |
| `ui.footer.hideSandboxStatus` | boolean | `false` | Hide sandbox status |
| `ui.footer.hideModelInfo` | boolean | `false` | Hide model info |
| `ui.footer.hideContextPercentage` | boolean | `true` | Hide context % |
| `ui.accessibility.screenReader` | boolean | `false` | Screen reader mode |

### Output Settings

| Key | Type | Default | Description |
|---|---|---|---|
| `output.format` | enum | `"text"` | `text` or `json` |

### Privacy Settings

| Key | Type | Default | Description |
|---|---|---|---|
| `privacy.usageStatisticsEnabled` | boolean | `true` | Usage statistics collection |

### Billing Settings

| Key | Type | Default | Description |
|---|---|---|---|
| `billing.overageStrategy` | enum | `"ask"` | `ask`, `always`, `never` |

### IDE Settings

| Key | Type | Default | Description |
|---|---|---|---|
| `ide.enabled` | boolean | `false` | Enable IDE integration |
| `ide.hasSeenNudge` | boolean | `false` | IDE nudge shown |

### Security Settings

| Key | Type | Default | Description |
|---|---|---|---|
| `security.auth.selectedType` | string | - | Current auth method |
| `security.folderTrust.enabled` | boolean | `true` | Folder trust system |

### Tools Settings

| Key | Type | Default | Description |
|---|---|---|---|
| `tools.allowed` | string[] | - | Auto-approved tool names |
| `tools.sandbox` | boolean | `true` | Enable tool sandboxing |

### Advanced Settings

| Key | Type | Default | Description |
|---|---|---|---|
| `policyPaths` | string[] | `[]` | Additional policy file paths |
| `adminPolicyPaths` | string[] | `[]` | Admin policy paths (cannot be overridden) |
| `mcpServers` | object | `{}` | MCP server configurations |
| `hooks` | object | - | Hook event configurations |
| `telemetry` | object | - | Telemetry (OTLP) configuration |

### MCP Server Configuration

Each MCP server entry under `mcpServers`:

```json
{
  "mcpServers": {
    "server-name": {
      "command": "node",
      "args": ["./server.js"],
      "env": { "KEY": "value" },
      "timeout": 30000,
      "trust": true
    }
  }
}
```

The `MCPServerConfig` class at `packages/core/src/config/config.ts:465` manages server lifecycle, connection state, and tool discovery.

### Environment Variables Reference

| Variable | Purpose | Required For |
|---|---|---|
| `GEMINI_API_KEY` | Gemini API key | USE_GEMINI auth |
| `GOOGLE_CLOUD_PROJECT` | GCP project ID | USE_VERTEX_AI auth |
| `GOOGLE_CLOUD_LOCATION` | GCP region | USE_VERTEX_AI auth |
| `GOOGLE_API_KEY` | Google API key | Vertex express mode |
| `GOOGLE_GENAI_USE_VERTEXAI` | Force Vertex AI mode | Vertex AI |
| `GEMINI_MODEL` | Override model name | - |
| `GEMINI_SANDBOX` | Sandbox mode | Sandboxing |
| `GEMINI_SANDBOX_IMAGE` | Custom sandbox Docker image | Docker sandbox |
| `GEMINI_SANDBOX_PROXY_COMMAND` | Proxy setup for sandbox | Corporate proxy |
| `SANDBOX_FLAGS` | Additional sandbox flags | - |
| `SANDBOX_MOUNTS` | Additional sandbox mounts | - |
| `BUILD_SANDBOX` | Build sandbox image | Dev |
| `GEMINI_CONFIG_DIR` | Override config directory | - |
| `GEMINI_CLI_HOME` | Override CLI home directory | - |
| `GEMINI_CLI_SYSTEM_SETTINGS_PATH` | System settings file path | Enterprise deployment |
| `GEMINI_CLI_SYSTEM_DEFAULTS_PATH` | System defaults file path | Enterprise deployment |
| `GEMINI_CLI_CUSTOM_HEADERS` | Custom HTTP headers | Proxy/middleware |
| `GEMINI_DEBUG_LOG_FILE` | Debug log file path | Debugging |
| `DEBUG` | Enable debug logging | Debugging |
| `DEBUG_MODE` | Debug mode flag | Debugging |
| `MCP_DEBUG` | MCP protocol debug logging | MCP debugging |
| `HTTPS_PROXY` | HTTPS proxy URL | Corporate network |
| `HTTP_PROXY` | HTTP proxy URL | Corporate network |
| `NO_PROXY` | Proxy bypass list | Corporate network |
| `GOOGLE_VERTEX_BASE_URL` | Custom Vertex AI endpoint | Custom infrastructure |
| `GOOGLE_GEMINI_BASE_URL` | Custom Gemini API endpoint | Custom infrastructure |
| `GEMINI_CLI_IDE_WORKSPACE_PATH` | IDE workspace path | IDE integration |
| `GEMINI_CLI_IDE_SERVER_PORT` | IDE companion server port | IDE integration |
| `VSCODE_PID` | VS Code process ID | IDE detection |
| `GEMINI_FOLDER_TRUST` | Override folder trust | CI/CD |
| `GEMINI_YOLO_MODE` | Force YOLO mode | CI/CD |
| `CHECKPOINTING` | Enable checkpointing | - |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OpenTelemetry endpoint | Observability |

---

## Security Architecture

### Authentication

Four authentication types, defined in `AuthType` enum:

| Type | Constant | Mechanism |
|---|---|---|
| Google OAuth | `LOGIN_WITH_GOOGLE` | Browser-based OAuth2 flow |
| Gemini API Key | `USE_GEMINI` | `GEMINI_API_KEY` env var |
| Vertex AI | `USE_VERTEX_AI` | GCP project + location or `GOOGLE_API_KEY` |
| Application Default Credentials | `COMPUTE_ADC` | `gcloud auth application-default` |

API keys are stored in the OS keychain via `HybridTokenStorage` (service name: `gemini-cli-api-key`). The storage uses a TTL cache (30 seconds) to minimize keychain access.

### Folder Trust System

Before loading any workspace configuration, Gemini CLI scans the `.gemini/` directory via `FolderTrustDiscoveryService`:

**Discovered items:**
- Custom commands (`.gemini/commands/*.toml`)
- Skills (`.gemini/skills/*/SKILL.md`)
- Agents (`.gemini/agents/*.md`)
- MCP servers (from `settings.json`)
- Hooks (from `settings.json`)
- Settings (non-mcpServer, non-hook keys)

**Security warnings are raised for:**
- `tools.allowed` — auto-approving tools
- `security.folderTrust.enabled = false` — disabling trust
- `tools.sandbox = false` — disabling sandboxing
- Custom agents present

Users must explicitly trust a folder before its configurations take effect.

### Sandbox System

> [!CAUTION]
> Running without a sandbox (empty `GEMINI_SANDBOX`) means shell commands execute directly on the host. Use sandboxing in any environment where you're working with untrusted code or running in YOLO mode.

**Sandbox implementations:**

| Class | Mode | Description |
|---|---|---|
| `LocalSandboxManager` | docker/podman | Container-based isolation |
| `NoopSandboxManager` | none | Direct host execution |

**Safe command allowlist** (`packages/core/src/sandbox/utils/commandSafety.ts`):

The sandbox evaluates commands before execution. Known read-only commands bypass confirmation:

- **Always safe**: `cat`, `cd`, `cut`, `echo`, `grep`, `head`, `id`, `ls`, `pwd`, `stat`, `tail`, `tr`, `uname`, `wc`, `which`, `whoami`
- **Conditionally safe**: `base64` (no `-o/--output`), `find` (no `-exec/-delete`), `rg` (no `--pre/--hostname-bin`), `git` (read-only subcommands only: `status`, `log`, `diff`, `show`, `branch` without write flags), `sed` (only `-n {N}p` patterns)

Commands are parsed with `shell-quote` to handle pipes, `&&`, `||`, and `bash -c` wrappers.

### Policy Engine

The policy engine evaluates tool calls against rules to determine approval:

```
Tool Call → Policy Engine → PolicyDecision
                              ├── ALLOW  (auto-approve)
                              ├── DENY   (block)
                              └── ASK    (prompt user)
```

**Approval modes** (`ApprovalMode` enum):

| Mode | Behavior |
|---|---|
| `DEFAULT` | All tool calls require approval |
| `AUTO_EDIT` | Edit tools auto-approved, shell commands ask |
| `YOLO` | All tools auto-approved |
| `PLAN` | Read-only mode, write tools denied |

Admin policies take precedence over workspace policies via the `MODES_BY_PERMISSIVENESS` ordering.

### Data Sanitization

The `agent-sanitization-utils.ts` module sanitizes sensitive data before it enters logs or telemetry:

- **PEM block redaction**: Iterative parser (not regex) to avoid ReDoS
- **Key-value pair redaction**: Matches `password=`, `api_key:`, `--token` patterns
- **Space-separated keyword redaction**: Handles `password mySecretValue` patterns
- **File path redaction**: Redacts paths to `.key`, `.pem`, `.p12`, `.pfx` files

Sensitive key patterns include: `password`, `apikey`, `token`, `secret`, `credential`, `auth`, `access_token`, `refresh_token`, `session_id`, `cookie`, `private_key`, `client_secret`.

> [!IMPORTANT]
> The sanitization uses an iterative approach for PEM blocks specifically to prevent Regular Expression Denial of Service (ReDoS) attacks. The test suite includes a ReDoS attack string that must process in under 50ms.

### Custom Base URL Validation

When using `GOOGLE_VERTEX_BASE_URL` or `GOOGLE_GEMINI_BASE_URL`:

- URLs must be valid (parsed with `URL` constructor)
- Non-localhost URLs must use HTTPS
- Invalid or HTTP URLs throw `Error` at startup

---

## Model Routing

### Strategy Chain

The `CompositeStrategy` chains routing strategies in priority order:

1. **OverrideStrategy** — Honors explicit model overrides (via `--model` flag or `context.requestedModel`)
2. **ApprovalModeStrategy** — Routes based on Plan/Act mode:
   - `PLAN` mode → Pro model (high-quality planning)
   - Approved plan exists → Flash model (efficient implementation)
3. **ClassifierStrategy** — Uses LLM classifier to route between Pro and Flash:
   - Evaluates task complexity (steps, ambiguity, strategic planning, debugging depth)
   - 4+ steps → complex → Pro
   - Single step, clear intent → simple → Flash
4. **DefaultStrategy** — Returns the configured default model
5. **FallbackStrategy** — Last resort when other strategies fail

### Model ID Resolution

Models go through a resolution pipeline based on context:

```
User-facing model ID
    → modelIdResolutions (preview access, custom tools, Gemini 3.1)
        → Final API model ID
```

Example: `auto` resolves to `gemini-3-pro-preview` by default, but falls back to `gemini-2.5-pro` if the user doesn't have preview access.

### Classifier Model

The classifier runs on `gemini-2.5-flash-lite` with a 512-token thinking budget and generates a JSON response:

```json
{
  "reasoning": "Simple single-file edit task",
  "model_choice": "flash"
}
```

---

## Hook System Internals

### Architecture

```
Event Trigger
    │
    ▼
HookSystem.fire*Event()
    │
    ▼
HookPlanner.plan()
    │ (selects matching hooks)
    ▼
HookRunner.executeHook()
    │ (spawns child process)
    ▼
HookAggregator.aggregateResults()
    │ (merges all hook outputs)
    ▼
HookEventHandler.handle*()
    │ (applies decisions)
    ▼
Result
```

### Hook Events

| Event | Input | Output Capabilities |
|---|---|---|
| `BeforeTool` | Tool name, args, MCP context | block, allow, modify args, stop, add context |
| `AfterTool` | Tool name, result | add context |
| `BeforeModel` | LLM request (model, config, contents) | modify request, block |
| `AfterModel` | Model response | add context |
| `BeforeToolSelection` | - | control tool calling mode (NONE, ANY, AUTO) |

### Aggregation Rules

When multiple hooks fire for the same event:

- **Block decisions use OR logic**: If any hook returns `"decision": "block"`, the tool is blocked
- **Continue=false takes precedence**: If any hook returns `"continue": false`, execution stops
- **Reasons are concatenated**: All hook reasons are joined with newlines
- **BeforeToolSelection merges**: NONE mode takes precedence over ANY, which takes precedence over AUTO. Allowed function names are unioned
- **BeforeModel uses field replacement**: Later hooks override earlier hooks' fields (last writer wins)
- **AdditionalContext is concatenated**: All hooks' additional context is joined

### Hook Execution

Hooks execute as child processes via `HookRunner`:

- Default timeout: 30,000ms (configurable per hook)
- Hook receives input via stdin as JSON
- Hook returns output via stdout as JSON
- Timeout is treated as failure
- Hook errors are aggregated but don't automatically block (unless the hook returned `"decision": "block"` before failing)

### Trusted Hooks

The `TrustedHooksManager` tracks which hooks have been approved by the user. Untrusted hooks trigger a confirmation prompt before first execution.

---

## Extension System Internals

### Extension Manifest Schema

`gemini-extension.json`:

```json
{
  "name": "extension-name",
  "version": "1.0.0",
  "description": "What this extension does",
  "mcpServers": {},
  "skills": {},
  "commands": {},
  "hooks": {},
  "policies": {},
  "themes": {}
}
```

### Extension Lifecycle

1. **Discovery**: `ExtensionManager` scans enabled extensions
2. **Validation**: Manifest validated against schema
3. **Loading**: Components registered (MCP servers, commands, skills, etc.)
4. **Initialization**: MCP servers started, hooks registered
5. **Runtime**: Extension components active in the session
6. **Shutdown**: MCP servers stopped, resources cleaned up

> [!NOTE]
> Extensions are loaded exactly once per session. Calling `loadExtensions()` a second time throws `"Extensions already loaded, only load extensions once."` This prevents resource leaks from duplicate MCP server processes.

### Extension Installation Types

| Type | Source | Storage |
|---|---|---|
| npm | `gemini extensions install <package>` | `~/.gemini/extensions/` |
| Local link | `gemini extensions link <path>` | Symlink to local directory |
| Workspace | `.gemini/` directory | Project-local |

### Extension Registry

The `ExtensionRegistryClient` queries a remote registry for available extensions. It supports ordering by relevance, downloads, or name.

### Admin Controls

Administrators can restrict extension features via system settings:

- Disable MCP servers globally
- Disable extensions
- Disable skills
- Restrict which extensions can be installed

These restrictions are checked before executing deferred commands in the CLI's argument parser.

---

## Scheduler and Tool Execution

### Tool Call Lifecycle

```
Model proposes tool call
    │
    ▼
Scheduler receives tool call
    │
    ▼
Policy Engine evaluates
    │
    ├── ALLOW → Execute directly
    ├── DENY → Return error to model
    └── ASK → Enter confirmation flow
              │
              ▼
         BeforeTool hooks fire
              │
              ├── Block → Return error
              ├── Modify args → Rebuild invocation
              └── Allow → Continue
                    │
                    ▼
              User confirmation (if needed)
                    │
                    ├── Approve → Execute
                    ├── Reject → Return rejection
                    └── Edit → Modify args, re-confirm
                          │
                          ▼
                    Tool executes
                          │
                          ▼
                    AfterTool hooks fire
                          │
                          ▼
                    Result returned to model
```

### State Transitions

Tool calls progress through states managed by `SchedulerStateManager`:

```
PENDING → VALIDATING → WAITING → EXECUTING → COMPLETED
                  ↘                      ↗
                   → REJECTED / ERROR →
```

### Parallel Execution

The `Scheduler` supports parallel tool execution. Multiple tool calls from a single model turn execute concurrently, with the state manager tracking each independently.

### Tool Modification

The `ToolModificationHandler` allows users to edit tool arguments during the confirmation flow. This is particularly useful for file edit tools where the user wants to adjust the proposed changes.

---

## Session Management Internals

### Session Storage

Sessions are stored as JSON files in the project's temporary directory:

```
~/.gemini/projects/<project-hash>/chats/<session-id>.json
```

The `Storage` class manages the project-specific temp directory, and `ChatRecordingService` handles read/write operations.

### Session File Format

Sessions are stored as `ConversationRecord` objects containing:

- `sessionId`: UUID
- `messages`: Array of conversation turns
- `metadata`: Model, timestamp, session state

### Checkpointing

When enabled, `Logger` creates git-based checkpoints:

1. Creates a checkpoint tag at the current commit
2. Stores conversation state alongside
3. `performRestore()` can restore both:
   - **Conversation history**: Reloads the chat state
   - **Git state**: Resets the working tree to the checkpoint

### Session Retention

The `sessionRetention` settings control automatic cleanup:

- Sessions older than `maxAge` are deleted
- If `maxCount` is set, only the most recent N sessions are kept
- `minRetention` provides a safety floor (cannot delete sessions newer than this)

---

## Telemetry and Observability

### Built-in Telemetry

Gemini CLI collects usage statistics via Clearcut logging (Google's telemetry pipeline):

- URL: `https://play.googleapis.com/log`
- Controlled by: `privacy.usageStatisticsEnabled`
- Events: model usage, error rates, feature adoption

### OpenTelemetry Support

Configure OTLP export for enterprise observability:

```json
{
  "telemetry": {
    "endpoint": "https://your-otel-collector:4318"
  }
}
```

Environment variable: `OTEL_EXPORTER_OTLP_ENDPOINT`

### Debug Logging

The `DebugLogger` class provides structured debug output:

```bash
DEBUG=* gemini           # All debug output
DEBUG=hooks gemini       # Only hook debug output
GEMINI_DEBUG_LOG_FILE=/tmp/debug.log gemini  # Write to file
```

### DevTools Inspector

Enable the Chrome DevTools-style inspector:

```json
{
  "general": {
    "devtools": true
  }
}
```

The `DevTools` class (extends `EventEmitter`) broadcasts events that the inspector client consumes via WebSocket.

---

## Performance

### Context Compression

When conversation context approaches the model's limit, Gemini CLI triggers compression:

- **Threshold**: `model.compressionThreshold` (default: 0.5)
- **Method**: A summarization model (from `chat-compression-*` aliases) condenses earlier conversation
- **Model selection**: Follows the current model family (Gemini 3 uses `chat-compression-3-pro`, 2.5 uses `chat-compression-2.5-pro`)

### Tool Output Summarization

Large tool outputs can be summarized before adding to context:

```json
{
  "model": {
    "summarizeToolOutput": {
      "run_shell_command": {
        "tokenBudget": 2000
      }
    }
  }
}
```

Currently only `run_shell_command` supports summarization.

### Loop Detection

`LoopDetectionService` monitors for infinite loops:

1. Detects repeated identical tool calls
2. Uses a lightweight LLM call to confirm the loop
3. Optionally double-checks with a Pro model
4. Injects a corrective message to break the loop

Disable with `model.disableLoopDetection: true`.

### File Discovery

File search uses ripgrep (bundled) via `FileDiscoveryService`. If ripgrep download fails at startup, falls back to slower Node.js-based search.

### Retry Strategy

`retryWithBackoff()` in `packages/core/src/utils/retry.ts`:

- Exponential backoff with jitter
- Configurable `maxAttempts` (default: 10, enforced max: 10)
- Respects `shouldRetryOnContent` for content validation
- Handles quota errors with specific retry logic:
  - `RetryableQuotaError`: Retry with backoff
  - `TerminalQuotaError`: Stop retrying
  - `ModelNotFoundError`: Try fallback chain

---

## Deployment Patterns

### Individual Developer Setup

```bash
npm install -g @google/gemini-cli
gemini  # Sign in with Google
```

### Team Deployment with Shared Config

1. Create system-level settings:

```bash
export GEMINI_CLI_SYSTEM_SETTINGS_PATH=/opt/gemini/system-settings.json
```

```json
{
  "general": {
    "defaultApprovalMode": "default"
  },
  "adminPolicyPaths": ["/opt/gemini/policies/"],
  "model": {
    "name": "gemini-2.5-pro"
  }
}
```

2. Distribute via configuration management (Puppet, Chef, Ansible)

### CI/CD Integration

```bash
export GEMINI_API_KEY="$CI_GEMINI_KEY"
export GEMINI_SANDBOX=docker
export GEMINI_FOLDER_TRUST=true
gemini --yolo -p "Run the full test suite and report results" --output-format json
```

### Enterprise Deployment with Vertex AI

```bash
export GOOGLE_CLOUD_PROJECT="enterprise-project"
export GOOGLE_CLOUD_LOCATION="us-central1"
export GEMINI_CLI_SYSTEM_SETTINGS_PATH="/etc/gemini/settings.json"
```

System settings enforce:

```json
{
  "adminPolicyPaths": ["/etc/gemini/admin-policies/"],
  "security": {
    "folderTrust": { "enabled": true }
  }
}
```

### Custom Endpoint Deployment

For private Gemini API endpoints or proxy setups:

```bash
export GOOGLE_VERTEX_BASE_URL="https://my-proxy.internal/vertex"
# or
export GOOGLE_GEMINI_BASE_URL="https://my-proxy.internal/gemini"
export GEMINI_CLI_CUSTOM_HEADERS="X-Custom-Auth=token123"
```

> [!WARNING]
> Custom base URLs must use HTTPS unless they point to localhost. HTTP URLs are rejected at startup with a clear error message.

---

## Operations

### Health Monitoring

Monitor Gemini CLI health through:

1. **Debug logs**: `GEMINI_DEBUG_LOG_FILE` for persistent logging
2. **Telemetry**: OTLP export for metrics and traces
3. **DevTools**: Real-time inspection of agent behavior
4. **Session recording**: `--record-responses` for reproducible debugging

### Error Hierarchy

The codebase defines a structured error hierarchy:

```
Error
├── FatalError (non-recoverable, exits the session)
│   ├── FatalAuthenticationError
│   ├── FatalInputError
│   ├── FatalSandboxError
│   ├── FatalConfigError
│   ├── FatalTurnLimitedError
│   ├── FatalToolExecutionError
│   └── FatalCancellationError
├── ForbiddenError (403)
│   └── AccountSuspendedError
├── UnauthorizedError (401)
├── BadRequestError (400)
├── CanceledError (user cancellation)
├── ChangeAuthRequestedError (auth method switch)
├── FetchError (network failures)
├── PrivateIpError (blocked private IP access)
├── InvalidStreamError (malformed model stream)
├── AgentExecutionStoppedError (hook stop)
├── AgentExecutionBlockedError (policy block)
├── TerminalQuotaError (unrecoverable quota limit)
├── RetryableQuotaError (temporary quota limit)
├── ValidationRequiredError (requires user action)
├── ModelNotFoundError (invalid model)
└── ShellParserInitializationError
```

### Quota Error Handling

| Error Type | Behavior |
|---|---|
| `RetryableQuotaError` | Retry with backoff (per-minute limits) |
| `TerminalQuotaError` | Stop retrying (daily limits). Offer AI credits if available |
| `ValidationRequiredError` | Prompt user for action (e.g., billing setup) |

### Common Operational Issues

**Problem:** MCP server processes orphaned after crash

MCP servers are child processes. If the CLI crashes, they may persist. Kill orphaned processes:

```bash
ps aux | grep "mcp-server" | grep -v grep | awk '{print $2}' | xargs kill
```

**Problem:** Settings changes not taking effect

Settings are loaded at startup. Most changes require restart. Check `"Requires restart: yes"` in the schema documentation.

**Problem:** Extension conflicts

The `SlashCommandConflictHandler` detects when multiple extensions register the same command name. It logs warnings and uses priority-based resolution.

**Problem:** Hook execution slowing down sessions

Profile hooks with `DEBUG=hooks gemini`. Hooks run sequentially per event. Slow hooks directly impact response time.

---

## Troubleshooting (Admin)

### Debug Mode

```bash
# Full debug output
DEBUG=* gemini

# Specific subsystems
DEBUG=hooks,mcp,sandbox gemini

# Write to file
GEMINI_DEBUG_LOG_FILE=/var/log/gemini-debug.log gemini
```

### Session Forensics

```bash
# List all sessions for a project
gemini --list-sessions

# Session files are at:
ls ~/.gemini/projects/*/chats/
```

### Config Debugging

Check effective merged settings:

```
/about
```

This shows: CLI version, OS, sandbox mode, model, auth type, GCP project, IDE client, user email, and tier.

### Extension Debugging

```bash
# Validate extension manifest
gemini extensions validate

# List with status
gemini extensions list

# Check MCP server connections
/mcp list
```

### Network Debugging

For proxy and connectivity issues:

```bash
# Test basic connectivity
curl -v https://generativelanguage.googleapis.com/

# Check proxy config
echo $HTTPS_PROXY $HTTP_PROXY $NO_PROXY

# MCP-specific debug
MCP_DEBUG=true gemini
```

### Model Response Debugging

Record and replay model responses for reproducible debugging:

```bash
# Record a session
gemini --record-responses /tmp/session-recording.json -p "reproduce the bug"

# Replay the recording
gemini --fake-responses /tmp/session-recording.json -p "reproduce the bug"
```

---

## Developer Internals

### Build System

The project uses npm workspaces with TypeScript:

```bash
# Install all dependencies
npm install

# Build all packages
npm run build

# Run tests
npm test

# Run specific package tests
npm test -w packages/core
```

### Testing Architecture

| Test Type | Location | Runner |
|---|---|---|
| Unit tests | `packages/*/src/**/*.test.ts` | Vitest |
| Integration tests | `integration-tests/` | Vitest |
| Component evals | `evals/` | Custom harness |
| Memory tests | `memory-tests/` | Custom harness with heap snapshots |
| Performance tests | `perf-tests/` | Custom harness with timing |
| SEA tests | `sea/` | Custom launcher tests |

### Key Test Utilities

| Class | Purpose |
|---|---|
| `TestRig` | Full integration test harness with CLI subprocess management |
| `InteractiveRun` | Manages an interactive CLI session in tests |
| `TestMcpServerBuilder` | Builds mock MCP servers for testing |
| `MemoryTestHarness` | Heap snapshot comparison for memory leak detection |
| `PerfTestHarness` | Timing and performance regression testing |
| `ComponentRig` | Lightweight component-level test harness |

### SEA (Single Executable Application)

The `sea/` directory packages Gemini CLI as a standalone binary:

- Uses Node.js SEA (Single Executable Application) feature
- Bundles all dependencies into a single executable
- Tests verify filesystem operations, rename handling, and permission checks

### Release Process

Release scripts live in `scripts/releasing/`:

| Script | Purpose |
|---|---|
| `release.ts` | Main release orchestrator |
| Options | `--commit`, `--pullRequestNumber`, `--channel`, `--cli-package-name`, `--dry-run` |

### Code Quality Patterns

- **Strict TypeScript**: All packages use `strict: true`
- **Error boundaries**: FatalError hierarchy for non-recoverable errors
- **Debug logging**: `debugLogger` throughout for structured diagnostics
- **Schema validation**: `SchemaValidator` for all external input
- **Sanitization**: Agent sanitization utils for all sensitive data
- **Cache management**: `CacheService` with TTL and configurable storage backends

---

## Integration Points

### SDK Integration

Build custom agents programmatically:

```typescript
import { GeminiCliAgent } from '@google/gemini-cli-sdk';

const agent = new GeminiCliAgent({
  instructions: 'You are a code review assistant.',
  model: 'gemini-2.5-pro',
  tools: [myCustomTool],
  skills: [mySkill],
});

const session = agent.session();
const stream = session.sendStream('Review the latest PR');

for await (const event of stream) {
  if (event.type === 'content') {
    process.stdout.write(event.value);
  }
}
```

**SDK classes:**

| Class | Purpose |
|---|---|
| `GeminiCliAgent` | Creates sessions, manages configuration |
| `GeminiCliSession` | Sends messages, streams responses |
| `SdkTool` | Base class for custom tools |
| `SdkToolInvocation` | Tool invocation with parameter access |
| `ModelVisibleError` | Errors surfaced to the model |
| `SdkAgentFilesystem` | Sandboxed file operations |
| `SdkAgentShell` | Shell command execution |

**Session resume:**

```typescript
const session = await agent.resumeSession(previousSessionId);
```

### A2A Protocol Integration

Expose Gemini CLI as an A2A-compatible agent server:

```typescript
import { createApp } from '@google/gemini-cli-a2a-server';

const app = createApp(config);
app.listen(3000);
```

Events stream via SSE using `CoderAgentEvent` types.

### VS Code Integration

The VS Code companion extension:

1. Starts a local HTTP server on `GEMINI_CLI_IDE_SERVER_PORT`
2. Exposes MCP endpoints for tool communication
3. Manages file diffs via `DiffManager` and `DiffContentProvider`
4. Tracks open files via `OpenFilesManager`
5. CORS restricts access to localhost origins only

Enable IDE mode:

```json
{
  "ide": {
    "enabled": true
  }
}
```

### MCP Protocol

Gemini CLI acts as an MCP client, connecting to external tool servers:

- **Transport**: stdio (command-based servers) or HTTP (SSE-based servers)
- **Discovery**: Tools and prompts are discovered from connected servers
- **Lifecycle**: Servers start with the session and stop on exit
- **Token storage**: MCP OAuth tokens stored via `HybridTokenStorage`
- **Debug**: `MCP_DEBUG=true` for protocol-level logging

---

## Known Issues and Open Feature Requests

Based on the project's GitHub issue tracker:

### Known Bugs (Resolved)

- **#25622**: Gemini Error — general error handling (closed)
- **#25584**: Shift+Tab not working on Windows for Plan/Act toggle (closed)
- **#24880**: 403 API Error after Google sign-in — commonly a quota/access issue (closed, 31 comments)
- **#25323**: RipGrep download failure should not slow startup (closed)
- **#18503**: Letter 'm' printed at startup — terminal escape code issue (closed)
- **#20603**: Cannot find module 'color-convert' in Colab (closed)
- **#20894**: Maximum update depth exceeded — React rendering loop (closed)

### Open Feature Requests

- **#15269**: Missing subagent hook events
- **#15267**: Test and refine hook migration tooling
- **#15263**: Granular extension hook control
- **#15167**: UI for BeforeTool hooks within tool confirmation
- **#15018**: Admin rules that can be overridden
- **#14964**: Subagent optimization flow within `/agents` UI
- **#11802**: OTLP headers for telemetry
- **#11303**: Change `--yolo` to be a policy shortcut

### Open UX/Security Issues

- **#15268**: Interactive hook configuration GUI
- **#15266**: Hook execution confirmation UX
- **#15258**: Natural language hook building
- **#15179**: Recursive subagent delegation
- **#15014**: Screen reader text repetition on Windows
- **#14724**: Hooks SessionStart "compress" vs "compact" incompatibility
- **#14540**: Complete CI/CD security review

---

## Quick Reference

### File Layout

```
~/.gemini/                      # User config directory
├── settings.json               # User settings
├── GEMINI.md                   # Global memory
├── extensions/                 # Installed extensions
└── projects/                   # Project-specific data
    └── <hash>/
        └── chats/              # Session files

.gemini/                        # Workspace config (in project root)
├── settings.json               # Workspace settings
├── commands/                   # Custom TOML commands
├── skills/                     # Custom skills (SKILL.md)
├── agents/                     # Custom agents (.md)
└── policies/                   # Policy files
```

### Config Precedence (highest wins)

1. CLI flags (`--model`, `--yolo`, etc.)
2. Workspace settings (`.gemini/settings.json`)
3. User settings (`~/.gemini/settings.json`)
4. System settings (`GEMINI_CLI_SYSTEM_SETTINGS_PATH`)
5. System defaults (`GEMINI_CLI_SYSTEM_DEFAULTS_PATH`)
6. Built-in defaults

### Key Source Files

| Purpose | Path |
|---|---|
| CLI entry point | `packages/cli/index.ts` |
| Core entry point | `packages/core/src/index.ts` |
| Settings schema | `schemas/settings.schema.json` |
| Config class | `packages/core/src/config/config.ts` |
| Agent loop | `packages/core/src/core/geminiChat.ts` |
| Scheduler | `packages/core/src/scheduler/scheduler.ts` |
| Hook system | `packages/core/src/hooks/hookSystem.ts` |
| Model routing | `packages/core/src/routing/strategies/` |
| Sandbox safety | `packages/core/src/sandbox/utils/commandSafety.ts` |
| Extension manager | `packages/cli/src/config/extension-manager.ts` |
| Settings loader | `packages/cli/src/config/settings.ts` |
| SDK agent | `packages/sdk/src/agent.ts` |
| A2A server | `packages/a2a-server/src/index.ts` |

---

_Generated May 2026 from google-gemini/gemini-cli at a809bc7. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
