Overview
MCP (Model Context Protocol) servers are currently configured via raw YAML in ~/.hermes/config.yaml and load all tools unconditionally at startup. There's no discovery preview, no tool selection, no interactive setup, and no way to manage MCP servers after initial configuration. This makes MCP integrations an all-or-nothing commitment that's invisible to users and hard to manage.
This enhancement introduces hermes mcp as a proper CLI subcommand for managing MCP server connections, and extends hermes tools to show MCP-sourced tools alongside built-in ones. The key capabilities:
- Discovery before install — Connect to an MCP server, list its tools, let the user review and select which tools to enable before committing
- Selective tool loading —
include / exclude filters in MCP server config, so users don't get 20+ tools dumped into their context
- Interactive management —
hermes mcp add/remove/list/configure CLI commands
- Unified tool view —
hermes tools shows both built-in and MCP tools, with the ability to toggle MCP tools on/off
Constraints (hard requirements):
- Tools are configured outside active sessions, never mid-session
- Changing tool configuration requires starting a new session (modifying tool schemas breaks KV cache and may confuse the model)
- Users must see and approve what tools will be added before they're committed
Current State
What exists:
tools/mcp_tool.py (~1050 lines) — Full MCP client with stdio + HTTP transport, auto-reconnect, tool auto-discovery
mcp_servers config key in config.yaml — Static YAML configuration
discover_mcp_tools() — Idempotent startup function that connects to all configured servers
- Per-server custom toolsets (
mcp-{name}) — Each MCP server's tools are grouped
hermes tools command — Interactive tool configuration, but only for built-in toolsets
What's missing:
- No tool filtering —
_discover_and_register_server() registers ALL tools from every server (line 808: for mcp_tool in server._tools:)
- No discovery preview — No way to see what tools a server offers before adding it
- No interactive MCP management — Must hand-edit config.yaml
- No MCP visibility in
hermes tools — MCP servers/tools are invisible in the tool configuration UI
- No individual tool toggle — Can't enable/disable specific tools from an MCP server
Design
Config Schema Extension
mcp_servers:
ink:
url: "https://mcp.ml.ink/mcp"
headers:
Authorization: "Bearer ${INK_API_KEY}" # env var interpolation (new)
timeout: 180
tools: # NEW: selective tool loading
include: # whitelist (if set, only these are loaded)
- create_service
- get_service
- list_services
- create_resource
- get_resource
# OR:
exclude: # blacklist (load all EXCEPT these)
- delete_service
- delete_resource
enabled: true # NEW: toggle entire server on/off
Rules:
- If
tools.include is set, only those tools are registered (whitelist)
- If
tools.exclude is set, all tools EXCEPT those are registered (blacklist)
- If neither is set, all tools are registered (current behavior, backward compatible)
include and exclude are mutually exclusive
enabled: false skips the server entirely without removing its config
hermes mcp CLI Subcommand
$ hermes mcp add <name> --url <endpoint>
$ hermes mcp add <name> --command <cmd> --args <args...>
$ hermes mcp remove <name>
$ hermes mcp list
$ hermes mcp configure <name>
$ hermes mcp test <name>
hermes mcp add — Discovery-first install
$ hermes mcp add ink --url "https://mcp.ml.ink/mcp"
Connecting to mcp.ml.ink...
🔑 Authentication required.
Enter API key (hidden): ********
✓ Authenticated
Connected! Found 20 tools from 'ink':
Services:
☑ ink_create_service Deploy from Ink/GitHub repo
☑ ink_get_service Status, URLs, env vars, logs
☑ ink_list_services List all services in project
☑ ink_update_service Modify scaling, branch, redeploy
☑ ink_delete_service Delete a service permanently
Resources:
☑ ink_create_resource Provision managed SQLite database
☑ ink_get_resource Get database connection details
☑ ink_list_resources List all databases
☑ ink_delete_resource Delete a database
Git:
☑ ink_create_repo Create git repository
☑ ink_get_git_token Get push credentials
Domains:
☑ ink_add_custom_domain Assign custom domain to service
☑ ink_remove_custom_domain Remove custom domain
☑ ink_list_delegations List domain delegations
☑ ink_list_dns_records List DNS records
☑ ink_add_dns_record Add DNS record
☑ ink_delete_dns_record Delete DNS record
Identity:
☑ ink_whoami Check authentication status
☑ ink_list_projects List all projects
☑ ink_list_workspaces List all workspaces
Enable all 20 tools? [Y/n/select]: s
(interactive toggle with arrow keys / space to select)
✓ Saved 'ink' to ~/.hermes/config.yaml (15 tools enabled)
✓ API key saved to ~/.hermes/.env as INK_API_KEY
Start a new session to use these tools.
hermes mcp list — Show configured servers
$ hermes mcp list
MCP Servers:
ink https://mcp.ml.ink/mcp 15/20 tools ✓ enabled
stripe stdio: npx @stripe/mcp 8/12 tools ✓ enabled
github stdio: npx @mcp/github 22/22 tools ✗ disabled
hermes mcp configure <name> — Reconfigure tools
$ hermes mcp configure ink
Currently 15/20 tools enabled for 'ink'.
(interactive toggle showing current state)
✓ Updated config. Start a new session for changes to take effect.
hermes mcp test <name> — Verify connection
$ hermes mcp test ink
Connecting to mcp.ml.ink... ✓
Auth: Bearer dk_live_***... ✓
Tools discovered: 20 ✓
Latency: 142ms
hermes tools Extension
The existing hermes tools command should also show MCP servers:
$ hermes tools
⚕ Hermes Tool Configuration
Built-in Toolsets:
☑ terminal Terminal, process management
☑ file Read, write, search, patch files
☑ web Web search, content extraction
☑ vision Image analysis
...
MCP Servers:
☑ ink 15/20 tools from mcp.ml.ink
☑ stripe 8/12 tools from Stripe MCP
[Configure built-in] [Configure MCP] [Add MCP server] [Done]
Env Var Interpolation in Config
MCP server configs should support ${ENV_VAR} references that resolve from ~/.hermes/.env:
mcp_servers:
ink:
url: "https://mcp.ml.ink/mcp"
headers:
Authorization: "Bearer ${INK_API_KEY}"
This keeps secrets in .env (one place) rather than duplicating them in config.yaml. The _load_mcp_config() function would resolve ${...} references before passing configs to the connection logic.
Implementation Plan
Phase 1: Selective tool loading
- Add
tools.include / tools.exclude / enabled to MCP server config schema
- Modify
_discover_and_register_server() to filter tools based on config
- Backward compatible — no filter = load all (existing behavior)
Phase 2: hermes mcp CLI
hermes mcp add — prompt for URL/command, connect, discover tools, interactive selection, save to config.yaml
hermes mcp remove — remove from config.yaml
hermes mcp list — show configured servers with tool counts and status
hermes mcp test — verify connection and auth
hermes mcp configure — interactive tool toggle for existing server
Phase 3: Env var interpolation + hermes tools integration
${ENV_VAR} resolution in _load_mcp_config()
- Secure API key prompting during
hermes mcp add (using getpass)
- Extend
hermes tools to show MCP servers alongside built-in toolsets
- Unified enable/disable across built-in and MCP tools
Phase 4: Optional skills integration
- Official optional skills in
optional-skills/mcp/ can declare MCP server configs
hermes skills install official/mcp/ink triggers hermes mcp add flow
- Skill provides usage guidance; MCP config provides the tools
- Clear separation: skill = knowledge, MCP config = tools
Pros & Cons
Pros
- User control — Users see exactly what tools are being added and choose which ones to enable
- Context efficiency — Don't waste context window on tools the user doesn't need
- Discoverability —
hermes mcp list and hermes tools make MCP servers visible and manageable
- Session safety — All changes happen outside sessions, respecting KV cache and context integrity
- Backward compatible — Existing raw YAML configs continue to work (all tools loaded by default)
Cons / Risks
- Complexity —
hermes mcp add needs to temporarily connect, discover, disconnect, then reconnect at session start. Two connection phases.
- Config.yaml writing — Need to safely read/modify/write YAML without destroying comments or structure
- Tool naming — MCP tools are prefixed with server name (
ink_create_service). Users need to understand this naming convention during selection.
Open Questions
-
Include vs. exclude default — When a user adds a server and selects tools, should the config store a whitelist (include) or blacklist (exclude)? Whitelist is safer (new tools don't auto-appear) but needs updating when the server adds tools.
-
Tool schema changes — If an MCP server adds/removes/renames tools between sessions, how do we handle stale include lists? Show a warning on startup?
-
YAML writer — Use ruamel.yaml (preserves comments) or yaml.safe_dump() (simpler but loses comments)?
-
Per-platform MCP tools — Should MCP tool selection be per-platform (CLI vs Telegram vs Discord) like built-in toolsets, or global?
-
Gateway support — hermes mcp add is a CLI operation. For gateway-only users, should there be a /mcp slash command, or is CLI-only acceptable for MCP management?
References
Overview
MCP (Model Context Protocol) servers are currently configured via raw YAML in
~/.hermes/config.yamland load all tools unconditionally at startup. There's no discovery preview, no tool selection, no interactive setup, and no way to manage MCP servers after initial configuration. This makes MCP integrations an all-or-nothing commitment that's invisible to users and hard to manage.This enhancement introduces
hermes mcpas a proper CLI subcommand for managing MCP server connections, and extendshermes toolsto show MCP-sourced tools alongside built-in ones. The key capabilities:include/excludefilters in MCP server config, so users don't get 20+ tools dumped into their contexthermes mcp add/remove/list/configureCLI commandshermes toolsshows both built-in and MCP tools, with the ability to toggle MCP tools on/offConstraints (hard requirements):
Current State
What exists:
tools/mcp_tool.py(~1050 lines) — Full MCP client with stdio + HTTP transport, auto-reconnect, tool auto-discoverymcp_serversconfig key inconfig.yaml— Static YAML configurationdiscover_mcp_tools()— Idempotent startup function that connects to all configured serversmcp-{name}) — Each MCP server's tools are groupedhermes toolscommand — Interactive tool configuration, but only for built-in toolsetsWhat's missing:
_discover_and_register_server()registers ALL tools from every server (line 808:for mcp_tool in server._tools:)hermes tools— MCP servers/tools are invisible in the tool configuration UIDesign
Config Schema Extension
Rules:
tools.includeis set, only those tools are registered (whitelist)tools.excludeis set, all tools EXCEPT those are registered (blacklist)includeandexcludeare mutually exclusiveenabled: falseskips the server entirely without removing its confighermes mcpCLI Subcommandhermes mcp add— Discovery-first installhermes mcp list— Show configured servershermes mcp configure <name>— Reconfigure toolshermes mcp test <name>— Verify connectionhermes toolsExtensionThe existing
hermes toolscommand should also show MCP servers:Env Var Interpolation in Config
MCP server configs should support
${ENV_VAR}references that resolve from~/.hermes/.env:This keeps secrets in
.env(one place) rather than duplicating them inconfig.yaml. The_load_mcp_config()function would resolve${...}references before passing configs to the connection logic.Implementation Plan
Phase 1: Selective tool loading
tools.include/tools.exclude/enabledto MCP server config schema_discover_and_register_server()to filter tools based on configPhase 2:
hermes mcpCLIhermes mcp add— prompt for URL/command, connect, discover tools, interactive selection, save to config.yamlhermes mcp remove— remove from config.yamlhermes mcp list— show configured servers with tool counts and statushermes mcp test— verify connection and authhermes mcp configure— interactive tool toggle for existing serverPhase 3: Env var interpolation +
hermes toolsintegration${ENV_VAR}resolution in_load_mcp_config()hermes mcp add(usinggetpass)hermes toolsto show MCP servers alongside built-in toolsetsPhase 4: Optional skills integration
optional-skills/mcp/can declare MCP server configshermes skills install official/mcp/inktriggershermes mcp addflowPros & Cons
Pros
hermes mcp listandhermes toolsmake MCP servers visible and manageableCons / Risks
hermes mcp addneeds to temporarily connect, discover, disconnect, then reconnect at session start. Two connection phases.ink_create_service). Users need to understand this naming convention during selection.Open Questions
Include vs. exclude default — When a user adds a server and selects tools, should the config store a whitelist (
include) or blacklist (exclude)? Whitelist is safer (new tools don't auto-appear) but needs updating when the server adds tools.Tool schema changes — If an MCP server adds/removes/renames tools between sessions, how do we handle stale
includelists? Show a warning on startup?YAML writer — Use
ruamel.yaml(preserves comments) oryaml.safe_dump()(simpler but loses comments)?Per-platform MCP tools — Should MCP tool selection be per-platform (CLI vs Telegram vs Discord) like built-in toolsets, or global?
Gateway support —
hermes mcp addis a CLI operation. For gateway-only users, should there be a/mcpslash command, or is CLI-only acceptable for MCP management?References
tools/mcp_tool.py:786-861—_discover_and_register_server()(where tool filtering goes)tools/mcp_tool.py:868-948—discover_mcp_tools()(startup discovery)toolsets.py:395-414—create_custom_toolset()(MCP toolset creation)hermes_cli/tools_config.py:839+— Existinghermes toolscommand