VIAxVOICE
Onboarding

Connect to VIAxVOICE.

Three ways in, by what you are. Agents speak over MCP, apps drop in a connector, humans open the Console. Pick your lane.


Agents Speak over MCP

If you're a fleet agent you already speak MCP β€” so voice is just two more tools. Request in, audio (and a transcript, or an envelope) back. No HTTP plumbing, no secret handling on your side.

Add the VIAxVOICE MCP server

It's registered in the fleet MCP registry. Your operator enables it for your identity β€” no config file to hand-edit.

Enroll a voice (once)

Pick a label from the pool (aria … ember). It becomes your stable voice β€” semi-permanent, like your avatar colour.

Call the tools

voice_synthesize to speak, voice_transcribe to listen. That's the whole surface.

voice_synthesize β€” MCP
# tool call (arguments)
{
  "text": "Handing off the mailer SKU.",
  "voice": "sage",
  "format": "ogg"
}

# result
{
  "audio_b64": "T2dnU…",
  "envelope": { "v":1, "rate":20, "peaks":[…] },
  "voice": "sage",
  "format": "ogg"
}
Why MCP and not a webhook? Synthesis is request/response β€” you want the audio back. Webhooks are for fire-and-forget events; the one place they'll fit later is an async /animate completion callback for long video renders.

Apps Drop in the connector

This is the first-adapter pattern the fleet standardized on. A thin, feature-flagged client: config β†’ mint-token β†’ typed client. When VIAxVOICE is reachable, voice lights up. When it isn't, every surface degrades to β€œvoice unavailable” β€” never an error.

Copy the connector

Take api/connectors/voice.py from VIAxTEAMS β€” it's the reference edge. Same three-piece shape as the LiveKit and MCP connectors.

Set two secrets

VIAXVOICE_URL and VIAXVOICE_SECRET. That's the whole activation β€” no code change to turn voice on.

Feature-detect, then call

Read capabilities() to show/hide affordances, then call synthesize() / transcribe(). The client mints a short-lived bearer per call.

voice.py β€” the edge
from api.connectors import voice

# cheap, no network β€” gate your UI on this
if voice.capabilities()["synthesize"]:
    audio = voice.synthesize(
        "Deploy is green, @viaxarmada",
        voice="sage", format="ogg",
    )
    # β†’ audio bytes; post it, play it, store it

# unset env β†’ is_configured() False β†’ clean 503,
# never a crash. Zero coupling.
The API itself is not behind fleet SSO β€” it authorizes each call with a short-lived HS256 bearer. SSO gates the human Console only.

Humans Open the Console

The operator Console is the human face of the service β€” a live neural-deck dashboard: the service heartbeat, the under-the-hood pipeline, the voice pool, a synth playground, the avatar pipeline, usage & metering, and access control.

Served from the service

The Console is served from the VIAxVOICE app at /console β€” same origin as the API it manages, so it can talk to it live and hold a session. Not a static page.

behind fleet SSO Β· operator scope

Coming online

The Console is being wired behind login.viaxarmada.com as a registered fleet app node. Until then, the fleet reaches voice through the connector and MCP paths above.

Auth One short-lived bearer

Every call carries an HS256 JWT signed with the shared secret. Call-scoped, not a session β€” a fresh token per request, minted by the caller, verified by the service.

audviaxvoicethe audience the service checks. scopestt Β· tts Β· healthone capability per token β€” metered & authorized per surface. isscaller idwho's calling β€” the metering key. expnow + 5 minshort TTL; tokens aren't reused.
mint β€” python
import jwt, time
now = int(time.time())
token = jwt.encode({
    "iss": "my-app",
    "aud": "viaxvoice",
    "scope": "tts",
    "iat": now,
    "exp": now + 300,
}, VIAXVOICE_SECRET, algorithm="HS256")