MCP Integration Pattern in Hermes Agent: A Complete Guide to Connecting External MCP Servers

Hermes Agent implements the Model Context Protocol (MCP) integration pattern by treating external MCP servers as long-running background services that expose their tools as native Hermes tools through a dedicated asyncio-based discovery and registration system.

The MCP integration pattern in Hermes Agent enables seamless extension of agent capabilities by connecting to external MCP servers. According to the NousResearch/hermes-agent source code, this architecture allows developers to integrate both local stdio-based servers and remote HTTP endpoints without modifying the core agent logic.

Understanding the MCP Integration Architecture

Hermes Agent follows a persistent connection pattern where each configured MCP server runs as a background task. The architecture separates transport handling from tool execution, ensuring that network interruptions or server restarts do not crash the main agent process.

The integration relies on three core components: the configuration layer in hermes_cli/config.py, the server management logic in tools/mcp_tool.py, and the tool registration system in tools/registry.py. Together, these components enable automatic discovery, schema conversion, and runtime execution of MCP-exposed functionality.

Configuring MCP Servers in Hermes Agent

Configuration File Structure

MCP servers are defined in the user's ~/.hermes/config.yaml under the mcp_servers key. Each server entry specifies transport parameters, timeouts, and environment variables.

mcp_servers:
  filesystem:
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    env: {}
    timeout: 120
    connect_timeout: 60

  remote_api:
    url: "https://my-mcp.example.com/mcp"
    headers:
      Authorization: "Bearer sk-..."
    timeout: 180

Stdio vs HTTP Transport

Hermes Agent supports two transport mechanisms for MCP integration. Stdio transport launches the server as a local subprocess, suitable for command-line tools like the filesystem server. HTTP transport connects to existing remote services via SSE (Server-Sent Events) endpoints, enabling integration with cloud-hosted MCP providers.

The MCPServerTask class in tools/mcp_tool.py handles transport abstraction, automatically selecting the appropriate client implementation based on the presence of either command (stdio) or url (HTTP) in the configuration.

How Hermes Agent Discovers and Registers MCP Tools

The Discovery Process

Tool discovery initiates when the agent starts or when the user issues the /reload-mcp command. The discover_mcp_tools() function in tools/mcp_tool.py loads the YAML configuration and launches an MCPServerTask for each configured server.


# From tools/mcp_tool.py - conceptual flow

def discover_mcp_tools():
    config = load_mcp_config()
    for server_name, server_config in config.items():
        task = MCPServerTask(server_name, server_config)
        task.start()

MCPServerTask and Connection Management

Each MCPServerTask runs in a dedicated asyncio task within a background daemon thread. The task opens the transport, creates an mcp.ClientSession, runs session.initialize(), and calls session.list_tools() to retrieve available capabilities.

The task implements automatic reconnection with exponential back-off. If the connection drops, the task enters a retry loop, ensuring that temporary network failures do not permanently disable external tools.

Tool Registration and Schema Conversion

For each discovered MCP tool, Hermes Agent converts the MCP schema to the internal Hermes format using _convert_mcp_schema(). The function maps MCP's JSON Schema definitions to Hermes tool parameters and registers the tool with the central registry via registry.register().

Additionally, the system generates four utility tools for every MCP server: list_resources, read_resource, list_prompts, and get_prompt (implemented in _build_utility_schemas). These expose MCP's resource and prompt capabilities as callable Hermes functions.

All MCP tools are grouped into a custom toolset named mcp-<server> and injected into every platform toolset (e.g., hermes-cli, hermes-telegram), making them immediately available in conversations.

Runtime Operations and Tool Execution

Synchronous Wrappers for Async Operations

While MCP operations are asynchronous, Hermes Agent exposes them through synchronous tool handlers to maintain compatibility with the agent's execution loop. The _make_tool_handler() function creates a closure that bridges sync and async contexts.

When a user invokes an MCP tool, the handler calls _run_on_mcp_loop(), which schedules the actual async execution on the background MCP event loop and blocks until completion or timeout.

Timeout Handling and Error Sanitization

Each MCP tool call respects the timeout specified in the configuration (defaulting to 120 seconds). If the server fails to respond, the wrapper raises a timeout exception that the agent can handle gracefully.

