docs/extensions/best-practices.md
This guide covers best practices for developing, securing, and maintaining Gemini CLI extensions.
Developing extensions for Gemini CLI is a lightweight, iterative process. Use these strategies to build robust and efficient extensions.
While simple extensions may contain only a few files, we recommend a organized structure for complex projects.
my-extension/
├── package.json
├── tsconfig.json
├── gemini-extension.json
├── src/
│ ├── index.ts
│ └── tools/
└── dist/
src/ and output
build artifacts to dist/.esbuild to reduce installation time and avoid conflicts.linkUse the gemini extensions link command to develop locally without reinstalling
your extension after every change.
cd my-extension
gemini extensions link .
Changes to your code are immediately available in the CLI after you rebuild the project and restart the session.
GEMINI.md effectivelyYour GEMINI.md file provides essential context to the model.
Follow the principle of least privilege and rigorous input validation when building extensions.
Only request the permissions your MCP server needs to function. Avoid giving the model broad access (such as full shell access) if restricted tools are sufficient.
If your extension uses powerful tools like run_shell_command, restrict them in
your gemini-extension.json file:
{
"name": "my-safe-extension",
"excludeTools": ["run_shell_command(rm -rf *)"]
}
This ensures the CLI blocks dangerous commands even if the model attempts to execute them.
Your MCP server runs on the user's machine. Always validate tool inputs to prevent arbitrary code execution or unauthorized filesystem access.
// Example: Validating paths
if (!path.resolve(inputPath).startsWith(path.resolve(allowedDir) + path.sep)) {
throw new Error('Access denied');
}
If your extension requires API keys or other secrets, use the sensitive: true
option in your manifest. This ensures keys are stored in the system keychain and
obfuscated in the CLI output.
"settings": [
{
"name": "API Key",
"envVar": "MY_API_KEY",
"sensitive": true
}
]
Follow standard versioning and release practices to ensure a smooth experience for your users.
Follow Semantic Versioning (SemVer) to communicate changes clearly.
Use Git branches to manage release channels. This lets users choose between stability and the latest features.
# Install the stable version (default branch)
gemini extensions install github.com/user/repo
# Install the development version
gemini extensions install github.com/user/repo --ref dev
When using GitHub Releases, ensure your archives only contain necessary files
(such as dist/, gemini-extension.json, and package.json). Exclude
node_modules/ and src/ to minimize download size.
Test your extension thoroughly before releasing it to users.
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.Use these tips to diagnose and fix common extension issues.
If your extension doesn't appear in /extensions list:
gemini-extension.json is in the root
directory and contains valid JSON.name field in the manifest must match the extension
directory name exactly.If your tools aren't working as expected:
command and args directly in your
terminal to ensure it starts correctly outside of Gemini CLI.If a custom command isn't responding:
/extension.command) to verify the extension's version./help to see a list of all available commands and
their sources.