native-mcp
Original:🇺🇸 English
Translated
MCP client: connect servers, register tools (stdio/HTTP).
4installs
Added on
NPX Install
npx skill4agent add nousresearch/hermes-agent native-mcpTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Native MCP Client
Hermes Agent has a built-in MCP client that connects to MCP servers at startup, discovers their tools, and makes them available as first-class tools the agent can call directly. No bridge CLI needed -- tools from MCP servers appear alongside built-in tools like , , etc.
terminalread_fileWhen to Use
Use this whenever you want to:
- Connect to MCP servers and use their tools from within Hermes Agent
- Add external capabilities (filesystem access, GitHub, databases, APIs) via MCP
- Run local stdio-based MCP servers (npx, uvx, or any command)
- Connect to remote HTTP/StreamableHTTP MCP servers
- Have MCP tools auto-discovered and available in every conversation
For ad-hoc, one-off MCP tool calls from the terminal without configuring anything, see the skill instead.
mcporterPrerequisites
- mcp Python package -- optional dependency; install with . If not installed, MCP support is silently disabled.
pip install mcp - Node.js -- required for -based MCP servers (most community servers)
npx - uv -- required for -based MCP servers (Python-based servers)
uvx
Install the MCP SDK:
bash
pip install mcp
# or, if using uv:
uv pip install mcpQuick Start
Add MCP servers to under the key:
~/.hermes/config.yamlmcp_serversyaml
mcp_servers:
time:
command: "uvx"
args: ["mcp-server-time"]Restart Hermes Agent. On startup it will:
- Connect to the server
- Discover available tools
- Register them with the prefix
mcp_time_* - Inject them into all platform toolsets
You can then use the tools naturally -- just ask the agent to get the current time.
Configuration Reference
Each entry under is a server name mapped to its config. There are two transport types: stdio (command-based) and HTTP (url-based).
mcp_serversStdio Transport (command + args)
yaml
mcp_servers:
server_name:
command: "npx" # (required) executable to run
args: ["-y", "pkg-name"] # (optional) command arguments, default: []
env: # (optional) environment variables for the subprocess
SOME_API_KEY: "value"
timeout: 120 # (optional) per-tool-call timeout in seconds, default: 120
connect_timeout: 60 # (optional) initial connection timeout in seconds, default: 60HTTP Transport (url)
yaml
mcp_servers:
server_name:
url: "https://my-server.example.com/mcp" # (required) server URL
headers: # (optional) HTTP headers
Authorization: "Bearer sk-..."
timeout: 180 # (optional) per-tool-call timeout in seconds, default: 120
connect_timeout: 60 # (optional) initial connection timeout in seconds, default: 60All Config Options
| Option | Type | Default | Description |
|---|---|---|---|
| string | -- | Executable to run (stdio transport, required) |
| list | | Arguments passed to the command |
| dict | | Extra environment variables for the subprocess |
| string | -- | Server URL (HTTP transport, required) |
| dict | | HTTP headers sent with every request |
| int | | Per-tool-call timeout in seconds |
| int | | Timeout for initial connection and discovery |
Note: A server config must have either (stdio) or (HTTP), not both.
commandurlHow It Works
Startup Discovery
When Hermes Agent starts, is called during tool initialization:
discover_mcp_tools()- Reads from
mcp_servers~/.hermes/config.yaml - For each server, spawns a connection in a dedicated background event loop
- Initializes the MCP session and calls to discover available tools
list_tools() - Registers each tool in the Hermes tool registry
Tool Naming Convention
MCP tools are registered with the naming pattern:
mcp_{server_name}_{tool_name}Hyphens and dots in names are replaced with underscores for LLM API compatibility.
Examples:
- Server , tool
filesystem→read_filemcp_filesystem_read_file - Server , tool
github→list-issuesmcp_github_list_issues - Server , tool
my-api→fetch.datamcp_my_api_fetch_data
Auto-Injection
After discovery, MCP tools are automatically injected into all platform toolsets (CLI, Discord, Telegram, etc.). This means MCP tools are available in every conversation without any additional configuration.
hermes-*Connection Lifecycle
- Each server runs as a long-lived asyncio Task in a background daemon thread
- Connections persist for the lifetime of the agent process
- If a connection drops, automatic reconnection with exponential backoff kicks in (up to 5 retries, max 60s backoff)
- On agent shutdown, all connections are gracefully closed
Idempotency
discover_mcp_tools()Transport Types
Stdio Transport
The most common transport. Hermes launches the MCP server as a subprocess and communicates over stdin/stdout.
yaml
mcp_servers:
filesystem:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]The subprocess inherits a filtered environment (see Security section below) plus any variables you specify in .
envHTTP / StreamableHTTP Transport
For remote or shared MCP servers. Requires the package to include HTTP client support ().
mcpmcp.client.streamable_httpyaml
mcp_servers:
remote_api:
url: "https://mcp.example.com/mcp"
headers:
Authorization: "Bearer sk-..."If HTTP support is not available in your installed version, the server will fail with an ImportError and other servers will continue normally.
mcpSecurity
Environment Variable Filtering
For stdio servers, Hermes does NOT pass your full shell environment to MCP subprocesses. Only safe baseline variables are inherited:
- ,
PATH,HOME,USER,LANG,LC_ALL,TERM,SHELLTMPDIR - Any variables
XDG_*
All other environment variables (API keys, tokens, secrets) are excluded unless you explicitly add them via the config key. This prevents accidental credential leakage to untrusted MCP servers.
envyaml
mcp_servers:
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
# Only this token is passed to the subprocess
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_..."Credential Stripping in Error Messages
If an MCP tool call fails, any credential-like patterns in the error message are automatically redacted before being shown to the LLM. This covers:
- GitHub PATs ()
ghp_... - OpenAI-style keys ()
sk-... - Bearer tokens
- Generic ,
token=,key=,API_KEY=,password=patternssecret=
Troubleshooting
"MCP SDK not available -- skipping MCP tool discovery"
The Python package is not installed. Install it:
mcpbash
pip install mcp"No MCP servers configured"
No key in , or it's empty. Add at least one server.
mcp_servers~/.hermes/config.yaml"Failed to connect to MCP server 'X'"
Common causes:
- Command not found: The binary isn't on PATH. Ensure
command,npx, or the relevant command is installed.uvx - Package not found: For npx servers, the npm package may not exist or may need in args to auto-install.
-y - Timeout: The server took too long to start. Increase .
connect_timeout - Port conflict: For HTTP servers, the URL may be unreachable.
"MCP server 'X' requires HTTP transport but mcp.client.streamable_http is not available"
Your package version doesn't include HTTP client support. Upgrade:
mcpbash
pip install --upgrade mcpTools not appearing
- Check that the server is listed under (not
mcp_serversormcp)servers - Ensure the YAML indentation is correct
- Look at Hermes Agent startup logs for connection messages
- Tool names are prefixed with -- look for that pattern
mcp_{server}_{tool}
Connection keeps dropping
The client retries up to 5 times with exponential backoff (1s, 2s, 4s, 8s, 16s, capped at 60s). If the server is fundamentally unreachable, it gives up after 5 attempts. Check the server process and network connectivity.
Examples
Time Server (uvx)
yaml
mcp_servers:
time:
command: "uvx"
args: ["mcp-server-time"]Registers tools like .
mcp_time_get_current_timeFilesystem Server (npx)
yaml
mcp_servers:
filesystem:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"]
timeout: 30Registers tools like , , .
mcp_filesystem_read_filemcp_filesystem_write_filemcp_filesystem_list_directoryGitHub Server with Authentication
yaml
mcp_servers:
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxxxxxxxxxx"
timeout: 60Registers tools like , , etc.
mcp_github_list_issuesmcp_github_create_pull_requestRemote HTTP Server
yaml
mcp_servers:
company_api:
url: "https://mcp.mycompany.com/v1/mcp"
headers:
Authorization: "Bearer sk-xxxxxxxxxxxxxxxxxxxx"
X-Team-Id: "engineering"
timeout: 180
connect_timeout: 30Multiple Servers
yaml
mcp_servers:
time:
command: "uvx"
args: ["mcp-server-time"]
filesystem:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxxxxxxxxxx"
company_api:
url: "https://mcp.internal.company.com/mcp"
headers:
Authorization: "Bearer sk-xxxxxxxxxxxxxxxxxxxx"
timeout: 300All tools from all servers are registered and available simultaneously. Each server's tools are prefixed with its name to avoid collisions.
Sampling (Server-Initiated LLM Requests)
Hermes supports MCP's capability — MCP servers can request LLM completions through the agent during tool execution. This enables agent-in-the-loop workflows (data analysis, content generation, decision-making).
sampling/createMessageSampling is enabled by default. Configure per server:
yaml
mcp_servers:
my_server:
command: "npx"
args: ["-y", "my-mcp-server"]
sampling:
enabled: true # default: true
model: "gemini-3-flash" # model override (optional)
max_tokens_cap: 4096 # max tokens per request
timeout: 30 # LLM call timeout (seconds)
max_rpm: 10 # max requests per minute
allowed_models: [] # model whitelist (empty = all)
max_tool_rounds: 5 # tool loop limit (0 = disable)
log_level: "info" # audit verbosityServers can also include in sampling requests for multi-turn tool-augmented workflows. The config prevents infinite tool loops. Per-server audit metrics (requests, errors, tokens, tool use count) are tracked via .
toolsmax_tool_roundsget_mcp_status()Disable sampling for untrusted servers with .
sampling: { enabled: false }Notes
- MCP tools are called synchronously from the agent's perspective but run asynchronously on a dedicated background event loop
- Tool results are returned as JSON with either or
{"result": "..."}{"error": "..."} - The native MCP client is independent of -- you can use both simultaneously
mcporter - Server connections are persistent and shared across all conversations in the same agent process
- Adding or removing servers requires restarting the agent (no hot-reload currently)