4.8 KiB
name, description, version, category
| name | description | version | category |
|---|---|---|---|
| hermes-api-server-setup | Set up Hermes Agent built-in OpenAI-compatible API server on a custom port with external access. Includes the critical extra nesting pitfall. | 1.0 | devops |
Hermes API Server Setup
Hermes has a built-in OpenAI-compatible API server (gateway/platforms/api_server.py) that exposes endpoints like /v1/chat/completions, /v1/responses, /v1/models, /health, etc. Any OpenAI-compatible frontend (Open WebUI, LobeChat, LibreChat, ChatBox, etc.) can connect.
Critical Pitfall - extra Nesting
Host, port, key, cors_origins MUST be nested under extra: in config.yaml. If placed directly under the platform name, PlatformConfig.from_dict() silently ignores them (it only reads enabled, token, api_key, home_channel, reply_to_mode, extra).
WRONG - binds to 127.0.0.1 only (silently ignores host/port):
platforms:
api_server:
enabled: true
host: "0.0.0.0"
port: 8642
key: "my-secret"
CORRECT - binds to 0.0.0.0:
platforms:
api_server:
enabled: true
extra:
host: "0.0.0.0"
port: 8642
key: "my-secret"
cors_origins:
- "*"
Defaults
DEFAULT_HOST:127.0.0.1(localhost only - NOT externally accessible)DEFAULT_PORT:8642
Setup Steps
-
Add the
platforms:block at the TOP LEVEL of~/.hermes/config.yaml(not nested underdisplay:oragent:). -
Ensure host is
0.0.0.0for external access, set akeyfor API auth, andcors_origins: ["*"]for browser clients. -
Restart the gateway:
systemctl --user restart hermes-gateway.service -
Verify:
# Check port is listening on 0.0.0.0 ss -tlnp | grep 8642 # Health check curl http://localhost:8642/health # Model list (auth required) curl http://localhost:8642/v1/models -H "Authorization: Bearer YOUR_KEY" -
If
ssshows127.0.0.1:8642instead of0.0.0.0:8642, theextra:nesting is wrong - recheck step 1.
Client Connection
| Field | Value |
|---|---|
| Base URL | http://YOUR_HOST:8642/v1 |
| API Key | Value of extra.key in config |
| Model ID | hermes-agent (or active profile name) |
Available Endpoints
GET /health- Health checkGET /v1/models- Model listPOST /v1/chat/completions- OpenAI Chat Completions (SSE streaming supported)POST /v1/responses- OpenAI Responses API (stateful)GET /v1/responses/{id}- Retrieve stored responseDELETE /v1/responses/{id}- Delete stored responsePOST /v1/runs- Async run (returns 202 + run_id)GET /v1/runs/{id}/events- SSE stream of run lifecycle events
Session Management Endpoints
GET /v1/sessions- List sessions (query:limit,offset,source,include_children,order_by_last_active)DELETE /v1/sessions/{session_id}- Delete a session and its messagesPOST /v1/sessions/prune- Delete ended sessions older than N days (body:older_than_days,source)GET /v1/capabilities- Advertises all endpoints including sessions (third-party UIs use this for discovery)
Session IDs are validated (hex + underscore/dash only) to prevent path traversal. All session endpoints require the same Authorization: Bearer KEY as other endpoints.
Troubleshooting: API Server Unresponsive
If the API server returns connection refused or times out:
-
Check if gateway service is running:
systemctl --user status hermes-gateway.service -
Check if port is listening:
ss -tlnp | grep 8642No output = gateway not running or API Server not started.
-
Check gateway logs for startup errors or SIGTERM:
cat ~/.hermes/logs/gateway.logLook for
Received SIGTERM(systemd or user killed it) orapi_server connected(started OK). -
Restart gateway:
systemctl --user restart hermes-gateway.service # or: hermes gateway start -
Verify after restart:
sleep 5 && curl -s http://localhost:8642/health
Common cause: Gateway received SIGTERM (e.g. from hermes gateway stop, system reboot, or OOM). The API Server is NOT a separate process — it runs inside the gateway. If the gateway dies, API Server dies with it.
Environment Variable Alternative
Instead of config.yaml, you can also use env vars (checked at gateway startup):
API_SERVER_ENABLED=trueAPI_SERVER_HOST=0.0.0.0API_SERVER_PORT=8642API_SERVER_KEY=my-secretAPI_SERVER_CORS_ORIGINS=*API_SERVER_MODEL_NAME=custom-name
These are read in gateway/config.py and take effect if API_SERVER_ENABLED=true OR API_SERVER_KEY is set.