MCP سرور ایک API کو چند نامزد ٹولز میں بدل دیتا ہے جنہیں ایجنٹ بات چیت کے دوران کال کرتا ہے، اور جب ٹول ایک ہینڈل واپس دے جس پر ایجنٹ محدود مرحلوں میں انتظار کرتا ہے تو طویل کام بھی اسی کے ذریعے چل سکتا ہے۔ کسی پوڈکاسٹ کا لنک چسپاں کریں، فرانسیسی میں خلاصہ مانگیں، اور کوئی کوڈ نہیں لکھنا پڑے گا۔
کوڈنگ ایجنٹ VocalStack API کو اسی طرح استعمال کر سکتا ہے جیسے کوئی بھی پروگرام کرتا ہے: API حوالہ پڑھیں، SDK کے ساتھ چند سطریں لکھیں، اور انہیں چلائیں۔ جو کام ایجنٹ کے بغیر چلے گا، اس کے لیے یہی درست راستہ ہے۔
MCP (Model Context Protocol) دوسرے معاملے کے لیے ہے: آپ کسی اسسٹنٹ سے بات کر رہے ہیں اور چاہتے ہیں کہ وہ ابھی، بغیر کوڈ کے، کچھ ٹرانسکرائب کرے۔ ایک MCP سرور ناموں والے ٹولز کی ایک مختصر فہرست شائع کرتا ہے، جن میں سے ہر ایک کے ساتھ تفصیل اور اس کے آرگیومنٹس کے لیے ایک JSON schema ہوتی ہے۔ ایجنٹ یہ فہرست ایک بار پڑھتا ہے اور جب کوئی درخواست کسی ٹول سے میل کھاتی ہے تو اسے نام سے کال کرتا ہے۔ "یہ پوڈکاسٹ ٹرانسکرائب کرو اور بتاؤ کہ انہوں نے قیمتوں کے بارے میں کیا کہا" تین ٹول کالز بن جاتا ہے، اور ایجنٹ کو کبھی HTTP روٹ نظر نہیں آتا۔
سرورز کی دو قسمیں ہیں۔ لوکل سرور کلائنٹ کا ایک subprocess بن کر stdio پر بات کرتا ہے، جیسے زیادہ تر فائل سسٹم اور ڈیٹا بیس سرورز کام کرتے ہیں۔ ریموٹ سرور ایک URL کے پیچھے ہوتا ہے اور Streamable HTTP بولتا ہے، یہ ٹرانسپورٹ مارچ 2025 کے spec ریویژن میں پرانے HTTP-plus-SSE (server-sent events) ٹرانسپورٹ کی جگہ آیا۔ کلائنٹ ہر درخواست بھیجتا ہے، اور سرور اسی کنکشن پر جواب دیتا ہے؛ حتمی نتیجے سے پہلے جو کچھ وہ کہنا چاہے، وہ اس سے پہلے سٹریم کیا جاتا ہے۔ موجودہ spec کے مطابق لکھا گیا کوئی بھی کلائنٹ دونوں میں سے کسی بھی قسم کو استعمال کر سکتا ہے۔
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 کے authorization spec کا عمل ہے، VocalStack کی کوئی چال نہیں۔ ایک ریموٹ سرور غیر تصدیق شدہ درخواست کا جواب 401 سے دیتا ہے جو اس کی protected-resource metadata کی طرف اشارہ کرتا ہے: ایک چھوٹی JSON دستاویز جو authorization server اور اس سرور کو درکار scopes کا نام دیتی ہے۔ کلائنٹ اسے پڑھتا ہے، آپ کے براؤزر میں ایک معیاری OAuth 2.1 فلو چلاتا ہے، اور اس سرور کے لیے جاری کیا گیا ٹوکن لے کر واپس آتا ہے۔ کوئی بھی ریموٹ MCP سرور جو spec پر چلتا ہے، آپ کو اسی طرح سائن اِن کرواتا ہے، اسی لیے اوپر کے کلائنٹ 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 progress notifications بھیجتا ہے: فیصد اور ایک مرحلہ، جیسے "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 ٹولز ایک صفحہ اور ایک cursor واپس کرتے ہیں اور ایجنٹ کو طے کرنے دیتے ہیں کہ اسے کتنا چاہیے۔
کنکشن ٹوٹنے یا ٹائم آؤٹ سے کام کبھی منسوخ نہیں ہوتا، کیونکہ کام سرور پر رہتا ہے، 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 کو کور کرتا ہے۔