mcpField
C
claude-plugin-converter

claude-plugin-converter

github.com/moonlight-lupinAgent 工作流113126 次安装1 天前更新
代码仓库

关于 claude-plugin-converter

claude-plugin-converter 可将 Claude Code 插件转换为可安装的独立 Hermes 插件。它先评估各组件的可转换程度,再生成插件,并标明不支持的部分及手动步骤。

主要功能

  1. 01分析插件组件的可转换性
  2. 02转换清单、技能和 MCP 配置
  3. 03映射可支持的命令、钩子和 Agent
  4. 04将输出打包为 Hermes 插件
  5. 05记录不支持的组件和手动步骤

适用场景

  1. 01为 Hermes Agent 准备 Claude Code 插件
  2. 02生成前评估转换缺口
  3. 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.md
scripts/
analyze.py
convert.py
scripts/schemas/
mcp.schema.json
plugin.schema.json
tests/
test_converter.py

详细介绍

Claude 插件转换器

将 Claude Code 插件(.claude-plugin/plugin.json 清单 + 组件)转换为独立、可安装的 Hermes 插件(plugin.yaml + __init__.py + 随附的技能/钩子)。

适用场景

  • 用户想在 Hermes Agent 中使用 Claude Code 插件
  • 用户说“转换这个 Claude 插件”或“让它能在 Hermes 中使用”
  • 用户提供了 Claude 插件目录、Git URL 或市场引用

概览

两阶段工作流:

  1. 发现 — 分析 Claude 插件,并报告可以和不可以转换的内容
  2. 转换 — 生成完整的 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 字段备注
descriptiondescription直接复制
namename直接复制(用于 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_call
  • SessionStart → on_session_start
  • SessionEnd → on_session_end
  • UserPromptSubmit → pre_llm_call(两者都可以注入上下文)
  • SubagentStart → subagent_start
  • SubagentStop → subagent_stop
  • Stop → 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>

常见陷阱

  1. $ARGUMENTS 没有对应的 Hermes 功能 — Claude 技能使用 $ARGUMENTS 接收用户输入。Hermes 技能会加载到上下文中,由 Agent 自然地读取用户消息。请标记为需要人工审核。

  2. disable-model-invocation — Claude 允许技能仅由用户手动调用。Hermes 技能始终由模型调用。请移除此字段并注明。

  3. Agent 范式转变 — Claude 有独立的 Agent 定义。Hermes 在运行时使用 delegate_task。转换器会将每个 Agent 封装为一个委派技能,但其行为不会完全相同。

  4. 许多钩子事件没有对应的 Hermes 功能 — Claude 的 30 个事件中,约有 20 个无法转换。报告会清楚列出这些事件。

  5. prompt 和 agent 钩子类型 — 没有直接对应的 Hermes 功能。如有需要,用户可在 MANUAL_STEPS 中查看说明并手动实现。

  6. LSP 服务 — Hermes 不支持 LSP 集成。相关内容会跳过并在报告中注明。

  7. ${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`。

  8. MCP 服务的作用域名称 — Claude 使用 mcp__plugin_<plugin-name>_<server-name>__<tool>。Hermes 使用 mcp__<server-name>__<tool>(不含插件命名空间)。转换器必须去掉插件命名空间前缀。

  9. 命令与技能 — Claude 的 commands/ 比 skills/ 更简单(扁平 Markdown 文件,没有前置元数据)。Hermes 斜杠命令需要 Python 处理程序。转换器会将每个命令封装为一个 ctx.register_command(),并将 Markdown 内容作为提示词返回。

  10. 必须复制非技能数据目录 — Claude 插件通常会附带支持目录(engines/、foundations/、connectors/、docs/),技能会通过相对路径引用这些目录。必须将这些目录复制到 Hermes 插件输出目录,与转换后的技能放在一起,否则所有相对链接都会失效。转换器会跳过 .git、__pycache__、.pytest_cache、tests 和隐藏目录,但会复制其他所有内容。

  11. 在 __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") 加载。这是预期行为,并非转换失败。

陷阱:解析器错误(测试中发现)

  1. monitors.json 可以是裸列表——不一定是 {"monitors": [...]}。分析器必须处理 isinstance(monitors_data, list) 并直接使用该列表;对于字典情况,则回退到 .get("monitors", [])。

  2. Claude 的 hooks.json 采用嵌套布局——每个事件条目内部都包含一个 hooks 数组:{"Stop": [{"hooks": [{"type": "command", "command": "..."}]}]}。分析器必须通过 hook_entry.get("hooks", []) 遍历内部钩子定义,而不是直接从外层条目读取 type/command。外层条目还可能包含一个适用于所有内部钩子的 matcher 字段。如果不存在内部 hooks 数组,则回退到扁平布局(从条目本身读取 type/command)。

  3. 必须将钩子回调名称从 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 中的钩子部分将为空,也不会触发任何钩子。

  4. 带有复杂引号的 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, ...)。

验证清单

  1. 对每个生成的 .py 文件运行 python3 -c "import py_compile; py_compile.compile('hooks.py', doraise=True)"
  2. 安装插件:cp -r <name> ~/.hermes/plugins/ && hermes plugins enable <name>
  3. 检查日志中是否存在加载失败:grep -i "failed to load plugin" ~/.hermes/logs/agent.log
  4. 测试技能加载:hermes chat -q 'Load skill "plugin-name:skill-name" and tell me what it does' -t skills
  5. 插件技能默认不启用(不在 <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 均可正常工作。

评论

支持 Markdown