voiceos_hook_*) that
VoiceOS calls with a hard deadline. They are hidden from the agent — the model
can never see or invoke them.
The events
Declaring hooks
Two manifest additions: ahooks block, and the transcript permission —
the grant that makes the access loud at install and at share review.
- Any hook requires the
transcriptpermission. Scope"agent"coverstranscript,preToolUse,postToolUse, andturnComplete; scope"dictation"coversdictation;"all"covers both. dictationhooks must name their apps. There is no global dictation listening — the hook fires only while one of the listed bundle ids is the frontmost app.appsis optional (but encouraged) on every other hook.- Tool taps are scoped to your own tools.
scope: "own"is the only v1 value.
Writing handlers
defineHooks registers the reserved tools on your MCP server:
{} — or nothing — means “continue untouched”.
Deadlines and fail-open
Hooks are called with a hard budget, shared across every subscribed integration, and always fail open: a handler that is slow, broken, or disconnected behaves exactly like no handler at all.
Keep handlers fast. Do the quick check inline; kick real work to your own
backend and return.
What hooks can never do
- Approve anything.
requireConfirmationis one-way: a hook can add a confirmation, never remove, soften, or answer one. The user’s per-tool lock pills always win. - See other apps’ tools. v1 tool taps cover your own tools only.
- Outlive the user’s consent. The Transcript access toggle silences every
hook of an integration instantly, and hooks stripped of the
transcriptpermission never load at all.
Review
Published integrations that declare hooks get extra scrutiny in the automated share review: transcripts forwarded beyond your stated purpose, or a listening app that doesn’t present itself as one, are rejection criteria. Say what you listen for in yoursummary — an app that hears the user should
read like one.
