Hermes 플러그인 만들기
기준일: 2026-07-26
난이도: 중급
공식 기준: Build a Hermes Plugin
개요
도구·훅·매니페스트·스킬 번들을 포함한 Hermes 플러그인 작성 튜토리얼입니다. (공식 canonical: developer-guide/plugins)
핵심 개념
| 구성 | 역할 |
|---|---|
| plugin.yaml | 매니페스트 |
| register_tool/hook | 컨텍스트 API |
| requires_env | 자격증명 게이트 |
| opt-in enable | 명시 활성화 |
상세
무엇을 만드는가
원문 절: What you're building
- calculator
1단계: 플러그인 디렉터리
원문 절: Step 1: Create the plugin directory
- 이 절의 절차·표·코드는 공식 원문을 기준으로 적용한다.
mkdir -p ~/.hermes/plugins/calculator
cd ~/.hermes/plugins/calculator
2단계: 매니페스트
원문 절: Step 2: Write the manifest
- 이 절의 절차·표·코드는 공식 원문을 기준으로 적용한다.
name: calculator
version: 1.0.0
description: Math calculator — evaluate expressions and convert units
provides_tools:
- calculate
- unit_convert
provides_hooks:
- post_tool_call
3단계: 도구 스키마
원문 절: Step 3: Write the tool schemas
- Why schemas matter:
4단계: 핸들러
원문 절: Step 4: Write the tool handlers
- Signature:
- Return:
- Never raise:
- Accept `
5단계: 등록
원문 절: Step 5: Write the registration
- What
register()does: dispatch_toolexample — a slash command that runs a tool:
def handle_scan(ctx, raw_args: str):
"""Implement /scan by invoking the terminal tool through the registry."""
result = ctx.dispatch_tool("terminal", {"command": f"find . -name '{raw_args}'"})
return result # returned to the caller's chat UI
def register(ctx):
# Handlers receive a single raw_args string; close over ctx via a lambda.
ctx.register_command(
"scan",
lambda raw: handle_scan(ctx, raw),
description="Find files matching a glob",
)
6단계: 테스트
원문 절: Step 6: Test it
- Debugging plugin discovery — 공식 하위 절. 구현·설정 세부 원문 참조.
- Not enabled in config
- Wrong directory layout
- Missing
__init__.py - Wrong
kind
hermes
최종 구조
원문 절: Your plugin's final structure
- Manifest
- Schemas
- Handlers
- Registration
~/.hermes/plugins/calculator/
├── plugin.yaml # "I'm calculator, I provide tools and hooks"
├── __init__.py # Wiring: schemas → handlers, register hooks
├── schemas.py # What the LLM reads (descriptions + parameter specs)
└── tools.py # What runs (calculate, unit_convert functions)
플러그인으로 더 할 수 있는 것
원문 절: What else can plugins do?
- Ship data files — 공식 하위 절. 구현·설정 세부 원문 참조.
- Bundle skills — 공식 하위 절. 구현·설정 세부 원문 참조.
- Gate on environment variables — 공식 하위 절. 구현·설정 세부 원문 참조.
- Lazy-install optional Python dependencies — 공식 하위 절. 구현·설정 세부 원문 참조.
- Thread-safe lazy singletons — 공식 하위 절. 구현·설정 세부 원문 참조.
- Conditional tool availability — 공식 하위 절. 구현·설정 세부 원문 참조.
| Field | Required | Description |
|---|---|---|
name |
Yes | Environment variable name |
description |
No | Shown to user during install prompt |
url |
No | Where to get the credential |
secret |
No | If true, input is hidden (like a password field) |
# In tools.py or __init__.py
from pathlib import Path
_PLUGIN_DIR = Path(__file__).parent
_DATA_FILE = _PLUGIN_DIR / "data" / "languages.yaml"
with open(_DATA_FILE) as f:
_DATA = yaml.safe_load(f)
Specialized plugin types
- Model provider plugins — add an LLM backend — 공식 하위 절. 구현·설정 세부 원문 참조.
- Platform plugins — add a gateway channel — 공식 하위 절. 구현·설정 세부 원문 참조.
- Memory provider plugins — add a cross-session knowledge backend — 공식 하위 절. 구현·설정 세부 원문 참조.
- Context engine plugins — replace the context compressor — 공식 하위 절. 구현·설정 세부 원문 참조.
- Image-generation backends — 공식 하위 절. 구현·설정 세부 원문 참조.
# plugins/model-providers/acme/__init__.py
from providers import register_provider
from providers.base import ProviderProfile
register_provider(ProviderProfile(
name="acme",
aliases=("acme-inference",),
display_name="Acme Inference",
env_vars=("ACME_API_KEY", "ACME_BASE_URL"),
base_url="https://api.acme.example.com/v1",
auth_type="api_key",
default_aux_model="acme-small-fast",
fallback_models=("acme-large-v3", "acme-medium-v3"),
))
Non-Python extension surfaces
- MCP servers — register external tools — 공식 하위 절. 구현·설정 세부 원문 참조.
- Gateway event hooks — fire on lifecycle events — 공식 하위 절. 구현·설정 세부 원문 참조.
- Shell hooks — run a shell command on tool calls — 공식 하위 절. 구현·설정 세부 원문 참조.
- Skill sources — add a custom skill registry — 공식 하위 절. 구현·설정 세부 원문 참조.
- TTS / STT via command templates — 공식 하위 절. 구현·설정 세부 원문 참조.
mcp_servers:
filesystem:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
timeout: 120
linear:
url: "https://mcp.linear.app/sse"
auth:
type: "oauth"
Distribute via pip
- 이 절의 절차·표·코드는 공식 원문을 기준으로 적용한다.
# pyproject.toml
[project.entry-points."hermes_agent.plugins"]
my-plugin = "my_plugin_package"
Distribute for NixOS
- Entry-point plugins
- Directory plugins
# User's configuration.nix
services.hermes-agent.extraPythonPackages = [
(pkgs.python312Packages.buildPythonPackage {
pname = "my-plugin";
version = "1.0.0";
src = pkgs.fetchFromGitHub {
owner = "you";
repo = "hermes-my-plugin";
rev = "v1.0.0";
hash = "sha256-..."; # nix-prefetch-url --unpack
};
format = "pyproject";
build-system = [ pkgs.python312Packages.setuptools ];
})
];
Common mistakes
- Handler doesn't return JSON string:
- **kwargs): return json.dumps({"result": 42})
**
- **kwargs` in handler signature:**
- **kwargs):
...
**
- Schema description too vague:
# Wrong — returns a dict
def handler(args, **kwargs):
return {"result": 42}
# Right — returns a JSON string
def handler(args, **kwargs):
return json.dumps({"result": 42})
체크리스트
- 공식 원문 Build a Hermes Plugin과 대조했다
- 관련 코드·설정·권한을 로컬에서 확인했다
- 보안·opt-in·allowlist 정책을 지켰다
- 스모크 테스트 또는 단계 검증을 수행했다
다음 단계
기준일: 2026-07-26 — 공식 문서 동기화 코퍼스