Generate speech with Murf: Gen2 text-to-speech, voice library, cloned voices, voice changer, text translation and Murf Dub dubbing jobs and projects.
Murf ships in the w6w first-party pack. It declares 15 actions, 3 health checks, and the host runs its code in a sandbox that never sees the credential.
io.w6w.murfMurf is an AI voice platform. This app synthesizes speech from text with the Gen2 model (voice, locale, style, speed, pitch, pronunciation dictionary, output format, optional zero-retention Base64 audio), browses the voice library with locale, gender and style filters, lists, checks and deletes cloned voices, converts an audio file at a URL into another voice with the Voice Changer, and translates text between languages.
It also drives the Murf Dub automation API: list the source and destination dubbing languages, create transient dubbing jobs or project-based jobs from a file URL, poll a job for its download links, and create, list and update dubbing projects. Murf Dub uses a separate API key from the speech API, so the connection takes both.
Health checks track Murf’s own status page (the API component) and whether api.murf.ai is serving.
Three routes to the same 15 actions. The Workflow tab is generated from Murf's own manifest and carries its real ids, so it is copy-pasteable; the Code and CLI examples are the same call for any action on any app, so every app-specific value in them is a blank you fill in.
convert-voice Re-voice an audio recording at a public URL with a Murf voice (POST /v1/voice-changer/convert, multipart with `file_url`). Uploading a file's bytes is not supported here, only a URL.
create-dubbing-job Start a transient Murf Dub job for a file at a public URL (POST /v1/murfdub/jobs/create, multipart with `file_url`). Output links expire after 72 hours and the dub cannot be edited in the Murf UI; use Create Dubbing Job For Project for a persistent one. Poll Get Dubbing Job Status or set a webhook. Needs the Murf Dub API key. Uploading file bytes is not supported here.
create-dubbing-job-for-project Start a persistent, project-based Murf Dub job for a file at a public URL (POST /v1/murfdub/jobs/create-with-project-id, multipart with `file_url`). The dub stays editable in the Murf Dubbing platform. The project's source and target locales apply. Needs the Murf Dub API key. Uploading file bytes is not supported here.
create-dubbing-project Create a Murf Dub project (POST /v1/murfdub/projects/create) to hold persistent, editable dubs. Not idempotent: a retry creates a second project. Needs the Murf Dub API key.
delete-cloned-voice Permanently delete a cloned voice from the workspace (DELETE /v1/speech/voices/cloned/{voiceId}). Not reversible. A voice that is already gone is a 404 and fails the action.
get-dubbing-job-status Read a Murf Dub job (GET /v1/murfdub/jobs/{job_id}/status): overall `status` and, per target locale, its own status, error and `download_url` / `download_srt_url`. Poll until the job reports COMPLETED. Needs the Murf Dub API key.
get-voice-clone-status Poll a voice clone creation (GET /v1/speech/voice-clone-creation-status/{requestId}) until `status` is COMPLETED (then `voiceId`, prefix cln_, is set) or FAILED (then `errorMessage`). The request ID comes from Murf's Create Voice Clone, which needs an audio file upload and is not covered by this app.
list-cloned-voices List the synthesis-ready cloned voices in the workspace (GET /v1/speech/voices/cloned). Per Murf, cloned voices work with Falcon streaming only, not Synthesize Speech.
list-dubbing-destination-languages List the languages Murf Dub can dub INTO (GET /v1/murfdub/list-destination-languages), with the dubbing types (AUTOMATED, QA) each supports. Needs the Murf Dub API key.
list-dubbing-projects List Murf Dub projects (GET /v1/murfdub/projects/list), one page at a time. Pass the returned `next` back to read the next page; it is absent on the last page. Needs the Murf Dub API key.
list-dubbing-source-languages List the languages Murf Dub can dub FROM (GET /v1/murfdub/list-source-languages). Needs the Murf Dub API key.
list-voices List the voices available for synthesis (GET /v1/speech/voices). Murf returns the whole catalogue in one response with no pagination; the locale, gender, style and search filters are applied here, after the call.
synthesize-speech Convert text to speech with the Gen2 model (POST /v1/speech/generate). Returns a URL to the audio file (or Base64 audio for zero retention), its length, word timings and the characters left in the billing cycle. Consumes characters on every call. Murf's streaming (Falcon 2) endpoints are not covered.
translate-text Translate one or more texts into a target language (POST /v1/text/translate). Costs Murf credits; the response reports `metadata.credits_used`.
update-dubbing-project Set a Murf Dub project's target locales (PUT /v1/murfdub/projects/{project_id}/update). The documented body carries only `target_locales`; whether the list replaces or extends the existing one is not stated by Murf, so read the project back to confirm. Needs the Murf Dub API key.
A workflow step names the app and the action, and the editor fills in the
connection when you pick one. This is the Step shape from the
workflow spec, carrying Murf's real ids.
{
"manifestVersion": "2",
"name": "murf-example",
"steps": [
{
"id": "convert-voice",
"uses": {
"app": "io.w6w.murf",
"action": "convert-voice",
"connection": "conn_YOUR_CONNECTION_ID"
},
"with": {
"voiceId": "<voiceId>",
"fileUrl": "<fileUrl>"
}
}
]
}convert-voice create-dubbing-job create-dubbing-job-for-project create-dubbing-project get-dubbing-job-status +10 more actions available
Every app-specific value here is a blank you have to fill in. An
app action is reached through the connection that authenticates it, so the
address is a connection id, not the app id — and connections belong to your account,
so a public page cannot know yours. Create one for Murf, then fill in
the three blanks: conn_YOUR_CONNECTION_ID, the action key, and the
parameters that action declares. The call itself is real — the shape is transcribed
from the studio's own snippet builder, which prints the same kind of blanks — but
nothing in it is specific to Murf. The Workflow tab is where this app's
real ids are.
npm install @w6w/sdkyarn add @w6w/sdkpnpm add @w6w/sdkdeno add npm:@w6w/sdkimport { W6wClient, isActionRun } from "@w6w/sdk";
// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.
const client = new W6wClient();
const envelope = await client.run({
urn: "conn_YOUR_CONNECTION_ID",
action: "convert-voice",
payload: {
voiceId: "<value>",
fileUrl: "<value>",
// format: "<value>",
// sampleRate: "<value>",
// channelType: "<value>",
// locale: "<value>",
// style: "<value>",
// rate: "<value>",
// pitch: "<value>",
// variation: "<value>",
// retainAccent: "<value>",
// retainProsody: "<value>",
// returnTranscription: "<value>",
// encodeOutputAsBase64: "<value>",
},
});
if (isActionRun(envelope)) console.log(envelope.value); npm install -g @w6w/cli w6w run conn_YOUR_CONNECTION_ID --action convert-voice --payload '{"voiceId":"<value>","fileUrl":"<value>"}' Give an AI agent Murf — without giving it Murf's credentials. One MCP endpoint exposes every app, function and workflow the caller is entitled to, as tools it can discover and run. Access is granted per team while we onboard.
One tool call{
"name": "w6w_invoke",
"arguments": {
"ref": "app:io.w6w.murf#convert-voice",
"input": {
"voiceId": "<voiceId>",
"fileUrl": "<fileUrl>"
}
}
}
Every tool names its target with a single ref. The
app: form above doesn't name a connection at all — the
host resolves which of the caller's Murf connections to sign
with, and refuses rather than guesses when the answer is ambiguous.
The token is attached host-side, at the moment of the call. It is never a tool argument, never in the model's context, and never in a transcript — so a prompt injection has nothing to exfiltrate.
Tools are derived per end user from what that person has actually connected and is entitled to — not one shared bot identity carrying the union of everyone's access.
Multi-step work runs on the workflow engine and returns a run handle the agent can poll — retries, branching and state survive the conversation that started them.
Murf's declared health checks are on the surface too, so an agent can tell "the vendor is down" from "your credential expired" before it burns a retry on either.
The MCP surface is part of the hosted platform. Murf itself is MIT, and the runtime that executes it is source-available (FSL).
Murf declares its own checks, so its health is a property of the app rather than something the host guesses at.
The "API" component from murf.statuspage.io, plus Studio for visibility.
An unauthenticated GET /v1/speech/voices. Murf's documented `error_code` / `error_message` refusal proves the API is serving; it says nothing about any credential.