Gemini CLI伴侣插件:接口规范
Gemini CLI伴侣插件:接口规范
Section titled “Gemini CLI伴侣插件:接口规范”最后更新:2025年9月15日
本文档定义了构建一个伴侣插件的合同,以启用Gemini CLI的IDE模式。对于VS Code,这些功能(本地差异比较、上下文感知)由官方扩展提供(市场)。此规范适用于希望为其他编辑器(如JetBrains IDEs、Sublime Text等)带来类似功能的贡献者。
I. 通信接口
Section titled “I. 通信接口”Gemini CLI和IDE插件通过本地通信通道进行通信。
1. 传输层:通过HTTP的MCP
Section titled “1. 传输层:通过HTTP的MCP”插件必须运行一个实现**模型上下文协议(MCP)**的本地HTTP服务器。
- **协议:**服务器必须是一个有效的MCP服务器。如果可用的话,我们建议使用您选择的语言的现有MCP SDK。
- **端点:**服务器应该公开一个单一端点(例如,
/mcp)用于所有MCP通信。 - 端口:服务器必须监听一个动态分配的端口(即,监听端口
0)。
2. 发现机制:端口文件
Section titled “2. 发现机制:端口文件”为了让Gemini CLI连接,它需要发现它正在运行的IDE实例以及您的服务器正在使用的端口。插件必须通过创建一个“发现文件”来促进这一点。
命令行界面如何找到文件: 命令行界面通过遍历进程树来确定其运行的IDE的进程ID(PID)。然后查找一个包含此PID的名称的发现文件。
文件位置: 文件必须创建在特定目录中:os.tmpdir()/gemini/ide/。如果不存在,您的插件必须创建此目录。
文件命名约定: 文件名至关重要,必须遵循以下模式:gemini-ide-server-${PID}-${PORT}.json
${PID}:父IDE进程的进程ID。您的插件必须确定此PID并将其包含在文件名中。${PORT}:您的MCP服务器监听的端口。 文件内容和工作空间验证: 文件必须包含一个具有以下结构的JSON对象:
{ "port": 12345, "workspacePath": "/path/to/project1:/path/to/project2", "authToken": "a-very-secret-token", "ideInfo": { "name": "vscode", "displayName": "VS Code" } }port(数字,必填):MCP服务器的端口。workspacePath(字符串,必填):所有打开的工作空间根路径列表,由操作系统特定的路径分隔符分隔(Linux/macOS为:,Windows为;)。命令行界面使用此路径确保其运行在与IDE中打开的同一项目文件夹中。如果命令行界面的当前工作目录不是workspacePath的子目录,连接将被拒绝。您的插件必须提供正确的、绝对路径到打开的工作空间根目录。authToken(字符串,必填):用于保护连接的秘密令牌。命令行界面将在所有请求的Authorization: Bearer <token>头部包含此令牌。ideInfo(对象,必填):有关IDE的信息。name(字符串,必填):IDE的简短、小写标识符(例如,vscode,jetbrains)。displayName(字符串,必填):IDE的用户友好名称(例如,VS Code,JetBrains IDE)。
认证: 为了确保连接安全,插件必须生成一个唯一且保密的令牌,并将其包含在发现文件中。命令行界面(CLI)随后将在所有请求MCP服务器的请求头中包含这个令牌(例如,Authorization)。您的服务器必须对每个请求验证此令牌,并拒绝任何未经授权的请求。
使用环境变量解决冲突(推荐): 为了获得最可靠的体验,您的插件应该既创建发现文件,又在集成终端中设置GEMINI_CLI_IDE_SERVER_PORT环境变量。文件作为主要的发现机制,但环境变量对于解决冲突至关重要。如果用户为同一个工作空间打开了多个IDE窗口,CLI会使用GEMINI_CLI_IDE_SERVER_PORT变量来识别并连接到正确窗口的服务器。
II. 上下文接口
Section titled “II. 上下文接口”为了启用上下文感知,插件可以向CLI提供关于用户在IDE中活动的实时信息。
ide/contextUpdate 通知
Section titled “ide/contextUpdate 通知”插件可以在用户上下文发生变化时向CLI发送一个ide/contextUpdate通知。
通知
-
触发事件: 此通知应在以下情况下发送(建议使用50ms的防抖动):
- 打开、关闭或聚焦文件。
- 用户在活动文件中的光标位置或文本选择发生变化。
-
负载(
IdeContext): 通知参数必须是一个IdeContext对象:interface IdeContext {workspaceState?: {openFiles?: File[];isTrusted?: boolean;};}interface File {// Absolute path to the filepath: string;// Last focused Unix timestamp (for ordering)timestamp: number;// True if this is the currently focused fileisActive?: boolean;cursor?: {// 1-based line numberline: number;// 1-based character numbercharacter: number;};// The text currently selected by the userselectedText?: string;}注意:
openFiles列表应只包含磁盘上存在的文件。虚拟文件(例如,没有路径且未保存的文件,编辑器设置页面)必须被排除。
CLI如何使用此上下文
Section titled “CLI如何使用此上下文”(以下部分未提供英文原文,故无法翻译。)
在接收到IdeContext对象后,CLI 会执行几个标准化和截断步骤,然后再将信息发送给模型。
- 文件排序: CLI 使用
timestamp字段来确定最近使用的文件。它根据这个值对openFiles列表进行排序。因此,您的插件必须为文件最后一次聚焦时提供一个准确的 Unix 时间戳。 - 活动文件: CLI 仅将排序后最新的文件视为“活动”文件。它会忽略其他所有文件的
isActive标志,并清除它们的cursor和selectedText字段。您的插件应专注于设置isActive: true,并仅为当前聚焦的文件提供光标/选择详情。 - 截断: 为了管理令牌限制,CLI 会将文件列表(截断为10个文件)和
selectedText(截断为16KB)进行截断。
虽然 CLI 负责最后的截断,但强烈建议您的插件也限制发送的上下文量。
III. 差异比较接口
Section titled “III. 差异比较接口”为了启用交互式代码修改,插件可以暴露一个差异比较接口。这允许 CLI 请求 IDE 打开一个差异视图,显示对文件的拟议更改。用户可以在 IDE 中直接查看、编辑并最终接受或拒绝这些更改。
openDiff工具
Section titled “openDiff工具”插件必须在其 MCP 服务器上注册一个openDiff工具。
-
描述: 此工具指示 IDE 为特定文件打开一个可修改的差异视图。
-
请求(
OpenDiffRequest): 通过tools/call请求调用该工具。请求的params中的arguments字段必须是一个OpenDiffRequest对象。interface OpenDiffRequest {// The absolute path to the file to be diffed.filePath: string;// The proposed new content for the file.newContent: string;}
响应 (CallToolResult): 工具 必须 立即返回一个
CallToolResult 以确认请求并报告差异视图是否成功打开。
- 成功时:如果差异视图成功打开,响应 必须
包含空内容(即
content: [])。 - 失败时:如果错误阻止了差异视图的打开,响应 必须
有
isError: true并在content数组中包含一个TextContent块来描述错误。
差异的实际结果(接受或拒绝)是通过通知异步传递的。
closeDiff 工具
Section titled “closeDiff 工具”插件 必须 在其MCP服务器上注册一个 closeDiff 工具。
-
描述: 此工具指示IDE关闭特定文件的打开差异视图。
-
请求 (
CloseDiffRequest): 通过tools/call请求调用工具。请求的params中的arguments字段 必须 是一个CloseDiffRequest对象。interface CloseDiffRequest {// The absolute path to the file whose diff view should be closed.filePath: string;} -
响应 (
CallToolResult): 工具 必须 返回一个CallToolResult。- 成功时:如果差异视图成功关闭,响应 必须 在内容数组中包含一个单独的 TextContent 块,其中包含关闭前文件的最终内容。
- 失败时:如果错误阻止了差异视图的关闭,响应 必须
有
isError: true并在content数组中包含一个TextContent块来描述错误。
ide/diffAccepted 通知
Section titled “ide/diffAccepted 通知”当用户在差异视图中接受更改(例如,通过点击“应用”或“保存”按钮)时,插件 必须 向CLI发送一个 ide/diffAccepted 通知。
-
有效载荷: 通知参数 必须 包括文件路径和文件的最终内容。如果用户在差异视图中进行了手动编辑,内容可能与原始
newContent不同。{// The absolute path to the file that was diffed.filePath: string;// The full content of the file after acceptance.content: string;}
ide/diffRejected 通知
Section titled “ide/diffRejected 通知”当用户拒绝更改(例如,在不接受的情况下关闭差异视图),插件必须向 CLI 发送一个 ide/diffRejected 通知。
-
负载:通知参数必须包括被拒绝差异的文件路径。
{// The absolute path to the file that was diffed.filePath: string;}
IV. 生命周期接口
Section titled “IV. 生命周期接口”插件必须根据 IDE 的生命周期正确管理其资源和发现文件。
- 激活时(IDE 启动/插件启用):
- 启动 MCP 服务器。
- 创建发现文件。
- 停用时(IDE 关闭/插件禁用):
- 停止 MCP 服务器。
- 删除发现文件。