Files
atomk-hermes-skills/skills/archived/hermes-api-server-setup/SKILL.md
T

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

  1. Add the platforms: block at the TOP LEVEL of ~/.hermes/config.yaml (not nested under display: or agent:).

  2. Ensure host is 0.0.0.0 for external access, set a key for API auth, and cors_origins: ["*"] for browser clients.

  3. Restart the gateway:

    systemctl --user restart hermes-gateway.service
    
  4. 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"
    
  5. If ss shows 127.0.0.1:8642 instead of 0.0.0.0:8642, the extra: 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 check
  • GET /v1/models - Model list
  • POST /v1/chat/completions - OpenAI Chat Completions (SSE streaming supported)
  • POST /v1/responses - OpenAI Responses API (stateful)
  • GET /v1/responses/{id} - Retrieve stored response
  • DELETE /v1/responses/{id} - Delete stored response
  • POST /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 messages
  • POST /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:

  1. Check if gateway service is running:

    systemctl --user status hermes-gateway.service
    
  2. Check if port is listening:

    ss -tlnp | grep 8642
    

    No output = gateway not running or API Server not started.

  3. Check gateway logs for startup errors or SIGTERM:

    cat ~/.hermes/logs/gateway.log
    

    Look for Received SIGTERM (systemd or user killed it) or api_server connected (started OK).

  4. Restart gateway:

    systemctl --user restart hermes-gateway.service
    # or: hermes gateway start
    
  5. 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=true
  • API_SERVER_HOST=0.0.0.0
  • API_SERVER_PORT=8642
  • API_SERVER_KEY=my-secret
  • API_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.