Gemini CLI 扩展机制详解:从 gemini-extension.json 清单到安装、管理与源码实现
Gemini CLI 的扩展(Extension)机制允许开发者把自定义命令、MCP 服务器、上下文文件、主题、Hooks、子代理与 Agent Skills 打包成一个可安装、可分享的单元,从而在不修改 CLI 本体的前提下扩展其能力。本文以仓库中 扩展文档入口 为核心,结合 扩展参考、扩展开发指南 以及 packages/cli 中的安装与加载源码,完整讲解扩展的目录结构、gemini-extension.json 清单格式、安装/更新/启停等管理命令,以及背后的信任与安全检查实现,帮助你既能正确安装管理扩展,也能从零构建自己的扩展。
扩展能打包什么
按 文档入口 的定义,扩展将以下能力封装为“熟悉且用户友好”的格式,可轻松安装与分享:
| 能力 | 载体 | 作用 |
|---|---|---|
| 自定义命令 | 扩展内 commands/ 目录下的 TOML 文件 |
提供形如 /my-cmd 的快捷指令,执行预设提示词或 shell 命令 |
| MCP 服务器 | 清单中的 mcpServers 字段 |
启动进程暴露新工具与数据源,让模型能“做新事情” |
| 上下文文件 | 扩展内 GEMINI.md(或 contextFileName 指定的文件) |
每次会话开始时注入扩展的“人设”与约定 |
| Agent Skills | 扩展内 skills/ 目录 |
按需激活的专项工作流,避免占用主上下文 |
| Hooks | 扩展内 hooks/hooks.json |
在工具调用等生命周期事件上拦截/修改 CLI 行为 |
| 子代理(Sub-agents) | 扩展内 agents/ 目录(预览功能) |
可被委派任务的代理定义文件(.md) |
| 主题(Themes) | 清单中的 themes 数组 |
自定义 CLI UI 配色方案 |
| 策略规则(Policy Engine) | 扩展内 policies/ 目录下的 .toml 文件 |
贡献策略规则与安全校验器 |
各能力的取舍建议可见 writing-extensions.md 中的特性对照表(MCP 服务器由模型触发、自定义命令由用户触发等)。
安装扩展
基本用法
在终端中通过 gemini extensions 命令组安装扩展,提供其 GitHub 仓库 URL 即可:
gemini extensions install https://github.com/gemini-cli-extensions/workspace
从 扩展参考 可知,安装支持 GitHub URL 或本地文件路径两种来源,完整签名与参数如下:
gemini extensions install <source> [--ref <ref>] [--auto-update] [--pre-release] [--consent] [--skip-settings]
<source>:扩展的 GitHub URL 或本地路径;--ref:要安装的 git ref(分支、标签或提交);--auto-update:为该扩展启用自动更新;--pre-release:允许安装预发布版本;--consent:确认已知晓安全风险并跳过确认提示;--skip-settings:跳过安装过程中的配置项填写。
两个重要的使用前提:Gemini CLI 在安装时会对扩展创建一份副本,因此需要从源拉取变更时必须运行 gemini extensions update;另外从 GitHub 安装要求本机已安装 git。
这些参数在源码中与文档完全对应,见 install.ts 中 yargs 命令定义:install <source> 命令的 builder 依次声明了 ref、auto-update、pre-release、consent、skip-settings 五个选项,并在 .check() 中强制要求提供 source。
安装流程中的信任与安全机制
阅读 install.ts 的 handleInstall 实现,可以看到安装远不止“拷贝文件”:
- 推断安装元数据。
inferInstallMetadata(source, ...)根据来源判断安装类型(git、github-release、local、link)。 - 本地来源的目录信任检查。对于本地/链接来源,先经
isWorkspaceTrusted判断是否受信任;若不受信任,调用FolderTrustDiscoveryService.discover(realPath)扫描目录中声明的命令、MCP 服务器、Hooks、Skills、Agents 与设置覆盖项,逐条列出后询问“Do you trust the files in this folder?”(见 install.ts#L55-L144)。用户拒绝则安装中止;接受则通过trustedFolders.setValue(realPath, TrustLevel.TRUST_FOLDER)记录信任。 - 同意(consent)流程。
--consent参数仅把requestConsent替换为恒返回true的函数并记录警告信息;默认走requestConsentNonInteractive交互式确认。 - 企业级安全策略。extension-manager.ts 的
installOrUpdateExtension开头会校验两个安全设置:security.allowedExtensions:若配置了正则白名单,只有匹配的来源才能安装,否则抛出 “not allowed by the allowedExtensions security setting” 错误;security.blockGitExtensions:若开启,则禁止从任何远程(git / github-release)来源安装扩展。
- GitHub Release 优先,git clone 兜底。对 GitHub URL,先尝试
downloadFromGitHubRelease下载发布包;若仓库没有 Release 数据且是普通 git 安装则直接回退cloneFromGit,否则询问用户是否改用git clone(见 extension-manager.ts#L247-L285)。 - 副本落盘与完整性记录。扩展最终被复制到
~/.gemini/extensions/<扩展名>/(ExtensionStorage.getUserExtensionsDir()),写入安装元数据文件,并通过storeExtensionIntegrity在安装时刻建立完整性基线,供后续verifyExtensionIntegrity校验扩展是否被篡改(见 extension-manager.ts#L433-L448)。
文件名约定在 variables.ts 中定义:清单文件固定为 gemini-extension.json,安装元数据文件为 .gemini-extension-install.json。
列出与管理扩展
查看已安装的扩展
在交互式 CLI 中,用 /extensions 命令族核对扩展及其状态:
/extensions list
在终端中则使用命令行:
gemini extensions list
完整管理命令一览
扩展参考 给出的命令组覆盖了扩展的完整生命周期:
# 卸载一个或多个扩展
gemini extensions uninstall <name...>
# 禁用扩展(全局或仅当前工作区)
gemini extensions disable <name> [--scope <scope>]
# 重新启用扩展
gemini extensions enable <name> [--scope <scope>]
# 更新单个扩展
gemini extensions update <name>
# 一次性更新所有已安装扩展
gemini extensions update --all
# 从内置模板创建新扩展
gemini extensions new <path> [template]
# 链接本地开发目录(符号链接,改动即时生效)
gemini extensions link <path>
# 修改扩展配置项
gemini extensions config <name> [setting] [--scope <scope>]
其中 --scope 取 user 或 workspace:扩展默认全局启用,可全局禁用或仅在某个工作区禁用。需要特别注意的两条限制:
gemini extensions install等管理命令不支持在 CLI 交互模式内执行,交互模式下只能用/extensions list查看;- 所有管理操作(包括 slash 命令的更新)都需要重启 CLI 会话后才生效。
对应实现分散在 packages/cli/src/commands/extensions/ 目录下的 install.ts、uninstall.ts、enable.ts、disable.ts、update.ts、link.ts、new.ts、configure.ts、list.ts 与 validate.ts 等文件中,每个命令均配有同名 *.test.ts 单元测试。
gemini-extension.json 清单格式
扩展从 <home>/.gemini/extensions 目录加载,每个扩展的根目录必须包含 gemini-extension.json。一个较为完整的清单示例(源自 reference.md)如下:
{
"name": "my-extension",
"version": "1.0.0",
"description": "My awesome extension",
"mcpServers": {
"my-server": {
"command": "node",
"args": ["${extensionPath}/my-server.js"],
"cwd": "${extensionPath}"
}
},
"contextFileName": "GEMINI.md",
"excludeTools": ["run_shell_command"],
"migratedTo": "https://github.com/new-owner/new-extension-repo",
"plan": {
"directory": ".gemini/plans"
}
}
各字段说明:
name:扩展唯一标识,用于命令冲突消解。应使用小写字母/数字并以连字符分隔,且期望与扩展目录名一致;version:扩展版本;description:简短描述,展示在官方扩展画廊中;mcpServers:MCP 服务器映射表,启动时按 settings.json 中 MCP 服务器的同等方式加载。注意两点:与settings.json中的同名 MCP 服务器冲突时,后者优先;所有 MCP 配置项均支持,但trust除外。为可移植性应使用${extensionPath}引用扩展目录内文件,并用command/args拆分可执行文件与参数;contextFileName:扩展上下文的文件名;未声明但扩展目录中存在GEMINI.md时会自动加载该文件;excludeTools:从模型可用工具中排除的工具名数组,支持命令级限定,例如"excludeTools": ["run_shell_command(rm -rf)"]可屏蔽rm -rf;这与 MCP 服务器配置里的excludeTools是两套机制;migratedTo:扩展新仓库地址。设置后 CLI 会自动检查新源的更新,并在发现更新时把安装迁移到新源;plan.directory:规划产物存储目录,作为用户未在设置中指定计划目录时的回退值;两者都未指定时默认为~/.gemini/tmp/<project>/<session-id>/plans/。
从源码结构看,清单的磁盘形态定义在 extension.ts 的 ExtensionConfig 接口中,其字段(name、version、mcpServers、contextFileName、excludeTools、settings、themes、plan、migratedTo)与上述文档字段一一对应,且该接口被刻意限定“仅在读取文件的逻辑中引用”,加载后的运行时数据则由 core 包中的 GeminiCLIExtension 类承载。
启动时,Gemini CLI 会加载全部扩展并合并其配置,冲突时工作区配置优先。
模板创建:gemini extensions new
用内置模板快速起步:
gemini extensions new my-first-extension mcp-server
mcp-server 模板会生成如下结构:
my-first-extension/
├── example.js
├── gemini-extension.json
└── package.json
其清单把 ${extensionPath}${/} 拼入 args 以跨平台定位服务器脚本:
{
"name": "mcp-server-example",
"version": "1.0.0",
"mcpServers": {
"nodeServer": {
"command": "node",
"args": ["${extensionPath}${/}example.js"],
"cwd": "${extensionPath}"
}
}
}
example.js 使用 @modelcontextprotocol/sdk 定义了一个 fetch_posts 工具(通过 registerTool 注册,StdioServerTransport 连接)。仓库中对应的模板源码位于 packages/cli/src/commands/extensions/examples/ 目录,包含 mcp-server、custom-commands、exclude-tools、hooks、policies、skills、themes-example 七套示例,可作为 gemini extensions new <path> [template] 的模板来源。
扩展配置项(settings)与环境变量净化
扩展可以声明“安装时由用户填写”的配置项(如 API Key、URL),值保存在扩展目录内的 .env 文件中。在清单中加入 settings 数组:
{
"name": "my-api-extension",
"version": "1.0.0",
"settings": [
{
"name": "API Key",
"description": "Your API key for the service.",
"envVar": "MY_API_KEY",
"sensitive": true
}
]
}
name:配置项显示名;description:说明文字;envVar:值所存入的环境变量名;sensitive:为true时值存入系统钥匙串(keychain)并在 UI 中打码。
安装时 CLI 会提示用户输入 “API Key”;由于 sensitive 为 true,该值写入钥匙串,并作为 MY_SERVICE_API_KEY 环境变量注入 MCP 服务器进程。修改已安装扩展的配置使用:
gemini extensions config <name> [setting] [--scope <scope>]
环境变量净化(Environment Variable Sanitization) 是一项关键安全设计:出于安全考虑,敏感环境变量默认被过滤,扩展与 MCP 服务器不会继承用户的完整 shell 环境,只能访问:
- 标准安全变量(如
HOME、PATH、TMPDIR); - 在
settings数组中通过envVar显式声明并请求的变量。
也就是说,扩展若需要特定环境变量(API Key、自定义 host、配置路径等),必须先声明进 settings 数组,CLI 才会将其加入允许列表。从源码看,相关逻辑集中在 extensionSettings.ts(getEnvContents、maybePromptForSettings、getMissingSettings 等);当安装后仍缺少配置项时,extension-manager.ts 会发出警告并提示运行 gemini extensions config <name> [setting-name] 补齐。
变量替换
gemini-extension.json 与 hooks/hooks.json 中均支持变量替换:
| 变量 | 说明 |
|---|---|
${extensionPath} |
扩展目录的绝对路径 |
${workspacePath} |
当前工作区的绝对路径 |
${/} |
平台相关的路径分隔符 |
各能力载体的目录约定
-
自定义命令:把 TOML 文件放入
commands/子目录,目录结构决定命令名。例如扩展gcp中:commands/deploy.toml成为/deploy;commands/gcs/sync.toml成为带命名空间冒号的/gcs:sync。开发指南中给出的示例命令会执行 shell 并把输出拼入提示词:prompt = """ Please summarize the findings for the pattern `{{args}}`. Search Results: !{grep -r {{args}} .} """保存后重启 CLI,即可运行
/fs:grep-code "some pattern"这类命令。 -
Hooks:在扩展目录的
hooks/hooks.json中定义(注意:不在gemini-extension.json中定义),用于在工具调用前后等事件上拦截与定制 CLI 行为。 -
Agent Skills:把技能定义放入
skills/目录,如skills/security-audit/SKILL.md暴露security-audit技能,CLI 自动发现,模型在识别到相关任务时才激活,从而节省上下文 token。 -
子代理:把
.md代理定义文件加入扩展根的agents/目录(预览功能,仍在活跃开发中)。 -
Policy Engine:在扩展根创建
policies/目录并放置.toml策略文件,CLI 自动全部加载,扩展激活时规则即生效。扩展贡献的规则运行在独立的 tier 2 层级(与工作区策略同级),优先级高于默认规则、低于用户/管理员策略。示例:[[rule]] mcpName = "my_server" toolName = "dangerous_tool" decision = "ask_user" priority = 100 [[safety_checker]] mcpName = "my_server" toolName = "write_data" priority = 200 [safety_checker.checker] type = "in-process" name = "allowed-path" required_context = ["environment"]安全限制:为防止扩展自动批准工具调用或绕过安全机制,Gemini CLI 会忽略扩展策略中的任何
allow决策与yolo模式配置。 -
主题:通过清单的
themes数组提供,例如定义名为shades-of-green的自定义主题(含background、text、status、border、ui等色板)。扩展主题可用/theme命令选择,或在settings.json的ui.theme中设置;引用扩展主题时主题名后带扩展名括注,如shades-of-green (my-green-extension)。
命令冲突消解
扩展命令的优先级最低。当扩展命令名与用户或项目命令冲突时,扩展命令会被加扩展名前缀(点号分隔),例如 /gcp.deploy。
本地开发与链接
开发扩展时无需反复安装:gemini extensions link <path> 会在 Gemini CLI 扩展目录与你的开发目录之间创建符号链接,改动即时生效。典型流程(见 writing-extensions.md):
cd my-first-extension
npm install
gemini extensions link .
重启 Gemini CLI 会话后即可使用扩展提供的新工具(如上文 fetch_posts)。注意这与 install 的“复制副本”语义不同:install 之后需要通过 update 拉取源变更,而 link 是直接的软链。
小结与延伸阅读
Gemini CLI 的扩展机制以 <home>/.gemini/extensions 下“清单 + 约定目录”为骨架:gemini-extension.json 声明 MCP 服务器、上下文、工具排除、主题、计划目录与迁移源,commands/、hooks/、skills/、agents/、policies/ 各自按目录约定贡献能力,settings 数组配合环境变量净化实现受控的配置注入。安装链路(gemini extensions install)内置了目录信任发现、consent 确认、Release 优先下载、完整性基线与 allowedExtensions/blockGitExtensions 企业策略等多层防护。想继续深入,可以阅读 扩展参考、扩展开发指南、最佳实践 与 发布指南,并在 扩展命令实现 与 ExtensionManager 中对照源码验证本文所述的各流程。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00