mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
Docs: Clarify extensions documentation. (#19277)
This commit is contained in:
@@ -1,19 +1,19 @@
|
|||||||
# Extensions on Gemini CLI: Best practices
|
# Gemini CLI extension best practices
|
||||||
|
|
||||||
This guide covers best practices for developing, securing, and maintaining
|
This guide covers best practices for developing, securing, and maintaining
|
||||||
Gemini CLI extensions.
|
Gemini CLI extensions.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
Developing extensions for Gemini CLI is intended to be a lightweight, iterative
|
Developing extensions for Gemini CLI is a lightweight, iterative process. Use
|
||||||
process.
|
these strategies to build robust and efficient extensions.
|
||||||
|
|
||||||
### Structure your extension
|
### Structure your extension
|
||||||
|
|
||||||
While simple extensions can just be a few files, we recommend a robust structure
|
While simple extensions may contain only a few files, we recommend a organized
|
||||||
for complex extensions:
|
structure for complex projects.
|
||||||
|
|
||||||
```
|
```text
|
||||||
my-extension/
|
my-extension/
|
||||||
├── package.json
|
├── package.json
|
||||||
├── tsconfig.json
|
├── tsconfig.json
|
||||||
@@ -24,47 +24,50 @@ my-extension/
|
|||||||
└── dist/
|
└── dist/
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Use TypeScript**: We strongly recommend using TypeScript for type safety and
|
- **Use TypeScript:** We strongly recommend using TypeScript for type safety and
|
||||||
better tooling.
|
improved developer experience.
|
||||||
- **Separate source and build**: Keep your source code in `src` and build to
|
- **Separate source and build:** Keep your source code in `src/` and output
|
||||||
`dist`.
|
build artifacts to `dist/`.
|
||||||
- **Bundle dependencies**: If your extension has many dependencies, consider
|
- **Bundle dependencies:** If your extension has many dependencies, bundle them
|
||||||
bundling them (e.g., with `esbuild` or `webpack`) to reduce install time and
|
using a tool like `esbuild` to reduce installation time and avoid conflicts.
|
||||||
potential conflicts.
|
|
||||||
|
|
||||||
### Iterate with `link`
|
### Iterate with `link`
|
||||||
|
|
||||||
Use `gemini extensions link` to develop locally without constantly reinstalling:
|
Use the `gemini extensions link` command to develop locally without reinstalling
|
||||||
|
your extension after every change.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd my-extension
|
cd my-extension
|
||||||
gemini extensions link .
|
gemini extensions link .
|
||||||
```
|
```
|
||||||
|
|
||||||
Changes to your code (after rebuilding) will be immediately available in the CLI
|
Changes to your code are immediately available in the CLI after you rebuild the
|
||||||
on restart.
|
project and restart the session.
|
||||||
|
|
||||||
### Use `GEMINI.md` effectively
|
### Use `GEMINI.md` effectively
|
||||||
|
|
||||||
Your `GEMINI.md` file provides context to the model. Keep it focused:
|
Your `GEMINI.md` file provides essential context to the model.
|
||||||
|
|
||||||
- **Do:** Explain high-level goals and how to use the provided tools.
|
- **Focus on goals:** Explain the high-level purpose of the extension and how to
|
||||||
- **Don't:** Dump your entire documentation.
|
interact with its tools.
|
||||||
- **Do:** Use clear, concise language.
|
- **Be concise:** Avoid dumping exhaustive documentation into the file. Use
|
||||||
|
clear, direct language.
|
||||||
|
- **Provide examples:** Include brief examples of how the model should use
|
||||||
|
specific tools or commands.
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
When building a Gemini CLI extension, follow general security best practices
|
Follow the principle of least privilege and rigorous input validation when
|
||||||
(such as least privilege and input validation) to reduce risk.
|
building extensions.
|
||||||
|
|
||||||
### Minimal permissions
|
### Minimal permissions
|
||||||
|
|
||||||
When defining tools in your MCP server, only request the permissions necessary.
|
Only request the permissions your MCP server needs to function. Avoid giving the
|
||||||
Avoid giving the model broad access (like full shell access) if a more
|
model broad access (such as full shell access) if restricted tools are
|
||||||
restricted set of tools will suffice.
|
sufficient.
|
||||||
|
|
||||||
If you must use powerful tools like `run_shell_command`, consider restricting
|
If your extension uses powerful tools like `run_shell_command`, restrict them in
|
||||||
them to specific commands in your `gemini-extension.json`:
|
your `gemini-extension.json` file:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -73,27 +76,26 @@ them to specific commands in your `gemini-extension.json`:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This ensures that even if the model tries to execute a dangerous command, it
|
This ensures the CLI blocks dangerous commands even if the model attempts to
|
||||||
will be blocked at the CLI level.
|
execute them.
|
||||||
|
|
||||||
### Validate inputs
|
### Validate inputs
|
||||||
|
|
||||||
Your MCP server is running on the user's machine. Always validate inputs to your
|
Your MCP server runs on the user's machine. Always validate tool inputs to
|
||||||
tools to prevent arbitrary code execution or filesystem access outside the
|
prevent arbitrary code execution or unauthorized filesystem access.
|
||||||
intended scope.
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// Good: Validating paths
|
// Example: Validating paths
|
||||||
if (!path.resolve(inputPath).startsWith(path.resolve(allowedDir) + path.sep)) {
|
if (!path.resolve(inputPath).startsWith(path.resolve(allowedDir) + path.sep)) {
|
||||||
throw new Error('Access denied');
|
throw new Error('Access denied');
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Sensitive settings
|
### Secure sensitive settings
|
||||||
|
|
||||||
If your extension requires API keys, use the `sensitive: true` option in
|
If your extension requires API keys or other secrets, use the `sensitive: true`
|
||||||
`gemini-extension.json`. This ensures keys are stored securely in the system
|
option in your manifest. This ensures keys are stored in the system keychain and
|
||||||
keychain and obfuscated in the UI.
|
obfuscated in the CLI output.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"settings": [
|
"settings": [
|
||||||
@@ -105,35 +107,82 @@ keychain and obfuscated in the UI.
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Releasing
|
## Release
|
||||||
|
|
||||||
You can upload your extension directly to GitHub to list it in the gallery.
|
Follow standard versioning and release practices to ensure a smooth experience
|
||||||
Gemini CLI extensions also offers support for more complicated
|
for your users.
|
||||||
[releases](releasing.md).
|
|
||||||
|
|
||||||
### Semantic versioning
|
### Semantic versioning
|
||||||
|
|
||||||
Follow [Semantic Versioning](https://semver.org/).
|
Follow [Semantic Versioning (SemVer)](https://semver.org/) to communicate
|
||||||
|
changes clearly.
|
||||||
|
|
||||||
- **Major**: Breaking changes (renaming tools, changing arguments).
|
- **Major:** Breaking changes (e.g., renaming tools or changing arguments).
|
||||||
- **Minor**: New features (new tools, commands).
|
- **Minor:** New features (e.g., adding new tools or commands).
|
||||||
- **Patch**: Bug fixes.
|
- **Patch:** Bug fixes and performance improvements.
|
||||||
|
|
||||||
### Release Channels
|
### Release channels
|
||||||
|
|
||||||
Use git branches to manage release channels (e.g., `main` for stable, `dev` for
|
Use Git branches to manage release channels. This lets users choose between
|
||||||
bleeding edge). This allows users to choose their stability level:
|
stability and the latest features.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Stable
|
# Install the stable version (default branch)
|
||||||
gemini extensions install github.com/user/repo
|
gemini extensions install github.com/user/repo
|
||||||
|
|
||||||
# Dev
|
# Install the development version
|
||||||
gemini extensions install github.com/user/repo --ref dev
|
gemini extensions install github.com/user/repo --ref dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### Clean artifacts
|
### Clean artifacts
|
||||||
|
|
||||||
If you are using GitHub Releases, ensure your release artifacts only contain the
|
When using GitHub Releases, ensure your archives only contain necessary files
|
||||||
necessary files (`dist/`, `gemini-extension.json`, `package.json`). Exclude
|
(such as `dist/`, `gemini-extension.json`, and `package.json`). Exclude
|
||||||
`node_modules` (users will install them) and `src/` to keep downloads small.
|
`node_modules/` and `src/` to minimize download size.
|
||||||
|
|
||||||
|
## Test and verify
|
||||||
|
|
||||||
|
Test your extension thoroughly before releasing it to users.
|
||||||
|
|
||||||
|
- **Manual verification:** Use `gemini extensions link` to test your extension
|
||||||
|
in a live CLI session. Verify that tools appear in the debug console (F12) and
|
||||||
|
that custom commands resolve correctly.
|
||||||
|
- **Automated testing:** If your extension includes an MCP server, write unit
|
||||||
|
tests for your tool logic using a framework like Vitest or Jest. You can test
|
||||||
|
MCP tools in isolation by mocking the transport layer.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
Use these tips to diagnose and fix common extension issues.
|
||||||
|
|
||||||
|
### Extension not loading
|
||||||
|
|
||||||
|
If your extension doesn't appear in `/extensions list`:
|
||||||
|
|
||||||
|
- **Check the manifest:** Ensure `gemini-extension.json` is in the root
|
||||||
|
directory and contains valid JSON.
|
||||||
|
- **Verify the name:** The `name` field in the manifest must match the extension
|
||||||
|
directory name exactly.
|
||||||
|
- **Restart the CLI:** Extensions are loaded at the start of a session. Restart
|
||||||
|
Gemini CLI after making changes to the manifest or linking a new extension.
|
||||||
|
|
||||||
|
### MCP server failures
|
||||||
|
|
||||||
|
If your tools aren't working as expected:
|
||||||
|
|
||||||
|
- **Check the logs:** View the CLI logs to see if the MCP server failed to
|
||||||
|
start.
|
||||||
|
- **Test the command:** Run the server's `command` and `args` directly in your
|
||||||
|
terminal to ensure it starts correctly outside of Gemini CLI.
|
||||||
|
- **Debug console:** In interactive mode, press **F12** to open the debug
|
||||||
|
console and inspect tool calls and responses.
|
||||||
|
|
||||||
|
### Command conflicts
|
||||||
|
|
||||||
|
If a custom command isn't responding:
|
||||||
|
|
||||||
|
- **Check precedence:** Remember that user and project commands take precedence
|
||||||
|
over extension commands. Use the prefixed name (e.g., `/extension.command`) to
|
||||||
|
verify the extension's version.
|
||||||
|
- **Help command:** Run `/help` to see a list of all available commands and
|
||||||
|
their sources.
|
||||||
|
|||||||
+34
-18
@@ -6,19 +6,44 @@ With extensions, you can expand the capabilities of Gemini CLI and share those
|
|||||||
capabilities with others. They are designed to be easily installable and
|
capabilities with others. They are designed to be easily installable and
|
||||||
shareable.
|
shareable.
|
||||||
|
|
||||||
To see examples of extensions, you can browse a gallery of
|
To see what's possible, browse the
|
||||||
[Gemini CLI extensions](https://geminicli.com/extensions/browse/).
|
[Gemini CLI extension gallery](https://geminicli.com/extensions/browse/).
|
||||||
|
|
||||||
## Managing extensions
|
## Choose your path
|
||||||
|
|
||||||
You can verify your installed extensions and their status using the interactive
|
Choose the guide that best fits your needs.
|
||||||
command:
|
|
||||||
|
### I want to use extensions
|
||||||
|
|
||||||
|
Learn how to discover, install, and manage extensions to enhance your Gemini CLI
|
||||||
|
experience.
|
||||||
|
|
||||||
|
- **[Manage extensions](#manage-extensions):** List and verify your installed
|
||||||
|
extensions.
|
||||||
|
- **[Install extensions](#installation):** Add new capabilities from GitHub or
|
||||||
|
local paths.
|
||||||
|
|
||||||
|
### I want to build extensions
|
||||||
|
|
||||||
|
Learn how to create, test, and share your own extensions with the community.
|
||||||
|
|
||||||
|
- **[Build extensions](writing-extensions.md):** Create your first extension
|
||||||
|
from a template.
|
||||||
|
- **[Best practices](best-practices.md):** Learn how to build secure and
|
||||||
|
reliable extensions.
|
||||||
|
- **[Publish to the gallery](releasing.md):** Share your work with the world.
|
||||||
|
|
||||||
|
## Manage extensions
|
||||||
|
|
||||||
|
Use the interactive `/extensions` command to verify your installed extensions
|
||||||
|
and their status:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/extensions list
|
/extensions list
|
||||||
```
|
```
|
||||||
|
|
||||||
or in noninteractive mode:
|
You can also manage extensions from your terminal using the `gemini extensions`
|
||||||
|
command group:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gemini extensions list
|
gemini extensions list
|
||||||
@@ -26,20 +51,11 @@ gemini extensions list
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
To install a real extension, you can use the `extensions install` command with a
|
Install an extension by providing its GitHub repository URL. For example:
|
||||||
GitHub repository URL in noninteractive mode. For example:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gemini extensions install https://github.com/gemini-cli-extensions/workspace
|
gemini extensions install https://github.com/gemini-cli-extensions/workspace
|
||||||
```
|
```
|
||||||
|
|
||||||
## Next steps
|
For more advanced installation options, see the
|
||||||
|
[Extension reference](reference.md#install-an-extension).
|
||||||
- [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.
|
|
||||||
|
|||||||
+107
-222
@@ -1,134 +1,113 @@
|
|||||||
# Extensions reference
|
# Extension reference
|
||||||
|
|
||||||
This guide covers the `gemini extensions` commands and the structure of the
|
This guide covers the `gemini extensions` commands and the structure of the
|
||||||
`gemini-extension.json` configuration file.
|
`gemini-extension.json` configuration file.
|
||||||
|
|
||||||
## Extension management
|
## Manage extensions
|
||||||
|
|
||||||
We offer a suite of extension management tools using `gemini extensions`
|
Use the `gemini extensions` command group to manage your extensions from the
|
||||||
commands.
|
terminal.
|
||||||
|
|
||||||
Note that these commands (e.g. `gemini extensions install`) are not supported
|
Note that commands like `gemini extensions install` are not supported within the
|
||||||
from within the CLI's **interactive mode**, although you can list installed
|
CLI's interactive mode. However, you can use the `/extensions list` command to
|
||||||
extensions using the `/extensions list` slash command.
|
view installed extensions. All management operations, including updates to slash
|
||||||
|
commands, take effect only after you restart the CLI session.
|
||||||
|
|
||||||
Note that all of these management operations (including updates to slash
|
### Install an extension
|
||||||
commands) will only be reflected in active CLI sessions on **restart**.
|
|
||||||
|
|
||||||
### Installing an extension
|
Install an extension by providing its GitHub repository URL or a local file
|
||||||
|
path.
|
||||||
|
|
||||||
You can install an extension using `gemini extensions install` with either a
|
Gemini CLI creates a copy of the extension during installation. You must run
|
||||||
GitHub URL or a local path.
|
`gemini extensions update` to pull changes from the source. To install from
|
||||||
|
GitHub, you must have `git` installed on your machine.
|
||||||
|
|
||||||
Note that we create a copy of the installed extension, so you will need to run
|
```bash
|
||||||
`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]
|
gemini extensions install <source> [--ref <ref>] [--auto-update] [--pre-release] [--consent]
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<source>`: The github URL or local path of the extension to install.
|
- `<source>`: The GitHub URL or local path of the extension.
|
||||||
- `--ref`: The git ref to install from.
|
- `--ref`: The git ref (branch, tag, or commit) to install.
|
||||||
- `--auto-update`: Enable auto-update for this extension.
|
- `--auto-update`: Enable automatic updates for this extension.
|
||||||
- `--pre-release`: Enable pre-release versions for this extension.
|
- `--pre-release`: Enable installation of pre-release versions.
|
||||||
- `--consent`: Acknowledge the security risks of installing an extension and
|
- `--consent`: Acknowledge security risks and skip the confirmation prompt.
|
||||||
skip the confirmation prompt.
|
|
||||||
|
|
||||||
### Uninstalling an extension
|
### Uninstall an extension
|
||||||
|
|
||||||
To uninstall one or more extensions, run
|
To uninstall one or more extensions, use the `uninstall` command:
|
||||||
`gemini extensions uninstall <name...>`:
|
|
||||||
|
|
||||||
```
|
```bash
|
||||||
gemini extensions uninstall gemini-cli-security gemini-cli-another-extension
|
gemini extensions uninstall <name...>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Disabling an extension
|
### Disable an extension
|
||||||
|
|
||||||
Extensions are, by default, enabled across all workspaces. You can disable an
|
Extensions are enabled globally by default. You can disable an extension
|
||||||
extension entirely or for specific workspace.
|
entirely or for a specific workspace.
|
||||||
|
|
||||||
```
|
```bash
|
||||||
gemini extensions disable <name> [--scope <scope>]
|
gemini extensions disable <name> [--scope <scope>]
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<name>`: The name of the extension to disable.
|
- `<name>`: The name of the extension to disable.
|
||||||
- `--scope`: The scope to disable the extension in (`user` or `workspace`).
|
- `--scope`: The scope to disable the extension in (`user` or `workspace`).
|
||||||
|
|
||||||
### Enabling an extension
|
### Enable an extension
|
||||||
|
|
||||||
You can enable extensions using `gemini extensions enable <name>`. You can also
|
Re-enable a disabled extension using the `enable` command:
|
||||||
enable an extension for a specific workspace using
|
|
||||||
`gemini extensions enable <name> --scope=workspace` from within that workspace.
|
|
||||||
|
|
||||||
```
|
```bash
|
||||||
gemini extensions enable <name> [--scope <scope>]
|
gemini extensions enable <name> [--scope <scope>]
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<name>`: The name of the extension to enable.
|
- `<name>`: The name of the extension to enable.
|
||||||
- `--scope`: The scope to enable the extension in (`user` or `workspace`).
|
- `--scope`: The scope to enable the extension in (`user` or `workspace`).
|
||||||
|
|
||||||
### Updating an extension
|
### Update an extension
|
||||||
|
|
||||||
For extensions installed from a local path or a git repository, you can
|
Update an extension to the version specified in its `gemini-extension.json`
|
||||||
explicitly update to the latest version (as reflected in the
|
file.
|
||||||
`gemini-extension.json` `version` field) with `gemini extensions update <name>`.
|
|
||||||
|
|
||||||
You can update all extensions with:
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gemini extensions update <name>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To update all installed extensions at once:
|
||||||
|
|
||||||
|
```bash
|
||||||
gemini extensions update --all
|
gemini extensions update --all
|
||||||
```
|
```
|
||||||
|
|
||||||
### Create a boilerplate extension
|
### Create an extension from a template
|
||||||
|
|
||||||
We offer several example extensions `context`, `custom-commands`,
|
Create a new extension directory using a built-in template.
|
||||||
`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
|
```bash
|
||||||
your choosing, run:
|
|
||||||
|
|
||||||
```
|
|
||||||
gemini extensions new <path> [template]
|
gemini extensions new <path> [template]
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<path>`: The path to create the extension in.
|
- `<path>`: The directory to create.
|
||||||
- `[template]`: The boilerplate template to use.
|
- `[template]`: The template to use (e.g., `mcp-server`, `context`,
|
||||||
|
`custom-commands`).
|
||||||
|
|
||||||
### Link a local extension
|
### Link a local extension
|
||||||
|
|
||||||
The `gemini extensions link` command will create a symbolic link from the
|
Create a symbolic link between your development directory and the Gemini CLI
|
||||||
extension installation directory to the development path.
|
extensions directory. This lets you test changes immediately without
|
||||||
|
reinstalling.
|
||||||
|
|
||||||
This is useful so you don't have to run `gemini extensions update` every time
|
```bash
|
||||||
you make changes you'd like to test.
|
|
||||||
|
|
||||||
```
|
|
||||||
gemini extensions link <path>
|
gemini extensions link <path>
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<path>`: The path of the extension to link.
|
|
||||||
|
|
||||||
## Extension format
|
## Extension format
|
||||||
|
|
||||||
On startup, Gemini CLI looks for extensions in `<home>/.gemini/extensions`
|
Gemini CLI loads extensions from `<home>/.gemini/extensions`. Each extension
|
||||||
|
must have a `gemini-extension.json` file in its root directory.
|
||||||
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`
|
### `gemini-extension.json`
|
||||||
|
|
||||||
The `gemini-extension.json` file contains the configuration for the extension.
|
The manifest file defines the extension's behavior and configuration.
|
||||||
The file has the following structure:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -145,56 +124,27 @@ The file has the following structure:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `name`: The name of the extension. This is used to uniquely identify the
|
- `name`: A unique identifier for the extension. Use lowercase letters, numbers,
|
||||||
extension and for conflict resolution when extension commands have the same
|
and dashes. This name must match the extension's directory name.
|
||||||
name as user or project commands. The name should be lowercase or numbers and
|
- `version`: The current version of the extension.
|
||||||
use dashes instead of underscores or spaces. This is how users will refer to
|
- `description`: A short summary shown in the extension gallery.
|
||||||
your extension in the CLI. Note that we expect this name to match the
|
- <a id="mcp-servers"></a>`mcpServers`: A map of Model Context Protocol (MCP)
|
||||||
extension directory name.
|
servers. Extension servers follow the same format as standard
|
||||||
- `version`: The version of the extension.
|
[CLI configuration](../get-started/configuration.md).
|
||||||
- `description`: A short description of the extension. This will be displayed on
|
- `contextFileName`: The name of the context file (defaults to `GEMINI.md`). Can
|
||||||
[geminicli.com/extensions](https://geminicli.com/extensions).
|
also be an array of strings to load multiple context files.
|
||||||
- `mcpServers`: A map of MCP servers to settings. The key is the name of the
|
- `excludeTools`: An array of tools to block from the model. You can restrict
|
||||||
server, and the value is the server configuration. These servers will be
|
specific arguments, such as `run_shell_command(rm -rf)`.
|
||||||
loaded on startup just like MCP servers settingsd in a
|
- `themes`: An optional list of themes provided by the extension. See
|
||||||
[`settings.json` file](../get-started/configuration.md). If both an extension
|
[Themes](../cli/themes.md) for more information.
|
||||||
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.
|
|
||||||
- `themes`: An array of custom themes provided by the extension. Each theme is
|
|
||||||
an object that defines the color scheme for the CLI UI. See the
|
|
||||||
[Themes guide](../cli/themes.md) for more details on the theme format.
|
|
||||||
|
|
||||||
When Gemini CLI starts, it loads all the extensions and merges their
|
### Extension settings
|
||||||
configurations. If there are any conflicts, the workspace configuration takes
|
|
||||||
precedence.
|
|
||||||
|
|
||||||
### Settings
|
Extensions can define settings that users provide during installation, such as
|
||||||
|
API keys or URLs. These values are stored in a `.env` file within the extension
|
||||||
|
directory.
|
||||||
|
|
||||||
Extensions can define settings that the user will be prompted to provide upon
|
To define settings, add a `settings` array to your manifest:
|
||||||
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
|
```json
|
||||||
{
|
{
|
||||||
@@ -204,106 +154,54 @@ Each object in the array should have the following properties:
|
|||||||
{
|
{
|
||||||
"name": "API Key",
|
"name": "API Key",
|
||||||
"description": "Your API key for the service.",
|
"description": "Your API key for the service.",
|
||||||
"envVar": "MY_API_KEY"
|
"envVar": "MY_API_KEY",
|
||||||
|
"sensitive": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
When a user installs this extension, they will be prompted to enter their API
|
- `name`: The setting's display name.
|
||||||
key. The value will be saved to a `.env` file in the extension's directory
|
- `description`: A clear explanation of the setting.
|
||||||
(e.g., `<home>/.gemini/extensions/my-api-extension/.env`).
|
- `envVar`: The environment variable name where the value is stored.
|
||||||
|
- `sensitive`: If `true`, the value is stored in the system keychain and
|
||||||
|
obfuscated in the UI.
|
||||||
|
|
||||||
You can view a list of an extension's settings by running:
|
To update an extension's settings:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gemini extensions config <name> [setting] [--scope <scope>]
|
||||||
```
|
```
|
||||||
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
|
### Custom commands
|
||||||
|
|
||||||
Extensions can provide [custom commands](../cli/custom-commands.md) by placing
|
Provide [custom commands](../cli/custom-commands.md) by placing TOML files in a
|
||||||
TOML files in a `commands/` subdirectory within the extension directory. These
|
`commands/` subdirectory. Gemini CLI uses the directory structure to determine
|
||||||
commands follow the same format as user and project custom commands and use
|
the command name.
|
||||||
standard naming conventions.
|
|
||||||
|
|
||||||
**Example**
|
For an extension named `gcp`:
|
||||||
|
|
||||||
An extension named `gcp` with the following structure:
|
- `commands/deploy.toml` becomes `/deploy`
|
||||||
|
- `commands/gcs/sync.toml` becomes `/gcs:sync` (namespaced with a colon)
|
||||||
```
|
|
||||||
.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
|
### Hooks
|
||||||
|
|
||||||
Extensions can provide [hooks](../hooks/index.md) to intercept and customize
|
Intercept and customize CLI behavior using [hooks](../hooks/index.md). Define
|
||||||
Gemini CLI behavior at specific lifecycle events. Hooks provided by an extension
|
hooks in a `hooks/hooks.json` file within your extension directory. Note that
|
||||||
must be defined in a `hooks/hooks.json` file within the extension directory.
|
hooks are not defined in the `gemini-extension.json` manifest.
|
||||||
|
|
||||||
> [!IMPORTANT] Hooks are not defined directly in `gemini-extension.json`. The
|
### Agent skills
|
||||||
> CLI specifically looks for the `hooks/hooks.json` file.
|
|
||||||
|
|
||||||
### Agent Skills
|
Bundle [agent skills](../cli/skills.md) to provide specialized workflows. Place
|
||||||
|
skill definitions in a `skills/` directory. For example,
|
||||||
Extensions can bundle [Agent Skills](../cli/skills.md) to provide specialized
|
`skills/security-audit/SKILL.md` exposes a `security-audit` skill.
|
||||||
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.
|
|
||||||
|
|
||||||
### Sub-agents
|
### Sub-agents
|
||||||
|
|
||||||
> **Note: Sub-agents are currently an experimental feature.**
|
> **Note:** Sub-agents are a preview feature currently under active development.
|
||||||
|
|
||||||
Extensions can provide [sub-agents](../core/subagents.md) that users can
|
Provide [sub-agents](../core/subagents.md) that users can delegate tasks to. Add
|
||||||
delegate tasks to.
|
agent definition files (`.md`) to an `agents/` directory in your extension root.
|
||||||
|
|
||||||
To bundle sub-agents with your extension, create an `agents/` directory in your
|
|
||||||
extension's root folder and add your agent definition files (`.md`) there.
|
|
||||||
|
|
||||||
**Example**
|
|
||||||
|
|
||||||
```
|
|
||||||
.gemini/extensions/my-extension/
|
|
||||||
├── gemini-extension.json
|
|
||||||
└── agents/
|
|
||||||
├── security-auditor.md
|
|
||||||
└── database-expert.md
|
|
||||||
```
|
|
||||||
|
|
||||||
Gemini CLI will automatically discover and load these agents when the extension
|
|
||||||
is installed and enabled.
|
|
||||||
|
|
||||||
### Themes
|
### Themes
|
||||||
|
|
||||||
@@ -351,30 +249,17 @@ the theme name in parentheses, e.g., `shades-of-green (my-green-extension)`.
|
|||||||
|
|
||||||
### Conflict resolution
|
### Conflict resolution
|
||||||
|
|
||||||
Extension commands have the lowest precedence. When a conflict occurs with user
|
Extension commands have the lowest precedence. If an extension command name
|
||||||
or project commands:
|
conflicts with a user or project command, the extension command is prefixed with
|
||||||
|
the extension name (e.g., `/gcp.deploy`) using a dot separator.
|
||||||
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
|
## Variables
|
||||||
|
|
||||||
Gemini CLI extensions allow variable substitution in both
|
Gemini CLI supports variable substitution in `gemini-extension.json` and
|
||||||
`gemini-extension.json` and `hooks/hooks.json`. This can be useful if e.g., you
|
`hooks/hooks.json`.
|
||||||
need the current directory to run an MCP server using an argument like
|
|
||||||
`"args": ["${extensionPath}${/}dist${/}server.js"]`.
|
|
||||||
|
|
||||||
**Supported variables:**
|
| Variable | Description |
|
||||||
|
| :----------------- | :---------------------------------------------- |
|
||||||
| variable | description |
|
| `${extensionPath}` | The absolute path to the extension's directory. |
|
||||||
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| `${workspacePath}` | The absolute path to the current workspace. |
|
||||||
| `${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. |
|
| `${/}` | The platform-specific path separator. |
|
||||||
| `${workspacePath}` | The fully-qualified path of the current workspace. |
|
|
||||||
| `${/} or ${pathSeparator}` | The path separator (differs per OS). |
|
|
||||||
|
|||||||
+74
-103
@@ -1,146 +1,117 @@
|
|||||||
# Extension releasing
|
# Release extensions
|
||||||
|
|
||||||
There are two primary ways of releasing extensions to users:
|
Release Gemini CLI extensions to your users through a Git repository or GitHub
|
||||||
|
Releases.
|
||||||
|
|
||||||
- [Git repository](#releasing-through-a-git-repository)
|
Git repository releases are the simplest approach and offer the most flexibility
|
||||||
- [Github Releases](#releasing-through-github-releases)
|
for managing development branches. GitHub Releases are more efficient for
|
||||||
|
initial installations because they ship as single archives rather than requiring
|
||||||
|
a full `git clone`. Use GitHub Releases if you need to include platform-specific
|
||||||
|
binary files.
|
||||||
|
|
||||||
Git repository releases tend to be the simplest and most flexible approach,
|
## List your extension in the gallery
|
||||||
while GitHub releases can be more efficient on initial install as they are
|
|
||||||
shipped as single archives instead of requiring a git clone which downloads each
|
|
||||||
file individually. Github releases may also contain platform specific archives
|
|
||||||
if you need to ship platform specific binary files.
|
|
||||||
|
|
||||||
## Releasing through a git repository
|
The [Gemini CLI extension gallery](https://geminicli.com/extensions/browse/)
|
||||||
|
automatically indexes public extensions to help users discover your work. You
|
||||||
|
don't need to submit an issue or email us to list your extension.
|
||||||
|
|
||||||
This is the most flexible and simple option. All you need to do is create a
|
To have your extension automatically discovered and listed:
|
||||||
publicly accessible git repo (such as a public github repository) and then users
|
|
||||||
can install your extension using `gemini extensions install <your-repo-uri>`.
|
|
||||||
They can optionally depend on a specific ref (branch/tag/commit) using the
|
|
||||||
`--ref=<some-ref>` argument, this defaults to the default branch.
|
|
||||||
|
|
||||||
Whenever commits are pushed to the ref that a user depends on, they will be
|
1. **Use a public repository:** Ensure your extension is hosted in a public
|
||||||
prompted to update the extension. Note that this also allows for easy rollbacks,
|
GitHub repository.
|
||||||
the HEAD commit is always treated as the latest version regardless of the actual
|
2. **Add the GitHub topic:** Add the `gemini-cli-extension` topic to your
|
||||||
version in the `gemini-extension.json` file.
|
repository's **About** section. Our crawler uses this topic to find new
|
||||||
|
extensions.
|
||||||
|
3. **Place the manifest at the root:** Ensure your `gemini-extension.json` file
|
||||||
|
is in the absolute root of the repository or the release archive.
|
||||||
|
|
||||||
### Managing release channels using a git repository
|
Our system crawls tagged repositories daily. Once you tag your repository, your
|
||||||
|
extension will appear in the gallery if it passes validation.
|
||||||
|
|
||||||
Users can depend on any ref from your git repo, such as a branch or tag, which
|
## Release through a Git repository
|
||||||
allows you to manage multiple release channels.
|
|
||||||
|
|
||||||
For instance, you can maintain a `stable` branch, which users can install this
|
Releasing through Git is the most flexible option. Create a public Git
|
||||||
way `gemini extensions install <your-repo-uri> --ref=stable`. Or, you could make
|
repository and provide the URL to your users. They can then install your
|
||||||
this the default by treating your default branch as your stable release branch,
|
extension using `gemini extensions install <your-repo-uri>`.
|
||||||
and doing development in a different branch (for instance called `dev`). You can
|
|
||||||
maintain as many branches or tags as you like, providing maximum flexibility for
|
|
||||||
you and your users.
|
|
||||||
|
|
||||||
Note that these `ref` arguments can be tags, branches, or even specific commits,
|
Users can optionally depend on a specific branch, tag, or commit using the
|
||||||
which allows users to depend on a specific version of your extension. It is up
|
`--ref` argument. For example:
|
||||||
to you how you want to manage your tags and branches.
|
|
||||||
|
|
||||||
### Example releasing flow using a git repo
|
```bash
|
||||||
|
gemini extensions install <your-repo-uri> --ref=stable
|
||||||
|
```
|
||||||
|
|
||||||
While there are many options for how you want to manage releases using a git
|
Whenever you push commits to the referenced branch, the CLI prompts users to
|
||||||
flow, we recommend treating your default branch as your "stable" release branch.
|
update their installation. The `HEAD` commit is always treated as the latest
|
||||||
This means that the default behavior for
|
version.
|
||||||
`gemini extensions install <your-repo-uri>` is to be on the stable release
|
|
||||||
branch.
|
|
||||||
|
|
||||||
Lets say you want to maintain three standard release channels, `stable`,
|
### Manage release channels
|
||||||
`preview`, and `dev`. You would do all your standard development in the `dev`
|
|
||||||
branch. When you are ready to do a preview release, you merge that branch into
|
|
||||||
your `preview` branch. When you are ready to promote your preview branch to
|
|
||||||
stable, you merge `preview` into your stable branch (which might be your default
|
|
||||||
branch or a different branch).
|
|
||||||
|
|
||||||
You can also cherry pick changes from one branch into another using
|
You can use branches or tags to manage different release channels, such as
|
||||||
`git cherry-pick`, but do note that this will result in your branches having a
|
`stable`, `preview`, or `dev`.
|
||||||
slightly divergent history from each other, unless you force push changes to
|
|
||||||
your branches on each release to restore the history to a clean slate (which may
|
|
||||||
not be possible for the default branch depending on your repository settings).
|
|
||||||
If you plan on doing cherry picks, you may want to avoid having your default
|
|
||||||
branch be the stable branch to avoid force-pushing to the default branch which
|
|
||||||
should generally be avoided.
|
|
||||||
|
|
||||||
## Releasing through GitHub releases
|
We recommend using your default branch as the stable release channel. This
|
||||||
|
ensures that the default installation command always provides the most reliable
|
||||||
|
version of your extension. You can then use a `dev` branch for active
|
||||||
|
development and merge it into the default branch when you are ready for a
|
||||||
|
release.
|
||||||
|
|
||||||
Gemini CLI extensions can be distributed through
|
## Release through GitHub Releases
|
||||||
[GitHub Releases](https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases).
|
|
||||||
This provides a faster and more reliable initial installation experience for
|
|
||||||
users, as it avoids the need to clone the repository.
|
|
||||||
|
|
||||||
Each release includes at least one archive file, which contains the full
|
Distributing extensions through
|
||||||
contents of the repo at the tag that it was linked to. Releases may also include
|
[GitHub Releases](https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases)
|
||||||
[pre-built archives](#custom-pre-built-archives) if your extension requires some
|
provides a faster installation experience by avoiding a repository clone.
|
||||||
build step or has platform specific binaries attached to it.
|
|
||||||
|
|
||||||
When checking for updates, gemini will just look for the "latest" release on
|
Gemini CLI checks for updates by looking for the **Latest** release on GitHub.
|
||||||
github (you must mark it as such when creating the release), unless the user
|
Users can also install specific versions using the `--ref` argument with a
|
||||||
installed a specific release by passing `--ref=<some-release-tag>`.
|
release tag. Use the `--pre-release` flag to install the latest version even if
|
||||||
|
it isn't marked as **Latest**.
|
||||||
You may also install extensions with the `--pre-release` flag in order to get
|
|
||||||
the latest release regardless of whether it has been marked as "latest". This
|
|
||||||
allows you to test that your release works before actually pushing it to all
|
|
||||||
users.
|
|
||||||
|
|
||||||
### Custom pre-built archives
|
### Custom pre-built archives
|
||||||
|
|
||||||
Custom archives must be attached directly to the github release as assets and
|
You can attach custom archives directly to your GitHub Release as assets. This
|
||||||
must be fully self-contained. This means they should include the entire
|
is useful if your extension requires a build step or includes platform-specific
|
||||||
extension, see [archive structure](#archive-structure).
|
binaries.
|
||||||
|
|
||||||
If your extension is platform-independent, you can provide a single generic
|
Custom archives must be fully self-contained and follow the required
|
||||||
asset. In this case, there should be only one asset attached to the release.
|
[archive structure](#archive-structure). If your extension is
|
||||||
|
platform-independent, provide a single generic asset.
|
||||||
|
|
||||||
Custom archives may also be used if you want to develop your extension within a
|
#### Platform-specific archives
|
||||||
larger repository, you can build an archive which has a different layout from
|
|
||||||
the repo itself (for instance it might just be an archive of a subdirectory
|
|
||||||
containing the extension).
|
|
||||||
|
|
||||||
#### Platform specific archives
|
To let Gemini CLI find the correct asset for a user's platform, use the
|
||||||
|
following naming convention:
|
||||||
|
|
||||||
To ensure Gemini CLI can automatically find the correct release asset for each
|
1. **Platform and architecture-specific:**
|
||||||
platform, you must follow this naming convention. The CLI will search for assets
|
|
||||||
in the following order:
|
|
||||||
|
|
||||||
1. **Platform and architecture-Specific:**
|
|
||||||
`{platform}.{arch}.{name}.{extension}`
|
`{platform}.{arch}.{name}.{extension}`
|
||||||
2. **Platform-specific:** `{platform}.{name}.{extension}`
|
2. **Platform-specific:** `{platform}.{name}.{extension}`
|
||||||
3. **Generic:** If only one asset is provided, it will be used as a generic
|
3. **Generic:** A single asset will be used as a fallback if no specific match
|
||||||
fallback.
|
is found.
|
||||||
|
|
||||||
- `{name}`: The name of your extension.
|
Use these values for the placeholders:
|
||||||
- `{platform}`: The operating system. Supported values are:
|
|
||||||
- `darwin` (macOS)
|
- `{name}`: Your extension name.
|
||||||
- `linux`
|
- `{platform}`: Use `darwin` (macOS), `linux`, or `win32` (Windows).
|
||||||
- `win32` (Windows)
|
- `{arch}`: Use `x64` or `arm64`.
|
||||||
- `{arch}`: The architecture. Supported values are:
|
- `{extension}`: Use `.tar.gz` or `.zip`.
|
||||||
- `x64`
|
|
||||||
- `arm64`
|
|
||||||
- `{extension}`: The file extension of the archive (e.g., `.tar.gz` or `.zip`).
|
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
|
|
||||||
- `darwin.arm64.my-tool.tar.gz` (specific to Apple Silicon Macs)
|
- `darwin.arm64.my-tool.tar.gz` (specific to Apple Silicon Macs)
|
||||||
- `darwin.my-tool.tar.gz` (for all Macs)
|
- `darwin.my-tool.tar.gz` (fallback for all Macs, e.g. Intel)
|
||||||
- `linux.x64.my-tool.tar.gz`
|
- `linux.x64.my-tool.tar.gz`
|
||||||
- `win32.my-tool.zip`
|
- `win32.my-tool.zip`
|
||||||
|
|
||||||
#### Archive structure
|
#### Archive structure
|
||||||
|
|
||||||
Archives must be fully contained extensions and have all the standard
|
Archives must be fully contained extensions. The `gemini-extension.json` file
|
||||||
requirements - specifically the `gemini-extension.json` file must be at the root
|
must be at the root of the archive. The rest of the layout should match a
|
||||||
of the archive.
|
standard extension structure.
|
||||||
|
|
||||||
The rest of the layout should look exactly the same as a typical extension, see
|
|
||||||
[extensions.md](./index.md).
|
|
||||||
|
|
||||||
#### Example GitHub Actions workflow
|
#### Example GitHub Actions workflow
|
||||||
|
|
||||||
Here is an example of a GitHub Actions workflow that builds and releases a
|
Use this example workflow to build and release your extension for multiple
|
||||||
Gemini CLI extension for multiple platforms:
|
platforms:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
name: Release Extension
|
name: Release Extension
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
# Getting started with Gemini CLI extensions
|
# Build Gemini CLI extensions
|
||||||
|
|
||||||
This guide will walk you through creating your first Gemini CLI extension.
|
Gemini CLI extensions let you expand the capabilities of Gemini CLI by adding
|
||||||
You'll learn how to set up a new extension, add a custom tool via an MCP server,
|
custom tools, commands, and context. This guide walks you through creating your
|
||||||
create a custom command, and provide context to the model with a `GEMINI.md`
|
first extension, from setting up a template to adding custom functionality and
|
||||||
file.
|
linking it for local development.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
Before you start, make sure you have the Gemini CLI installed and a basic
|
Before you start, ensure you have the Gemini CLI installed and a basic
|
||||||
understanding of Node.js.
|
understanding of Node.js.
|
||||||
|
|
||||||
## When to use what
|
## Extension features
|
||||||
|
|
||||||
Extensions offer a variety of ways to customize Gemini CLI.
|
Extensions offer several ways to customize Gemini CLI. Use this table to decide
|
||||||
|
which features your extension needs.
|
||||||
|
|
||||||
| Feature | What it is | When to use it | Invoked by |
|
| Feature | What it is | When to use it | Invoked by |
|
||||||
| :------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------- |
|
| :------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------- |
|
||||||
@@ -25,8 +26,8 @@ Extensions offer a variety of ways to customize Gemini CLI.
|
|||||||
|
|
||||||
## Step 1: Create a new extension
|
## Step 1: Create a new extension
|
||||||
|
|
||||||
The easiest way to start is by using one of the built-in templates. We'll use
|
The easiest way to start is by using a built-in template. We'll use the
|
||||||
the `mcp-server` example as our foundation.
|
`mcp-server` example as our foundation.
|
||||||
|
|
||||||
Run the following command to create a new directory called `my-first-extension`
|
Run the following command to create a new directory called `my-first-extension`
|
||||||
with the template files:
|
with the template files:
|
||||||
@@ -35,7 +36,7 @@ with the template files:
|
|||||||
gemini extensions new my-first-extension mcp-server
|
gemini extensions new my-first-extension mcp-server
|
||||||
```
|
```
|
||||||
|
|
||||||
This will create a new directory with the following structure:
|
This creates a directory with the following structure:
|
||||||
|
|
||||||
```
|
```
|
||||||
my-first-extension/
|
my-first-extension/
|
||||||
@@ -46,12 +47,11 @@ my-first-extension/
|
|||||||
|
|
||||||
## Step 2: Understand the extension files
|
## Step 2: Understand the extension files
|
||||||
|
|
||||||
Let's look at the key files in your new extension.
|
Your new extension contains several key files that define its behavior.
|
||||||
|
|
||||||
### `gemini-extension.json`
|
### `gemini-extension.json`
|
||||||
|
|
||||||
This is the manifest file for your extension. It tells Gemini CLI how to load
|
The manifest file tells Gemini CLI how to load and use your extension.
|
||||||
and use your extension.
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -69,17 +69,15 @@ and use your extension.
|
|||||||
|
|
||||||
- `name`: The unique name for your extension.
|
- `name`: The unique name for your extension.
|
||||||
- `version`: The version of your extension.
|
- `version`: The version of your extension.
|
||||||
- `mcpServers`: This section defines one or more Model Context Protocol (MCP)
|
- `mcpServers`: Defines Model Context Protocol (MCP) servers to add new tools.
|
||||||
servers. MCP servers are how you can add new tools for the model to use.
|
- `command`, `args`, `cwd`: Specify how to start your server. The
|
||||||
- `command`, `args`, `cwd`: These fields specify how to start your server.
|
`${extensionPath}` variable is replaced with the absolute path to your
|
||||||
Notice the use of the `${extensionPath}` variable, which Gemini CLI replaces
|
extension's directory.
|
||||||
with the absolute path to your extension's installation directory. This
|
|
||||||
allows your extension to work regardless of where it's installed.
|
|
||||||
|
|
||||||
### `example.js`
|
### `example.js`
|
||||||
|
|
||||||
This file contains the source code for your MCP server. It's a simple Node.js
|
This file contains the source code for your MCP server. It uses the
|
||||||
server that uses the `@modelcontextprotocol/sdk`.
|
`@modelcontextprotocol/sdk` to define tools.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
/**
|
/**
|
||||||
@@ -121,24 +119,49 @@ server.registerTool(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// ... (prompt registration omitted for brevity)
|
|
||||||
|
|
||||||
const transport = new StdioServerTransport();
|
const transport = new StdioServerTransport();
|
||||||
await server.connect(transport);
|
await server.connect(transport);
|
||||||
```
|
```
|
||||||
|
|
||||||
This server defines a single tool called `fetch_posts` that fetches data from a
|
|
||||||
public API.
|
|
||||||
|
|
||||||
### `package.json`
|
### `package.json`
|
||||||
|
|
||||||
This is the standard configuration file for a Node.js project. It defines
|
The standard configuration file for a Node.js project. It defines dependencies
|
||||||
dependencies and scripts.
|
and scripts for your extension.
|
||||||
|
|
||||||
## Step 3: Link your extension
|
## Step 3: Add extension settings
|
||||||
|
|
||||||
Before you can use the extension, you need to link it to your Gemini CLI
|
Some extensions need configuration, such as API keys or user preferences. Let's
|
||||||
installation for local development.
|
add a setting for an API key.
|
||||||
|
|
||||||
|
1. Open `gemini-extension.json`.
|
||||||
|
2. Add a `settings` array to the configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "mcp-server-example",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"settings": [
|
||||||
|
{
|
||||||
|
"name": "API Key",
|
||||||
|
"description": "The API key for the service.",
|
||||||
|
"envVar": "MY_SERVICE_API_KEY",
|
||||||
|
"sensitive": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mcpServers": {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
When a user installs this extension, Gemini CLI will prompt them to enter the
|
||||||
|
"API Key". The value will be stored securely in the system keychain (because
|
||||||
|
`sensitive` is true) and injected into the MCP server's process as the
|
||||||
|
`MY_SERVICE_API_KEY` environment variable.
|
||||||
|
|
||||||
|
## Step 4: Link your extension
|
||||||
|
|
||||||
|
Link your extension to your Gemini CLI installation for local development.
|
||||||
|
|
||||||
1. **Install dependencies:**
|
1. **Install dependencies:**
|
||||||
|
|
||||||
@@ -150,20 +173,19 @@ installation for local development.
|
|||||||
2. **Link the extension:**
|
2. **Link the extension:**
|
||||||
|
|
||||||
The `link` command creates a symbolic link from the Gemini CLI extensions
|
The `link` command creates a symbolic link from the Gemini CLI extensions
|
||||||
directory to your development directory. This means any changes you make
|
directory to your development directory. Changes you make are reflected
|
||||||
will be reflected immediately without needing to reinstall.
|
immediately.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gemini extensions link .
|
gemini extensions link .
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, restart your Gemini CLI session. The new `fetch_posts` tool will be
|
Restart your Gemini CLI session to use the new `fetch_posts` tool. Test it by
|
||||||
available. You can test it by asking: "fetch posts".
|
asking: "fetch posts".
|
||||||
|
|
||||||
## Step 4: Add a custom command
|
## Step 5: Add a custom command
|
||||||
|
|
||||||
Custom commands provide a way to create shortcuts for complex prompts. Let's add
|
Custom commands create shortcuts for complex prompts.
|
||||||
a command that searches for a pattern in your code.
|
|
||||||
|
|
||||||
1. Create a `commands` directory and a subdirectory for your command group:
|
1. Create a `commands` directory and a subdirectory for your command group:
|
||||||
|
|
||||||
@@ -182,18 +204,17 @@ a command that searches for a pattern in your code.
|
|||||||
"""
|
"""
|
||||||
```
|
```
|
||||||
|
|
||||||
This command, `/fs:grep-code`, will take an argument, run the `grep` shell
|
This command, `/fs:grep-code`, takes an argument, runs the `grep` shell
|
||||||
command with it, and pipe the results into a prompt for summarization.
|
command, and pipes the results into a prompt for summarization.
|
||||||
|
|
||||||
After saving the file, restart the Gemini CLI. You can now run
|
After saving the file, restart Gemini CLI. Run `/fs:grep-code "some pattern"` to
|
||||||
`/fs:grep-code "some pattern"` to use your new command.
|
use your new command.
|
||||||
|
|
||||||
## Step 5: Add a custom `GEMINI.md`
|
## Step 6: Add a custom `GEMINI.md`
|
||||||
|
|
||||||
You can provide persistent context to the model by adding a `GEMINI.md` file to
|
Provide persistent context to the model by adding a `GEMINI.md` file to your
|
||||||
your extension. This is useful for giving the model instructions on how to
|
extension. This is useful for setting behavior or providing essential tool
|
||||||
behave or information about your extension's tools. Note that you may not always
|
information.
|
||||||
need this for extensions built to expose commands and prompts.
|
|
||||||
|
|
||||||
1. Create a file named `GEMINI.md` in the root of your extension directory:
|
1. Create a file named `GEMINI.md` in the root of your extension directory:
|
||||||
|
|
||||||
@@ -204,7 +225,7 @@ need this for extensions built to expose commands and prompts.
|
|||||||
posts, use the `fetch_posts` tool. Be concise in your responses.
|
posts, use the `fetch_posts` tool. Be concise in your responses.
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Update your `gemini-extension.json` to tell the CLI to load this file:
|
2. Update your `gemini-extension.json` to load this file:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -221,14 +242,13 @@ need this for extensions built to expose commands and prompts.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Restart the CLI again. The model will now have the context from your `GEMINI.md`
|
Restart Gemini CLI. The model now has the context from your `GEMINI.md` file in
|
||||||
file in every session where the extension is active.
|
every session where the extension is active.
|
||||||
|
|
||||||
## (Optional) Step 6: Add an Agent Skill
|
## (Optional) Step 7: Add an Agent Skill
|
||||||
|
|
||||||
[Agent Skills](../cli/skills.md) let you bundle specialized expertise and
|
[Agent Skills](../cli/skills.md) bundle specialized expertise and workflows.
|
||||||
procedural workflows. Unlike `GEMINI.md`, which provides persistent context,
|
Skills are activated only when needed, which saves context tokens.
|
||||||
skills are activated only when needed, saving context tokens.
|
|
||||||
|
|
||||||
1. Create a `skills` directory and a subdirectory for your skill:
|
1. Create a `skills` directory and a subdirectory for your skill:
|
||||||
|
|
||||||
@@ -255,28 +275,18 @@ skills are activated only when needed, saving context tokens.
|
|||||||
3. Suggest remediation steps for any findings.
|
3. Suggest remediation steps for any findings.
|
||||||
```
|
```
|
||||||
|
|
||||||
Skills bundled with your extension are automatically discovered and can be
|
Gemini CLI automatically discovers skills bundled with your extension. The model
|
||||||
activated by the model during a session when it identifies a relevant task.
|
activates them when it identifies a relevant task.
|
||||||
|
|
||||||
## Step 7: Release your extension
|
## Step 8: Release your extension
|
||||||
|
|
||||||
Once you're happy with your extension, you can share it with others. The two
|
When your extension is ready, share it with others via a Git repository or
|
||||||
primary ways of releasing extensions are via a Git repository or through GitHub
|
GitHub Releases. Refer to the [Extension Releasing Guide](./releasing.md) for
|
||||||
Releases. Using a public Git repository is the simplest method.
|
detailed instructions and learn how to list your extension in the gallery.
|
||||||
|
|
||||||
For detailed instructions on both methods, please refer to the
|
## Next steps
|
||||||
[Extension Releasing Guide](./releasing.md).
|
|
||||||
|
|
||||||
## Conclusion
|
- [Extension reference](reference.md): Deeply understand the extension format,
|
||||||
|
commands, and configuration.
|
||||||
You've successfully created a Gemini CLI extension! You learned how to:
|
- [Best practices](best-practices.md): Learn strategies for building great
|
||||||
|
extensions.
|
||||||
- Bootstrap a new extension from a template.
|
|
||||||
- Add custom tools with an MCP server.
|
|
||||||
- Create convenient custom commands.
|
|
||||||
- Provide persistent context to the model.
|
|
||||||
- Bundle specialized Agent Skills.
|
|
||||||
- Link your extension for local development.
|
|
||||||
|
|
||||||
From here, you can explore more advanced features and build powerful new
|
|
||||||
capabilities into the Gemini CLI.
|
|
||||||
|
|||||||
+40
-97
@@ -52,115 +52,42 @@
|
|||||||
{
|
{
|
||||||
"label": "Features",
|
"label": "Features",
|
||||||
"items": [
|
"items": [
|
||||||
|
{ "label": "Agent Skills", "slug": "docs/cli/skills" },
|
||||||
{
|
{
|
||||||
"label": "/about - About Gemini CLI",
|
"label": "Authentication",
|
||||||
"link": "/docs/cli/commands/#about"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "/auth - Authentication",
|
|
||||||
"slug": "docs/get-started/authentication"
|
"slug": "docs/get-started/authentication"
|
||||||
},
|
},
|
||||||
{ "label": "/bug - Report a bug", "link": "/docs/cli/commands/#bug" },
|
{ "label": "Checkpointing", "slug": "docs/cli/checkpointing" },
|
||||||
{ "label": "/chat - Chat history", "link": "/docs/cli/commands/#chat" },
|
|
||||||
{ "label": "/clear - Clear screen", "link": "/docs/cli/commands/#clear" },
|
|
||||||
{
|
{
|
||||||
"label": "/compress - Compress context",
|
"label": "Extensions",
|
||||||
"link": "/docs/cli/commands/#compress"
|
|
||||||
},
|
|
||||||
{ "label": "/copy - Copy output", "link": "/docs/cli/commands/#copy" },
|
|
||||||
{
|
|
||||||
"label": "/directory - Manage workspace",
|
|
||||||
"link": "/docs/cli/commands/#directory-or-dir"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "/docs - Open documentation",
|
|
||||||
"link": "/docs/cli/commands/#docs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "/editor - Select editor",
|
|
||||||
"link": "/docs/cli/commands/#editor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "/extensions - Manage extensions",
|
|
||||||
"slug": "docs/extensions/index"
|
"slug": "docs/extensions/index"
|
||||||
},
|
},
|
||||||
{ "label": "/help - Show help", "link": "/docs/cli/commands/#help-or" },
|
{ "label": "Headless mode", "slug": "docs/cli/headless" },
|
||||||
{ "label": "/hooks - Hooks", "slug": "docs/hooks" },
|
{ "label": "Help", "link": "/docs/cli/commands/#help-or" },
|
||||||
{ "label": "/ide - IDE integration", "slug": "docs/ide-integration" },
|
{ "label": "Hooks", "slug": "docs/hooks" },
|
||||||
|
{ "label": "IDE integration", "slug": "docs/ide-integration" },
|
||||||
|
{ "label": "MCP servers", "slug": "docs/tools/mcp-server" },
|
||||||
{
|
{
|
||||||
"label": "/init - Initialize context",
|
"label": "Memory management",
|
||||||
"link": "/docs/cli/commands/#init"
|
|
||||||
},
|
|
||||||
{ "label": "/mcp - MCP servers", "slug": "docs/tools/mcp-server" },
|
|
||||||
|
|
||||||
{
|
|
||||||
"label": "/memory - Manage memory",
|
|
||||||
"link": "/docs/cli/commands/#memory"
|
"link": "/docs/cli/commands/#memory"
|
||||||
},
|
},
|
||||||
{ "label": "/model - Model selection", "slug": "docs/cli/model" },
|
{ "label": "Model routing", "slug": "docs/cli/model-routing" },
|
||||||
|
{ "label": "Model selection", "slug": "docs/cli/model" },
|
||||||
|
{ "label": "Plan mode (experimental)", "slug": "docs/cli/plan-mode" },
|
||||||
|
{ "label": "Rewind", "slug": "docs/cli/rewind" },
|
||||||
|
{ "label": "Sandboxing", "slug": "docs/cli/sandbox" },
|
||||||
|
{ "label": "Settings", "slug": "docs/cli/settings" },
|
||||||
{
|
{
|
||||||
"label": "/policies - Manage policies",
|
"label": "Shell",
|
||||||
"link": "/docs/cli/commands/#policies"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "/privacy - Privacy notice",
|
|
||||||
"link": "/docs/cli/commands/#privacy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "/quit - Exit CLI",
|
|
||||||
"link": "/docs/cli/commands/#quit-or-exit"
|
|
||||||
},
|
|
||||||
{ "label": "/restore - Restore files", "slug": "docs/cli/checkpointing" },
|
|
||||||
{
|
|
||||||
"label": "/resume - Resume session",
|
|
||||||
|
|
||||||
"link": "/docs/cli/commands/#resume"
|
|
||||||
},
|
|
||||||
{ "label": "/rewind - Rewind", "slug": "docs/cli/rewind" },
|
|
||||||
{ "label": "/settings - Settings", "slug": "docs/cli/settings" },
|
|
||||||
{
|
|
||||||
"label": "/setup-github - GitHub setup",
|
|
||||||
"link": "/docs/cli/commands/#setup-github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "/shells - Manage processes",
|
|
||||||
"link": "/docs/cli/commands/#shells-or-bashes"
|
"link": "/docs/cli/commands/#shells-or-bashes"
|
||||||
},
|
},
|
||||||
{ "label": "/skills - Agent skills", "slug": "docs/cli/skills" },
|
|
||||||
{
|
{
|
||||||
"label": "/stats - Session statistics",
|
"label": "Stats",
|
||||||
"link": "/docs/cli/commands/#stats"
|
"link": "/docs/cli/commands/#stats"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"label": "/terminal-setup - Terminal keybindings",
|
|
||||||
"link": "/docs/cli/commands/#terminal-setup"
|
|
||||||
},
|
|
||||||
{ "label": "/theme - Themes", "slug": "docs/cli/themes" },
|
|
||||||
{ "label": "/tools - List tools", "link": "/docs/cli/commands/#tools" },
|
|
||||||
{ "label": "/vim - Vim mode", "link": "/docs/cli/commands/#vim" },
|
|
||||||
|
|
||||||
{
|
|
||||||
"label": "Activate skill (tool)",
|
|
||||||
"slug": "docs/tools/activate-skill"
|
|
||||||
},
|
|
||||||
{ "label": "Ask user (tool)", "slug": "docs/tools/ask-user" },
|
|
||||||
{ "label": "Checkpointing", "slug": "docs/cli/checkpointing" },
|
|
||||||
{ "label": "File system (tool)", "slug": "docs/tools/file-system" },
|
|
||||||
{ "label": "Headless mode", "slug": "docs/cli/headless" },
|
|
||||||
{
|
|
||||||
"label": "Internal documentation (tool)",
|
|
||||||
"slug": "docs/tools/internal-docs"
|
|
||||||
},
|
|
||||||
{ "label": "Memory (tool)", "slug": "docs/tools/memory" },
|
|
||||||
{ "label": "Model routing", "slug": "docs/cli/model-routing" },
|
|
||||||
{ "label": "Plan mode (experimental)", "slug": "docs/cli/plan-mode" },
|
|
||||||
{ "label": "Sandboxing", "slug": "docs/cli/sandbox" },
|
|
||||||
{ "label": "Shell (tool)", "slug": "docs/tools/shell" },
|
|
||||||
{ "label": "Telemetry", "slug": "docs/cli/telemetry" },
|
{ "label": "Telemetry", "slug": "docs/cli/telemetry" },
|
||||||
{ "label": "Todo (tool)", "slug": "docs/tools/todos" },
|
|
||||||
{ "label": "Token caching", "slug": "docs/cli/token-caching" },
|
{ "label": "Token caching", "slug": "docs/cli/token-caching" },
|
||||||
{ "label": "Web fetch (tool)", "slug": "docs/tools/web-fetch" },
|
{ "label": "Tools", "link": "/docs/cli/commands/#tools" }
|
||||||
{ "label": "Web search (tool)", "slug": "docs/tools/web-search" }
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -186,14 +113,30 @@
|
|||||||
{
|
{
|
||||||
"label": "Extensions",
|
"label": "Extensions",
|
||||||
"items": [
|
"items": [
|
||||||
{ "label": "Introduction", "slug": "docs/extensions" },
|
|
||||||
{
|
{
|
||||||
"label": "Writing extensions",
|
"label": "Overview",
|
||||||
|
"slug": "docs/extensions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "User guide: Install and manage",
|
||||||
|
"link": "/docs/extensions/#manage-extensions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Developer guide: Build extensions",
|
||||||
"slug": "docs/extensions/writing-extensions"
|
"slug": "docs/extensions/writing-extensions"
|
||||||
},
|
},
|
||||||
{ "label": "Reference", "slug": "docs/extensions/reference" },
|
{
|
||||||
{ "label": "Best practices", "slug": "docs/extensions/best-practices" },
|
"label": "Developer guide: Best practices",
|
||||||
{ "label": "Releasing", "slug": "docs/extensions/releasing" }
|
"slug": "docs/extensions/best-practices"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Developer guide: Releasing",
|
||||||
|
"slug": "docs/extensions/releasing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Developer guide: Reference",
|
||||||
|
"slug": "docs/extensions/reference"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user