Gemini CLI Extensions Reference

Updated by

Independent reference, not affiliated with Google. Tables are generated from the Gemini CLI source at v0.62.0 (v0.62.0). Official documentation: geminicli.com.

A Gemini CLI extension is a directory with a gemini-extension.json manifest that packages MCP servers, a context file, slash commands, hooks, skills, subagents and policy rules into one installable unit. Extensions install into ~/.gemini/extensions/<name>/ with gemini extensions install <git-url-or-path> and load in every session until disabled.

What goes in gemini-extension.json?#

Only name and version are required; a manifest missing either fails to load with Invalid configuration ... missing "name" (or "version").

{
  "name": "mcp-server-example",
  "version": "1.0.0",
  "mcpServers": {
    "nodeServer": {
      "command": "node",
      "args": ["${extensionPath}${/}example.js"],
      "cwd": "${extensionPath}"
    }
  }
}
FieldTypeRequiredNotes
namestringyes—
versionstringyes—
mcpServersRecord<string, MCPServerConfig>noSame entries as settings.json mcpServers (see the settings reference); trust is stripped.
contextFileNamestring | string[]noDefaults to GEMINI.md when omitted.
excludeToolsstring[]noAdded to the excluded-tools set while the extension is active.
settingsExtensionSetting[]noValues prompted for at install; see the settings table.
themesCustomTheme[]noCustom themes contributed by this extension. These themes will be registered when the extension is activated.
planobjectnoPlanning features configuration contributed by this extension.
plan.directorystringnoThe directory where planning artifacts are stored.
migratedTostringnoUsed to migrate an extension to a new repository source.

String values in the manifest and in hooks/hooks.json can use these variables, substituted when the extension loads:

VariableValue
${extensionPath}The path of the extension in the filesystem.
${workspacePath}The absolute path of the current workspace.
${/}The path separator.
${pathSeparator}The path separator.

settings declares values the user supplies at install time. Each value is exposed as an environment variable to the extension's MCP servers and hooks:

