En MCP-server gjør et API om til noen få navngitte verktøy som en agent kaller midt i en samtale, og en lang jobb passer bak ett når verktøyet gir tilbake et håndtak som agenten venter på i avgrensede runder. Lim inn en podcastlenke, be om hovedpunktene på fransk, og ingen kode blir skrevet.
En kodeagent kan bruke VocalStack-API-et slik ethvert program gjør: lese API-referansen, skrive noen linjer mot SDK-en og kjøre dem. Det er den riktige veien for noe som skal kjøre uten agenten.
MCP (Model Context Protocol) er til det andre tilfellet: du snakker med en assistent og vil at den skal transkribere noe nå, uten kode. En MCP-server publiserer en kort liste med navngitte verktøy, hver med en beskrivelse og et JSON-skjema for argumentene. Agenten leser listen én gang og kaller et verktøy med navn når en forespørsel passer. «Transkriber denne podcasten og fortell meg hva de sa om priser» blir til tre verktøykall, og agenten ser aldri en HTTP-rute.
Det finnes to typer servere. En lokal server kjører som en underprosess av klienten og kommuniserer over stdio, slik de fleste fil- og databaseservere fungerer. En ekstern server ligger bak en URL og bruker Streamable HTTP, transporten som erstattet den eldre HTTP-plus-SSE-transporten (server-sent events) i spesifikasjonens revisjon fra mars 2025. Klienten sender hver forespørsel, og serveren svarer på samme forbindelse; alt den har å si før det endelige resultatet, strømmes i forkant. Enhver klient skrevet mot gjeldende spesifikasjon kan bruke begge typene.
VocalStacks server er den eksterne typen, på {{api}}/v1/mcp, og bruk av den koster det samme som API-et. Alt du trenger er URL-en.
Åpne utviklerområdet i dashbordet på {{app}}/developers. Den første fanen, Connect an AI agent, viser server-URL-en og et oppsettsutdrag for hver klient. De tre utdragene nedenfor samsvarer med dem som vises der.
Kjør dette i terminalen din:
claude mcp add --transport http vocalstack {{api}}/v1/mcp
Legg dette til i .cursor/mcp.json i prosjektet ditt, eller i ~/.cursor/mcp.json for alle prosjekter:
{"mcpServers":{"vocalstack":{"url":"{{api}}/v1/mcp"}}}
Enhver klient som støtter Streamable HTTP kan legge til serveren med denne URL-en. Dette er den generelle formen dashbordet viser:
{
"vocalstack": {
"type": "streamable-http",
"url": "{{api}}/v1/mcp"
}
}
Du trenger ikke en API-nøkkel for å starte. Første gang klienten kobler til, logger du inn med VocalStack-kontoen din i nettleseren, og klienten beholder tokenet. Dashbordet sier det i én linje: "You'll sign in with your VocalStack account the first time. No key needed."
Dette er MCPs autorisasjonsspesifikasjon i praksis, ikke et VocalStack-triks. En ekstern server svarer på en uautentisert forespørsel med en 401 som peker til sine metadata for beskyttet ressurs: et lite JSON-dokument som navngir autorisasjonsserveren og scopene serveren krever. Klienten leser det, kjører en standard OAuth 2.1-flyt i nettleseren din, og kommer tilbake med et token utstedt for den serveren alene. Enhver ekstern MCP-server som følger spesifikasjonen logger deg inn på samme måte, og det er derfor klientene over kan gjøre det uten å vite noe om VocalStack.
En API-nøkkel fungerer også, for en klient som kjører på en server eller i et skript. Send den som Authorization: Bearer vs_key_..., samme header som REST-API-et tar. Nøkler opprettes under Developers → API keys. De to transkripsjonsverktøyene trenger tillatelsene Write og Stream audio. Den andre høres rar ut for en fil, men verktøyene går gjennom samme opprettelsespunkt som all transkripsjon, også direkte, og dette punktet sjekker begge. Lesverktøyene trenger Read; list_voices trenger bare en gyldig legitimasjon.
Når du er innlogget, ser agenten ni verktøy. Du vil sjelden nevne dem selv, men å kjenne dem forklarer hva agenten gjør videre.
Hvert verktøy tar imot og returnerer camelCase-JSON, med de samme feltnavnene som /v1-wire-typene; en transkripsjons håndtak er dens transcriptionId.
transcribe_url starter transkripsjon av lyd eller video på en offentlig URL: en fillenke, en podcastepisode, en YouTube-video. Direktestrømmer godtas ikke. Valgfrie argumenter: name, spokenLanguage (utelat for å oppdage språket), speakerLabels (auto, on eller off) og startS/endS for å transkribere bare en del av lyden.transcribe_file gjør det samme for en fil agenten har, sendt som fileBase64 med filename. Den dekodede størrelsen er begrenset til 10 MiB, omtrent ti minutter 128 kbps MP3; for noe større, gi agenten en lenke.Begge returnerer straks med transcriptionId, state: "queued" og et next-hint som nevner ventverktøyet. Transkripsjoner startet av agenten er private, uten delingslenke.
En agent kan ikke sitte gjennom en direktesending tålmodigere enn du kan; den ville fortsatt å kalle ventverktøyet til noen tok bærbaren fra den. En ferdig opptak har en slutt, og det er det neste verktøyparet venter på.
Et verktøykall er én HTTP-forespørsel, og HTTP-forespørsler er ikke ment å vare i en time. Klienter gir opp på dem, proxyer lukker dem, og en modell som er blokkert av ett verktøy kan ikke gjøre noe annet. Mønsteret for enhver lang jobb bak MCP er derfor det samme REST-API-et bruker: start jobben og få et håndtak, vent på den i en avgrenset tid, og kall igjen hvis den ikke er ferdig. Det er håndtaket, ikke forbindelsen, som bærer tilstanden.
wait_for_transcription blokkerer til jobben er done eller failed, eller til timeoutS er gått (standard 50 sekunder, maksimum 60, som holder kallet under tidsgrensene de fleste klienter og proxyer bruker). Hvis resultatet sier timedOut: true, kjører jobben fortsatt, og agenten kaller verktøyet igjen. Mens verktøyet venter, sender serveren MCP-fremdriftsvarsler hvis klienten har bedt om dem: en prosentandel og en fase, for eksempel «henter 3,1 / 8,0 MB» eller «transkriberer 01:25 av 02:00».get_transcription returnerer status og, når den er ferdig, teksten. format: "text" gir én linje per segment som [mm:ss] Speaker 1: ...; "segments" gir tidsatte linjer med start, end, speaker og speakerName; includeWords: true legger til ordtidspunkter. Resultater deles i sider (offset, limit, standard 500 segmenter) med en nextOffset når flere gjenstår.Sidedelingen er der for modellen, ikke for nettverket. Alt et verktøy returnerer limes inn i agentens kontekstvindu, der det konkurrerer med samtalen din og koster tokens i hver senere tur. Et to timer langt møte er titusenvis av ord; å returnere alt på en gang ville skyve spørsmålet du stilte ut av konteksten. Gode MCP-verktøy returnerer en side og en markør, og lar agenten bestemme hvor mye den trenger.
Et frakoblet eller et tidsavbrudd avbryter aldri jobben, fordi jobben lever på serveren, ikke i MCP-forespørselen. Når den er ferdig, er jobben én oppføring til i biblioteket ditt, og de neste verktøyene behandler den som alle andre.
list_transcriptions lister kontoens transkripsjoner, nyeste først, med tilstand og varighet; lifecycle er active, archived eller all.search_transcriptions søker i det som ble sagt på tvers av alle transkripsjoner, på alle språk, og returnerer de treffende linjene, hver med sin transkripsjon og sekundet den ble sagt. transcriptionId begrenser søket til én transkripsjon; lang legger til en oversettelse av hvert treff.Å finne en linje er den billige halvdelen. To verktøy til finner ut hva hele greia sa.
get_summary returnerer AI-tittelen og sammendraget for en ferdig transkripsjon, eventuelt oversatt med lang. state: "pending" betyr at sammendraget fortsatt skrives (det er vanligvis klart innen sekunder etter at jobben er ferdig), og agenten spør igjen.translate_transcription returnerer en ferdig transkripsjon på et annet språk, som tekst eller tidsatte segmenter, delt i sider som get_transcription. Oversettelser lagres, så å spørre på nytt gjentar ikke arbeidet.list_voices lister stemmene som kan lese en transkripsjon på et språk: id, navn, kjønn og aksent når de er kjent, en kvalitetsvurdering, og om det er standardstemmen eller en av dine klonede stemmer. Den beskriver stemmer; den får ingen til å si noe nytt (mer om hva serveren ikke gjør nedenfor).Slik kjeder verktøyene seg sammen i praksis.
Når serveren er lagt til, går en samtale i Claude Code slik. Du limer inn en podcastlenke og ber om hovedpunktene på fransk.
Agenten kaller transcribe_url:
{ "url": "https://example.org/episodes/42.mp3", "name": "Episode 42", "speakerLabels": "auto" }
Den får tilbake en transcriptionId og state: "queued", og følger next-hintet:
{ "transcriptionId": "4f1c...", "timeoutS": 50 }
En femti minutter lang episode transkriberes mange ganger raskere enn den spilles, men ikke innen én ventetid. Den første ventetiden returnerer timedOut: true med fremdrift på, la oss si, 61 prosent, så agenten kaller verktøyet én gang til og får state: "done".
Nå kaller agenten get_summary med lang: "fr":
{ "transcriptionId": "4f1c...", "lang": "fr" }
Hvis sammendraget fortsatt er pending, venter agenten noen sekunder; ellers gir den deg en tittel og et sammendrag på fransk. Spør «hvor snakket de om priser?», og den kaller search_transcriptions med query: "pricing" og samme transcriptionId, og siterer de treffende linjene med tidsstemplene. Spør om alt på fransk, og den kaller translate_transcription.
Et håndfull verktøykall, ingen kode, og en transkripsjon i biblioteket ditt. Hvert av disse kallene gikk gjennom de samme portene som en REST-forespørsel, og det er disse portene som setter regningen og grensene.
MCP-serveren er API-et gjennom en annen inngang: samme grenser, samme regning.
POST /v1/transcriptions: abonnementets opprettelsesrate (10, 100 eller et eget antall transkripsjoner startet per time), taket for samtidige transkripsjoner (1, 5 eller ubegrenset) og kreditten gjelder alle. Registreringskreditten på $5 dekker en første økt, uten kort.isError: true med REST-API-ets feilkode, en setning modellen kan handle etter, og feltene retryable og retryAfterS. insufficient_credit har en topUpUrl; rate_limited sier hvor lenge du må vente. Dette betyr mer enn det høres ut som: en modell leser feilteksten, og en setning den kan handle etter gjør en blindvei om til neste verktøykall./v1/mcp-forespørselen: en løkkende agent får en HTTP 429 med Retry-After før noe verktøy kjører.idempotencyKey: å gjenbruke nøkkelen til et fullført kall spiller av det første resultatet, og å gjenbruke den med andre argumenter avvises, så en agent som prøver på nytt av seg selv aldri starter en ny jobb. Ethvert verktøy som bruker penger bør tilby dette; agenter prøver igjen langt friere enn folk gjør.Dette er kantene av hva serveren gjør. To ting ligger utenfor dem med vilje.
Serveren har ingen verktøy som gjør vilkårlig tekst om til tale, og ingen er planlagt. VocalStack snakker transkripsjoner og deres oversettelser, med en standard- eller klonet stemme, og ikke noe annet. list_voices forteller en agent hvilke stemmer som kan lese en transkripsjon på et språk, ikke hvordan man får en stemme til å si noe nytt.
Transkripsjonsverktøyene avviser også direktesendinger. En YouTube-direktesending eller en radiostrøm trenger en direkte transkripsjon, startet fra dashbordet eller gjennom POST /v1/transcriptions/live i API-referansen. En ferdig YouTube-video er en fil, og transcribe_url tar den.
Hvis du heller vil skrive koden selv, går transkribere en fil med API-et gjennom de samme stegene som HTTP-kall, og sanntidsveiledningen dekker WebSocket.