Back to Browse

Hermes Agent MCP Server

Developer ToolsModerate5.2MCP RegistryLocal
Free

Server data from the Official MCP Registry

Operate a local Hermes Agent install over stdio: tasks, cron, config, gateway, doctor. No network.

About

Operate a local Hermes Agent install over stdio: tasks, cron, config, gateway, doctor. No network.

Security Report

5.2
Moderate5.2Moderate Risk

This MCP server exhibits strong security fundamentals with a defensive design philosophy. The codebase properly isolates CLI execution through argument lists (no shell injection), implements an allowlist for subcommands, and redacts sensitive credentials before returning output. Permissions are appropriately scoped to local stdio-only operation with no network exposure by design. Minor findings include unvalidated input on the `shell` tool (opt-in by configuration) and a potential edge case in HMAC validation, but these do not materially impact the security posture. Supply chain analysis found 5 known vulnerabilities in dependencies (0 critical, 5 high severity). Package verification found 1 issue.

7 files analyzed · 10 issues found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Required

This plugin requests these system permissions. Most are normal for its category.

File System Read

Reads files on your machine. Normal for tools that analyze or process local data.

File System Write

Writes or modifies files on your machine. Check that this is expected for the tool.

env_vars

Check that this permission is expected for this type of plugin.

process_spawn

Check that this permission is expected for this type of plugin.

HTTP Network Access

Connects to external APIs or services over the internet.

What You'll Need

Set these up before or after installing:

Hermes data directory (default ~/.hermes)Optional

Environment variable: HERMES_HOME

Allow state-changing tools (default 1)Optional

Environment variable: HERMES_MCP_ALLOW_WRITE

Enable the shell tool (default 0)Optional

Environment variable: HERMES_MCP_ALLOW_SHELL

How to Install

Add this to your MCP configuration file:

