Extensibility Guide
Hermes Agent Plugins: Install, Enable, and Configure
Plugins are how Hermes Agent gains executable capabilities it did not ship with: new tools, lifecycle hooks, slash commands, memory providers, and model providers. This guide covers the CLI, the exact config keys, the capability model, and how the OpenClaw plugin system differs.
Plugins, skills, and MCP are three different things
The three extension systems get conflated constantly, and choosing the wrong one is the usual reason an integration goes nowhere.
| System | What it is | Reach for it when |
|---|---|---|
| Skill | Markdown procedural knowledge in ~/.hermes/skills/ | The agent needs to know how to do something it can already do |
| MCP server | An external server the agent connects to, under mcp_servers | A tool already exists as an MCP server |
| Plugin | Executable code with a register(ctx) entry point | You need a new tool, hook, command, or provider inside the agent process |
A plugin is the only one of the three that runs inside the agent process and can register a lifecycle hook. It is also the only one that can ship all three: a plugin may call ctx.register_skill() and read from an MCP server via ctx.call_mcp().
The four plugin types
Hermes discovers four categories, and they differ in how many can be active at once:
- General plugins — tools, hooks, slash commands, and CLI commands. Multi-select through
plugins.enabled. - Memory providers — single-select, chosen with
memory.provider. - Context engines — single-select, chosen with
context.engine. - Model providers — multi-register, adding new model backends.
Memory and context are single-select because only one can own the behaviour. Enabling a second memory provider does not layer them; it replaces the choice.
Where Hermes looks for plugins
| Source | Path | Note |
|---|---|---|
| Bundled | <repo>/plugins/ | Ships with Hermes |
| User | ~/.hermes/plugins/ | Personal installs, survives upgrades |
| Project | .hermes/plugins/ | Requires HERMES_ENABLE_PROJECT_PLUGINS=true |
| pip | hermes_agent.plugins entry points | Distributed Python packages |
Project plugins are gated behind an environment variable on purpose. Cloning a repository should not silently grant its .hermes/plugins/ directory the right to execute in your agent.
Install and enable
hermes plugins # interactive browser
hermes plugins list # table of discovered plugins
hermes plugins search <term> # search the catalog
hermes plugins install <name> # from the catalog
hermes plugins install user/repo # from Git
hermes plugins install user/repo --enable
hermes plugins install user/repo --ref <40-char-SHA> # pinned
hermes plugins enable <name>
hermes plugins disable <name>
hermes plugins capabilities [name] # review what it was granted
hermes plugins update <name>
hermes plugins remove <name>There are three distinct states, and the middle one surprises people: enabled (listed in plugins.enabled, loads automatically), disabled (listed in plugins.disabled, will not load even if something tries to enable it), and not enabled — discovered but never opted into, which is the default for every newly installed plugin. Installing is not enabling.
The config keys
Plugin state lives in ~/.hermes/config.yaml. Edit it with hermes config edit rather than by hand if the gateway is running.
plugins:
enabled:
- my-plugin
disabled:
- noisy-plugin
scan_on_install: false # optional; default true
hook_callback_timeout: 30 # seconds
entries:
my-plugin:
allow_gateway_injection: true
mcp_allowlist: ["server1", "server2"]
granted_capabilities: [...]plugins.disabled wins over plugins.enabled. That precedence is useful operationally: to take a misbehaving plugin out of service without losing its configuration, add it to disabled rather than deleting it from enabled.
hook_callback_timeout matters more than it looks. A hook runs inside the agent turn, so a plugin that blocks on a slow network call delays every message until this timeout fires.
Capability grants are the security boundary
A plugin is code you chose to run in the same process as your agent and its credentials. Two entry keys are worth reading before enabling anything from a third party:
allow_gateway_injection— lets the plugin callctx.inject_message(), pushing content into a session as if it came from the user. That is a genuine prompt-injection surface, so grant it only to plugins you control.mcp_allowlist— restricts which MCP servers the plugin may reach throughctx.call_mcp(). An empty or absent allowlist is not a tightening.
Run hermes plugins capabilities <name> before enabling, and pin Git installs with --ref so a later upstream commit cannot change what executes. The same reasoning applies to OpenClaw security advisories: extension code is the part of an agent most likely to be attacker-supplied.
What a plugin can register
Inside register(ctx), the plugin context exposes the extension points. The commonly used ones:
ctx.register_tool(name=..., toolset=..., schema=..., handler=...)
ctx.register_hook("post_tool_call", callback)
ctx.register_command(name, handler, description)
ctx.register_cli_command(name, help, setup_fn, handler_fn)
ctx.register_skill(name, path)
ctx.register_platform(name, label, adapter_factory, check_fn, ...)
ctx.register_context_engine(engine)
ctx.call_mcp(server, tool, arguments, timeout=30)
ctx.inject_message(content, role="user", session_key=...)register_platform is the one worth knowing about: a plugin can add an entire messaging surface, which is how Hermes reaches platforms that are not bundled.
The OpenClaw plugin system, for comparison
Both frameworks have plugins, but they share no code and no format. If you run both, keep them straight:
| Hermes Agent | OpenClaw | |
|---|---|---|
| Config file | ~/.hermes/config.yaml | openclaw.json |
| Enable key | plugins.enabled list | plugins.entries.<id>.enabled |
| Install | hermes plugins install | openclaw plugins install |
| Sources | Catalog, Git, pip entry points | clawhub:, npm:, git:, local path |
| Manifest | Python register(ctx) entry point | openclaw.plugin.json with a JSON Schema |
| Pinning | --ref <SHA> | --pin for npm specs |
One OpenClaw detail catches people out: if your plugins section is backed by a single-file $include, the install, update, enable, disable, and uninstall commands write through to the included file that owns the change and leave openclaw.json untouched. Looking only at openclaw.json will then show no change at all.
A note on pre-installing plugins
If you are building images or templates, resist pre-installing npm-backed channel plugins into a base image. We run this fleet, and the failure mode is consistent: intermittent install failures and stale staging directories produce agents that look provisioned and are not. On-demand installation at connect time costs a little latency and is far more reliable.
OpenClaw Launch manages the Hermes Agent runtime itself. Plugins you install remain yours to review, pin, and update.
Hermes Agent plugins FAQ
Are plugins the same thing as skills in Hermes Agent?
No. A skill is procedural knowledge written in Markdown that the agent reads and can author itself. A plugin is executable code that registers new tools, hooks, slash commands, or CLI commands through a register(ctx) entry point. A plugin can ship a skill with ctx.register_skill(), but the two systems are separate. See Hermes Agent skills.
How do I install a Hermes Agent plugin?
Use hermes plugins install <name> for a catalog entry, or hermes plugins install user/repo to install from Git. Installing does not enable it: add --enable, or run hermes plugins enable <name> afterwards.
Does OpenClaw have plugins too?
Yes, and they are a different system. OpenClaw installs with openclaw plugins install from ClawHub, npm, or git, and stores state under plugins.entries.<id> in openclaw.json. Each native OpenClaw plugin ships an openclaw.plugin.json manifest. A Hermes plugin will not load in OpenClaw and vice versa.
Can I pin a plugin to a specific version?
Yes. hermes plugins install user/repo --ref <40-char-SHA> pins a Git install to an exact commit. Pinning is the safer default for anything running unattended, because it stops an upstream push from changing what your agent executes.
Do plugins work on managed hosting?
On managed Hermes Agent hosting the agent runs in its own container with a persistent ~/.hermes, so the same hermes plugins commands apply from the terminal. Treat a third-party plugin as code you are choosing to run: review its capability grants first.