* docs: deep audit — fix stale config keys, missing commands, and registry drift Cross-checked ~80 high-impact docs pages (getting-started, reference, top-level user-guide, user-guide/features) against the live registries: hermes_cli/commands.py COMMAND_REGISTRY (slash commands) hermes_cli/auth.py PROVIDER_REGISTRY (providers) hermes_cli/config.py DEFAULT_CONFIG (config keys) toolsets.py TOOLSETS (toolsets) tools/registry.py get_all_tool_names() (tools) python -m hermes_cli.main <subcmd> --help (CLI args) reference/ - cli-commands.md: drop duplicate hermes fallback row + duplicate section, add stepfun/lmstudio to --provider enum, expand auth/mcp/curator subcommand lists to match --help output (status/logout/spotify, login, archive/prune/ list-archived). - slash-commands.md: add missing /sessions and /reload-skills entries + correct the cross-platform Notes line. - tools-reference.md: drop bogus '68 tools' headline, drop fictional 'browser-cdp toolset' (these tools live in 'browser' and are runtime-gated), add missing 'kanban' and 'video' toolset sections, fix MCP example to use the real mcp_<server>_<tool> prefix. - toolsets-reference.md: list browser_cdp/browser_dialog inside the 'browser' row, add missing 'kanban' and 'video' toolset rows, drop the stale '38 tools' count for hermes-cli. - profile-commands.md: add missing install/update/info subcommands, document fish completion. - environment-variables.md: dedupe GMI_API_KEY/GMI_BASE_URL rows (kept the one with the correct gmi-serving.com default). - faq.md: Anthropic/Google/OpenAI examples — direct providers exist (not just via OpenRouter), refresh the OpenAI model list. getting-started/ - installation.md: PortableGit (not MinGit) is what the Windows installer fetches; document the 32-bit MinGit fallback. - installation.md / termux.md: installer prefers .[termux-all] then falls back to .[termux]. - nix-setup.md: Python 3.12 (not 3.11), Node.js 22 (not 20); fix invalid 'nix flake update --flake' invocation. - updating.md: 'hermes backup restore --state pre-update' doesn't exist — point at the snapshot/quick-snapshot flow; correct config key 'updates.pre_update_backup' (was 'update.backup'). user-guide/ - configuration.md: api_max_retries default 3 (not 2); display.runtime_footer is the real key (not display.runtime_metadata_footer); checkpoints defaults enabled=false / max_snapshots=20 (not true / 50). - configuring-models.md: 'hermes model list' / 'hermes model set ...' don't exist — hermes model is interactive only. - tui.md: busy_indicator -> tui_status_indicator with values kaomoji|emoji|unicode|ascii (not kawaii|minimal|dots|wings|none). - security.md: SSH backend keys (TERMINAL_SSH_HOST/USER/KEY) live in .env, not config.yaml. - windows-wsl-quickstart.md: there is no 'hermes api' subcommand — the OpenAI-compatible API server runs inside hermes gateway. user-guide/features/ - computer-use.md: approvals.mode (not security.approval_level); fix broken ./browser-use.md link to ./browser.md. - fallback-providers.md: top-level fallback_providers (not model.fallback_providers); the picker is subcommand-based, not modal. - api-server.md: API_SERVER_* are env vars — write to per-profile .env, not 'hermes config set' which targets YAML. - web-search.md: drop web_crawl as a registered tool (it isn't); deep-crawl modes are exposed through web_extract. - kanban.md: failure_limit default is 2, not '~5'. - plugins.md: drop hard-coded '33 providers' count. - honcho.md: fix unclosed quote in echo HONCHO_API_KEY snippet; document that 'hermes honcho' subcommand is gated on memory.provider=honcho; reconcile subcommand list with actual --help output. - memory-providers.md: legacy 'hermes honcho setup' redirect documented. Verified via 'npm run build' — site builds cleanly; broken-link count went from 149 to 146 (no regressions, fixed a few in passing). * docs: round 2 audit fixes + regenerate skill catalogs Follow-up to the previous commit on this branch: Round 2 manual fixes: - quickstart.md: KIMI_CODING_API_KEY mentioned alongside KIMI_API_KEY; voice-mode and ACP install commands rewritten — bare 'pip install ...' doesn't work for curl-installed setups (no pip on PATH, not in repo dir); replaced with 'cd ~/.hermes/hermes-agent && uv pip install -e ".[voice]"'. ACP already ships in [all] so the curl install includes it. - cli.md / configuration.md: 'auxiliary.compression.model' shown as 'google/gemini-3-flash-preview' (the doc's own claimed default); actual default is empty (= use main model). Reworded as 'leave empty (default) or pin a cheap model'. - built-in-plugins.md: added the bundled 'kanban/dashboard' plugin row that was missing from the table. Regenerated skill catalogs: - ran website/scripts/generate-skill-docs.py to refresh all 163 per-skill pages and both reference catalogs (skills-catalog.md, optional-skills-catalog.md). This adds the entries that were genuinely missing — productivity/teams-meeting-pipeline (bundled), optional/finance/* (entire category — 7 skills: 3-statement-model, comps-analysis, dcf-model, excel-author, lbo-model, merger-model, pptx-author), creative/hyperframes, creative/kanban-video-orchestrator, devops/watchers, productivity/shop-app, research/searxng-search, apple/macos-computer-use — and rewrites every other per-skill page from the current SKILL.md. Most diffs are tiny (one line of refreshed metadata). Validation: - 'npm run build' succeeded. - Broken-link count moved 146 -> 155 — the +9 are zh-Hans translation shells that lag every newly-added skill page (pre-existing pattern). No regressions on any en/ page.
376 lines
13 KiB
Markdown
376 lines
13 KiB
Markdown
---
|
|
title: "Native Mcp — MCP client: connect servers, register tools (stdio/HTTP)"
|
|
sidebar_label: "Native Mcp"
|
|
description: "MCP client: connect servers, register tools (stdio/HTTP)"
|
|
---
|
|
|
|
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
|
|
|
|
# Native Mcp
|
|
|
|
MCP client: connect servers, register tools (stdio/HTTP).
|
|
|
|
## Skill metadata
|
|
|
|
| | |
|
|
|---|---|
|
|
| Source | Bundled (installed by default) |
|
|
| Path | `skills/mcp/native-mcp` |
|
|
| Version | `1.0.0` |
|
|
| Author | Hermes Agent |
|
|
| License | MIT |
|
|
| Platforms | linux, macos, windows |
|
|
| Tags | `MCP`, `Tools`, `Integrations` |
|
|
| Related skills | [`mcporter`](/docs/user-guide/skills/optional/mcp/mcp-mcporter) |
|
|
|
|
## Reference: full SKILL.md
|
|
|
|
:::info
|
|
The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active.
|
|
:::
|
|
|
|
# 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 `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:
|
|
|
|
```bash
|
|
pip install mcp
|
|
# or, if using uv:
|
|
uv pip install mcp
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
Add MCP servers to `~/.hermes/config.yaml` under the `mcp_servers` key:
|
|
|
|
```yaml
|
|
mcp_servers:
|
|
time:
|
|
command: "uvx"
|
|
args: ["mcp-server-time"]
|
|
```
|
|
|
|
Restart Hermes Agent. On startup it will:
|
|
1. Connect to the server
|
|
2. Discover available tools
|
|
3. Register them with the prefix `mcp_time_*`
|
|
4. 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)
|
|
|
|
```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: 60
|
|
```
|
|
|
|
### HTTP 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: 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:
|
|
|
|
1. Reads `mcp_servers` from `~/.hermes/config.yaml`
|
|
2. For each server, spawns a connection in a dedicated background event loop
|
|
3. Initializes the MCP session and calls `list_tools()` to discover available tools
|
|
4. 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.
|
|
|
|
```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 `env`.
|
|
|
|
### HTTP / StreamableHTTP Transport
|
|
|
|
For remote or shared MCP servers. Requires the `mcp` package to include HTTP client support (`mcp.client.streamable_http`).
|
|
|
|
```yaml
|
|
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.
|
|
|
|
```yaml
|
|
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=`, `secret=` patterns
|
|
|
|
## Troubleshooting
|
|
|
|
### "MCP SDK not available -- skipping MCP tool discovery"
|
|
|
|
The `mcp` Python package is not installed. Install it:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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)
|
|
|
|
```yaml
|
|
mcp_servers:
|
|
time:
|
|
command: "uvx"
|
|
args: ["mcp-server-time"]
|
|
```
|
|
|
|
Registers tools like `mcp_time_get_current_time`.
|
|
|
|
### Filesystem Server (npx)
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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
|
|
|
|
```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: 30
|
|
```
|
|
|
|
### Multiple 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: 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:
|
|
|
|
```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 verbosity
|
|
```
|
|
|
|
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)
|