MCP сървърът превръща API в няколко именувани инструмента, които агентът извиква по време на разговор, а дълга задача се побира зад тях, когато инструментът върне идентификатор, който агентът чака на ограничени по време ходове. Поставете линк към подкаст, поискайте обобщението на френски и не се пише нито ред код.
Програмен агент може да използва VocalStack API както всяка програма: да прочете API справката, да напише няколко реда със SDK и да ги изпълни. Това е правилният път за нещо, което ще работи и без агента.
MCP (Model Context Protocol) е за другия случай: разговаряте с асистент и искате той да транскрибира нещо веднага, без код. MCP сървърът публикува кратък списък с именувани инструменти, всеки с описание и JSON схема за аргументите си. Агентът прочита списъка веднъж и извиква инструмент по име, когато една заявка съвпадне с него. „Транскрибирай този подкаст и ми кажи какво са казали за цените“ се превръща в три извиквания на инструменти, а агентът изобщо не вижда HTTP маршрут.
Сървърите са два вида. Локалният сървър работи като подпроцес на клиента и комуникира през stdio, което е начинът, по който работят повечето сървъри за файлова система и бази данни. Отдалеченият сървър се намира зад URL адрес и говори Streamable HTTP – транспорта, който замени по-стария HTTP-plus-SSE (server-sent events) транспорт в мартовата 2025 ревизия на спецификацията. Клиентът изпраща всяка заявка, а сървърът отговаря в същата връзка; всичко, което трябва да каже преди крайния резултат, се изпраща предварително като поток. Всеки клиент, написан според актуалната спецификация, може да използва и двата вида.
Сървърът на VocalStack е от отдалечения вид, на адрес {{api}}/v1/mcp, и използването му струва колкото струва API-то. Трябва ви само URL адресът.
Отворете секцията Developers на таблото в {{app}}/developers. Първият таб, Connect an AI agent, показва URL адреса на сървъра и фрагмент за настройка за всеки клиент. Трите фрагмента по-долу съвпадат с показаните там.
Изпълнете това в терминала:
claude mcp add --transport http vocalstack {{api}}/v1/mcp
Добавете това в .cursor/mcp.json във вашия проект или в ~/.cursor/mcp.json за всеки проект:
{"mcpServers":{"vocalstack":{"url":"{{api}}/v1/mcp"}}}
Всеки клиент, който поддържа Streamable HTTP, може да добави сървъра с този URL адрес. Това е общата форма, която показва таблото:
{
"vocalstack": {
"type": "streamable-http",
"url": "{{api}}/v1/mcp"
}
}
За начало не ви е нужен API ключ. При първото свързване на клиента влизате в акаунта си във VocalStack през браузъра, а клиентът запазва токена. Таблото го казва с един ред на английски: "You'll sign in with your VocalStack account the first time. No key needed."
Това е работа на спецификацията за упълномощаване на MCP, а не трик на VocalStack. Отдалеченият сървър отговаря на неупълномощена заявка с 401, която сочи към метаданните на защитения ресурс: малък JSON документ, който посочва сървъра за упълномощаване и скоповете, които сървърът изисква. Клиентът го прочита, изпълнява стандартен OAuth 2.1 поток в браузъра ви и се връща с токен, издаден само за този сървър. Всеки отдалечен MCP сървър, който следва спецификацията, ви впуска по същия начин, затова горните клиенти могат да го направят, без да знаят нищо за VocalStack.
API ключ също работи – за клиент, който работи на сървър или в скрипт. Изпращайте го като Authorization: Bearer vs_key_..., същия хедър, който приема REST API-то. Ключовете се създават в Developers → API keys. Двата инструмента за транскрибиране изискват разрешенията Write и Stream audio. Вторият звучи странно за файл, но инструментите минават през същата точка на създаване като всяка транскрипция, включително на живо, а тази точка проверява и двете. Инструментите за четене изискват Read; list_voices изисква само валидни удостоверителни данни.
Щом влезете, агентът вижда девет инструмента. Рядко ще ги назовавате сами, но ако ги познавате, е ясно какво прави агентът след това.
Всеки инструмент приема и връща camelCase JSON със същите имена на полетата като типовете /v1; идентификаторът на транскрипцията е нейният transcriptionId.
transcribe_url стартира транскрибиране на аудио или видео на публичен URL адрес: линк към файл, подкаст епизод, YouTube видео. Живите потоци не се приемат. Незадължителни аргументи: name, spokenLanguage (пропуснете го, за да се определи езикът автоматично), speakerLabels (auto, on или off) и startS/endS, за да транскрибирате само част от аудиото.transcribe_file прави същото за файл, който агентът държи, изпратен като fileBase64 с filename. Декодираният размер е ограничен до 10 MiB, приблизително десет минути MP3 с 128 kbps; за по-голямо ще дадете на агента линк.И двата връщат веднага transcriptionId, state: "queued" и подсказка next, която назовава инструмента за изчакване. Транскрипциите, създадени от агента, започват като частни, без линк за споделяне.
Агентът не може да изтърпи излъчване на живо по-търпеливо от вас; би извиквал инструмента за изчакване, докато някой не му вземе лаптопа. Завършилият запис има край и точно него чака следващата двойка инструменти.
Извикването на инструмент е една HTTP заявка, а HTTP заявките не са предназначени да траят час. Клиентите ги прекъсват, прокситата ги затварят, а модел, блокиран в една инструмент заявка, не може да прави нищо друго. Затова схемата за всяка дълга задача зад MCP е същата, която използва и REST API-то: стартирате задачата и получавате идентификатор, изчаквате я за ограничено време и извиквате отново, ако не е готова. Състоянието се пази в идентификатора, не във връзката.
wait_for_transcription блокира, докато задачата стане done или failed, или докато мине timeoutS (по подразбиране 50 секунди, максимум 60, което държи извикването под времевите ограничения, които прилагат повечето клиенти и проксита). Ако резултатът казва timedOut: true, задачата все още работи и агентът извиква инструмента отново. Докато инструментът чака, сървърът изпраща MCP известия за напредък, ако клиентът ги е поискал: процент и фаза, например „fetching 3.1 / 8.0 MB“ или „transcribing 01:25 of 02:00“.get_transcription връща статуса и, след като е готова, текста. format: "text" дава по един ред на сегмент като [mm:ss] Speaker 1: ...; "segments" дава времеви редове с start, end, speaker и speakerName; includeWords: true добавя времената на думите. Резултатите се странират (offset, limit, по подразбиране 500 сегмента) с nextOffset, когато остават още.Страницирането е за модела, не за мрежата. Всичко, което инструмент връща, се залепва в контекстния прозорец на агента, където се конкурира с разговора ви и струва токени при всеки следващ ход. Двучасова среща са десетки хиляди думи; връщането им наведнъж би изтласкало въпроса ви извън контекста. Добрите MCP инструменти връщат страница и курсор и оставят агента сам да реши колко му трябва.
Прекъсване или времево изтичане никога не отменя задачата, защото задачата живее на сървъра, а не в MCP заявката. Когато е готова, тя е още един запис в библиотеката ви, а следващите инструменти я третират като всеки друг.
list_transcriptions изброява транскрипциите на акаунта, най-новите първи, със статус и продължителност; lifecycle е active, archived или all.search_transcriptions търси какво е било казано във всички транскрипции, на всеки език, и връща съвпадащите редове, всеки с транскрипцията си и секундата, в която е бил казан. transcriptionId ограничава търсенето до една транскрипция; lang добавя превод на всяко съвпадение.Намирането на ред е лесната половина. Още два инструмента разбират какво е казано в цялото.
get_summary връща AI заглавието и обобщението на завършена транскрипция, по избор преведени с lang. state: "pending" означава, че обобщението още се пише (обикновено е готово в рамките на секунди след завършването на задачата), и агентът пита отново.translate_transcription връща завършен транскрипт на друг език, като текст или времеви сегменти, страницирани както при get_transcription. Преводите се пазят, така че повторното питане не повтаря работата.list_voices изброява гласовете, които могат да прочетат транскрипт на даден език: идентификатор, име, пол и акцент, когато са известни, оценка на качеството и дали е стандартният или един от вашите клонирани гласове. Той описва гласове; не кара никой да говори (повече за това по-долу, при това, което сървърът не прави).Ето как инструментите се свързват на практика.
След като добавите сървъра, разговорът в Claude Code протича така. Поставяте линк към подкаст и искате обобщението му на френски.
Агентът извиква transcribe_url:
{ "url": "https://example.org/episodes/42.mp3", "name": "Episode 42", "speakerLabels": "auto" }
Получава transcriptionId и state: "queued" и следва подсказката next:
{ "transcriptionId": "4f1c...", "timeoutS": 50 }
Петдесетминутен епизод се транскрибира много пъти по-бързо, отколкото се пуска, но не в рамките на едно изчакване. Първото изчакване връща timedOut: true с напредък от, да речем, 61 процента, затова агентът извиква инструмента още веднъж и получава state: "done".
Сега агентът извиква get_summary с lang: "fr":
{ "transcriptionId": "4f1c...", "lang": "fr" }
Ако обобщението още е pending, агентът изчаква няколко секунди; иначе ви връща заглавие и обобщение на френски. Ако попитате „къде говориха за цените?“, той извиква search_transcriptions с query: "pricing" и същия transcriptionId и цитира съвпадащите редове с техните времеви маркери. Ако поискате целия текст на френски, той извиква translate_transcription.
Няколко извиквания на инструменти, без код, и транскрипция в библиотеката ви. Всяко от тези извиквания е минало през същите врати като REST заявка, а именно тези врати определят сметката и лимитите.
MCP сървърът е API-то през друга входна врата: същите лимити, същата сметка.
POST /v1/transcriptions: прилагат се скоростта на създаване на плана (10, 100 или друго зададено число транскрипции, започнати на час), ограничението за едновременни транскрипции (1, 5 или без ограничение) и кредитът му. Кредитът от $5 при регистрация покрива първа сесия, без да се изисква карта.isError: true с кода на грешката от REST API-то, изречение, с което моделът може да работи, и полетата retryable и retryAfterS. insufficient_credit носи topUpUrl; rate_limited казва колко време да се чака. Това е по-важно, отколкото звучи: моделът чете текста на грешката, така че изречение, с което може да действа, превръща задънена улица в следващо извикване на инструмент./v1/mcp: зациклил агент получава HTTP 429 с Retry-After, преди да се е изпълнил някой инструмент.idempotencyKey: повторното използване на ключа на завършено извикване връща първия резултат, а повторно използване с различни аргументи се отхвърля, така че агент, който опитва сам отново, никога не стартира втора задача. Всеки инструмент, който харчи пари, трябва да предлага това; агентите опитват отново много по-свободно от хората.Това са границите на сървъра. Две неща съзнателно лежат извън тях.
Сървърът няма инструмент, който превръща произволен текст в реч, и такъв не е планиран. VocalStack озвучава транскрипти и техните преводи, със стандартен или клониран глас, и нищо друго. list_voices казва на агента кои гласове могат да прочетат транскрипт на даден език, а не как да накара глас да каже нещо ново.
Инструментите за транскрибиране също отхвърлят живите потоци. Потокът на YouTube на живо или радиопотокът изисква транскрибиране на живо, стартирано от таблото или чрез POST /v1/transcriptions/live в API справката. Завършено YouTube видео е файл и transcribe_url го приема.
Ако предпочитате сами да напишете кода, транскрибиране на файл с API показва същите стъпки като HTTP заявки, а урокът за реално време разглежда WebSocket.