In a previous post, I covered what Hermes Agent is and why it matters. This time, I’m diving into the actual installation process — the choices I made, the problems I hit, and the optimizations I applied for my setup.
What the Installer Actually Does
Hermes Agent provides a one-liner installer:
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bashBut what does that script actually do? After reading through all 1,133 lines, here’s the execution order:
- OS detection — identifies Linux, macOS, or Windows (bails on native Windows, recommends WSL2)
- Installs
uv— the fast Python package manager from Astral, if not already present - Ensures Python 3.11 — downloads and manages it via
uv(no system Python needed) - Checks for Git — exits with distro-specific install instructions if missing
- Installs Node.js 22 — downloads the binary to
~/.hermes/node/and symlinks to~/.local/bin/ - Installs system packages —
ripgrep(fast search) andffmpeg(TTS audio), using apt/brew/pacman or cargo as fallback - Clones the repo — tries SSH first, falls back to HTTPS, to
~/.hermes/hermes-agent/. If already cloned, runsgit pull(stashing local changes with a restore prompt) - Creates a Python venv — via
uv venvwith Python 3.11 - Installs Python dependencies —
uv pip install -e ".[all]"with fallback to base install - Installs Node.js dependencies —
npm install+ Playwright Chromium, plus WhatsApp bridge deps - Sets up the
hermesCLI — symlinks the venv entry point to~/.local/bin/hermesand adds it to PATH in shell config - Creates config — copies
.envandconfig.yamltemplates to~/.hermes/, createsSOUL.mdpersona file, syncs bundled skills - Runs setup wizard — interactive
hermes setupfor API key configuration - Optionally starts the gateway — if a messaging token is configured, offers to install as a systemd service or background process
The script is well-designed for curl | bash piping — it reads interactive prompts from /dev/tty instead of stdin, so non-interactive mode works without hanging.
PyTorch CPU-Only Optimization
By default, uv pip install -e ".[all]" pulls in the full PyTorch build with CUDA support — which is unnecessary if you’re running on CPU or using an API-based LLM provider. The full CUDA build is several gigabytes larger.
I modified the installer to use the CPU-only PyTorch wheels by adding --extra-index-url https://download.pytorch.org/whl/cpu:
uv pip install --index-strategy unsafe-best-match \ --extra-index-url https://download.pytorch.org/whl/cpu \ -e ".[all]"The --index-strategy Gotcha
Without --index-strategy unsafe-best-match, this breaks. Here’s why:
uv has strict security around index priority. When a package (like requests) is found on the first index that contains it, uv only considers versions from that index — even if the version it needs is on a different index. Since PyTorch’s CPU wheel index hosts an outdated requests==2.28.1, uv refuses to look at PyPI for requests>=2.33.0.
The --index-strategy unsafe-best-match flag tells uv to pick the best matching version across all indexes, not just the first one. This way, PyTorch packages come from the CPU wheel index while everything else resolves from PyPI normally.
The error you’d see without this flag:
hint: `requests` was found on https://download.pytorch.org/whl/cpu, but not atthe requested version (requests>=2.33.0,<3). A compatible version may be availableon a subsequent index (e.g., https://pypi.org/simple). By default, uv will onlyconsider versions that are published on the first index that contains a givenpackage, to avoid dependency confusion attacks.Playwright Browser Reuse
Hermes Agent uses Playwright for browser automation. If you already have Playwright installed globally (like I do at version 1.59.1), you might wonder if it downloads another browser.
The answer depends on version matching:
- Browser binaries are stored in
~/.cache/ms-playwright/with version-pinned directories (e.g.,chromium-1208) - If the Playwright version in Hermes Agent’s
package.jsonmatches your global install, it reuses the cached browser — no extra download - If versions differ, a separate Chromium directory gets created alongside your existing ones — nothing gets overwritten
No special configuration needed. They coexist peacefully.
Can You Replace Node.js with Bun?
I looked into this since I prefer Bun’s speed. Hermes Agent’s Node.js dependencies are:
Root package.json:
| Package | Bun Compatible |
|---|---|
agent-browser ^0.13.0 | Likely yes |
@askjo/camoufox-browser ^1.0.0 | Uncertain — Firefox fork with possible native bindings |
WhatsApp bridge:
| Package | Bun Compatible |
|---|---|
@whiskeysockets/baileys 7.0.0-rc.9 | Yes — pure JS WebSocket library |
express ^4.21.0 | Yes |
qrcode-terminal ^0.12.0 | Yes |
pino ^9.0.0 | Partial — core works, some transports may break |
The dealbreaker: The installer runs npx playwright install --with-deps chromium, which uses Node.js APIs to detect the OS and install system libraries. Playwright’s --with-deps flag is known to be Node-specific and doesn’t work reliably under Bun.
Given that the installer isolates Node.js in ~/.hermes/node/ (~50MB) without interfering with anything else on the system, I decided to keep Node.js for this project. The risk/reward of swapping to Bun isn’t worth it here.
RL Training vs. Built-In Learning
One thing that confused me during installation: the [rl] extra is not included in [all]. The pyproject.toml has this:
all = [ "hermes-agent[modal]", "hermes-agent[messaging]", "hermes-agent[cron]", # ... everything else ... # rl is NOT here]At first I thought: does Hermes Agent actually learn without RL?
Yes, absolutely. The “learning” in Hermes Agent has nothing to do with RL training:
- Memory — persists knowledge across sessions in
~/.hermes/memories/ - Auto-generated skills — creates reusable skills from experience in
~/.hermes/skills/ - Conversation history — searches past conversations to recall context
- Self-improvement loop — creates skills from experience and improves them during use
The RL training ([rl] extra + tinker-atropos submodule) is for fine-tuning the LLM model weights — a separate, advanced workflow for researchers. It’s what Nous Research uses to produce models like DeepHermes-ToolCalling-Specialist-Atropos on HuggingFace.
The RL extra is excluded from [all] because:
- It pulls in
atroposlibandtinkerviagit+https://...— slow and can fail on network issues - It transitively depends on PyTorch (even if you’re using CPU-only wheels, it’s still heavy)
- It requires the
tinker-atroposgit submodule to be cloned separately - Only researchers doing RL training need it
You can install it manually anytime:
git submodule update --init tinker-atroposuv pip install -e "./tinker-atropos"Regular learning works out of the box without any of this.
Firecrawl Setup
Firecrawl (web scraping) is already included as a core Python dependency (firecrawl-py>=4.16.0). No extra installation needed — it’s part of the base dependencies, not even an extra.
To enable it, just add your API key to ~/.hermes/.env:
FIRECRAWL_API_KEY=fc-your-key-hereSign up at firecrawl.dev to get an API key.
What Gets Installed with [all]
For reference, here’s everything that .[all] pulls in:
Core (always installed):
openai, anthropic, httpx, requests, rich, prompt_toolkit, pyyaml, jinja2, pydantic, fire, tenacity, python-dotenv, exa-py, firecrawl-py, parallel-web, fal-client, edge-tts, PyJWT
Extras included in [all]:
| Extra | Purpose |
|---|---|
messaging | Telegram, Discord bots via python-telegram-bot, discord.py |
cron | Scheduled tasks via croniter |
cli | Terminal menu UI |
dev | pytest, debugpy, mcp |
tts-premium | ElevenLabs voice |
voice | Local STT with faster-whisper, audio input |
mcp | Model Context Protocol |
modal | Modal cloud compute |
daytona | Daytona dev environments |
pty | PTY process management |
honcho | Honcho AI integration |
homeassistant | Home Assistant control |
sms | SMS via aiohttp |
slack | Slack messaging |
acp | Agent Client Protocol |
dingtalk, feishu | Chinese messaging platforms |
Excluded from [all] (install manually):
| Extra | Reason |
|---|---|
matrix | python-olm is broken on modern macOS |
rl | Heavy ML dependencies, git submodules |
yc-bench | Benchmark tool, requires Python 3.12+ |
My Final Installation Command
After all the modifications, here’s what worked for my setup:
# Clone with submodulesgit clone --recurse-submodules https://github.com/NousResearch/hermes-agent.gitcd hermes-agent
# Install uvcurl -LsSf https://astral.sh/uv/install.sh | sh
# Create venvuv venv venv --python 3.11export VIRTUAL_ENV="$(pwd)/venv"
# Install with CPU-only PyTorchuv pip install --index-strategy unsafe-best-match \ --extra-index-url https://download.pytorch.org/whl/cpu \ -e ".[all]"
# Node.js dependencies (browser tools + WhatsApp)npm installnpx playwright install chromium
# Configuremkdir -p ~/.hermes/{cron,sessions,logs,memories,skills,pairing,hooks,image_cache,audio_cache,whatsapp/session}cp cli-config.yaml.example ~/.hermes/config.yamlcp .env.example ~/.hermes/.env
# Make hermes available globallymkdir -p ~/.local/binln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes
# Run setup wizardhermes setupPost-Installation: Setting Up CLI Skills
Hermes Agent ships with bundled skills, but its real power comes from creating project-specific skills that teach it how to use the CLIs already on your system. Rather than calling APIs directly, Hermes can delegate to system-installed tools — which means your other agents (Claude Code, Codex, etc.) and Hermes all share the same tools and authentication.
Here’s how I set up three essential skills: web search, library documentation, and issue tracking.
Tavily CLI (tvly) for Web Search
Hermes has built-in web search via the TAVILY_API_KEY env var, but I prefer using the Tavily CLI directly. This way every agent on my laptop uses the same interface.
# Installnpm install -g @tavily/cli
# Authenticate (one-time)tvly login --api-key tvly-YOUR_KEY
# Verifytvly authThe CLI supports --json output for agent-friendly parsing:
# Search with AI-generated answertvly search "Hermes Agent skills" --max-results 5 --include-answer basic --json
# Extract content from URLstvly extract https://example.com https://other.com --json
# Deep research (multi-step, takes minutes)tvly research "comprehensive analysis of X" --json
# Crawl a websitetvly crawl https://example.com --max-depth 2 --limit 20 --jsonTo create the skill, Hermes uses its skill_manage tool — but the key insight is that the skill file is just a markdown document at ~/.hermes/skills/research/tvly/SKILL.md. Hermes auto-loads skills when their trigger conditions match the current task.
Context7 CLI (ctx7) for Library Documentation
When coding, you often need up-to-date API docs. Context7 provides this without web searches — it serves curated, versioned documentation for libraries directly from the terminal.
# Install (via npm)npm install -g @upstash/context7
# Authenticate (one-time)ctx7 login
# Verifyctx7 whoamiThe workflow is two-step: resolve a library name to an ID, then query docs:
# Find the libraryctx7 library "react" --json# Returns IDs like /facebook/react, /reactjs/react.dev with trust scores
# Query documentationctx7 docs /facebook/react "useEffect cleanup" --json# Returns code snippets with descriptions and source linksEach result includes a benchmarkScore and trustScore to help pick the best source. If a library has tagged versions (e.g., v19_2_0), you can query specific versions.
Beads (bd) for Issue Tracking
Beads is a dependency-aware issue tracker backed by Dolt (versioned SQL). No server needed — it embeds a Dolt database in your project’s .beads/ directory.
# Install (Go binary)go install github.com/steveyegge/beads/cmd/bd@latest
# Initialize in a projectcd ~/my-projectbd init
# Verifybd whereOnce initialized, bd manages issues with dependency tracking:
# Session startbd prime # Load workflow contextbd ready # Show unblocked work
# Create and manage issuesbd create "Fix auth bug" -t bug -p 1bd update <id> --claim # Atomically claim workbd dep add <a> <b> # B blocks Abd close <id>
# Cross-session memorybd remember "auth uses JWT not sessions" --key auth-jwtbd recall auth-jwt
# Sync with teambd dolt push # Push to Dolt remoteWhat makes bd powerful for multi-agent workflows:
bd readyshows only issues with no blocking dependencies — perfect for agents to self-assign workbd dep addprevents agents from duplicating effort on dependent tasksbd worktreecreates parallel git worktrees that share the same issue databasebd mol pourinstantiates reusable workflow templates (molecules) from formulas
Registering as a Hermes Skill
For each CLI, creating a Hermes skill is straightforward. Skills live at ~/.hermes/skills/<category>/<name>/SKILL.md with YAML frontmatter and a markdown body containing usage instructions, examples, and pitfalls.
---name: tvlydescription: "Tavily CLI for web search, extraction, crawling, and deep research. Triggers: web search, tavily, tvly."---The critical part is the description field — Hermes scans all skill descriptions against the current task and auto-loads matching skills. For tvly, triggers include “web search”, “tavily”, and “tvly”. For ctx7, triggers include “library docs”, “framework documentation”, and “API reference”.
Hermes also persists user preferences in memory so it doesn’t need to re-learn them each session. For example, I told it to always prefer system-installed CLIs over npx or bunx, and to ask before installing anything not already on the system. These preferences survive across sessions.
Integrating with Other Agents
The nice thing about using CLIs instead of direct API calls: every agent benefits. bd has built-in setup recipes for Claude Code, Codex, OpenCode, Cursor, Windsurf, and others:
bd setup claude # Install Claude Code hooks (SessionStart, PreCompact)bd setup codex # Add to AGENTS.mdbd setup opencode # Add to AGENTS.mdThis injects beads workflow instructions into each agent’s config file — CLAUDE.md, AGENTS.md, or rules files. For Hermes, I registered a custom recipe:
bd setup --add hermes ~/.beads/recipes/hermes.mdThis writes beads rules into AGENTS.md that tell Hermes to use bd instead of its built-in todo tool, and to run bd prime at session start for workflow context.
The same principle applies to tvly and ctx7 — since they’re system CLIs, any agent with terminal access can use them. No API keys to manage per-agent, no MCP servers to configure, no duplicate setup.
References
- Nous Research. Hermes Agent Documentation — Installation. Accessed 5 Apr. 2026.
- Nous Research. Hermes Agent GitHub Repository. Accessed 5 Apr. 2026.
- Astral. uv pip install — Index Strategy. Accessed 5 Apr. 2026.
- PyTorch. Installing CPU-Only PyTorch. Accessed 5 Apr. 2026.
- Tavily. Tavily CLI Documentation. Accessed 5 Apr. 2026.
- Context7. Context7 — LLM Context as a Service. Accessed 5 Apr. 2026.
- Steve Yegge. Beads — Dependency-Aware Issue Tracker. Accessed 5 Apr. 2026.
This article was written by opencode (GLM-5-Turbo | Z.AI Coding Plan).

