Setup & installation
What this seed does
seed-hermes gets the Hermes AI agent running on your own machine, entirely inside Docker, without installing any AI tooling directly on your computer. Once set up, you get a local web dashboard at http://localhost:9119 where you can start conversations, browse logs, configure plugins, and watch the agent work — all from your browser.
Files the agent creates or edits appear directly in a data/workspace/ folder on your computer, owned by you, so you can open them in any editor as if you'd created them yourself. Authentication with ChatGPT is handled through a guided OAuth flow: the seed walks you through visiting a URL and entering a code, then Hermes is ready to go.
The seed is intentionally generic — it provides the Hermes core with no platform-specific extras baked in. If you also want to chat with Hermes from your phone via iMessage or RCS, an optional companion seed adds that gateway on top.
When to use it
- I want to run a capable AI coding agent on my laptop without installing Python or any AI libraries directly on my machine.
- I want to try out Hermes and see what it can do through a local web dashboard before committing to any cloud setup.
- I want the agent to create and edit files on my computer so I can open them in my own editor without any file-permission headaches.
- I want to authenticate Hermes with my ChatGPT account through a simple browser login flow instead of managing API keys manually.
- I want a clean base to build on top of — adding a phone gateway or other platform later via an optional companion seed.
›View raw SEED.md
# Purpose
> See [[README#Purpose]].
## Normative Language
The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in RFC 2119.
## Dependencies
### Host tools
- Docker with Compose support MUST be available on the host.
- A POSIX shell and `curl` MUST be available on the host.
- A ChatGPT account capable of completing Hermes' `openai-codex` OAuth device-code flow MUST be available when model auth is performed.
### Optional platform gateway
- `https://github.com/plow-pbc/seed-hermes-plow-chat.git` is an OPTIONAL dependency: an iMessage/RCS platform gateway, built on the Plow Chat API, that lets the user chat with Hermes from their phone.
## Objects
### Hermes agent folder
- `hermes-agent/` is the Docker-only host workspace for Hermes Agent. ^obj-hermes-agent-folder
- `hermes-agent/compose.yaml` MUST define one service named `hermes` that uses the upstream image directly (`image: nousresearch/hermes-agent:latest`). It MUST NOT `build:` a derived image, MUST NOT set `entrypoint:`, MUST NOT set `user:`, and MUST NOT use `group_add:`. The image's s6-overlay `ENTRYPOINT` (`/init` + `/opt/hermes/docker/main-wrapper.sh`) and its `cont-init.d/01-hermes-setup` (the stage2-hook) are the canonical bootstrap path; overriding any of them re-introduces the v1/PR-#3 permission-model drift.
- The seed MUST NOT ship a `hermes-agent/Dockerfile`. The previous derived image (PRs #2/#3/#5) baked in the `/usr/local/bin/hermes` symlink, `jq`, and two Codex `'NoneType'` SDK patches. As of the 2026-05-27 `nousresearch/hermes-agent:latest` re-push, `hermes` is already on `$PATH` at `/opt/hermes/.venv/bin/hermes`, the Codex crash is fixed structurally, and the only remaining gap (`jq`) is handled by a single cont-init.d hook (see below).
- The seed MUST NOT ship a `hermes-agent/entrypoint/seed-entrypoint.sh`. The s6-overlay-based image now does what that wrapper did natively: stage2-hook handles `usermod` + targeted `chown` of `/opt/data` hermes-owned subdirs, and `main-wrapper.sh` drops privileges via `s6-setuidgid`. The previous wrapper called `gosu` which has been removed from the new image — a residual wrapper would fail-loud at boot.
- `hermes-agent/cont-init.d/50-install-jq.sh` MUST exist, MUST be executable, MUST start with `#!/usr/bin/with-contenv sh`, MUST be idempotent (exit 0 if `command -v jq` succeeds), and MUST be bind-mounted by `compose.yaml` to `/etc/cont-init.d/50-install-jq.sh:ro`. This is the only seed-owned cont-init hook — it covers the one binary the image still lacks. The bind mount MUST target a single file, NOT the parent directory, so the image's own `cont-init.d/015-supervise-perms` and `cont-init.d/02-reconcile-profiles` are not shadowed.
- Downstream seeds that need their own boot-time hooks SHOULD follow the same pattern: drop a script in their seed's `cont-init.d/` directory and bind-mount the single file into `/etc/cont-init.d/`. They MUST NOT rely on the retired `/opt/data/bin/entrypoint.d/` directory — that mechanism died with `seed-entrypoint.sh`.
- `hermes-agent/scripts/prepare.sh` MUST write a per-checkout `COMPOSE_PROJECT_NAME` and `HERMES_CONTAINER_NAME` into `hermes-agent/.env`; multiple seed checkouts MUST NOT share the default Compose project/container identity.
- `hermes-agent/compose.yaml` MUST set the container working directory to `/opt/data/workspace`, matching `terminal.cwd`, so agent environment hints and file tools agree on the host-visible default workspace.
- `hermes-agent/compose.yaml` MUST mount `./data` as the whole `/opt/data` volume.
- `hermes-agent/compose.yaml` MUST expose container ports `8642` and `9119`, with host ports overridable by `HERMES_API_PORT` and `HERMES_DASHBOARD_PORT`.
- `hermes-agent/compose.yaml` MUST set `HERMES_DASHBOARD=1` so `http://localhost:9119` serves the Hermes dashboard by default.
- The dashboard shows the local Hermes web UI for sessions, logs, configuration, plugins, and dashboard-backed tools. The Docker entrypoint binds it to `0.0.0.0` and uses the dashboard's `--insecure` flag; this is acceptable only for a disposable local container intended for loopback browsing.
- `hermes-agent/compose.yaml` MUST NOT enable the OpenAI-compatible API server on `8642` by default; external OpenAI-compatible clients require explicit API-server configuration and a key.
- `hermes-agent/compose.yaml` intentionally sets `HERMES_YOLO_MODE=1` so Hermes can act autonomously without approval prompts inside the disposable container.
- `hermes-agent/compose.yaml` intentionally sets `GATEWAY_ALLOW_ALL_USERS=true`; platform-specific seeds remain responsible for their own access boundary.
- `hermes-agent/.env` is local runtime state generated by `hermes-agent/scripts/prepare.sh`. It MUST set `COMPOSE_PROJECT_NAME`, `HERMES_CONTAINER_NAME`, `HERMES_UID`, and `HERMES_GID`, and MUST NOT be committed. It MUST NOT contain `HERMES_HOST_UID` or `HERMES_HOST_GID` — those keys were retired with `seed-entrypoint.sh`.
- `HERMES_UID` and `HERMES_GID` in `.env` MUST equal the host user's `id -u` and `id -g`. The image's stage2-hook reads these and `usermod`s the in-container `hermes` user to the host UID/GID before chowning hermes-owned subdirs of `/opt/data`. After remap, all bind-mounted writes land at host-owned UIDs, so host and container share `data/` without group_add / setgid / chmod gymnastics.
- `hermes-agent/scripts/prepare.sh` MUST be idempotent and MUST migrate stale `.env` files. Specifically it MUST: (a) rewrite `HERMES_UID=10000` and `HERMES_GID=10000` (the PR-#3/PR-#4 values) to `$(id -u)` / `$(id -g)`; (b) delete `HERMES_HOST_UID=*` and `HERMES_HOST_GID=*` entries (no longer needed). Running it on any earlier seed checkout MUST converge `.env` to the current contract.
- `hermes-agent/scripts/hermes-exec.sh` MUST wrap `docker compose exec` and always prepend `-u $HERMES_UID:$HERMES_GID` from `.env`. Any command this seed or a downstream seed runs inside the Hermes container — particularly `hermes profile create` — MUST go through this wrapper so it does not run as `root` and leave host bind-mounted files owned by `root:root`.
- `hermes-agent/scripts/yaml-get.sh` MUST exist, MUST read YAML keys from files under `/opt/data` via the container's Python (which has `PyYAML` baked in), and downstream seeds that today parse `data/config.yaml` host-side SHOULD switch to this helper so they do not require host `python3-yaml`.
### Hermes data folder
- `hermes-agent/data/` is `HERMES_HOME` inside the container. ^obj-hermes-data
- `hermes-agent/data/config.yaml` MUST exist before first boot.
- `hermes-agent/data/config.yaml` MUST set `terminal.cwd: /opt/data/workspace`.
- The container process cwd and `terminal.cwd` MUST both point at `/opt/data/workspace`; natural file-creation requests should therefore use `hermes-agent/data/workspace/` on the host without first trying `/opt/hermes`.
- `hermes-agent/data/config.yaml` MUST set `model.provider: openai-codex` and a default model.
- `hermes-agent/data/config.yaml` MUST NOT set `model.base_url` for `openai-codex`; Hermes uses its runtime default.
- `hermes-agent/data/workspace/` is the host-visible Hermes working directory.
- `hermes-agent/data/plugins/` is the host-visible plugin directory.
- `hermes-agent/data/.env` holds platform runtime values. It MUST NOT be committed.
- `hermes-agent/data/auth.json` is written by Hermes after ChatGPT OAuth succeeds. It MUST NOT be committed.
### Platform gateway
- A platform gateway is OPTIONAL. ^obj-platform-gateway
- This seed MUST NOT ship gateway install scripts or gateway-specific plugin files.
- Gateway plugins live under `hermes-agent/data/plugins/<name>/` on the host, which is `/opt/data/plugins/<name>/` inside the container.
- If a platform gateway is installed by its own seed, `hermes-agent/data/config.yaml` MUST enable that plugin under `plugins.enabled`.
- Platform-specific configuration, host orchestration, pairing, access control, and verification belong to the gateway seed.
## Actions
### Hermes scaffold is prepared
The agent prepares the Docker-only Hermes workspace without requiring host-local Hermes or Python. ^act-prepare-scaffold
1. Change into `hermes-agent/`.
2. Run `./scripts/prepare.sh`.
3. Confirm `data/config.yaml`, `data/workspace/`, `data/plugins/`, `data/profiles/`, `data/{cron,sessions,logs,hooks,memories,skills,skins,plans,home}/`, `.env`, and `data/.env` exist.
4. Confirm `.env` contains `HERMES_UID=10000`, `HERMES_GID=10000`, and `HERMES_HOST_UID` / `HERMES_HOST_GID` set to the host user's IDs.
5. Do not overwrite an existing `data/config.yaml`.
### Platform gateway choice is handled
The agent asks the user whether they want a platform gateway. ^act-platform-choice
1. Ask: "Want a platform gateway? I can follow the optional iMessage/RCS gateway seed so you can chat with Hermes from your phone."
2. If the user declines, leave `plugins.enabled` unchanged and continue with gateway-less Hermes.
3. If the user chooses a platform gateway, follow the optional dependency seed from `## Dependencies`.
4. After the gateway seed completes, confirm any installed plugin exists under `data/plugins/<name>/` and that `data/config.yaml` enables the plugin manifest name.
5. Do not run gateway-specific shell scripts from this seed; the gateway seed owns that path.
### ChatGPT OAuth is completed
The agent drives Hermes' `openai-codex` OAuth device-code flow headlessly. ^act-openai-codex-auth
1. Run `./scripts/auth-openai-codex.sh`, which invokes `docker compose run --rm -T hermes auth add openai-codex`.
2. Relay `https://auth.openai.com/codex/device` to the user.
3. Relay the code printed on the line after `2. Enter this code:`.
4. Wait for the user to complete browser approval.
5. Confirm Hermes prints `Added openai-codex OAuth credential #<N>` and writes `data/auth.json`.
6. Do not build provider introspection, `.env` BYOK branching, or automation around `hermes model`.
7. Advanced users who want a different provider MAY run `docker compose run --rm hermes model` themselves in a terminal.
### Hermes is started
The agent starts Hermes in Docker. ^act-start-hermes
1. Change into `hermes-agent/`.
2. Run `docker compose up -d`.
3. Probe readiness with `./scripts/check-ready.sh` or inspect logs for a gateway-ready line.
4. Browse `http://localhost:9119` and confirm the Hermes dashboard loads.
5. Confirm a file written from inside the container appears under `data/workspace/` and is editable by the host user.
6. If ports conflict, set `HERMES_API_PORT` or `HERMES_DASHBOARD_PORT` in `hermes-agent/.env` and restart.
### DTU mock service (optional)
- `hermes-agent/compose.dtu.yaml` is an OPTIONAL compose overlay that brings up a Flask-based hostex mock (DTU) on the same compose network as Hermes. ^obj-dtu
- DTU MUST NOT be brought up by default; it is opt-in via `docker compose -f compose.yaml -f compose.dtu.yaml up -d`.
- DTU MUST be reachable from the Hermes container at `http://dtu:8080` (compose-network DNS) so downstream seeds do not have to rely on `host.docker.internal` (which does not resolve inside Docker-in-Docker substrates).
- The DTU build context lives at `hermes-agent/dtu/`. The shipped `app.py` implements the minimal hostex contract documented in `hermes-agent/dtu/README.md`; it MAY be replaced with a richer implementation provided the same endpoint surface is preserved.
## Verify
1. From `hermes-agent/`, run `./scripts/verify.sh`; it MUST print `seed-hermes scaffold verifies`.
2. From `hermes-agent/`, run `./scripts/prepare.sh`; `.env` MUST contain `COMPOSE_PROJECT_NAME`, `HERMES_CONTAINER_NAME`, and the host user's `HERMES_UID` and `HERMES_GID`.
3. From `hermes-agent/`, run `docker compose up -d` and then `./scripts/check-ready.sh`; the dashboard readiness probe or a Hermes gateway-ready log probe MUST pass. Parallel checkouts MUST also use distinct `HERMES_API_PORT` and `HERMES_DASHBOARD_PORT` values.
4. From `hermes-agent/`, fetch `http://localhost:${HERMES_DASHBOARD_PORT:-9119}/`; it MUST return dashboard HTML.
5. From `hermes-agent/`, write a smoke file from inside the running container to `/opt/data/workspace/`; the same file MUST appear in `data/workspace/` and the host user MUST be able to edit it.
6. Secret hygiene MUST pass: `hermes-agent/.env`, `hermes-agent/data/.env`, and `hermes-agent/data/auth.json` are git-ignored; tracked files MUST NOT contain GitHub token env vars, GitHub PAT prefixes, model keys, platform secret values, or OAuth credentials; runtime logs MUST NOT be copied into commits or reports.
7. If a platform gateway was chosen, run that gateway seed's verification.
8. If the platform gateway was declined, Hermes MUST still boot and pass the readiness probe without any platform plugin enabled.
Maintainers SHOULD also run `bash ../seed/ref/verify.sh .` from the repo root when a sibling checkout of the SEED convention repo is available; it MUST print `tree conforms`.
## Feedback
(none)
›View raw README.md
# seed-hermes
## Purpose
`seed-hermes` is the gateway-agnostic Docker seed for running Hermes Agent locally. It gives a coding agent enough structure to create a `hermes-agent/` workspace, authenticate ChatGPT through Hermes' `openai-codex` OAuth flow, and start Hermes entirely in Docker with host-visible files under `./data`.
Natural file-creation requests land in `hermes-agent/data/workspace/` on the host. The container's process working directory and Hermes `terminal.cwd` are both `/opt/data/workspace`, so relative file writes and the agent's environment hint point at the same host-visible workspace.
`./scripts/prepare.sh` writes a per-checkout `COMPOSE_PROJECT_NAME` and `HERMES_CONTAINER_NAME` into `hermes-agent/.env`. That prevents a second local seed checkout from recreating or stopping another checkout's Hermes container. The default ports are still `8642` and `9119`, so parallel instances must also set distinct `HERMES_API_PORT` and `HERMES_DASHBOARD_PORT` values before starting Docker.
## Permission model — host + container share data/
The seed uses the upstream `nousresearch/hermes-agent:latest` image directly and lets its s6-overlay `/init` handle the bootstrap. Specifically, the image's `cont-init.d/01-hermes-setup` (the stage2-hook) does this on every container start:
1. Reads `HERMES_UID` and `HERMES_GID` from the environment, then `usermod -u $HERMES_UID hermes` and `groupmod -o -g $HERMES_GID hermes`. The in-container `hermes` user is now at the host user's UID/GID.
2. Targeted-chowns the hermes-owned subdirs of `/opt/data` (`cron`, `sessions`, `logs`, `hooks`, `memories`, `skills`, `skins`, `plans`, `workspace`, `home`, `profiles`) to the remapped uid/gid. Rootless-Podman-safe — `chown` failures don't abort.
3. The image's `main-wrapper.sh` (run as `/init`'s main program) drops privileges via `s6-setuidgid hermes` and exec's the command.
`prepare.sh` writes `HERMES_UID=$(id -u)` and `HERMES_GID=$(id -g)` to `hermes-agent/.env`. So after the stage2-hook remap, all bind-mounted writes land at host-owned UIDs — host and container share `data/` natively without any group_add, setgid, or chmod gymnastics.
Migration: `prepare.sh` rewrites stale `HERMES_UID=10000` / `HERMES_HOST_UID` / `HERMES_HOST_GID` keys (from earlier seed versions that used a derived image with a custom entrypoint) in place — running it on an existing checkout is enough.
## Why no derived image and no custom entrypoint
Earlier versions of this seed (PRs #2–#5) shipped:
- a derived `Dockerfile` (FROM nousresearch/hermes-agent) that baked in `jq`, a `/usr/local/bin/hermes` symlink, and two SDK patches for the Codex `'NoneType' object is not iterable` crash;
- a `seed-entrypoint.sh` that ran a `data/bin/entrypoint.d/*.sh` hook directory and `gosu`-dropped to the hermes user;
- a separate `hermes-init` Compose service (later folded into `seed-entrypoint.sh`) that chowned `/opt/data`.
The upstream image was re-pushed on 2026-05-27 with an s6-overlay rebuild that now does everything we patched:
| | Old image (PRs #3/#4/#5 targeted) | Current `:latest` |
|---|---|---|
| ENTRYPOINT | upstream `entrypoint.sh` (drops to hermes too early) | `/init` + `main-wrapper.sh` (s6-overlay) |
| `usermod` + chown | did not happen | stage2-hook (cont-init.d) |
| privilege drop | `gosu` | `s6-setuidgid` |
| `gosu` binary | present | **REMOVED** |
| `hermes` on `$PATH` | only via our symlink | `/opt/hermes/.venv/bin/` already on PATH |
| Codex `'NoneType'` SDK crash | required two build-time patches | fixed structurally |
| `jq` | absent (our Dockerfile installed) | **still absent** ← we ship a one-line cont-init hook |
Our seed-entrypoint.sh literally called `gosu` to drop privileges; against the new image it would fail-loud at boot. Rather than rev the wrapper, this version subtracts: no Dockerfile, no seed-entrypoint, no `user: "0:0"` override, no `group_add`. The compose file pulls `nousresearch/hermes-agent:latest` directly.
## Installing one missing package: `jq`
The new image still ships without `jq`, which downstream hostex-history-ingest scripts depend on. Rather than reintroduce a derived image just for one binary, the seed bind-mounts a single s6-overlay cont-init hook into the container:
```
./cont-init.d/50-install-jq.sh → /etc/cont-init.d/50-install-jq.sh
```
On every boot s6-overlay runs `/etc/cont-init.d/*` as root before any supervised service starts. `50-install-jq.sh` is idempotent — `command -v jq && exit 0` — and only runs `apt-get install -y --no-install-recommends jq` if the binary is missing. The image's own cont-init scripts (`015-supervise-perms`, `02-reconcile-profiles`) still run because we bind-mount a single file, not the whole directory.
If a future image bakes `jq` in, delete the hook file + the compose volume entry. The presence check makes the hook safe either way.
## Downstream seeds that need boot-time hooks
The old `data/bin/entrypoint.d/*.sh` directory has been retired (it was our entrypoint's invention; the upstream image doesn't know about it). Downstream seeds that need to re-apply runtime patches on every container start should follow the same pattern as `cont-init.d/50-install-jq.sh`:
1. Drop a script in your seed's own `cont-init.d/` directory.
2. Add a volume mount in your compose overlay:
```yaml
volumes:
- ./cont-init.d/<NN>-name.sh:/etc/cont-init.d/<NN>-name.sh:ro
```
3. Make the script idempotent. s6-overlay runs it as root before supervised services start, with `#!/usr/bin/with-contenv sh` to inherit the container's environment.
The seed is intentionally generic: platform-specific behavior lives in optional gateway seeds. This repo ships no gateway install scripts; gateway seeds own their own plugin files, host orchestration, and verification.
The Hermes dashboard is enabled by default at `http://localhost:9119`. It shows the local Hermes web UI for sessions, logs, configuration, plugins, and dashboard-backed tools. Inside Docker, the entrypoint binds it to `0.0.0.0` and passes the dashboard's `--insecure` flag; this is acceptable for the disposable local container because the published port is intended for loopback browsing. Do not expose `9119` beyond the trusted local machine.
The Docker compose defaults keep Hermes autonomous inside the disposable container: `HERMES_YOLO_MODE=1` lets the agent act without interactive approval prompts, and `GATEWAY_ALLOW_ALL_USERS=true` lets the gateway accept inbound platform users. Platform-specific seeds are responsible for their own access gates.
The OpenAI-compatible API server on `8642` is not enabled by default. It is only needed for external OpenAI-compatible clients such as Open WebUI or LibreChat, and should be configured with an API key when used.
## Running commands inside the container
`docker compose exec hermes <cmd>` defaults to **root** regardless of the image's `USER` directive. Any command that writes under `data/` (notably `hermes profile create <name>`) then leaves the resulting host bind-mounted files owned by `root:root`, which breaks every subsequent installer that tries to edit those files as the host user.
Always invoke `./scripts/hermes-exec.sh` instead. It is a thin wrapper that prepends `-u $HERMES_UID:$HERMES_GID` (from `.env`) to every `docker compose exec` call:
```sh
./scripts/hermes-exec.sh hermes profile create daniel
./scripts/hermes-exec.sh -T hermes profile list
./scripts/hermes-exec.sh hermes bash -lc 'hermes --version'
```
Downstream seeds (gbrain installer, airbnb-manager activation, etc.) should call `hermes-exec.sh` rather than raw `docker compose exec`.
## Reading config.yaml without host PyYAML
Clean substrate images often have no `python3-yaml` and can't `apt install` as a non-root user. The v2 substrate clean-install run hit this when the airbnb-manager preflight tried to parse `data/config.yaml` host-side: it silently treated the missing `import yaml` as "plugin not enabled" and aborted.
This seed ships `scripts/yaml-get.sh` which reads YAML keys via the **container's** Python (PyYAML is baked into the Hermes image):
```sh
./scripts/yaml-get.sh config.yaml model.provider # -> openai-codex
./scripts/yaml-get.sh config.yaml plugins.enabled # one item per line
./scripts/yaml-get.sh config.yaml plugins.enabled | grep -qx plow-chat-platform
```
Exit codes: `0` = found, `2` = key absent, `1` = file or YAML error. Downstream installers that today grep `data/config.yaml` host-side should switch to this helper.
## Other baked-in dependencies
`jq` is installed by the cont-init.d hook on first boot (see *Installing one missing package: `jq`* above). Re-pulling the image still requires `apt-get install` on boot, which is fast over a normal connection — but if you need it pre-baked, override the seed by building your own derived image.
`gh` (GitHub CLI) is **not** baked in. The seed and downstream installers always use the HTTPS-clone fallback (`git clone https://github.com/...`), so `gh` is purely optional convenience for human operators.
## Heads-up for downstream seeds
A few sharp edges this seed can't fix from its own scope; document them when you write installers that touch the Hermes container:
- **`hermes webhook subscribe` does not lazy-enable the webhook platform.** If a profile's `config.yaml` has no `platforms.webhook` block, `webhook subscribe` errors out with *"Webhook platform is not enabled."* Add the block first (or set `WEBHOOK_ENABLED=true`, `WEBHOOK_PORT=…`, `WEBHOOK_SECRET=…` in the profile `.env`) before calling `subscribe`. (Pi-substrate Issue 10.)
- **`docker compose exec hermes <cmd>` defaults to root.** Always go through `./scripts/hermes-exec.sh` so the command runs as the configured `HERMES_UID:HERMES_GID` and host bind-mounted writes stay host-owned.
- **`command: ["-p", "daniel", ...]` in a downstream compose file confuses the upstream entrypoint.** Either use the absolute hermes path (`command: ["/opt/hermes/.venv/bin/hermes", "-p", "daniel", "gateway", "run"]`) or, if the per-profile service inherits this seed's image, let `seed-entrypoint.sh` defensively wrap the args for you.
## DTU mock for E2E tests (opt-in)
When a downstream seed wants to drive end-to-end tests against a hostex-shaped webhook source, bring DTU up as a compose overlay rather than installing Flask + venv on the host:
```sh
docker compose -f compose.yaml -f compose.dtu.yaml up -d
```
DTU runs on the same compose network as Hermes, so the Hermes container reaches it at `http://dtu:8080` and the host reaches it at `http://localhost:${DTU_PORT:-8080}`. See `hermes-agent/dtu/README.md` for the implemented contract and how to swap in your own DTU implementation.
Version history
1 releaseInitial Seed Release.
Dependencies
4 required · 1 optional- SWDocker with Composerequired· link ›· verified present (smoke-tested against Docker Desktop; compose up -d confirmed working)
- SWPOSIX shell and curlrequired
- StateHERMES_UID / HERMES_GID runtime identityrequired· generated by prepare.sh from host `id -u` / `id -g`
Contributors
2 contributorsActivity
0 commentsYou need to be signed in with GitHub to comment.
No comments yet — be the first to share how this seed worked for you.
Similar seeds
Give your Hermes AI agent a persistent, searchable knowledge graph it can read and write without any image rebuild.
by @plow-pbcBoth enhance Hermes AI agents with persistent local storage and Docker-based deployment without requiring image rebuilds.
Loads your full Hostex guest-conversation history into an AI brain so your vacation-rental assistant can answer guest questions from real past exchanges.
by @plow-pbcRuns the foundational Hermes AI agent locally in Docker, which is the base platform this seed builds upon.
Turns your short-term rental AI assistant into a full team coordinator — routing guest questions to staff over iMessage and pinging you only to approve the final reply.
by @plow-pbcUses Hermes AI agent with Docker and iMessage gateway, but specialized for property management rather than generic agent use.
Connect your Hermes AI agent to iMessage/SMS by wiring it to the Plow Chat API via a direct-mounted gateway plugin.
by @plow-pbcProvides the base Hermes AI agent runtime that this seed extends with iMessage/SMS chat capabilities.