Error messages undergo sanitization to prevent credential leakage. The _run_on_mcp_loop() function strips sensitive information from stack traces before returning them to the user interface, ensuring that API keys or tokens defined in headers remain confidential.

Managing MCP Server Lifecycle

Checking Server Status

The get_mcp_status() function in tools/mcp_tool.py provides real-time visibility into MCP server health. It returns a list of status objects containing the server name, transport type, number of discovered tools, and connection state.

from tools.mcp_tool import get_mcp_status

for srv in get_mcp_status():
    print(f"{srv['name']} ({srv['transport']}): "
          f"{srv['tools']} tools – "
          f"{'connected' if srv['connected'] else 'offline'}")

This information powers the agent's startup banner, displaying which external services are available for the current session.

Reloading Servers with /reload-mcp

Hermes Agent supports hot-reloading of MCP configurations without restarting the entire agent. The /reload-mcp slash command, implemented in gateway/run.py, triggers a graceful shutdown of existing MCP connections followed by a fresh discovery cycle.

When executed, the command calls shutdown_mcp_servers() to terminate current tasks, then invokes discover_mcp_tools() to re-read the configuration and establish new connections. This enables dynamic addition or modification of MCP servers during long-running agent sessions.

Graceful Shutdown

When the agent terminates or when reloading configurations, shutdown_mcp_servers() ensures clean disconnection from all MCP services. The function signals each MCPServerTask to exit, closes active client sessions, and stops the background event loop, preventing resource leaks and hanging subprocesses.

Summary

  • Hermes Agent implements the MCP integration pattern by running external servers as persistent background tasks managed by MCPServerTask in tools/mcp_tool.py.
  • Configuration occurs in ~/.hermes/config.yaml under the mcp_servers key, supporting both stdio subprocesses and HTTP/SSE endpoints.
  • Discovery happens via discover_mcp_tools(), which initializes connections, converts MCP schemas using _convert_mcp_schema(), and registers tools with the central registry.
  • Runtime execution uses synchronous wrappers (_make_tool_handler()) that schedule async calls on a dedicated background loop with configurable timeouts and error sanitization.
  • Lifecycle management includes status checking via get_mcp_status(), hot-reloading via the /reload-mcp command in gateway/run.py, and graceful shutdown via shutdown_mcp_servers().

Frequently Asked Questions

What is the MCP integration pattern in Hermes Agent?

The MCP integration pattern in Hermes Agent treats external Model Context Protocol servers as long-running background services that expose their capabilities as native Hermes tools. According to the source code in tools/mcp_tool.py, the pattern involves persistent asyncio tasks (MCPServerTask) that maintain connections, automatically reconnect on failure, and bridge asynchronous MCP operations with the agent's synchronous tool execution loop.

How do I configure an external MCP server in Hermes Agent?

To connect an external MCP server, add an entry to the mcp_servers section of your ~/.hermes/config.yaml file. For local servers, specify the command and args keys to launch a stdio subprocess. For remote services, provide a url key pointing to the HTTP/SSE endpoint. You can also set timeout, connect_timeout, and headers (for HTTP) to control connection behavior and authentication.

What transport protocols does Hermes Agent support for MCP?

Hermes Agent supports two transport mechanisms for MCP integration: stdio and HTTP/SSE. The stdio transport launches the MCP server as a local subprocess, ideal for command-line tools like the filesystem server. The HTTP transport connects to remote servers via Server-Sent Events, suitable for cloud-hosted MCP providers. The MCPServerTask class in tools/mcp_tool.py automatically selects the appropriate client based on whether the configuration contains a command (stdio) or url (HTTP) key.

How can I reload MCP servers without restarting Hermes Agent?

Hermes Agent supports hot-reloading of MCP configurations through the /reload-mcp slash command. When invoked from the chat interface or CLI, the command handler in gateway/run.py calls shutdown_mcp_servers() to gracefully terminate existing connections, then triggers discover_mcp_tools() to re-read the configuration and establish fresh connections. This allows you to add, remove, or modify MCP servers dynamically during long-running agent sessions without losing conversation context.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →