| name | native-mcp |
| title | MCP Tooling — Native Hermes Client + mcporter + AIP Docs MCP Server |
| description | Complete guide to MCP in Hermes: the built-in native MCP client (config, transport types, security, troubleshooting), the mcporter CLI for ad-hoc server calls, and the AIP docs MCP server for library documentation search. |
| author | Hermes Agent |
| date | 2026-04-30T00:00:00.000Z |
| tags | ["mcp","mcporter","aip-docs","tools","integrations","stdio","http"] |
MCP Tooling — Native Client + mcporter + AIP Docs Server
This umbrella covers all three MCP-related skills in the library.
Part 1: Native Hermes MCP Client (built-in)
Hermes 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.
When to Use
- 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
For ad-hoc, one-off MCP tool calls from the terminal without configuring anything,
see the mcporter section below.
Prerequisites
- mcp Python package -- optional dependency; install with
pip install mcp
- Node.js -- required for
npx-based MCP servers
- uv -- required for
uvx-based MCP servers
Configuration Reference
Add MCP servers to ~/.hermes/config.yaml under the mcp_servers key:
mcp_servers:
time:
command: "uvx"
args: ["mcp-server-time"]
filesystem:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"]
company_api:
url: "https://mcp.mycompany.com/v1/mcp"
headers:
Authorization: "Bearer sk-..."
Config options: command (stdio, required), args, env, url (HTTP, required),
headers, timeout (default 120s), connect_timeout (default 60s).
How It Works
- On startup, reads
mcp_servers from config
- For each server, spawns a connection in a dedicated background event loop
- Initializes the MCP session and calls
list_tools() to discover tools
- Registers each tool with prefix
mcp_{server_name}_{tool_name}
- Auto-injects into all platform toolsets
Security
- Environment variable filtering: Only safe baseline variables are inherited
by stdio servers. Sensitive vars must be explicitly added via
env: config.
- Credential stripping: Error messages automatically redact API keys and tokens.
Troubleshooting
| Symptom | Fix |
|---|
| "MCP SDK not available" | pip install mcp |
| "No MCP servers configured" | Add mcp_servers key to config |
| Failed to connect to server | Check command/path, increase timeouts |
| Tools not appearing | Check mcp_servers indentation; look for mcp_{server}_ prefix |
| Connection keeps dropping | Server fundamentally unreachable; check network |
| TLS errors | Use custom CA bundle via NODE_EXTRA_CA_CERTS |
Manual curl testing
curl -s -X POST https://<host>/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}'
Critical: Many HTTP MCP servers require BOTH application/json AND text/event-stream
in the Accept header. Without the SSE portion, the server returns 406.
Part 2: mcporter CLI
Use mcporter to discover, call, and manage MCP servers directly from the terminal.
Auto-discovers servers configured by other MCP clients on the machine.
mcporter list
mcporter call <server.tool> key=value --output json
mcporter list --http-url https://some-server.com --name my_server
mcporter call my_server.tool arg=value --output json
mcporter list --stdio "npx -y @mcp/server" --name fs
Key flags: --output json for structured output, --app for multi-account servers.
Part 3: AIP Documentation MCP Server
Access the AIP docs MCP server at https://docs-mcp-server.kube.aip.de for searching
library documentation (reana, pandas, snakemake, dask, unsloth, etc.).
Configure in ~/.hermes/config.yaml:
mcp_servers:
docs:
url: https://docs-mcp-server.kube.aip.de/mcp
Typical MCP calls: mcp_docs_list_libraries, mcp_docs_find_version,
mcp_docs_search_docs, mcp_docs_fetch_url.
TLS fix for missing intermediate chain: Set REQUESTS_CA_BUNDLE and
NODE_EXTRA_CA_CERTS to point at /home/$USER/.hermes/certs/custom-ca-bundle.pem.
Routing to companion skills
- Python code from these docs → load
python-mcp-docs-first
- Dask-specific → load
dask-mcp-docs-first
- pandas + Datashader plotting → load
pandas-datashader-mcp-docs-first
Part 4: Indexing Docs (mcp_docs_scrape_docs)
Use mcp_docs_scrape_docs to index external documentation sites into the AIP docs MCP server:
mcp_docs_scrape_docs(
library="My Library Name",
url="https://docs.example.com/",
scope="subpages", # NOT "hostname" — too broad
maxDepth=3, # 2 small, 3 medium, 4+ only if needed
maxPages=100 # Start conservative
)
Monitor: mcp_docs_list_jobs every 30-60s. Jobs take 5-15 min typically.
When NOT to use: Sites with Jupyter notebooks, interactive content, >300 pages,
or behind auth/paywalls. Use a local reference file instead.
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 terminal, read_file, etc.
When 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 mcporter skill instead.
Prerequisites
- mcp Python package -- optional dependency; install with
pip install mcp. If not installed, MCP support is silently disabled.
- Node.js -- required for
npx-based MCP servers (most community servers)
- uv -- required for
uvx-based MCP servers (Python-based servers)
Install the MCP SDK:
pip install mcp
uv pip install mcp
Quick Start
Add MCP servers to ~/.hermes/config.yaml under the mcp_servers key:
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 mcp_servers is a server name mapped to its config. There are two transport types: stdio (command-based) and HTTP (url-based).
Stdio Transport (command + args)
mcp_servers:
server_name:
command: "npx"
args: ["-y", "pkg-name"]
env:
SOME_API_KEY: "value"
timeout: 120
connect_timeout: 60
HTTP Transport (url)
mcp_servers:
server_name:
url: "https://my-server.example.com/mcp"
headers:
Authorization: "Bearer sk-..."
timeout: 180
connect_timeout: 60
All Config Options
| Option | Type | Default | Description |
|---|
command | string | -- | Executable to run (stdio transport, required) |
args | list | [] | Arguments passed to the command |
env | dict | {} | Extra environment variables for the subprocess |
url | string | -- | Server URL (HTTP transport, required) |
headers | dict | {} | HTTP headers sent with every request |
timeout | int | 120 | Per-tool-call timeout in seconds |
connect_timeout | int | 60 | Timeout for initial connection and discovery |
Note: A server config must have either command (stdio) or url (HTTP), not both.
How It Works
Startup Discovery
When Hermes Agent starts, discover_mcp_tools() is called during tool initialization:
- Reads
mcp_servers from ~/.hermes/config.yaml
- For each server, spawns a connection in a dedicated background event loop
- Initializes the MCP session and calls
list_tools() to discover available 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
filesystem, tool read_file → mcp_filesystem_read_file
- Server
github, tool list-issues → mcp_github_list_issues
- Server
my-api, tool fetch.data → mcp_my_api_fetch_data
Auto-Injection
After discovery, MCP tools are automatically injected into all hermes-* platform toolsets (CLI, Discord, Telegram, etc.). This means MCP tools are available in every conversation without any additional configuration.
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() is idempotent -- calling it multiple times only connects to servers that aren't already connected. Failed servers are retried on subsequent calls.
Transport Types
Stdio Transport
The most common transport. Hermes launches the MCP server as a subprocess and communicates over stdin/stdout.
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 env.
HTTP / StreamableHTTP Transport
For remote or shared MCP servers. Requires the mcp package to include HTTP client support (mcp.client.streamable_http).
mcp_servers:
remote_api:
url: "https://mcp.example.com/mcp"
headers:
Authorization: "Bearer sk-..."
If HTTP support is not available in your installed mcp version, the server will fail with an ImportError and other servers will continue normally.
Security
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, SHELL, TMPDIR
- Any
XDG_* variables
All other environment variables (API keys, tokens, secrets) are excluded unless you explicitly add them via the env config key. This prevents accidental credential leakage to untrusted MCP servers.
mcp_servers:
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
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=, secret= patterns
Manual Connection Testing
Before configuring a server in Hermes, test it manually to diagnose connectivity, TLS, and protocol issues.
Step-by-step curl testing
curl -v https://<server-host>/mcp --max-time 10 2>&1 | grep -E "(SSL|certificate|verify|TLS)"
curl -s -X POST https://<server-host>/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0.1.0"}}}'
curl -s -X POST https://<server-host>/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
curl -s -X POST https://<server-host>/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"<tool_name>","arguments":{}}}'
SSE Accept Header Requirement
Critical pitfall: Many HTTP MCP servers require BOTH application/json AND text/event-stream in the Accept header. Without the SSE portion, the server returns:
{"error":{"code":-32000,"message":"Not Acceptable: Client must accept both application/json and text/event-stream"}}
This error is common with servers that use SSE transport (Langfuse MCP, AIP docs MCP, etc.). The Hermes native MCP client handles this automatically — but manual testing with curl will fail without it.
Common error codes
| Code | Meaning | Fix |
|---|
| Connection refused / timeout | Server not running or unreachable | Check host/port, network, firewall |
| SSL certificate verify error | Missing CA cert for self-hosted server | Verify with custom-ca-bundle.pem or use curl -k for testing |
| 406 Not Acceptable | Missing SSE Accept header | Add -H "Accept: application/json, text/event-stream" |
| Empty response to GET | Server expects POST with JSON-RPC | Use POST with initialize payload |
| JSON parse error | Server returned non-JSON | Server may not be an MCP server at this URL |
When Hermes native MCP fails to connect but curl works
The Hermes client may have different timeout values or TLS behavior than curl:
- Increase
connect_timeout (default 60s) in server config
- Verify the
mcp Python package includes HTTP support: pip show mcp should list streamable_http
- Check startup logs:
grep -i mcp ~/.hermes/logs/gateway.log
Troubleshooting
"MCP SDK not available -- skipping MCP tool discovery"
The mcp Python package is not installed. Install it:
pip install mcp
"No MCP servers configured"
No mcp_servers key in ~/.hermes/config.yaml, or it's empty. Add at least one server.
"Failed to connect to MCP server 'X'"
Common causes:
- Command not found: The
command binary isn't on PATH. Ensure npx, uvx, or the relevant command is installed.
- Package not found: For npx servers, the npm package may not exist or may need
-y in args to auto-install.
- 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 mcp package version doesn't include HTTP client support. Upgrade:
pip install --upgrade mcp
Tools not appearing
- Check that the server is listed under
mcp_servers (not mcp or servers)
- Ensure the YAML indentation is correct
- Look at Hermes Agent startup logs for connection messages
- Tool names are prefixed with
mcp_{server}_{tool} -- look for that pattern
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)
mcp_servers:
time:
command: "uvx"
args: ["mcp-server-time"]
Registers tools like mcp_time_get_current_time.
Filesystem Server (npx)
mcp_servers:
filesystem:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"]
timeout: 30
Registers tools like mcp_filesystem_read_file, mcp_filesystem_write_file, mcp_filesystem_list_directory.
GitHub Server with Authentication
mcp_servers:
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxxxxxxxxxx"
timeout: 60
Registers tools like mcp_github_list_issues, mcp_github_create_pull_request, etc.
Remote HTTP Server
mcp_servers:
company_api:
url: "https://mcp.mycompany.com/v1/mcp"
headers:
Authorization: "Bearer sk-xxxxxxxxxxxxxxxxxxxx"
X-Team-Id: "engineering"
timeout: 180
connect_timeout: 30
Multiple Servers
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: 300
All 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 sampling/createMessage 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 is enabled by default. Configure per server:
mcp_servers:
my_server:
command: "npx"
args: ["-y", "my-mcp-server"]
sampling:
enabled: true
model: "gemini-3-flash"
max_tokens_cap: 4096
timeout: 30
max_rpm: 10
allowed_models: []
max_tool_rounds: 5
log_level: "info"
Servers can also include tools in sampling requests for multi-turn tool-augmented workflows. The max_tool_rounds config prevents infinite tool loops. Per-server audit metrics (requests, errors, tokens, tool use count) are tracked via get_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
{"result": "..."} or {"error": "..."}
- The native MCP client is independent of
mcporter -- you can use both simultaneously
- 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)