Agent skill

Hermes Agentvibes Hook

by paulpreibisch in paulpreibisch/AgentVibes

Auto-speak every Hermes response via AgentVibes TTS on a remote machine over SSH.

Apache-2.0Auto-check: warningsMedia & Creative

Install Hermes Agentvibes Hook

The automated check flagged lines worth reading first. See the safety section below.

skills CLI
$ npx skills add paulpreibisch/AgentVibes --skill hermes-agentvibes-hook -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install paulpreibisch/AgentVibes hermes-agentvibes-hook --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/paulpreibisch/AgentVibes.git skills-src && mkdir -p .claude/skills && cp -r skills-src/docs/hermes/skills/tts/hermes-agentvibes-hook .claude/skills/hermes-agentvibes-hook && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
hermes-agentvibes-hook
GitHub stars
155
Token cost
~2.3k tokens
SKILL.md length
414 words
Files
3
Skills in repo
6
Repo updated
First seen
Licence
Apache-2.0

At a glance

Auto-speak every Hermes response via AgentVibes TTS on a remote machine over SSH.

  • Works in 5 steps: Install AgentVibes on the target machine… → Generate an SSH key on the Hermes server → Create the hook directory and files → …
  • Tasks that involve Text to speech and voice
  • SKILL.md covers Architecture, Setup, Configuration Reference and How It Works, plus 2 more sections
  • Runs Python scripts from its folder; calls npx; needs AGENTVIBES_SSH_KEY

What it does

Hermes Agentvibes Hook is an agent skill from paulpreibisch/AgentVibes. Auto-speak every Hermes response via AgentVibes TTS on a remote machine over SSH. Portable skill — works with any AgentVibes setup.

Its SKILL.md is about 2.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files (for example `HOOK.yaml` and `handler.py`).

It sits in Media & Creative, covering Text to speech and voice. The repository describes itself as: 🎭 TTS for Claude Code. The licence is Apache-2.0.

When your agent uses it

  • Tasks that involve Text to speech and voice

Example prompts

  • “/hermes-agentvibes-hook”

Requirements

  • Python 3
  • Node.js
  • Docker
  • A credential in AGENTVIBES_SSH_KEY

Workflow steps

5 steps, taken from the step headings in SKILL.md.

  1. Install AgentVibes on the target machine (the one with speakers)
  2. Generate an SSH key on the Hermes server
  3. Create the hook directory and files
  4. Restart gateway
  5. Verify

What it can do on your machine

Read from SKILL.md and the folder at commit f62c8ff. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships script files (Python), which the agent can run.

    Shell commands in SKILL.md call:

    • npx

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npx, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • AGENTVIBES_SSH_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Hermes Agentvibes Hook loads about 2.3k tokens when it runs. Until then it costs about 39 tokens; SKILL.md has 414 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~39
When it runs · the whole SKILL.md, loaded when a task matches
~2.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: warnings

The automated check found patterns that need a careful read before installing.

  • WarningMentions a credentials file (SSH keys, cloud or package-manager tokens)SKILL.md:75
    GENTVIBES_SSH_KEY  = "/absolute/path/to/id_ed25519"   # no tilde — subprocess won't expand it

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from paulpreibisch/AgentVibes at commit f62c8ff, republished under its Apache-2.0 licence (© paulpreibisch). 414 words, ~2,335 tokens.

Download SKILL.mdSave it as .claude/skills/hermes-agentvibes-hook/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
hermes-agentvibes-hook
description
Auto-speak every Hermes response via AgentVibes TTS on a remote machine over SSH. Portable skill — works with any AgentVibes setup.
category
tts

Hermes ↔ AgentVibes TTS Hook

Send every Hermes response as spoken audio to a remote machine via the AgentVibes SSH receiver.

Architecture

Hermes (server/Docker)
  └── agent:end event fires
      └── hooks/agentvibes-tts/handler.py
          └── strip markdown, truncate at word boundary
          └── JSON payload → base64-encode
          └── SSH → agentvibes-receiver@<host>:<port>
              └── Remote machine queues & plays via Piper TTS

