Az MCP-szerver néhány elnevezett eszközzé alakít egy API-t, amelyeket az ügynök a beszélgetés közben hív meg, a hosszú feladat pedig úgy illeszthető mögé, hogy az eszköz egy azonosítót ad vissza, amelyre az ügynök korlátos számú körben vár. Illessz be egy podcast-linket, kérd a lényeget franciául, és nem kell kódot írni.
A kódoló ügynök ugyanúgy használhatja a VocalStack API-t, mint bármely program: elolvassa az API-referenciát, néhány sort ír az SDK-ra, majd lefuttatja. Ez az út olyan feladathoz való, amely az ügynök nélkül fog futni.
Az MCP (Model Context Protocol) a másik esetre való: egy asszisztenssel beszélgetsz, és azt szeretnéd, hogy most, kód nélkül írjon át valamit. Az MCP-szerver rövid listát tesz közzé elnevezett eszközökről, mindegyikhez leírással és az argumentumaihoz tartozó JSON-sémával. Az ügynök egyszer beolvassa a listát, és amikor egy kérés illeszkedik valamelyik eszközre, annak nevével hívja meg. A „Írd át ezt a podcastet, és mondd el, mit mondtak az árakról” kérésből három eszközhívás lesz, és az ügynök soha nem látja a HTTP-útvonalat.
A szervereknek két fajtája van. A helyi szerver a kliens alfolyamataként fut, és stdio-n keresztül kommunikál, ahogy a legtöbb fájlrendszer- és adatbázis-szerver működik. A távoli szerver egy URL mögött áll, és Streamable HTTP-n beszél: ez az átvitel váltotta fel a régebbi HTTP-plus-SSE (server-sent events, szerver által küldött események) átvitelt a specifikáció 2025 márciusi revíziójában. A kliens minden kérést elküld, a szerver ugyanazon a kapcsolaton válaszol, és minden, amit a végső eredmény előtt mondani akar, a válasz elé van streamelve. A jelenlegi specifikáció szerint írt bármely kliens mindkét fajtát tudja használni.
A VocalStack szervere a távoli fajta, a {{api}}/v1/mcp címen, és használata annyiba kerül, mint az API. Csak az URL kell hozzá.
Nyisd meg a Dashboard Developers területét: {{app}}/developers. Az első fül, a Connect an AI agent, megmutatja a szerver URL-jét, és minden klienshez egy beállítórészletet. Az alábbi három részlet megegyezik az ott látható részletekkel.
Futtasd ezt a terminálban:
claude mcp add --transport http vocalstack {{api}}/v1/mcp
Ezt add hozzá a projekt .cursor/mcp.json fájljához, vagy minden projekthez a ~/.cursor/mcp.json fájlhoz:
{"mcpServers":{"vocalstack":{"url":"{{api}}/v1/mcp"}}}
Bármely Streamable HTTP-t támogató kliens hozzáadhatja a szervert ezzel az URL-lel. Ez az általános forma, amelyet a Dashboard mutat:
{
"vocalstack": {
"type": "streamable-http",
"url": "{{api}}/v1/mcp"
}
}
Az induláshoz nincs szükséged API-kulcsra. Amikor a kliens először csatlakozik, a böngészőben bejelentkezel a VocalStack-fiókoddal, a kliens pedig megtartja a tokent. A Dashboard egy sorban foglalja össze: "You'll sign in with your VocalStack account the first time. No key needed."
Ez az MCP hitelesítési specifikációjának működése, nem valami VocalStack-trükk. A távoli szerver a hitelesítés nélküli kérésre 401-es válasszal felel, amely a védett erőforrás metaadataira mutat: ez egy kis JSON-dokumentum, amely megnevezi a hitelesítési szervert és a szerver által megkövetelt hatóköröket. A kliens beolvassa, a böngészőben lefuttat egy szabványos OAuth 2.1 folyamatot, és egyetlen szerverre kiállított tokennel tér vissza. Bármely, a specifikációt követő távoli MCP-szerver ugyanígy jelentkeztet be, ezért a fenti kliensek a VocalStackről mit sem tudva is képesek erre.
Egy API-kulcs is működik, olyan kliensnél, amely szerveren vagy szkriptben fut. Küldd Authorization: Bearer vs_key_... formában, ugyanazzal a fejléccel, amelyet a REST API is elfogad. A kulcsokat a Developers → API keys alatt hozod létre. A két átíró eszköz a Write és a Stream audio jogosultságot igényli. A második furcsán hangzik egy fájlnál, de az eszközök ugyanazon a létrehozási ponton haladnak át, mint minden átírás, az élők is, és ez a pont mindkettőt ellenőrzi. Az olvasó eszközök a Read jogosultságot igénylik; a list_voices csak érvényes hitelesítő adatot kér.
Miután bejelentkeztél, az ügynök kilenc eszközt lát. Ritkán fogod őket név szerint megnevezni, de ha ismered őket, megérted, mit tesz az ügynök a következő lépésben.
Minden eszköz camelCase JSON-t fogad és ad vissza, ugyanazokkal a mezőnevekkel, mint a /v1 wire-típusok; egy átírás fogódzója a transcriptionId.
transcribe_url hangot vagy videót ír át nyilvános URL-en: fájllinken, podcastepizódon, YouTube-videón. Élő adatfolyamokat nem fogad el. Opcionális argumentumok: name, spokenLanguage (ha kihagyod, a nyelvet felismeri), speakerLabels (auto, on vagy off), valamint startS/endS, hogy csak a hang egy részét írja át.transcribe_file ugyanezt teszi az ügynök birtokában lévő fájllal, amelyet fileBase64 mezőben, a filename-mel együtt küld. A dekódolt méret 10 MiB-ra van korlátozva, ez nagyjából tíz perc 128 kbps-es MP3; ennél nagyobbhoz adj az ügynöknek egy linket.Mindkettő azonnal visszatér a transcriptionId-val, a state: "queued" értékkel és egy next tippel, amely a várakozó eszközt nevezi meg. Az ügynök által létrehozott átírások privátként indulnak, megosztási link nélkül.
Egy élő közvetítést az ügynök sem tud türelmesebben végigülni, mint te: addig hívná a várakozó eszközt, amíg valaki el nem veszi tőle a laptopot. Egy kész felvételnek van vége, és a következő két eszköz erre vár.
Egy eszközhívás egy HTTP-kérés, a HTTP-kéréseknek pedig nem az a dolguk, hogy egy óráig tartsanak. A kliensek feladják őket, a proxyk lezárják, és egy modell, amely egy eszközhívásra vár, mást nem tud csinálni. Ezért bármely MCP mögötti hosszú feladat mintája ugyanaz, mint a REST API-é: elindítod a feladatot, kapsz egy fogódzót, korlátos ideig várakozol rá, és ha nincs kész, újra hívod. Az állapotot a fogódzó hordozza, nem a kapcsolat.
wait_for_transcription addig blokkol, amíg a feladat done vagy failed nem lesz, vagy le nem telik a timeoutS (alapértelmezés 50 másodperc, maximum 60, ez a legtöbb kliens és proxy időkorlátja alatt marad). Ha az eredmény timedOut: true, a feladat még fut, és az ügynök újra hívja az eszközt. Miközben az eszköz vár, a szerver MCP-haladásértesítéseket küld, ha a kliens kérte: százalékot és fázist, például "fetching 3.1 / 8.0 MB" vagy "transcribing 01:25 of 02:00".get_transcription visszaadja az állapotot, kész állapotban pedig a szöveget. A format: "text" szegmensenként egy sort ad [mm:ss] Speaker 1: ... formában; a "segments" időzített sorokat ad a start, end, speaker és speakerName mezőkkel; az includeWords: true szavankénti időzítéseket is hozzáad. Az eredmények lapozhatók (offset, limit, alapértelmezés 500 szegmens), és nextOffset jelzi, ha van még.A lapozás a modellnek szól, nem a hálózatnak. Minden, amit egy eszköz visszaad, bekerül az ügynök kontextusablakába, ahol versenyez a beszélgetéseddel, és minden későbbi körben tokenekbe kerül. Egy kétórás megbeszélés tízezernyi szó; ha mindent egyszerre adna vissza, a kérdésed kiszorulna a kontextusból. A jó MCP-eszközök egy oldalt és egy kurzort adnak vissza, és az ügynökre bízzák, mennyire van szüksége.
A kapcsolat megszakadása vagy időtúllépés soha nem szakítja meg a feladatot, mert a feladat a szerveren fut, nem az MCP-kérésben. Ha kész, a feladat egy újabb bejegyzés a könyvtáradban, a következő eszközök pedig úgy kezelik, mint bármely másikat.
list_transcriptions listázza a fiók átírásait, a legújabbal kezdve, állapottal és hosszúsággal; a lifecycle értéke active, archived vagy all.search_transcriptions minden átírásban keres, bármely nyelven, és a találatoknak megfelelő sorokat adja vissza, mindegyiket az átírásával és azzal a másodperccel, amikor elhangzott. A transcriptionId egy átírásra szűkíti a keresést; a lang minden találathoz fordítást ad.A sor megtalálása a könnyebbik fele. Két további eszköz állapítja meg, mit mondott összesen az egész.
get_summary egy kész átírás MI-címét és összefoglalóját adja vissza, opcionálisan lang paraméterrel lefordítva. A state: "pending" azt jelenti, hogy az összefoglaló még íródik (a feladat befejezése után általában másodpercekben kész), és az ügynök újra kérdez.translate_transcription egy kész átiratot ad vissza más nyelven, szövegként vagy időzített szegmensekként, lapozva, mint a get_transcription. A fordítások tárolódnak, így ha újra kéred, nem végzi el újra a munkát.list_voices felsorolja azokat a hangokat, amelyek egy nyelven fel tudnak olvasni átiratot: azonosító, név, nem és akcentus, ha ismert, minőségi besorolás, valamint hogy alapértelmezettek-e, vagy a saját klónozott hangjaid egyike. Hangokat ír le; nem szólaltat meg egyet sem (lásd lentebb, mit nem tesz a szerver).Íme, hogyan láncolódnak az eszközök a gyakorlatban.
Miután a szerver hozzá van adva, a Claude Code-beli beszélgetés így zajlik. Beilleszted egy podcast linkjét, és franciául kéred a lényeget.
Az ügynök meghívja a transcribe_url-t:
{ "url": "https://example.org/episodes/42.mp3", "name": "Episode 42", "speakerLabels": "auto" }
Visszakap egy transcriptionId-t és state: "queued" értéket, és követi a next tippet:
{ "transcriptionId": "4f1c...", "timeoutS": 50 }
Egy ötvenperces epizód sokszor gyorsabban íródik át, mint ahogy lejátszódik, de egyetlen várakozáson belül nem. Az első várakozás timedOut: true válasszal tér vissza, mondjuk 61 százalékos haladással, így az ügynök még egyszer meghívja az eszközt, és state: "done" értéket kap.
Most az ügynök meghívja a get_summary-t lang: "fr" paraméterrel:
{ "transcriptionId": "4f1c...", "lang": "fr" }
Ha az összefoglaló még pending, az ügynök néhány másodpercet vár; különben franciául ad egy címet és összefoglalót. Ha megkérdezed: "hol beszéltek az árakról?", meghívja a search_transcriptions-t a query: "pricing" paraméterrel és ugyanazzal a transcriptionId-val, és idézi a megfelelő sorokat az időbélyegükkel. Ha az egészet franciául kéred, meghívja a translate_transcription-t.
Néhány eszközhívás, kód nélkül, és egy átírás a könyvtáradban. Mindegyik hívás ugyanazokon a kapukon ment át, mint egy REST-kérés, és ezek a kapuk állapítják meg a számlát és a korlátokat.
Az MCP-szerver az API másik bejáratán keresztül érhető el: ugyanazok a korlátok, ugyanaz a számla.
POST /v1/transcriptions: érvényes a csomag létrehozási sebessége (óránként 10, 100 vagy egyedi szám indított átírás), az egyidejű átírások felső határa (1, 5 vagy korlátlan), valamint a kredit. Az $5-ös regisztrációs kredit fedezi az első munkamenetet, kártya nélkül.isError: true jelzést ad a REST API hibakódjával, egy mondattal, amelyből a modell tud dolgozni, valamint retryable és retryAfterS mezőkkel. Az insufficient_credit egy topUpUrl-t hordoz; a rate_limited megmondja, mennyit kell várni. Ez többet számít, mint hangzik: a modell a hibaszöveget olvassa, és egy olyan mondat, amellyel tud mit kezdeni, a zsákutcából a következő eszközhívást csinálja./v1/mcp kérésre is vonatkozik: a hurkoló ügynök HTTP 429 választ kap Retry-After fejléccel, mielőtt bármely eszköz lefutna.idempotencyKey-t fogad: egy befejezett hívás kulcsának újrahasználata az első eredményt adja vissza, a kulcs más argumentumokkal való újrahasználatát pedig elutasítják, így az önállóan újrapróbálkozó ügynök nem indít második feladatot. Minden pénzt költő eszköznek ezt kellene felajánlania; az ügynökök sokkal szabadabban próbálkoznak újra, mint az emberek.Ezek a szerver határai. Két dolog szándékosan kívül esik rajtuk.
A szervernek nincs olyan eszköze, amely tetszőleges szöveget beszéddé alakít, és nem is tervezett. A VocalStack átiratokat és azok fordításait olvassa fel, beépített vagy klónozott hangon, és mást nem. A list_voices azt mondja meg az ügynöknek, mely hangok tudnak átiratot felolvasni egy nyelven, nem azt, hogyan szólaltasson meg egy új mondatot.
Az átíró eszközök az élő adatfolyamokat is elutasítják. Egy YouTube-os élő adás vagy egy rádióadás élő átírást igényel, amelyet a Dashboardról vagy a POST /v1/transcriptions/live végponton indítasz, az API-referenciában. Egy befejezett YouTube-videó fájl, és azt a transcribe_url fogadja el.
Ha inkább magad szeretnéd megírni a kódot, a fájl átírása az API-val ugyanazokat a lépéseket mutatja be HTTP-hívásokként, a valós idejű oktatóanyag pedig a WebSocketet tárgyalja.