# Hermes setup

> Install and run memory_tencentdb with Hermes: Docker greenfield image, attach to existing Hermes, provider directory naming, Gateway auto-discovery, and health verification.

- Repository: TencentCloud/TencentDB-Agent-Memory
- GitHub: https://github.com/TencentCloud/TencentDB-Agent-Memory
- Human docs: https://grok-wiki.com/public/docs/tencentcloud-tencentdb-agent-memory-5a33bbf5540a
- Complete Markdown: https://grok-wiki.com/public/docs/tencentcloud-tencentdb-agent-memory-5a33bbf5540a/llms-full.txt

## Source Files

- `README.md`
- `hermes-plugin/memory/memory_tencentdb/README.md`
- `hermes-plugin/memory/memory_tencentdb/__init__.py`
- `hermes-plugin/memory/memory_tencentdb/plugin.yaml`
- `hermes-plugin/memory/memory_tencentdb/supervisor.py`
- `docker/opensource/Dockerfile.hermes`
- `docker/opensource/README-hermes.md`
- `scripts/install_hermes_memory_tencentdb.sh`

---

---
title: "Hermes setup"
description: "Install and run memory_tencentdb with Hermes: Docker greenfield image, attach to existing Hermes, provider directory naming, Gateway auto-discovery, and health verification."
---

Hermes uses the Python provider under `hermes-plugin/memory/memory_tencentdb/` as a thin HTTP client and process supervisor. Capture, L1–L3 extraction, storage, and recall run in the Node.js Gateway (`src/gateway/server.ts`) on `127.0.0.1:8420` by default. Choose **Docker greenfield** (single image) or **attach to an existing Hermes** install.

```text
Hermes Agent (Python)
  MemoryManager
    └─ memory_tencentdb provider
         ├─ GatewaySupervisor  (start / health / log tail)
         └─ MemoryTencentdbSdkClient  →  HTTP 127.0.0.1:8420
                                              │
                                    memory-tencentdb Gateway (Node)
                                      └─ L0 → L1 → L2 → L3 core
```

| Hermes surface | Gateway route | Behavior |
|---|---|---|
| `prefetch(query)` | `POST /recall` | Sync; injects `<memory-context>` |
| `sync_turn(user, assistant)` | `POST /capture` | Background (max 4 in-flight) |
| `shutdown` / `on_session_end` | `POST /session/end` | Flush pipeline |
| `get_tool_schemas()` | — | `memory_tencentdb_memory_search`, `memory_tencentdb_conversation_search` |

<Note>
Provider directory name must be exactly `memory_tencentdb` (underscore). Hermes uses that directory name as the provider key. Config aliases `memory-tencentdb` and `tdai` resolve to the same provider; they are not valid directory names.
</Note>

## Prerequisites

| Requirement | Notes |
|---|---|
| Node.js ≥ 22 | Gateway runtime; Docker image installs Node 22 |
| Hermes Agent | Official install, or bundled in the Docker image |
| OpenAI-compatible LLM | Required for L1/L2/L3; Gateway reads `TDAI_LLM_*` or `tdai-gateway.json` |
| npm package | `@tencentdb-agent-memory/memory-tencentdb` (Docker and install script pull `@latest`) |

## Path A — Docker greenfield

Image build does **not** `COPY` local source. It installs the npm package, Hermes via the official installer, and symlinks the provider into Hermes bundled plugins.

### Build and run

```bash
cd docker/opensource

docker build -f Dockerfile.hermes -t hermes-memory .

docker run -d \
  --name hermes-memory \
  --restart unless-stopped \
  -p 8420:8420 \
  -e MODEL_API_KEY="your-api-key" \
  -e MODEL_BASE_URL="https://api.lkeap.cloud.tencent.com/v1" \
  -e MODEL_NAME="deepseek-v3.2" \
  -e MODEL_PROVIDER="custom" \
  -v hermes_data:/opt/data \
  hermes-memory
```