Setup

1. Install AgentVibes on the target machine (the one with speakers)
bash
npx agentvibes install
2. Generate an SSH key on the Hermes server
bash
ssh-keygen -t ed25519 -f /absolute/path/to/id_ed25519_agentvibes -N ""

Use an absolute path — tilde (~) expansion does not work inside Python subprocess argument lists.

Register the public key on the target machine's agentvibes-receiver user.

3. Create the hook directory and files

Create <hermes_home>/hooks/agentvibes-tts/HOOK.yaml:

yaml
name: agentvibes-tts
description: Send agent responses to AgentVibes TTS remotely
events:
  - agent:end

Create <hermes_home>/hooks/agentvibes-tts/handler.py — update the four config constants at the top:

python
"""
AgentVibes TTS Hook — fires on agent:end to speak the agent's response.

Sends the response via SSH to the AgentVibes receiver using the full JSON
payload format (supports voice, project, effects metadata).
"""

import asyncio
import base64
import json
import logging
import os
import re
import subprocess
import time

# ---------------------------------------------------------------------------
# Configuration
# ---------------------------------------------------------------------------

AGENTVIBES_SSH_KEY  = "/absolute/path/to/id_ed25519"   # no tilde — subprocess won't expand it
AGENTVIBES_HOST     = "<target-ip-or-hostname>"
AGENTVIBES_PORT     = "<receiver-port>"
AGENTVIBES_USER     = "agentvibes-receiver"
AGENTVIBES_VOICE    = "en_US-libritts-high::Leo-8"
AGENTVIBES_PROJECT  = "hermes"
MAX_CONTENT_LEN     = 200          # chars of spoken content (prefix NOT counted)
PREFIX              = "Hermes here, "
_KNOWN_HOSTS        = "/absolute/path/to/known_hosts"   # persistent across restarts
_LOG_FILE           = os.path.join(os.path.dirname(os.path.abspath(__file__)), "tts-hook.log")

# ---------------------------------------------------------------------------
# File logger — writes to tts-hook.log next to handler.py, never to stdout
# ---------------------------------------------------------------------------

_log = logging.getLogger("agentvibes-tts")
if not _log.handlers:
    try:
        _h = logging.FileHandler(_LOG_FILE, encoding="utf-8")
        _h.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
        _log.addHandler(_h)
    except OSError:
        _log.addHandler(logging.NullHandler())
    _log.setLevel(logging.INFO)

# ---------------------------------------------------------------------------
# Rate limiting — prevent queue flooding on rapid consecutive turns
# ---------------------------------------------------------------------------

_last_sent: float = 0.0
_MIN_INTERVAL_S: float = 3.0


def _tts_speak(text: str) -> None:
    """Build JSON payload and send to AgentVibes receiver over SSH."""
    global _last_sent

    if not text or not text.strip():
        return

    now = time.monotonic()
    if now - _last_sent < _MIN_INTERVAL_S:
        _log.info("rate-limited: %.1fs since last send — skipping", now - _last_sent)
        return
    _last_sent = now

    # Truncate at word boundary so the spoken text never cuts mid-syllable
    full_text = PREFIX + text.strip()
    max_len = len(PREFIX) + MAX_CONTENT_LEN
    if len(full_text) > max_len:
        truncated = full_text[:max_len].rsplit(" ", 1)[0]
        full_text = truncated + "..."

    payload = base64.b64encode(
        json.dumps({
            "text":     full_text,
            "voice":    AGENTVIBES_VOICE,
            "project":  AGENTVIBES_PROJECT,
            "provider": "piper",
            "pretext":  "",   # prefix already prepended above
            "effects":  "",
            "music":    "",
            "volume":   "",
            "speed":    "",
        }).encode()
    ).decode()

    cmd = [
        "ssh",
        "-i", AGENTVIBES_SSH_KEY,
        "-o", "ConnectTimeout=5",
        # accept-new: trust the host key on first connection, reject changes
        # (MITM protection without interactive prompts)
        "-o", "StrictHostKeyChecking=accept-new",
        "-o", f"UserKnownHostsFile={_KNOWN_HOSTS}",
        "-o", "BatchMode=yes",
        "-p", AGENTVIBES_PORT,
        f"{AGENTVIBES_USER}@{AGENTVIBES_HOST}",
        payload,
    ]

    try:
        result = subprocess.run(cmd, capture_output=True, timeout=15)
        if result.returncode != 0:
            stderr = result.stderr.decode(errors="replace").strip()
            _log.warning("ssh exit %d: %s", result.returncode, stderr or "(no stderr)")
        else:
            stdout = result.stdout.decode(errors="replace").strip()
            _log.info("queued OK: %s", stdout)
    except subprocess.TimeoutExpired:
        _log.warning("ssh timed out after 15s to %s:%s", AGENTVIBES_HOST, AGENTVIBES_PORT)
    except Exception as exc:
        _log.warning("ssh error: %s", exc)


