|
| 1 | +# Extensions on Gemini CLI: Best practices |
| 2 | + |
| 3 | +This guide covers best practices for developing, securing, and maintaining |
| 4 | +Gemini CLI extensions. |
| 5 | + |
| 6 | +## Development |
| 7 | + |
| 8 | +Developing extensions for Gemini CLI is intended to be a lightweight, iterative |
| 9 | +process. |
| 10 | + |
| 11 | +### Structure your extension |
| 12 | + |
| 13 | +While simple extensions can just be a few files, we recommend a robust structure |
| 14 | +for complex extensions: |
| 15 | + |
| 16 | +``` |
| 17 | +my-extension/ |
| 18 | +├── package.json |
| 19 | +├── tsconfig.json |
| 20 | +├── gemini-extension.json |
| 21 | +├── src/ |
| 22 | +│ ├── index.ts |
| 23 | +│ └── tools/ |
| 24 | +└── dist/ |
| 25 | +``` |
| 26 | + |
| 27 | +- **Use TypeScript**: We strongly recommend using TypeScript for type safety and |
| 28 | + better tooling. |
| 29 | +- **Separate source and build**: Keep your source code in `src` and build to |
| 30 | + `dist`. |
| 31 | +- **Bundle dependencies**: If your extension has many dependencies, consider |
| 32 | + bundling them (e.g., with `esbuild` or `webpack`) to reduce install time and |
| 33 | + potential conflicts. |
| 34 | + |
| 35 | +### Iterate with `link` |
| 36 | + |
| 37 | +Use `gemini extensions link` to develop locally without constantly reinstalling: |
| 38 | + |
| 39 | +```bash |
| 40 | +cd my-extension |
| 41 | +gemini extensions link . |
| 42 | +``` |
| 43 | + |
| 44 | +Changes to your code (after rebuilding) will be immediately available in the CLI |
| 45 | +on restart. |
| 46 | + |
| 47 | +### Use `GEMINI.md` effectively |
| 48 | + |
| 49 | +Your `GEMINI.md` file provides context to the model. Keep it focused: |
| 50 | + |
| 51 | +- **Do:** Explain high-level goals and how to use the provided tools. |
| 52 | +- **Don't:** Dump your entire documentation. |
| 53 | +- **Do:** Use clear, concise language. |
| 54 | + |
| 55 | +## Security |
| 56 | + |
| 57 | +When building a Gemini CLI extension, follow general security best practices |
| 58 | +(such as least privilege and input validation) to reduce risk. |
| 59 | + |
| 60 | +### Minimal permissions |
| 61 | + |
| 62 | +When defining tools in your MCP server, only request the permissions necessary. |
| 63 | +Avoid giving the model broad access (like full shell access) if a more |
| 64 | +restricted set of tools will suffice. |
| 65 | + |
| 66 | +If you must use powerful tools like `run_shell_command`, consider restricting |
| 67 | +them to specific commands in your `gemini-extension.json`: |
| 68 | + |
| 69 | +```json |
| 70 | +{ |
| 71 | + "name": "my-safe-extension", |
| 72 | + "excludeTools": ["run_shell_command(rm -rf *)"] |
| 73 | +} |
| 74 | +``` |
| 75 | + |
| 76 | +This ensures that even if the model tries to execute a dangerous command, it |
| 77 | +will be blocked at the CLI level. |
| 78 | + |
| 79 | +### Validate inputs |
| 80 | + |
| 81 | +Your MCP server is running on the user's machine. Always validate inputs to your |
| 82 | +tools to prevent arbitrary code execution or filesystem access outside the |
| 83 | +intended scope. |
| 84 | + |
| 85 | +```typescript |
| 86 | +// Good: Validating paths |
| 87 | +if (!path.resolve(inputPath).startsWith(path.resolve(allowedDir) + path.sep)) { |
| 88 | + throw new Error('Access denied'); |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +### Sensitive settings |
| 93 | + |
| 94 | +If your extension requires API keys, use the `sensitive: true` option in |
| 95 | +`gemini-extension.json`. This ensures keys are stored securely in the system |
| 96 | +keychain and obfuscated in the UI. |
| 97 | + |
| 98 | +```json |
| 99 | +"settings": [ |
| 100 | + { |
| 101 | + "name": "API Key", |
| 102 | + "envVar": "MY_API_KEY", |
| 103 | + "sensitive": true |
| 104 | + } |
| 105 | +] |
| 106 | +``` |
| 107 | + |
| 108 | +## Releasing |
| 109 | + |
| 110 | +You can upload your extension directly to GitHub to list it in the gallery. |
| 111 | +Gemini CLI extensions also offers support for more complicated |
| 112 | +[releases](releasing.md). |
| 113 | + |
| 114 | +### Semantic versioning |
| 115 | + |
| 116 | +Follow [Semantic Versioning](https://semver.org/). |
| 117 | + |
| 118 | +- **Major**: Breaking changes (renaming tools, changing arguments). |
| 119 | +- **Minor**: New features (new tools, commands). |
| 120 | +- **Patch**: Bug fixes. |
| 121 | + |
| 122 | +### Release Channels |
| 123 | + |
| 124 | +Use git branches to manage release channels (e.g., `main` for stable, `dev` for |
| 125 | +bleeding edge). This allows users to choose their stability level: |
| 126 | + |
| 127 | +```bash |
| 128 | +# Stable |
| 129 | +gemini extensions install github.com/user/repo |
| 130 | + |
| 131 | +# Dev |
| 132 | +gemini extensions install github.com/user/repo --ref dev |
| 133 | +``` |
| 134 | + |
| 135 | +### Clean artifacts |
| 136 | + |
| 137 | +If you are using GitHub Releases, ensure your release artifacts only contain the |
| 138 | +necessary files (`dist/`, `gemini-extension.json`, `package.json`). Exclude |
| 139 | +`node_modules` (users will install them) and `src/` to keep downloads small. |
0 commit comments