Last updated: 2026-09-27

MCP in Hermes — Add, Filter & Secure MCP Servers

MCP (Model Context Protocol) lets Hermes use tools from outside servers, such as GitHub, Linear, Stripe, a database or your own scripts, without anyone writing a native Hermes tool first. MCP support ships with every install. There are two ways in: a catalog of servers that Nous has reviewed, installed with one command, and an mcp_servers section in ~/.hermes/config.yaml for everything else.

This guide was rewritten on 2026-09-27

The previous version configured MCP under tools.mcp.servers in a hermes.json file and used hermes config reload, hermes tools authorise and hermes run. None of those exist. MCP servers go under mcp_servers in config.yaml. You control access by filtering which tools each server exposes and through Hermes' normal approval system.

The fastest way: the catalog

Hermes ships a catalog of MCP servers that Nous has reviewed and merged. All of them are off until you install them.

hermes mcp                 # interactive picker: browse, install, enable/disable
hermes mcp catalog         # plain list (scriptable)
hermes mcp install deepwiki

You can also just ask in chat, for example "add the Linear MCP". A setup card appears with any fields the server needs and, for OAuth servers, a sign-in link. Hermes never opens a browser by itself. The desktop app's MCP page (v0.21.0+) shows the same catalog, plus health checks and each server's token cost and usage.

Reviewed doesn't mean risk-free. Installing an entry runs its install commands and the server's own code. Read the entry's source: repository and bootstrap commands, which the picker and dashboard show before you install. In August 2026, Nous removed the Blender server from the catalog after its upstream project was compromised.

Adding any server

From the command line:

hermes mcp add github --command npx --args -y @modelcontextprotocol/server-github
hermes mcp add myservice --url https://mcp.example.com/mcp --auth oauth
hermes mcp list
hermes mcp test github
hermes mcp configure github     # choose which of its tools to enable
hermes mcp remove github

Put --args last; everything after it is passed to the server command.

Or edit ~/.hermes/config.yaml directly. Stdio servers run as a local process:

mcp_servers:
  filesystem:
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/you/projects"]
  github:
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-github"]
    env:
      GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}"

HTTP servers are remote endpoints:

mcp_servers:
  remote_api:
    url: "https://mcp.example.com/mcp"
    headers:
      Authorization: "Bearer ${EXAMPLE_TOKEN}"

Keep secrets out of config.yaml. Put the token in ~/.hermes/.env (for example GITHUB_TOKEN=…) and refer to it as ${GITHUB_TOKEN} or ${env:GITHUB_TOKEN}. Hermes fills it in when it connects, so snippets copied from Cursor or Claude configs work unchanged.

Then run /reload-mcp in your session. A running gateway notices config changes by itself within about a minute, with no restart needed. Hermes names MCP tools mcp_<server>_<tool> (for example mcp_github_create_issue) so they never clash with built-in tools. You don't have to call them by name; the agent picks them like any other tool.

OAuth servers: sign in when prompted. If a token expires while the gateway runs unattended, the server is parked with a warning in gateway.log. Sign in again with hermes mcp login <server>.

Expose only the tools you need

Per-server filtering is Hermes' main MCP safety control: tools you filter out are never shown to the model. Allow a short list on sensitive servers, and remove destructive actions from the rest:

mcp_servers:
  github:
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-github"]
    env:
      GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}"
    tools:
      include: [list_issues, create_issue, update_issue]
      prompts: false      # drop the prompt wrappers
      resources: false    # drop the resource wrappers
  stripe:
    url: "https://mcp.stripe.com"
    headers:
      Authorization: "Bearer ${STRIPE_KEY}"
    tools:
      exclude: [delete_customer, refund_payment]
  legacy:
    url: "https://mcp.legacy.internal"
    enabled: false        # skipped entirely

include and exclude accept glob patterns such as "*_dns_*", which is useful for servers that expose hundreds of tools.

Keeping many servers cheap and fast

  • Lazy start (v0.20.0+): lazy: true registers a server's tools from a cache and starts the process only on first use, so twenty configured servers don't all boot with every session. The server must have connected once to fill the cache.
  • Recycle memory-hungry servers: idle_timeout_seconds or max_lifetime_seconds restart a stdio server transparently.
  • Mind the token cost: every enabled tool's description is sent with every request. Filtering tools cuts cost as well as risk. The desktop MCP page shows an estimate for each server.

How Hermes protects you from MCP servers

  • No blanket environment: a stdio server gets only the env you configure plus a safe baseline, never your whole shell environment.
  • Hidden-character stripping: invisible Unicode tag characters, a known prompt-injection trick, are removed from tool results and descriptions.
  • Normal approvals still apply to anything the agent does with an MCP tool's output. See hardening.
  • Audit what you pin: hermes security audit checks pinned MCP servers against the OSV.dev vulnerability database.

Writing your own MCP server

Any MCP server works. The quickest is a small Python script using the official MCP SDK:

# ~/.hermes/mcp/status_check.py   (pip install mcp)
import urllib.request
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("status-check")

@mcp.tool()
def check_status(url: str) -> str:
    """Return the HTTP status of a URL."""
    try:
        with urllib.request.urlopen(urllib.request.Request(url, method="HEAD"), timeout=5) as r:
            return f"{url} — {r.status}"
    except Exception as e:
        return f"{url} — UNREACHABLE: {e}"

if __name__ == "__main__":
    mcp.run()   # stdio
mcp_servers:
  status_check:
    command: "python3"
    args: ["/home/you/.hermes/mcp/status_check.py"]

Reload with /reload-mcp and ask: "Check whether https://example.com and https://api.example.com/health are up." For a production server with OAuth scopes, see our video summary on building a secured MCP server with FastMCP.

Hermes as an MCP server

It works the other way too. hermes mcp serve exposes Hermes' conversations to other agents and MCP clients, and hermes acp runs Hermes as an editor agent over the Agent Client Protocol.

Official reference: Hermes MCP docs.

← Back to Hermes hub · See also: Long-Running Tasks & Scheduling · Hermes vs OpenClaw

📬 Weekly Digest — In Your Inbox

One email a week: top news, releases, and our deepest new guide. No spam. Same content via RSS if you prefer.