前言:上一篇解释 Skill、Plugin 和 MCP 的边界,这一篇只实现一个功能:检查 Markdown 的 H1 数量、标题跳级、代码块语言和空链接。三条路线使用相同输入、相同规则和相同 JSON 契约;区别只在发现方式、执行位置、协议与确定性。
系列导航:这组文章按“总览 → 入口 → 运行时 → 扩展 → 状态 → 协作 → 安全”的顺序展开;第一次阅读可以从总览开始,带着具体问题也可以直接跳到专题。
- 01|Hermes Agent 架构总览:从 Agent Loop 到智能体平台
- 02|Hermes Desktop 架构:Electron 如何连接本地 Python Agent
- 03|Hermes Agent 运行时:AIAgent、模型协议与工具执行
- 04|Hermes Agent 扩展体系:Skill、Plugin 与 MCP
- 05|实战:同一个 Markdown 检查器的 Skill、Plugin 与 MCP 三种实现
- 06|Hermes Agent 的持续学习系统:Memory、Review、Skill 与 Curator
- 07|Hermes Agent 的长会话架构:Prompt Cache、压缩与 SessionDB
- 08|Hermes Agent 的多 Agent 与自动化:从 Goal 到 Kanban
- 09|Hermes Agent 安全架构:审批、沙箱、回滚与凭据隔离
先列需求:只做一个 Markdown 规范检查器
如果 Skill、Plugin 和 MCP 分别解决不同业务,读者就很难公平比较。这里故意把功能压缩到四条离线规则,并要求三种实现接受同一份 Markdown、返回同一结构。
| 编号 | 需求 | 验收标准 |
|---|---|---|
| R1 | 输入是一段 UTF-8 Markdown 和 max_issues | 三种路线使用完全相同的正文与上限 50 |
| R2 | 文档必须且只能有一个 H1 | 数量不为 1 时返回 h1-count error |
| R3 | 标题不得跨级 | H1 直接到 H3 返回 heading-jump warning |
| R4 | 围栏代码必须声明语言 | 缺少语言返回 code-language warning |
| R5 | 普通 Markdown 链接目标不能为空 | 空目标返回 empty-link error |
| R6 | 默认只读、无网络、输入最多 64 KiB | 不注册写工具,不修改输入,不发出外部请求 |
| R7 | 统一 JSON 输出 | 字段、严重级别、行号和排序遵守同一契约 |
统一输入(Canonical Input)
请检查下面的 Markdown,最多返回 50 个问题。
严格返回 JSON,不要修改原文。
# 部署指南
### 安装
```
pip install demo
```
访问[项目主页]()了解更多。统一输出(Canonical Output)
{
"ok": false,
"summary": {
"errors": 1,
"warnings": 2
},
"findings": [
{
"severity": "warning",
"rule": "heading-jump",
"message": "标题层级从 H1 跳到了 H3:安装",
"line": 3
},
{
"severity": "warning",
"rule": "code-language",
"message": "围栏代码块没有声明语言",
"line": 5
},
{
"severity": "error",
"rule": "empty-link",
"message": "链接目标为空",
"line": 9
}
],
"findings_truncated": false
}公平比较原则:用户输入和结果契约相同;只改变中间执行路径。Plugin 与 MCP 可以做到逐字段一致;Skill 以同一 JSON 为目标,但模型生成天然不保证每次逐字一致。
先看一张总图:输入输出相同,中间执行者不同
flowchart LR
Input[同一 Markdown 请求
Canonical Input] --> S[技能路线
Skill]
Input --> P[插件路线
Plugin]
Input --> M[MCP 服务路线
MCP]
S --> SM[模型执行规则
Model Execution]
P --> PH[进程内处理函数
In-process Handler]
M --> MS[独立 MCP 服务器
Out-of-process Server]
SM --> Output[统一 JSON 契约
Canonical Output]
PH --> Output
MS --> Output| 路线 | 规则由谁执行 | 运行位置 | 是否新增模型工具 |
|---|---|---|---|
| 技能(Skill) | 大模型依据 SKILL.md | 模型当前上下文 | 否;只使用 skill_view 展开说明 |
| 插件(Plugin) | Python audit_markdown_text | Hermes 进程内 | 是:audit_markdown |
| MCP 服务 | 同一 Python 核心函数 | 独立 FastMCP 子进程 | 是:mcp__markdown_audit__audit_markdown |
公共规则核心:让 Plugin 与 MCP 真正可对比
为了排除算法差异,Plugin 与 MCP 都复制同一份 audit_core.py。这段纯函数不知道 Hermes、PluginContext 或 MCP,只接收文本并返回 JSON 兼容字典;两种封装的区别只在注册和调用边界。
# 文件(File):audit_core.py
from __future__ import annotations
import re
HEADING_RE = re.compile(r"^(#{1,6})\s+(.+?)\s*$")
FENCE_RE = re.compile(r"^```([^`\s]*)\s*$")
LINK_RE = re.compile(r"(?<!!)\[([^\]]*)\]\(([^)]*)\)")
def finding(
severity: str,
rule: str,
message: str,
line: int,
) -> dict:
return {
"severity": severity,
"rule": rule,
"message": message,
"line": line,
}
def audit_markdown_text(
content: str,
max_issues: int = 50,
max_bytes: int = 65_536,
) -> dict:
"""按固定规则检查 Markdown,并返回稳定的 JSON 兼容字典。"""
if len(content.encode("utf-8")) > max_bytes:
raise ValueError(f"Markdown 超过 {max_bytes} 字节限制")
max_issues = max(1, min(int(max_issues), 50))
findings: list[dict] = []
headings: list[tuple[int, int, str]] = []
in_fence = False
for line_number, line in enumerate(content.splitlines(), start=1):
fence = FENCE_RE.match(line)
if fence:
if not in_fence and not fence.group(1):
findings.append(finding(
"warning",
"code-language",
"围栏代码块没有声明语言",
line_number,
))
in_fence = not in_fence
continue
# 围栏代码块(fenced code block)内部不参与标题和链接结构检查。
if in_fence:
continue
heading = HEADING_RE.match(line)
if heading:
headings.append((line_number, len(heading.group(1)), heading.group(2)))
for link in LINK_RE.finditer(line):
if not link.group(2).strip():
findings.append(finding(
"error",
"empty-link",
"链接目标为空",
line_number,
))
h1_lines = [line for line, level, _ in headings if level == 1]
if len(h1_lines) != 1:
findings.append(finding(
"error",
"h1-count",
f"一级标题数量应为 1,实际为 {len(h1_lines)}",
h1_lines[0] if h1_lines else 1,
))
previous_level = 0
for line_number, level, title in headings:
if previous_level and level > previous_level + 1:
findings.append(finding(
"warning",
"heading-jump",
f"标题层级从 H{previous_level} 跳到了 H{level}:{title}",
line_number,
))
previous_level = level
findings.sort(key=lambda item: (item["line"], item["rule"]))
errors = sum(item["severity"] == "error" for item in findings)
warnings = sum(item["severity"] == "warning" for item in findings)
return {
"ok": errors == 0,
"summary": {"errors": errors, "warnings": warnings},
"findings": findings[:max_issues],
"findings_truncated": len(findings) > max_issues,
}实现一:技能(Skill)——让模型执行规则
技能(Skill)不注册新的业务工具。Hermes 构建系统提示词(System Prompt)时扫描 SKILL.md 元数据头(Frontmatter),把名称和 description 放进紧凑索引;模型匹配到任务后调用 skill_view,完整规则作为工具结果(Tool Result)进入对话,随后由模型本身完成检查。
sequenceDiagram
participant I as 技能索引
Skill Index
participant U as 用户
User
participant L as 模型
Model
participant V as 技能查看工具
skill_view
U->>L: 同一 Markdown 输入
I-->>L: 名称与说明
name + description
L->>V: 加载技能
skill_view markdown-quality-review
V-->>L: 完整技能正文
SKILL.md Tool Result
L->>L: 模型按四条规则检查
L-->>U: 统一 JSON 输出这里的“发现”与“加载”是两步:文件扫描生成候选索引,skill_view 才展开正文。它不是向量检索,也没有 audit_markdown 处理函数(Handler)。
---
name: markdown-quality-review
description: 按固定规则检查 Markdown 的一级标题、标题跳级、代码块语言和空链接,并严格返回 JSON;只读,不修改原文。
version: 1.0.0
author: 你的名字
license: MIT
platforms: [linux, macos, windows]
metadata:
hermes:
tags: [Markdown, 审校, 文档]
---
# Markdown 规范检查(Markdown Quality Review)
## 适用场景(When to Use)
当用户提供 Markdown 正文并要求检查格式规范时使用。
## 输入约定(Input Contract)
- `content`:待检查的 Markdown,最多 65536 字节。
- `max_issues`:最多返回的问题数,范围 1~50,默认 50。
## 检查规则(Rules)
1. 文档必须且只能有一个 H1。
2. 标题不能从 Hn 直接跳到 H(n+2) 或更深。
3. 三反引号围栏代码块必须在起始行声明语言。
4. 普通 Markdown 链接的目标不能为空;图片不按本规则处理。
5. 围栏代码块内部不参与标题和链接结构检查。
## 执行步骤(Procedure)
1. 从 1 开始计算行号。
2. 按原文顺序扫描,但最终按行号和 rule 排序。
3. `empty-link` 与 `h1-count` 是 error;其余两项是 warning。
4. 统计全部问题后,再按 `max_issues` 截断 findings。
5. 只返回输出约定中的 JSON,不添加 Markdown 围栏或解释文字。
## 输出约定(Output Contract)
返回 `ok`、`summary.errors`、`summary.warnings`、`findings` 和
`findings_truncated`。每个 finding 包含 `severity`、`rule`、`message`、`line`。
## 安全边界(Guardrails)
- 不修改、发布或上传原文。
- 不访问网络。
- 不把无法确认的问题提升为 error。技能(Skill)完整对话轨迹
[会话前相关上下文 / Relevant Context]
系统提示词的技能索引(Skill Index):
markdown-quality-review — 按固定规则检查 Markdown,并严格返回 JSON;只读。
相关工具(Relevant Tool):skill_view
[用户 / User]
请检查下面的 Markdown,最多返回 50 个问题。
严格返回 JSON,不要修改原文。
# 部署指南
### 安装
```
pip install demo
```
访问[项目主页]()了解更多。
[模型 → 工具调用 / Model → Tool Call]
name: skill_view
arguments: {"name":"markdown-quality-review"}
[工具返回 / Tool Result]
完整 SKILL.md:输入约定、四条规则、行号算法、排序方式和 JSON 输出契约。
[模型内部执行位置 / Execution Location]
规则由大模型在下一次推理中执行;没有 audit_markdown 工具调用。
[模型输出 / Model Output]
与本文“统一输出”中的 JSON 相同。优点是实现最短、适合带语义判断的规则;代价是检查和 JSON 都由模型生成,无法像代码一样保证逐字确定。
实现二:插件(Plugin)——在 Hermes 进程内执行规则
Plugin 是被 Hermes 导入的 Python 扩展。Bundled 表示随 Hermes 分发的第一方 Plugin;此外还有 User、Project 和 pip Entry Point 来源。无论来自哪里,目录型 Plugin 都通过 plugin.yaml 声明,通过 register(ctx) 注册。
| 概念 | 在本例中的含义 |
|---|---|
| 清单(Manifest) | plugin.yaml;声明身份、版本、配置和 provides_tools |
| 插件上下文(ctx / PluginContext) | Hermes 创建的受控宿主门面;不是模型上下文,也不是完整 AIAgent |
| 工具模式(Schema) | 模型看到的名称、中文 description 与 JSON 参数契约 |
| 处理函数(Handler) | 真正调用 audit_markdown_text 的 Python 函数 |
| 作用域注册表(Scoped Registry) | 按当前配置档案(Profile)保存工具注册,避免不同运行环境相互污染 |
| 所有权台账(Ownership Ledger) | 记录工具属于哪个 Plugin,卸载时按逆序 dispose |
sequenceDiagram
participant PM as 插件管理器
Plugin Manager
participant PY as 插件 Python 模块
Plugin Python Module
participant C as 插件上下文
PluginContext ctx
participant R as 作用域工具注册表
Scoped Tool Registry
participant U as 用户
User
participant L as 模型
Model
participant E as 工具执行器
Tool Executor
PM->>PY: 命名空间导入
Namespaced Import
PM->>C: 创建插件上下文
Create PluginContext
PM->>PY: 调用注册入口
register ctx
PY->>C: 注册工具
ctx.register_tool
C->>R: 注册模式与处理函数
Schema + Handler
U->>L: 同一 Markdown 输入
L->>E: 工具调用参数
audit_markdown arguments
E->>R: 按名称分派
Registry Dispatch
R->>PY: 处理函数参数
handler args kwargs
PY-->>E: 确定性工具结果
JSON Tool Result
E-->>L: 工具消息
Tool Message
L-->>U: 原样返回统一 JSONmarkdown-audit/
├── plugin.yaml
├── __init__.py
├── schema.py
└── audit_core.pyname: markdown-audit
version: 1.0.0
manifest_version: 2
api_version: 1
description: 在 Hermes 进程内确定性检查 Markdown 规范,并返回统一 JSON 结果
license: MIT
tags: [markdown, 文档, 审计]
provides_tools:
- audit_markdown
config_schema:
max_content_bytes:
type: int
default: 65536
description: 单次调用允许检查的 Markdown 最大字节数# 文件(File):schema.py
AUDIT_MARKDOWN_SCHEMA = {
"name": "audit_markdown",
"description": (
"按固定规则检查 Markdown 的 H1 数量、标题跳级、围栏代码语言和空链接。"
"输入只读;严格返回统一 JSON 结果。"
),
"parameters": {
"type": "object",
"properties": {
"content": {
"type": "string",
"description": "待检查的 Markdown 正文",
},
"max_issues": {
"type": "integer",
"minimum": 1,
"maximum": 50,
"default": 50,
"description": "最多返回的问题数量",
},
},
"required": ["content"],
},
}# 文件(File):__init__.py
import json
from .audit_core import audit_markdown_text
from .schema import AUDIT_MARKDOWN_SCHEMA
def register(ctx):
"""通过插件上下文(PluginContext)注册进程内工具。"""
max_bytes = int(ctx.get_config("max_content_bytes", 65_536))
def handler(args: dict, **kwargs) -> str:
del kwargs
result = audit_markdown_text(
content=str(args.get("content") or ""),
max_issues=int(args.get("max_issues") or 50),
max_bytes=max_bytes,
)
return json.dumps(result, ensure_ascii=False)
ctx.register_tool(
name="audit_markdown",
toolset="markdown_audit",
schema=AUDIT_MARKDOWN_SCHEMA,
handler=handler,
)插件(Plugin)完整对话轨迹
[会话前相关上下文 / Relevant Context]
已启用插件(Enabled Plugin):markdown-audit
模型可见工具(Model-visible Tool):audit_markdown
执行位置(Execution Location):Hermes Python 进程内
[用户 / User]
请检查下面的 Markdown,最多返回 50 个问题。
严格返回 JSON,不要修改原文。
# 部署指南
### 安装
```
pip install demo
```
访问[项目主页]()了解更多。
[模型 → 工具调用 / Model → Tool Call]
name: audit_markdown
arguments: {
"content":"# 部署指南
### 安装
```
pip install demo
```
访问[项目主页]()了解更多。",
"max_issues":50
}
[可观察运行路径 / Observable Runtime Path]
工具执行器(Tool Executor)
→ 参数与作用域检查(Arguments / Scope)
→ 作用域注册表(Scoped Registry)按名称分派
→ 插件处理函数(Plugin Handler)
→ 公共规则核心(audit_markdown_text)
[工具返回 / Tool Result]
与本文“统一输出”中的 JSON 完全一致。
[模型输出 / Model Output]
严格模式下原样返回工具结果(Tool Result)。Plugin 路线调用开销小、结果确定,但模块一旦导入就是当前 Hermes Python 进程中的可信代码。Capability Consent 是高权限宿主 API 的授权门槛,不等于操作系统 Sandbox。
实现三:MCP 服务——在独立进程中执行同一规则
MCP 方案不把 server.py 导入 Hermes。Hermes 是宿主(Host),内部 MCP 客户端(MCP Client)通过标准输入输出(stdio)启动并连接 FastMCP 服务器(FastMCP Server);连接建立时先完成初始化(initialize)和工具发现(tools/list),用户回合真正调用时才发送工具调用(tools/call)。
| 概念 | 在本例中的含义 |
|---|---|
| 宿主(Host) | Hermes Agent;承载模型、选择工具并保存工具结果(Tool Result) |
| MCP 客户端(MCP Client) | Hermes 内部连接层;负责初始化、发现与调用 |
| MCP 服务器(MCP Server) | 独立 server.py 子进程;持有工具实现 |
| 标准输入输出传输(stdio Transport) | 客户端(Client)与 Python 子进程之间的标准输入输出通道,不是函数直接导入 |
| 工具发现(tools/list) | 连接发现阶段取得工具 Schema,通常不是每个用户回合都调用 |
| 工具调用(tools/call) | 用户回合中传递 content 与 max_issues 的 MCP 方法 |
| 限定工具名 | Hermes 注册为 mcp__markdown_audit__audit_markdown,明确服务器(Server)与工具(Tool)边界 |
一个 MCP 工具怎样从配置进入模型工具集
这里还需要区分“配置了 Server”和“模型已经能调用 Tool”。Hermes 的 discover_mcp_tools() 先读取启用的 mcp_servers,连接 Server 并保存 initialize 返回的能力;只有 Server 声明了工具能力,才继续通过 tools/list 取得名称、说明和输入 Schema。
| 阶段 | Hermes 做什么 | 此时模型能否调用 |
|---|---|---|
| 已配置(Configured) | 在 mcp_servers 中找到启用的 Server | 不能;只有连接参数 |
| 已连接(Connected) | 建立 stdio 或 HTTP 传输并完成 initialize | 通常还不能;需要发现工具 |
| 已发现(Discovered) | 调用可分页的 tools/list,取得工具说明和 inputSchema | 还要经过过滤与注册 |
| 已注册(Registered) | 应用 tools.include / tools.exclude,转换 Schema,并以 mcp__server__tool 写入作用域工具注册表 | 新建 Agent 可以从 Registry 取得它 |
| 模型可见(Model-visible) | 把最新 Registry 结果合并进当前 agent.tools 工具快照 | 可以在下一次安全的模型回合调用 |
注册时如果 MCP 工具与核心工具或其他 Server 发生名称冲突,Hermes 会保留既有所有者并跳过冲突项,而不是静默覆盖。/reload-mcp 会重新发现并刷新 Agent 工具快照;支持动态发现的 Server 也可以发送 notifications/tools/list_changed,触发异步更新。启用 lazy: true 且 Schema Cache 有效时,Hermes 可以先从缓存注册工具,第一次真实调用时再启动 Server。
sequenceDiagram
participant H as Hermes 宿主
Hermes Host
participant C as MCP 客户端
MCP Client
participant S as FastMCP 服务器
FastMCP Server
participant U as 用户
User
participant L as 模型
Model
H->>C: 启动配置
command args env
C->>S: 标准输入输出初始化
stdio initialize
C->>S: 发现工具
tools/list
S-->>C: 工具模式
audit_markdown Schema
C-->>H: 注册 mcp__markdown_audit__audit_markdown
U->>L: 同一 Markdown 输入
L->>C: MCP 工具调用
MCP Tool Call
C->>S: 标准输入输出工具调用
stdio tools/call arguments
S->>S: 执行公共规则核心
audit_markdown_text
S-->>C: MCP 工具结果
MCP Tool Result
C-->>L: Hermes 工具结果
Hermes Tool Result
L-->>U: 原样返回统一 JSONmarkdown-audit-mcp/
├── server.py
└── audit_core.py# 文件(File):server.py
from fastmcp import FastMCP
from audit_core import audit_markdown_text
mcp = FastMCP("Markdown 规范检查")
@mcp.tool
def audit_markdown(content: str, max_issues: int = 50) -> dict:
"""按固定规则检查 Markdown;只读,并返回统一 JSON 结果。"""
return audit_markdown_text(
content=content,
max_issues=max_issues,
max_bytes=65_536,
)
if __name__ == "__main__":
mcp.run()mcp_servers:
markdown_audit:
command: "python"
args: ["/absolute/path/markdown-audit-mcp/server.py"]
tools:
include: [audit_markdown]
prompts: false
resources: falseMCP 服务完整对话轨迹
[连接发现阶段 / Connection and Discovery]
Hermes 读取 mcp_servers.markdown_audit
→ 启动 python server.py
→ 建立标准输入输出传输(stdio Transport)
→ MCP 初始化(initialize)
→ 工具发现(tools/list)
→ 注册 mcp__markdown_audit__audit_markdown
[用户 / User]
请检查下面的 Markdown,最多返回 50 个问题。
严格返回 JSON,不要修改原文。
# 部署指南
### 安装
```
pip install demo
```
访问[项目主页]()了解更多。
[模型 → 工具调用 / Model → Tool Call]
name: mcp__markdown_audit__audit_markdown
arguments: {
"content":"# 部署指南
### 安装
```
pip install demo
```
访问[项目主页]()了解更多。",
"max_issues":50
}
[可观察运行路径 / Observable Runtime Path]
工具执行器(Tool Executor)
→ Hermes MCP 适配器 / 客户端(Adapter / Client)
→ 标准输入输出工具调用(stdio: tools/call)
→ FastMCP 服务器(FastMCP Server)
→ 公共规则核心(audit_markdown_text)
→ MCP 工具结果(MCP Tool Result)
→ Hermes 工具结果(Hermes Tool Result)
[工具返回 / Tool Result]
与本文“统一输出”中的 JSON 完全一致。
[模型输出 / Model Output]
严格模式下原样返回工具结果(Tool Result)。进程边界带来依赖隔离和跨宿主(Host)复用,但不自动等于安全沙箱;子进程仍继承配置允许传入的环境和操作系统权限。MCP 还多出进程启动、协议序列化与连接管理成本。
最终对比:输入输出一样,中间运行过程不同
| 对比项 | Skill | Plugin | MCP |
|---|---|---|---|
| 用户输入 | 相同 Markdown | 相同 Markdown | 相同 Markdown |
| 目标输出 | 同一 JSON 契约 | 同一 JSON 契约 | 同一 JSON 契约 |
| 发现方式 | 系统提示词(System Prompt)技能索引 | 插件发现(Plugin Discovery)+ 清单(Manifest) | 初始化(initialize)+ 工具发现(tools/list) |
| 按需入口 | skill_view | 模型调用 audit_markdown | 模型调用带前缀 MCP 工具 |
| 执行规则的位置 | 大模型推理 | Hermes 进程内处理函数(Handler) | 独立 MCP 服务器(MCP Server) |
| 中间协议 | Hermes 工具结果(Tool Result) | 注册表分派(Registry Dispatch) | 通过 stdio 执行 MCP 工具调用(tools/call) |
| 确定性 | 较低;目标一致但不保证逐字相同 | 高;代码确定 | 高;同一代码确定 |
| 额外进程 | 无 | 无 | 有 |
| 依赖隔离 | 不适用 | 共享 Hermes Python 环境 | 可使用独立环境 |
| 复用范围 | Hermes Skill 用户 | 当前 Hermes Plugin 系统 | 任何兼容 MCP 的宿主(Host) |
| 主要风险 | 模型漏检或格式漂移 | 进程内可信代码权限 | 外部进程权限、配置与传输边界 |
| 最适合 | 方法、语义规则、低成本试验 | 高频、本地、确定性扩展 | 跨进程、跨语言、可复用服务 |
核心结论:Skill 把规则交给模型执行;Plugin 把规则放进 Hermes 进程;MCP 把规则放进独立服务。三者可以拥有相同输入输出,但不能因此忽略确定性、权限、进程和协议成本。
用同一契约做验证
Plugin 与 MCP 的 audit_core.py 使用下面同一个测试。Skill 则检查是否满足同一 JSON Schema 和 Findings 语义,而不能宣称字节级确定。
# 文件(File):test_contract.py
from audit_core import audit_markdown_text
SAMPLE = """# 部署指南
### 安装
```
pip install demo
```
访问[项目主页]()了解更多。"""
def test_unified_contract():
result = audit_markdown_text(SAMPLE, max_issues=50)
assert result == {
"ok": False,
"summary": {"errors": 1, "warnings": 2},
"findings": [
{
"severity": "warning",
"rule": "heading-jump",
"message": "标题层级从 H1 跳到了 H3:安装",
"line": 3,
},
{
"severity": "warning",
"rule": "code-language",
"message": "围栏代码块没有声明语言",
"line": 5,
},
{
"severity": "error",
"rule": "empty-link",
"message": "链接目标为空",
"line": 9,
},
],
"findings_truncated": False,
}# 公共规则单元测试(shared contract test)
python -m pytest -q test_contract.py
# Plugin 发现、导入与注册
hermes plugins doctor ~/.hermes/plugins/markdown-audit --ci
hermes plugins enable markdown-audit
# MCP 服务器工具模式(Server Schema)与直接调用
fastmcp inspect server.py:mcp
fastmcp call server.py audit_markdown content="# 标题" max_issues=50 --json怎样选择
| 先问的问题 | 选择 |
|---|---|
| 规则是否主要依赖语言理解,而且允许少量输出差异? | Skill |
| 是否需要高频、确定、低延迟,并愿意信任进程内 Python? | Plugin |
| 是否需要独立依赖、跨语言或被多个宿主(Host)复用? | MCP |
| 只是为了展示三种技术,是否应该同时安装? | 不应该;本文三条路线是替代方案,不是组合依赖 |
参考资料与源码入口
- 官方源码核验基线:59795c40
- Creating Skills
- Skill 索引与 Prompt 构建源码
- skills_list 与 skill_view 源码
- Plugin 开发指南
- 插件管理器(Plugin Manager)与插件上下文(PluginContext)源码
- Tool Registry 源码
- MCP 配置与运行时
- MCP 工具注册与命名源码
- FastMCP Skill
题图来源:《湖、小屋与码头》,创作者 FrankyFromGermany,来自 Pixabay;依据 Pixabay Content License(Pixabay 内容许可)使用。