MCP-palvelin tekee API:sta muutaman nimetyn työkalun, joita agentti kutsuu keskustelun aikana. Pitkä työ mahtuu sen taakse, kun työkalu palauttaa kahvan, jota agentti odottaa rajatuissa vuoroissa. Liitä podcast-linkki, pyydä pääkohdat ranskaksi, eikä koodia tarvitse kirjoittaa.
Koodausagentti voi käyttää VocalStackin API:a samalla tavalla kuin mikä tahansa ohjelma: lukea API-viitteen, kirjoittaa muutaman rivin SDK:lla ja ajaa ne. Se on oikea tie asiaan, joka ajetaan ilman agenttia.
MCP (Model Context Protocol) on tarkoitettu toiseen tilanteeseen: keskustelet avustajan kanssa ja haluat sen litteroivan jotain heti ilman koodia. MCP-palvelin julkaisee lyhyen listan nimettyjä työkaluja, joista jokaisella on kuvaus ja argumenteille JSON-skeema. Agentti lukee listan kerran ja kutsuu työkalua nimeltä, kun pyyntö vastaa sitä. ”Litteroi tämä podcast ja kerro, mitä siinä sanottiin hinnoittelusta” muuttuu kolmeksi työkalukutsuksi, eikä agentti näe koskaan HTTP-reittiä.
Palvelimia on kahta tyyppiä. Paikallinen palvelin toimii asiakasohjelman aliprosessina ja puhuu stdio:n kautta, ja näin toimii useimmat tiedostojärjestelmä- ja tietokantapalvelimet. Etäpalvelin on URL:n takana ja puhuu Streamable HTTP:tä, siirtotapaa, joka korvasi vanhemman HTTP-plus-SSE-siirtotavan (server-sent events) määrittelyn maaliskuun 2025 versiossa. Asiakas lähettää jokaisen pyynnön, ja palvelin vastaa samalla yhteydellä; kaikki, mitä sen on sanottava ennen lopullista tulosta, suoratoistetaan sitä edeltäen. Mikä tahansa nykyistä määritystä vastaan kirjoitettu asiakas voi käyttää kumpaa tahansa.
VocalStackin palvelin on etäpalvelin osoitteessa {{api}}/v1/mcp, ja sen käyttö maksaa saman kuin API:n käyttö. Tarvitset vain URL-osoitteen.
Avaa hallintapaneelin kehittäjäalue: {{app}}/developers. Ensimmäinen välilehti, Connect an AI agent, näyttää palvelimen URL-osoitteen ja asennuskatkelman jokaiselle asiakkaalle. Kolme alla olevaa katkelmaa vastaavat siellä näytettäviä.
Aja tämä terminaalissa:
claude mcp add --transport http vocalstack {{api}}/v1/mcp
Lisää tämä projektisi tiedostoon .cursor/mcp.json, tai tiedostoon ~/.cursor/mcp.json kaikille projekteille:
{"mcpServers":{"vocalstack":{"url":"{{api}}/v1/mcp"}}}
Mikä tahansa asiakas, joka tukee Streamable HTTP:tä, voi lisätä palvelimen tällä URL-osoitteella. Tämä on yleinen muoto, jonka hallintapaneeli näyttää:
{
"vocalstack": {
"type": "streamable-http",
"url": "{{api}}/v1/mcp"
}
}
Aloittamiseen ei tarvita API-avainta. Kun asiakas yhdistää ensimmäisen kerran, kirjaudut sisään VocalStack-tililläsi selaimessa, ja asiakas tallentaa tunnuksen. Hallintapaneeli kertoo tämän yhdellä rivillä: ”Kirjaudut sisään VocalStack-tililläsi ensimmäisellä kerralla. Avainta ei tarvita.”
Tämä on MCP:n valtuutusmäärittelyn toimintaa, ei VocalStackin temppu. Etäpalvelin vastaa tunnistamattomaan pyyntöön 401-virheellä, joka osoittaa suojatun resurssin metatietoihin: pieneen JSON-dokumenttiin, joka nimeää valtuutuspalvelimen ja palvelimen vaatimat oikeusalueet (scopes). Asiakas lukee sen, suorittaa selaimessa tavallisen OAuth 2.1 -kulun ja palaa tokenilla, joka on myönnetty vain kyseiselle palvelimelle. Jokainen määritystä noudattava etä-MCP-palvelin kirjaa sinut sisään samalla tavalla, minkä vuoksi yllä olevat asiakkaat osaavat tehdä sen tietämättä mitään VocalStackista.
API-avain toimii myös, kun asiakas ajaa palvelimella tai skriptissä. Lähetä se muodossa Authorization: Bearer vs_key_..., sama otsake, jonka REST API hyväksyy. Avaimet luodaan kohdassa Developers → API keys. Kaksi litterointityökalua tarvitsevat oikeudet Write ja Stream audio. Jälkimmäinen kuulostaa oudolta tiedostolle, mutta työkalut kulkevat samaa luontipistettä kuin jokainen litterointi, myös suorat, ja piste tarkistaa molemmat. Lukutyökalut tarvitsevat Read-oikeuden; list_voices tarvitsee vain voimassa olevan tunnistetiedon.
Kun olet kirjautunut sisään, agentti näkee yhdeksän työkalua. Harva nimeää ne itse, mutta niiden tunteminen selittää, mitä agentti tekee seuraavaksi.
Jokainen työkalu ottaa ja palauttaa camelCase-JSON-muotoista dataa samoilla kenttänimillä kuin /v1-rajapinnan tietotyypit. Litteroinnin kahva on sen transcriptionId.
transcribe_url aloittaa äänen tai videon litteroinnin julkisesta URL-osoitteesta: tiedostolinkki, podcast-jakso tai YouTube-video. Suoria lähetyksiä ei hyväksytä. Valinnaiset argumentit: name, spokenLanguage (jätä pois, jolloin kieli tunnistetaan), speakerLabels (auto, on tai off) ja startS/endS, joilla litteroidaan vain osa äänestä.transcribe_file tekee saman tiedostolle, jonka agentti pitää hallussaan. Tiedosto lähetetään kentässä fileBase64 ja nimellä filename. Puretun tiedoston koko on rajattu 10 MiB:iin, mikä on noin kymmenen minuuttia 128 kbps MP3:a. Suuremmille tiedostoille anna agentille linkki.Molemmat palauttavat heti transcriptionId:n, tilan state: "queued" ja next-vihjeen, joka nimeää odotustyökalun. Agentin luomat litteroinnit alkavat yksityisinä, ilman jakolinkkiä.
Agentti ei jaksa istua suoraa lähetystä yhtään kärsivällisemmin kuin sinä. Se kutsuisi odotustyökalua, kunnes joku vie kannettavan pois. Valmiilla tallenteella on loppu, ja juuri sitä seuraava työkalupari odottaa.
Työkalukutsu on yksi HTTP-pyyntö, eikä HTTP-pyyntöjen ole tarkoitus kestää tuntia. Asiakkaat luovuttavat, välityspalvelimet katkaisevat ne, ja malli, joka on jumissa yhdessä työkalussa, ei voi tehdä mitään muuta. Siksi pitkän työn kaava MCP:n takana on sama kuin REST API:ssa: aloita työ ja saa kahva, odota sitä rajatun ajan, ja kutsu uudelleen, jos se ei ole valmis. Tila kulkee kahvan mukana, ei yhteyden.
wait_for_transcription odottaa, kunnes työ on done tai failed, tai kunnes timeoutS kuluu (oletus 50 sekuntia, enimmäismäärä 60, mikä pitää kutsun alle useimpien asiakkaiden ja välityspalvelimien aikarajojen). Jos tulos sanoo timedOut: true, työ on yhä käynnissä, ja agentti kutsuu työkalua uudelleen. Odotuksen aikana palvelin lähettää MCP:n edistymisilmoituksia, jos asiakas on niitä pyytänyt: prosentin ja vaiheen, kuten ”haetaan 3.1 / 8.0 MB” tai ”litteroidaan 01:25 / 02:00”.get_transcription palauttaa tilan ja valmistuttuaan tekstin. format: "text" antaa yhden rivin per segmentti muodossa [mm:ss] Speaker 1: .... "segments" antaa aikaleimatut rivit kentillä start, end, speaker ja speakerName. includeWords: true lisää sanojen ajoitukset. Tulokset sivutetaan (offset, limit, oletus 500 segmenttiä), ja nextOffset kertoo, kun lisää on jäljellä.Sivutus on mallia varten, ei verkkoa varten. Kaikki, minkä työkalu palauttaa, liitetään agentin kontekstiikkunaan, jossa se kilpailee keskustelusi kanssa ja maksaa tokeneita jokaisessa myöhemmässä vuorossa. Kaksituntinen kokous on kymmeniätuhansia sanoja. Jos ne palautettaisiin kerralla, kysymyksesi putoaisi kontekstista. Hyvät MCP-työkalut palauttavat sivun ja kursorin ja antavat agentin päättää, kuinka paljon se tarvitsee.
Katkos tai aikaraja ei peruuta työtä, koska työ elää palvelimella, ei MCP-pyynnössä. Kun se on valmis, se on yksi merkintä kirjastossasi, ja seuraavat työkalut käsittelevät sitä kuten mitä tahansa muuta.
list_transcriptions listaa tilin litteroinnit uusimmasta vanhimpaan tilan ja keston kanssa. lifecycle on active, archived tai all.search_transcriptions etsii sanotun kaikista litteroinneista millä tahansa kielellä ja palauttaa osuvat rivit. Jokainen rivi liittyy omaan litterointiinsa ja sekuntiin, jolloin se sanottiin. transcriptionId rajaa haun yhteen litterointiin, ja lang lisää jokaiseen osumaan käännöksen.Rivin löytäminen on helpompi puoli. Kaksi muuta työkalua selvittävät, mitä koko puhe sanoi.
get_summary palauttaa valmiin litteroinnin AI-otsikon ja yhteenvedon, tarvittaessa käännettynä lang-kentän mukaan. state: "pending" tarkoittaa, että yhteenvetoa vielä kirjoitetaan (se on yleensä valmis sekunneissa työn valmistumisen jälkeen), ja agentti kysyy uudelleen.translate_transcription palauttaa valmiin litteraatin toisella kielellä tekstinä tai ajoitettuina segmentteinä, sivutettuna kuten get_transcription. Käännökset tallennetaan, joten uudelleen kysyminen ei toista työtä.list_voices listaa äänet, jotka voivat lukea litteraatin kielellä: tunnisteen, nimen, sukupuolen ja aksentin, kun ne tunnetaan, laatuarvion sekä sen, onko ääni oletus vai yksi kloonatuista äänistäsi. Se kuvaa ääniä, mutta ei saa mitään puhumaan. Lisää siitä, mitä palvelin ei tee, alempana.Näin työkalut ketjuuntuvat käytännössä.
Kun palvelin on lisätty, keskustelu Claude Codessa etenee näin. Liität podcast-linkin ja pyydät pääkohdat ranskaksi.
Agentti kutsuu transcribe_url-työkalua:
{ "url": "https://example.org/episodes/42.mp3", "name": "Episode 42", "speakerLabels": "auto" }
Se saa takaisin transcriptionId:n ja state: "queued", ja seuraa next-vihjettä:
{ "transcriptionId": "4f1c...", "timeoutS": 50 }
Viidenkymmenen minuutin jakso litteroituu moninkertaisesti nopeammin kuin se soi, mutta ei yhdellä odotuksella. Ensimmäinen odotus palauttaa timedOut: true ja edistymisen esimerkiksi 61 prosenttia, joten agentti kutsuu työkalua vielä kerran ja saa state: "done".
Nyt agentti kutsuu get_summary-työkalua kielellä lang: "fr":
{ "transcriptionId": "4f1c...", "lang": "fr" }
Jos yhteenveto on yhä pending, agentti odottaa muutaman sekunnin. Muuten se antaa sinulle otsikon ja yhteenvedon ranskaksi. Kysy ”missä puhuttiin hinnoittelusta?”, ja agentti kutsuu search_transcriptions-työkalua arvolla query: "pricing" ja samalla transcriptionId:llä. Sitten se lainaa osuvat rivit aikaleimoineen. Pyydä koko sisältö ranskaksi, ja se kutsuu translate_transcription-työkalua.
Muutama työkalukutsu, ei koodia ja litterointi kirjastossasi. Jokainen näistä kutsuista kulki samoja portteja kuin REST-pyyntö, ja juuri nämä portit määrittävät laskun ja rajat.
MCP-palvelin on API toisen sisäänkäynnin kautta: samat rajat, sama lasku.
POST /v1/transcriptions. Paketin luontinopeus (10, 100 tai mukautettu määrä aloitettuja litterointeja tunnissa), samanaikaisten litterointien katto (1, 5 tai rajaton) ja krediitti pätevät kaikki. $5:n rekisteröitymiskrediitti riittää ensimmäiseen keskusteluun, eikä korttia tarvita.isError: true, REST API:n virhekoodin, lauseen, johon malli voi toimia, sekä kentät retryable ja retryAfterS. insufficient_credit sisältää topUpUrl:n, ja rate_limited kertoo, kuinka kauan on odotettava. Tällä on enemmän merkitystä kuin miltä kuulostaa. Malli lukee virhetekstin, joten lause, johon se voi toimia, muuttaa umpikujan seuraavaksi työkalukutsuksi./v1/mcp-pyyntöä itseään: silmukoiva agentti saa HTTP 429 -vastauksen ja Retry-After-otsakkeen ennen kuin mikään työkalu ajetaan.idempotencyKey-argumentti. Valmistuneen kutsun avaimen uudelleenkäyttö toistaa ensimmäisen tuloksen, ja avaimen käyttö eri argumenteilla hylätään. Agentti, joka yrittää uudelleen omin päin, ei siis koskaan aloita toista työtä. Jokaisen rahaa kuluttavan työkalun pitäisi tarjota tämä, sillä agentit yrittävät uudelleen paljon vapaammin kuin ihmiset.Nämä ovat palvelimen reunat. Kaksi asiaa jää niiden ulkopuolelle tarkoituksella.
Palvelimessa ei ole työkalua, joka muuttaa mielivaltaisen tekstin puheeksi, eikä sellaista ole suunniteltu. VocalStack puhuu litteraatit ja niiden käännökset valmis- tai kloonatulla äänellä, eikä mitään muuta. list_voices kertoo agentille, mitkä äänet voivat lukea litteraatin kielellä. Se ei kerro, miten saada ääni sanomaan jotain uutta.
Litterointityökalut hylkäävät myös suorat lähetykset. YouTube-suora tai radiolähetys tarvitsee suoran litteroinnin, joka käynnistetään hallintapaneelista tai kutsulla POST /v1/transcriptions/live API-viitteessä. Valmis YouTube-video on tiedosto, ja transcribe_url ottaa sen vastaan.
Jos haluat kirjoittaa koodin itse, tiedoston litterointi API:lla käy läpi samat vaiheet HTTP-kutsuina. Reaaliaikainen opas käsittelee WebSocketia.