async def handle(event_type: str, context: dict) -> None:
    """Async handler — only processes agent:end events."""
    if event_type != "agent:end":
        return

    response = (context.get("response") or "").strip()
    if not response:
        return

    response = _strip_markdown(response)

    loop = asyncio.get_running_loop()
    await loop.run_in_executor(None, _tts_speak, response)


def _strip_markdown(text: str) -> str:
    """Remove markdown artifacts that sound unnatural in TTS."""
    # Fenced code blocks — always unlistenable
    text = re.sub(r"```[\s\S]*?```", "", text)
    # Inline code — unwrap
    text = re.sub(r"`([^`]+)`", r"\1", text)
    # Bold / italic markers
    text = re.sub(r"\*{1,2}([^\*]+)\*{1,2}", r"\1", text)
    # Links — keep label, drop URL
    text = re.sub(r"\[([^\]]+)\]\([^\)]+\)", r"\1", text)
    # Emoji — strip everywhere, not just line-start
    text = re.sub(
        r"[\U0001F300-\U0001F9FF"
        r"\U00002600-\U000027FF"
        r"\U0000FE00-\U0000FE0F"
        r"•→↓↑]+",
        "",
        text,
    )
    text = re.sub(r"\s+", " ", text).strip()
    return text
4. Restart gateway
bash
hermes gateway restart
5. Verify

Check hooks/agentvibes-tts/tts-hook.log after the next agent turn. Every SSH call logs its result (exit code, receiver ACK, or error message).

Configuration Reference

ConstantDescriptionNotes
AGENTVIBES_SSH_KEYAbsolute path to SSH private keyNo ~ — subprocess will not expand it
AGENTVIBES_HOSTHostname or IP of target machineTailscale IP recommended
AGENTVIBES_PORTSSH port of AgentVibes receiverSet during npx agentvibes install
AGENTVIBES_USERSSH user on target machineagentvibes-receiver
AGENTVIBES_VOICEVoice in voiceId::SpeakerName formate.g. en_US-libritts-high::Leo-8
AGENTVIBES_PROJECTProject tag shown in receiver loghermes
MAX_CONTENT_LENMax chars of spoken contentPrefix length NOT counted
PREFIXSpoken intro before each responseHermes here,
_KNOWN_HOSTSAbsolute path to persistent known_hostsRequired for accept-new to survive restarts
_MIN_INTERVAL_SSeconds between TTS callsPrevents queue flooding on rapid turns
Show full SKILL.md (202 more words)Show less

How It Works

  1. Guards on event_type == "agent:end" — ignores all other hook events
  2. Strips markdown (code blocks, bold, links, emoji — anywhere in the string)
  3. Prepends PREFIX, truncates at last word boundary before MAX_CONTENT_LEN chars, appends ...
  4. Builds JSON payload with voice, project, and provider fields (uses AgentVibes full format, not legacy plain text)
  5. Base64-encodes and sends over SSH — every call logged to tts-hook.log
  6. StrictHostKeyChecking=accept-new + explicit UserKnownHostsFile protects against MITM after first connect

