voicehook
by voicehook-ai · remote · no sign-in to list tools · v1.0.0 · published by GitHub user voicehook-ai
Talk with your agents. A voice call in the browser that your agent can start or join.
21 tools: 6 can delete or cancel things, 2 do something that can't be undone, 11 change things and 2 only read.
Scanned Oct 21, 2026
- Deletes or cancels6Claude Code: deny: see these tools
- Can't be undone2Claude Code: ask: see these tools
- Changes things11Claude Code: ask: see these tools
- Only reads2Claude Code: allow: see these tools
27 checks matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.
claude mcp add --transport http voicehook https://voicehook.ai/mcp?utm_source=mcpregistry&utm_campaign=d11-registryFindings
Matches of fixed checks, with the text they matched.
- Warnjoin
The description contains "every other tool", wording about other tools or servers.
What this check looks forMatched text
description: "...out). Returns `session` (the handle for every other tool, valid until the call ends, after 10 mi..."
- Warnstatus
The server marks "status" destructive (destructiveHint: true), and its name says "status", a word for reading.
What this check looks forMatched text
annotations: {"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true,"openWorldHint":true}; The name "status" says "status": a word for reading.
- Warnhelper_status
The server marks "helper_status" destructive (destructiveHint: true), and its name says "status", a word for reading.
What this check looks forMatched text
annotations: {"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":true}; The name "helper_status" says "status": a word for reading.
- Warnhelper_show
The server marks "helper_show" as not read-only (readOnlyHint: false), and its words say it reads.
What this check looks forMatched text
annotations: {"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":true}; The name "helper_show" says "show": a word for reading.
- Infojoin
The description is 2,141 characters long, over the 2,000 this check looks for.
What this check looks forMatched text
description ends: "...nd wakes you); never end your turn before that. Then keep calling next in a loop."
- Infonext
The description is 3,065 characters long, over the 2,000 this check looks for.
What this check looks forMatched text
description ends: "...nd wakes you); never end your turn before that. Then keep calling next in a loop."
Show 21 more findingsShow fewer
The title mentions "credential".
What this check looks forMatched text
title: "Get a helper credential"
The annotations title mentions "credential".
What this check looks forMatched text
annotations.title: "Get a helper credential"
The description mentions "credential".
What this check looks forMatched text
description: "...the call (`session`): returns a helper credential `token` (with `url` and `expires_in`) t..."
The input schema at properties.rotate.description mentions "credentials".
What this check looks forMatched text
inputSchema.properties.rotate.description: "true = invalidate earlier helper credentials."
- Infohelper_status
The input schema at properties.credential.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credential.description: "Helper credential `token` from helper_credential or POST..."
- Infohelper_status
The input schema at properties.credential.title mentions "Credential".
What this check looks forMatched text
inputSchema.properties.credential.title: "Credential"
- Infohelper_status
The input schema at required[0] mentions "credential".
What this check looks forMatched text
inputSchema.required[0]: "credential"
- Infohelper_activity
The input schema at properties.credential.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credential.description: "Helper credential `token` from helper_credential or POST..."
- Infohelper_activity
The input schema at properties.credential.title mentions "Credential".
What this check looks forMatched text
inputSchema.properties.credential.title: "Credential"
- Infohelper_activity
The input schema at required[0] mentions "credential".
What this check looks forMatched text
inputSchema.required[0]: "credential"
- Infohelper_show
The input schema at properties.credential.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credential.description: "Helper credential `token` from helper_credential or POST..."
- Infohelper_show
The input schema at properties.credential.title mentions "Credential".
What this check looks forMatched text
inputSchema.properties.credential.title: "Credential"
- Infohelper_show
The input schema at required[0] mentions "credential".
What this check looks forMatched text
inputSchema.required[0]: "credential"
- Infohelper_decide
The description mentions "credential".
What this check looks forMatched text
description: "...ange or delete only own questions (same credential and from), else 403. Returns id and num..."
- Infohelper_decide
The input schema at properties.credential.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credential.description: "Helper credential `token` from helper_credential or POST..."
- Infohelper_decide
The input schema at properties.credential.title mentions "Credential".
What this check looks forMatched text
inputSchema.properties.credential.title: "Credential"
- Infohelper_decide
The input schema at required[0] mentions "credential".
What this check looks forMatched text
inputSchema.required[0]: "credential"
- Infohelper_next
The description mentions "credential".
What this check looks forMatched text
description: "...the answers to its own questions (same credential and helper_name) as events [{type: deci..."
- Infohelper_next
The input schema at properties.credential.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credential.description: "Helper credential `token` from helper_credential or POST..."
- Infohelper_next
The input schema at properties.credential.title mentions "Credential".
What this check looks forMatched text
inputSchema.properties.credential.title: "Credential"
- Infohelper_next
The input schema at required[0] mentions "credential".
What this check looks forMatched text
inputSchema.required[0]: "credential"
Tools
Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.
21 tools
Deletes or cancels 6Claude Code: deny
decidePut a question for the person on the call's Decision Board (shown as #number with buttons; the person can also answer by voice, also freely).No findings
Why it is in this group
- The description's first verb is "put": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Put a question for the person on the call's Decision Board (shown as #number with buttons; the person can also answer by voice, also freely). Meant for every question the person decides: yes/no, A/B, an approval, picking a value. A question only spoken via say leaves no button and no decision event. Without options it is a yes/no question (buttons Yes/No); options: 2 to 3, max 40 characters each, recommend = index of the recommended option. question: max 160 characters. Longer or more: 422, never cut. Returns id and number. The answer arrives later as a `next` event {type: decision, id, number, verdict: yes|no|option|other|unclear, option?, text? (their own answer, or for unclear the request to ask it again more simply), by}. context: the background the person opens with the arrow next to the question on the card and Delta uses to explain it, only what the reader needs, nothing internal, one short line per part (Was / Warum / Bei Ja / Bei Nein, or What / Why / If yes / If no; lines starting with '- ' show as bullet points); faq: the 3 likely follow-up questions with prepared answers, shown below it as questions and answers. Without context and faq the card shows no arrow; without context and 3 faq the result carries `warnings` (no error). Change an open one with id plus new fields, remove it with id and delete true. no_question = id of a question_check event, alone: confirms that line was no question to the person. Decisions marked auto (detected automatically) are answered only by a human; changing or deleting them gives 403.
Annotations the server declares
- destructiveHint: true
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Ask the human to decide
helper_decideFor a helper session that is not in the call: puts its own question on the Decision Board, shown with the sender 'Helper <label>: <helper_name>'.4 findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it destructive (destructiveHint: true).
Findings
- Info
The description mentions "credential".
What this check looks forMatched text
description: "...ange or delete only own questions (same credential and from), else 403. Returns id and num..."
- Info
The input schema at properties.credential.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credential.description: "Helper credential `token` from helper_credential or POST..."
- Info
The input schema at properties.credential.title mentions "Credential".
What this check looks forMatched text
inputSchema.properties.credential.title: "Credential"
- Info
The input schema at required[0] mentions "credential".
What this check looks forMatched text
inputSchema.required[0]: "credential"
Description, as the server wrote it For a helper session that is not in the call: puts its own question on the Decision Board, shown with the sender 'Helper <label>: <helper_name>'. Same fields and limits as decide (question max 160 chars, 2-3 options max 40 chars each, recommend = index, context = background shown behind the arrow next to the question and used by Delta, faq = 3 follow-up questions with prepared answers; without them the result carries warnings). Change or delete only own questions (same credential and from), else 403. Returns id and number; the answer comes from helper_next, never from the main agent's next.
Annotations the server declares
- destructiveHint: true
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Helper: ask the human to decide
helper_statusFor a helper session that is not in the call: sets its own status board on the call page, shown as 'Helper <label>: <helper_name>' below the main agent; the main agent's board stay…4 findings
Why it is in this group
- The name "helper_status" says "status": a word for reading.
- The server marks it destructive (destructiveHint: true).
Findings
- Info
The input schema at properties.credential.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credential.description: "Helper credential `token` from helper_credential or POST..."
- Info
The input schema at properties.credential.title mentions "Credential".
What this check looks forMatched text
inputSchema.properties.credential.title: "Credential"
- Info
The input schema at required[0] mentions "credential".
What this check looks forMatched text
inputSchema.required[0]: "credential"
- Warn
The server marks "helper_status" destructive (destructiveHint: true), and its name says "status", a word for reading.
What this check looks forMatched text
annotations: {"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":true}; The name "helper_status" says "status": a word for reading.
Description, as the server wrote it For a helper session that is not in the call: sets its own status board on the call page, shown as 'Helper <label>: <helper_name>' below the main agent; the main agent's board stays as it is. Same limits as status (doing max 400 chars, open / done max 10 items). meta: Per entry hidden background for the voicebot, never shown on the page: context (max 2000 chars) and faq (up to 3 follow-up questions with prepared answers). Without context and 3 faq on an entry the result carries `warnings` (no error). Empty doing, open and done removes the helper's board. Returns ok and, when context or faq is missing on an entry, warnings.
Annotations the server declares
- destructiveHint: true
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Helper: set own status board
leaveLeave the call (optionally speaking `say` first, e.g.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Leave the call (optionally speaking `say` first, e.g. a short goodbye). The session handle is invalid afterwards.
Annotations the server declares
- destructiveHint: true
- idempotentHint: true
- openWorldHint: true
- readOnlyHint: false
- title: Leave the call
sayThe voicebot speaks `text` aloud in the call (verbatim in normal mode; in a live room the voice rephrases it and the answer has verbatim false, mode live_paraphrase).No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it The voicebot speaks `text` aloud in the call (verbatim in normal mode; in a live room the voice rephrases it and the answer has verbatim false, mode live_paraphrase). mode: append (default, queued after earlier says), overwrite (replaces this agent's says that have not started yet), revise (like overwrite, and next then returns a revise event). Returns ok and seq.
Annotations the server declares
- destructiveHint: true
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Speak in the call
statusReplace the agent's status board on the call page with this one (never spoken; the voicebot answers the person's questions about progress from it).1 finding
Why it is in this group
- The name "status" says "status": a word for reading.
- The description's first verb is "replace": a word for a change.
- The server marks it destructive (destructiveHint: true).
Findings
- Warn
The server marks "status" destructive (destructiveHint: true), and its name says "status", a word for reading.
What this check looks forMatched text
annotations: {"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true,"openWorldHint":true}; The name "status" says "status": a word for reading.
Description, as the server wrote it Replace the agent's status board on the call page with this one (never spoken; the voicebot answers the person's questions about progress from it). Progress only: questions for the person belong on the Decision Board (decide). doing: current step and ETA (max 400 chars). open / done: max 10 items each, 200 chars per item. faq: up to 6 question/answer pairs the voicebot can answer directly. meta: Per entry hidden background for the voicebot, never shown on the page: context (max 2000 chars) and faq (up to 3 follow-up questions with prepared answers). Without context and 3 faq on an entry the result carries `warnings` (no error). emoji (optional): An emoji shown on the agent's chip in the call, from the listed set. Empty string removes it, left out keeps it. Whole board max 2000 chars. Returns ok, humans_present and, when context or faq is missing on an entry, warnings.
Annotations the server declares
- destructiveHint: true
- idempotentHint: true
- openWorldHint: true
- readOnlyHint: false
- title: Update the status board
Can't be undone 2Claude Code: ask
notify_meReach the human who owns this call when they are not on the call page: an SMS to their own confirmed number with a single-use link back into this call (valid 10 min, opens only log…No findings
Why it is in this group
- The name "notify_me" says "notify": a word for sending, and what is sent cannot be taken back.
Description, as the server wrote it Reach the human who owns this call when they are not on the call page: an SMS to their own confirmed number with a single-use link back into this call (valid 10 min, opens only logged in or with the PIN from the SMS); if they do not open it within 2 minutes, a phone call follows. Prefer this over call_me. Their account rules decide (opt-in, reasons, quiet hours, per day, budget, credit); a refusal returns {status: refused, why}. Otherwise {status: sms_sent|sms_failed|insufficient, phone_call_id, billed_eur, link_valid_s, fallback_call_in_s}. reason: done | blocked | decision. message: max 120 characters, in the SMS.
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Notify the human (SMS first)
send_dataSend JSON, text or a file to other agents in this call (silent data channel: never spoken, never shown to the human, never to the voicebot; the human only sees one activity line 'D…No findings
Why it is in this group
- The name "send_data" says "send": a word for sending, and what is sent cannot be taken back.
- The input addresses people (input.to): what it sends cannot be taken back.
Description, as the server wrote it Send JSON, text or a file to other agents in this call (silent data channel: never spoken, never shown to the human, never to the voicebot; the human only sees one activity line 'Data to B: name (size)'). to: the other agent's label (as on its chip), its identity, or "*" for all other agents; unknown -> 404 with the labels in the call. kind json: payload any JSON; text: payload a string; file: payload = base64 of the file plus name and mime, or file_id of a file uploaded with the REST endpoint POST /api/bridge/upload (files over about 11 KB, up to 10 MB). The whole packet is max 15000 bytes inline (413 otherwise; base64 makes a file 4/3 larger). Receivers get it in next as type data {from, from_identity, kind, id, name?, mime?, payload | url + file_id, size?}; url is a path, served at https://voicehook.ai<url> with the header Authorization: Bearer <session>. Returns id, to (labels), size.
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Send data to another agent
Changes things 11Claude Code: ask
activityAppend one line (3-8 words) to the activity feed on the call page, shown as a timestamped line.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Description, as the server wrote it Append one line (3-8 words) to the activity feed on the call page, shown as a timestamped line. Never spoken. context and faq: hidden background of this line for the voicebot.
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Add an activity line
add_vocabTeach the call's speech recognition words it keeps mishearing (product names, people, jargon).No findings
Why it is in this group
- The name "add_vocab" says "add": a word for a change.
Description, as the server wrote it Teach the call's speech recognition words it keeps mishearing (product names, people, jargon). Adds to the vocabulary of the account that pays for this call (add only: never deletes, never returns the account's list; the person manages it on their account page). terms: words to recognize; fixes: {wrong, right} = a known mishearing and the correct word (right is added to the terms too). Max 20 entries per call of this tool, 100 per call, 50 characters each. Corrections apply right away, the word list from the next sentence or the next call. 409: guest call without an account. Returns added {terms, fixes}, total, call_left, reloaded.
Annotations the server declares
- destructiveHint: false
- idempotentHint: true
- openWorldHint: true
- readOnlyHint: false
- title: Add vocabulary for speech recognition
call_mePhone the human who owns this call on their own confirmed phone number, e.g.No findings
Why it is in this group
- The name "call_me" says "call": a word for a change.
Description, as the server wrote it Phone the human who owns this call on their own confirmed phone number, e.g. when a long task is done, you are stuck, or you need a decision and they are not on the call page. You never pass a number. Their account rules decide (opt-in, allowed reasons, quiet hours, calls per day, budget, credit); a refusal returns {status: refused, why}. Otherwise returns {status: answered|no_answer|busy|failed|insufficient, phone_call_id, billed_eur} after the call. reason: done | blocked | decision. message: max 200 characters, said when they pick up.
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Phone the human
create_callStart a new voicehook.ai voice call.No findings
Why it is in this group
- The name "create_call" says "create": a word for a change.
Description, as the server wrote it Start a new voicehook.ai voice call. `lang` = the language of the person being called (de or en, default de). Returns `human_url` (the link for the person; whoever opens it starts the call, on their own free allowance or credit), `share_text` (a ready message with human_url and the hint that the link needs a normal browser, because an app's built-in browser blocks the microphone), `operator_invite_url` (the agent's own link for `join`), `room` and `expires_in` (seconds until an unopened link expires, 30 min); `local_cli_hint` only for a local client with a shell (Claude Code, Cursor, VS Code and similar). join with operator_invite_url waits for the person (up to 200 s in Claude clients, else 50 s) and returns waiting_for_human with `next_action` until they open human_url; it can be repeated until the link expires (410), also from a background job over the HTTPS bridge. Errors: 429 = too many new calls right now. Hard rule: after create_call, show share_text to your user as text first, then call join at once and repeat it until it returns `session` (or start a background job that joins over the HTTPS bridge and wakes you); never end your turn before that. Then keep calling next in a loop.
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Start a new voicehook call
helper_activityFor a helper session that is not in the call: appends one line (3-8 words) to the call's activity feed as 'Helper <label>: <helper_name>: <text>'.3 findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Findings
- Info
The input schema at properties.credential.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credential.description: "Helper credential `token` from helper_credential or POST..."
- Info
The input schema at properties.credential.title mentions "Credential".
What this check looks forMatched text
inputSchema.properties.credential.title: "Credential"
- Info
The input schema at required[0] mentions "credential".
What this check looks forMatched text
inputSchema.required[0]: "credential"
Description, as the server wrote it For a helper session that is not in the call: appends one line (3-8 words) to the call's activity feed as 'Helper <label>: <helper_name>: <text>'. Never spoken verbatim. context and faq: hidden background of this line for the voicebot. Returns the line.
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Helper: add an activity line
helper_credentialFor the agent in the call (`session`): returns a helper credential `token` (with `url` and `expires_in`) that lets other sessions working for the same person add their own status b…4 findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Findings
- Info
The title mentions "credential".
What this check looks forMatched text
title: "Get a helper credential"
- Info
The annotations title mentions "credential".
What this check looks forMatched text
annotations.title: "Get a helper credential"
- Info
The description mentions "credential".
What this check looks forMatched text
description: "...the call (`session`): returns a helper credential `token` (with `url` and `expires_in`) t..."
- Info
The input schema at properties.rotate.description mentions "credentials".
What this check looks forMatched text
inputSchema.properties.rotate.description: "true = invalidate earlier helper credentials."
Description, as the server wrote it For the agent in the call (`session`): returns a helper credential `token` (with `url` and `expires_in`) that lets other sessions working for the same person add their own status board, decisions and activity lines to this call without joining (no voice, no chip). `label` = name of the helper's machine, max 22 chars, shown as 'Helper <label>: <helper_name>'. rotate true makes every earlier helper credential of this call invalid. The credential works only for the helper_* tools and /api/activity/relay*, never for say or join, and ends with the call.
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Get a helper credential
helper_nextFor a helper session that is not in the call: returns the answers to its own questions (same credential and helper_name) as events [{type: decision, id, number, verdict: yes|no|opt…4 findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
Findings
- Info
The description mentions "credential".
What this check looks forMatched text
description: "...the answers to its own questions (same credential and helper_name) as events [{type: deci..."
- Info
The input schema at properties.credential.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credential.description: "Helper credential `token` from helper_credential or POST..."
- Info
The input schema at properties.credential.title mentions "Credential".
What this check looks forMatched text
inputSchema.properties.credential.title: "Credential"
- Info
The input schema at required[0] mentions "credential".
What this check looks forMatched text
inputSchema.required[0]: "credential"
Description, as the server wrote it For a helper session that is not in the call: returns the answers to its own questions (same credential and helper_name) as events [{type: decision, id, number, verdict: yes|no|option|other, option?, text?, by}], plus question_check events (a status or activity line of this helper reads like a question to the person: id, quote, wait_s, text; answered by helper_decide with the question or with no_question = id), plus user_turn events (the person addressed this helper by name in the call: text as transcribed, to, ts), waiting up to `timeout` seconds (0-25) when none is there. At most 50 kept per helper, gone when the call ends.
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: true
- title: Helper: answers to own decisions
helper_showFor a helper session that is not in the call: puts a card on the person's call page (never spoken), shown with the sender 'Helper <label>: <helper_name>'.4 findings
Why it is in this group
- The name "helper_show" says "show": a word for reading.
- The server marks it as not read-only (readOnlyHint: false).
Findings
- Info
The input schema at properties.credential.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credential.description: "Helper credential `token` from helper_credential or POST..."
- Info
The input schema at properties.credential.title mentions "Credential".
What this check looks forMatched text
inputSchema.properties.credential.title: "Credential"
- Info
The input schema at required[0] mentions "credential".
What this check looks forMatched text
inputSchema.required[0]: "credential"
- Warn
The server marks "helper_show" as not read-only (readOnlyHint: false), and its words say it reads.
What this check looks forMatched text
annotations: {"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":true}; The name "helper_show" says "show": a word for reading.
Description, as the server wrote it For a helper session that is not in the call: puts a card on the person's call page (never spoken), shown with the sender 'Helper <label>: <helper_name>'. kind: text (default), code, link (exactly one http(s) URL) or image (`image` = SVG text or base64 PNG/JPEG/WebP, never a URL). Same checks and limits as show: text 4000 chars, title 80, SVG 300 KB, raster 1024 KB, at most 10 images a minute. An image returns ok only after a call page loaded it (shown = number of pages); otherwise an error says why (nobody in the call, image did not load).
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Helper: show something on the call page
joinConnect to a voicehook.ai voice call as the agent behind its voicebot.2 findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Findings
- Warn
The description contains "every other tool", wording about other tools or servers.
What this check looks forMatched text
description: "...out). Returns `session` (the handle for every other tool, valid until the call ends, after 10 mi..."
- Info
The description is 2,141 characters long, over the 2,000 this check looks for.
What this check looks forMatched text
description ends: "...nd wakes you); never end your turn before that. Then keep calling next in a loop."
Description, as the server wrote it Connect to a voicehook.ai voice call as the agent behind its voicebot. invite_url: the full invite link including ?invite= (from the person or from create_call). label: the text on the agent's chip in the call, max 22 characters (longer is rejected). model: the model id the agent runs on (internal, not shown). greet (default true): the voicebot speaks a short greeting with the label in the call language right after the join (or when the person is back, if they are out). Returns `session` (the handle for every other tool, valid until the call ends, after 10 min without next or say, or after leave), `room`, `lang` (call language), `idle_timeout_s`, `peers`, `humans_present` (people in the call; 0 plus `human_away` = the person is out right now), `solo` (true = solo call: the voicebot speaks as you, in your voice, first person; other agents may join with their own voices) and `context` (lang, mode, functions, skill_url, status_every = seconds between the voicebot's status summaries). With a link from create_call, join waits for the person (up to 200 s in Claude clients, else 50 s, with progress every 10 s) and then returns status waiting_for_human (not an error, with share_text and `next_action`) while the link is still unopened. `local_cli_hint` only for a local client with a shell (Claude Code, Cursor, VS Code and similar). Errors: 403 invalid invite, 409 no person in the room, 410 link expired or call over, 429 too many joins, 503 server restarting (the call stays valid). MCP and bridge connect one agent to the call; activity lines are only what that agent writes. For several agents or sessions on one machine in one call, the voicehook-agent CLI (pro tool) feeds the live activity log, status and decisions of all local sessions into the call automatically; MCP and bridge run on the server and cannot see the user's local sessions. Hard rule: after create_call, show share_text to your user as text first, then call join at once and repeat it until it returns `session` (or start a background job that joins over the HTTPS bridge and wakes you); never end your turn before that. Then keep calling next in a loop.
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Join a voicehook call
showPut a card on the person's call page (never spoken): text, code, a link or an image.No findings
Why it is in this group
- The name "show" says "show": a word for reading.
- The description's first verb is "put": a word for a change.
Description, as the server wrote it Put a card on the person's call page (never spoken): text, code, a link or an image. kind: text (default), code (monospace with copy button), link (exactly one http(s) URL, shown as a tappable link), image (`image` = SVG text or base64 PNG/JPEG/WebP, line breaks, a data:image/...;base64, prefix and missing padding are accepted; or `file_id` of an image uploaded with the REST endpoint POST /api/bridge/upload, which keeps large base64 out of the tool call). A new card appears as a small preview top left; panel cards opens the cards view, board, log or decisions open those panels, none closes them. large: true opens the cards view big in the middle with this card at full size (diagrams, swimlanes; implies panel cards). SVG may draw anything (no scripts, no foreignObject, no external references). Limits: text 4000 chars, title 80, SVG 300 KB, raster 1024 KB.
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Show something on the call page
uiChange the person's call page right away, like their own clicks: cmd window (win log=activity, dec=decisions, board=status board, wrap=transcript, cards; state open, close, min, me…No findings
Why it is in this group
- The input takes a statement or command to run (input.cmd), which can change anything it can reach.
Description, as the server wrote it Change the person's call page right away, like their own clicks: cmd window (win log=activity, dec=decisions, board=status board, wrap=transcript, cards; state open, close, min, medium, large, max), cmd layout (preset halves, quarters, thirds, bigmid, bar), cmd move (win + slot l, m, r, b, tl, tr, bl, br, main, side; optional preset), cmd focus (project voicehook, salesengine, kunden, sonstiges or all: only that project's sections stay open in activity, status and decisions). Never spoken. Only when the person asks for it or it clearly helps (e.g. open decisions after asking one).
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: false
- title: Arrange the call page
Only reads 2Claude Code: allow
decisionsLists every OPEN decision on the call's Decision Board, from all agents in the call and their helper sessions (relay, MCP, bridge), oldest number first.No findings
Why it is in this group
- The description's first verb is "list": a word for reading.
Description, as the server wrote it Lists every OPEN decision on the call's Decision Board, from all agents in the call and their helper sessions (relay, MCP, bridge), oldest number first. Returns count and open: [{id, number, question, options, recommend, agent, from (asking label, with the helper name), sender? (helper session), state, at (created, epoch), age_s, mine (asked by this session or one of its helpers), context? (background, also shown on the card behind the arrow)}]. Also recent: the last decided ones, newest first (same fields plus verdict, option, text, by, decided_age_s; auto = put on the board by the server), and boards: every helper session's status board in the room [{from, name, doing, open, done, state?, age_s (since its last update), meta? (context/faq, shortened)}], newest first: read-only overview for the main agent. Errors: 503 = voicebot not (yet) in the call.
Annotations the server declares
- destructiveHint: false
- idempotentHint: true
- openWorldHint: true
- readOnlyHint: true
- title: List decisions and helper boards
nextWait (up to `timeout` seconds, max 50) for the next event in the call and return it.1 finding
Why it is in this group
- The description's first verb is "wait": a word for reading.
Findings
- Info
The description is 3,065 characters long, over the 2,000 this check looks for.
What this check looks forMatched text
description ends: "...nd wakes you); never end your turn before that. Then keep calling next in a loop."
Description, as the server wrote it Wait (up to `timeout` seconds, max 50) for the next event in the call and return it. Event `type`: user (`text` = what the person said; after a pause also `missed` = earlier turns, oldest first, and `away_s`), revise (queued says were replaced; reason user_stop = the person said stop; reason stale + stale:true = your says waited over 60 s unspoken and were dropped (items = seq + text): do not repeat them, if still relevant say ONE short current summary), status_request (the person asked what the agent is doing), decision (answer to a decide question: id, number, verdict yes|no|option|other, option, text, by), helper_decision (the human answered a helper session's question: from, label, id, number, question, verdict, option, text, by; a routing hint, never speak or answer it: send it to that session so it continues), question_check (a status or activity line of this agent reads like a question to the person: id, quote, wait_s, text; answered by decide with the question, or by decide with no_question = id; without either, after wait_s the server puts it on the Decision Board itself, marked as detected automatically, answered only by a human), timeout (nothing happened; reconnect true = server restart), human_left / human_rejoined (the person dropped out / is back; greeted true = the join greeting was just spoken), voicebot_left / voicebot_back (the voicebot dropped out, e.g. a server update; a new one usually joins within ~20 s, says are not heard until then / it is back after `seconds`, say works again), operator (another agent addressed this one: addressed_to_you), data (another agent sent data with send_data: from, kind, payload or url + file_id; never spoken), context (the call language changed, new context), superseded (a newer next call replaced this one), ended (the call is over; detail live_budget, wallet_empty, free_limit or review_budget = budget used up (quota), unspoken says were dropped). Every answer has `humans_present`; user events and `operators_said` lines carry addressed_to / addressed_to_you; a user event with routed_by_delta = the person gave Delta a request, it is yours; a user event with to_kind helper = the person addressed a helper session by name (to), the sentence is in that helper's inbox, info_only; to_kind helper_ambiguous = several helpers matched, Delta asks which one. `agent_said` = what the voicebot said on its own since the last next, `operators_said` = what other agents said (with name), `board_now` / `activity_now` = the agent's current doing line and last feed line as the voicebot sees them, `stale_error` = board or feed older than 60 s while the agent is working, or no activity line yet after the join. Errors: 404 = unknown session (after leave); 5xx, 503 or a network error leave the session valid. Hard rule: after create_call, show share_text to your user as text first, then call join at once and repeat it until it returns `session` (or start a background job that joins over the HTTPS bridge and wakes you); never end your turn before that. Then keep calling next in a loop.
Annotations the server declares
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
- readOnlyHint: true
- title: Wait for the next turn
This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.
Install
Pinned to version 1.0.0. Values in angle brackets are yours to fill in.
claude mcp add --transport http voicehook https://voicehook.ai/mcp?utm_source=mcpregistry&utm_campaign=d11-registryRun in a terminal.
Claude Code permissions
Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.
{
"permissions": {
"allow": [
"mcp__voicehook__next",
"mcp__voicehook__decisions"
],
"ask": [
"mcp__voicehook__create_call",
"mcp__voicehook__join",
"mcp__voicehook__show",
"mcp__voicehook__ui",
"mcp__voicehook__activity",
"mcp__voicehook__send_data",
"mcp__voicehook__add_vocab",
"mcp__voicehook__helper_credential",
"mcp__voicehook__helper_activity",
"mcp__voicehook__helper_show",
"mcp__voicehook__helper_next",
"mcp__voicehook__notify_me",
"mcp__voicehook__call_me"
],
"deny": [
"mcp__voicehook__say",
"mcp__voicehook__status",
"mcp__voicehook__decide",
"mcp__voicehook__leave",
"mcp__voicehook__helper_status",
"mcp__voicehook__helper_decide"
]
}
}Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as voicehook. Review it before you use it.
