关于 claude-plugin-converter
claude-plugin-converter 可将 Claude Code 插件转换为可安装的独立 Hermes 插件。它先评估各组件的可转换程度,再生成插件,并标明不支持的部分及手动步骤。
主要功能
- 01分析插件组件的可转换性
- 02转换清单、技能和 MCP 配置
- 03映射可支持的命令、钩子和 Agent
- 04将输出打包为 Hermes 插件
- 05记录不支持的组件和手动步骤
适用场景
- 01为 Hermes Agent 准备 Claude Code 插件
- 02生成前评估转换缺口
- 03将支持的技能和 MCP 设置迁入 Hermes
MCP 相关
它会将源插件的 MCP 服务配置转换为 Hermes 使用的 `mcp_config.yaml` 片段。它本身不提供 MCP 服务。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ moonlight-lupin/ agent-skills --skill claude-plugin-converter安装后在 Claude Code 中输入/claude-plugin-converter确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/mapping-tables.mdscripts/analyze.pyconvert.pyscripts/schemas/mcp.schema.jsonplugin.schema.jsontests/test_converter.py详细介绍
Claude 插件转换器
将 Claude Code 插件(.claude-plugin/plugin.json 清单 + 组件)转换为独立、可安装的 Hermes 插件(plugin.yaml + __init__.py + 随附的技能/钩子)。
适用场景
- 用户想在 Hermes Agent 中使用 Claude Code 插件
- 用户说“转换这个 Claude 插件”或“让它能在 Hermes 中使用”
- 用户提供了 Claude 插件目录、Git URL 或市场引用
概览
两阶段工作流:
- 发现 — 分析 Claude 插件,并报告可以和不可以转换的内容
- 转换 — 生成完整的 Hermes 插件目录,供用户通过
hermes plugins enable <name>安装
输出是一个独立的 Hermes 插件——技能、钩子和 MCP 配置全部包含在同一个 ~/.hermes/plugins/<name>/ 目录中,不会散落在各处。
⚠️ 安全与信任边界
只转换来自可信来源的插件。 转换器会读取源插件中的 Shell 命令、Python 钩子和 MCP 服务配置,并在 Hermes 输出中复现这些内容。转换后的钩子可能会通过 subprocess.run(..., shell=True, ...) 执行源插件中的 Shell 命令。
启用转换后的插件前:
- 检查
hooks.py— 检查每个subprocess.run调用和_CMD_*变量,确认没有危险命令 - 检查
__init__.py— 查看注册了哪些内容(工具、钩子、斜杠命令) - 检查
mcp_config.yaml— 确认 MCP 服务命令和环境变量安全 - 检查
MANUAL_STEPS.md— 了解转换器无法自动处理的内容
不要在未检查生成内容的情况下,盲目转换并启用来自不可信 GitHub 仓库或市场的插件。
阶段 1:发现
运行分析脚本:
python3 {SKILL_DIR}/scripts/analyze.py <claude_plugin_dir> --output <output_dir>/analysis.json
该脚本会读取 .claude-plugin/plugin.json 和所有组件目录,并为每个组件生成包含可转换性评估的结构化 JSON。
以表格形式向用户展示结果,说明:
- 哪些内容可以顺利转换(✅)
- 哪些内容只能部分转换(⚠️)
- 哪些内容在 Hermes 中没有对应项(⏭️)
完整的组件 → 组件映射见 references/mapping-tables.md。
阶段 2:转换
获得用户批准后,运行转换脚本:
python3 {SKILL_DIR}/scripts/convert.py <claude_plugin_dir> --analysis <output_dir>/analysis.json --output <output_dir>/<plugin_name>
这会生成完整的 Hermes 插件目录:
<plugin_name>/
├── plugin.yaml # Translated manifest
├── __init__.py # register(ctx) — wires tools, hooks, skills, commands
├── schemas.py # Tool schemas (if MCP servers had custom tools)
├── tools.py # Tool handlers (if any)
├── hooks.py # Hook callback functions (only if hooks exist)
├── skills/ # Bundled skills (registered via ctx.register_skill)
│ └── <skill-name>/
│ └── SKILL.md
├── engines/ # Non-skill data dirs copied from source (engines, foundations, etc.)
├── foundations/
├── connectors/
├── mcp_config.yaml # MCP server config snippet (for user to merge)
├── CONVERSION_REPORT.md # Full report: converted, partial, skipped, manual steps
└── MANUAL_STEPS.md # What the user must do by hand
安装
转换完成后,安装插件:
cp -r <output_dir>/<plugin_name> ~/.hermes/plugins/
hermes plugins enable <plugin_name>
# Then restart: /reset in CLI or /restart in gateway
如果插件包含 MCP 服务,请将 mcp_config.yaml 合并到 ~/.hermes/config.yaml:
cat <plugin_name>/mcp_config.yaml >> ~/.hermes/config.yaml
# Or use: hermes mcp add <name> --command <cmd> --args <args>
组件映射摘要
| Claude 组件 | Hermes 目标 | 位置 | 可转换性 |
|---|---|---|---|
清单(plugin.json) | plugin.yaml | 插件根目录 | ✅ 字段直接映射 |
技能(skills/*/SKILL.md) | 随附的技能 | skills/*/SKILL.md + ctx.register_skill() | ✅ Frontmatter 映射 |
命令(commands/*.md) | 斜杠命令 | __init__.py 中的 ctx.register_command() | ⚠️ 格式更简单,需要封装 |
钩子(hooks/hooks.json) | 插件钩子 | hooks.py + ctx.register_hook() | ⚠️ 约 30 个事件中有 10 个有对应项 |
Agent(agents/*.md) | 委派技能 | skills/<agent-name>/SKILL.md | ⚠️ 范式转变 |
MCP 服务(.mcp.json) | MCP 配置 | mcp_config.yaml 片段 | ✅ 配置格式转换 |
LSP 服务(.lsp.json) | ❌ 无对应项 | — | ⏭️ 跳过,并在报告中注明 |
监视器(monitors/*.json) | Cron 作业 | 在 MANUAL_STEPS.md 中注明 | ⚠️ 概念不同,需手动设置 |
bin/(PATH 可执行文件) | 插件数据文件 | 复制到插件目录中 | ✅ 优先级较低 |
Frontmatter 映射(SKILL.md)
| Claude 字段 | Hermes 字段 | 备注 |
|---|---|---|
description | description | 直接复制 |
name | name | 直接复制(用于 ctx.register_skill) |
disable-model-invocation | ❌ | 没有对应项 — Hermes 技能始终由模型调用。删除并注明。 |
$ARGUMENTS(正文中) | ❌ | 没有对应的占位符。改为引用“用户的请求”,或标记为需人工审核。 |
| (缺失) | version | 从 plugin.json 继承版本 |
| (缺失) | author | 从 plugin.json 继承作者 |
Hook 事件映射
完整的 30 多项事件映射表请参阅 references/mapping-tables.md。
关键映射:
PreToolUse→pre_tool_call(两者都可以阻止操作)PostToolUse→post_tool_callSessionStart→on_session_startSessionEnd→on_session_endUserPromptSubmit→pre_llm_call(两者都可以注入上下文)SubagentStart→subagent_startSubagentStop→subagent_stopStop→post_llm_call(最接近的对应项)PermissionRequest→pre_approval_request
没有对应 Hermes 事件的事件:PostToolBatch、PreCompact、PostCompact、Notification、FileChanged、WorktreeCreate/Remove、CwdChanged、InstructionsLoaded、ConfigChange、TeammateIdle、Elicitation、TaskCreated/Completed。
Hook 类型映射
| Claude Hook 类型 | Hermes 实现 | 备注 |
|---|---|---|
command(shell) | 在 hooks.py 中使用 subprocess 的 Python 回调 | 或在 config.yaml 中使用 shell hook |
http(向 URL 发送 POST 请求) | 使用 httpx.post() 的 Python 回调 | 简单直接 |
mcp_tool(调用 MCP 工具) | 使用 ctx.dispatch_tool() 的 Python 回调 | 映射限定范围的工具名称 |
prompt(LLM 评估) | ⚠️ 没有直接对应项 | 在 MANUAL_STEPS 中注明 — 可以启动单次 Agent |
agent(Agent 式验证器) | ⚠️ 没有直接对应项 | 在 MANUAL_STEPS 中注明 — 可以使用 delegate_task |
Agent → 委派技能转换
Claude Agent 是包含系统提示词和 frontmatter(model、effort、maxTurns、tools)的 Markdown 文件。
Hermes 没有独立的 Agent 定义。因此,每个 Agent 都会转换为一个捆绑技能,指示 Agent 使用 delegate_task:
---
name: <agent-name>
description: <from Claude agent description>
---
# <Agent Name>
When the user's task matches this agent's specialty, delegate it:
1. Call `delegate_task` with:
- `goal`: "<from Claude agent description>"
- `context`: "<full system prompt from the Claude agent .md file>"
2. Do not attempt the task yourself — delegate it.
## Original Agent Config
- Model: <from frontmatter>
- MaxTurns: <from frontmatter>
- Tools: <from frontmatter, if restricted>
常见陷阱
-
$ARGUMENTS没有对应的 Hermes 功能 — Claude 技能使用$ARGUMENTS接收用户输入。Hermes 技能会加载到上下文中,由 Agent 自然地读取用户消息。请标记为需要人工审核。 -
disable-model-invocation— Claude 允许技能仅由用户手动调用。Hermes 技能始终由模型调用。请移除此字段并注明。 -
Agent 范式转变 — Claude 有独立的 Agent 定义。Hermes 在运行时使用
delegate_task。转换器会将每个 Agent 封装为一个委派技能,但其行为不会完全相同。 -
许多钩子事件没有对应的 Hermes 功能 — Claude 的 30 个事件中,约有 20 个无法转换。报告会清楚列出这些事件。
-
prompt和agent钩子类型 — 没有直接对应的 Hermes 功能。如有需要,用户可在 MANUAL_STEPS 中查看说明并手动实现。 -
LSP 服务 — Hermes 不支持 LSP 集成。相关内容会跳过并在报告中注明。
-
${CLAUDE_PLUGIN_ROOT}出现在技能正文中,而不只是在钩子中 — Claude 技能会在 Markdown 链接和行内代码中使用${CLAUDE_PLUGIN_ROOT}引用插件目录中的文件(例如[${CLAUDE_PLUGIN_ROOT}/foundations/doctrine.md](../../foundations/doctrine.md))。一个实际插件在 21 个技能中共有 120 处此类引用。转换器会将${CLAUDE_PLUGIN_ROOT}替换为..(从skills//指向插件根目录的相对路径)。对于 Python 钩子,请改用Path(file).parent`。 -
MCP 服务的作用域名称 — Claude 使用
mcp__plugin_<plugin-name>_<server-name>__<tool>。Hermes 使用mcp__<server-name>__<tool>(不含插件命名空间)。转换器必须去掉插件命名空间前缀。 -
命令与技能 — Claude 的
commands/比skills/更简单(扁平 Markdown 文件,没有前置元数据)。Hermes 斜杠命令需要 Python 处理程序。转换器会将每个命令封装为一个ctx.register_command(),并将 Markdown 内容作为提示词返回。 -
必须复制非技能数据目录 — Claude 插件通常会附带支持目录(
engines/、foundations/、connectors/、docs/),技能会通过相对路径引用这些目录。必须将这些目录复制到 Hermes 插件输出目录,与转换后的技能放在一起,否则所有相对链接都会失效。转换器会跳过.git、__pycache__、.pytest_cache、tests和隐藏目录,但会复制其他所有内容。 -
在
__init__.py中有条件地导入钩子 — 如果 Claude 插件没有钩子,生成的__init__.py就不能导入hooks模块。转换器会检查analysis["components"]["hooks"],仅在存在钩子时才生成from . import hooks这一行。
验证
转换后,验证插件是否已加载:
# Copy to plugins dir (if not already there)
cp -r <output_dir>/<plugin_name> ~/.hermes/plugins/
# Check it's discovered
HERMES_PLUGINS_DEBUG=1 hermes plugins list
# Enable and test
hermes plugins enable <plugin_name>
# Then test skill loading (plugin skills are opt-in, not in available_skills):
hermes chat -q 'Load skill "plugin-name:skill-name" and tell me what it does' -t skills
插件技能为选择加入(不会列在 <available_skills> 中)。它们通过 skill_view("plugin-name:skill-name") 加载。这是预期行为,并非转换失败。
陷阱:解析器错误(测试中发现)
-
monitors.json可以是裸列表——不一定是{"monitors": [...]}。分析器必须处理isinstance(monitors_data, list)并直接使用该列表;对于字典情况,则回退到.get("monitors", [])。 -
Claude 的
hooks.json采用嵌套布局——每个事件条目内部都包含一个hooks数组:{"Stop": [{"hooks": [{"type": "command", "command": "..."}]}]}。分析器必须通过hook_entry.get("hooks", [])遍历内部钩子定义,而不是直接从外层条目读取type/command。外层条目还可能包含一个适用于所有内部钩子的matcher字段。如果不存在内部hooks数组,则回退到扁平布局(从条目本身读取type/command)。 -
必须将钩子回调名称从
convert_hooks()传递给generate_init_py()——convert_hooks()会生成回调函数名称(例如_on_post_llm_call_0),并在hook_infos中返回,但generate_init_py()需要这些名称来生成ctx.register_hook()调用。将它们作为{event_name: [callback_name, ...]}字典传递。如果跳过这一步,__init__.py中的钩子部分将为空,也不会触发任何钩子。 -
带有复杂引号的 Shell 命令会导致手动转义失败——Claude 钩子命令通常包含嵌套的单引号、双引号和反斜杠(例如
python3 -c "import os; os.environ.get('CLAUDE_PLUGIN_ROOT')...")。切勿用.replace("'", "\\'")手动转义这些内容——这样会生成无效的 Python。使用 Python 的repr()(!r格式说明符)生成安全加引号的模块级变量,然后在subprocess.run()中引用该变量:将命令存为_CMD_0 = {command!r},然后调用subprocess.run(_CMD_0, shell=True, ...)。
验证清单
- 对每个生成的
.py文件运行python3 -c "import py_compile; py_compile.compile('hooks.py', doraise=True)" - 安装插件:
cp -r <name> ~/.hermes/plugins/ && hermes plugins enable <name> - 检查日志中是否存在加载失败:
grep -i "failed to load plugin" ~/.hermes/logs/agent.log - 测试技能加载:
hermes chat -q 'Load skill "plugin-name:skill-name" and tell me what it does' -t skills - 插件技能默认不启用(不在
<available_skills>中)——通过skill_view("plugin:skill")加载才是正确的测试方式,而不是检查它是否出现在 skills_list 中
测试对象
-
一个包含 21 个技能的会计类插件(Python 引擎、基础组件、连接器)——全部 21 个技能均已顺利转换,120 个
${CLAUDE_PLUGIN_ROOT}引用已改写,数据目录已复制,插件已加载,且已确认 skill_view 可正常工作。 -
一个包含 51 个技能的多组件插件(6 个 Agent、2 个钩子、1 个监控器、bin/)——51 个技能已转换,6 个 Agent → 委派技能,2 个 Stop 钩子 → post_llm_call,监控器已标记为需手动配置 cron。发现 4 个错误(monitors.json 列表格式、钩子嵌套布局、回调名称传递、Shell 引号)——均已在脚本中修复。插件已加载,且已确认常规技能和委派技能的 skill_view 均可正常工作。