From 67e80def53b57cddc2efc37949830659cbfc71e3 Mon Sep 17 00:00:00 2001 From: teknium1 Date: Sat, 14 Mar 2026 06:36:01 -0700 Subject: [PATCH] docs(mcp): add comprehensive Hermes MCP docs Expand the MCP feature docs with filtering and capability-aware registration details, add a practical 'Use MCP with Hermes' tutorial, add a config reference page, and wire the new docs into the sidebar and landing page. --- website/docs/guides/use-mcp-with-hermes.md | 410 +++++++++++++ website/docs/index.md | 3 +- website/docs/reference/faq.md | 15 +- .../docs/reference/mcp-config-reference.md | 215 +++++++ website/docs/user-guide/features/mcp.md | 556 ++++++++++-------- website/sidebars.ts | 2 + 6 files changed, 955 insertions(+), 246 deletions(-) create mode 100644 website/docs/guides/use-mcp-with-hermes.md create mode 100644 website/docs/reference/mcp-config-reference.md diff --git a/website/docs/guides/use-mcp-with-hermes.md b/website/docs/guides/use-mcp-with-hermes.md new file mode 100644 index 000000000..e202594d1 --- /dev/null +++ b/website/docs/guides/use-mcp-with-hermes.md @@ -0,0 +1,410 @@ +--- +sidebar_position: 5 +title: "Use MCP with Hermes" +description: "A practical guide to connecting MCP servers to Hermes Agent, filtering their tools, and using them safely in real workflows" +--- + +# Use MCP with Hermes + +This guide shows how to actually use MCP with Hermes Agent in day-to-day workflows. + +If the feature page explains what MCP is, this guide is about how to get value from it quickly and safely. + +## When should you use MCP? + +Use MCP when: +- a tool already exists in MCP form and you do not want to build a native Hermes tool +- you want Hermes to operate against a local or remote system through a clean RPC layer +- you want fine-grained per-server exposure control +- you want to connect Hermes to internal APIs, databases, or company systems without modifying Hermes core + +Do not use MCP when: +- a built-in Hermes tool already solves the job well +- the server exposes a huge dangerous tool surface and you are not prepared to filter it +- you only need one very narrow integration and a native tool would be simpler and safer + +## Mental model + +Think of MCP as an adapter layer: + +- Hermes remains the agent +- MCP servers contribute tools +- Hermes discovers those tools at startup or reload time +- the model can use them like normal tools +- you control how much of each server is visible + +That last part matters. Good MCP usage is not just β€œconnect everything.” It is β€œconnect the right thing, with the smallest useful surface.” + +## Step 1: install MCP support + +```bash +pip install hermes-agent[mcp] +``` + +For npm-based servers, make sure Node.js and `npx` are available. + +For many Python MCP servers, `uvx` is a nice default. + +## Step 2: add one server first + +Start with a single, safe server. + +Example: filesystem access to one project directory only. + +```yaml +mcp_servers: + project_fs: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/my-project"] +``` + +Then start Hermes: + +```bash +hermes chat +``` + +Now ask something concrete: + +```text +Inspect this project and summarize the repo layout. +``` + +## Step 3: verify MCP loaded + +You can verify MCP in a few ways: + +- Hermes banner/status should show MCP integration when configured +- ask Hermes what tools it has available +- use `/reload-mcp` after config changes +- check logs if the server failed to connect + +A practical test prompt: + +```text +Tell me which MCP-backed tools are available right now. +``` + +## Step 4: start filtering immediately + +Do not wait until later if the server exposes a lot of tools. + +### Example: whitelist only what you want + +```yaml +mcp_servers: + github: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-github"] + env: + GITHUB_PERSONAL_ACCESS_TOKEN: "***" + tools: + include: [list_issues, create_issue, search_code] +``` + +This is usually the best default for sensitive systems. + +### Example: blacklist dangerous actions + +```yaml +mcp_servers: + stripe: + url: "https://mcp.stripe.com" + headers: + Authorization: "Bearer ***" + tools: + exclude: [delete_customer, refund_payment] +``` + +### Example: disable utility wrappers too + +```yaml +mcp_servers: + docs: + url: "https://mcp.docs.example.com" + tools: + prompts: false + resources: false +``` + +## What does filtering actually affect? + +There are two categories of MCP-exposed functionality in Hermes: + +1. Server-native MCP tools +- filtered with: + - `tools.include` + - `tools.exclude` + +2. Hermes-added utility wrappers +- filtered with: + - `tools.resources` + - `tools.prompts` + +### Utility wrappers you may see + +Resources: +- `list_resources` +- `read_resource` + +Prompts: +- `list_prompts` +- `get_prompt` + +These wrappers only appear if: +- your config allows them, and +- the MCP server session actually supports those capabilities + +So Hermes will not pretend a server has resources/prompts if it does not. + +## Common patterns + +### Pattern 1: local project assistant + +Use MCP for a repo-local filesystem or git server when you want Hermes to reason over a bounded workspace. + +```yaml +mcp_servers: + fs: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/project"] + + git: + command: "uvx" + args: ["mcp-server-git", "--repository", "/home/user/project"] +``` + +Good prompts: + +```text +Review the project structure and identify where configuration lives. +``` + +```text +Check the local git state and summarize what changed recently. +``` + +### Pattern 2: GitHub triage assistant + +```yaml +mcp_servers: + github: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-github"] + env: + GITHUB_PERSONAL_ACCESS_TOKEN: "***" + tools: + include: [list_issues, create_issue, update_issue, search_code] + prompts: false + resources: false +``` + +Good prompts: + +```text +List open issues about MCP, cluster them by theme, and draft a high-quality issue for the most common bug. +``` + +```text +Search the repo for uses of _discover_and_register_server and explain how MCP tools are registered. +``` + +### Pattern 3: internal API assistant + +```yaml +mcp_servers: + internal_api: + url: "https://mcp.internal.example.com" + headers: + Authorization: "Bearer ***" + tools: + include: [list_customers, get_customer, list_invoices] + resources: false + prompts: false +``` + +Good prompts: + +```text +Look up customer ACME Corp and summarize recent invoice activity. +``` + +This is the sort of place where a strict whitelist is far better than an exclude list. + +### Pattern 4: documentation / knowledge servers + +Some MCP servers expose prompts or resources that are more like shared knowledge assets than direct actions. + +```yaml +mcp_servers: + docs: + url: "https://mcp.docs.example.com" + tools: + prompts: true + resources: true +``` + +Good prompts: + +```text +List available MCP resources from the docs server, then read the onboarding guide and summarize it. +``` + +```text +List prompts exposed by the docs server and tell me which ones would help with incident response. +``` + +## Tutorial: end-to-end setup with filtering + +Here is a practical progression. + +### Phase 1: add GitHub MCP with a tight whitelist + +```yaml +mcp_servers: + github: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-github"] + env: + GITHUB_PERSONAL_ACCESS_TOKEN: "***" + tools: + include: [list_issues, create_issue, search_code] + prompts: false + resources: false +``` + +Start Hermes and ask: + +```text +Search the codebase for references to MCP and summarize the main integration points. +``` + +### Phase 2: expand only when needed + +If you later need issue updates too: + +```yaml +tools: + include: [list_issues, create_issue, update_issue, search_code] +``` + +Then reload: + +```text +/reload-mcp +``` + +### Phase 3: add a second server with different policy + +```yaml +mcp_servers: + github: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-github"] + env: + GITHUB_PERSONAL_ACCESS_TOKEN: "***" + tools: + include: [list_issues, create_issue, update_issue, search_code] + prompts: false + resources: false + + filesystem: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/project"] +``` + +Now Hermes can combine them: + +```text +Inspect the local project files, then create a GitHub issue summarizing the bug you find. +``` + +That is where MCP gets powerful: multi-system workflows without changing Hermes core. + +## Safe usage recommendations + +### Prefer allowlists for dangerous systems + +For anything financial, customer-facing, or destructive: +- use `tools.include` +- start with the smallest set possible + +### Disable unused utilities + +If you do not want the model browsing server-provided resources/prompts, turn them off: + +```yaml +tools: + resources: false + prompts: false +``` + +### Keep servers scoped narrowly + +Examples: +- filesystem server rooted to one project dir, not your whole home directory +- git server pointed at one repo +- internal API server with read-heavy tool exposure by default + +### Reload after config changes + +```text +/reload-mcp +``` + +Do this after changing: +- include/exclude lists +- enabled flags +- resources/prompts toggles +- auth headers / env + +## Troubleshooting by symptom + +### "The server connects but the tools I expected are missing" + +Possible causes: +- filtered by `tools.include` +- excluded by `tools.exclude` +- utility wrappers disabled via `resources: false` or `prompts: false` +- server does not actually support resources/prompts + +### "The server is configured but nothing loads" + +Check: +- `enabled: false` was not left in config +- command/runtime exists (`npx`, `uvx`, etc.) +- HTTP endpoint is reachable +- auth env or headers are correct + +### "Why do I see fewer tools than the MCP server advertises?" + +Because Hermes now respects your per-server policy and capability-aware registration. That is expected, and usually desirable. + +### "How do I remove an MCP server without deleting the config?" + +Use: + +```yaml +enabled: false +``` + +That keeps the config around but prevents connection and registration. + +## Recommended first MCP setups + +Good first servers for most users: +- filesystem +- git +- GitHub +- fetch / documentation MCP servers +- one narrow internal API + +Not-great first servers: +- giant business systems with lots of destructive actions and no filtering +- anything you do not understand well enough to constrain + +## Related docs + +- [MCP (Model Context Protocol)](/docs/user-guide/features/mcp) +- [FAQ](/docs/reference/faq) +- [Slash Commands](/docs/reference/slash-commands) diff --git a/website/docs/index.md b/website/docs/index.md index a4ea0a8e3..0e33c9dc3 100644 --- a/website/docs/index.md +++ b/website/docs/index.md @@ -31,7 +31,8 @@ It's not a coding copilot tethered to an IDE or a chatbot wrapper around a singl | πŸ”§ **[Tools & Toolsets](/docs/user-guide/features/tools)** | 40+ built-in tools and how to configure them | | 🧠 **[Memory System](/docs/user-guide/features/memory)** | Persistent memory that grows across sessions | | πŸ“š **[Skills System](/docs/user-guide/features/skills)** | Procedural memory the agent creates and reuses | -| πŸ”Œ **[MCP Integration](/docs/user-guide/features/mcp)** | Connect to any MCP server for extended capabilities | +| πŸ”Œ **[MCP Integration](/docs/user-guide/features/mcp)** | Connect to MCP servers, filter their tools, and extend Hermes safely | +| 🧭 **[Use MCP with Hermes](/docs/guides/use-mcp-with-hermes)** | Practical MCP setup patterns, examples, and tutorials | | πŸ“„ **[Context Files](/docs/user-guide/features/context-files)** | Project context files that shape every conversation | | πŸ”’ **[Security](/docs/user-guide/security)** | Command approval, authorization, container isolation | | πŸ’‘ **[Tips & Best Practices](/docs/guides/tips)** | Quick wins to get the most out of Hermes | diff --git a/website/docs/reference/faq.md b/website/docs/reference/faq.md index 88e5210a2..02a82dce7 100644 --- a/website/docs/reference/faq.md +++ b/website/docs/reference/faq.md @@ -391,21 +391,28 @@ mcp_servers: #### Tools not showing up from MCP server -**Cause:** Server started but tool discovery failed, or tools are filtered out. +**Cause:** Server started but tool discovery failed, tools were filtered out by config, or the server does not support the MCP capability you expected. **Solution:** - Check gateway/agent logs for MCP connection errors - Ensure the server responds to the `tools/list` RPC method -- Restart the agent β€” MCP tools are discovered at startup +- Review any `tools.include`, `tools.exclude`, `tools.resources`, `tools.prompts`, or `enabled` settings under that server +- Remember that resource/prompt utility tools are only registered when the session actually supports those capabilities +- Use `/reload-mcp` after changing config ```bash # Verify MCP servers are configured -hermes config show | grep -A 5 mcp_servers +hermes config show | grep -A 12 mcp_servers -# Restart hermes to re-discover tools +# Restart Hermes or reload MCP after config changes hermes chat ``` +See also: +- [MCP (Model Context Protocol)](/docs/user-guide/features/mcp) +- [Use MCP with Hermes](/docs/guides/use-mcp-with-hermes) +- [MCP Config Reference](/docs/reference/mcp-config-reference) + #### MCP timeout errors **Cause:** The MCP server is taking too long to respond, or it crashed during execution. diff --git a/website/docs/reference/mcp-config-reference.md b/website/docs/reference/mcp-config-reference.md new file mode 100644 index 000000000..5f78185b9 --- /dev/null +++ b/website/docs/reference/mcp-config-reference.md @@ -0,0 +1,215 @@ +--- +sidebar_position: 8 +title: "MCP Config Reference" +description: "Reference for Hermes Agent MCP configuration keys, filtering semantics, and utility-tool policy" +--- + +# MCP Config Reference + +This page is the compact reference companion to the main MCP docs. + +For conceptual guidance, see: +- [MCP (Model Context Protocol)](/docs/user-guide/features/mcp) +- [Use MCP with Hermes](/docs/guides/use-mcp-with-hermes) + +## Root config shape + +```yaml +mcp_servers: + : + command: "..." # stdio servers + args: [] + env: {} + + # OR + url: "..." # HTTP servers + headers: {} + + enabled: true + timeout: 120 + connect_timeout: 60 + tools: + include: [] + exclude: [] + resources: true + prompts: true +``` + +## Server keys + +| Key | Type | Applies to | Meaning | +|---|---|---|---| +| `command` | string | stdio | Executable to launch | +| `args` | list | stdio | Arguments for the subprocess | +| `env` | mapping | stdio | Environment passed to the subprocess | +| `url` | string | HTTP | Remote MCP endpoint | +| `headers` | mapping | HTTP | Headers for remote server requests | +| `enabled` | bool | both | Skip the server entirely when false | +| `timeout` | number | both | Tool call timeout | +| `connect_timeout` | number | both | Initial connection timeout | +| `tools` | mapping | both | Filtering and utility-tool policy | + +## `tools` policy keys + +| Key | Type | Meaning | +|---|---|---| +| `include` | string or list | Whitelist server-native MCP tools | +| `exclude` | string or list | Blacklist server-native MCP tools | +| `resources` | bool-like | Enable/disable `list_resources` + `read_resource` | +| `prompts` | bool-like | Enable/disable `list_prompts` + `get_prompt` | + +## Filtering semantics + +### `include` + +If `include` is set, only those server-native MCP tools are registered. + +```yaml +tools: + include: [create_issue, list_issues] +``` + +### `exclude` + +If `exclude` is set and `include` is not, every server-native MCP tool except those names is registered. + +```yaml +tools: + exclude: [delete_customer] +``` + +### Precedence + +If both are set, `include` wins. + +```yaml +tools: + include: [create_issue] + exclude: [create_issue, delete_issue] +``` + +Result: +- `create_issue` is still allowed +- `delete_issue` is ignored because `include` takes precedence + +## Utility-tool policy + +Hermes may register these utility wrappers per MCP server: + +Resources: +- `list_resources` +- `read_resource` + +Prompts: +- `list_prompts` +- `get_prompt` + +### Disable resources + +```yaml +tools: + resources: false +``` + +### Disable prompts + +```yaml +tools: + prompts: false +``` + +### Capability-aware registration + +Even when `resources: true` or `prompts: true`, Hermes only registers those utility tools if the MCP session actually exposes the corresponding capability. + +So this is normal: +- you enable prompts +- but no prompt utilities appear +- because the server does not support prompts + +## `enabled: false` + +```yaml +mcp_servers: + legacy: + url: "https://mcp.legacy.internal" + enabled: false +``` + +Behavior: +- no connection attempt +- no discovery +- no tool registration +- config remains in place for later reuse + +## Empty result behavior + +If filtering removes all server-native tools and no utility tools are registered, Hermes does not create an empty MCP runtime toolset for that server. + +## Example configs + +### Safe GitHub allowlist + +```yaml +mcp_servers: + github: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-github"] + env: + GITHUB_PERSONAL_ACCESS_TOKEN: "***" + tools: + include: [list_issues, create_issue, update_issue, search_code] + resources: false + prompts: false +``` + +### Stripe blacklist + +```yaml +mcp_servers: + stripe: + url: "https://mcp.stripe.com" + headers: + Authorization: "Bearer ***" + tools: + exclude: [delete_customer, refund_payment] +``` + +### Resource-only docs server + +```yaml +mcp_servers: + docs: + url: "https://mcp.docs.example.com" + tools: + include: [] + resources: true + prompts: false +``` + +## Reloading config + +After changing MCP config, reload servers with: + +```text +/reload-mcp +``` + +## Tool naming + +Server-native MCP tools become: + +```text +mcp__ +``` + +Examples: +- `mcp_github_create_issue` +- `mcp_filesystem_read_file` +- `mcp_my_api_query_data` + +Utility tools follow the same prefixing pattern: +- `mcp__list_resources` +- `mcp__read_resource` +- `mcp__list_prompts` +- `mcp__get_prompt` diff --git a/website/docs/user-guide/features/mcp.md b/website/docs/user-guide/features/mcp.md index d1caeb065..5009fab70 100644 --- a/website/docs/user-guide/features/mcp.md +++ b/website/docs/user-guide/features/mcp.md @@ -1,334 +1,408 @@ --- sidebar_position: 4 title: "MCP (Model Context Protocol)" -description: "Connect Hermes Agent to external tool servers via MCP β€” databases, APIs, filesystems, and more" +description: "Connect Hermes Agent to external tool servers via MCP β€” and control exactly which MCP tools Hermes loads" --- # MCP (Model Context Protocol) -MCP lets Hermes Agent connect to external tool servers β€” giving the agent access to databases, APIs, filesystems, and more without any code changes. +MCP lets Hermes Agent connect to external tool servers so the agent can use tools that live outside Hermes itself β€” GitHub, databases, file systems, browser stacks, internal APIs, and more. -## Overview +If you have ever wanted Hermes to use a tool that already exists somewhere else, MCP is usually the cleanest way to do it. -The [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) is an open standard for connecting AI agents to external tools and data sources. MCP servers expose tools over a lightweight RPC protocol, and Hermes Agent can connect to any compliant server automatically. +## What MCP gives you -What this means for you: +- Access to external tool ecosystems without writing a native Hermes tool first +- Local stdio servers and remote HTTP MCP servers in the same config +- Automatic tool discovery and registration at startup +- Utility wrappers for MCP resources and prompts when supported by the server +- Per-server filtering so you can expose only the MCP tools you actually want Hermes to see -- **Thousands of ready-made tools** β€” browse the [MCP server directory](https://github.com/modelcontextprotocol/servers) for servers covering GitHub, Slack, databases, file systems, web scraping, and more -- **No code changes needed** β€” add a few lines to `~/.hermes/config.yaml` and the tools appear alongside built-in ones -- **Mix and match** β€” run multiple MCP servers simultaneously, combining stdio-based and HTTP-based servers -- **Secure by default** β€” environment variables are filtered and credentials are stripped from error messages +## Quick start -## Prerequisites +1. Install MCP support: ```bash pip install hermes-agent[mcp] ``` -| Server Type | Runtime Needed | Example | -|-------------|---------------|---------| -| HTTP/remote | Nothing extra | `url: "https://mcp.example.com"` | -| npm-based (npx) | Node.js 18+ | `command: "npx"` | -| Python-based | uv (recommended) | `command: "uvx"` | - -## Configuration - -MCP servers are configured in `~/.hermes/config.yaml` under the `mcp_servers` key. - -### Stdio Servers - -Stdio servers run as local subprocesses, communicating over stdin/stdout: +2. Add an MCP server to `~/.hermes/config.yaml`: ```yaml mcp_servers: filesystem: command: "npx" args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"] - env: {} +``` +3. Start Hermes: + +```bash +hermes chat +``` + +4. Ask Hermes to use the MCP-backed capability. + +For example: + +```text +List the files in /home/user/projects and summarize the repo structure. +``` + +Hermes will discover the MCP server's tools and use them like any other tool. + +## Two kinds of MCP servers + +### Stdio servers + +Stdio servers run as local subprocesses and talk over stdin/stdout. + +```yaml +mcp_servers: github: command: "npx" args: ["-y", "@modelcontextprotocol/server-github"] env: - GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxx" + GITHUB_PERSONAL_ACCESS_TOKEN: "***" ``` -| Key | Required | Description | -|-----|----------|-------------| -| `command` | Yes | Executable to run (`npx`, `uvx`, `python`) | -| `args` | No | Command-line arguments | -| `env` | No | Environment variables for the subprocess | +Use stdio servers when: +- the server is installed locally +- you want low-latency access to local resources +- you are following MCP server docs that show `command`, `args`, and `env` -:::info Security -Only explicitly listed `env` variables plus a safe baseline (`PATH`, `HOME`, `USER`, `LANG`, `SHELL`, `TMPDIR`, `XDG_*`) are passed to the subprocess. Your API keys and secrets are **not** leaked. -::: +### HTTP servers -### HTTP Servers +HTTP MCP servers are remote endpoints Hermes connects to directly. ```yaml mcp_servers: remote_api: - url: "https://my-mcp-server.example.com/mcp" + url: "https://mcp.example.com/mcp" headers: - Authorization: "Bearer sk-xxxxxxxxxxxx" + Authorization: "Bearer ***" ``` -### Per-Server Timeouts +Use HTTP servers when: +- the MCP server is hosted elsewhere +- your organization exposes internal MCP endpoints +- you do not want Hermes spawning a local subprocess for that integration + +## Basic configuration reference + +Hermes reads MCP config from `~/.hermes/config.yaml` under `mcp_servers`. + +### Common keys + +| Key | Type | Meaning | +|---|---|---| +| `command` | string | Executable for a stdio MCP server | +| `args` | list | Arguments for the stdio server | +| `env` | mapping | Environment variables passed to the stdio server | +| `url` | string | HTTP MCP endpoint | +| `headers` | mapping | HTTP headers for remote servers | +| `timeout` | number | Tool call timeout | +| `connect_timeout` | number | Initial connection timeout | +| `enabled` | bool | If `false`, Hermes skips the server entirely | +| `tools` | mapping | Per-server tool filtering and utility policy | + +### Minimal stdio example ```yaml mcp_servers: - slow_database: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-postgres"] - env: - DATABASE_URL: "postgres://user:pass@localhost/mydb" - timeout: 300 # Tool call timeout (default: 120s) - connect_timeout: 90 # Initial connection timeout (default: 60s) -``` - -### Mixed Configuration Example - -```yaml -mcp_servers: - # Local filesystem via stdio - filesystem: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] - - # GitHub API via stdio with auth - github: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-github"] - env: - GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxx" - - # Remote database via HTTP - company_db: - url: "https://mcp.internal.company.com/db" - headers: - Authorization: "Bearer sk-xxxxxxxxxxxx" - timeout: 180 - - # Python-based server via uvx - memory: - command: "uvx" - args: ["mcp-server-memory"] -``` - -## Translating from Claude Desktop Config - -Many MCP server docs show Claude Desktop JSON format. Here's the translation: - -**Claude Desktop JSON:** -```json -{ - "mcpServers": { - "filesystem": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] - } - } -} -``` - -**Hermes YAML:** -```yaml -mcp_servers: # mcpServers β†’ mcp_servers (snake_case) filesystem: command: "npx" args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] ``` -Rules: `mcpServers` β†’ `mcp_servers` (snake_case), JSON β†’ YAML. Keys like `command`, `args`, `env` are identical. +### Minimal HTTP example -## How It Works - -### Tool Registration - -Each MCP tool is registered with a prefixed name: - -``` -mcp_{server_name}_{tool_name} +```yaml +mcp_servers: + company_api: + url: "https://mcp.internal.example.com" + headers: + Authorization: "Bearer ***" ``` -| Server Name | MCP Tool Name | Registered As | -|-------------|--------------|---------------| +## How Hermes registers MCP tools + +Hermes prefixes MCP tools so they do not collide with built-in names: + +```text +mcp__ +``` + +Examples: + +| Server | MCP tool | Registered name | +|---|---|---| | `filesystem` | `read_file` | `mcp_filesystem_read_file` | | `github` | `create-issue` | `mcp_github_create_issue` | | `my-api` | `query.data` | `mcp_my_api_query_data` | -Tools appear alongside built-in tools β€” the agent calls them like any other tool. +In practice, you usually do not need to call the prefixed name manually β€” Hermes sees the tool and chooses it during normal reasoning. -:::info -In addition to the server's own tools, each MCP server also gets 4 utility tools auto-registered: `list_resources`, `read_resource`, `list_prompts`, and `get_prompt`. These allow the agent to discover and use MCP resources and prompts exposed by the server. +## MCP utility tools -Each configured server also creates a **runtime toolset** named `mcp-`. This means you can filter or reason about MCP servers at the toolset level in the same way you do with built-in toolsets. -::: +When supported, Hermes also registers utility tools around MCP resources and prompts: -### Reconnection +- `list_resources` +- `read_resource` +- `list_prompts` +- `get_prompt` -If an MCP server disconnects, Hermes automatically reconnects with exponential backoff (1s, 2s, 4s, 8s, 16s β€” max 5 attempts). Initial connection failures are reported immediately. +These are registered per server with the same prefix pattern, for example: -### Shutdown +- `mcp_github_list_resources` +- `mcp_github_get_prompt` -On agent exit, all MCP server connections are cleanly shut down. +### Important -## Popular MCP Servers +These utility tools are now capability-aware: +- Hermes only registers resource utilities if the MCP session actually supports resource operations +- Hermes only registers prompt utilities if the MCP session actually supports prompt operations -| Server | Package | Description | -|--------|---------|-------------| -| Filesystem | `@modelcontextprotocol/server-filesystem` | Read/write/search local files | -| GitHub | `@modelcontextprotocol/server-github` | Issues, PRs, repos, code search | -| Git | `@modelcontextprotocol/server-git` | Git operations on local repos | -| Fetch | `@modelcontextprotocol/server-fetch` | HTTP fetching and web content | -| Memory | `@modelcontextprotocol/server-memory` | Persistent key-value memory | -| SQLite | `@modelcontextprotocol/server-sqlite` | Query SQLite databases | -| PostgreSQL | `@modelcontextprotocol/server-postgres` | Query PostgreSQL databases | -| Brave Search | `@modelcontextprotocol/server-brave-search` | Web search via Brave API | -| Puppeteer | `@modelcontextprotocol/server-puppeteer` | Browser automation | +So a server that exposes callable tools but no resources/prompts will not get those extra wrappers. -### Example Configs +## Per-server filtering + +This is the main feature added by the PR work. + +You can now control which tools each MCP server contributes to Hermes. + +### Disable a server entirely ```yaml mcp_servers: - # No API key needed - filesystem: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"] + legacy: + url: "https://mcp.legacy.internal" + enabled: false +``` - git: - command: "uvx" - args: ["mcp-server-git", "--repository", "/home/user/my-repo"] +If `enabled: false`, Hermes skips the server completely and does not even attempt a connection. - fetch: - command: "uvx" - args: ["mcp-server-fetch"] +### Whitelist server tools - sqlite: - command: "uvx" - args: ["mcp-server-sqlite", "--db-path", "/home/user/data.db"] - - # Requires API key +```yaml +mcp_servers: github: command: "npx" args: ["-y", "@modelcontextprotocol/server-github"] env: - GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxx" + GITHUB_PERSONAL_ACCESS_TOKEN: "***" + tools: + include: [create_issue, list_issues] +``` - brave_search: +Only those MCP server tools are registered. + +### Blacklist server tools + +```yaml +mcp_servers: + stripe: + url: "https://mcp.stripe.com" + tools: + exclude: [delete_customer] +``` + +All server tools are registered except the excluded ones. + +### Precedence rule + +If both are present: + +```yaml +tools: + include: [create_issue] + exclude: [create_issue, delete_issue] +``` + +`include` wins. + +### Filter utility tools too + +You can also separately disable Hermes-added utility wrappers: + +```yaml +mcp_servers: + docs: + url: "https://mcp.docs.example.com" + tools: + prompts: false + resources: false +``` + +That means: +- `tools.resources: false` disables `list_resources` and `read_resource` +- `tools.prompts: false` disables `list_prompts` and `get_prompt` + +### Full example + +```yaml +mcp_servers: + github: command: "npx" - args: ["-y", "@modelcontextprotocol/server-brave-search"] + args: ["-y", "@modelcontextprotocol/server-github"] env: - BRAVE_API_KEY: "BSA_xxxxxxxxxxxx" + GITHUB_PERSONAL_ACCESS_TOKEN: "***" + tools: + include: [create_issue, list_issues, search_code] + prompts: false + + stripe: + url: "https://mcp.stripe.com" + headers: + Authorization: "Bearer ***" + tools: + exclude: [delete_customer] + resources: false + + legacy: + url: "https://mcp.legacy.internal" + enabled: false +``` + +## What happens if everything is filtered out? + +If your config filters out all callable tools and disables or omits all supported utilities, Hermes does not create an empty runtime MCP toolset for that server. + +That keeps the tool list clean. + +## Runtime behavior + +### Discovery time + +Hermes discovers MCP servers at startup and registers their tools into the normal tool registry. + +### Reloading + +If you change MCP config, use: + +```text +/reload-mcp +``` + +This reloads MCP servers from config and refreshes the available tool list. + +### Toolsets + +Each configured MCP server also creates a runtime toolset when it contributes at least one registered tool: + +```text +mcp- +``` + +That makes MCP servers easier to reason about at the toolset level. + +## Security model + +### Stdio env filtering + +For stdio servers, Hermes does not blindly pass your full shell environment. + +Only explicitly configured `env` plus a safe baseline are passed through. This reduces accidental secret leakage. + +### Config-level exposure control + +The new filtering support is also a security control: +- disable dangerous tools you do not want the model to see +- expose only a minimal whitelist for a sensitive server +- disable resource/prompt wrappers when you do not want that surface exposed + +## Example use cases + +### GitHub server with a minimal issue-management surface + +```yaml +mcp_servers: + github: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-github"] + env: + GITHUB_PERSONAL_ACCESS_TOKEN: "***" + tools: + include: [list_issues, create_issue, update_issue] + prompts: false + resources: false +``` + +Use it like: + +```text +Show me open issues labeled bug, then draft a new issue for the flaky MCP reconnection behavior. +``` + +### Stripe server with dangerous actions removed + +```yaml +mcp_servers: + stripe: + url: "https://mcp.stripe.com" + headers: + Authorization: "Bearer ***" + tools: + exclude: [delete_customer, refund_payment] +``` + +Use it like: + +```text +Look up the last 10 failed payments and summarize common failure reasons. +``` + +### Filesystem server for a single project root + +```yaml +mcp_servers: + project_fs: + command: "npx" + args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/my-project"] +``` + +Use it like: + +```text +Inspect the project root and explain the directory layout. ``` ## Troubleshooting -### "MCP SDK not available" +### MCP server not connecting + +Check: ```bash pip install hermes-agent[mcp] +node --version +npx --version ``` -### Server fails to start +Then verify your config and restart Hermes. -The MCP server command (`npx`, `uvx`) is not on PATH. Install the required runtime: +### Tools not appearing -```bash -# For npm-based servers -npm install -g npx # or ensure Node.js 18+ is installed +Possible causes: +- the server failed to connect +- discovery failed +- your filter config excluded the tools +- the utility capability does not exist on that server +- the server is disabled with `enabled: false` -# For Python-based servers -pip install uv # then use "uvx" as the command -``` +If you are intentionally filtering, this is expected. -### Server connects but tools fail with auth errors +### Why didn't resource or prompt utilities appear? -Ensure the key is in the server's `env` block: +Because Hermes now only registers those wrappers when both are true: +1. your config allows them +2. the server session actually supports the capability -```yaml -mcp_servers: - github: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-github"] - env: - GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_your_actual_token" # Check this -``` +This is intentional and keeps the tool list honest. -### Connection timeout +## Related docs -Increase `connect_timeout` for slow-starting servers: - -```yaml -mcp_servers: - slow_server: - command: "npx" - args: ["-y", "heavy-server-package"] - connect_timeout: 120 # default is 60 -``` - -### Reload MCP Servers - -You can reload MCP servers without restarting Hermes: - -- In the CLI: the agent reconnects automatically -- In messaging: send `/reload-mcp` - -## Sampling (Server-Initiated LLM Requests) - -MCP's `sampling/createMessage` capability allows MCP servers to request LLM completions through the Hermes agent. This enables agent-in-the-loop workflows where servers can leverage the LLM during tool execution β€” for example, a database server asking the LLM to interpret query results, or a code analysis server requesting the LLM to review findings. - -### How It Works - -When an MCP server sends a `sampling/createMessage` request: - -1. The sampling callback validates against rate limits and model whitelist -2. Resolves which model to use (config override > server hint > default) -3. Converts MCP messages to OpenAI-compatible format -4. Offloads the LLM call to a thread via `asyncio.to_thread()` (non-blocking) -5. Returns the response (text or tool use) back to the server - -### Configuration - -Sampling is **enabled by default** for all MCP servers. No extra setup needed β€” if you have an auxiliary LLM client configured, sampling works automatically. - -```yaml -mcp_servers: - analysis_server: - command: "npx" - args: ["-y", "my-analysis-server"] - sampling: - enabled: true # default: true - model: "gemini-3-flash" # override model (optional) - max_tokens_cap: 4096 # max tokens per request (default: 4096) - timeout: 30 # LLM call timeout in seconds (default: 30) - max_rpm: 10 # max requests per minute (default: 10) - allowed_models: [] # model whitelist (empty = allow all) - max_tool_rounds: 5 # max consecutive tool use rounds (0 = disable) - log_level: "info" # audit verbosity: debug, info, warning -``` - -### Tool Use in Sampling - -Servers can include `tools` and `toolChoice` in sampling requests, enabling multi-turn tool-augmented workflows within a single sampling session. The callback forwards tool definitions to the LLM, handles tool use responses with proper `ToolUseContent` types, and enforces `max_tool_rounds` to prevent infinite loops. - -### Security - -- **Rate limiting**: Per-server sliding window (default: 10 req/min) -- **Token cap**: Servers can't request more than `max_tokens_cap` (default: 4096) -- **Model whitelist**: `allowed_models` restricts which models a server can use -- **Tool loop limit**: `max_tool_rounds` caps consecutive tool use rounds -- **Credential stripping**: LLM responses are sanitized before returning to the server -- **Non-blocking**: LLM calls run in a separate thread via `asyncio.to_thread()` -- **Typed errors**: All failures return structured `ErrorData` per MCP spec - -To disable sampling for untrusted servers: - -```yaml -mcp_servers: - untrusted: - command: "npx" - args: ["-y", "untrusted-server"] - sampling: - enabled: false -``` +- [Use MCP with Hermes](/docs/guides/use-mcp-with-hermes) +- [CLI Commands](/docs/reference/cli-commands) +- [Slash Commands](/docs/reference/slash-commands) +- [FAQ](/docs/reference/faq) diff --git a/website/sidebars.ts b/website/sidebars.ts index 0861cdf08..21b20b315 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -22,6 +22,7 @@ const sidebars: SidebarsConfig = { 'guides/daily-briefing-bot', 'guides/team-telegram-assistant', 'guides/python-library', + 'guides/use-mcp-with-hermes', ], }, { @@ -128,6 +129,7 @@ const sidebars: SidebarsConfig = { 'reference/slash-commands', 'reference/tools-reference', 'reference/toolsets-reference', + 'reference/mcp-config-reference', 'reference/skills-catalog', 'reference/optional-skills-catalog', 'reference/environment-variables',