MCP server pretvara API u nekoliko imenovanih alata koje agent poziva usred razgovora, a dugi posao stane iza jednog kada alat vrati ručku na koju agent čeka u ograničenim koracima. Zalijepite poveznicu na podcast, zatražite sažetak na francuskom i ne napišete ni retka koda.
Programski agent može koristiti VocalStack API na isti način kao i svaki drugi program: pročitati referencu API-ja, napisati nekoliko redaka koda uz SDK i pokrenuti ih. To je pravi put za nešto što će raditi bez agenta.
MCP (Model Context Protocol) namijenjen je drugom slučaju: razgovarate s asistentom i želite da odmah nešto transkribira, bez koda. MCP server objavljuje kratak popis imenovanih alata, pri čemu svaki ima opis i JSON shemu za svoje argumente. Agent pročita popis jednom i pozove alat po imenu kada zahtjev odgovara. „Transkribiraj ovaj podcast i reci mi što su rekli o cijenama” postaje tri poziva alata, a agent nikada ne vidi HTTP rutu.
Serveri su dvije vrste. Lokalni server radi kao podproces klijenta i komunicira preko stdio-a, što je način na koji rade većina servera za datotečni sustav i baze podataka. Udaljeni server nalazi se iza URL-a i koristi Streamable HTTP, transport koji je u ožujku 2025. reviziji specifikacije zamijenio stariji transport HTTP-plus-SSE (server-sent events). Klijent šalje svaki zahtjev, a server odgovara na istoj vezi; sve što mora reći prije konačnog rezultata šalje se unaprijed u streamu. Svaki klijent napisan prema aktualnoj specifikaciji može koristiti bilo koju vrstu.
VocalStackov server je udaljeni tip, na adresi {{api}}/v1/mcp, a korištenje košta isto koliko i API. Potreban vam je samo URL.
Otvorite područje Developers na nadzornoj ploči na {{app}}/developers. Prva kartica, Connect an AI agent, prikazuje URL servera i snippet za postavljanje za svaki klijent. Tri snippeta u nastavku odgovaraju onima prikazanima tamo.
Pokrenite ovo u terminalu:
claude mcp add --transport http vocalstack {{api}}/v1/mcp
Dodajte ovo u .cursor/mcp.json u svoj projekt ili u ~/.cursor/mcp.json za svaki projekt:
{"mcpServers":{"vocalstack":{"url":"{{api}}/v1/mcp"}}}
Svaki klijent koji podržava Streamable HTTP može dodati server ovim URL-om. Ovo je generički oblik koji prikazuje nadzorna ploča:
{
"vocalstack": {
"type": "streamable-http",
"url": "{{api}}/v1/mcp"
}
}
Za početak ne trebate API ključ. Pri prvom povezivanju klijenta prijavite se u pregledniku svojim VocalStack računom, a klijent zadržava token. Nadzorna ploča to kaže u jednoj rečenici: "You'll sign in with your VocalStack account the first time. No key needed."
Ovo je MCP-ova specifikacija za autorizaciju u radu, a ne trik VocalStacka. Udaljeni server na neautorizirani zahtjev odgovara statusom 401 koji upućuje na svoje metapodatke zaštićenog resursa: mali JSON dokument koji navodi autorizacijski server i opsege koje server zahtijeva. Klijent ga pročita, u pregledniku pokrene standardni OAuth 2.1 tok i vraća se s tokenom izdanim samo za taj server. Svaki udaljeni MCP server koji slijedi specifikaciju prijavljuje vas na isti način, zbog čega gore navedeni klijenti to mogu bez ikakvog znanja o VocalStacku.
API ključ također radi, za klijent koji radi na serveru ili u skripti. Pošaljite ga kao Authorization: Bearer vs_key_..., u istom zaglavlju koje prima REST API. Ključevi se stvaraju pod Developers → API keys. Dva alata za transkripciju trebaju dozvole Write i Stream audio. Druga može zvučati čudno za datoteku, ali alati prolaze kroz istu točku stvaranja kao svaka transkripcija, uključujući i one uživo, a ta točka provjerava obje. Alati za čitanje trebaju Read; list_voices treba samo valjane vjerodajnice.
Nakon prijave agent vidi devet alata. Rijetko ćete ih sami spominjati, ali njihovo poznavanje objašnjava što agent radi dalje.
Svaki alat prima i vraća JSON u camelCase obliku, s istim nazivima polja kao i tipovi /v1 API-ja; ručka transkripcije je njezin transcriptionId.
transcribe_url pokreće transkripciju zvuka ili videa na javnom URL-u: poveznici na datoteku, epizodi podcasta, YouTube videu. Streamovi uživo se ne prihvaćaju. Neobavezni argumenti: name, spokenLanguage (izostavite ga za automatsko prepoznavanje jezika), speakerLabels (auto, on ili off) i startS/endS za transkribiranje samo dijela zvuka.transcribe_file radi isto za datoteku koju agent ima, poslanu kao fileBase64 s njezinim filename. Dekodirana veličina ograničena je na 10 MiB, otprilike deset minuta MP3-a od 128 kbps; za veće datoteke agentu dajte poveznicu.Oba vraćaju odmah transcriptionId, state: "queued" i next savjet koji imenuje alat za čekanje. Transkripcije koje kreira agent počinju kao privatne, bez poveznice za dijeljenje.
Agent ne može strpljivije pratiti prijenos uživo nego vi; neprestano bi pozivao alat za čekanje dok netko ne makne laptop. Završena snimka ima kraj, a za njega čeka sljedeći par alata.
Poziv alata jedan je HTTP zahtjev, a HTTP zahtjevi nisu namijenjeni da traju sat vremena. Klijenti ih odustanu, proxyji ih zatvore, a model koji je blokiran na jednom alatu ne može raditi ništa drugo. Zato je obrazac za svaki dugi posao iza MCP-a isti kao i kod REST API-ja: pokrenite posao i dobijete ručku, čekajte na nju ograničeno vrijeme i pozovite ponovno ako nije gotovo. Stanje nosi ručka, a ne veza.
wait_for_transcription čeka dok posao ne bude done ili failed, ili dok ne prođe timeoutS (zadano 50 sekundi, najviše 60, što drži poziv ispod vremenskih ograničenja koje primjenjuje većina klijenata i proxyja). Ako rezultat kaže timedOut: true, posao još radi i agent ponovno poziva alat. Dok alat čeka, server šalje MCP obavijesti o napretku ako ih klijent traži: postotak i fazu, primjerice „dohvaćanje 3,1 / 8,0 MB” ili „transkribiranje 01:25 od 02:00”.get_transcription vraća status i, kada je gotovo, tekst. format: "text" daje jedan redak po segmentu u obliku [mm:ss] Speaker 1: ...; "segments" daje vremenski označene retke s poljima start, end, speaker i speakerName; includeWords: true dodaje vremena riječi. Rezultati se stranicaju (offset, limit, zadano 500 segmenata) s nextOffset kada ih ostane više.Stranicenje služi modelu, a ne mreži. Sve što alat vrati lijepi se u kontekstni prozor agenta, gdje se natječe s vašim razgovorom i troši tokene pri svakom sljedećem koraku. Sastanak od dva sata vrijedi desetke tisuća riječi; kad bi se sve vratilo odjednom, pitanje koje ste postavili bi gurnulo iz konteksta. Dobri MCP alati vraćaju stranicu i kursor, a agent odlučuje koliko mu treba.
Prekid veze ili istek vremena nikada ne otkazuje posao, jer posao živi na serveru, a ne u MCP zahtjevu. Kada je gotov, posao je još jedan unos u vašoj biblioteci, a sljedeći alati s njim postupaju kao i s bilo kojim drugim.
list_transcriptions popisuje transkripcije računa, od najnovije prema starijoj, sa statusom i trajanjem; lifecycle je active, archived ili all.search_transcriptions pretražuje što je rečeno u svim transkripcijama, na bilo kojem jeziku, i vraća odgovarajuće retke, svaki s transkripcijom i sekundom u kojoj je izgovoren. transcriptionId sužava pretragu na jednu transkripciju; lang dodaje prijevod svakog pogotka.Pronaći redak je jeftina polovica posla. Dva alata dodatno rade na tome da utvrde što je cijela stvar rekla.
get_summary vraća AI naslov i sažetak završene transkripcije, po želji preveden s lang. state: "pending" znači da se sažetak još piše (obično je spreman unutar nekoliko sekundi nakon završetka posla), pa agent pita ponovno.translate_transcription vraća završeni transkript na drugom jeziku, kao tekst ili vremenske segmente, stranicen kao get_transcription. Prijevodi se pohranjuju, pa ponovno pitanje ne ponavlja posao.list_voices popisuje glasove koji mogu pročitati transkript na nekom jeziku: id, ime, spol i naglasak kada su poznati, ocjenu kvalitete te je li to zadani glas ili jedan od vaših kloniranih glasova. Opisuje glasove; ne tjera nijedan da nešto kaže (više o tome što server ne radi u nastavku).Evo kako alati rade zajedno u praksi.
Kada je server dodan, razgovor u Claude Codeu teče ovako. Zalijepite poveznicu na podcast i zatražite sažetak na francuskom.
Agent poziva transcribe_url:
{ "url": "https://example.org/episodes/42.mp3", "name": "Episode 42", "speakerLabels": "auto" }
Dobije natrag transcriptionId i state: "queued" te slijedi next savjet:
{ "transcriptionId": "4f1c...", "timeoutS": 50 }
Epizoda od pedeset minuta transkribira se mnogo puta brže nego što traje, ali ne unutar jednog čekanja. Prvo čekanje vraća timedOut: true s napretkom od, recimo, 61 posto, pa agent alat poziva još jednom i dobije state: "done".
Sada agent poziva get_summary s lang: "fr":
{ "transcriptionId": "4f1c...", "lang": "fr" }
Ako je sažetak još pending, agent čeka nekoliko sekundi; inače vam predaje naslov i sažetak na francuskom. Pitate „gdje su govorili o cijenama?” i on poziva search_transcriptions s query: "pricing" i istim transcriptionId, te citira odgovarajuće retke s vremenskim oznakama. Zatražite cijeli tekst na francuskom i on poziva translate_transcription.
Nekoliko poziva alata, bez koda, i transkripcija u vašoj biblioteci. Svaki od tih poziva prošao je iste provjere kao REST zahtjev, a upravo te provjere određuju račun i ograničenja.
MCP server je API kroz drugi ulaz: ista ograničenja, isti račun.
POST /v1/transcriptions: primjenjuju se stopa stvaranja paketa (10, 100 ili prilagođeni broj transkripcija pokrenutih po satu), njegovo ograničenje istodobnih transkripcija (1, 5 ili neograničeno) i njegov kredit. Kredit za registraciju od $5 pokriva prvu sesiju, bez kartice.isError: true s REST API-jevim kodom greške, rečenicom koju model može iskoristiti te poljima retryable i retryAfterS. insufficient_credit nosi topUpUrl; rate_limited kaže koliko treba čekati. To je važnije nego što zvuči: model čita tekst greške, pa rečenica s kojom može nešto učiniti slijepu ulicu pretvara u sljedeći poziv alata./v1/mcp: petlja dobije HTTP 429 s Retry-After prije nego što se pokrene ijedan alat.idempotencyKey: ponovna upotreba ključa dovršenog poziva vraća prvi rezultat, a ponovna upotreba s drugim argumentima se odbija, pa agent koji sam ponavlja pokušaje nikada ne pokreće drugi posao. Svaki alat koji troši novac trebao bi to ponuditi; agenti ponavljaju pokušaje puno slobodnije nego ljudi.Ovo su granice onoga što server radi. Dvije stvari su namjerno izvan njih.
Server nema alat koji pretvara proizvoljni tekst u govor i nije planiran. VocalStack izgovara transkripte i njihove prijevode, standardnim ili kloniranim glasom, i ništa drugo. list_voices govori agentu koji glasovi mogu pročitati transkript na nekom jeziku, a ne kako natjerati glas da kaže nešto novo.
Alati za transkripciju također odbijaju streamove uživo. YouTube live stream ili radijski stream traži transkripciju uživo, pokrenutu s nadzorne ploče ili kroz POST /v1/transcriptions/live u referenci API-ja. Završen YouTube video je datoteka i transcribe_url ga prima.
Ako radije sami napišete kod, transkripcija datoteke API-jem prolazi kroz iste korake kao HTTP pozivi, a vodič za transkripciju u stvarnom vremenu obrađuje WebSocket.