Skip to content

Repository files navigation

Hermes Bridge API

A lightweight REST + SSE bridge that exposes Hermes Agent to mobile apps and any HTTP client. Built for the Agentfy iOS app, but provider-agnostic — it's plain HTTP, no WebSocket or custom handshake required.

The bridge runs alongside a Hermes installation, discovers the agents and skills configured under ~/.hermes/, and streams agent responses over Server-Sent Events.


Features

  • Chat with any Hermes agent over HTTP, with token-by-token streaming via SSE
  • Multi-agent — list, create, and edit agents; each gets isolated sessions
  • Skill management — browse the ~/.hermes/skills/ catalog and attach/detach skills per agent
  • Model routing — list available models, switch an agent's model on the fly
  • Provider key management — read/write API keys in ~/.hermes/.env so mobile clients never hold secrets
  • TTS proxy — ElevenLabs / OpenAI text-to-speech and transcription routed server-side
  • Session persistence — message history stored in the Hermes SQLite DB, importable/exportable
  • Device pairing — QR-code pairing flow for connecting the Agentfy app

Requirements

  • Python 3.11+ (the same interpreter that runs your Hermes install)
  • A working Hermes Agent install at ~/.hermes/hermes-agent (the bridge imports it at runtime and reads config from ~/.hermes/)

Install (one command)

curl -fsSL https://get.agentfy.app | bash

That's it. The bootstrap clones this repo to ~/.hermes/hermes-bridge-src, runs install.sh, and prints exactly how to start. Safe to re-run (idempotent) — it updates an existing checkout in place.

Prefer to clone it yourself?
git clone https://github.com/jcnh74/hermes-bridge.git
cd hermes-bridge
./install.sh

The installer:

  1. Finds your Hermes install (or honors HERMES_AGENT_ROOT=/path)
  2. Picks the same Python venv that runs Hermes (so imports resolve)
  3. Installs the bridge + optional QR support
  4. Runs a preflight check and prints exactly how to start

If anything's off, it tells you precisely what to fix — no stack traces.

Verify the environment anytime

hermes-bridge doctor
✓ Hermes Agent found: /Users/you/.hermes/hermes-agent
✓ Hermes Python modules import cleanly
✓ Hermes config loaded (default model: claude-opus-4-8)
All checks passed. Start the bridge with: hermes-bridge start

Start it

hermes-bridge start              # daemonized; runs preflight first
hermes-bridge start --foreground # run in the foreground for debugging
hermes-bridge status             # is it running?
hermes-bridge pair               # QR + URL to connect the Agentfy app
hermes-bridge stop

Verify it's up:

curl http://localhost:8765/api/v1/health
# {"status":"ok","version":"0.1.0","agents_available":5,"sessions_active":0, ...}