Troubleshooting

  • No audio, no tts-hook.log: Check HERMES_HOME env var so the hook file is found; check directory write permissions
  • SSH permission denied: Register the key's public half on the agentvibes-receiver user
  • SSH host key changed error: Remove the stale entry from the _KNOWN_HOSTS file and reconnect once
  • "Queued" but silent on target: Check the queue watcher (tts-watcher.ps1) is running on the target machine
  • Responses not spoken: Check tts-hook.log — SSH errors are now logged with full detail

MCP Server Integration

AgentVibes ships with an MCP server (npx -y -p agentvibes@beta agentvibes-mcp-server) with tools for voice selection, effects, background music, and mute/unmute. Install it in your Hermes MCP config to control AgentVibes with natural language commands. The MCP server must run on the target machine where speakers live.

© paulpreibisch, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 2 other files in docs/hermes/skills/tts/hermes-agentvibes-hook of paulpreibisch/AgentVibes.

  • SKILL.md
  • HOOK.yaml
  • handler.py

Open the folder on GitHubat commit f62c8ff

Compare with similar skills

Hermes Agentvibes Hook next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Hermes Agentvibes Hook compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Hermes Agentvibes Hook this skillpaulpreibisch/AgentVibes155—~2.3kAutomated safety check: WarnApache-2.0
MoneyPrinterTurbo Video Generatorharry0703/MoneyPrinterTurbo129k—~2.1kAutomated safety check: WarnMIT
HyperFrames Media Useheygen-com/hyperframes60k—~2.4kAutomated safety check: PassApache-2.0
Openspec OnboardSAP/e-mobility-charging-stations-simulator22725 repos~3.5kAutomated safety check: PassMIT
Blog AudioAgriciDaniel/claude-blog2.3k1 repos~2.2kAutomated safety check: NotesMIT
Musictadaspetra/loop2962 repos~827Automated safety check: PassMIT

Similar skills

  • MoneyPrinterTurbo Video Generator

    harry0703/MoneyPrinterTurbo

    Installs and runs MoneyPrinterTurbo to turn a topic or script into a finished short video with voice-over, subtitles, stock footage and music.

    129k GitHub stars~2.1k tokensUpdated today
    Media & CreativeAuto-check: warnings
  • HyperFrames Media Use

    heygen-com/hyperframes

    Finds, generates and edits media for HyperFrames video projects: music, sound effects, images, icons, logos, voiceovers, captions and color grades.

    60k GitHub stars~2.4k tokensUpdated today
    Media & CreativeAuto-check passed
  • Openspec Onboard

    SAP/e-mobility-charging-stations-simulator

    Official

    Guided onboarding for OpenSpec - walk through a complete workflow cycle with narration and real codebase work.

    227 GitHub starsUsed in 25 repos~3.5k tokens
    Media & CreativeAuto-check passed
  • Blog Audio

    AgriciDaniel/claude-blog

    Generate audio narration of blog posts using Google Gemini TTS.

    2.3k GitHub starsUsed in 1 repo~2.2k tokens
    Media & CreativeAuto-check: notes
  • Music

    tadaspetra/loop

    Generate music using ElevenLabs Music API. An agent skill from tadaspetra/loop.

    296 GitHub starsUsed in 2 repos~827 tokens
    Media & CreativeAuto-check passed
  • Create News Video

    hoquanghai/Auto-Create-Video

    Tạo video tin tức ngắn 9:16 (~60s) từ URL bài báo hoặc file .txt tiếng Việt.

    319 GitHub starsUsed in 1 repo~3.7k tokens
    Media & CreativeAuto-check passed

