MCP սերվերը API-ն վերածում է մի քանի անվանված գործիքների, որոնք գործակալը կանչում է զրույցի ընթացքում, իսկ երկար աշխատանքը կարող է տեղավորվել դրանց հետևում, երբ գործիքը վերադարձնում է բռնակ (handle), որին գործակալը սահմանափակ փուլերով սպասում է։ Տեղադրեք podcast-ի հղում, խնդրեք ամփոփումը ֆրանսերենով, և ոչ մի կոդ գրել պետք չի լինի։
Կոդավորման գործակալը կարող է օգտագործել VocalStack API-ն այնպես, ինչպես ցանկացած ծրագիր՝ կարդալ API տեղեկատուն, SDK-ի հետ մի քանի տող գրել և գործարկել դրանք։ Դա ճիշտ ուղին է այն դեպքի համար, որը գործակալի մասնակցությունից անկախ կաշխատի։
MCP-ն (Model Context Protocol) մյուս դեպքի համար է. դուք խոսում եք օգնականի հետ և ցանկանում եք, որ նա հենց հիմա ինչ-որ բան տառադարձի, առանց կոդի։ MCP սերվերը հրապարակում է անվանված գործիքների կարճ ցանկ, որից յուրաքանչյուրն ունի նկարագրություն և իր արգումենտների JSON սխեման։ Գործակալը ցանկը կարդում է մեկ անգամ և, երբ հարցումը համընկնում է որևէ գործիքի հետ, կանչում է այն անունով։ «Տառադարձիր այս podcast-ը և ասա, թե ինչ են ասել գնների մասին» հարցումը դառնում է երեք գործիքի կանչ, և գործակալը երբեք չի տեսնում HTTP երթուղի։
Սերվերները երկու տեսակի են։ Տեղական սերվերը գործում է որպես կլիենտի ենթապրոցես և հաղորդակցվում է stdio-ով, ինչպես աշխատում են ֆայլային համակարգի և տվյալների բազայի սերվերների մեծ մասը։ Հեռավոր սերվերը գտնվում է URL-ի հետևում և խոսում է Streamable HTTP-ով՝ տրանսպորտով, որը 2025 թվականի մարտի սպեցիֆիկացիայի վերանայմամբ փոխարինեց հին HTTP-plus-SSE (server-sent events) տրանսպորտին։ Կլիենտը ուղարկում է յուրաքանչյուր հարցում, իսկ սերվերը պատասխանում է նույն կապով. այն ամենը, ինչ նա պետք է ասի վերջնական արդյունքից առաջ, հոսքով է ուղարկվում նախ։ Ընթացիկ սպեցիֆիկացիայի համաձայն գրված ցանկացած կլիենտ կարող է օգտվել երկու տեսակներից որևէ մեկից։
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 հաշվով, և կլիենտը պահում է թոքենը։ Կառավարման վահանակն այդ մասին ասում է մեկ տողով. «Առաջին անգամ մուտք կգործեք ձեր VocalStack հաշվով։ Բանալի պետք չէ»։
Սա MCP-ի նույնականացման սպեցիֆիկացիայի աշխատանքն է, ոչ թե VocalStack-ի հնարք։ Հեռավոր սերվերը չնույնականացված հարցումին պատասխանում է 401-ով, որը ցույց է տալիս դեպի իր պաշտպանված ռեսուրսի մետատվյալները. դա JSON փաստաթուղթ է, որը նշում է նույնականացման սերվերը և սերվերի պահանջած թույլտվությունների շրջանակները (scopes)։ Կլիենտը կարդում է այն, բրաուզերում կատարում է OAuth 2.1 ստանդարտ հոսքը և վերադառնում թոքենով, որը տրված է միայն այդ սերվերի համար։ Սպեցիֆիկացիային հետևող ցանկացած հեռավոր MCP սերվեր նույն ձևով մուտք է գործում, և հենց դրա շնորհիվ վերևում նշված կլիենտները կարող են դա անել՝ առանց VocalStack-ի մասին որևէ բան իմանալու։
API բանալին նույնպես աշխատում է, սերվերի վրա կամ սկրիպտում գործող կլիենտի համար։ Ուղարկեք այն որպես Authorization: Bearer vs_key_..., նույն վերնագրով, որը ընդունում է REST API-ն։ Բանալիները ստեղծվում են Developers → API keys բաժնում։ Երկու տառադարձման գործիքներին անհրաժեշտ են Write և Stream audio թույլտվությունները։ Երկրորդը ֆայլի համար տարօրինակ է հնչում, բայց գործիքները անցնում են այն նույն կետով, որով անցնում է յուրաքանչյուր տառադարձում, ներառյալ ուղիղ տառադարձումները, և այդ կետը ստուգում է երկուսն էլ։ Ընթերցման գործիքներին պետք է Read. list_voices-ին բավարար է միայն վավեր հավատարմագրերը։
Մուտք գործելուց հետո գործակալը տեսնում է ինը գործիք։ Դուք հազվադեպ եք անունով դիմելու դրանց, բայց դրանք իմանալը բացատրում է, թե ինչ է գործակալն անում հետո։
Յուրաքանչյուր գործիք ընդունում և վերադարձնում է camelCase JSON, նույն դաշտերի անուններով, ինչ /v1 wire տիպերը. տառադարձման բռնակը դրա transcriptionId-ն է։
transcribe_url-ը սկսում է աուդիո կամ տեսանյութի տառադարձումը հանրային URL-ով՝ ֆայլի հղում, podcast-ի էպիզոդ, YouTube տեսանյութ։ Ուղիղ եթերները չեն ընդունվում։ Կամընտիր արգումենտներ՝ name, spokenLanguage (բաց թողեք, որ լեզուն որոշվի ավտոմատ), speakerLabels (auto, on կամ off) և startS/endS՝ աուդիոյի միայն մի մասը տառադարձելու համար։transcribe_file-ը անում է նույնը գործակալի ունեցած ֆայլի համար, որն ուղարկվում է fileBase64-ով և իր filename-ով։ Վերծանված չափը սահմանափակված է 10 MiB-ով, մոտավորապես տասը րոպե 128 kbps MP3՝ ավելի մեծի դեպքում տվեք գործակալին հղում։Երկուսն էլ անմիջապես վերադարձնում են transcriptionId-ը, state: "queued"-ը և next ցուցումը, որը նշում է սպասման գործիքը։ Գործակալի ստեղծած տառադարձումները սկսվում են մասնավոր, առանց կիսվելու հղման։
Գործակալը ուղիղ հեռարձակումը ավելի համբերատար չի կարող դիտել, քան դուք. նա կշարունակեր կանչել սպասման գործիքը, մինչև մեկը վերցներ նոութբուքը։ Ավարտված ձայնագրությունն ունի վերջ, և հենց դա է սպասում հաջորդ գործիքների զույգը։
Գործիքի կանչը մեկ HTTP հարցում է, իսկ HTTP հարցումները չեն նախատեսված ժամ տևելու համար։ Կլիենտները հրաժարվում են դրանցից, պրոքսիները դրանք փակում են, և մոդելը, որը արգելափակված է մեկ գործիքով, ոչինչ այլ չի կարող անել։ Ուստի MCP-ի հետևում ցանկացած երկար աշխատանքի օրինաչափությունը նույնն է, ինչ օգտագործում է REST API-ն. սկսել աշխատանքը և ստանալ բռնակ, սահմանափակ ժամանակով սպասել դրան, և եթե այն չի ավարտվել, կանչել նորից։ Վիճակը պահում է բռնակը, ոչ թե կապը։
wait_for_transcription-ը արգելափակում է մինչև աշխատանքի done կամ failed վիճակը կամ մինչև timeoutS ժամանակի անցնելը (լռելյայն 50 վայրկյան, առավելագույնը 60, ինչը կանչն ավարտում է մինչև այն ժամանակաժամկետները, որոնք կիրառում են կլիենտների և պրոքսիների մեծ մասը)։ Եթե արդյունքը ասում է timedOut: true, աշխատանքը դեռ ընթացքի մեջ է, և գործակալը կրկին կանչում է գործիքը։ Գործիքի սպասման ընթացքում սերվերը, եթե կլիենտը դա խնդրել է, ուղարկում է MCP ընթացքի ծանուցումներ՝ տոկոս և փուլ, օրինակ՝ «բեռնում 3.1 / 8.0 ՄԲ» կամ «տառադարձում 01:25՝ 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-ը թվարկում է այն ձայները, որոնք կարող են կարդալ տեքստը որևէ լեզվով՝ id, անուն, սեռ և շեշտադրում, երբ հայտնի են, որակի գնահատական, և այն, թե լռելյայն է՝ թե ձեր կլոնավորած ձայներից մեկը։ Այն նկարագրում է ձայները, բայց չի ստիպում որևէ մեկին խոսել (ավելին ստորև, թե սերվերն ինչ չի անում)։Ահա, թե ինչպես են գործիքները գործնականում շղթայվում միմյանց։
Երբ սերվերն ավելացված է, Claude Code-ում զրույցը ընթանում է այսպես։ Դուք տեղադրում եք podcast-ի հղում և խնդրում եք ֆրանսերենով ամփոփել էությունը։
Գործակալը կանչում է 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-ի ուղիղ եթերը կամ ռադիոեթերը պահանջում են ուղիղ տառադարձում, որը սկսվում է կառավարման վահանակից կամ API տեղեկատվում POST /v1/transcriptions/live-ի միջոցով։ Ավարտված YouTube տեսանյութը ֆայլ է, և transcribe_url-ը այն ընդունում է։
Եթե նախընտրում եք կոդը ինքներդ գրել, ֆայլի տառադարձումը API-ով անցնում է նույն քայլերը որպես HTTP կանչեր, իսկ իրական ժամանակի ձեռնարկը ներկայացնում է WebSocket-ը։