For developers running Nous Research’s Hermes Agent, connecting to a remote Model Context Protocol (MCP) server is straightforward. But as you add more services, you run into real problems: configuration sprawl, credential management, and raw API wrappers that cause the language model to hallucinate parameters and burn tokens.
Arcade.dev’s MCP gateway gives your Hermes Agent access to thousands of agent-optimized tools through a single endpoint, with downstream credentials vaulted away from the agent process and native OAuth for gateway authentication.
Scope note: One person, one Hermes profile, one gateway process. A shared multi-user service needs per-user MCP connections and token storage, plus an appropriate isolation boundary (containers or OS-level separation, since Hermes profiles are not sandboxes). Arcade User Sources can provide external identity for production agents, but do not add per-user MCP isolation to Hermes by themselves. That architecture is a separate problem.
TL;DR
- Install MCP support (included in the standard installer; from source:
uv pip install -e ".[mcp]"). - Point Hermes at your Arcade MCP gateway using
auth: oauthin~/.hermes/config.yaml. Do not put a staticARCADE_API_KEYin the config; Hermes’s native OAuth flow establishes a user-bound session in Arcade. - Authorize each required tool or provider scope set through Arcade’s
tools.authorizeAPI before running tool calls that need them. Arcade vaults the tokens so they never reach the language model. - Restrict tool exposure with
tools.include/tools.excludefor least privilege.
How to connect Hermes Agent to an MCP server (quick start)
Before connecting to Arcade, make sure your base Hermes Agent installation supports the Model Context Protocol. The standard installer includes MCP support by default. If you’re working from source or managing a custom environment, install the MCP extras from the repository root:
Install MCP support (from source)
uv pip install -e ".[mcp]"
Add an MCP server to ~/.hermes/config.yaml
Once installed, Hermes routes connections through the mcp_servers block in config.yaml. For a basic test against a standard HTTP MCP server, define the connection and inject a static Bearer token:
mcp_servers:
remote_test_api:
url: "https://mcp.internal.example.com"
headers:
Authorization: "Bearer ${REMOTE_TEST_API_KEY}"
This pattern is fine for a single developer hitting an internal test server they control. For remote servers that support OAuth, prefer Hermes’s native OAuth flow instead of static tokens.
Authenticate with Hermes’s native OAuth flow
The recommended way to connect Hermes to OAuth-protected remote MCP servers, including Arcade, is through its native OAuth 2.1 support. Set auth: oauth in the configuration block. When configured, Hermes handles dynamic client registration, prints an authorization URL to the terminal, opens your browser, and waits for the callback on a local loopback port.
mcp_servers:
my_server:
url: "https://example.com/mcp"
auth: oauth
Authenticate and reload tools
After saving an OAuth configuration, run hermes mcp login <server> from a fresh terminal. This provides enough time to complete browser authentication (five minutes, compared to the 30-second window during automatic config reload). Once authenticated, start or restart Hermes. Use /reload-mcp in the chat interface when you need to refresh the registered tools after later configuration changes.
Verify the tools loaded successfully by running:
hermes mcp test <server>
Why connect Hermes to Arcade
You could wire Hermes to each service individually, one MCP server for Gmail, another for Slack, another for your CRM. That works until you’re managing a dozen config blocks, each with its own credentials, timeouts, and failure modes. Arcade solves several problems at once.
One endpoint instead of many
The Arcade MCP Gateway gives your Hermes Agent access to thousands of tools through a single URL. Instead of managing separate server connections and keeping track of which service lives where, your Hermes Agent talks to one gateway. Arcade handles routing and tool execution behind it.
Agent-optimized tools reduce hallucinations and token cost
Raw API wrappers hurt agent performance because they’re built for deterministic software, not probabilistic language models.
When an agent receives a raw API definition, it frequently hallucinates required parameters, enters retry loops on malformed JSON payloads, and burns tokens trying to correct its own errors. Arcade’s tools are designed at the intent level, translating natural language into precise API calls. In published benchmarks, this approach has cut response token usage substantially compared to raw API passthrough, while also lowering parameter hallucination rates.
Downstream credentials stay out of the agent process
Storing API keys and OAuth tokens in environment files is a real risk, even for a single user. Recent reports from GitGuardian identified tens of thousands of unique secrets exposed in public MCP configuration files.
Arcade vaults downstream service tokens (Gmail, Slack, CRM, etc.) so they never reach Hermes or the model context. Refresh and revocation are centralized in Arcade rather than scattered across config files.
How to configure the Arcade MCP gateway in Hermes
Gateway configuration
Define the gateway connection in ~/.hermes/config.yaml and set auth: oauth. When you start Hermes, the native OAuth flow will prompt you to authenticate with your Arcade account in the browser.
mcp_servers:
arcade_gateway:
url: "https://api.arcade.dev/mcp/<YOUR-GATEWAY-SLUG>"
auth: oauth
Replace <YOUR-GATEWAY-SLUG> with the slug shown in your Arcade dashboard after creating a gateway. When setting up the gateway, select Arcade Auth as the authentication mode, which lets you sign in with your Arcade account.
Do not use a static ARCADE_API_KEY in the headers. Arcade’s own documentation describes API keys as administrator credentials that let anyone who has the key make requests as you. Hermes’s native OAuth flow gives you a user-bound OAuth session instead.
You can optionally override connect_timeout and timeout in the config block if you need custom values, but Hermes ships with reasonable defaults.
After authenticating with hermes mcp login arcade_gateway, verify the connection:
hermes mcp test arcade_gateway
What changes after connecting to Arcade
With this configuration, Hermes no longer needs to manage credentials for the third-party services it calls. It formulates intent and sends the request to the Arcade gateway. Arcade resolves the authentication for the connected services and executes the underlying API call, returning only the result to Hermes.
How downstream service authorization works
Authorizing services like Gmail, Slack, and CRMs
Before your Hermes Agent can act on a downstream service like Gmail or a CRM, you need to authorize that service’s connection through Arcade. Arcade’s standard flow is just-in-time: when an agent calls a tool that requires a service the user hasn’t connected yet, Arcade returns an authorization URL through MCP URL-mode elicitation. A client that supports elicitation surfaces this URL to the user, who completes the OAuth flow once. Arcade then vaults and automatically refreshes the resulting token.
As of June 2026, Hermes does not support URL-mode elicitation. Its handler explicitly declines URL-mode responses (current implementation), so the authorization URL never reaches you. This limitation may change in a future release. Until then, authorize your service connections before running tool calls that require them.
Arcade provides a tools.authorize API for this purpose. Install the SDK and set a temporary API key in a dedicated setup shell:
pip install arcadepy
export ARCADE_API_KEY="<your-api-key>"
Run preauthorization in this dedicated shell, separate from the one you use to launch Hermes.
Then run the following to authorize a tool’s required scopes:
from arcadepy import Arcade
# For this personal Arcade Auth setup, use the email address
# associated with your Arcade account.
USER_ID = "you@example.com"
client = Arcade() # Uses ARCADE_API_KEY from the environment
auth_response = client.tools.authorize(
tool_name="Gmail.ListEmails",
user_id=USER_ID,
)
if auth_response.status != "completed":
print(f"Authorize Gmail: {auth_response.url}")
client.auth.wait_for_completion(auth_response)
A few things to note about this setup step:
- In this workflow, use the administrator API key only for preauthorization; the key itself is not scoped to that operation. Never place it in Hermes’s configuration, and unset or revoke it afterward.
- The Arcade SDK uses dotted names (
Gmail.ListEmails) fortools.authorizecalls. Hermestools.includefilters use the MCP wire names, which are underscore-separated (Gmail_ListEmails). - Authorization applies to the scopes requested by that specific tool. Another Gmail tool may request additional scopes and trigger a separate authorization challenge. Authorize each tool or provider scope set you plan to use, not just one per service.
- For this personal Arcade Auth configuration, use the same email address you used to sign into Arcade as the
user_id. If theuser_iddoesn’t match your gateway OAuth session identity, Arcade vaults the token under a different user and Hermes won’t be able to use it.
How token vaulting works at runtime
When your Hermes Agent calls a tool that interacts with an authorized service, the request goes to the Arcade gateway. Arcade checks that you have a valid, vaulted token for that service, makes the API call on your behalf, and returns the result to Hermes.
If a token has expired, Arcade handles the refresh automatically. If a service isn’t authorized yet, the tool call will return an authorization error. Authorize the required tool scopes through the tools.authorize API and retry.
Arcade keeps downstream service tokens out of Hermes and the model context. Hermes still stores its own MCP gateway OAuth token locally (under ~/.hermes/mcp-tokens/), so normal host and process security remain necessary. Vaulting prevents direct disclosure of downstream tokens and centralizes refresh and revocation, but it does not prevent a compromised Hermes process from invoking tools already authorized for its Arcade session.
How to manage tool visibility and filtering in Hermes
How to use tools.include and tools.exclude
Hermes provides native configuration semantics to restrict tool access, so your agent operates under the principle of least privilege. Use tools.include and tools.exclude in config.yaml to filter Arcade’s tool catalog down to what your use case actually needs. Restrict visibility to safe, read-only, or draft actions where possible:
mcp_servers:
arcade_gateway:
url: "https://api.arcade.dev/mcp/<YOUR-GATEWAY-SLUG>"
auth: oauth
tools:
include:
- Gmail_ListEmails
- Gmail_WriteDraftEmail
Hermes compares tools.include against the raw tool names returned by the MCP server. Arcade’s MCP layer converts canonical dotted names to underscores before sending them over the wire, so use underscore names in your filter (e.g. Gmail_ListEmails, not Gmail.ListEmails).
In this configuration, even though Arcade supports sending and deleting emails, the Hermes Agent can’t see or invoke those capabilities. If you use an exclude block alongside an include block, the include rules take precedence.
Restricting to safe actions
A good starting pattern is to give the agent read and draft access only. Let it list emails, read calendar events, and write draft messages, but not send, delete, or modify anything irreversibly. You can widen the tool set incrementally as you build confidence in the agent’s behavior.
Troubleshooting
Troubleshooting checklist (symptoms, causes, fixes)
| Symptom | Likely cause | Concrete fix |
|---|---|---|
| Expected tools are missing in chat | Gateway tool selection doesn’t include that tool, overly restrictive tools.include filtering, or the MCP server failed discovery. | Verify the tool is enabled in your Arcade gateway, review your Hermes include/exclude rules, and check ~/.hermes/logs/errors.log for discovery errors. |
| OAuth flow times out during config reload | Hermes config auto-reload allows only 30 seconds for interactive OAuth, which may not be enough. | Run hermes mcp login arcade_gateway from a separate terminal, which allows five minutes. Then restart Hermes or use /reload-mcp to refresh tools. |
| Connection rejected after config change | OAuth flow not completed or incorrect gateway URL. | Check ~/.hermes/logs/errors.log, confirm the gateway URL matches your Arcade dashboard, and re-run the OAuth flow. |
| OAuth flow fails in a headless environment | Hermes can’t open a browser in a remote or containerized deployment. | See the Hermes headless OAuth documentation for workarounds including SSH port forwarding. |
| Tool call returns authorization error for a downstream service | The required tool scopes haven’t been authorized yet in Arcade. | Authorize the required tool scopes using the tools.authorize API, then retry the tool call. |
Where to debug: Hermes logs vs Arcade dashboard
When a tool call fails, start with ~/.hermes/logs/errors.log for connection-level issues (wrong URL, OAuth failures, timeouts). For tool execution failures (authorization errors, malformed requests, downstream API rejections), check Arcade’s execution logs when available for your deployment.
Conclusion: connect Hermes to Arcade and start building
Connecting Hermes Agent to MCP takes minimal effort in local development. Adding dozens of services, managing credentials for each, and keeping raw API wrappers from causing hallucinations is where the real time goes.
Arcade gives your Hermes Agent access to thousands of agent-optimized tools through one gateway, with downstream credentials vaulted away from the agent process and the language model. You focus on building the agent logic that matters.
Create a free Arcade.dev account, configure your first gateway, and connect your Hermes Agent today.
Frequently asked questions (FAQ)
Should I use Hermes’s native OAuth or a static API key to connect to Arcade?
Use native OAuth (auth: oauth). A static ARCADE_API_KEY is an administrator credential that lets anyone who has the key make requests as you. The OAuth flow gives you a user-bound session instead.
What do I need to add to ~/.hermes/config.yaml to connect Hermes to Arcade?
Add an mcp_servers entry with your gateway url (format: https://api.arcade.dev/mcp/<YOUR-GATEWAY-SLUG>) and set auth: oauth. Optionally add tools.include / tools.exclude to restrict the visible tool set. Timeout overrides are available but Hermes ships with reasonable defaults.
How do I authorize downstream services like Gmail or Slack?
Use Arcade’s tools.authorize API to authorize each required tool or provider scope set before running tool calls that need them. Hermes does not currently support MCP URL-mode elicitation, so authorization must happen out of band. Make sure the user_id you pass matches the identity from your gateway OAuth session. Once authorized, Arcade vaults the tokens and your agent can call the corresponding tools.
How do I prevent downstream tokens from being exposed to the language model?
Use auth: oauth to connect to Arcade, and authorize downstream services through the tools.authorize API. Arcade vaults all downstream tokens and returns only tool results to Hermes. Note that Hermes still stores its own gateway OAuth token locally under ~/.hermes/mcp-tokens/, so host-level security practices still apply.
Why are expected tools missing in the Hermes chat UI?
Common causes: the tool isn’t included in your Arcade gateway configuration, your tools.include filter is too restrictive, or MCP server discovery failed. Verify the tool is enabled in your gateway, check your Hermes include/exclude rules, and review ~/.hermes/logs/errors.log for discovery errors.
How do I reload MCP tools after changing config.yaml?
Use /reload-mcp in Hermes for local iteration. If the OAuth flow times out during a config reload (the auto-reload window is 30 seconds), run hermes mcp login arcade_gateway from a separate terminal, then restart Hermes or use /reload-mcp.
Can I use this setup for multiple users?
Not with a single Hermes process. Hermes shares its MCP server connections and OAuth token store at the process level, so all users of one process share the same identity. For multi-user setups, you need per-user Hermes profiles running as separate processes, with appropriate OS-level or container isolation (profiles alone are not sandboxes). Arcade User Sources can provide external identity for production agents, but do not add per-user MCP isolation to Hermes by themselves.
What’s the minimum setup checklist for Hermes plus Arcade?
Create an Arcade account and gateway, authorize the required tool scopes through tools.authorize, add the gateway to config.yaml with auth: oauth, and optionally restrict tools with include/exclude.