More from paulpreibisch/AgentVibes

  • Bmad Agent QA

    paulpreibisch/AgentVibes

    QA engineer for test automation and coverage. An agent skill from paulpreibisch/AgentVibes.

    155 GitHub starsUsed in 1 repo~769 tokens
    Auto-check passed
  • Bmad Install Agentvibes

    paulpreibisch/AgentVibes

    Install AgentVibes TTS voice system for BMAD agents. An agent skill from paulpreibisch/AgentVibes.

    155 GitHub stars~557 tokensUpdated today
    Auto-check passed
  • Bmad Agent Sm

    paulpreibisch/AgentVibes

    Scrum master for sprint planning and story preparation. An agent skill from paulpreibisch/AgentVibes.

    155 GitHub starsUsed in 1 repo~769 tokens
    Auto-check passed
  • Agentvibes

    paulpreibisch/AgentVibes

    🎤 AgentVibes Voice Management - Manage your text-to-speech voices across multiple providers (Piper TTS, Piper, macOS Say).

    155 GitHub stars~1.5k tokensUpdated today
    Auto-check passed
  • Agentvibes Target

    paulpreibisch/AgentVibes

    Send TTS text from Hermes to a Windows laptop or Android device via AgentVibes queue-based player over SSH

    155 GitHub stars~2.4k tokensUpdated today
    Auto-check: warnings

Questions about Hermes Agentvibes Hook

What does Hermes Agentvibes Hook do?

Auto-speak every Hermes response via AgentVibes TTS on a remote machine over SSH. Hermes Agentvibes Hook is an agent skill from paulpreibisch/AgentVibes. Auto-speak every Hermes response via AgentVibes TTS on a remote machine over SSH.

When should I use Hermes Agentvibes Hook?

Hermes Agentvibes Hook fits situations like: tasks that involve Text to speech and voice.

How do I install Hermes Agentvibes Hook in Claude Code?

Run `npx skills add paulpreibisch/AgentVibes --skill hermes-agentvibes-hook -a claude-code`. Or copy the skill folder (docs/hermes/skills/tts/hermes-agentvibes-hook in paulpreibisch/AgentVibes) into .claude/skills/hermes-agentvibes-hook in your project. Claude Code loads it when a task matches its description.

How do I install Hermes Agentvibes Hook in Codex?

Run `npx skills add paulpreibisch/AgentVibes --skill hermes-agentvibes-hook -a codex`. Or copy the skill folder (docs/hermes/skills/tts/hermes-agentvibes-hook in paulpreibisch/AgentVibes) into .agents/skills/hermes-agentvibes-hook in your project. Codex loads it when a task matches its description.

Can I use Hermes Agentvibes Hook in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add paulpreibisch/AgentVibes --skill hermes-agentvibes-hook -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/hermes-agentvibes-hook, .gemini/skills/hermes-agentvibes-hook, .github/skills/hermes-agentvibes-hook and .opencode/skills/hermes-agentvibes-hook in your project.

What does Hermes Agentvibes Hook need to run?

Going by SKILL.md and its folder, Hermes Agentvibes Hook needs Python for the scripts in its folder, the command-line tools its instructions call (npx) and credentials named AGENTVIBES_SSH_KEY. Our summary lists: Python 3; Node.js; Docker; A credential in AGENTVIBES_SSH_KEY.

Does Hermes Agentvibes Hook access the network?

SKILL.md contains no URLs. Its commands use npx, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Hermes Agentvibes Hook safe to install?

Our automated static check of SKILL.md flagged 1 warning(s): mentions a credentials file (ssh keys, cloud or package-manager tokens). Read the flagged lines before installing; the check is not a guarantee either way.

What licence does Hermes Agentvibes Hook use?

Hermes Agentvibes Hook is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Hermes Agentvibes Hook use?

About 2.3k tokens (SKILL.md is roughly 9.3k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Hermes Agentvibes Hook?

Skills that share tags, products or a category with Hermes Agentvibes Hook: MoneyPrinterTurbo Video Generator (harry0703/MoneyPrinterTurbo, 129k stars), HyperFrames Media Use (heygen-com/hyperframes, 60k stars), Openspec Onboard (SAP/e-mobility-charging-stations-simulator, 227 stars) and Blog Audio (AgriciDaniel/claude-blog, 2.3k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Hermes Agentvibes Hook?

paulpreibisch (a GitHub user) maintains it in paulpreibisch/AgentVibes, which has 155 GitHub stars. The repository holds 6 skills in this directory. The repository was last updated on October 10, 2026.

Source: paulpreibisch/AgentVibes on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.