voicehook-agentCAUTION
Talk with your agents. Zero-install CLI that lets any coding agent (Claude Code, Codex, opencode) join a voicehook.ai voice call. stdin/stdout protocol, no SDK.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://github.com/voicehook-ai/voicehook-agent/actions/workflows/ci.yml) [](https://github.com/voicehook-ai/voicehook-agent/actions/workflows/codeql.yml) [](LICENSE) [](plugins/voicehook-join/.claude-plugin/plugin.json) [](pyproject.toml)
Talk to your coding agents instead of reading their output.
voicehook.ai is a voice call in the browser. Hit "invite agent", hand the link to Claude Code, Codex or opencode, and talk to it while it keeps working. Delta, the voice in the call, answers from the status board and FAQ your agent keeps up to date, so you hear what is going on without opening a terminal.
This repo holds the agent side: the voicehook-join Claude Code plugin and the voicehook-agent CLI that lets any agent with a shell join a call.
Three ways to connect
e85044119258OBSERVED · 2026-10-10Install
Commands as the repository documents them. They are shown, not run.
uvx voicehook-agent join 'https://voicehook.ai/r/<slug>?invite=<code>' --name <your-own-name> --model <your-model-name>
uvx voicehook-agent join 'https://voicehook.ai/r/<slug>?invite=<code>' --name <your-own-name> --model <your-model-name>
uvx voicehook-agent join 'https://voicehook.ai/r/<slug>?invite=<code>' --name <your-own-name> --model <your-model-name>
uv tool install voicehook-agent
uv tool install -q --upgrade $R || pip install -q --upgrade --user $R
uv tool upgrade voicehook-agent
Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned | |
| claude-desktop | mentioned | |
| codex | mentioned | |
| cursor | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: voicehook-join
description: Join or start a voicehook.ai voice call as the brain behind its voicebot, through the voicehook MCP tools (create_call, join, next, say, status, activity, show, leave). Use when the user shares a voicehook invite URL (https://voicehook.ai/r/<slug>?invite=...), says "join voicehook", "tritt meinem Call bei", "übernimm den voice-call", "/voicehook-join", or wants you to call them ("ruf mich an", "call me", "lass uns telefonieren"). The voicebot speaks what you send with `say`; you listen with `next`.
---
# voicehook-join (MCP): be the brain in a voicehook call
Canonical: https://voicehook.ai/agent/mcp/SKILL.md. You only use the tools of the
`voicehook` MCP server. Nothing to install, no keys: the invite link is the permission.
## Hard rules (read first, always)
- **`create_call`: the link first.** FIRST give your user share_text, verbatim.
- Claude Code / clients that can keep a background process running: start join + next in the background, then END your turn with share_text as your final message; intermediate text may never reach a remote user.
- claude.ai chat, remote apps / clients that only show your final message: END YOUR TURN with share_text as your final message and call join when the user replies that they opened it.
- join waits up to 50 s and returns status waiting_for_human until they open it; then call join again at once.
- Until they have joined, end EVERY message to your user with share_text as the last block. A link further up scrolls away.
- Never wait or block in the foreground before the link is out as your final message, never "I am waiting for you" in the foreground. If your channel can, also send the link as a file or push. On 5xx, 503 or a network error call the tool again after 2 s.
- **Right after `join`, at once** (also with `quiet: true`: quiet only suppresses `share` and `notice`, nothing audible). You lead: never wait silently until the human says something.
1. Greet: `greet` (true by default in `join`) speaks the default greeting in the call language. With greet, the `say` in `context.first_actions` drops out. Without greet: right after join, `say` one short greeting in the call language: who you are and that you are listening ("Hi, this is <your label>, I'm in and listening. What's up?" / "Hallo, <your label> hier, ich bin drin und höre zu. Worum geht's?"). If you stay silent, the voicebot announces you after 3 seconds.
2. `status` with `doing`, `open`, `done`.
3. One `activity` line.
4. Open questions for the human: `decide` (Decision Board), never into `open`.
5. `show` with `panel: "board"` (or `log`, `decisions`) so the human sees it at once.
- **Acknowledge within 3 s:** on every request of the human first one short `say` ("On it, one moment." / "Mach ich, Moment."), THEN work. Progress goes to `status` and `activity`, never silence.
## Join
1. Call `join` with `invite_url` = the FULL invite link the user gave you (including
`?invite=`), `label` = the text on your chip in the call (max 22 characters: your session
or chat name, else your model name; too long is rejected), `model` = the exact model id
you run on (not shown). Never call yourself "Claude" if you are not Claude. Unknown model:
`"unbekannt"`. The old `name` still works as `label`. `greet` is true by default (`false` = you greet with `say`).
2. Keep the returned `session` and pass it as `session` to EVERY other tool. It is a short-lived handle
for this one call; it ends with the call, after 10 min without `next`/`say`, or with `leave`. Never show it in the call or to anyone else.
3. `lang` = the call language: speak it. `share` = one line for YOUR user (show it once
in your chat, never say it in the call); `quiet: true` drops it (and `notice`; nothing audible). `context` = lang, mode,
instructions, functions, rules, skill_url: the source of truth for this call.
4. Then the Hard rules checklist (greeting, board, feed, decide, panel) and `next` at once.
## Or call your user yourself (`create_call`)
1. `create_call`: set `lang` to the language of the person you are calling (`de` or `en`, default `de`).
You get `human_url`, `share_text`, `operator_invite_url`, `room` and `expires_in` (seconds; an unopened link expires, 30 min).
2. Give your user `share_text` verbatim (it holds `human_url` and the hint to use a normal
browser; an app's built-in browser blocks the mic) as your FINAL message (Hard rules). The opener
pays from THEIR free allowance or credit, you pay nothing. Never send `operator_invite_url` to anyone.
3. `join` with `invite_url` = `operator_invite_url` (in the background, or when your user says
the link is open). It waits up to 50 s and returns status `waiting_for_human` (not an error,
with `share_text` again) until the person opens the link: call `join` again at once, until it
succeeds or answers `410` (link expired: ask your user whether to start a new call).
4. Then the Hard rules checklist and `next` as below.
## The work cycle: say -> next -> say
`next` (waits up to 50 s for the user) -> one `say` -> `next` again at once. Never sleep, never poll, never end your turn while the call runs. Working? Still call `next` at least every 10-15 s (split long work into steps, `next` in between). Exactly ONE `next` loop per agent: a second one makes the older answer `superseded`. After a pause `next` brings `missed` (all user turns you missed, oldest first) and `away_s`: answer them together in one `say`.
| `type` | meaning | do |
|---|---|---|
| `user` | `text` = what the user just said | answer with ONE `say` |
| `revise` | your queued says were replaced; `reason: "user_stop"` = the user said "stopp"/"reicht" | still needed: one merged `say` with `mode: "overwrite"`; `user_stop`: never resend, wait |
| `status_request` | the user asked what you are doing | send a `status` board at once |
| `timeout` | silence (also `reconnect: true` = server restart) | call `next` again |
| `human_leTrust audit
CAUTIONgrade C · trust 71/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- declared (8 observation(s))
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- found
Findings (12)
p_sum.add_argument("--ollama-url", default="http://127.0.0.1:11434",help="Ollama base URL (default http://127.0.0.1:11434).")
"sk-ant-api03-abcdefghijklmnop",
"ghp_abcdefghijklmnopqrstuvwxyz0123456789",
activity.post_tool_use(_event(tool_input={"description": "Key ghp_abcdefghijklmnopqrstuvwxyz01234 testen"}))"file_path": "/tmp/ghp_abcdefghijklmnopqrstuvwxyz0123456789.txt"}))
"xoxb-123456789012-abcdefghij",
"sk_live_51Habcdefghijklmnop",
.gitleaks.toml
activity.save_bridge_session({"session": "s"}, "http://127.0.0.1:9")assert activity._bridge_post("http://127.0.0.1:9", "s", "x") is Noneactivity.save_bridge_session({"session": "s"}, "http://127.0.0.1:9")Gates applied: no_behavioural_pass.
e85044119258full audit observations/trust-audit/skill/voicehook-ai__voicehook-agent.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-10 | e85044119258 | CAUTION | C | 71 | first audit |
Questions
What does the voicehook-agent skill do?
Talk with your agents. Zero-install CLI that lets any coding agent (Claude Code, Codex, opencode) join a voicehook.ai voice call. stdin/stdout protocol, no SDK.
Is voicehook-agent safe to install?
With care. The audit graded it C (71/100) and found 12 things worth knowing before you trust this skill, listed below with the exact line each was found on.
What can voicehook-agent access on my machine?
The audit observed that it reaches the network. Each of those is consistent with what it says it does. Secrets in the source: found — see the findings.
Which assistants does voicehook-agent work with?
Its documentation mentions claude-code, claude-desktop, codex and cursor. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (e85044119258), read on 2026-10-10. The repository is watched, and a new audit runs when it changes — this is the first audit.