hermes-mcp-gateway
Allows remote MCP clients to run governed one-shot tasks through Hermes Agent, including configurable profiles, toolsets, models, working directories, timeouts, approvals, and audit logging.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@hermes-mcp-gatewaySearch my working directory for TODO comments using the file toolset."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
hermes-mcp-gateway
A governed MCP gateway that exposes Hermes Agent one-shot task execution to remote MCP clients over MCP Streamable HTTP. Clients authenticate with OAuth 2.1 client credentials, receive per-client RBAC (toolset/model/workdir allowlists, concurrency and duration caps), and terminal-capable clients run behind task-level human-in-the-loop approval. Every task, approval, and issued token is written to a SQLite audit store.
Architecture
MCP client ── HTTP (Bearer JWT) ──> gateway (policy / audit)
│
▼
hermes -p mcp-worker chat -q <prompt> (subprocess)
│
▼
per-task status.json + session storeThe gateway is a single Starlette app: /token and /.well-known/* handle
OAuth discovery and issuance, /healthz reports liveness, and /mcp is the
Bearer-authed MCP Streamable HTTP endpoint. Tasks run as governed
hermes -p mcp-worker chat -q subprocesses with capped duration, captured
stdout/stderr, and the Hermes session id attributed back to the task row.
Related MCP server: ChatGPT Gateway MCP Nyan
Quickstart
uv sync
mkdir -p ~/.hermes/mcp-gateway
cp deploy/config.yaml.example ~/.hermes/mcp-gateway/config.yaml
# edit the config: point hermes.bin at hermes and set workdirs to a real path
openssl rand -hex 32 # this is your signing key
export HERMES_MCP_GATEWAY_SIGNING_KEY="<the hex value>"
# hash a client secret and put its sha256 into config for the client
uv run hermes-mcp-gateway clients hash spec-client-secret
# edit config: replace the placeholder secret_hash for your client
uv run hermes-mcp-gateway --check # validate config, no server started
uv run hermes-mcp-gateway serve # or just: hermes-mcp-gateway
curl -sf http://127.0.0.1:8778/healthzGetting a token
The token endpoint speaks client credentials with either
client_secret_basic or client_secret_post:
# client_secret_basic: HTTP Basic (client_id:client_secret)
curl -s -u research:spec-client-secret \
-d grant_type=client_credentials \
http://127.0.0.1:8778/token
# client_secret_post: credentials in the form body
curl -s \
-d grant_type=client_credentials \
-d client_id=research \
-d client_secret=spec-client-secret \
http://127.0.0.1:8778/tokenThe response is {"access_token": "...", "token_type": "Bearer", "expires_in": 600, "scope": "..."}. Pass access_token as the bearer token on
/mcp.
MCP client configuration
OAuth bearer handling is client-specific, so configure your client to send the
bearer token directly on the /mcp URL.
Claude Code (.mcp.json):
{
"mcpServers": {
"hermes-mcp-gateway": {
"type": "http",
"url": "http://127.0.0.1:8778/mcp",
"headers": {
"Authorization": "Bearer <access_token>"
}
}
}
}Generic mcpServers JSON (many clients accept this shape):
{
"mcpServers": {
"hermes-mcp-gateway": {
"url": "http://127.0.0.1:8778/mcp",
"headers": {
"Authorization": "Bearer <access_token>"
}
}
}
}Security model
Deny-by-default toolset scopes: a client can only request toolsets granted by a
toolset:*scope, and any disallowed toolset rejects the whole request.Empty resolved toolsets are forced to the locked-down
safetoolset (never the profile's own defaults, which would include terminal).Workdir jail: tasks run only inside a real directory that resolves under a configured workdir root, symlink escapes rejected.
Model allowlist: configured
modelsrestrict which models a client may pick.Per-client concurrency and duration caps (
max_concurrency,max_duration_s) plus a turn budget (max_turns).Task-level human-in-the-loop:
requires_approvalclients with terminal park the task aspending_approvaluntil an operator approves or denies.Per-task
session_idattribution: the Hermes session id is parsed from task stderr and stored.SQLite audit store records a row for every task, approval decision, and issued token.
--yolois never passed to hermes; approval timeouts and non-TTY dangerous command approvals stay at hermes defaults and auto-deny inside hermes.
Operator CLI
The hermes-mcp-gateway entry point serves the gateway by default and exposes
operator verbs. Every verb reads --config like serve does.
Command | Effect |
| Run the gateway server |
| Table of clients: id, scopes, approval flag, caps, workdirs, models |
| Print |
| Rows of |
| Approve and spawn a pending task (no-op if already decided) |
| Deny a pending task with an optional reason |
| List tasks, newest first |
| Full task row plus approval state and output path |
| Cancel a running task (no-op if already finished) |
| Dev-only token issuance (requires |
All verbs exit nonzero on an unknown task or client.
Deployment (systemd user unit)
mkdir -p ~/.config/systemd/user
cp deploy/hermes-mcp-gateway.service ~/.config/systemd/user/
chmod 600 ~/.hermes/mcp-gateway/env # file holds HERMES_MCP_GATEWAY_SIGNING_KEY
systemctl --user daemon-reload
systemctl --user enable --now hermes-mcp-gateway
journalctl --user -u hermes-mcp-gateway -fThe unit template lives at deploy/hermes-mcp-gateway.service; it runs the
gateway from the project venv, reads the signing key from
~/.hermes/mcp-gateway/env, and restarts on failure.
Roadmap
Command-level HITL via the hermes approval queue (finer than task-level).
RS256 / JWKS token verification for stateless, header-only clients.
Notification push (webhook/queue) when a task needs approval or finishes.
Per-task cost and token evidence sourced from the session store.
This server cannot be deployed
Maintenance
Related MCP Connectors
Remote MCP for A2A caller identity, scope policy, verdict receipts, and audit history.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
An authenticated remote MCP server for user-owned devices and one-shot capability invocation.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables policy-governed MCP interactions with deterministic authorization, tenant isolation, minimized PII exposure, and human approval gates for sensitive mutations, while producing structured audit events.3MIT
- AlicenseNot gradedqualityBmaintenanceEnables agent clients to safely connect to tools and execution resources through MCP with authorization, approvals, audit, chat-context isolation, SSH/Docker access, and long-running command session tracking.MIT
- AlicenseNot gradedqualityCmaintenanceEnables centralized proxy and orchestration of MCP servers, providing unified tool discovery, authentication, and secure request routing. It adds a human-in-the-loop approval gate for high-risk actions and audit logging.Apache 2.0
- FlicenseCqualityCmaintenanceEnables stdio-capable MCP clients to run governed enterprise operations tasks, including policy/runbook retrieval and ticket and user lookups or writes. High-risk actions are held for human approval and role-based access is enforced server-side, so clients cannot bypass governance.41-