agentleFS
iapiap/hermes-guide/skills/diagnosing-mcp/SKILL.md

diagnosing-mcp

Skill6 starsChanged 9 days agoMITView on GitHub

Diagnose Hermes MCP servers that will not connect, expose no tools, fail OAuth, or ignore config — with the exact config.yaml fields and hermes mcp commands to fix each.

  • Reads credentials

The file

We split this skill into the rules it gives an agent

1 rule. About 0 are common, 1 is distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Check filters (pitfall 3) before blaming the connection.

    line 63

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Diagnosing MCP Configuration

Goal: reduce any MCP problem to one concrete fix — a mcp_servers: entry in $HERMES_HOME/config.yaml (resolve with hermes config path) or a hermes mcp subcommand. Hermes registers server tools as mcp__<server>__<tool> and one runtime toolset per contributing server (mcp-<server>).

Disambiguation: if a model provider is configured but silently unavailable (not an MCP server issue), see diagnosing-providers.

1. Configuration shape

mcp_servers:
  filesystem:                      # stdio server
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
  linear:                          # OAuth 2.1 HTTP server
    url: "https://mcp.linear.app/mcp"
    auth: oauth

Key fields: stdio → command, args, env (only these plus a safe baseline reach the subprocess); http → url, headers; mTLS → client_cert (PEM path or [cert, key(, password)]), client_key; timing → timeout (tool call; _DEFAULT_TOOL_TIMEOUT = 300 in tools/mcp_tool_common.py), connect_timeout (_DEFAULT_CONNECT_TIMEOUT = 60 in tools/mcp_tool.py, consumed via discovery — read the constant rather than trusting a remembered number), keepalive_interval; recycling → idle_timeout_seconds, max_lifetime_seconds (tools/mcp_tool.py, tools/mcp_tool_health.py); enabled (default true — hermes_cli/mcp_config.py); supports_parallel_tool_calls; sampling (per-server block; expose_client_tools: false by default — set true to advertise the extended sampling.tools capability, tools/mcp_tool_sampling.py). Verify any default against the installed source: the defaults live in constants, and a doc that quotes a stale number sends you chasing a non-bug. (elicitation is referenced in discovery code; treat its default as version-dependent unless you have checked it.) ${VAR} in command/args/url/headers is expanded at connect time from the environment including $HERMES_HOME/.env.

Per-server tool filtering: tools.include (whitelist) / tools.exclude (blacklist, fnmatch globs allowed) — include wins when both are set (tools/mcp_tool_registration.py, verified); an empty tools.include: [] registers nothing; tools.prompts: false / tools.resources: false disable utility wrappers. If everything callable and all utilities are filtered out, Hermes creates no toolset for that server — by design.

2. How to inspect

  • hermes mcp — interactive picker showing each server's status (available / enabled / installed (disabled)); without a TTY it prints the same text dump instead of the picker (run_picker() gates on sys.stdin.isatty()), so no-TTY contexts still get status output — hermes mcp catalog is the explicit non-interactive form.
  • hermes mcp configure <name> — re-probe the server and re-pick its tools.
  • hermes mcp login <name> — run the OAuth flow and wait for it to complete.
  • In chat: /reload-mcp reloads from config; /context shows the MCP token share.
  • Edit config from a fresh terminal while a session is running — the in-session config auto-reload window is short (previously documented as 30s; the window is version-dependent, and a reload that lands mid-OAuth kills the browser flow). Prefer a fresh terminal regardless.

3. Pitfalls (symptom → cause → fix)

  1. Server not listed at all — YAML syntax error in config.yaml drops servers (or the whole file), enabled: false skips the server entirely, or the entry was simply never added. → Permanent: validate YAML, check the entry exists under mcp_servers:, set enabled: true or remove the field. Temporary: /reload-mcp picks up a corrected config without restarting the session.
  2. command not found / spawn ENOENT — command is not on PATH. On Windows point at the .cmd/.exe or use an absolute path; check the PATH the server will actually be spawned with — run hermes mcp test <name> to surface the spawn error, and read hermes logs errors for details. Note that Hermes's own JS runs on the PM-managed Node, not a system Node, so node --version in your shell does not describe the interpreter Hermes uses — it only tells you what a server you launch with a bare node would get. When PM reports node missing (or the managed Node cannot execute on the host), point command at a working Node directly: resolve the store first (hermes config path for the active home; ${HERMES_RUNTIME_DIR} overrides $HERMES_HOME/tools when set), then paste the resolved absolute path (e.g. .../tools/node-<ver>-<target>/bin/npx on POSIX, ...\node-<ver>-<target>\npx.cmd on native Windows — not the $HERMES_HOME variable itself) — verify it runs (<path> --version) before trusting it. Note npx itself shebangs env node, so this only helps where node also resolves in the spawned environment: if hermes mcp test then fails naming node, apply the same absolute-path treatment to the interpreter.
  3. Tools missing — a tools.include/exclude filter removed them (include wins), or the server session lacks the capability (resource/prompt wrappers only register when the server supports them), or the server failed to connect so nothing registered. → Run hermes mcp configure <name>; check status in hermes mcp.
  4. OAuth never completes — (a) config edited inside a running session: the version-dependent auto-reload window can interrupt the browser flow → run hermes mcp login <name> from a fresh terminal; (b) headless/remote host → use paste-back of the redirect URL, SSH port-forward, or oauth.redirect_uri (tools/mcp_oauth.py, verified); (c) WAF 403s loopback redirects → check the redirect-host knob in your version — verify with grep -rn redirect_host tools/mcp_oauth*.py in the installed source before relying on it).
  5. OAuth login "works" but tool calls time out — the provider rejects dynamic client registration (Google Drive, Atlassian): tools/list succeeds unauthenticated, so login looks fine but no token lands. → Create an OAuth client in the provider console and set oauth.client_id / oauth.client_secret, then hermes mcp login <name>.
  6. Tool call times out — slow server startup. → Raise timeout / connect_timeout on that entry.
  7. Catalog entry stale after Hermes update — catalog MCPs never auto-update. → Re-run hermes mcp install <name>.
  8. Claude-Code-style config pasted in — mcpServers JSON or nested mcp.servers is not read. → Use top-level mcp_servers: in YAML (or install the plugin and run the import):

    hermes plugins install agent-importers
    hermes import-agent claude-code
  9. Server works without a key but you want identified/limited use — some servers (e.g. context7) run free anonymously and also accept an API key. → Set the key in the active .env (resolve it first: hermes config path prints the config file, .env sits beside it — never assume ~/.hermes) as CONTEXT7_API_KEY. For catalog-installed entries, which use HTTP transport (optional-mcps/context7/manifest.yaml declares transport.type: http), add it as a Bearer header via mcp_servers.context7.headers — env: only reaches spawned subprocesses and never authenticates HTTP requests. For stdio servers, reference it as ${CONTEXT7_API_KEY} in the entry's env:. hermes mcp test <name> reports OAuth and HTTP-header auth modes (stdio env: keys show as Auth: none even when set — verify those from the entry instead).

