Skip to main content
Tools let the agent call your app. Hooks let your app hear the pipeline: the user’s transcript before the agent acts on it, dictation before it is pasted, your own tool calls before and after they execute, and a receipt when the turn finishes. With hooks, VoiceOS can become the voice front-end for an app you already built — your handler recognizes an intent, does the work in your own backend, and answers in the notch. The agent never runs. Hooks are ordinary MCP tools with reserved names (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: a hooks block, and the transcript permission — the grant that makes the access loud at install and at share review.
Rules the validator enforces:
  • Any hook requires the transcript permission. Scope "agent" covers transcript, preToolUse, postToolUse, and turnComplete; scope "dictation" covers dictation; "all" covers both.
  • dictation hooks 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. apps is optional (but encouraged) on every other hook.
  • Tool taps are scoped to your own tools. scope: "own" is the only v1 value.
Users see a dedicated callout on the install sheet when a manifest declares hooks, and can switch any integration’s hooks off at any time with the Transcript access toggle on its page — without uninstalling it.

Writing handlers

defineHooks registers the reserved tools on your MCP server:
Every handler receives one typed input object and returns the same envelope:
Returning {} — 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. requireConfirmation is 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 transcript permission 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 your summary — an app that hears the user should read like one.