Kimi Code CLI 插件系统实战:用 plugin.json 打造轻量级自定义工具
【免费下载链接】kimi-cliKimi Code CLI is your next CLI agent.项目地址: https://gitcode.com/GitHub_Trending/ki/kimi-cli
Kimi Code CLI 的插件(Plugin)系统允许你通过一个包含plugin.json的目录为 CLI Agent 注入可执行的自定义工具,从而扩展 AI 的能力边界。本文以官方文档 docs/zh/customization/plugins.md 为骨架,结合仓库中 plugin 模块源码、CLI 命令实现 与 示例插件 展开,帮助你从安装、声明、凭证注入到工具脚本编写,完整掌握插件的开发与使用闭环。
插件是什么
一个插件就是一个包含plugin.json文件的目录。插件可以声明多个「工具」(Tools),每个工具是一个可执行命令(Python、TypeScript、Shell 脚本等),AI 可以调用这些工具来完成特定任务。
例如,你可以创建一个插件来:
- 封装内部 API 的调用脚本
- 提供项目特定的代码生成工具
- 集成专有服务或数据库查询
与需要持续运行的 MCP 服务器不同,插件是轻量级的本地工具包,适合封装项目特定的脚本和实用程序。两者是互补的扩展机制:
| 机制 | 适用场景 |
|---|---|
| MCP | 需要持续运行的服务、复杂的工具编排、跨进程通信 |
| 插件 | 简单的脚本封装、项目特定的工具、快速原型开发 |
插件与 Agent Skills 的核心区别在于:
- Skills:通过
SKILL.md提供知识性指导,AI 读取后遵循其中的规范 - Plugins:通过
plugin.json声明可执行工具,AI 可以直接调用工具获取结果
从源码结构看,插件机制由三部分构成:plugin/__init__.py负责plugin.json的解析校验与凭证注入,plugin/manager.py负责安装/卸载/列出,plugin/tool.py负责把声明包装成可被 Agent 调用的PluginTool(基于 kosong 的CallableTool基类),见 plugin/init.py 与 plugin/tool.py。
注意:插件系统目前处于Beta 阶段,具体实现细节和配置定义可能会在未来版本中调整,请谨慎在生产环境中使用并关注后续更新。
安装插件
使用kimi plugin命令管理插件,对应实现见 cli/plugin.py。
从本地目录安装
kimi plugin install /path/to/my-plugin从 ZIP 文件安装
# 本地 ZIP 文件 kimi plugin install my-plugin.zip # 远程 ZIP 链接(含 GitHub/GitLab 归档下载链接) kimi plugin install https://example.com/my-plugin.zip kimi plugin install https://github.com/user/repo/archive/refs/heads/main.zipZIP 的解析逻辑会先检查归档内成员路径是否逃逸临时目录(防止 zip-slip 攻击),再在解压根目录及一层子目录中寻找plugin.json,见 cli/plugin.py。
从 Git 仓库安装
# 安装根目录的插件 kimi plugin install https://github.com/user/repo.git # 安装子目录中的插件(多插件仓库) kimi plugin install https://github.com/user/repo.git/plugins/my-plugin # 指定分支(使用浏览器 URL 格式) kimi plugin install https://github.com/user/repo/tree/develop/plugins/my-pluginGit URL 的解析由_parse_git_url完成:它能在.git边界处拆分出克隆地址与子路径,也能识别 GitHub/GitLab 短链接(取前两段为 owner/repo,其余为子路径),还会剥离浏览器复制 URL 中的tree/{branch}/与 GitLab 的-/tree/{branch}/前缀并提取分支名,见 cli/plugin.py。
多插件仓库:当 Git 仓库根目录没有plugin.json时,Kimi Code CLI 会扫描根目录及其直接子目录,列出可用的插件供你选择,提示形如:
Error: No plugin.json at repository root. Available plugins: - my-plugin - other-plugin Use: kimi plugin install <url>/<plugin-name>管理命令
# 列出已安装插件 kimi plugin list # 查看插件详情 kimi plugin info my-plugin # 移除插件 kimi plugin remove my-plugin其中list会区分installed(由宿主安装、写入过 runtime 信息)与not configured两种状态;info会展示插件名称、版本、描述、配置文件、inject 映射以及安装时的宿主(host)与版本,见 cli/plugin.py。
创建插件
创建插件只需要三步:
- 创建一个目录
- 编写
plugin.json文件 - 实现工具脚本
目录结构
my-plugin/ ├── plugin.json # 插件配置(必需) ├── config.json # 插件配置(可选,用于凭证注入) └── scripts/ # 工具脚本 ├── greet.py └── calc.tsplugin.json格式
{ "name": "my-plugin", "version": "1.0.0", "description": "My custom plugin for project X", "config_file": "config.json", "inject": { "api_key": "api_key", "endpoint": "base_url" }, "tools": [ { "name": "greet", "description": "Generate a greeting message", "command": ["python3", "scripts/greet.py"], "parameters": { "type": "object", "properties": { "name": { "type": "string", "description": "Name to greet" } }, "required": ["name"] } } ] }字段说明
| 字段 | 说明 | 是否必填 |
|---|---|---|
name | 插件名称,只能使用小写字母、数字和连字符 | 是 |
version | 插件版本,语义化版本格式 | 是 |
description | 插件描述 | 否 |
config_file | 配置文件路径,用于凭证注入 | 否 |
inject | 凭证注入映射,键为目标路径,值为源变量名 | 否 |
tools | 工具列表 | 否 |
工具字段说明
| 字段 | 说明 | 是否必填 |
|---|---|---|
name | 工具名称 | 是 |
description | 工具描述 | 是 |
command | 执行命令,字符串数组 | 是 |
parameters | JSON Schema 格式的参数定义 | 否 |
源码中的校验逻辑(plugin/init.py)会强制执行两条规则:name与version缺失直接报错;一旦声明了inject就必须同时提供config_file,否则抛出PluginError。解析结果通过 pydantic 的PluginSpec/PluginToolSpec模型验证,parameters的默认值为空对象{"type": "object", "properties": {}}。
凭证注入
如果插件需要调用 LLM API,可以通过inject配置自动获取 Kimi Code CLI 的凭证配置。
inject配置示例
{ "config_file": "config.json", "inject": { "llm.api_key": "api_key", "llm.endpoint": "base_url" } }支持的注入变量
| 变量名 | 说明 |
|---|---|
api_key | LLM 提供商的 API 密钥,支持 OAuth token 和静态 API key |
base_url | LLM API 的基础 URL |
config.json模板
{ "llm": { "api_key": "", "endpoint": "" } }注入的底层机制在 plugin/init.py 的inject_config中实现:它把inject的键视为点号分隔的嵌套路径(由_set_nested逐层创建中间字典),把宿主提供的凭证值写入config.json对应位置;同时对config_file做路径逃逸检查,确保它不能越出插件目录。
宿主凭证由collect_host_values(plugin/manager.py)从当前默认模型对应的 Provider 解析而来:静态 API key 直接读取,OAuth 场景则通过OAuthManager.resolve_api_key解析出有效 token。
凭证的更新链路分为三个层面:
- 安装时:将当前配置的 API 密钥和 base URL 注入到指定的配置文件中;
- 应用启动时:Kimi Code CLI 会遍历
~/.kimi/plugins/下所有插件,对声明了inject+config_file的插件重新注入最新凭证,见 app.py 中调用的refresh_plugin_configs(plugin/manager.py); - 工具运行时:
PluginTool._build_env会在每次调用时从当前配置重新读取最新凭证(如刷新后的 OAuth token),以环境变量形式传给子进程,见 plugin/tool.py。
提示:一般情况下,不需要为了更新凭证而重新安装插件:切换 LLM 提供商或重新授权后,重启 Kimi Code CLI 即可自动刷新配置文件中的凭证,插件工具在实际运行时也会通过环境变量获得当前有效的凭证。只有在修改了插件本身的配置结构(例如
config_file或inject映射)时,才需要重新安装插件。
关于 inject 键名:
inject中的键名(如llm.api_key)也会被用作环境变量名传递给插件工具子进程。由于这些名称包含点号,在某些运行环境中访问可能不便(例如 POSIX shell 中$llm.api_key是无效的)。你可以通过字典/映射方式访问:
- Node.js:
process.env["llm.api_key"]- Python:
os.environ["llm.api_key"]如果希望使用更友好的环境变量名,建议在插件中使用大写下划线格式(如
LLM_API_KEY),并相应调整配置文件结构。
工具脚本规范
工具脚本通过标准输入接收参数,标准输出返回结果。运行时由PluginTool.__call__以子进程方式执行声明好的command(工作目录为插件根目录),参数序列化为 JSON 写入 stdin,stdout 整体作为工具结果返回,见 plugin/tool.py。
输入格式:脚本从stdin接收 JSON 对象:
{ "name": "World" }输出格式:脚本向stdout输出的内容会作为字符串返回给 Agent。如果需要结构化输出,建议输出 JSON 文本:
{ "content": "Hello, World!" }Python 示例
#!/usr/bin/env python3 import json import sys params = json.load(sys.stdin) name = params.get("name", "Guest") result = {"content": f"Hello, {name}!"} print(json.dumps(result))TypeScript 示例
#!/usr/bin/env tsx import * as readline from "readline"; const rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false, }); let input = ""; rl.on("line", (line) => { input += line; }); rl.on("close", () => { const params = JSON.parse(input); const name = params.name || "Guest"; console.log(JSON.stringify({ content: `Hello, ${name}!` })); });运行约束(来自 plugin/tool.py 的实现事实):
- 单次工具调用有120 秒超时,超时后子进程会被 kill,返回
Timeout错误; - 进程退出码非 0 时,工具调用失败,错误信息取 stderr(为空时回退到 stdout 或退出码);
- stderr 非空但退出码为 0 时仅记录 debug 日志,不视为失败;
- stdout 输出会先解码 UTF-8(非法字节用替换符处理)再去除首尾空白;
- 如果运行环境配置了审批机制,执行插件工具前会先发起审批请求,被拒绝则返回
ToolRejectedError(plugin/tool.py)。
完整示例
仓库的 examples/sample-plugin/ 是一个开箱即用的参考实现,同时包含一个 Python 工具与一个 TypeScript 工具:
{ "name": "sample-plugin", "version": "1.0.0", "description": "Sample plugin demonstrating Skills + Tools", "tools": [ { "name": "py_greet", "description": "Generate a greeting message (Python tool)", "command": ["python3", "scripts/greet.py"], "parameters": { "type": "object", "properties": { "name": { "type": "string", "description": "Name to greet" }, "lang": { "type": "string", "enum": ["en", "zh", "ja"], "description": "Language" } }, "required": ["name"] } }, { "name": "ts_calc", "description": "Evaluate a math expression (TypeScript tool)", "command": ["npx", "tsx", "scripts/calc.ts"], "parameters": { "type": "object", "properties": { "expression": { "type": "string", "description": "Math expression to evaluate" } }, "required": ["expression"] } } ] }对应的两个脚本分别位于 scripts/greet.py 与 scripts/calc.ts。greet.py按lang参数输出英/中/日三种语言的问候;calc.ts通过正则白名单^[\d\s+\-*/.()]+$过滤表达式后求值,非法输入直接写 stderr 并以非零码退出——这正是前面「退出码非 0 即失败」协议的典型用法。
该插件还附带 SKILL.md,展示了「Skills 提供使用指导、Plugins 提供可执行工具」的组合用法:Skill 告诉 Agent「greet Alice in Chinese 应调用 py_greet(name="Alice", lang="zh")」,而实际执行交给插件工具完成。这也印证了两种扩展机制在实战中往往是配合使用的。
插件安装位置与生命周期
插件统一安装在~/.kimi/plugins/目录下(由get_plugins_dir()基于 share 目录计算,见 plugin/manager.py)。每个插件是一个独立的子目录,包含完整的plugin.json和脚本文件。
安装过程(install_plugin,plugin/manager.py)有几个值得注意的实现细节:
- 两阶段安装:先把源目录拷贝到插件目录内的临时 staging 目录,依次完成凭证注入与 runtime 写入,再整体 rename 到最终位置。升级失败时旧安装不会被破坏;
- runtime 元数据:安装成功后会往
plugin.json写入runtime字段,记录宿主名称(kimi-code)与宿主版本,用于kimi plugin list/info展示安装状态; - 名称安全校验:插件名会被解析为绝对路径并校验必须位于插件目录内,防止路径穿越。
启动后,Kimi Code CLI 会在加载 Agent 工具集时扫描~/.kimi/plugins/,把每个插件声明的工具包装为PluginTool注册进工具列表(见 soul/agent.py 与load_plugin_tools,plugin/tool.py),Agent 即可像调用内置工具一样调用它们。
如果你需要更深地验证插件机制的行为,可以参考仓库测试 tests/core/test_plugin.py 与 tests/core/test_plugin_manager.py,其中覆盖了解析校验、注入、安装等路径的断言。
结语
插件系统为 Kimi Code CLI 提供了一条从「脚本封装」到「Agent 可调用工具」的最短路径:一个目录、一份plugin.json、若干遵循 stdin/stdout 协议的脚本,即可完成一次能力扩展。配合inject凭证注入、启动时凭证刷新、运行时环境变量传递三层机制,插件既能在安装时拿到宿主配置,也能在 OAuth token 刷新后继续使用最新凭证,无需反复重装。对于需要持续运行或复杂编排的场景,可以进一步参考 MCP 扩展机制,与插件形成互补。
【免费下载链接】kimi-cliKimi Code CLI is your next CLI agent.项目地址: https://gitcode.com/GitHub_Trending/ki/kimi-cli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考