4. Localization workflow

  1. hermes config path → open the file, confirm the entry exists under mcp_servers: and YAML parses.
  2. hermes mcp → read the entry's status: absent → pitfall 1; disabled → enable it; present-but-failing → step 3.
  3. Match the failure: ENOENT → 2; timeout → 6; OAuth → 4/5.
  4. Check filters (pitfall 3) before blaming the connection.
  5. Apply the fix, then /reload-mcp (or restart), and confirm the mcp__<server>__* tools appear (/context).
  6. Re-run the detector: hermes guide mcp headless or /hermes-doctor mcp in-session; + means healthy, ~ means informational, and x/? means unresolved.

Verification

The server is healthy when hermes mcp test <name> succeeds and its tools appear in the active session.

# Confirm server connectivity (dedicated probe)
hermes mcp test <name>

Pass: probe reports connected/available; no connection error. Fail: server still fails — re-check the pitfall matched in step 3 and re-apply the fix.

# Confirm tools visible in the active session
# (run inside a hermes session)
/context

Pass: mcp-<server> toolset appears with at least one tool. If the entry's tools.include/exclude filters intentionally remove everything callable (e.g. tools.include: []), no toolset is created — by design (section 1) — and its absence is not a failure. Fail: tools the configuration intends to expose are absent — /reload-mcp and check hermes logs errors for a new spawn or OAuth error.

Report

This skill diagnoses MCP servers that will not connect, expose no tools, fail OAuth, or ignore config. When you run the diagnostic workflow, present findings in the standard format below.

Summary

Your MCP server is not listed because the command field is not on PATH. The server entry exists in config.yaml but the spawn fails with ENOENT, so the server is silently dropped.

Findings

SeverityWhatEvidence
HIGHMCP server command not found on PATHhermes mcp shows server as failed; error: spawn npx ENOENT
MEDIUMServer uses bare npx instead of absolute pathConfig has command: "npx" but npx is not on the PATH the server is spawned with

Recommended Fix

Edit $HERMES_HOME/config.yaml and change the server's command to an absolute path (e.g., /usr/local/bin/npx on POSIX or C:\path\to\npx.cmd on Windows), then run /reload-mcp and verify with hermes mcp.

References

  • $HERMES_HOME/config.yaml — mcp_servers: entry
  • hermes_cli/mcp_config.py — MCP config loading
  • tools/mcp_tool_common.py — _DEFAULT_TOOL_TIMEOUT; tools/mcp_tool.py — _DEFAULT_CONNECT_TIMEOUT

Facts re-verified 2026-09-14 (corrective pass) against upstream source at commit 46a0daee58abbc1b07f84f505a5ba90f1958295c: mcp__<server>__<tool> naming and the per-server mcp-<server> toolset alias (tools/mcp_tool_schema.py, tools/mcp_tool_registration.py); the server field set and defaults (tools/mcp_tool_common.py, tools/mcp_tool_discovery.py, hermes_cli/mcp_config.py); include-wins filtering with fnmatch and the empty-list semantics (tools/mcp_tool_registration.py); recycling fields (tools/mcp_tool.py); redirect_uri (tools/mcp_oauth.py); the install/configure/login subcommands. Four previously asserted specifics could not be confirmed at current main and are now marked version-dependent instead of quoted as fact: the 30s reload window, oauth.redirect_host, the elicitation default, and the exact connect_timeout value. Re-checked 2026-10-12 against upstream main (53bc70c5): _DEFAULT_CONNECT_TIMEOUT = 60 lives in tools/mcp_tool.py:238 (consumed via discovery; line re-checked 2026-10-19 at upstream 86fa9e6, moved from :233). Re-checked 2026-10-14 against the live install: absolute store-npx path resolves MCP spawn when PM node is unverifiable (stdio env: keys report Auth: none; npx still needs node on the spawned PATH). Verified 2026-10-15 against the installed source at 9bda154d (v0.21.7): per-server sampling: block with expose_client_tools default false (tools/mcp_tool_sampling.py). Re-verified 2026-10-20 against the installed source at dd519c74 (v0.22.2+1915): the hermes mcp picker gates on sys.stdin.isatty() and degrades to the catalog text dump instead of failing (hermes_cli/mcp_picker.py::run_picker), with hermes mcp list/hermes mcp catalog as explicit text forms (hermes_cli/mcp_config.py::cmd_mcp_list, hermes_cli/mcp_picker.py::show_catalog). Re-verify before reuse.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.