{
  "mcpServers": {
    "io-github-woonyong-choi-hermes-agent-mcp": {
      "env": {
        "HERMES_HOME": "your-hermes-home-here",
        "HERMES_MCP_ALLOW_SHELL": "your-hermes-mcp-allow-shell-here",
        "HERMES_MCP_ALLOW_WRITE": "your-hermes-mcp-allow-write-here"
      },
      "args": [
        "hermes-agent-mcp"
      ],
      "command": "uvx"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

hermes-agent-mcp

Operate your local Hermes Agent install from any MCP client — without exposing it to the network.

hermes-agent-mcp is a Model Context Protocol server that wraps the local hermes CLI over stdio. Point Claude Code, Cursor, Codex or any other MCP-capable agent at it and they can hand Hermes a task, read and change its config, manage cron jobs, restart the gateway and run hermes doctor — without a terminal and without ever seeing a token.

uvx hermes-agent-mcp

That is the whole install. No ports, no tunnel, no OAuth. It runs as a child process of your MCP client, on the same machine as Hermes, and nothing leaves the box.

mcp-name: io.github.woonyong-choi/hermes-agent-mcp

Why this exists

Hermes is a great always-on agent, but everything about operating it happens in a terminal: hermes cron edit, hermes config set, hermes gateway restart. If the agent that wants to do those things has no terminal — a desktop app, a coding assistant sandboxed away from your shell — it is stuck asking a human to type for it.

There is already a good project called hermes-mcp by mlennie. It solves a different problem: reaching Hermes remotely, over HTTP through a cloudflared tunnel with OAuth, so a hosted client can delegate tasks. If that is what you need, use it.

This project was written by someone who did not want that. Opening a Hermes gateway to the internet means an agent with a shell is one leaked token away from anyone. hermes-agent-mcp stays local on purpose:

  • it never listens on a port — MCP over stdio only
  • it never handles credentials — it calls the CLI, which already has them
  • it exposes the operations surface (cron, config, gateway, doctor, skills), not just "send a prompt"
hermes-agent-mcp (this)hermes-mcp (mlennie)
Transportstdio, local processHTTP, tunnel + OAuth
Reachable fromMCP clients on the same machineAnywhere
Surface16 tools: ask + cron, config, gateway, doctor, skills, sessions4 tools: ask, check, cancel, reset
Typed config.yaml writesYes—
Network exposureNoneBy design

Tools

ToolWhat it does
hermes_statusServer config, whether the CLI answers, which tools are enabled
hermes_askHand the agent a task and get its reply (one non-interactive turn)
doctorhermes doctor health report
gateway_status / gateway_restartMessaging gateway state and restart
cron_list / cron_create / cron_edit / cron_run / cron_runsScheduled jobs, including per-job model and reasoning effort
config_get / config_setTyped reads and writes against config.yaml
skills_listInstalled skills
sessions_listRecent sessions
model_infoDefault model, provider and Nous Portal status
shellRun a shell command on the host — off by default
bridge_setup / bridge_statusPoint the bridge at a chat (Telegram by default)
bridge_ask / bridge_checkAsk through the gateway and mirror prompt + reply into that chat

bridge_ask keeps the phone in the loop

hermes_ask runs a one-shot CLI turn: fine for work, but it runs outside the gateway, so nothing appears in the user's chat. bridge_ask goes through the gateway's own webhook adapter instead: your prompt is posted into the chat (prefixed ▸ Claude Code · — the caller name comes from HERMES_MCP_CALLER, the format from HERMES_MCP_LABEL_FORMAT), the agent runs inside the gateway with its full toolset, and the reply lands in the chat and comes back to you. The person can pick the thread up on their phone as if they had typed it themselves.

bridge_setup registers two loopback-only, HMAC-signed webhook routes and targets the most recently active chat unless you pass chat_id. The secret lives in $HERMES_HOME/hermes-agent-mcp.json (mode 0600) and is never returned to the model. The bridged turn does not share the chat's own session history — Hermes keys webhook sessions separately — but memory and skills are shared and the transcript in the chat is continuous.

config_set fixes a real trap

hermes config set platforms.telegram.reply_to_mode off stores the YAML boolean False, not the string "off". Several Hermes options compare against the string, so the setting silently does nothing. config_set takes an explicit value_type (str, int, float, bool, null, json), writes a .bak before touching the file, and returns the resulting section so you can see what landed.

Setup

Claude Code

claude mcp add hermes -- uvx hermes-agent-mcp

Cursor / Windsurf / Claude Desktop

{
  "mcpServers": {
    "hermes": {
      "command": "uvx",
      "args": ["hermes-agent-mcp"]
    }
  }
}

Hermes itself

Hermes can drive its own install — useful for a supervisor profile that manages other profiles. Add to ~/.hermes/config.yaml:

mcp_servers:
  hermes:
    command: uvx
    args: ["hermes-agent-mcp"]

From a clone

git clone https://github.com/woonyong-choi/hermes-agent-mcp
cd hermes-agent-mcp
uv tool install -e .

Configuration

Everything is an environment variable, so the same server works on macOS, Linux, WSL and inside a container that mounts someone else's ~/.hermes.

VariableDefaultMeaning
HERMES_HOME~/.hermesHermes data directory
HERMES_MCP_BINhermes on PATHPath to the CLI
HERMES_MCP_ALLOW_WRITE1Allow tools that change state (cron edit, config set, restart). Set 0 for read-only
HERMES_MCP_ALLOW_SHELL0Enable the shell tool
HERMES_MCP_TIMEOUT120Seconds for ordinary CLI calls
HERMES_MCP_ASK_TIMEOUT900Seconds for hermes_ask
HERMES_MCP_MAX_OUTPUT40000Characters returned per call before truncation
HERMES_MCP_CALLERClaudeWho this registration is for; shown in the chat prefix (▸ Claude Code · …). Set it per registration
HERMES_MCP_LABEL_FORMAT▸ {caller} · Template for that prefix, e.g. [{caller}]

Security model

This server gives a language model the ability to operate an agent that has a terminal. The design assumes the model is talking to untrusted content and keeps the blast radius small:

  • Argument lists, never a shell. Every CLI call is subprocess.run([...]) with shell=False. Prompt text cannot become shell syntax.
  • Subcommand allowlist. Only config, cron, doctor, gateway, model, portal, profile, sessions, skills, tools and --version are reachable. hermes auth and anything that handles credentials is not, on purpose.
  • Redaction on every return. Telegram bot tokens, Anthropic/OpenAI/GitHub/Slack/AWS keys and JWTs are replaced with [redacted] before output reaches the model. .env is never read.
  • Read-only mode. HERMES_MCP_ALLOW_WRITE=0 blocks every state-changing verb.
  • Shell is opt-in. shell refuses to run until you set HERMES_MCP_ALLOW_SHELL=1, and you should only do that on a machine you control, for an agent you trust.

See SECURITY.md for reporting.

Releasing

Tag a version and CI publishes to PyPI via Trusted Publishing and attaches the wheel to a GitHub release:

git tag v0.1.0 && git push --tags

server.json at the repo root is the manifest for the MCP Registry; publish it with mcp-publisher publish after the PyPI release exists.

Development

uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
pytest
ruff check .

Tests do not need a Hermes install; the runner is exercised against a missing binary and the config writer against a temp directory.

Compatibility

Built against Hermes Agent 0.21.x. The CLI is moving fast — if a subcommand's flags change, the tool returns the CLI's own error text rather than guessing. Issues and PRs that track upstream changes are welcome.

License

MIT. Hermes Agent is MIT-licensed by Nous Research; this project is independent and not affiliated with them.

Reviews

No reviews yet

Be the first to review this server!