# Hermes Start

> Boot full Hermes Agent local stack on macOS — Ollama service, hermes3:8b model warmup, Hermes Desktop GUI, optional gateway. Use when user says /hermes-start, "hermes-start", "harmes-start" (common typo), "start hermes", "spin up hermes", "launch hermes desktop", "run hermes agent locally", or "boot hermes stack".

- Skill: `rohitguta2432/hermes-start` (Agent Skill)
- Install (CLI): `npx skillmds@latest add rohitguta2432/hermes-start`
- Raw SKILL.md: https://api.skillmd.com/api/skills/rohitguta2432/hermes-start/raw
- Safety review: WARNING
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: rohitguta2432 (https://skillmd.com/u/rohitguta2432)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/rohitguta2432/hermes-start

---


# Start Hermes Agent Stack (macOS)

Bring up local agent infra end-to-end on macOS (tested on Apple Silicon, Darwin 25.x):
1. Ollama runtime (port 11434) — model server
2. hermes3:8b model loaded + warmed in RAM
3. Hermes web dashboard UI (port 9119)
4. Optional: Hermes gateway (Telegram/Slack/WhatsApp)

Print final URL at end. All local. No API key. $0 cost.

## Prerequisites (must already be installed)

This skill BOOTS the stack — it does not install it. Required:
- **Ollama** — `/Applications/Ollama.app` or `brew install ollama` (provides `/opt/homebrew/bin/ollama` on Apple Silicon, `/usr/local/bin/ollama` on Intel)
- **Hermes Agent** — installed to `~/.hermes/hermes-agent/` with `hermes` CLI on PATH at `~/.local/bin/hermes`. Official install (does both Python 3.11 via `uv` AND Node 22 LTS to `~/.hermes/node/`):
  ```bash
  curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
  ```
  Then `pip install hermes-agent[web]` (or `uv pip install -e ".[all,dev]"` from source) for the dashboard.
- **Node 22** — bundled at `~/.hermes/node/` by the official installer. Only need standalone `fnm` if you skipped the installer.
- ~5 GB free disk for `hermes3:8b`

If any are missing, the skill reports the gap and stops — do NOT attempt to install Ollama or other system tooling unless the user explicitly authorizes.

**Current upstream version: v0.15.0 (May 16, 2026)** — repo: https://github.com/NousResearch/hermes-agent

### Install gotchas learned the hard way (macOS, no Homebrew)

These are the failure modes encountered during a fresh bootstrap on an Apple Silicon Mac WITHOUT Homebrew. The official installer mostly works, but expect:

1. **Optional brew packages skip gracefully.** The installer's `ripgrep` and `ffmpeg` step shows `⚠ Could not auto-install (brew not found or install failed)` — this is fine; Hermes runs without them (you lose fast file search and TTS voice messages).
2. **Git clone may fail with HTTP/2 stream cancel.** Symptom: `error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8)`. Retry with HTTP/1.1 and shallow:
   ```bash
   rm -rf ~/.hermes/hermes-agent
   git -c http.version=HTTP/1.1 clone --depth=1 https://github.com/NousResearch/hermes-agent.git ~/.hermes/hermes-agent
   ```
3. **`uv pip install --system -e ".[all]"` picks system Python 3.9 and fails.** Hermes needs Python `>=3.11`. The installer normally creates a venv; if you're re-doing this manually:
   ```bash
   cd ~/.hermes/hermes-agent
   uv venv .venv --python 3.11
   source .venv/bin/activate
   uv pip install -e ".[all]"
   ```
4. **`hermes` CLI symlink is created at `~/.local/bin/hermes` by the installer**, but if the install aborted before that step you must symlink yourself:
   ```bash
   ln -sf ~/.hermes/hermes-agent/.venv/bin/hermes ~/.local/bin/hermes
   ```
5. **Ollama direct-download path** (no Homebrew): grab the .zip, extract, and symlink the CLI from inside the .app bundle. The CLI is at `Contents/Resources/ollama`, **NOT** `Contents/MacOS/Ollama` (which is the GUI binary):
   ```bash
   curl -fL -o /tmp/Ollama-darwin.zip https://ollama.com/download/Ollama-darwin.zip
   unzip -q /tmp/Ollama-darwin.zip -d /tmp/ollama-extract/
   mv /tmp/ollama-extract/Ollama.app ~/Applications/
   ln -sf ~/Applications/Ollama.app/Contents/Resources/ollama ~/.local/bin/ollama
   ```
6. **PATH bootstrap** — after install, add to `~/.zshrc` (the installer warns about this but doesn't always patch it):
   ```bash
   export PATH="$HOME/.local/bin:$HOME/.hermes/node/bin:$PATH"
   ```
   `~/.local/bin` provides `hermes`, `ollama`, `uv`, `python3.11`. `~/.hermes/node/bin` provides bundled Node 22.
7. **Headless Ollama server** — instead of `open -a Ollama` (which launches the GUI), run the CLI server directly so it survives without a GUI session:
   ```bash
   nohup ollama serve > /tmp/ollama.log 2>&1 & disown
   ```

## Steps

### 1. Ollama service (port 11434)

macOS uses launchd / brew services, not systemctl. Check three install paths:

```bash
# Already running? (most common case after first boot)
lsof -nP -iTCP:11434 -sTCP:LISTEN 2>/dev/null | grep -q LISTEN && echo "ollama up" || echo "needs start"
```

If not running, start by whichever install method exists:

```bash
# brew-installed
brew services list 2>/dev/null | grep -q "ollama.*started" || brew services start ollama 2>/dev/null

# .app bundle (Ollama.app's bundled server)
[ -d /Applications/Ollama.app ] && open -a Ollama 2>/dev/null

# direct binary fallback (no brew, no .app)
pgrep -f "ollama serve" >/dev/null || (nohup ollama serve > /tmp/ollama.log 2>&1 & disown)
```

Verify port reachable:

```bash
curl -sf http://localhost:11434/api/tags >/dev/null && echo "ollama API ready"
```

### 2. Model present

REQUIRED: `hermes3:8b` (only model used — no fallback per user spec).

```bash
ollama list | grep -q "hermes3:8b" || ollama pull hermes3:8b
```

Pull takes ~5–8 min on average broadband (4.7 GB). Run in background if missing; wait before warmup. Do NOT swap to llama3.1 or any fallback — user wants hermes3 only.

### 3. Warmup model into RAM

Reduces first-prompt latency from ~30s → ~1s:

```bash
curl -s http://localhost:11434/api/generate -d '{"model":"hermes3:8b","keep_alive":"30m"}' >/dev/null
```

`keep_alive=30m` keeps weights resident. Apple Silicon Metal acceleration is used automatically by Ollama — no config needed.

### 4. Hermes CLI sanity check

```bash
hermes --version
hermes status 2>&1 | head -20
```

If `hermes status` errors on provider, verify config:

```bash
grep -E "^  (provider|default|model|base_url):" ~/.hermes/config.yaml
```

Expected (verified against Hermes Agent **v0.14.0** runtime, May 2026):
```yaml
model:
  provider: custom
  base_url: http://localhost:11434/v1
  model: hermes3:8b
  default: hermes3:8b
```

Also set in `~/.hermes/.env`:
```
OPENAI_API_KEY=ollama
```

**CRITICAL — `provider` value must come from `hermes doctor`'s known-providers list.** The runtime in v0.14.0 lists exactly these (run `hermes doctor` to re-fetch — list can change between versions):

```
ai-gateway, alibaba, alibaba-coding-plan, anthropic, arcee, auto,
azure-foundry, bedrock, copilot, copilot-acp, custom, deepseek,
gemini, gmi, google-gemini-cli, huggingface, kilocode, kimi-coding,
kimi-coding-cn, lmstudio, minimax, minimax-cn, minimax-oauth, nous,
novita, novita-ai, novitaai, nvidia, ollama-cloud, openai-codex,
opencode-go, opencode-zen, openrouter, qwen-oauth, stepfun,
tencent-tokenhub, xai, xai-oauth, xiaomi, zai
```

For a local Ollama server, use **`custom`** (OpenAI-compatible endpoint). Do NOT use:
- `main` — was suggested by some doc pages, but rejected by runtime as "Unknown provider 'main'"
- `ollama` — not in the list (only `ollama-cloud` for the hosted service)
- `lmstudio` — only valid for actual LM Studio, not Ollama

To verify: `hermes doctor` should print `✓ model.provider 'custom' is a recognised provider`.

Configure via: `hermes config set model.provider custom` (then `hermes config set model.default hermes3:8b`, etc.) — writes directly to `~/.hermes/config.yaml`.

**After changing config, restart the dashboard** so it re-reads:
```bash
hermes dashboard --stop && nohup hermes dashboard --no-open --tui > /tmp/hermes-dashboard.log 2>&1 & disown
```
Then refresh the browser tab — the chat tab caches the init result.

### 5. Web dashboard UI (port 9119)

PREFERRED UI = web dashboard. (The macOS Electron `.app` may launch silently from a non-GUI exec env — skip it from inside this skill; user can double-click Hermes.app themselves.)

**CRITICAL pre-reqs (else "Chat unavailable: 1"):**
- `hermes-agent[web]` extra installed (`pip install hermes-agent[web]` or `uv pip install -e ".[all]"`)
- Node 22 MUST be first in PATH when starting dashboard. Prefer the **bundled** Node at `~/.hermes/node/bin/node` (installed automatically by `install.sh`). Fall back to `fnm exec --using=22.22.2` only if the bundled Node is absent.
- Web UI dist built (`hermes_cli/web_dist/assets/`)
- TUI dist built (`ui-tui/dist/entry.js`) — chat tab spawns this subprocess

Skip if already up:

```bash
lsof -nP -iTCP:9119 -sTCP:LISTEN 2>/dev/null | grep -q LISTEN && echo "dashboard up" || echo "needs start"
```

Resolve Node 22 path (bundled preferred, fnm fallback):

```bash
if [ -x ~/.hermes/node/bin/node ]; then
  NODE22_DIR=~/.hermes/node/bin
elif command -v fnm >/dev/null; then
  NODE22_DIR=$(dirname $(fnm exec --using=22.22.2 -- which node))
else
  echo "ERROR: No Node 22 available. Run the official installer or 'brew install fnm && fnm install 22.22.2'." && exit 1
fi
echo "Using Node at: $NODE22_DIR"
```

Build web UI if missing:

```bash
[ -f ~/.hermes/hermes-agent/hermes_cli/web_dist/index.html ] || \
  (cd ~/.hermes/hermes-agent/web && \
   PATH="$NODE22_DIR:$PATH" npm install && \
   PATH="$NODE22_DIR:$PATH" npm run build)
```

Build TUI if missing (REQUIRED for Chat tab):

```bash
[ -f ~/.hermes/hermes-agent/ui-tui/dist/entry.js ] || \
  (cd ~/.hermes/hermes-agent/ui-tui && \
   PATH="$NODE22_DIR:$PATH" npm install --no-fund --no-audit && \
   PATH="$NODE22_DIR:$PATH" npm run build)
```

Start dashboard with Node 22 PATH + TUI tab:

```bash
PATH="$NODE22_DIR:$PATH" nohup hermes dashboard --no-open --tui > /tmp/hermes-dashboard.log 2>&1 & disown
```

Wait + verify:

```bash
sleep 6 && hermes dashboard --status && lsof -nP -iTCP:9119 -sTCP:LISTEN 2>/dev/null
```

Confirm Node 22 inherited (macOS uses `ps eww`, not `/proc/$PID/environ`):

```bash
PID=$(pgrep -f "hermes dashboard")
ps eww -p $PID 2>/dev/null | tr ' ' '\n' | grep "^PATH=" | head -1
```

URL: **http://127.0.0.1:9119** (token auto-injects on page load — no manual auth)

**Debug "Chat unavailable: 1":** means `_make_tui_argv` in `hermes_cli/main.py:1075` did `sys.exit(1)`. Causes: node/npm missing in PATH, ui-tui not built, or npm install failed. Check `/tmp/hermes-dashboard.log` for "npm install failed" or "TUI build failed".

Optional native Hermes.app (only if user explicitly asks — launches the Electron desktop UI):
```bash
[ -d /Applications/Hermes.app ] && open -a Hermes
```

### 6. Optional — Gateway (only if user asks)

For Telegram/Slack/WhatsApp inbound messaging:

```bash
nohup hermes gateway start > /tmp/hermes-gateway.log 2>&1 & disown
```

Skip unless user explicitly requests messaging integrations.

### 7. Status report + URL

Print table to user with the **UI URL prominently** at end:

| Component | Status | Endpoint |
|-----------|--------|----------|
| Ollama | active | http://localhost:11434 |
| Model | hermes3:8b loaded + warmed | — |
| Hermes CLI | ready | `hermes chat` |
| Web Dashboard | **UP** | **http://127.0.0.1:9119** |
| Gateway | (skipped unless asked) | — |

Final line MUST be a clickable URL line:

```
🌐 Open: http://127.0.0.1:9119
```

## Notes

- Apple Silicon Macs use Metal acceleration via Ollama automatically — no GPU flags. Expect ~25–40 tok/s for `hermes3:8b` on M1/M2/M3 with 16 GB+ RAM. Intel Macs fall back to CPU (~6–10 tok/s).
- Ollama `keep_alive` evicts model after timeout — re-warmup if cold-start latency returns.
- Hermes config: `~/.hermes/config.yaml`. Edit `provider`/`default`/`base_url` to swap backend.
- Logs: `/tmp/ollama.log` (only if started via nohup; brew services logs to `$(brew --prefix)/var/log/ollama.log`), `/tmp/hermes-dashboard.log`, `/tmp/hermes-gateway.log`. `/tmp` is wiped on reboot.
- If port 11434 is occupied by a stale `ollama serve`, identify with `lsof -nP -iTCP:11434 -sTCP:LISTEN` — don't kill blindly.
- Disk: each model ~5 GB. Check free space: `df -h ~ | tail -1`.
- macOS firewall (System Settings → Network → Firewall) may prompt the first time `ollama serve` binds. Allow it.
- If `hermes`/`ollama`/`fnm` are not on PATH inside this skill's shell, source the user's profile first:
  ```bash
  [ -f ~/.zprofile ] && source ~/.zprofile
  [ -f ~/.zshrc ] && source ~/.zshrc
  ```
  Apple Silicon Homebrew installs to `/opt/homebrew/bin`; Intel to `/usr/local/bin`.

## Alternative backend: Claude via OAuth (no longer free with Pro/Max — May 2026)

Hermes ships an OAuth/PKCE flow that lets the user authenticate against Anthropic via their Claude.ai account (`hermes_cli/main.py:_run_anthropic_oauth_flow` and `agent/anthropic_adapter.run_hermes_oauth_login_pure`). **Two important facts to surface up front, NOT after the user logs in:**

1. **`hermes -z PROMPT` is silent on backend errors.** If Anthropic returns a 4xx, `hermes -z` exits 0 with empty stdout. Always inspect `~/.hermes/sessions/request_dump_*.json` when output is empty — the error body is there.
2. **The Pro/Max OAuth path returns different errors depending on the day** — both expose the same underlying gate:
   - Sometimes: `HTTP 400 invalid_request_error "Third-party apps now draw from your extra usage, not your plan limits. Add more at claude.ai/settings/usage and keep going."` — a hard policy refusal.
   - Sometimes: `HTTP 429 rate_limit_error {"message":"Error"}` — opaque body, no Retry-After. Anthropic hides the real cap.
   - Same Claude.ai account quota appears to be **shared across tools** — if the user is concurrently using Claude Code on the same account, Hermes calls get throttled even when the policy block isn't tripped.
   The OAuth token always authenticates (no 401), but inference is gated. Two ways to make this work: (a) add extra-usage credits at https://claude.ai/settings/usage AND ensure no concurrent heavy use of the same account elsewhere, or (b) use Path C (paid `ANTHROPIC_API_KEY`).

So when a user asks "can Hermes use Claude without an API key?" the honest answer is now:
- **Path A** (auto-link Claude Code credentials): only works if standalone Claude Code CLI is installed and logged in — fails in Agent SDK / IDE host environments because the host manages credentials privately.
- **Path B** (Claude.ai OAuth via PKCE): wires up, but inference is blocked unless the user has paid extra-usage credits. Effectively not free.
- **Path C** (Anthropic API key): paid pay-per-token, always works.

Default to **local Ollama** for genuinely-free local inference. The skill's main flow assumes this. The OAuth code path remains in Hermes — and may resume working for free if Anthropic reverses the policy — but as of May 2026 it requires payment.

If the user explicitly wants to try Path B anyway (e.g. they've added extra-usage credits):
1. `hermes config set model.provider anthropic`
2. `hermes config set model.default claude-opus-4-7` (or whichever model)
3. Trigger the PKCE flow by importing `agent.anthropic_adapter.run_hermes_oauth_login_pure` in the venv Python, OR run `hermes model` interactively and pick option 1 from the auth-method menu.
4. After login, the access_token + refresh_token persist to `~/.hermes/.anthropic_oauth.json` in **camelCase** schema: `{accessToken, refreshToken, expiresAt, scopes}`. Do NOT use snake_case — `read_hermes_oauth_credentials()` will silently ignore it.

