Skip to content

构建高质量 Gemini CLI 扩展的核心是:只申请必要权限、严格验证 MCP 工具输入、用 sensitive 字段保护密钥、TypeScript + link 命令做本地迭代,以及 SemVer 让用户平滑升级。本页是扩展开发者在发布前必须过一遍的清单。

扩展开发最佳实践

本页汇总了开发、安全加固和维护 Gemini CLI 扩展的最佳实践,配合 扩展开发入门扩展完整参考 一起阅读效果最佳。


开发

推荐目录结构

简单扩展只需几个文件,复杂项目建议使用分层结构:

text
my-extension/
├── package.json
├── tsconfig.json
├── gemini-extension.json
├── src/
│   ├── index.ts
│   └── tools/
└── dist/

推荐 TypeScript:强烈建议用 TypeScript 开发 MCP 服务器,类型安全能帮助你捕获运行时错误,尤其是工具参数验证逻辑。

分离源码和构建产物:源码放 src/,构建产物输出到 dist/,避免两者混杂。

打包依赖:若扩展依赖较多,使用 esbuild 等工具打包,减少安装时间并避免依赖冲突。


本地开发时,每次改代码都重新安装扩展非常低效。使用 link 命令:

bash
cd my-extension
gemini extensions link .

link 创建符号链接,代码改动后只需:

  1. 重新构建(如 npm run build
  2. 重启 CLI 会话

变更即时生效,无需 uninstall + install


有效使用 GEMINI.md

GEMINI.md 是扩展向模型传递上下文的主要途径:

  • 聚焦目标:说明扩展的核心用途和如何与工具交互,而不是写完整的 API 文档
  • 保持简洁:避免把大量文档堆进去,清晰直接的语言比面面俱到更有效
  • 提供示例:包含简短示例,告诉模型该何时调用哪些工具或命令

安全

最小权限原则

只申请 MCP 服务器实际需要的权限。如果受限工具足够完成任务,不要开放全 Shell 访问。

如果扩展需要 run_shell_command,在 manifest 中明确限制危险命令:

json
{
  "name": "my-safe-extension",
  "excludeTools": ["run_shell_command(rm -rf *)"]
}

这样即使模型尝试执行危险命令,CLI 也会在策略层拦截。


验证工具输入

MCP 服务器运行在用户机器上,不受沙箱保护。必须对所有工具输入进行验证,防止路径遍历、任意代码执行等安全问题:

typescript
// 路径访问控制示例
import path from 'node:path';

function validatePath(inputPath: string, allowedDir: string): string {
  const resolved = path.resolve(inputPath);
  const allowed = path.resolve(allowedDir);
  if (!resolved.startsWith(allowed + path.sep)) {
    throw new Error('Access denied: path is outside the allowed directory');
  }
  return resolved;
}

安全存储敏感配置

如果扩展需要 API Key 等敏感信息,在 settings 中使用 sensitive: true

json
"settings": [
  {
    "name": "API Key",
    "envVar": "MY_API_KEY",
    "sensitive": true
  }
]

sensitive: true 效果:

  • 值存入操作系统 Keychain(macOS Keychain、Windows Credential Manager)
  • CLI 界面中脱敏显示(显示为 ***
  • 通过 MCP 服务器启动参数的环境变量安全注入,不会明文写到磁盘

发布

语义化版本(SemVer)

遵循 Semantic Versioning 规范,让用户清楚了解每次更新的影响范围:

版本号变化含义示例
Major(主版本)破坏性变更重命名工具、修改参数签名
Minor(次版本)新功能,向后兼容添加新工具、新命令
Patch(补丁版本)Bug 修复、性能优化修正工具行为、改进错误消息

发布渠道管理

用 Git 分支管理发布渠道,让用户自由选择稳定版或最新功能:

bash
# 安装稳定版(默认分支)
gemini extensions install github.com/user/repo

# 安装开发版
gemini extensions install github.com/user/repo --ref dev

推荐策略

  • 默认分支(main/master)作为稳定发布渠道
  • devpreview 分支用于日常开发
  • 功能稳定后合并到默认分支发布

GitHub Release 打包

发布 GitHub Release 时,只打包必要文件(dist/gemini-extension.jsonpackage.json),排除 node_modules/src/,减少用户下载体积。

详细发布流程参见 发布 Gemini CLI 扩展


测试与验证

手动验证

  • gemini extensions link 在真实 CLI 会话中测试扩展
  • 检查工具是否出现在 F12 调试控制台
  • 验证自定义命令是否正确解析参数

自动化测试

如果扩展包含 MCP 服务器,为工具逻辑编写单元测试(推荐使用 Vitest 或 Jest)。测试时可通过 mock transport 层来隔离 MCP 工具,无需运行完整服务器。


故障排查

扩展不加载

如果 /extensions list 中没有出现你的扩展:

  1. 检查 manifest:确认 gemini-extension.json 在根目录且 JSON 格式合法
  2. 确认名称匹配:manifest 中的 name 字段必须与扩展目录名完全一致
  3. 重启 CLI:扩展在会话启动时加载,修改后必须重启

MCP 服务器工具不工作

  1. 查看日志:检查 CLI 日志确认 MCP 服务器是否启动失败
  2. 直接测试命令:在终端直接运行 commandargs 确认服务器能独立启动
  3. F12 调试控制台:在交互模式中按 F12 查看工具调用和响应详情

自定义命令不响应

  1. 检查优先级:用户命令和项目命令优先级高于扩展命令。若有冲突,扩展命令会加前缀(/extension.command
  2. 验证命令名:运行 /help 查看所有已注册命令及其来源

常见问题

Q: 什么时候应该用 MCP 服务器,什么时候用自定义命令?

A: MCP 服务器适合需要模型主动调用的动态能力(查 API、执行逻辑);自定义命令适合用户手动触发的固定 Prompt 模板或 Shell 脚本快捷方式。两者可以同时存在于一个扩展中。

Q: 扩展的 GEMINI.md 和项目的 GEMINI.md 会冲突吗?

A: 不会冲突,两者都会被加载。项目级 .gemini/GEMINI.md 优先级高于扩展提供的 GEMINI.md,但两者内容通常是互补关系。

Q: 可以在扩展中引用另一个扩展的工具吗?

A: 扩展相互独立,不直接引用彼此的工具。但如果两个扩展都已安装,它们的工具都会注册到同一个会话中,模型可以同时使用。