FieldTypeRequiredNotes
namestringyes—
descriptionstringyes—
envVarstringyesEnvironment variable the value is exposed as (to MCP servers and the extension's hooks).
sensitivebooleannoStored in the OS keychain instead of .env when true.

What can a Gemini CLI extension bundle?#

Hooks are not a manifest key. Everything except MCP servers, excludeTools, themes and settings comes from files and folders next to the manifest:

File or directoryWhat it provides
gemini-extension.jsonmanifest: name, version, MCP servers, context file, excludeTools, settings, themes
GEMINI.mdcontext file loaded into memory (contextFileName overrides the name)
commands/custom slash commands as .toml files (trusted folders only when folder trust is on)
hooks/hooks.jsonhooks, same shape as the settings.json hooks block, under a top-level "hooks" key; loaded only when hooksConfig.enabled
skills/agent skills
agents/subagent definitions
policies/policy engine TOML rules and safety checkers (extension tier)
.envvalues for the manifest's settings (user scope; workspace scope uses <workspace>/.env)

An extension's hooks/hooks.json uses the same event names and entry shape as the hooks block of settings.json, wrapped in a top-level "hooks" object:

{
  "hooks": {
    "SessionStart": [
      { "hooks": [{ "type": "command", "command": "node ${extensionPath}/scripts/on-start.js" }] }
    ]
  }
}

What is an extension not allowed to do?#

An extension's MCP servers and hooks run as local commands, so install and link ask for consent first (skip the prompt with --consent). Some capabilities are withheld from extensions regardless of consent:

ItemRule
MCP server trustthe `trust` field is removed from every extension MCP server, so its tools still need approval
Policy ALLOW rulesignored with a warning: extensions cannot auto-approve tool calls
Policy YOLO rulesignored with a warning: extensions cannot add rules for YOLO mode
contextFileNamemust stay inside the extension directory: no absolute paths, no `..`
plan.directoryrelative path only; absolute paths and `..` are rejected
admin.mcp.enabled = falsedrops every extension MCP server
Duplicate namestwo installed extensions with the same name stop loading with an error

The practical result: an extension can add MCP tools and ask for confirmation on them, deny tools through its own policies, or narrow tool lists, but it cannot make its own tools run without a prompt. That requires a user-tier policy rule, mcp.allowed in settings, or a user decision to always allow.

How do I install, update or uninstall an extension?#

CommandWhat it doesOptions
gemini extensions install <source> [--auto-update] [--pre-release]Installs an extension from a git repository URL or a local path.--ref, --auto-update, --pre-release, --consent, --skip-settings
gemini extensions uninstall [names..]Uninstalls one or more extensions.--all
gemini extensions listLists installed extensions.--output-format
gemini extensions update [<name>] [--all]Updates all extensions or a named extension to the latest version.--all
gemini extensions disable [--scope] <name>Disables an extension.--scope
gemini extensions enable [--scope] <name>Enables an extension.--scope
gemini extensions link <path>Links an extension from a local path. Updates made to the local path will always be reflected.--consent
gemini extensions new <path> [template]Create a new extension from a boilerplate example.none
gemini extensions validate <path>Validates an extension from a local path.none
gemini extensions config [name] [setting]Configure extension settings.--scope

install accepts a GitHub URL, any git URL or a local path, and records how it was installed so update knows where to pull from. link keeps the extension pointed at your working copy, so edits apply on the next session without reinstalling, which is the usual loop while writing one. enable and disable take --scope user (the default) or --scope workspace. Inside a session, /extensions list, /extensions update, /extensions explore and /extensions reload are always available.

gemini extensions new <path> <template> scaffolds a new extension from a built-in example:

gemini extensions new <path> <template>Files it creates
custom-commandsgemini-extension.json, .gitignore, commands
exclude-toolsgemini-extension.json, .gitignore
hooksgemini-extension.json, .gitignore, hooks, scripts
mcp-servergemini-extension.json, .gitignore, README.md, example.js, package.json
policiesgemini-extension.json, README.md, policies
skillsgemini-extension.json, .gitignore, skills
themes-examplegemini-extension.json, README.md

Where are Gemini CLI extensions installed?#

PathHolds
~/.gemini/extensions/<name>/each installed or linked extension (one directory per extension, user level only)
~/.gemini/extensions/<name>/.gemini-extension-install.jsoninstall source and type: git | local | link | github-release
~/.gemini/extensions/extension-enablement.jsonenabled/disabled state per extension and path scope

Extensions install per user, never per project: there is no project-level extensions folder. Per-project control comes from gemini extensions disable --scope workspace <name>, which records the choice in extension-enablement.json, and the -e / --extensions flag limits one session to a named set.

Frequently asked questions#

What are Gemini CLI extensions?#

Installable packages that add capabilities to Gemini CLI: MCP servers, a GEMINI.md context file, slash commands from commands/*.toml, hooks, skills, subagents, policy rules and themes. Each is a directory with a gemini-extension.json manifest, installed from a git repository or a local path into ~/.gemini/extensions/<name>/.

How do I install a Gemini CLI extension?#

Run gemini extensions install <source> with a GitHub URL, git URL or local path. Add --ref to install a specific git ref, --auto-update to keep it current, and --consent to skip the security prompt in scripts. For local development use gemini extensions link <path> instead, so changes apply without reinstalling.

How do I update or uninstall an extension?#

gemini extensions update <name> updates one extension and gemini extensions update --all updates every installed one. gemini extensions uninstall <name> removes it, accepts several names, and --all removes everything. Linked extensions track your local folder, so they need no update step.

Can a Gemini CLI extension include hooks?#

Yes, through a hooks/hooks.json file in the extension directory, not through the manifest. The file uses the same event names and structure as the hooks block in settings.json, wrapped in a top-level "hooks" object, and can reference ${extensionPath}. Extension hooks load only while hooksConfig.enabled is true.

Can an extension auto-approve its own tools?#

No. The trust flag is stripped from every MCP server an extension defines, and ALLOW rules or YOLO-mode rules in an extension's policies/ folder are ignored with a warning. Extension tools therefore follow your own policy rules and still prompt for confirmation unless you allow them in user-level settings or policies.

Where do I find Gemini CLI extensions?#

The official gallery at geminicli.com/extensions lists published extensions, and /extensions explore opens it from inside a session. Any git repository with a gemini-extension.json at its root also works as an install source, so extensions on GitHub install directly by URL.

Sources

Release-by-release changes: Gemini CLI version tracker. All Gemini CLI pages: Gemini CLI reference index.