Skip to content

Feature: MCP Server Management — Discovery, Selective Tool Loading, and hermes mcp CLI #690

@teknium1

Description

@teknium1

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:

  1. Discovery before install — Connect to an MCP server, list its tools, let the user review and select which tools to enable before committing
  2. Selective tool loadinginclude / exclude filters in MCP server config, so users don't get 20+ tools dumped into their context
  3. Interactive managementhermes mcp add/remove/list/configure CLI commands
  4. Unified tool viewhermes 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
  • Discoverabilityhermes 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

  • Complexityhermes 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

  1. 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.

  2. 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?

  3. YAML writer — Use ruamel.yaml (preserves comments) or yaml.safe_dump() (simpler but loses comments)?

  4. Per-platform MCP tools — Should MCP tool selection be per-platform (CLI vs Telegram vs Discord) like built-in toolsets, or global?

  5. Gateway supporthermes 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions