fix(mobile): wire plugin catalog and session-scoped subagent controls

This commit is contained in:
yilsem committed 2026-10-07 22:37:49 +03:00
1 parent 61d765e2df
commit 1acb5dd90f
27 files changed
+1573 -17

No files matched your search

+194
View File
@@ -0,0 +1,194 @@
# Hermes Plugin Catalog
Curated, Nous-approved Hermes plugins. Each YAML file in this directory
(except `removed.yaml`) is one catalog entry, discoverable via
`hermes plugins catalog` / `hermes plugins search` and installable with
`hermes plugins install <name>`.
## Admission policy
Presence in this directory **is** the trust signal. The rules that keep it
meaningful:
<!-- admission-rules:start (mirrored in website/docs/developer-guide/plugins/catalog-submission.md; tests/website/test_catalog_rules_mirror.py keeps them identical) -->
1. **Human-merged gate.** Entries are added *only* via a PR to the
`hermes-agent` repository, reviewed and merged by a maintainer. There is
no self-serve registry, no automated ingestion.
2. **Exact SHA pins are mandatory.** Every entry pins a full 40-character
commit SHA. Branches, tags, and short SHAs are rejected by the loader.
Installs clone the repository and check out exactly that commit.
3. **No self-updating code.** A listed plugin must not fetch and replace
its own files (in-app "check for updates", signed release downloaders,
remote `plugin.js` loaders). The exact SHA pin *is* the trust model; a
self-updater lets an installed copy move to a commit nobody reviewed.
Updates reach users only through a SHA-bump PR here plus
`hermes plugins update <name>`. Keep the updater in the standalone
distribution if you want one; strip it from the catalog build.
4. **SHA bumps are new PRs.** Updating an entry's pin is a new PR whose diff
(old SHA → new SHA) is re-reviewed like any other change — reviewers are
expected to look at the upstream commit range being adopted.
5. **Owner-or-major-contributor submissions, or a maintainer-curated sweep.**
An entry may be submitted by the plugin repository's owner or a major
contributor to it; drive-by submissions of third-party repos are declined.
Hermes maintainers may also add entries in batches from a reviewed sweep
of community plugins (every pin validated and scanned at the pinned
commit, self-updater and credential-store checks run, English-first UI).
Authors of swept-in entries keep control: a PR from the owner adjusting
or removing their entry is accepted on request, and SHA bumps stay
owner-or-maintainer PRs under rule 4.
6. **Declared capabilities must match reality.** The `capabilities:` block
(tools, hooks, middleware, env vars) must match what the plugin actually
registers at the pinned commit. Validation fails the entry otherwise —
undeclared capability creep is treated as a security issue.
7. **The install scanner runs at admission.** `hermes plugins validate` includes
the `security scan` check: `dangerous` fails the entry; `caution` findings
appear as warnings in the CI log and the reviewer reads them before merging.
In exchange, installs at the pinned SHA accept `caution` without a prompt
(`dangerous` still blocks). Review the warnings; do not merge past them.
8. **Desktop plugins stay inside the SDK surface.** A `desktop/plugin.js` runs
in the Desktop renderer with the app's full authority (the loader isolates
errors, not capabilities), so a listed one may only use the plugin SDK:
no prototype patching (`X.prototype.y =`, `Object.defineProperty(...prototype`),
no `eval`/`new Function`, no `import()` of anything but `@hermes/plugin-sdk`
/ `react` (app bundle chunks, blob or http URLs included), no script-tag
injection, no reaching into the app's internal stores or its own markup
(querying `data-slot` / `data-tour` / `data-sidebar` / `data-testid`
elements from `document`, or a `document.body` MutationObserver, to restyle,
hide, click or rewrite core UI). `hermes plugins validate` refuses these at
admission (`desktop surface` check); a plugin that needs a capability the
SDK lacks asks for an SDK hook instead of patching around it.
9. **No runtime overrides of Hermes core.** A listed plugin extends Hermes only
through public surfaces: hooks, middleware, provider profiles and the
other `register_*` APIs, and Desktop SDK slots and routes. It must not
replace, wrap or rebind core functions, methods, module attributes or
private dicts in place (`AIAgent.<method> = ...`, `setattr(server, ...)`,
`sys.modules[...]`, writes into a core module's tables). Two plugins
patching the same seam silently break each other, and every core release
can break both. `hermes plugins validate` refuses these at admission (`no
core override` check). If the hook you need does not exist, open an issue
describing it: we would rather add the seam than list a patch.
10. **Dependency security policy is the plugin's.** Hermes's 14-day
`exclude-newer` quarantine covers Hermes's own dependencies only; a plugin's
`python_dependencies` / `pyproject.toml` install under the plugin's policy
(no quarantine, still inside Hermes's core constraints). Reviewers read the
dependency list at the pinned SHA: bare floors (`>=X` with no upper bound)
and floors on the newest release get a request for the oldest
API-compatible floor plus an upper bound, and authors are strongly
recommended to run their own release quarantine (`uv --exclude-newer` in
their CI) — see the developer guide's *Dependency security policy*. A
recent floor alone is not grounds to hold an entry.
11. **Credentials stay with their owner.** A plugin reads the credentials it is
configured with: the env vars in `requires_env` and its own `config_schema`
secrets. Reading another tool's login (a vendor CLI's token file, a browser
profile) must be disclosed in the PR and is a trust-tier call for a
maintainer. Refreshing, rotating or writing another client's OAuth tokens, or
presenting itself as another vendor's client, is not admitted without an
explicit maintainer ruling; a read-only build is the usual way through.
12. **Approvals and unattended runs are respected.** A plugin never routes around
Hermes's approval system: no auto-approving, no disabling guards, and no
spawning Hermes or shell children that inherit YOLO or non-interactive mode
to run commands nobody approved. Anything that waits for a person (a prompt,
an OAuth browser flow) fails cleanly or times out under cron, the messaging
gateway and other unattended runs instead of hanging the agent.
13. **Risky behaviour is disclosed.** What a user would want to know before
installing goes in the PR description and the plugin's README: network calls
to third-party services, reads outside the plugin's own data, shell commands,
long-running background processes, stored credentials. Telemetry and usage
reporting are opt-in. Reviewers summarise these as disclosure lines on the
entry PR; undisclosed behaviour found in review is a request for changes.
14. **Compatibility metadata is truthful.** `requires_hermes` is a SemVer floor
(`">=0.21.5"`), never a CalVer date, and never newer than the current release
(the loader skips the plugin otherwise). `version` matches the pinned code,
and Python dependencies resolve under Hermes's core constraints
(`hermes plugins validate --install-deps` is what CI runs).
15. **No skins or forks of bundled plugins.** A change to a bundled plugin is a
PR against `hermes-agent`, not a competing listing, and vendor-lookalike skins
are not listed under Nous branding.
16. **One listing per plugin lineage.** A fork of a listed community plugin is
listed only when it is materially different from the original: a different
transport or architecture, or capability the original lacks and its author
declined or has not answered a PR for 30 days. Improvements to a listed plugin
go upstream as a PR to its author. A fork that renames, rebrands or adds small
changes is declined in favour of the original. A listed fork names its origin
in its disclosure line (`Derived from <entry>`).
<!-- admission-rules:end -->
The step-by-step submission guide, with the same rules and what reviewers check,
lives at
[Submitting to the plugin catalog](https://hermes-agent.nousresearch.com/docs/developer-guide/plugins/catalog-submission).
## Entry schema
```yaml
name: example-plugin # [a-z0-9_-]{1,64}, the catalog key
repo: https://github.com/owner/repo # https:// only
sha: <40-hex commit sha> # mandatory exact pin
subdir: "" # optional; plain relative path inside the repo
# ([A-Za-z0-9._/-]+ only: no '..', '.', empty
# segments, absolute, or backslash forms)
description: One-line description.
maintainer: OwnerName
tier: official # official | community (default community)
category: memory # desktop | memory | platform | web | tools | voice | automation | models | general
# (default desktop) — the shelf the entry sits on at /docs/plugins
requires_hermes: ">=0.19" # optional
docs_url: "" # optional
version: "1.4.0" # optional human label for the sha (quote it); shown as "1.4.0 @ abcd1234"
image: "" # optional https image on a GitHub host, 2:1 (e.g. 1200x600), e.g.
# https://raw.githubusercontent.com/owner/repo/<sha>/docs/banner.png
screenshots: [] # optional, up to 6 https images on a GitHub host; gallery on /docs/plugins/<name>
readme: true # optional, default true; the README at the PINNED SHA renders on /docs/plugins/<name>
platforms: [] # optional, e.g. [linux, macos]; empty = all
title: "" # optional human name on cards ("NVIDIA App"); default = name
onboarding: false # optional; offered on the Desktop onboarding card (official entries only)
known_issues: [] # optional strings shown at the install prompt; informational, never blocks
capabilities:
provides_tools: []
provides_hooks: []
provides_middleware: []
requires_env: []
```
`version`, `image`, `screenshots` and `readme` are cosmetic: none is parsed or
used to pick what installs. The sha stays the release; bump `version` in the
same PR that bumps `sha` so the label on the card matches the code. Images must
live on `raw.githubusercontent.com`, `github.com` or `*.githubusercontent.com`
so the Desktop catalog and the docs site never fetch from third-party hosts;
pin the raw URL to the entry's commit and the picture is as immutable as the
code.
Every entry gets a page at `https://hermes-agent.nousresearch.com/docs/plugins/<name>`
and every maintainer a page at `/docs/plugins/by/<maintainer>`, both generated
from these files at docs build time. `screenshots:` fills the page's gallery;
the build fetches the README (from `subdir` if set, else the repo root) **at the
pinned sha** — GitHub and GitLab repos, on by default, `readme: false` opts out — and renders it
through an allowlist (raw HTML dropped, links and images resolved against the
pinned tree). The page therefore shows the README the reviewer read, and it
changes only when a reviewed re-pin lands.
## removed.yaml — the blocklist
When an entry is pulled from the catalog for security or policy reasons, it
is recorded in `removed.yaml` with a reason and date. The installer refuses
to install anything matching a removed entry's name or repo URL, so a
malicious plugin cannot be re-installed from a stale identifier after
removal. A plugin that lands on the list after a user installed it stops
updating, cannot be enabled and is refused at load time. Removals, like
additions, land via reviewed PRs.
Delisting is different from removal: an entry that is unmaintained, superseded, squatting a
name it is not affiliated with, or no longer meets a rule is deleted from the catalog (plain
file removal, users who already installed it are unaffected). It is welcome back once the
problem is fixed; a name squatter comes back under a distinct name. When a new rule affects
entries that are already listed, their authors get an issue on their repository explaining
the change and time to update before anything is delisted.
## Names
The catalog key and the manifest `name:` are what users search, install, and — for memory
providers — put in `memory.provider`. A `memory` / `exclusive` entry must not reuse the name of
another provider or of a well-known upstream project it is not affiliated with: two providers
registering the same `register_memory_provider` name make `memory.provider` ambiguous
(whichever loads last wins). Reviewers check the registered provider name, not just the file
name, and the affiliated project gets the bare key.
+23
View File
@@ -0,0 +1,23 @@
name: blender
repo: https://github.com/NousResearch/hermes-plugin-blender
sha: d1929b593bddd2241a8939fb355e0a69b8e077af
version: "0.1.0"
description: >-
Official Blender Lab MCP server over stdio, pinned to upstream v1.0.3,
with a Blender workflow skill. Requires Blender 5.1+, its separately
installed MCP add-on, Git and uv. First startup downloads Python dependencies;
prepare the uv environment before connecting. Disclosure: tools execute
arbitrary Python in Blender with the user's privileges. No automatic
application/version/liveness gate; server discovery does not prove scene readiness.
title: Blender
maintainer: NousResearch
tier: official
category: tools
docs_url: https://github.com/NousResearch/hermes-plugin-blender#readme
platforms: [windows, macos, linux]
onboarding: true
capabilities:
provides_tools: []
provides_hooks: []
provides_middleware: []
requires_env: []
@@ -0,0 +1,22 @@
name: claude-subscription-directsdk
repo: https://github.com/NousResearch/hermes-plugin-claude-subscription-directsdk
sha: 31b591fd04737a7807183f3d7f3d389b19f94687
description: Experimental model provider that runs Hermes turns on a Claude Pro/Max subscription through
the official Claude Code CLI (the Agent SDK path), so no separate API key or per-token bill. Requires
the claude CLI installed and logged in; the plugin checks for it at load, in hermes model, in the pickers
and before every request, and refuses cleanly with the install hint when it is missing. Disclosure — every
turn is billed against your Claude subscription's Agent SDK allowance, and the provider inherits whatever
account claude is logged into.
maintainer: NousResearch
tier: official
category: models
requires_hermes: ">=0.21.4"
docs_url: https://github.com/NousResearch/hermes-plugin-claude-subscription-directsdk#readme
version: "0.3.2"
platforms: []
image: https://raw.githubusercontent.com/NousResearch/hermes-plugin-claude-subscription-directsdk/31b591fd04737a7807183f3d7f3d389b19f94687/assets/card.png
capabilities:
provides_tools: []
provides_hooks: []
provides_middleware: []
requires_env: []
+15
View File
@@ -0,0 +1,15 @@
name: hermes-memory-wiki
repo: https://github.com/NousResearch/hermes-memory-wiki
sha: 9bc3913b8474eaf4d7eec32e97af4d77957c36df
description: 'Memory Wiki dashboard tab: browsable subject pages and daily logs derived from local session
history, plus a read-only Persistent Memory (MEMORY.md / USER.md) audit panel.'
maintainer: NousResearch
tier: official
requires_hermes: ">=0.21"
docs_url: https://github.com/NousResearch/hermes-memory-wiki#readme
platforms: []
capabilities:
provides_tools: []
provides_hooks: []
provides_middleware: []
requires_env: []
@@ -0,0 +1,15 @@
name: hermes-telegram-business
repo: https://github.com/NousResearch/hermes-telegram-business
sha: e905f3bc5eeaa5a9dab9bc5155601b3ebec75757
description: 'Observe-with-approval Telegram Business Mode (secretary bot): every drafted customer reply
needs owner approval before it is sent.'
maintainer: NousResearch
tier: official
category: platform
docs_url: https://github.com/NousResearch/hermes-telegram-business
platforms: []
capabilities:
provides_tools: []
provides_hooks: []
provides_middleware: []
requires_env: []
+23
View File
@@ -0,0 +1,23 @@
name: homeassistant
repo: https://github.com/NousResearch/hermes-homeassistant
sha: ba30cb0cf86c52bdb5cde98974bc062e97966529
description: 'Home Assistant gateway platform (state-change events in, persistent notifications and cron notify
delivery out) plus the homeassistant toolset (ha_list_entities, ha_get_state, ha_list_services, ha_call_service).
Formerly built into Hermes core; existing users are migrated automatically.'
maintainer: NousResearch
tier: official
category: platform
requires_hermes: ">=0.21.5"
version: "2.0.1"
docs_url: https://github.com/NousResearch/hermes-homeassistant
platforms: []
capabilities:
provides_tools:
- ha_list_entities
- ha_get_state
- ha_list_services
- ha_call_service
provides_hooks: []
provides_middleware: []
requires_env:
- HASS_TOKEN
+24
View File
@@ -0,0 +1,24 @@
name: nvidia-app
repo: https://github.com/NousResearch/hermes-nvidia
sha: 65bb8d89263f920e8599432823d2d4e05cc113e3
subdir: nvidia-app
description: "NVIDIA App control through its local MCP server: overlay capture and state, driver status
and release notes, game optimization, and app launch. Requires NVIDIA App 11.0 or newer on Windows;
the install is refused when the app is absent, and the tools appear while the app's service is running.
The plugin reads the endpoint and token NVIDIA App publishes in its own McpServer server.json on every
connection, so a changed port or token needs no reconfiguration. Disclosure: the tools read and change
NVIDIA App settings on this machine; nothing leaves loopback."
title: NVIDIA App
maintainer: NousResearch
tier: official
category: tools
requires_hermes: ">=0.21.4"
docs_url: https://github.com/NousResearch/hermes-nvidia/tree/main/nvidia-app
version: "0.1.0"
platforms: [windows]
onboarding: true
capabilities:
provides_tools: []
provides_hooks: []
provides_middleware: []
requires_env: []
+24
View File
@@ -0,0 +1,24 @@
name: nvidia-broadcast
repo: https://github.com/NousResearch/hermes-nvidia
sha: 65bb8d89263f920e8599432823d2d4e05cc113e3
subdir: nvidia-broadcast
description: "NVIDIA Broadcast control through its local MCP gateway: camera, microphone and speaker
effects, Studio Voice profiles, device selection, camera resolution, and effects on local media files.
Requires NVIDIA Broadcast 2.3 or newer on Windows (2.2 and older have no gateway); the install is
refused when the app is absent, and the tools appear while NVIDIA Broadcast is running in the user's
desktop session. Disclosure: the tools change live audio and video effects on this machine; nothing
leaves loopback."
title: NVIDIA Broadcast
maintainer: NousResearch
tier: official
category: tools
requires_hermes: ">=0.21.4"
docs_url: https://github.com/NousResearch/hermes-nvidia/tree/main/nvidia-broadcast
version: "0.1.0"
platforms: [windows]
onboarding: true
capabilities:
provides_tools: []
provides_hooks: []
provides_middleware: []
requires_env: []
+12
View File
@@ -0,0 +1,12 @@
# Blocklist for plugins pulled from the catalog for security or policy
# reasons. The installer refuses to install anything whose name or repo URL
# matches an entry here (unless the caller explicitly bypasses the check).
# Each entry: {name, repo, reason, date}. Removals land via reviewed PRs,
# same as additions.
#
# Name only. Do not set repo: the replacement entry is the same repository,
# and a repo match would refuse that install too.
removed:
- name: or-picker
reason: "Folded into openrouter-picker. Installing the provider alone left the picker broken. Install openrouter-picker."
date: "2026-09-28"
+17
View File
@@ -0,0 +1,17 @@
name: snyk
repo: https://github.com/NousResearch/hermes-plugin-snyk
sha: 2a41a07f81e45125bf82a19af1b13396ace4b81f
description: 'Scan code (SAST), dependencies, container images, IaC and SBOMs with Snyk through its
first-party MCP server (pinned snyk@1.1306.0 over npx stdio, CLI analytics disabled), with the
snyk-security-scan workflow skill bundled. Portable Agent Plugins v1 package (mcp.json + skills/);
needs Node.js/npm on PATH and a free Snyk account (browser login via the snyk_auth tool).'
maintainer: NousResearch
tier: official
category: tools
docs_url: https://github.com/NousResearch/hermes-plugin-snyk
platforms: []
capabilities:
provides_tools: []
provides_hooks: []
provides_middleware: []
requires_env: []
+16
View File
@@ -0,0 +1,16 @@
name: touchdesigner
repo: https://github.com/NousResearch/hermes-plugin-touchdesigner
sha: 88a7a7884e5eda33cfe4b1dd5e69df7cb15d5898
description: 'Drive a live TouchDesigner session through the twozero MCP server (Streamable HTTP on
127.0.0.1:40404), with the touchdesigner-mcp workflow skill bundled. Portable Agent Plugins v1 package
(mcp.json + skills/); TouchDesigner itself runs on macOS/Windows.'
maintainer: NousResearch
tier: official
category: tools
docs_url: https://github.com/NousResearch/hermes-plugin-touchdesigner
platforms: []
capabilities:
provides_tools: []
provides_hooks: []
provides_middleware: []
requires_env: []