En MCP-server gör ett API till några namngivna verktyg som en agent anropar mitt i en konversation, och ett långt jobb ryms bakom ett när verktyget returnerar ett handtag som agenten väntar på i avgränsade omgångar. Klistra in en podd-länk, be om huvudinnehållet på franska, så skrivs ingen kod.
En kodningsagent kan använda VocalStack API:t på samma sätt som vilket program som helst: läs API-referensen, skriv några rader mot SDK:n och kör dem. Det är rätt väg för något som ska köra utan agenten.
MCP (Model Context Protocol) är till för det andra fallet: du pratar med en assistent och vill att den transkriberar något direkt, utan kod. En MCP-server publicerar en kort lista med namngivna verktyg, var och ett med en beskrivning och ett JSON-schema för sina argument. Agenten läser listan en gång och anropar ett verktyg med namn när en förfrågan passar. ”Transkribera den här podden och berätta vad de sa om priser” blir tre verktygsanrop, och agenten ser aldrig någon HTTP-rutt.
Servrar finns i två slag. En lokal server körs som en underprocess till klienten och kommunicerar via stdio, vilket är hur de flesta filsystem- och databasservrar fungerar. En fjärrserver ligger bakom en URL och talar Streamable HTTP, transporten som i revideringen av specifikationen från mars 2025 ersatte den äldre HTTP-plus-SSE-transporten (server-sent events). Klienten skickar varje förfrågan, och servern svarar på samma anslutning; allt den behöver säga före slutresultatet strömmas i förväg. Varje klient som är skriven mot den aktuella specifikationen kan använda båda slagen.
VocalStacks server är fjärrsorten, på {{api}}/v1/mcp, och att använda den kostar detsamma som API:t. Du behöver bara URL:en.
Öppna Developers-området i dashboarden på {{app}}/developers. Den första fliken, Connect an AI agent, visar server-URL:en och ett installationsutdrag för varje klient. De tre utdragen nedan är desamma som visas där.
Kör det här i din terminal:
claude mcp add --transport http vocalstack {{api}}/v1/mcp
Lägg till det här i .cursor/mcp.json i ditt projekt, eller i ~/.cursor/mcp.json för alla projekt:
{"mcpServers":{"vocalstack":{"url":"{{api}}/v1/mcp"}}}
Alla klienter som stöder Streamable HTTP kan lägga till servern med den här URL:en. Det här är den generella formen som dashboarden visar:
{
"vocalstack": {
"type": "streamable-http",
"url": "{{api}}/v1/mcp"
}
}
Du behöver ingen API-nyckel för att komma igång. Första gången klienten ansluter loggar du in med ditt VocalStack-konto i webbläsaren, och klienten sparar token:en. Dashboarden sammanfattar det på en rad: ”Du loggar in med ditt VocalStack-konto första gången. Ingen nyckel behövs.”
Det här är MCP:s auktoriseringsspecifikation i praktiken, inte ett VocalStack-trick. En fjärrserver svarar på en oautentiserad förfrågan med en 401 som pekar på dess metadata för skyddade resurser: ett litet JSON-dokument som anger auktoriseringsservern och de scopes servern kräver. Klienten läser det, kör ett standardiserat OAuth 2.1-flöde i din webbläsare och kommer tillbaka med en token som är utfärdad enbart för den servern. Varje fjärr-MCP-server som följer specifikationen loggar in dig på samma sätt, och därför kan klienterna ovan göra det utan att veta något om VocalStack.
En API-nyckel fungerar också, för en klient som körs på en server eller i ett skript. Skicka den som Authorization: Bearer vs_key_..., samma header som REST-API:t tar. Nycklar skapas under Developers → API keys. De två transkriberingsverktygen behöver behörigheterna Write och Stream audio. Den andra låter konstig för en fil, men verktygen går genom samma skapandepunkt som alla transkriberingar, även livetranskriberingar, och den punkten kontrollerar båda. Läsverktygen behöver Read; list_voices behöver bara en giltig autentisering.
När du har loggat in ser agenten nio verktyg. Du kommer sällan att nämna dem själv, men att känna till dem förklarar vad agenten gör härnäst.
Alla verktyg tar emot och returnerar camelCase-JSON, med samma fältnamn som /v1-typerna; en transkriberings handtag är dess transcriptionId.
transcribe_url startar transkribering av ljud eller video på en offentlig URL: en fillänk, ett podd-avsnitt, en YouTube-video. Livesändningar tas inte emot. Valfria argument: name, spokenLanguage (utelämna det för att identifiera språket), speakerLabels (auto, on eller off) och startS/endS för att transkribera bara en del av ljudet.transcribe_file gör samma sak för en fil som agenten har, skickad som fileBase64 med sitt filename. Den avkodade storleken är begränsad till 10 MiB, ungefär tio minuter 128 kbps MP3; för allt större ger du agenten en länk.Båda returnerar direkt med transcriptionId, state: "queued" och en next-ledtråd som pekar ut väntverktyget. Transkriberingar som agenten skapar startar privata, utan delningslänk.
En agent kan inte sitta igenom en livesändning mer tåligt än du kan; den skulle fortsätta anropa väntverktyget tills någon tog datorn ifrån den. En färdig inspelning har ett slut, och det är vad nästa par verktyg väntar på.
Ett verktygsanrop är en HTTP-förfrågan, och HTTP-förfrågningar är inte ämnade att vara en timme långa. Klienter ger upp på dem, proxyservrar stänger dem, och en modell som väntar på ett verktyg kan inte göra något annat. Mönstret för alla långa jobb bakom MCP är därför detsamma som REST-API:t använder: starta jobbet och få ett handtag, vänta på det under en begränsad tid och anropa igen om det inte är klart. Det är handtaget, inte anslutningen, som bär tillståndet.
wait_for_transcription blockerar tills jobbet är done eller failed, eller tills timeoutS har gått (standard 50 sekunder, högst 60, vilket håller anropet under de tidsgränser de flesta klienter och proxyservrar tillämpar). Om resultatet säger timedOut: true kör jobbet fortfarande och agenten anropar verktyget igen. Medan verktyget väntar skickar servern MCP-framstegsnotiser om klienten har bett om dem: en procentsats och en fas, till exempel ”hämtar 3,1 / 8,0 MB” eller ”transkriberar 01:25 av 02:00”.get_transcription returnerar status och, när den är klar, texten. format: "text" ger en rad per segment som [mm:ss] Speaker 1: ...; "segments" ger tidsatta rader med start, end, speaker och speakerName; includeWords: true lägger till ordtider. Resultaten delas upp i sidor (offset, limit, standard 500 segment) med en nextOffset när fler återstår.Sidindelningen finns för modellen, inte för nätverket. Allt ett verktyg returnerar klistras in i agentens kontextfönster, där det konkurrerar med din konversation och kostar tokens vid varje senare tur. Ett tvåtimmarsmöte är tiotusentals ord; om allt returnerades på en gång skulle frågan du ställde trängas ut ur kontexten. Bra MCP-verktyg returnerar en sida och en markör och låter agenten avgöra hur mycket den behöver.
En frånkoppling eller en timeout avbryter aldrig jobbet, eftersom jobbet finns på servern, inte i MCP-förfrågan. När det är klart är jobbet ytterligare en post i ditt bibliotek, och nästa verktyg behandlar det som vilket annat som helst.
list_transcriptions listar kontots transkriberingar, nyast först, med status och längd; lifecycle är active, archived eller all.search_transcriptions söker i vad som sagts i alla transkriberingar, på vilket språk som helst, och returnerar de matchande raderna, var och en med sin transkribering och sekunden den sades. transcriptionId begränsar sökningen till en transkribering; lang lägger till en översättning av varje träff.Att hitta en rad är den billiga halvan. Två verktyg till reder ut vad hela sagt.
get_summary returnerar AI-titeln och sammanfattningen av en färdig transkribering, eventuellt översatt med lang. state: "pending" betyder att sammanfattningen fortfarande skrivs (den är vanligtvis klar inom några sekunder efter att jobbet blivit klart), och agenten frågar igen.translate_transcription returnerar ett färdigt transkript på ett annat språk, som text eller tidsatta segment, uppdelat i sidor precis som get_transcription. Översättningar sparas, så att fråga igen inte upprepar arbetet.list_voices listar de röster som kan läsa upp ett transkript på ett språk: id, namn, kön och accent när de är kända, ett kvalitetsbetyg och om den är standardrösten eller en av dina klonade röster. Den beskriver röster; den får inte en att tala (mer om vad servern inte gör nedan).Så här hänger verktygen ihop i praktiken.
När servern är tillagd ser en konversation i Claude Code ut så här. Du klistrar in en podd-länk och ber om huvudinnehållet på franska.
Agenten anropar transcribe_url:
{ "url": "https://example.org/episodes/42.mp3", "name": "Episode 42", "speakerLabels": "auto" }
Den får tillbaka ett transcriptionId och state: "queued", och följer next-ledtråden:
{ "transcriptionId": "4f1c...", "timeoutS": 50 }
Ett femtiominuters avsnitt transkriberas många gånger snabbare än det spelas upp, men inte inom ett enda väntanrop. Det första väntanropet returnerar timedOut: true med framsteg på, säg, 61 procent, så agenten anropar verktyget en gång till och får state: "done".
Nu anropar agenten get_summary med lang: "fr":
{ "transcriptionId": "4f1c...", "lang": "fr" }
Om sammanfattningen fortfarande är pending väntar agenten några sekunder; annars ger den dig en titel och en sammanfattning på franska. Fråga ”var pratade de om priser?” så anropar den search_transcriptions med query: "pricing" och samma transcriptionId, och citerar de matchande raderna med deras tidsstämplar. Ber du om hela innehållet på franska anropar den translate_transcription.
En handfull verktygsanrop, ingen kod och en transkribering i ditt bibliotek. Vart och ett av anropen gick genom samma spärrar som en REST-förfrågan, och det är de spärrarna som sätter notan och gränserna.
MCP-servern är API:t genom en annan ingång: samma gränser, samma räkning.
POST /v1/transcriptions: abonnemangets skapandetakt (10, 100 eller ett eget antal transkriberingar startade per timme), dess tak för samtidiga transkriberingar (1, 5 eller obegränsat) och dess kredit gäller alla. Registreringskrediten på $5 räcker till en första session, utan kort.isError: true med REST-API:ts felkod, en mening som modellen kan agera på, och fälten retryable och retryAfterS. insufficient_credit bär en topUpUrl; rate_limited anger hur länge man ska vänta. Det är viktigare än det låter: en modell läser feltexten, så en mening den kan agera på förvandlar en återvändsgränd till nästa verktygsanrop./v1/mcp-förfrågan: en agent i loop får en HTTP 429 med Retry-After innan något verktyg körs.idempotencyKey: att återanvända nyckeln från ett slutfört anrop spelar upp det första resultatet, och att återanvända den med andra argument avvisas, så att en agent som försöker igen på egen hand aldrig startar ett andra jobb. Varje verktyg som spenderar pengar bör erbjuda detta; agenter försöker igen betydligt friare än människor.Det var kanterna på vad servern gör. Två saker ligger med avsikt utanför dem.
Servern har inget verktyg som gör godtycklig text till tal, och inget sådant är planerat. VocalStack talar transkript och deras översättningar, med en standardröst eller en klonad röst, och inget annat. list_voices berättar för en agent vilka röster som kan läsa upp ett transkript på ett språk, inte hur man får en röst att säga något nytt.
Transkriberingsverktygen avvisar också livesändningar. En YouTube-livesändning eller en radiosändning kräver en livetranskribering, startad från dashboarden eller via POST /v1/transcriptions/live i API-referensen. En färdig YouTube-video är en fil, och den tar transcribe_url emot.
Om du hellre skriver koden själv går att transkribera en fil med API:et igenom samma steg som HTTP-anrop, och realtidsguiden täcker WebSocket.