Image defaults: `MODEL_NAME=deepseek-v3.2`, `MODEL_BASE_URL=https://api.lkeap.cloud.tencent.com/v1`, `MODEL_PROVIDER=custom`. With that stack you can pass only `MODEL_API_KEY`. Any OpenAI-compatible endpoint works by setting the four `MODEL_*` vars.

### What the container does at start

1. Maps `MODEL_*` → `TDAI_LLM_*` for the Gateway.
2. Writes `/opt/data/config.yaml` with model settings and `memory.provider: memory_tencentdb`.
3. Writes `/opt/data/.env` with `OPENAI_API_KEY` for Hermes.
4. Starts the Gateway in the foreground on `:8420` (keeps the container alive).

Interact with Hermes:

```bash
docker exec -it hermes-memory hermes
```

### Docker environment

| Variable | Default | Role |
|---|---|---|
| `MODEL_API_KEY` | _(required at run)_ | Shared LLM key for Hermes + Gateway |
| `MODEL_BASE_URL` | Tencent LKE OpenAI path | LLM base URL |
| `MODEL_NAME` | `deepseek-v3.2` | Model id |
| `MODEL_PROVIDER` | `custom` | Hermes provider label |
| `TDAI_GATEWAY_PORT` | `8420` | Gateway listen port |
| `TDAI_GATEWAY_HOST` | `0.0.0.0` | Gateway bind (healthcheck uses localhost) |
| `TDAI_DATA_DIR` | `/opt/data/tdai-memory` | L0–L3 data root |
| `HERMES_HOME` | `/opt/data` | Hermes config/sessions home |
| `MEMORY_TENCENTDB_GATEWAY_HOST` | `127.0.0.1` | Plugin → Gateway host |
| `MEMORY_TENCENTDB_GATEWAY_PORT` | `8420` | Plugin → Gateway port |

### Docker data layout

```text
/opt/data/
├── tdai-memory/       # Gateway data (SQLite, scenes, persona, …)
├── sessions/
├── skills/
├── config.yaml        # generated at start
├── .env               # generated at start
└── gateway.log        # when present
```

## Path B — Attach to existing Hermes

Use this when Hermes is already installed on the host. Prefer `scripts/install_hermes_memory_tencentdb.sh` after Hermes is present, or follow the manual steps below.

### Install script (recommended)

```bash
# After Hermes install; Node ≥ 22 on PATH
bash scripts/install_hermes_memory_tencentdb.sh
```

The script:

1. Migrates legacy `~/tdai-memory-openclaw-plugin` and `~/memory-tdai` into `~/.memory-tencentdb/` when needed.
2. Downloads `@tencentdb-agent-memory/memory-tencentdb@latest` into `~/.memory-tencentdb/tdai-memory-openclaw-plugin`.
3. Runs `npm install` (and installs `tsx` if missing).
4. Symlinks the provider into `$HERMES_AGENT_DIR/plugins/memory/memory_tencentdb` (default `$HERMES_HOME/hermes-agent`).
5. Writes `MEMORY_TENCENTDB_GATEWAY_*` into `/etc/profile.d/memory-tencentdb-env.sh` and `~/.hermes/.env` (for systemd / interactive shells).
6. Does **not** auto-enable the provider; you must set `memory.provider` yourself.

Override roots with `MEMORY_TENCENTDB_ROOT`, `TDAI_INSTALL_DIR`, `TDAI_DATA_DIR`, `HERMES_AGENT_DIR`, `INSTALL_AS_USER`.

### Manual attach

<Steps>
<Step title="Install the npm package under the canonical root">
```bash
mkdir -p ~/.memory-tencentdb
TEMP_DIR=$(mktemp -d)
cd "$TEMP_DIR"
npm init -y --silent
npm install @tencentdb-agent-memory/memory-tencentdb@latest --omit=dev
cp -r node_modules/@tencentdb-agent-memory/memory-tencentdb \
      ~/.memory-tencentdb/tdai-memory-openclaw-plugin
rm -rf "$TEMP_DIR"

cd ~/.memory-tencentdb/tdai-memory-openclaw-plugin
npm install --omit=dev
npm install tsx
```
</Step>
<Step title="Link the provider (underscore directory name)">
```bash
rm -rf ~/.hermes/hermes-agent/plugins/memory/memory_tencentdb
ln -sf ~/.memory-tencentdb/tdai-memory-openclaw-plugin/hermes-plugin/memory/memory_tencentdb \
       ~/.hermes/hermes-agent/plugins/memory/memory_tencentdb
```