Manual install (if you'd rather not use the script)

# Use the Python that runs Hermes
~/.hermes/hermes-agent/venv/bin/python -m pip install -e ".[qr]"
~/.hermes/hermes-agent/venv/bin/python -m hermes_bridge.cli doctor

Pointing at a non-standard Hermes location

export HERMES_AGENT_ROOT=/opt/hermes-agent   # dir containing run_agent.py
hermes-bridge doctor

CLI commands

Command Description
hermes-bridge doctor Check the environment is ready (run this first)
hermes-bridge start [--port 8765] [--host 0.0.0.0] [--foreground] [--skip-checks] Start the server (runs preflight unless --skip-checks)
hermes-bridge stop Stop the running server
hermes-bridge status Check whether the server is running
hermes-bridge restart Restart the server
hermes-bridge pair Print pairing URL + QR code for the Agentfy app

Multiple instances: PID files are port-specific (~/.hermes/bridge-<port>.pid), so you can run several bridges on different ports without their lifecycle commands (stop/status/restart) clobbering each other.


Run with Docker

The bridge containerizes by deriving from the official Hermes Agent image rather than reinventing the runtime. Hermes already ships a Python venv with every dependency the bridge needs (fastapi, uvicorn, sse-starlette, pydantic, httpx), so the image just installs the bridge package into that venv and runs it as an s6-overlay-supervised service alongside the gateway — exactly how Hermes runs its own dashboard.

This means the bridge inherits Hermes' container methodology wholesale:

  • HERMES_HOME=/opt/data — you mount ~/.hermes:/opt/data. Config, .env keys, and hermes.db live there and are never baked into the image. The bridge and gateway share the same DB and keys automatically.
  • UID/GID remap (HERMES_UID/HERMES_GID) so container-written files stay owned by your host user.
  • s6 supervision — gateway, bridge, and (optionally) dashboard run in one container, each restarted independently if it crashes.
  • Env-gated — the bridge service only starts when HERMES_BRIDGE=1, mirroring the dashboard's HERMES_DASHBOARD gate.
# From the repo root:
HERMES_UID=$(id -u) HERMES_GID=$(id -g) docker compose up -d
docker compose logs -f      # follow logs
docker compose down         # stop

The bridge is then reachable at http://localhost:8765/api/v1 (host networking).

Pin the Hermes version for reproducible builds:

HERMES_IMAGE=nousresearch/hermes-agent:v1.2.3 \
  HERMES_UID=$(id -u) HERMES_GID=$(id -g) docker compose up -d

Bridge-only (no gateway)? Swap the compose command to keep the container alive while only the supervised bridge runs:

    command: ["sleep", "infinity"]   # with HERMES_BRIDGE=1

Why derive instead of a standalone image

An earlier approach built a standalone image that reinstalled Hermes' entire dependency tree into a second venv and mounted the Hermes source separately. Deriving from the official image is simpler and more correct: no duplicate deps, no second venv, no first-boot install, no custom entrypoint — and the bridge stays in lockstep with the Hermes runtime it talks to.


Testing

The suite covers the bridge's own logic — discovery, persistence, skill scanning, model validation, and the port-specific PID fix — with no live Hermes install or running server required (a fake Hermes root and temp DBs are fabricated in fixtures).

# Use the Python that runs Hermes
pip install -e ".[test]"
pytest                # run the suite
pytest --cov          # with coverage report

Coverage focuses on the pure, testable modules:

Module Coverage
models.py 100%
hermes_env.py ~95%
skills.py ~88%
persistence.py ~81%

server.py and agent_proxy.py need a live Hermes/uvicorn runtime and are covered by integration smoke tests rather than the unit suite (they're omitted from the coverage target in pyproject.toml).


API Reference

Base path: /api/v1

Health & pairing

Method Path Description
GET /health Health check + feature flags
GET /pairing Pairing payload for the mobile app

Agents & models

Method Path Description
GET /agents List available Hermes agents
POST /agents Create a new agent
PATCH /agents/{agent_id} Update an agent (name, model, description, emoji)
GET /models List available models + status

Sessions & messages

Method Path Description
POST /sessions Create a session with an agent
GET /agents/{agent_id}/sessions List an agent's sessions
POST /sessions/{session_key}/messages Send a message — returns an SSE stream
GET /sessions/{session_key}/messages Get message history
POST /sessions/import Import sessions/messages

Skills

Method Path Description
GET /skills List all skills (search/category filters)
GET /skills/{skill_name} Get a skill's detail
GET /skills/{skill_name}/files/{file_path} Read a linked skill file
GET /agents/{agent_id}/skills List skills attached to an agent
POST /agents/{agent_id}/skills Attach a skill to an agent
DELETE /agents/{agent_id}/skills/{skill_name} Detach a skill from an agent

Keys & TTS

Method Path Description
GET /settings/keys List provider key status (never returns secret values)
POST /settings/keys Set a provider key (written to ~/.hermes/.env)
GET /tts/status TTS provider availability + credit status
GET /tts/speak Synthesize speech
POST /tts/transcribe Transcribe audio
GET /files/{file_id} Download a file referenced in an agent response

Full interactive docs are served at http://localhost:8765/docs (FastAPI/OpenAPI) while the server is running.


Connecting the Agentfy App

In Agentfy, add a bridge connection pointing at:

http://<hermes-host>:8765/api/v1

Or run hermes-bridge pair and scan the QR code. For remote access, put the bridge behind a tunnel (e.g. Cloudflare Tunnel) and point the app at the public HTTPS URL — the API path stays /api/v1.


Architecture

Agentfy app  ──HTTP/SSE──▶  Hermes Bridge (FastAPI)  ──sys.path import──▶  Hermes Agent
                                   │                                          (~/.hermes/)
                                   ├── server.py       REST + SSE routes
                                   ├── agent_proxy.py  spawns/streams the agent
                                   ├── hermes_env.py   locates Hermes, hardens imports
                                   ├── skills.py       scans ~/.hermes/skills, attach/detach
                                   ├── persistence.py  SQLite (~/.hermes/hermes.db)
                                   ├── models.py       pydantic request/response schemas
                                   └── cli.py          start/stop/status/restart/pair/doctor

Repo layout also includes:
  Dockerfile, docker-compose.yml, docker/s6-rc.d/   derived-image + s6 bridge service
  tests/                                            pytest suite (no live Hermes needed)
  install.sh                                        one-command host install

The bridge does not bundle Hermes — it locates an existing install at ~/.hermes/hermes-agent and imports run_agent / hermes_cli at runtime. Keys and config are read from and written to the standard ~/.hermes/ locations so the bridge and the Hermes CLI stay in sync.


Security Notes

  • API keys live only in ~/.hermes/.env on the host. The /settings/keys endpoints report status but never echo secret values.
  • The bridge binds 0.0.0.0 by default for LAN access. Do not expose it directly to the public internet — front it with an authenticated tunnel or reverse proxy.

License

MIT

About

REST + SSE bridge API exposing Hermes agents to the Agentfy app and HTTP clients

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages