MCP सर्व्हर एका API ला काही नावाच्या टूल्समध्ये बदलतो, जे एजंट संभाषणादरम्यान वापरतो. एखादे मोठे काम टूल एक हँडल परत देते तेव्हा अशा सर्व्हरमागे बसू शकते, ज्यावर एजंट मर्यादित वळणांमध्ये वाट पाहतो. एक पॉडकास्ट लिंक पेस्ट करा, फ्रेंचमध्ये सारांश मागा, आणि कोणताही कोड लिहावा लागत नाही.
एक कोडिंग एजंट VocalStack API कोणत्याही प्रोग्रामप्रमाणे वापरू शकतो: API संदर्भ वाचा, SDK वापरून काही ओळी लिहा, आणि त्या चालवा. जे काम एजंटशिवाय चालणार आहे, त्यासाठी हाच योग्य मार्ग आहे.
MCP (Model Context Protocol) हे दुसऱ्या प्रकरणासाठी आहे: तुम्ही एका सहाय्यकाशी बोलत आहात आणि त्याने आत्ता, कोड न लिहिता, काहीतरी ट्रान्सक्राइब करावे अशी इच्छा आहे. MCP सर्व्हर नावाच्या टूल्सची एक छोटी यादी प्रकाशित करतो, प्रत्येकासह वर्णन आणि त्याच्या आर्ग्युमेंट्ससाठी JSON स्कीमा. एजंट यादी एकदा वाचतो आणि विनंती जुळली की टूलला नावाने कॉल करतो. "हा पॉडकास्ट ट्रान्सक्राइब करा आणि त्यांनी किमतींबद्दल काय सांगितले ते सांगा" ही तीन टूल कॉल्स बनतात, आणि एजंटला HTTP राउट कधीच दिसत नाही.
सर्व्हर दोन प्रकारचे असतात. लोकल सर्व्हर क्लायंटचा सबप्रोसेस म्हणून चालतो आणि stdio वर बोलतो; बहुतेक फाइल-सिस्टम आणि डेटाबेस सर्व्हर असेच काम करतात. रिमोट सर्व्हर एका URL मागे असतो आणि Streamable HTTP वापरतो, जो मार्च 2025 च्या स्पेक आवृत्तीत जुन्या HTTP-plus-SSE (server-sent events) ट्रान्सपोर्टची जागा घेतला. क्लायंट प्रत्येक विनंती पोस्ट करतो, आणि सर्व्हर त्याच कनेक्शनवर उत्तर देतो; अंतिम निकालाआधी सांगायच्या गोष्टी त्याआधीच स्ट्रीम केल्या जातात. सध्याच्या स्पेकनुसार लिहिलेला कोणताही क्लायंट यापैकी कोणताही प्रकार वापरू शकतो.
VocalStack चा सर्व्हर रिमोट प्रकारचा आहे, {{api}}/v1/mcp येथे, आणि तो वापरण्याचा खर्च API इतकाच आहे. तुम्हाला फक्त URL लागेल.
{{app}}/developers येथील डॅशबोर्डच्या 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."
हे VocalStack ची युक्ती नसून MCP च्या authorization स्पेकचे काम आहे. रिमोट सर्व्हर अनधिकृत विनंतीला 401 देऊन उत्तर देतो, जो त्याच्या protected-resource metadata कडे निर्देश करतो: एक छोटा JSON दस्तऐवज जो authorization server आणि सर्व्हरला हव्या असलेल्या 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 वायर प्रकारांप्रमाणेच फील्ड नावांसह; ट्रान्सक्रिप्शनचा हँडल त्याचा transcriptionId आहे.
transcribe_url सार्वजनिक URL वरील ऑडिओ किंवा व्हिडिओ ट्रान्सक्राइब करण्यास सुरुवात करतो: फाइल लिंक, पॉडकास्ट भाग, 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 प्रगती सूचना पाठवतो: टक्केवारी आणि "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 एखाद्या भाषेत ट्रान्सक्रिप्ट वाचू शकणारे आवाज यादी करतो: id, नाव, लिंग आणि उच्चार (माहीत असल्यास), गुणवत्ता रेटिंग, आणि तो डीफॉल्ट आहे की तुमचा क्लोन केलेला आवाज. तो आवाजांचे वर्णन करतो; कोणाला काहीही बोलायला लावत नाही (खाली सर्व्हर काय करत नाही ते पहा).टूल्स व्यवहारात कसे साखळीत जातात ते येथे आहे.
सर्व्हर जोडल्यावर 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" मिळवतो.
आता एजंट lang: "fr" सह get_summary कॉल करतो:
{ "transcriptionId": "4f1c...", "lang": "fr" }
सारांश अजून pending असल्यास एजंट काही सेकंद थांबतो; नाहीतर तो तुम्हाला फ्रेंचमध्ये शीर्षक आणि सारांश देतो. "किंमतींबद्दल कुठे बोलले?" असे विचारलात, तर तो query: "pricing" आणि तोच transcriptionId देऊन search_transcriptions कॉल करतो, आणि जुळणाऱ्या ओळी त्यांच्या टाइमस्टॅम्पसह उद्धृत करतो. संपूर्ण गोष्ट फ्रेंचमध्ये मागितलीत, तर तो 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 विनंतीलाही लागू होते: लूप करणारा एजंट कोणतेही टूल चालण्यापूर्वी Retry-After सह HTTP 429 मिळवतो.idempotencyKey घेतात: पूर्ण झालेल्या कॉलची की पुन्हा वापरल्यास पहिला निकाल पुन्हा दाखवला जातो, आणि वेगळ्या आर्ग्युमेंट्ससह ती पुन्हा वापरल्यास नाकारले जाते, त्यामुळे स्वतःहून पुन्हा प्रयत्न करणारा एजंट दुसरे काम कधीच सुरू करत नाही. पैसे खर्च करणाऱ्या कोणत्याही टूलने हे द्यावे; एजंट लोकांपेक्षा खूप मोकळेपणाने पुन्हा प्रयत्न करतात.सर्व्हर काय करतो त्या या कडा आहेत. यापैकी दोन गोष्टी हेतुपुरस्सर त्याबाहेर आहेत.
सर्व्हरमध्ये मजकुराचे भाषण बनवणारे कोणतेही टूल नाही, आणि नियोजितही नाही. VocalStack ट्रान्सक्रिप्ट्स आणि त्यांची भाषांतरे, तयार किंवा क्लोन केलेल्या आवाजात बोलते, आणि त्यापलीकडे काहीही नाही. list_voices एजंटला सांगतो की कोणते आवाज एखाद्या भाषेतील ट्रान्सक्रिप्ट वाचू शकतात, एखाद्या आवाजाला नवीन काही बोलायला कसे लावायचे नाही.
ट्रान्सक्राइब टूल्स लाइव्ह स्ट्रीम्सही नाकारतात. YouTube लाइव्ह स्ट्रीम किंवा रेडिओ स्ट्रीमला लाइव्ह ट्रान्सक्रिप्शन हवे, जे डॅशबोर्डवरून किंवा API संदर्भ मधील POST /v1/transcriptions/live द्वारे सुरू केले जाते. संपलेला YouTube व्हिडिओ ही फाइल असते, आणि transcribe_url ती घेतो.
स्वतः कोड लिहायचा असेल, तर API सह फाइल ट्रान्सक्राइब करणे तीच पायरी HTTP कॉल्स म्हणून सांगते, आणि रिअल-टाइम ट्युटोरियल WebSocket समजावते.