Skip to main content

MCP Server Management (in Hermes)

Use when connecting/verifying MCP servers inside Hermes. Use when a task involves adding, configuring, verifying, or smoke-testing a Model Context Protocol (MCP) server inside Hermes Agent — connecting an external capability (GitHub, filesystem, databases, APIs) so its tools appear as native mcp_<server>_* tools. Complements the bundled hermes-agent skill's references/native-mcp.md; this skill carries the hard-won practical workflow (headless automation, secret hygiene, verification, direct-client probing) that the reference alone doesn't spell out.

Prereqs for most stdio servers: npx (Node) or uvx (uv), plus the mcp python package (pip install mcp).

Core workflow​

  1. Preflight what's available before starting:

    node --version 2>/dev/null; uv --version 2>/dev/null
    python3 -c "import mcp; print('mcp ok')" 2>/dev/null || pip install mcp
  2. Keep secrets in .env, never in config.yaml. Hermes resolves ${VAR} placeholders inside mcp_servers.*.env from ~/.hermes/.env at load time (function _interpolate_env_vars). Store the raw token in .env, reference the placeholder in the server config:

    echo "SOME_API_TOKEN=$(provider-command-to-get-token)" >> "${HERMES_HOME:-$HOME/.hermes}/.env"
    hermes mcp add myserver --command npx \
    --env 'SOME_API_TOKEN=${SOME_API_TOKEN}' \
    --args -y some-mcp-package

    Use single quotes so the shell stores the literal ${...}; the discovery probe resolves it from .env (_probe_single_server → _resolve_mcp_server_config). Sanity-check the credential first: curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $T" <api-endpoint> — expect 200 before wiring anything.

  3. Headless hermes mcp add needs a piped answer. After discovering tools, hermes mcp add calls a plain input("Enable all N tools? [Y/n/select]"). Without a TTY that raises EOFError → prints Cancelled. and saves nothing to config, even though discovery succeeded. Pipe the default:

    printf 'Y\n' | hermes mcp add myserver ...

    Confirm the ✓ Saved ... (N/N tools enabled) line — if you see Cancelled instead, nothing persisted.

  4. Verify, don't assume. hermes mcp list (server + status + tool count) and hermes mcp test myserver (connects + lists tools). Then run a real tool call (step 5).

    • MCP servers load at agent startup — no hot reload. A live session won't expose mcp_* tools until restart/new session. Say so explicitly.
    • Rotating a credential only requires editing .env; the placeholder keeps working.
  5. Smoke-test via the mcp python client to prove the integration (and tool behavior) without an agent restart — see scripts/mcp-server-smoke-test.py. It spawns the server over stdio, lists tools, and calls one with a harmless read-only argument.

  6. Treat third-party auto-configuration as optional, not authoritative. A server's installer may successfully place its binary/skill but fail while editing a valid Hermes YAML file. Preserve the installed artifacts and complete the integration through Hermes' own CLI rather than hand-editing config.yaml:

    printf 'Y\n' | hermes mcp add <name> --command /absolute/path/to/server --connect-timeout 60
    hermes config set hooks.pre_llm_call '[{"id":"<id>","type":"command","command":"/absolute/path/to/hook-command"}]' --force # only when the server documents this hook

    Derive any hook object and command from the server's source/docs or installer dry-run; do not invent them. Then read back with hermes config get hooks, run hermes mcp test <name>, execute one harmless read-only server operation, and finish with hermes doctor. A dry-run of the vendor installer can provide a final idempotency check without rewriting state.

Pitfalls​

  • Tool argument schemas are not a single "owner/repo" string. e.g. @modelcontextprotocol/server-github's list_issues requires BOTH owner and repo as separate strings; passing repo: "owner/repo" returns Invalid input: Required owner. When a call fails with invalid_type/Required, dump the tool's inputSchema (t.inputSchema from list_tools()) before guessing params.
  • Don't mistake valid-empty for failure. An empty list (e.g. list_issues → []) is often a valid success (no open issues). Distinguish "valid empty" from a connect error by structured output vs an exception.
  • hermes mcp add arg ordering: --args must come last; place --env before it.
  • Probe env interpolation: the add-time probe resolves ${VAR} from .env too (not just runtime) — so a placeholder-style --env still authenticates during discovery rather than 401ing with a literal placeholder.
  • npx shim-PATH failure in non-interactive shells. npx -y @modelcontextprotocol/server-* (and npm exec) can fail with sh: 1: <bin>: not found / exit 127 even though the package is cached and works when invoked directly via node <pkg>/dist/index.js. This bites hermes mcp add/mcp test inside Hermes' headless shell. Diagnosis: run the direct stdio probe (node <resolved-path>/dist/index.js) — if it handshakes but npx doesn't, it's the shim bug, not a broken server. Fix: npm install -g <pkg> (bins land in /usr/bin/), then hermes mcp add <name> --command /usr/bin/<bin> — the global bin path, with NO npx. Confirm with which <bin> and hermes mcp test <name>.
  • Some reference servers aren't npx packages. e.g. @modelcontextprotocol/server-git is Python (pyproject.toml, runs via uvx mcp-server-git, installable as pip/PyPI mcp-server-git), not a Node npm package — npx @modelcontextprotocol/server-git 404s. Also, the git server hard-requires a single --repository <path> arg at launch (mcp-server-git --repository <path>) and is bound to ONE repo per instance; without it the process crashes to Connection closed. If you need multi-repo or already have native git tools, skip the git MCP server.
  • Bundled-help conflict: the bundled hermes-agent skill and this one both touch MCP. This skill owns the practical/headless/verify/probe workflow; use the bundled reference for the full config-option table.

Support files​

  • scripts/mcp-server-smoke-test.py — drive any stdio MCP server with the mcp python client: connect, list tools, print a tool's input schema, and call one tool.
  • references/vendor-auto-config-fallback.md — recover safely when a vendor installer places artifacts but cannot edit Hermes config; includes the validated codebase-memory-mcp hook shape.
  • references/tailscale-loopback-ui.md — securely expose a loopback-only MCP web UI through tailnet-only Tailscale Serve, including the Host/Origin compatibility-proxy pattern and end-to-end verification gate.

Supporting files: this skill's supporting files are held in the docsite at docs/15-skills/_support/autonomous-ai-agents/mcp-server-management/ — fetch them fresh from jknash/docsite main alongside this page. Source: jknash/hermes-shared-skills · branch hermes-jkdev001 @ 1d0d545c3970 · skills/autonomous-ai-agents/mcp-server-management/ · view source · Imported 2026-10-04. Supporting files (references, scripts) remain in the source repository.

version 1.0.0 · author Hermes Agent · license MIT.

Published by Muse · 2026-10-04.