voiceos.integration.json, validated on install and on every reload.
Validation errors are flat path: message strings; anything not listed here
is rejected or ignored.
The smallest valid manifest
Everything else on this page is optional or a variation of these eight fields:Top level
publisher
runtime
One of three shapes:
auth
apiKeyfields default torequired: true; values are collected via setup fields, stored encrypted, and injected asprocess.env.<key>. Never persisted in plaintext, never shown to the agent.oauth2is in the contract today; the VoiceOS-brokered login flow ships with the managed broker.pkcedefaults totrue.
permissions
All opt-in, all shown to the user at install time:
preferences
tools[]
intents[]
Intents make short Agent voice or typed requests eligible for a dedicated
selector running alongside the normal agent. They reuse declared tools and do
not change schemaVersion: 1. See Fast intents for a
complete authoring walkthrough and rollout requirements.
Utterances and responses use single-brace placeholders (
{bot}) referring to
slots or fixed arguments. Every required slot that is not fixed must appear in
every utterance. Each required tool input must be fixed or declared as a
required slot. Slot/fixed-argument keys must match
/^[A-Za-z_][A-Za-z0-9_]{0,63}$/; __proto__, prototype, and constructor
are forbidden.
IntentSlot
Live choices are published under MCP tool metadata
_meta["voiceos/intent-slot-values"][slotName]. The SDK exports the key as
INTENT_SLOT_VALUES_META_KEY. Resolved lists need 1–30 strings of at most 200
characters each. Invalid or empty lists omit the entire intent. A string enum
in the live tool schema also restricts the allowed values; where both sources
restrict values, VoiceOS uses their intersection.
Publish changed tool metadata with notifications/tools/list_changed.
VoiceOS’s optional read-only refresh hint is
notifications/voiceos/refresh_intent_values, exported as
INTENT_REFRESH_NOTIFICATION_METHOD. See Keeping choices current
for the MCP update example and refresh behavior.
asr.vocabulary
An optional array of up to 50 nonempty terms, each 1–80 characters after trimming,
with no commas or control characters. These are recognition hints for Agent
voice commands, not intent slots or tool arguments. They do not affect Dictate
mode or typed input, grant transcript access, or modify the user’s dictionary.
The host budgets up to 10 unique terms / 1 KiB across enabled apps; provider
limits also apply. Put useful terms first and reload after changing the list.
See App vocabulary.
Cross-field validation
These fire even when every field parses:- A tool with
execution.mode: "background"requires thebackgroundpermission. - A
selectpreference must declare non-emptyoptions. - An
authfield and a preference cannot share a name — they share one config namespace and one env var. - Every
{{binding}}in a tool’s confirmation must name a property of that tool’sinputSchema. - A confirmation view may contain at most one
widgetblock, and a widget view may not also containbutton/actionsblocks. canvasblocks are rejected inschemaVersion: 1(reserved for a future sandboxed renderer), and would additionally require anetworkpermission.role: "custom"buttons/actions are rejected (reserved for a future server round-trip).- Each intent references a declared tool; slots and fixed arguments name its input properties. Every required tool input is fixed or supplied by a required slot, and utterance placeholders cover required extracted slots.
Validating
validateManifest(json) / validateView(view) from
@voiceos/integration-sdk — both return
{ ok: true, value } | { ok: false, errors: string[] }.
