En MCP-server gør et API til nogle få navngivne værktøjer, som en agent kalder midt i en samtale. Et langt job kan styres bag ét værktøj, når værktøjet returnerer et håndtag, som agenten venter på i afgrænsede trin. Indsæt et podcast-link, bed om hovedpointerne på fransk, og der skrives ingen kode.
En kodeagent kan bruge VocalStack API'et, som ethvert program gør: læse API-referencen, skrive nogle få linjer mod SDK'et og køre dem. Det er den rigtige vej for noget, der skal køre uden agenten.
MCP (Model Context Protocol) er til det andet tilfælde: du taler med en assistent og vil have den til at transskribere noget nu, uden kode. En MCP-server udgiver en kort liste med navngivne værktøjer, hver med en beskrivelse og et JSON-skema for sine argumenter. Agenten læser listen én gang og kalder et værktøj ved navn, når en forespørgsel passer til det. »Transskribér denne podcast, og fortæl mig, hvad de sagde om priser« bliver til tre værktøjskald, og agenten ser aldrig en HTTP-rute.
Der findes to slags servere. En lokal server kører som en underproces af klienten og kommunikerer via stdio, sådan som de fleste fil- og databaseservere fungerer. En fjernserver sidder bag en URL og taler Streamable HTTP, transporten, der afløste den ældre HTTP-plus-SSE-transport (server-sent events) i specifikationens revision fra marts 2025. Klienten sender hver forespørgsel, og serveren svarer på samme forbindelse; alt, serveren har at sige før det endelige resultat, streames forud for det. Enhver klient, der er skrevet mod den aktuelle specifikation, kan bruge begge slags.
VocalStacks server er den fjerne slags, på {{api}}/v1/mcp, og brug af den koster det samme som API'et. Alt, du skal bruge, er URL'en.
Åbn Dashboardets Developers-område på {{app}}/developers. Den første fane, Connect an AI agent, viser server-URL'en og et opsætningsuddrag for hver klient. De tre uddrag nedenfor svarer til dem, der vises der.
Kør dette i din terminal:
claude mcp add --transport http vocalstack {{api}}/v1/mcp
Tilføj dette til .cursor/mcp.json i dit projekt eller til ~/.cursor/mcp.json for alle projekter:
{"mcpServers":{"vocalstack":{"url":"{{api}}/v1/mcp"}}}
Enhver klient, der understøtter Streamable HTTP, kan tilføje serveren med denne URL. Dette er den generiske form, som Dashboardet viser:
{
"vocalstack": {
"type": "streamable-http",
"url": "{{api}}/v1/mcp"
}
}
Du behøver ikke en API-nøgle for at komme i gang. Første gang klienten forbinder, logger du ind med din VocalStack-konto i browseren, og klienten gemmer tokenet. Dashboardet siger det på én linje: »You'll sign in with your VocalStack account the first time. No key needed.«
Det er MCP's autorisationsspecifikation i arbejde, ikke et VocalStack-trick. En fjernserver besvarer en uautoriseret forespørgsel med en 401, der peger på dens metadata for den beskyttede ressource: et lille JSON-dokument, der navngiver autorisationsserveren og de scopes, serveren kræver. Klienten læser det, kører et standard OAuth 2.1-flow i din browser og vender tilbage med et token, der kun er udstedt til den server. Enhver fjern-MCP-server, der følger specifikationen, logger dig ind på samme måde, og derfor kan klienterne ovenfor gøre det uden at kende noget til VocalStack.
En API-nøgle virker også, til en klient, der kører på en server eller i et script. Send den som Authorization: Bearer vs_key_..., den samme header som REST API'et tager. Nøgler oprettes under Developers → API keys. De to transskriptionsværktøjer kræver tilladelserne Write og Stream audio. Den anden lyder underlig for en fil, men værktøjerne går gennem det samme oprettelsespunkt som enhver transskription, også live-transskriptioner, og det punkt kontrollerer begge. Læseværktøjerne kræver Read; list_voices kræver kun en gyldig legitimation.
Når du er logget ind, ser agenten ni værktøjer. Du vil sjældent nævne dem selv, men det at kende dem forklarer, hvad agenten gør næste gang.
Hvert værktøj tager og returnerer camelCase-JSON med de samme feltnavne som /v1-wire-typerne; en transskriptions håndtag er dens transcriptionId.
transcribe_url starter transskription af lyd eller video på en offentlig URL: et link til en fil, en podcastepisode, en YouTube-video. Live-streams accepteres ikke. Valgfri argumenter: name, spokenLanguage (udelad det for at få sproget registreret automatisk), speakerLabels (auto, on eller off) og startS/endS for kun at transskribere en del af lyden.transcribe_file gør det samme for en fil, agenten har, sendt som fileBase64 med sit filename. Den afkodede størrelse er begrænset til 10 MiB, nogenlunde ti minutters MP3 ved 128 kbps; for alt større skal agenten have et link.Begge returnerer straks med transcriptionId, state: "queued" og et next-hint, der nævner venteværktøjet. Agentoprettede transskriptioner starter private, uden delingslink.
En agent kan ikke sidde gennem en live-udsendelse tålmodigere end du kan; den ville blive ved med at kalde venteværktøjet, indtil nogen tog computeren fra den. En færdig optagelse har en ende, og det er det, næste par af værktøjer venter på.
Et værktøjskald er én HTTP-forespørgsel, og HTTP-forespørgsler er ikke beregnet til at vare en time. Klienter giver op på dem, proxyer lukker dem, og en model, der er blokeret af ét værktøj, kan ikke gøre andet. Mønsteret for ethvert langt job bag MCP er derfor det samme, som REST API'et bruger: start jobbet og få et håndtag, vent på det i et afgrænset tidsrum, og kald igen, hvis det ikke er færdigt. Det er håndtaget, ikke forbindelsen, der bærer tilstanden.
wait_for_transcription blokerer, indtil jobbet er done eller failed, eller indtil timeoutS er gået (standard 50 sekunder, maksimum 60, hvilket holder kaldet under de timeouts, de fleste klienter og proxyer anvender). Hvis resultatet siger timedOut: true, kører jobbet stadig, og agenten kalder værktøjet igen. Mens værktøjet venter, sender serveren MCP-fremskridtsnotifikationer, hvis klienten har bedt om dem: en procentdel og en fase, f.eks. "fetching 3.1 / 8.0 MB" eller "transcribing 01:25 of 02:00".get_transcription returnerer status og, når den er færdig, teksten. format: "text" giver én linje pr. segment som [mm:ss] Speaker 1: ...; "segments" giver tidsatte linjer med start, end, speaker og speakerName; includeWords: true tilføjer ordtider. Resultater paginerer (offset, limit, standard 500 segmenter) med et nextOffset, når flere er tilbage.Pagineringen er der for modellen, ikke for netværket. Alt, et værktøj returnerer, indsættes i agentens kontekstvindue, hvor det konkurrerer med din samtale og koster tokens ved hver senere tur. Et to timer langt møde er titusindvis af ord; at returnere det hele på én gang ville skubbe det spørgsmål, du stillede, ud af konteksten. Gode MCP-værktøjer returnerer en side og en markør og lader agenten afgøre, hvor meget den har brug for.
En afbrydelse eller en timeout annullerer aldrig jobbet, for jobbet lever på serveren, ikke i MCP-forespørgslen. Når det er færdigt, er jobbet blot en ekstra post i dit bibliotek, og de næste værktøjer behandler det som alle andre.
list_transcriptions lister kontoens transskriptioner, nyeste først, med status og varighed; lifecycle er active, archived eller all.search_transcriptions søger i, hvad der blev sagt i alle transskriptioner, på alle sprog, og returnerer de matchende linjer, hver med sin transskription og det sekund, den blev sagt. transcriptionId indsnævrer søgningen til én transskription; lang tilføjer en oversættelse af hvert hit.At finde en linje er den billige halvdel. To værktøjer mere finder ud af, hvad det hele sagde.
get_summary returnerer den AI-genererede titel og resumé for en færdig transskription, eventuelt oversat med lang. state: "pending" betyder, at resuméet stadig skrives (det er normalt klar få sekunder efter, jobbet er færdigt), og agenten spørger igen.translate_transcription returnerer en færdig transskription på et andet sprog, som tekst eller tidsatte segmenter, pagineret ligesom get_transcription. Oversættelser gemmes, så at spørge igen gentager ikke arbejdet.list_voices lister de stemmer, der kan læse en transskription op på et sprog: id, navn, køn og accent når kendt, en kvalitetsvurdering, og om det er standardstemmen eller en af dine klonede stemmer. Den beskriver stemmer; den får ikke en til at sige noget nyt (mere om det, hvad serveren ikke gør, nedenfor).Sådan hænger værktøjerne sammen i praksis.
Når serveren er tilføjet, forløber en samtale i Claude Code sådan her. Du indsætter et podcast-link og beder om hovedpointerne på fransk.
Agenten kalder transcribe_url:
{ "url": "https://example.org/episodes/42.mp3", "name": "Episode 42", "speakerLabels": "auto" }
Den får et transcriptionId og state: "queued" tilbage og følger next-hintet:
{ "transcriptionId": "4f1c...", "timeoutS": 50 }
En halvtreds minutter lang episode transskriberes mange gange hurtigere, end den afspilles, men ikke inden for ét ventetidsrum. Den første ventetid returnerer timedOut: true med fremskridt på f.eks. 61 procent, så agenten kalder værktøjet én gang til og får state: "done".
Nu kalder agenten get_summary med lang: "fr":
{ "transcriptionId": "4f1c...", "lang": "fr" }
Hvis resuméet stadig er pending, venter agenten nogle sekunder; ellers giver den dig en titel og et resumé på fransk. Spørger du »hvor talte de om priser?«, kalder den search_transcriptions med query: "pricing" og samme transcriptionId og citerer de matchende linjer med deres tidsstempler. Beder du om hele teksten på fransk, kalder den translate_transcription.
Et håndfuld værktøjskald, ingen kode og en transskription i dit bibliotek. Hvert af disse kald gik gennem de samme porte som en REST-forespørgsel, og det er de porte, der sætter regningen og grænserne.
MCP-serveren er API'et gennem en anden indgang: de samme grænser og den samme regning.
POST /v1/transcriptions: abonnementets oprettelsesrate (10, 100 eller et selvvalgt antal transskriptioner startet pr. time), dets samtidige-transskriptionsloft (1, 5 eller ubegrænset) og dens kredit gælder alle. De $5 i kredit ved tilmelding dækker en første session, uden kort.isError: true med REST API'ets fejlkode, en sætning modellen kan handle på, og felterne retryable og retryAfterS. insufficient_credit medfører en topUpUrl; rate_limited siger, hvor længe der skal ventes. Det betyder mere, end det lyder: en model læser fejlteksten, og en sætning den kan handle på, forvandler en blindgyde til næste værktøjskald./v1/mcp-forespørgslen: en agent i en løkke får en HTTP 429 med Retry-After, før noget værktøj kører.idempotencyKey: genbrug af nøglen fra et gennemført kald gentager det første resultat, og genbrug med andre argumenter afvises, så en agent, der prøver igen af sig selv, aldrig starter et andet job. Ethvert værktøj, der bruger penge, bør tilbyde dette; agenter prøver langt mere frit igen end mennesker.Det er kanterne af, hvad serveren gør. To ting falder bevidst uden for dem.
Serveren har intet værktøj, der omsætter vilkårlig tekst til tale, og et sådant er ikke planlagt. VocalStack taler transskriptioner og deres oversættelser, med en standardstemme eller en klonet stemme, og intet andet. list_voices fortæller en agent, hvilke stemmer der kan læse en transskription på et sprog, ikke hvordan man får en stemme til at sige noget nyt.
Transskriptionsværktøjerne afviser også live-streams. En YouTube-livestream eller en radiostream kræver en live-transskription, startet fra Dashboardet eller via POST /v1/transcriptions/live i API-referencen. En færdig YouTube-video er en fil, og den tager transcribe_url.
Hvis du hellere vil skrive koden selv, gennemgår transskription af en fil med API'et de samme trin som HTTP-kald, og realtidsvejledningen dækker WebSocket.