2026-03-05 05:24:55 -08:00
---
sidebar_position: 4
title: "MCP (Model Context Protocol)"
2026-03-14 06:36:01 -07:00
description: "Connect Hermes Agent to external tool servers via MCP — and control exactly which MCP tools Hermes loads"
2026-03-05 05:24:55 -08:00
---
# MCP (Model Context Protocol)
2026-03-14 06:36:01 -07:00
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.
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
If you have ever wanted Hermes to use a tool that already exists somewhere else, MCP is usually the cleanest way to do it.
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
## What MCP gives you
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
- 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
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
## Quick start
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
1. Install MCP support:
2026-03-05 05:24:55 -08:00
```bash
pip install hermes-agent[mcp]
```
2026-03-14 06:36:01 -07:00
2. Add an MCP server to `~/.hermes/config.yaml` :
2026-03-05 05:24:55 -08:00
```yaml
mcp_servers:
filesystem:
command: "npx"
args: ["-y", "@modelcontextprotocol/server -filesystem", "/home/user/projects"]
```
2026-03-14 06:36:01 -07:00
3. Start Hermes:
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
```bash
hermes chat
```
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
4. Ask Hermes to use the MCP-backed capability.
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
For example:
```text
List the files in /home/user/projects and summarize the repo structure.
2026-03-05 05:24:55 -08:00
```
2026-03-14 06:36:01 -07:00
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.
2026-03-05 05:24:55 -08:00
```yaml
mcp_servers:
2026-03-14 06:36:01 -07:00
github:
2026-03-05 05:24:55 -08:00
command: "npx"
2026-03-14 06:36:01 -07:00
args: ["-y", "@modelcontextprotocol/server -github"]
2026-03-05 05:24:55 -08:00
env:
2026-03-14 06:36:01 -07:00
GITHUB_PERSONAL_ACCESS_TOKEN: "***"
2026-03-05 05:24:55 -08:00
```
2026-03-14 06:36:01 -07:00
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`
### HTTP servers
HTTP MCP servers are remote endpoints Hermes connects to directly.
2026-03-05 05:24:55 -08:00
```yaml
mcp_servers:
2026-03-14 06:36:01 -07:00
remote_api:
url: "https://mcp.example.com/mcp"
headers:
Authorization: "Bearer * * *"
```
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
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
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
## Basic configuration reference
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
Hermes reads MCP config from `~/.hermes/config.yaml` under `mcp_servers` .
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
### Common keys
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
| 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 |
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
### Minimal stdio example
2026-03-05 05:24:55 -08:00
```yaml
2026-03-14 06:36:01 -07:00
mcp_servers:
2026-03-05 05:24:55 -08:00
filesystem:
command: "npx"
args: ["-y", "@modelcontextprotocol/server -filesystem", "/tmp"]
```
2026-03-14 06:36:01 -07:00
### Minimal HTTP example
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
```yaml
mcp_servers:
company_api:
url: "https://mcp.internal.example.com"
headers:
Authorization: "Bearer * * *"
```
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
## How Hermes registers MCP tools
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
Hermes prefixes MCP tools so they do not collide with built-in names:
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
```text
mcp_<server_name>_<tool_name>
2026-03-05 05:24:55 -08:00
```
2026-03-14 06:36:01 -07:00
Examples:
| Server | MCP tool | Registered name |
|---|---|---|
2026-03-05 05:24:55 -08:00
| `filesystem` | `read_file` | `mcp_filesystem_read_file` |
| `github` | `create-issue` | `mcp_github_create_issue` |
| `my-api` | `query.data` | `mcp_my_api_query_data` |
2026-03-14 06:36:01 -07:00
In practice, you usually do not need to call the prefixed name manually — Hermes sees the tool and chooses it during normal reasoning.
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
## MCP utility tools
docs: expand Docusaurus coverage across CLI, tools, skills, and skins (#1232)
- add code-derived reference pages for slash commands, tools, toolsets,
bundled skills, and official optional skills
- document the skin system and link visual theming separately from
conversational personality
- refresh quickstart, configuration, environment variable, and messaging
docs to match current provider, gateway, and browser behavior
- fix stale command, session, and Home Assistant configuration guidance
2026-03-13 21:34:41 -07:00
2026-03-14 06:36:01 -07:00
When supported, Hermes also registers utility tools around MCP resources and prompts:
docs: fix all remaining minor accuracy issues
- updating.md: Note that 'hermes update' auto-handles config migration
- cli.md: Add summary_model to compression config, fix display config
(add personality/compact), remove unverified pastes/ claim
- configuration.md: Add 5 missing config sections (stt, human_delay,
code_execution, delegation, clarify), fix display defaults,
fix reasoning_effort default to empty/unset
- messaging/index.md: Add GATEWAY_ALLOWED_USERS to security section
- skills.md: Add category field to skills_list return value
- mcp.md: Document auto-registered utility tools (resources/prompts)
- architecture.md: Fix file_tools.py reference, base_url default to None,
synchronous agent loop pseudocode
- cli-commands.md: Fix hermes logout description
- environment-variables.md: Add HERMES_QUIET, HERMES_EXEC_ASK,
BROWSER_INACTIVITY_TIMEOUT, GATEWAY_ALLOWED_USERS
Verification scan: 27/27 checks passed, zero issues remaining.
2026-03-05 07:00:51 -08:00
2026-03-14 06:36:01 -07:00
- `list_resources`
- `read_resource`
- `list_prompts`
- `get_prompt`
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
These are registered per server with the same prefix pattern, for example:
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
- `mcp_github_list_resources`
- `mcp_github_get_prompt`
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
### Important
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
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
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
So a server that exposes callable tools but no resources/prompts will not get those extra wrappers.
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
## 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
2026-03-05 05:24:55 -08:00
```yaml
mcp_servers:
2026-03-14 06:36:01 -07:00
legacy:
url: "https://mcp.legacy.internal"
enabled: false
```
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
If `enabled: false` , Hermes skips the server completely and does not even attempt a connection.
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
### Whitelist server tools
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
```yaml
mcp_servers:
2026-03-05 05:24:55 -08:00
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server -github"]
env:
2026-03-14 06:36:01 -07:00
GITHUB_PERSONAL_ACCESS_TOKEN: "***"
tools:
include: [create_issue, list_issues]
```
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
Only those MCP server tools are registered.
### Blacklist server tools
```yaml
mcp_servers:
stripe:
url: "https://mcp.stripe.com"
tools:
exclude: [delete_customer]
2026-03-05 05:24:55 -08:00
```
2026-03-14 06:36:01 -07:00
All server tools are registered except the excluded ones.
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
### Precedence rule
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
If both are present:
```yaml
tools:
include: [create_issue]
exclude: [create_issue, delete_issue]
2026-03-05 05:24:55 -08:00
```
2026-03-14 06:36:01 -07:00
`include` wins.
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
### Filter utility tools too
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
You can also separately disable Hermes-added utility wrappers:
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
```yaml
mcp_servers:
docs:
url: "https://mcp.docs.example.com"
tools:
prompts: false
resources: false
2026-03-05 05:24:55 -08:00
```
2026-03-14 06:36:01 -07:00
That means:
- `tools.resources: false` disables `list_resources` and `read_resource`
- `tools.prompts: false` disables `list_prompts` and `get_prompt`
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
### Full example
2026-03-05 05:24:55 -08:00
```yaml
mcp_servers:
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server -github"]
env:
2026-03-14 06:36:01 -07:00
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
2026-03-05 05:24:55 -08:00
```
2026-03-14 06:36:01 -07:00
## What happens if everything is filtered out?
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
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.
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
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
2026-03-05 05:24:55 -08:00
```
2026-03-14 06:36:01 -07:00
This reloads MCP servers from config and refreshes the available tool list.
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
### Toolsets
2026-03-05 05:24:55 -08:00
2026-03-14 06:36:01 -07:00
Each configured MCP server also creates a runtime toolset when it contributes at least one registered tool:
2026-03-09 03:37:38 -07:00
2026-03-14 06:36:01 -07:00
```text
mcp-<server>
```
That makes MCP servers easier to reason about at the toolset level.
## Security model
### Stdio env filtering
2026-03-09 03:37:38 -07:00
2026-03-14 06:36:01 -07:00
For stdio servers, Hermes does not blindly pass your full shell environment.
2026-03-09 03:37:38 -07:00
2026-03-14 06:36:01 -07:00
Only explicitly configured `env` plus a safe baseline are passed through. This reduces accidental secret leakage.
2026-03-09 03:37:38 -07:00
2026-03-14 06:36:01 -07:00
### Config-level exposure control
2026-03-09 03:37:38 -07:00
2026-03-14 06:36:01 -07:00
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
2026-03-09 03:37:38 -07:00
2026-03-14 06:36:01 -07:00
## Example use cases
2026-03-09 03:37:38 -07:00
2026-03-14 06:36:01 -07:00
### GitHub server with a minimal issue-management surface
2026-03-09 03:37:38 -07:00
```yaml
mcp_servers:
2026-03-14 06:36:01 -07:00
github:
2026-03-09 03:37:38 -07:00
command: "npx"
2026-03-14 06:36:01 -07:00
args: ["-y", "@modelcontextprotocol/server -github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "***"
tools:
include: [list_issues, create_issue, update_issue]
prompts: false
resources: false
2026-03-09 03:37:38 -07:00
```
2026-03-14 06:36:01 -07:00
Use it like:
2026-03-09 03:37:38 -07:00
2026-03-14 06:36:01 -07:00
```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]
```
2026-03-09 03:37:38 -07:00
2026-03-14 06:36:01 -07:00
Use it like:
2026-03-09 03:37:38 -07:00
2026-03-14 06:36:01 -07:00
```text
Look up the last 10 failed payments and summarize common failure reasons.
```
2026-03-09 03:37:38 -07:00
2026-03-14 06:36:01 -07:00
### Filesystem server for a single project root
2026-03-09 03:37:38 -07:00
```yaml
mcp_servers:
2026-03-14 06:36:01 -07:00
project_fs:
2026-03-09 03:37:38 -07:00
command: "npx"
2026-03-14 06:36:01 -07:00
args: ["-y", "@modelcontextprotocol/server -filesystem", "/home/user/my-project"]
```
Use it like:
```text
Inspect the project root and explain the directory layout.
```
## Troubleshooting
### MCP server not connecting
Check:
```bash
pip install hermes-agent[mcp]
node --version
npx --version
2026-03-09 03:37:38 -07:00
```
2026-03-14 06:36:01 -07:00
Then verify your config and restart Hermes.
### Tools not appearing
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`
If you are intentionally filtering, this is expected.
### Why didn't resource or prompt utilities appear?
Because Hermes now only registers those wrappers when both are true:
1. your config allows them
2. the server session actually supports the capability
This is intentional and keeps the tool list honest.
## Related docs
- [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 )