Developer symlink from a git checkout:

```bash
ln -s "$(pwd)/hermes-plugin/memory/memory_tencentdb" \
      <hermes-agent-checkout>/plugins/memory/memory_tencentdb
```
</Step>
<Step title="Enable the provider in Hermes config">
In `~/.hermes/config.yaml`:

```yaml
memory:
  provider: memory_tencentdb
  # aliases still accepted: memory-tencentdb, tdai
```
</Step>
<Step title="Configure Gateway env and LLM">
In `~/.hermes/.env` (authoritative for systemd-managed Hermes):

```bash
MEMORY_TENCENTDB_GATEWAY_CMD="sh -c 'cd ~/.memory-tencentdb/tdai-memory-openclaw-plugin && exec npx tsx src/gateway/server.ts'"
MEMORY_TENCENTDB_GATEWAY_HOST="127.0.0.1"
MEMORY_TENCENTDB_GATEWAY_PORT="8420"

# Gateway-side LLM (what src/gateway/config.ts actually reads)
TDAI_LLM_API_KEY="sk-..."
TDAI_LLM_BASE_URL="https://api.openai.com/v1"
TDAI_LLM_MODEL="gpt-4o"
```

Or write LLM (and other Gateway settings) to `~/.memory-tencentdb/memory-tdai/tdai-gateway.json`:

```json
{
  "llm": {
    "baseUrl": "https://your-api-endpoint/v1",
    "apiKey": "your-api-key",
    "model": "your-model-name"
  }
}
```
</Step>
<Step title="Start or let the supervisor start the Gateway">
See [Gateway startup options](#gateway-startup-options) below.
</Step>
</Steps>

### Default path map (host)

| Path | Purpose |
|---|---|
| `~/.memory-tencentdb/` | Unified install root (`MEMORY_TENCENTDB_ROOT`) |
| `…/tdai-memory-openclaw-plugin/` | Package extract + `node_modules` + Gateway source |
| `…/memory-tdai/` | Gateway data dir default (`TDAI_DATA_DIR`) |
| `…/memory-tdai/tdai-gateway.json` | Optional Gateway config file |
| `~/.hermes/config.yaml` | Hermes memory provider selection |
| `~/.hermes/.env` | Env for Hermes (and supervised Gateway child) |
| `~/.hermes/logs/memory_tencentdb/` | Supervisor stdout/stderr logs (default) |

## Provider discovery and directory naming

Hermes scans, in order:

1. **Bundled** — `<hermes-agent>/plugins/memory/<name>/` (preferred for this package).
2. **User** — `$HERMES_HOME/plugins/<name>/` (default `~/.hermes/plugins/`).

Requirements inside the provider dir:

- Directory name: `memory_tencentdb`
- Files: `__init__.py`, `plugin.yaml`, plus `client.py` / `supervisor.py`
- `__init__.py` must contain `MemoryProvider` or `register_memory_provider` (both present)

`plugin.yaml` metadata:

```yaml
name: memory_tencentdb
display_name: memory-tencentdb
hooks:
  - on_memory_write
  - on_session_end
aliases:
  - tdai
  - memory-tencentdb
```

Verify discovery from a Hermes checkout:

```bash
python -c 'from plugins.memory import discover_memory_providers; \
           [print(n, a) for n, _, a in discover_memory_providers()]'
# expect: memory_tencentdb ...
```

## Gateway startup options

| Option | When to use | Mechanism |
|---|---|---|
| **A — Auto-discovery** | Install at a well-known path; no `MEMORY_TENCENTDB_GATEWAY_CMD` | Provider finds `src/gateway/server.ts`, `Popen`s via `sh -c 'cd … && pnpm exec tsx …'` |
| **B — Explicit CMD** | Pin path; install script; systemd PATH issues | Set `MEMORY_TENCENTDB_GATEWAY_CMD` |
| **C — External process** | Docker CMD, `memory-tencentdb-ctl`, manual `npx tsx` | Provider sees `/health` and skips spawn |

### Auto-discovery search order

When `MEMORY_TENCENTDB_GATEWAY_CMD` is unset:

1. In-tree: plugin root’s `src/gateway/server.ts` (via `__file__` → parents)
2. `~/.memory-tencentdb/tdai-memory-openclaw-plugin/src/gateway/server.ts` (canonical)
3. `~/tdai-memory-openclaw-plugin/src/gateway/server.ts` (legacy)
4. `~/.hermes/plugins/tdai-memory-openclaw-plugin/src/gateway/server.ts` (legacy)

Success logs:

```text
memory-tencentdb Gateway command auto-discovered: …/src/gateway/server.ts
```

`MEMORY_TENCENTDB_GATEWAY_CMD` always wins over discovery.

### Supervisor behavior

- If `/health` already returns `status` in `ok` | `degraded`, attach and do not spawn.
- Otherwise spawn `MEMORY_TENCENTDB_GATEWAY_CMD` (or discovered command), wait up to **30s**, poll every **0.5s**.
- Gateway init runs on a **background thread** so Hermes is not blocked up to 30s; early turns no-op until ready.
- Logs: `MEMORY_TENCENTDB_LOG_DIR` or `~/.hermes/logs/memory_tencentdb` → `gateway.stdout.log` / `gateway.stderr.log`.
- Child stdout/stderr go to files (not pipes) to avoid pipe-buffer deadlock.
- Circuit breaker: **5** consecutive failures → pause **60s**.
- Capture back-pressure: max **4** in-flight `sync_turn` threads.
- Watchdog (~**10s**) can revive a dead Gateway without restarting Hermes.

### Day-2 ops with `memory-tencentdb-ctl`

```bash
# hermes mode: logs under ~/.hermes, enable-hermes-memory available
memory-tencentdb-ctl --hermes start
memory-tencentdb-ctl --hermes health
memory-tencentdb-ctl --hermes enable-hermes-memory
```

Default mode is **standalone** (does not touch `~/.hermes`). Use `--hermes` or `MEMORY_TENCENTDB_MODE=hermes` when integrating with Hermes. See [Gateway lifecycle](/gateway-ops).

## Environment variables (Hermes client)

<ParamField body="MEMORY_TENCENTDB_GATEWAY_HOST" type="string">
Default `127.0.0.1`. Gateway host for the Python client.
</ParamField>

<ParamField body="MEMORY_TENCENTDB_GATEWAY_PORT" type="string">
Default `8420`. Invalid or out-of-range values fall back to `8420`.
</ParamField>

<ParamField body="MEMORY_TENCENTDB_GATEWAY_CMD" type="string">
Shell command the supervisor `Popen`s. Install script resolves absolute `node` and uses `node --import tsx/esm` so systemd does not depend on nvm PATH.
</ParamField>

<ParamField body="MEMORY_TENCENTDB_LOG_DIR" type="string">
Supervisor log directory. Default `~/.hermes/logs/memory_tencentdb`.
</ParamField>

<ParamField body="MEMORY_TENCENTDB_GATEWAY_API_KEY" type="string">
Client Bearer token. Fallback: `TDAI_GATEWAY_API_KEY`. Does **not** enable Gateway auth; set `TDAI_GATEWAY_API_KEY` / `server.apiKey` on the Gateway separately.
</ParamField>

<ParamField body="TDAI_DATA_DIR" type="string">
Gateway data root. Not owned by the Python provider. Default `~/.memory-tencentdb/memory-tdai` (legacy `~/memory-tdai` if present).
</ParamField>

<ParamField body="TDAI_LLM_API_KEY" type="string" required>
Gateway LLM key (or set via `tdai-gateway.json` `llm.apiKey`). Required for L1/L2/L3.
</ParamField>

Data directory is resolved only inside the Gateway (`TDAI_DATA_DIR` → config file `data.baseDir` → defaults). `MEMORY_TENCENTDB_DATA_DIR` is not read.

## Health verification

Expected Gateway health statuses: `ok` or `degraded`.

```bash
# Host attach or published Docker port
curl -s http://127.0.0.1:8420/health

# Docker container
docker exec hermes-memory curl -s http://localhost:8420/health

# Optional recall smoke test
curl -s -X POST http://127.0.0.1:8420/recall \
  -H "Content-Type: application/json" \
  -d '{"query":"test","session_key":"debug"}'
```

| Check | Signal |
|---|---|
| Provider linked | Path ends with `plugins/memory/memory_tencentdb` |
| Provider enabled | `memory.provider: memory_tencentdb` in Hermes config |
| Gateway process | Listen on configured port; `/health` ok/degraded |
| Auto-discovery | Log line `Gateway command auto-discovered` |
| Tools visible | LLM sees `memory_tencentdb_*` tools after init |
| Auth (if enabled) | Client and Gateway share the same secret |

`GET /health` stays unauthenticated even when `TDAI_GATEWAY_API_KEY` is set (orchestrator probes).

## Troubleshooting

| Symptom | Likely cause | Action |
|---|---|---|
| `memory-tencentdb Gateway not available` | No CMD, no discovery hit, nothing on :8420, or crash | Check `gateway.stderr.log`; set `MEMORY_TENCENTDB_GATEWAY_CMD`; enable DEBUG for discovery path list |
| Wrong checkout started | Discovery preference order | Set `MEMORY_TENCENTDB_GATEWAY_CMD` explicitly |
| Provider missing from discovery | Hyphen dir name, wrong path, missing files | Use underscore dir; ensure `__init__.py` + `plugin.yaml` |
| Search tools empty | No Gateway and no CMD/PORT env | Set `MEMORY_TENCENTDB_GATEWAY_CMD` or PORT so schemas register optimistically |
| Circuit breaker tripped | 5 consecutive Gateway errors | Fix Gateway/LLM; wait 60s |
| Capture backlog | ≥4 in-flight syncs | Inspect L1/LLM timeouts on Gateway |
| Auth 401 | Gateway key set, client key missing/mismatch | Align `TDAI_GATEWAY_API_KEY` and `MEMORY_TENCENTDB_GATEWAY_API_KEY` |
| systemd PATH / nvm | `node`/`npx` not found | Re-run install script (absolute `node` in CMD) or use full path |
| Docker: no memory | Missing `MODEL_API_KEY` or volume not mounted | Pass `-e MODEL_API_KEY` and `-v …:/opt/data` |

Docker debug:

```bash
docker exec hermes-memory cat /opt/data/config.yaml
docker exec hermes-memory env | grep -E '(MODEL_|TDAI_LLM_)'
docker exec hermes-memory cat /opt/data/tdai-memory/gateway.log
```

## Related pages

<CardGroup>
<Card title="Overview" href="/overview">
Host surfaces: OpenClaw plugin vs Hermes Gateway.
</Card>
<Card title="Gateway lifecycle" href="/gateway-ops">
`memory-tencentdb-ctl` start/stop/status/health and path layout.
</Card>
<Card title="Secure the Gateway" href="/secure-gateway">
Bearer auth, CORS, client/server key alignment.
</Card>
<Card title="Gateway HTTP API" href="/gateway-http-api">
`/health`, `/recall`, `/capture`, search, seed routes.
</Card>
<Card title="Environment variables" href="/environment-variables">
`TDAI_*`, `MEMORY_TENCENTDB_*`, `MODEL_*` resolution order.
</Card>
<Card title="Agent tools" href="/agent-tools">
Hermes `memory_tencentdb_*` tool schemas and limits.
</Card>
<Card title="Troubleshooting" href="/troubleshooting">
Broader failure modes and probe checklist.
</Card>
</CardGroup>
