mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-02-01 22:48:03 +00:00
Update extensions docs (#16093)
This commit is contained in:
139
docs/extensions/best-practices.md
Normal file
139
docs/extensions/best-practices.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Extensions on Gemini CLI: Best practices
|
||||
|
||||
This guide covers best practices for developing, securing, and maintaining
|
||||
Gemini CLI extensions.
|
||||
|
||||
## Development
|
||||
|
||||
Developing extensions for Gemini CLI is intended to be a lightweight, iterative
|
||||
process.
|
||||
|
||||
### Structure your extension
|
||||
|
||||
While simple extensions can just be a few files, we recommend a robust structure
|
||||
for complex extensions:
|
||||
|
||||
```
|
||||
my-extension/
|
||||
├── package.json
|
||||
├── tsconfig.json
|
||||
├── gemini-extension.json
|
||||
├── src/
|
||||
│ ├── index.ts
|
||||
│ └── tools/
|
||||
└── dist/
|
||||
```
|
||||
|
||||
- **Use TypeScript**: We strongly recommend using TypeScript for type safety and
|
||||
better tooling.
|
||||
- **Separate source and build**: Keep your source code in `src` and build to
|
||||
`dist`.
|
||||
- **Bundle dependencies**: If your extension has many dependencies, consider
|
||||
bundling them (e.g., with `esbuild` or `webpack`) to reduce install time and
|
||||
potential conflicts.
|
||||
|
||||
### Iterate with `link`
|
||||
|
||||
Use `gemini extensions link` to develop locally without constantly reinstalling:
|
||||
|
||||
```bash
|
||||
cd my-extension
|
||||
gemini extensions link .
|
||||
```
|
||||
|
||||
Changes to your code (after rebuilding) will be immediately available in the CLI
|
||||
on restart.
|
||||
|
||||
### Use `GEMINI.md` effectively
|
||||
|
||||
Your `GEMINI.md` file provides context to the model. Keep it focused:
|
||||
|
||||
- **Do:** Explain high-level goals and how to use the provided tools.
|
||||
- **Don't:** Dump your entire documentation.
|
||||
- **Do:** Use clear, concise language.
|
||||
|
||||
## Security
|
||||
|
||||
When building a Gemini CLI extension, follow general security best practices
|
||||
(such as least privilege and input validation) to reduce risk.
|
||||
|
||||
### Minimal permissions
|
||||
|
||||
When defining tools in your MCP server, only request the permissions necessary.
|
||||
Avoid giving the model broad access (like full shell access) if a more
|
||||
restricted set of tools will suffice.
|
||||
|
||||
If you must use powerful tools like `run_shell_command`, consider restricting
|
||||
them to specific commands in your `gemini-extension.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-safe-extension",
|
||||
"excludeTools": ["run_shell_command(rm -rf *)"]
|
||||
}
|
||||
```
|
||||
|
||||
This ensures that even if the model tries to execute a dangerous command, it
|
||||
will be blocked at the CLI level.
|
||||
|
||||
### Validate inputs
|
||||
|
||||
Your MCP server is running on the user's machine. Always validate inputs to your
|
||||
tools to prevent arbitrary code execution or filesystem access outside the
|
||||
intended scope.
|
||||
|
||||
```typescript
|
||||
// Good: Validating paths
|
||||
if (!path.resolve(inputPath).startsWith(path.resolve(allowedDir) + path.sep)) {
|
||||
throw new Error('Access denied');
|
||||
}
|
||||
```
|
||||
|
||||
### Sensitive settings
|
||||
|
||||
If your extension requires API keys, use the `sensitive: true` option in
|
||||
`gemini-extension.json`. This ensures keys are stored securely in the system
|
||||
keychain and obfuscated in the UI.
|
||||
|
||||
```json
|
||||
"settings": [
|
||||
{
|
||||
"name": "API Key",
|
||||
"envVar": "MY_API_KEY",
|
||||
"sensitive": true
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Releasing
|
||||
|
||||
You can upload your extension directly to GitHub to list it in the gallery.
|
||||
Gemini CLI extensions also offers support for more complicated
|
||||
[releases](releasing.md).
|
||||
|
||||
### Semantic versioning
|
||||
|
||||
Follow [Semantic Versioning](https://semver.org/).
|
||||
|
||||
- **Major**: Breaking changes (renaming tools, changing arguments).
|
||||
- **Minor**: New features (new tools, commands).
|
||||
- **Patch**: Bug fixes.
|
||||
|
||||
### Release Channels
|
||||
|
||||
Use git branches to manage release channels (e.g., `main` for stable, `dev` for
|
||||
bleeding edge). This allows users to choose their stability level:
|
||||
|
||||
```bash
|
||||
# Stable
|
||||
gemini extensions install github.com/user/repo
|
||||
|
||||
# Dev
|
||||
gemini extensions install github.com/user/repo --ref dev
|
||||
```
|
||||
|
||||
### Clean artifacts
|
||||
|
||||
If you are using GitHub Releases, ensure your release artifacts only contain the
|
||||
necessary files (`dist/`, `gemini-extension.json`, `package.json`). Exclude
|
||||
`node_modules` (users will install them) and `src/` to keep downloads small.
|
||||
@@ -1,377 +1,44 @@
|
||||
# Gemini CLI extensions
|
||||
|
||||
_This documentation is up-to-date with the v0.4.0 release._
|
||||
|
||||
Gemini CLI extensions package prompts, MCP servers, Agent Skills, and custom
|
||||
commands into a familiar and user-friendly format. With extensions, you can
|
||||
Gemini CLI extensions package prompts, MCP servers, custom commands, hooks, and
|
||||
agent skills into a familiar and user-friendly format. With extensions, you can
|
||||
expand the capabilities of Gemini CLI and share those capabilities with others.
|
||||
They're designed to be easily installable and shareable.
|
||||
They are designed to be easily installable and shareable.
|
||||
|
||||
To see examples of extensions, you can browse a gallery of
|
||||
[Gemini CLI extensions](https://geminicli.com/extensions/browse/).
|
||||
|
||||
See [getting started docs](getting-started-extensions.md) for a guide on
|
||||
creating your first extension.
|
||||
## Managing extensions
|
||||
|
||||
See [releasing docs](extension-releasing.md) for an advanced guide on setting up
|
||||
GitHub releases.
|
||||
You can verify your installed extensions and their status using the interactive
|
||||
command:
|
||||
|
||||
## Extension management
|
||||
|
||||
We offer a suite of extension management tools using `gemini extensions`
|
||||
commands.
|
||||
|
||||
Note that these commands are not supported from within the CLI, although you can
|
||||
list installed extensions using the `/extensions list` subcommand.
|
||||
|
||||
Note that all of these commands will only be reflected in active CLI sessions on
|
||||
restart.
|
||||
|
||||
### Installing an extension
|
||||
|
||||
You can install an extension using `gemini extensions install` with either a
|
||||
GitHub URL or a local path.
|
||||
|
||||
Note that we create a copy of the installed extension, so you will need to run
|
||||
`gemini extensions update` to pull in changes from both locally-defined
|
||||
extensions and those on GitHub.
|
||||
|
||||
NOTE: If you are installing an extension from GitHub, you'll need to have `git`
|
||||
installed on your machine. See
|
||||
[git installation instructions](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
|
||||
for help.
|
||||
|
||||
```
|
||||
gemini extensions install <source> [--ref <ref>] [--auto-update] [--pre-release] [--consent]
|
||||
```bash
|
||||
/extensions list
|
||||
```
|
||||
|
||||
- `<source>`: The github URL or local path of the extension to install.
|
||||
- `--ref`: The git ref to install from.
|
||||
- `--auto-update`: Enable auto-update for this extension.
|
||||
- `--pre-release`: Enable pre-release versions for this extension.
|
||||
- `--consent`: Acknowledge the security risks of installing an extension and
|
||||
skip the confirmation prompt.
|
||||
or in noninteractive mode:
|
||||
|
||||
### Uninstalling an extension
|
||||
|
||||
To uninstall one or more extensions, run
|
||||
`gemini extensions uninstall <name...>`:
|
||||
|
||||
```
|
||||
gemini extensions uninstall gemini-cli-security gemini-cli-another-extension
|
||||
```
|
||||
|
||||
### Disabling an extension
|
||||
|
||||
Extensions are, by default, enabled across all workspaces. You can disable an
|
||||
extension entirely or for specific workspace.
|
||||
|
||||
```
|
||||
gemini extensions disable <name> [--scope <scope>]
|
||||
```
|
||||
|
||||
- `<name>`: The name of the extension to disable.
|
||||
- `--scope`: The scope to disable the extension in (`user` or `workspace`).
|
||||
|
||||
### Enabling an extension
|
||||
|
||||
You can enable extensions using `gemini extensions enable <name>`. You can also
|
||||
enable an extension for a specific workspace using
|
||||
`gemini extensions enable <name> --scope=workspace` from within that workspace.
|
||||
|
||||
```
|
||||
gemini extensions enable <name> [--scope <scope>]
|
||||
```
|
||||
|
||||
- `<name>`: The name of the extension to enable.
|
||||
- `--scope`: The scope to enable the extension in (`user` or `workspace`).
|
||||
|
||||
### Updating an extension
|
||||
|
||||
For extensions installed from a local path or a git repository, you can
|
||||
explicitly update to the latest version (as reflected in the
|
||||
`gemini-extension.json` `version` field) with `gemini extensions update <name>`.
|
||||
|
||||
You can update all extensions with:
|
||||
|
||||
```
|
||||
gemini extensions update --all
|
||||
```
|
||||
|
||||
### Create a boilerplate extension
|
||||
|
||||
We offer several example extensions `context`, `custom-commands`,
|
||||
`exclude-tools` and `mcp-server`. You can view these examples
|
||||
[here](https://github.com/google-gemini/gemini-cli/tree/main/packages/cli/src/commands/extensions/examples).
|
||||
|
||||
To copy one of these examples into a development directory using the type of
|
||||
your choosing, run:
|
||||
|
||||
```
|
||||
gemini extensions new <path> [template]
|
||||
```
|
||||
|
||||
- `<path>`: The path to create the extension in.
|
||||
- `[template]`: The boilerplate template to use.
|
||||
|
||||
### Link a local extension
|
||||
|
||||
The `gemini extensions link` command will create a symbolic link from the
|
||||
extension installation directory to the development path.
|
||||
|
||||
This is useful so you don't have to run `gemini extensions update` every time
|
||||
you make changes you'd like to test.
|
||||
|
||||
```
|
||||
gemini extensions link <path>
|
||||
```
|
||||
|
||||
- `<path>`: The path of the extension to link.
|
||||
|
||||
## How it works
|
||||
|
||||
On startup, Gemini CLI looks for extensions in `<home>/.gemini/extensions`
|
||||
|
||||
Extensions exist as a directory that contains a `gemini-extension.json` file.
|
||||
For example:
|
||||
|
||||
`<home>/.gemini/extensions/my-extension/gemini-extension.json`
|
||||
|
||||
### `gemini-extension.json`
|
||||
|
||||
The `gemini-extension.json` file contains the configuration for the extension.
|
||||
The file has the following structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-extension",
|
||||
"version": "1.0.0",
|
||||
"mcpServers": {
|
||||
"my-server": {
|
||||
"command": "node my-server.js"
|
||||
}
|
||||
},
|
||||
"contextFileName": "GEMINI.md",
|
||||
"excludeTools": ["run_shell_command"]
|
||||
}
|
||||
```
|
||||
|
||||
- `name`: The name of the extension. This is used to uniquely identify the
|
||||
extension and for conflict resolution when extension commands have the same
|
||||
name as user or project commands. The name should be lowercase or numbers and
|
||||
use dashes instead of underscores or spaces. This is how users will refer to
|
||||
your extension in the CLI. Note that we expect this name to match the
|
||||
extension directory name.
|
||||
- `version`: The version of the extension.
|
||||
- `mcpServers`: A map of MCP servers to settings. The key is the name of the
|
||||
server, and the value is the server configuration. These servers will be
|
||||
loaded on startup just like MCP servers settings in a
|
||||
[`settings.json` file](../get-started/configuration.md). If both an extension
|
||||
and a `settings.json` file settings an MCP server with the same name, the
|
||||
server defined in the `settings.json` file takes precedence.
|
||||
- Note that all MCP server configuration options are supported except for
|
||||
`trust`.
|
||||
- `contextFileName`: The name of the file that contains the context for the
|
||||
extension. This will be used to load the context from the extension directory.
|
||||
If this property is not used but a `GEMINI.md` file is present in your
|
||||
extension directory, then that file will be loaded.
|
||||
- `excludeTools`: An array of tool names to exclude from the model. You can also
|
||||
specify command-specific restrictions for tools that support it, like the
|
||||
`run_shell_command` tool. For example,
|
||||
`"excludeTools": ["run_shell_command(rm -rf)"]` will block the `rm -rf`
|
||||
command. Note that this differs from the MCP server `excludeTools`
|
||||
functionality, which can be listed in the MCP server config.
|
||||
|
||||
When Gemini CLI starts, it loads all the extensions and merges their
|
||||
configurations. If there are any conflicts, the workspace configuration takes
|
||||
precedence.
|
||||
|
||||
### Settings
|
||||
|
||||
_Note: This is an experimental feature. We do not yet recommend extension
|
||||
authors introduce settings as part of their core flows._
|
||||
|
||||
Extensions can define settings that the user will be prompted to provide upon
|
||||
installation. This is useful for things like API keys, URLs, or other
|
||||
configuration that the extension needs to function.
|
||||
|
||||
To define settings, add a `settings` array to your `gemini-extension.json` file.
|
||||
Each object in the array should have the following properties:
|
||||
|
||||
- `name`: A user-friendly name for the setting.
|
||||
- `description`: A description of the setting and what it's used for.
|
||||
- `envVar`: The name of the environment variable that the setting will be stored
|
||||
as.
|
||||
- `sensitive`: Optional boolean. If true, obfuscates the input the user provides
|
||||
and stores the secret in keychain storage. **Example**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-api-extension",
|
||||
"version": "1.0.0",
|
||||
"settings": [
|
||||
{
|
||||
"name": "API Key",
|
||||
"description": "Your API key for the service.",
|
||||
"envVar": "MY_API_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
When a user installs this extension, they will be prompted to enter their API
|
||||
key. The value will be saved to a `.env` file in the extension's directory
|
||||
(e.g., `<home>/.gemini/extensions/my-api-extension/.env`).
|
||||
|
||||
You can view a list of an extension's settings by running:
|
||||
|
||||
```
|
||||
```bash
|
||||
gemini extensions list
|
||||
```
|
||||
|
||||
and you can update a given setting using:
|
||||
## Installation
|
||||
|
||||
```
|
||||
gemini extensions config <extension name> [setting name] [--scope <scope>]
|
||||
To install a real extension, you can use the `extensions install` command with a
|
||||
GitHub repository URL in noninteractive mode. For example:
|
||||
|
||||
```bash
|
||||
gemini extensions install https://github.com/gemini-cli-extensions/workspace
|
||||
```
|
||||
|
||||
- `--scope`: The scope to set the setting in (`user` or `workspace`). This is
|
||||
optional and will default to `user`.
|
||||
## Next steps
|
||||
|
||||
### Custom commands
|
||||
|
||||
Extensions can provide [custom commands](../cli/custom-commands.md) by placing
|
||||
TOML files in a `commands/` subdirectory within the extension directory. These
|
||||
commands follow the same format as user and project custom commands and use
|
||||
standard naming conventions.
|
||||
|
||||
**Example**
|
||||
|
||||
An extension named `gcp` with the following structure:
|
||||
|
||||
```
|
||||
.gemini/extensions/gcp/
|
||||
├── gemini-extension.json
|
||||
└── commands/
|
||||
├── deploy.toml
|
||||
└── gcs/
|
||||
└── sync.toml
|
||||
```
|
||||
|
||||
Would provide these commands:
|
||||
|
||||
- `/deploy` - Shows as `[gcp] Custom command from deploy.toml` in help
|
||||
- `/gcs:sync` - Shows as `[gcp] Custom command from sync.toml` in help
|
||||
|
||||
### Agent Skills
|
||||
|
||||
_Note: This is an experimental feature enabled via `experimental.skills`._
|
||||
|
||||
Extensions can bundle [Agent Skills](../cli/skills.md) to provide on-demand
|
||||
expertise and specialized workflows. To include skills in your extension, place
|
||||
them in a `skills/` subdirectory within the extension directory. Each skill must
|
||||
follow the [Agent Skills structure](../cli/skills.md#folder-structure),
|
||||
including a `SKILL.md` file.
|
||||
|
||||
**Example**
|
||||
|
||||
An extension named `security-toolkit` with the following structure:
|
||||
|
||||
```
|
||||
.gemini/extensions/security-toolkit/
|
||||
├── gemini-extension.json
|
||||
└── skills/
|
||||
├── audit/
|
||||
│ ├── SKILL.md
|
||||
│ └── scripts/
|
||||
│ └── scan.py
|
||||
└── hardening/
|
||||
└── SKILL.md
|
||||
```
|
||||
|
||||
Upon installation, these skills will be discovered by Gemini CLI and can be
|
||||
activated during a session when the model identifies a task matching their
|
||||
descriptions.
|
||||
|
||||
Extension skills have the lowest precedence and will be overridden by user or
|
||||
workspace skills of the same name. They can be viewed and managed (enabled or
|
||||
disabled) using the [`/skills` command](../cli/skills.md#managing-skills).
|
||||
|
||||
### Hooks
|
||||
|
||||
Extensions can provide [hooks](../hooks/index.md) to intercept and customize
|
||||
Gemini CLI behavior at specific lifecycle events. Hooks provided by an extension
|
||||
must be defined in a `hooks/hooks.json` file within the extension directory.
|
||||
|
||||
> [!IMPORTANT] Hooks are not defined directly in `gemini-extension.json`. The
|
||||
> CLI specifically looks for the `hooks/hooks.json` file.
|
||||
|
||||
#### Directory structure
|
||||
|
||||
```
|
||||
.gemini/extensions/my-extension/
|
||||
├── gemini-extension.json
|
||||
└── hooks/
|
||||
└── hooks.json
|
||||
```
|
||||
|
||||
#### `hooks/hooks.json` format
|
||||
|
||||
The `hooks.json` file contains a `hooks` object where keys are
|
||||
[event names](../hooks/reference.md#supported-events) and values are arrays of
|
||||
[hook definitions](../hooks/reference.md#hook-definition).
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"BeforeAgent": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "node ${extensionPath}/scripts/setup.js",
|
||||
"name": "Extension Setup"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Supported variables
|
||||
|
||||
Just like `gemini-extension.json`, the `hooks/hooks.json` file supports
|
||||
[variable substitution](#variables). This is particularly useful for referencing
|
||||
scripts within the extension directory using `${extensionPath}`.
|
||||
|
||||
### Conflict resolution
|
||||
|
||||
Extension commands have the lowest precedence. When a conflict occurs with user
|
||||
or project commands:
|
||||
|
||||
1. **No conflict**: Extension command uses its natural name (e.g., `/deploy`)
|
||||
2. **With conflict**: Extension command is renamed with the extension prefix
|
||||
(e.g., `/gcp.deploy`)
|
||||
|
||||
For example, if both a user and the `gcp` extension define a `deploy` command:
|
||||
|
||||
- `/deploy` - Executes the user's deploy command
|
||||
- `/gcp.deploy` - Executes the extension's deploy command (marked with `[gcp]`
|
||||
tag)
|
||||
|
||||
### Variables
|
||||
|
||||
Gemini CLI extensions allow variable substitution in both
|
||||
`gemini-extension.json` and `hooks/hooks.json`. This can be useful if e.g., you
|
||||
need the current directory to run an MCP server or hook script using
|
||||
`"cwd": "${extensionPath}${/}run.ts"`.
|
||||
|
||||
**Supported variables:**
|
||||
|
||||
| variable | description |
|
||||
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `${extensionPath}` | The fully-qualified path of the extension in the user's filesystem e.g., '/Users/username/.gemini/extensions/example-extension'. This will not unwrap symlinks. |
|
||||
| `${workspacePath}` | The fully-qualified path of the current workspace. |
|
||||
| `${/} or ${pathSeparator}` | The path separator (differs per OS). |
|
||||
| `${process.execPath}` | The path to the Node.js binary executing the CLI. |
|
||||
- [Writing extensions](writing-extensions.md): Learn how to create your first
|
||||
extension.
|
||||
- [Extensions reference](reference.md): Deeply understand the extension format,
|
||||
commands, and configuration.
|
||||
- [Best practices](best-practices.md): Learn strategies for building great
|
||||
extensions.
|
||||
- [Extensions releasing](releasing.md): Learn how to share your extensions with
|
||||
the world.
|
||||
|
||||
312
docs/extensions/reference.md
Normal file
312
docs/extensions/reference.md
Normal file
@@ -0,0 +1,312 @@
|
||||
# Extensions reference
|
||||
|
||||
This guide covers the `gemini extensions` commands and the structure of the
|
||||
`gemini-extension.json` configuration file.
|
||||
|
||||
## Extension management
|
||||
|
||||
We offer a suite of extension management tools using `gemini extensions`
|
||||
commands.
|
||||
|
||||
Note that these commands (e.g. `gemini extensions install`) are not supported
|
||||
from within the CLI's **interactive mode**, although you can list installed
|
||||
extensions using the `/extensions list` slash command.
|
||||
|
||||
Note that all of these management operations (including updates to slash
|
||||
commands) will only be reflected in active CLI sessions on **restart**.
|
||||
|
||||
### Installing an extension
|
||||
|
||||
You can install an extension using `gemini extensions install` with either a
|
||||
GitHub URL or a local path.
|
||||
|
||||
Note that we create a copy of the installed extension, so you will need to run
|
||||
`gemini extensions update` to pull in changes from both locally-defined
|
||||
extensions and those on GitHub.
|
||||
|
||||
NOTE: If you are installing an extension from GitHub, you'll need to have `git`
|
||||
installed on your machine. See
|
||||
[git installation instructions](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
|
||||
for help.
|
||||
|
||||
```
|
||||
gemini extensions install <source> [--ref <ref>] [--auto-update] [--pre-release] [--consent]
|
||||
```
|
||||
|
||||
- `<source>`: The github URL or local path of the extension to install.
|
||||
- `--ref`: The git ref to install from.
|
||||
- `--auto-update`: Enable auto-update for this extension.
|
||||
- `--pre-release`: Enable pre-release versions for this extension.
|
||||
- `--consent`: Acknowledge the security risks of installing an extension and
|
||||
skip the confirmation prompt.
|
||||
|
||||
### Uninstalling an extension
|
||||
|
||||
To uninstall one or more extensions, run
|
||||
`gemini extensions uninstall <name...>`:
|
||||
|
||||
```
|
||||
gemini extensions uninstall gemini-cli-security gemini-cli-another-extension
|
||||
```
|
||||
|
||||
### Disabling an extension
|
||||
|
||||
Extensions are, by default, enabled across all workspaces. You can disable an
|
||||
extension entirely or for specific workspace.
|
||||
|
||||
```
|
||||
gemini extensions disable <name> [--scope <scope>]
|
||||
```
|
||||
|
||||
- `<name>`: The name of the extension to disable.
|
||||
- `--scope`: The scope to disable the extension in (`user` or `workspace`).
|
||||
|
||||
### Enabling an extension
|
||||
|
||||
You can enable extensions using `gemini extensions enable <name>`. You can also
|
||||
enable an extension for a specific workspace using
|
||||
`gemini extensions enable <name> --scope=workspace` from within that workspace.
|
||||
|
||||
```
|
||||
gemini extensions enable <name> [--scope <scope>]
|
||||
```
|
||||
|
||||
- `<name>`: The name of the extension to enable.
|
||||
- `--scope`: The scope to enable the extension in (`user` or `workspace`).
|
||||
|
||||
### Updating an extension
|
||||
|
||||
For extensions installed from a local path or a git repository, you can
|
||||
explicitly update to the latest version (as reflected in the
|
||||
`gemini-extension.json` `version` field) with `gemini extensions update <name>`.
|
||||
|
||||
You can update all extensions with:
|
||||
|
||||
```
|
||||
gemini extensions update --all
|
||||
```
|
||||
|
||||
### Create a boilerplate extension
|
||||
|
||||
We offer several example extensions `context`, `custom-commands`,
|
||||
`exclude-tools` and `mcp-server`. You can view these examples
|
||||
[here](https://github.com/google-gemini/gemini-cli/tree/main/packages/cli/src/commands/extensions/examples).
|
||||
|
||||
To copy one of these examples into a development directory using the type of
|
||||
your choosing, run:
|
||||
|
||||
```
|
||||
gemini extensions new <path> [template]
|
||||
```
|
||||
|
||||
- `<path>`: The path to create the extension in.
|
||||
- `[template]`: The boilerplate template to use.
|
||||
|
||||
### Link a local extension
|
||||
|
||||
The `gemini extensions link` command will create a symbolic link from the
|
||||
extension installation directory to the development path.
|
||||
|
||||
This is useful so you don't have to run `gemini extensions update` every time
|
||||
you make changes you'd like to test.
|
||||
|
||||
```
|
||||
gemini extensions link <path>
|
||||
```
|
||||
|
||||
- `<path>`: The path of the extension to link.
|
||||
|
||||
## Extension format
|
||||
|
||||
On startup, Gemini CLI looks for extensions in `<home>/.gemini/extensions`
|
||||
|
||||
Extensions exist as a directory that contains a `gemini-extension.json` file.
|
||||
For example:
|
||||
|
||||
`<home>/.gemini/extensions/my-extension/gemini-extension.json`
|
||||
|
||||
### `gemini-extension.json`
|
||||
|
||||
The `gemini-extension.json` file contains the configuration for the extension.
|
||||
The file has the following structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-extension",
|
||||
"version": "1.0.0",
|
||||
"description": "My awesome extension",
|
||||
"mcpServers": {
|
||||
"my-server": {
|
||||
"command": "node my-server.js"
|
||||
}
|
||||
},
|
||||
"contextFileName": "GEMINI.md",
|
||||
"excludeTools": ["run_shell_command"]
|
||||
}
|
||||
```
|
||||
|
||||
- `name`: The name of the extension. This is used to uniquely identify the
|
||||
extension and for conflict resolution when extension commands have the same
|
||||
name as user or project commands. The name should be lowercase or numbers and
|
||||
use dashes instead of underscores or spaces. This is how users will refer to
|
||||
your extension in the CLI. Note that we expect this name to match the
|
||||
extension directory name.
|
||||
- `version`: The version of the extension.
|
||||
- `description`: A short description of the extension. This will be displayed on
|
||||
[geminicli.com/extensions](https://geminicli.com/extensions).
|
||||
- `mcpServers`: A map of MCP servers to settings. The key is the name of the
|
||||
server, and the value is the server configuration. These servers will be
|
||||
loaded on startup just like MCP servers settingsd in a
|
||||
[`settings.json` file](../get-started/configuration.md). If both an extension
|
||||
and a `settings.json` file settings an MCP server with the same name, the
|
||||
server defined in the `settings.json` file takes precedence.
|
||||
- Note that all MCP server configuration options are supported except for
|
||||
`trust`.
|
||||
- `contextFileName`: The name of the file that contains the context for the
|
||||
extension. This will be used to load the context from the extension directory.
|
||||
If this property is not used but a `GEMINI.md` file is present in your
|
||||
extension directory, then that file will be loaded.
|
||||
- `excludeTools`: An array of tool names to exclude from the model. You can also
|
||||
specify command-specific restrictions for tools that support it, like the
|
||||
`run_shell_command` tool. For example,
|
||||
`"excludeTools": ["run_shell_command(rm -rf)"]` will block the `rm -rf`
|
||||
command. Note that this differs from the MCP server `excludeTools`
|
||||
functionality, which can be listed in the MCP server config.
|
||||
|
||||
When Gemini CLI starts, it loads all the extensions and merges their
|
||||
configurations. If there are any conflicts, the workspace configuration takes
|
||||
precedence.
|
||||
|
||||
### Settings
|
||||
|
||||
_Note: This is an experimental feature. We do not yet recommend extension
|
||||
authors introduce settings as part of their core flows._
|
||||
|
||||
Extensions can define settings that the user will be prompted to provide upon
|
||||
installation. This is useful for things like API keys, URLs, or other
|
||||
configuration that the extension needs to function.
|
||||
|
||||
To define settings, add a `settings` array to your `gemini-extension.json` file.
|
||||
Each object in the array should have the following properties:
|
||||
|
||||
- `name`: A user-friendly name for the setting.
|
||||
- `description`: A description of the setting and what it's used for.
|
||||
- `envVar`: The name of the environment variable that the setting will be stored
|
||||
as.
|
||||
- `sensitive`: Optional boolean. If true, obfuscates the input the user provides
|
||||
and stores the secret in keychain storage. **Example**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-api-extension",
|
||||
"version": "1.0.0",
|
||||
"settings": [
|
||||
{
|
||||
"name": "API Key",
|
||||
"description": "Your API key for the service.",
|
||||
"envVar": "MY_API_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
When a user installs this extension, they will be prompted to enter their API
|
||||
key. The value will be saved to a `.env` file in the extension's directory
|
||||
(e.g., `<home>/.gemini/extensions/my-api-extension/.env`).
|
||||
|
||||
You can view a list of an extension's settings by running:
|
||||
|
||||
```
|
||||
gemini extensions list
|
||||
```
|
||||
|
||||
and you can update a given setting using:
|
||||
|
||||
```
|
||||
gemini extensions config <extension name> [setting name] [--scope <scope>]
|
||||
```
|
||||
|
||||
- `--scope`: The scope to set the setting in (`user` or `workspace`). This is
|
||||
optional and will default to `user`.
|
||||
|
||||
### Custom commands
|
||||
|
||||
Extensions can provide [custom commands](../cli/custom-commands.md) by placing
|
||||
TOML files in a `commands/` subdirectory within the extension directory. These
|
||||
commands follow the same format as user and project custom commands and use
|
||||
standard naming conventions.
|
||||
|
||||
**Example**
|
||||
|
||||
An extension named `gcp` with the following structure:
|
||||
|
||||
```
|
||||
.gemini/extensions/gcp/
|
||||
├── gemini-extension.json
|
||||
└── commands/
|
||||
├── deploy.toml
|
||||
└── gcs/
|
||||
└── sync.toml
|
||||
```
|
||||
|
||||
Would provide these commands:
|
||||
|
||||
- `/deploy` - Shows as `[gcp] Custom command from deploy.toml` in help
|
||||
- `/gcs:sync` - Shows as `[gcp] Custom command from sync.toml` in help
|
||||
|
||||
### Hooks
|
||||
|
||||
Extensions can provide [hooks](../hooks/index.md) to intercept and customize
|
||||
Gemini CLI behavior at specific lifecycle events. Hooks provided by an extension
|
||||
must be defined in a `hooks/hooks.json` file within the extension directory.
|
||||
|
||||
> [!IMPORTANT] Hooks are not defined directly in `gemini-extension.json`. The
|
||||
> CLI specifically looks for the `hooks/hooks.json` file.
|
||||
|
||||
### Agent Skills
|
||||
|
||||
Extensions can bundle [Agent Skills](../cli/skills.md) to provide specialized
|
||||
workflows. Skills must be placed in a `skills/` directory within the extension.
|
||||
|
||||
**Example**
|
||||
|
||||
An extension with the following structure:
|
||||
|
||||
```
|
||||
.gemini/extensions/my-extension/
|
||||
├── gemini-extension.json
|
||||
└── skills/
|
||||
└── security-audit/
|
||||
└── SKILL.md
|
||||
```
|
||||
|
||||
Will expose a `security-audit` skill that the model can activate.
|
||||
|
||||
### Conflict resolution
|
||||
|
||||
Extension commands have the lowest precedence. When a conflict occurs with user
|
||||
or project commands:
|
||||
|
||||
1. **No conflict**: Extension command uses its natural name (e.g., `/deploy`)
|
||||
2. **With conflict**: Extension command is renamed with the extension prefix
|
||||
(e.g., `/gcp.deploy`)
|
||||
|
||||
For example, if both a user and the `gcp` extension define a `deploy` command:
|
||||
|
||||
- `/deploy` - Executes the user's deploy command
|
||||
- `/gcp.deploy` - Executes the extension's deploy command (marked with `[gcp]`
|
||||
tag)
|
||||
|
||||
## Variables
|
||||
|
||||
Gemini CLI extensions allow variable substitution in `gemini-extension.json`.
|
||||
This can be useful if e.g., you need the current directory to run an MCP server
|
||||
using an argument like `"args": ["${extensionPath}${/}dist${/}server.js"]`.
|
||||
|
||||
**Supported variables:**
|
||||
|
||||
| variable | description |
|
||||
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `${extensionPath}` | The fully-qualified path of the extension in the user's filesystem e.g., '/Users/username/.gemini/extensions/example-extension'. This will not unwrap symlinks. |
|
||||
| `${workspacePath}` | The fully-qualified path of the current workspace. |
|
||||
| `${/} or ${pathSeparator}` | The path separator (differs per OS). |
|
||||
@@ -8,7 +8,19 @@ file.
|
||||
## Prerequisites
|
||||
|
||||
Before you start, make sure you have the Gemini CLI installed and a basic
|
||||
understanding of Node.js and TypeScript.
|
||||
understanding of Node.js.
|
||||
|
||||
## When to use what
|
||||
|
||||
Extensions offer a variety of ways to customize Gemini CLI.
|
||||
|
||||
| Feature | What it is | When to use it | Invoked by |
|
||||
| :------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------- |
|
||||
| **[MCP server](reference.md#mcp-servers)** | A standard way to expose new tools and data sources to the model. | Use this when you want the model to be able to _do_ new things, like fetching data from an internal API, querying a database, or controlling a local application. We also support MCP resources (which can replace custom commands) and system instructions (which can replace custom context) | Model |
|
||||
| **[Custom commands](../cli/custom-commands.md)** | A shortcut (like `/my-cmd`) that executes a pre-defined prompt or shell command. | Use this for repetitive tasks or to save long, complex prompts that you use frequently. Great for automation. | User |
|
||||
| **[Context file (`GEMINI.md`)](reference.md#contextfilename)** | A markdown file containing instructions that are loaded into the model's context at the start of every session. | Use this to define the "personality" of your extension, set coding standards, or provide essential knowledge that the model should always have. | CLI provides to model |
|
||||
| **[Agent skills](../cli/skills.md)** | A specialized set of instructions and workflows that the model activates only when needed. | Use this for complex, occasional tasks (like "create a PR" or "audit security") to avoid cluttering the main context window when the skill isn't being used. | Model |
|
||||
| **[Hooks](../hooks/index.md)** | A way to intercept and customize the CLI's behavior at specific lifecycle events (e.g., before/after a tool call). | Use this when you want to automate actions based on what the model is doing, like validating tool arguments, logging activity, or modifying the model's input/output. | CLI |
|
||||
|
||||
## Step 1: Create a new extension
|
||||
|
||||
@@ -26,10 +38,9 @@ This will create a new directory with the following structure:
|
||||
|
||||
```
|
||||
my-first-extension/
|
||||
├── example.ts
|
||||
├── example.js
|
||||
├── gemini-extension.json
|
||||
├── package.json
|
||||
└── tsconfig.json
|
||||
└── package.json
|
||||
```
|
||||
|
||||
## Step 2: Understand the extension files
|
||||
@@ -43,12 +54,12 @@ and use your extension.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-first-extension",
|
||||
"name": "mcp-server-example",
|
||||
"version": "1.0.0",
|
||||
"mcpServers": {
|
||||
"nodeServer": {
|
||||
"command": "node",
|
||||
"args": ["${extensionPath}${/}dist${/}example.js"],
|
||||
"args": ["${extensionPath}${/}example.js"],
|
||||
"cwd": "${extensionPath}"
|
||||
}
|
||||
}
|
||||
@@ -64,12 +75,12 @@ and use your extension.
|
||||
with the absolute path to your extension's installation directory. This
|
||||
allows your extension to work regardless of where it's installed.
|
||||
|
||||
### `example.ts`
|
||||
### `example.js`
|
||||
|
||||
This file contains the source code for your MCP server. It's a simple Node.js
|
||||
server that uses the `@modelcontextprotocol/sdk`.
|
||||
|
||||
```typescript
|
||||
```javascript
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
@@ -118,16 +129,15 @@ await server.connect(transport);
|
||||
This server defines a single tool called `fetch_posts` that fetches data from a
|
||||
public API.
|
||||
|
||||
### `package.json` and `tsconfig.json`
|
||||
### `package.json`
|
||||
|
||||
These are standard configuration files for a TypeScript project. The
|
||||
`package.json` file defines dependencies and a `build` script, and
|
||||
`tsconfig.json` configures the TypeScript compiler.
|
||||
This is the standard configuration file for a Node.js project. It defines
|
||||
dependencies and scripts.
|
||||
|
||||
## Step 3: Build and link your extension
|
||||
## Step 3: Link your extension
|
||||
|
||||
Before you can use the extension, you need to compile the TypeScript code and
|
||||
link the extension to your Gemini CLI installation for local development.
|
||||
Before you can use the extension, you need to link it to your Gemini CLI
|
||||
installation for local development.
|
||||
|
||||
1. **Install dependencies:**
|
||||
|
||||
@@ -136,16 +146,7 @@ link the extension to your Gemini CLI installation for local development.
|
||||
npm install
|
||||
```
|
||||
|
||||
2. **Build the server:**
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
This will compile `example.ts` into `dist/example.js`, which is the file
|
||||
referenced in your `gemini-extension.json`.
|
||||
|
||||
3. **Link the extension:**
|
||||
2. **Link the extension:**
|
||||
|
||||
The `link` command creates a symbolic link from the Gemini CLI extensions
|
||||
directory to your development directory. This means any changes you make
|
||||
@@ -212,7 +213,7 @@ need this for extensions built to expose commands and prompts.
|
||||
"mcpServers": {
|
||||
"nodeServer": {
|
||||
"command": "node",
|
||||
"args": ["${extensionPath}${/}dist${/}example.js"],
|
||||
"args": ["${extensionPath}${/}example.js"],
|
||||
"cwd": "${extensionPath}"
|
||||
}
|
||||
}
|
||||
@@ -265,7 +266,7 @@ primary ways of releasing extensions are via a Git repository or through GitHub
|
||||
Releases. Using a public Git repository is the simplest method.
|
||||
|
||||
For detailed instructions on both methods, please refer to the
|
||||
[Extension Releasing Guide](./extension-releasing.md).
|
||||
[Extension Releasing Guide](./releasing.md).
|
||||
|
||||
## Conclusion
|
||||
|
||||
@@ -102,10 +102,10 @@ This documentation is organized into the following sections:
|
||||
|
||||
- **[Introduction: Extensions](./extensions/index.md):** How to extend the CLI
|
||||
with new functionality.
|
||||
- **[Get Started with extensions](./extensions/getting-started-extensions.md):**
|
||||
Learn how to build your own extension.
|
||||
- **[Extension releasing](./extensions/extension-releasing.md):** How to release
|
||||
Gemini CLI extensions.
|
||||
- **[Writing extensions](./extensions/writing-extensions.md):** Learn how to
|
||||
build your own extension.
|
||||
- **[Extension releasing](./extensions/releasing.md):** How to release Gemini
|
||||
CLI extensions.
|
||||
|
||||
### Hooks
|
||||
|
||||
|
||||
@@ -192,12 +192,20 @@
|
||||
"slug": "docs/extensions"
|
||||
},
|
||||
{
|
||||
"label": "Get started with extensions",
|
||||
"slug": "docs/extensions/getting-started-extensions"
|
||||
"label": "Writing extensions",
|
||||
"slug": "docs/extensions/writing-extensions"
|
||||
},
|
||||
{
|
||||
"label": "Extension releasing",
|
||||
"slug": "docs/extensions/extension-releasing"
|
||||
"label": "Extensions reference",
|
||||
"slug": "docs/extensions/reference"
|
||||
},
|
||||
{
|
||||
"label": "Best practices",
|
||||
"slug": "docs/extensions/best-practices"
|
||||
},
|
||||
{
|
||||
"label": "Extensions releasing",
|
||||
"slug": "docs/extensions/releasing"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user