test(mcp): pin hermes mcp test exit codes; document them
Two invariant tests: the handler returns 0/1/3 for connected / connection failed / not in config, and the `hermes mcp` CLI dispatcher forwards that code to `main()` (which already exits on an int return). The MCP guide documents the codes so probes and watchdogs can stop parsing the output.
This commit is contained in:
@@ -303,6 +303,35 @@ class TestMcpTest:
|
||||
assert "Connected" in out
|
||||
assert "Tools discovered: 2" in out
|
||||
|
||||
def test_exit_codes_distinguish_failure_from_unknown_server(self, tmp_path, capsys, monkeypatch):
|
||||
"""0 connected, 1 connection failed, 3 not in config — never argparse's 2, never a silent 0."""
|
||||
_seed_config(tmp_path, {"ink": {"url": "https://mcp.ml.ink/mcp"}})
|
||||
from hermes_cli.mcp_config import cmd_mcp_test
|
||||
|
||||
monkeypatch.setattr("hermes_cli.mcp_config._probe_single_server", lambda name, cfg, **kw: [])
|
||||
assert cmd_mcp_test(_make_args(name="ink")) == 0
|
||||
|
||||
def failing_probe(name, cfg, **kw):
|
||||
raise RuntimeError("Server returned an error response")
|
||||
|
||||
monkeypatch.setattr("hermes_cli.mcp_config._probe_single_server", failing_probe)
|
||||
assert cmd_mcp_test(_make_args(name="ink")) == 1
|
||||
assert cmd_mcp_test(_make_args(name="doesnotexist")) == 3
|
||||
assert "not found in config" in capsys.readouterr().out
|
||||
|
||||
def test_cli_dispatcher_forwards_test_exit_code(self, tmp_path, monkeypatch):
|
||||
"""``hermes mcp test`` reaches ``main()`` with the handler's code (the dispatcher used to drop it)."""
|
||||
_seed_config(tmp_path, {"ink": {"url": "https://mcp.ml.ink/mcp"}})
|
||||
from hermes_cli.main import cmd_mcp
|
||||
|
||||
def failing_probe(name, cfg, **kw):
|
||||
raise RuntimeError("boom")
|
||||
|
||||
monkeypatch.setattr("hermes_cli.mcp_config._probe_single_server", failing_probe)
|
||||
assert cmd_mcp(_make_args(name="ink", mcp_action="test")) == 1
|
||||
assert cmd_mcp(_make_args(name="doesnotexist", mcp_action="test")) == 3
|
||||
assert cmd_mcp(_make_args(mcp_action="list")) is None
|
||||
|
||||
def test_probe_uses_configured_connect_timeout(self, monkeypatch):
|
||||
"""OAuth-capable probes must not hard-code a short 30s timeout."""
|
||||
import asyncio
|
||||
|
||||
@@ -83,6 +83,11 @@ You can verify MCP in a few ways:
|
||||
- ask Hermes what tools it has available
|
||||
- use `/reload-mcp` after config changes
|
||||
- check logs if the server failed to connect
|
||||
- run `hermes mcp test <server>` from a shell — it connects, lists the
|
||||
discovered tools, and exits `0` on a completed connect, `1` when the
|
||||
connection fails, and `3` when the server is not in your config (`2` is
|
||||
argparse's usage error), so health probes and cron watchdogs can branch on
|
||||
`$?` instead of parsing the output
|
||||
|
||||
A practical test prompt:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user