اس صفحہ پر
8 جون 2026 کو Anthropic نے Claude کی ڈائریکٹری میں موجود کنیکٹرز کے مالکان کو ایک ڈیش بورڈ دیا۔ یہ فعال صارفین، ٹول کالز کی کل تعداد اور ڈائریکٹری میں درجہ دکھاتا ہے۔ یہ “ایک نظر میں ہیلتھ اسکور، ایرر ریٹس اور لیٹنسی، ہر ٹول کے حساب سے ایررز کی تفصیل کے ساتھ تاکہ ٹھیک ٹھیک پتا چلے کہ کیا ناکام ہو رہا ہے” دکھاتا ہے۔
اس سے ایک سال پہلے، Weights & Biases کے Alex Volkov نے یہی مسئلہ دوسرے سرے سے بیان کیا تھا۔ جب ان کے ایجنٹ نے MCP کے ذریعے ٹولز کال کرنا شروع کیے تو “وہ ساری آبزرویبلٹی جس کا میں اپنے کوڈ کو شروع سے آخر تک چلانے کی وجہ سے عادی ہوں، تھوڑی سی تاریک ہو گئی ہے”۔ ان کے ساتھ گفتگو کرنے والے Dylibso کے Benjamin Eckel نے اس کی وجہ دکھائی۔ ریموٹ MCP سرور “ٹریس میں ہمیں ایک واحد سروس span کی طرح نظر آتا ہے” کیونکہ یہ کال کرنے والے کے کنٹرول سے باہر چلتا ہے۔
دونوں نقطۂ نظر سرور کے باہر کھڑے ہیں۔ کلائنٹ ایک مبہم span دیکھتا ہے۔ ڈائریکٹری مجموعی تعداد دیکھتی ہے۔ دونوں میں سے کسی نے یہ نہیں دیکھا کہ سرور سے کیا مانگا گیا، اس نے کیا رد کیا اور کس چیز کو چھوا۔ یہ صرف سرور نے دیکھا، اس لیے صرف سرور ہی اسے لکھ سکتا ہے۔
Tajo کے MCP سرورز یہی لکھتے ہیں، جیسا کہ انہیں چلانے والے کوڈ سے پڑھا گیا اور دستاویزات میں بیان کیا گیا ہے۔ MCP سرور کیا ہے پروٹوکول کی وضاحت کرتا ہے۔ یہ مضمون قطار کی وضاحت کرتا ہے۔
ہر کال کے لیے ایک قطار
ڈیش بورڈ ہاربر ماسٹر کا منظر ہے: کون سے جہاز آئے، کون سے گئے، کون سے دیر سے پہنچے۔ ریکویسٹ لاگ جہاز کا اپنا لاگ بک ہے، جو اسی وقت جہاز پر لکھا جاتا ہے۔
Tajo کے ورک اسپیس سرور اور ہر کنیکٹر سرور پر ہر tools/call ایک قطار پر ختم ہوتی ہے۔ قطار جواب تیار ہونے کے بعد لکھی جاتی ہے، جواب جو بھی ہو۔ جو کال اس لیے مسترد ہوئی کہ کلید کو لکھنے کی اجازت نہیں، یا اس لیے کہ اینڈ پوائنٹ صرف پڑھنے کے لیے ہے، اسے بھی کسی دوسری کال کی طرح ایک قطار ملتی ہے۔ ایسے ٹول کی کال کو بھی جو موجود ہی نہیں۔
قطار میں یہ ہوتا ہے، اور یہ وہ ہے جسے رکھنے سے وہ انکار کرتی ہے۔
| فیلڈ | رکھا جاتا ہے | نہیں رکھا جاتا |
|---|---|---|
| کون | کال کرنے والی API کلید کی آئی ڈی۔ OAuth سائن ان سے ملنے والا ٹوکن بھی ایک کلید ہے۔ | کلید کا سیکرٹ یا اس کا پری فکس۔ |
| کہاں | ورک اسپیس سرور یا کوئی کنیکٹر سرور، اس کے کنیکٹر اور پروفائل کے ساتھ۔ | |
| ٹول | نام، جب سرور کے پاس اس نام کا ٹول ہو۔ | کلائنٹ کا بھیجا ہوا کوئی بھی دوسرا نام: یہ (unknown) کے طور پر محفوظ ہوتا ہے۔ |
| اثر | read، write، send یا destructive: سب سے بھاری اثر جو کال کا ہو سکتا تھا۔ | |
| نتیجہ | ok، یا snake_case میں ایک مختصر ایرر کوڈ جیسے unknown_tool۔ | ایرر کا متن: جو کچھ کوڈ نہیں وہ tool_error کے طور پر محفوظ ہوتا ہے۔ |
| دورانیہ اور سائز | پہنچنے سے جواب تک ملی سیکنڈز، اور کال کرنے والے کو ملنے والے بائٹس۔ | |
| ٹریس آئی ڈی | ریکویسٹ کی آئی ڈی، x-request-id، x-trace-id یا W3C traceparent ہیڈر سے، ورنہ ایک نئی۔ | ہیڈر کی ایسی ویلیو جو hex یا UUID نہ ہو۔ |
| ریکارڈز | ان ریکارڈز کی 20 تک آئی ڈیز جن کا کال نے نام لیا یا جو اس نے بنائے: ایک رابطہ، ایک پیغام، ایک منظوری۔ | خود ریکارڈز۔ |
| باڈیز | آرگیومنٹس اور جواب، صاف کیے گئے، ہر ایک زیادہ سے زیادہ 4 KB۔ | سیکرٹس، آزاد متن، اور نیچے درج ذاتی ڈیٹا۔ |
ان میں سے تین انکار ڈیٹا کے بارے میں نہیں بلکہ کلائنٹ کے بارے میں ہیں۔ ٹول کا نام، ایرر کوڈ اور ٹریس آئی ڈی تینوں باہر سے آتے ہیں۔ ہر ایک صرف اسی شکل میں رکھا جاتا ہے جس کی سرور ضمانت دے سکے۔ جو لاگ کال کرنے والے کی بھیجی ہوئی ہر چیز محفوظ کر لے، اسے کسی بھی چیز سے بھرا جا سکتا ہے، یہاں تک کہ ٹول کے نام والے کالم میں کسی گاہک کے ای میل ایڈریس سے بھی۔
گفتگو کے آخر میں Benjamin Eckel کا کھلا سوال یہ تھا کہ کلیکٹر کو کیسے پتا چلے کہ “یہ ایک MCP ٹول کال ہے جس میں ایرر ہے”۔ ایک سرور پر اس کا جواب ایک کالم ہے۔ ok کی ویلیو false ہوتی ہے، اور کوڈ بتاتا ہے کہ کون سا ایرر ہے۔
آرگیومنٹس: ایک اصول جو ہم نے بدل دیا
اعتراض جائز ہے، اور یہ ہمارا اپنا ہے۔ آرگیومنٹس لاگ کریں تو آپ نے اپنے گاہکوں کے ڈیٹا کی ایک دوسری کاپی بنا لی، جو ڈیٹا حذف کرنے کی ہر درخواست کی پہنچ سے باہر ہے۔ 18 اکتوبر 2026 تک یہی ہمارا اپنا اصول تھا۔ لاگ نہ آرگیومنٹس رکھتا تھا نہ نتیجے کی باڈی، کیونکہ دونوں میں ذاتی ڈیٹا ہو سکتا ہے۔
یہ غلط سودا تھا۔ جو ریکویسٹ لاگ یہ نہ دکھا سکے کہ کیا بھیجا گیا اور کیا واپس آیا، وہ اس ایک سوال کا جواب نہیں دے سکتا جس کے لیے وہ موجود ہے: میرے ایجنٹ کی کال کیوں ناکام ہوئی؟
اس لیے باڈیز رکھی جاتی ہیں، اور جس وجہ سے انہیں نہیں رکھا جاتا تھا اس کا حل دوسرے طریقے سے کیا گیا ہے۔ ہر باڈی کیو میں ڈالے جانے سے پہلے ایک ڈیٹرمنسٹک مرحلے سے گزرتی ہے۔
- کوئی سیکرٹ باقی نہیں رہتا۔ جس فیلڈ کا نام token، password، secret، signature، cookie، session یا تقریباً بیس ملتے جلتے الفاظ میں سے کوئی ہو، وہ صرف
[secret]رکھتی ہے۔ کسی معلوم کریڈینشل کی شکل والی ویلیو کے ساتھ بھی یہی ہوتا ہے، چاہے وہ کہیں بھی ہو۔ اس میں bearer ٹوکنز، JWTs، پرائیویٹ کیز، پاس ورڈ والے URLs اور کلید کے 40 یا زیادہ حروف کا کوئی بھی مبہم سلسلہ شامل ہے۔ - نثری متن بالکل نہیں رکھا جاتا۔ جس فیلڈ کا نام
html،text،body،markdownیاcontentہو وہ صرف[redacted]رکھتی ہے۔ نثر میں نام اور گلیوں کے پتے ہوتے ہیں جنہیں کوئی پیٹرن نہیں پکڑ سکتا۔ - ذاتی ڈیٹا ہمیشہ کے لیے چھپا دیا جاتا ہے۔ جس فیلڈ کا نام ذاتی ڈیٹا کی نشاندہی کرے، جیسے ای میل، فون، نام، پتا یا نوٹ، وہ صرف
[redacted]رکھتی ہے۔ کسی بھی دوسری اسٹرنگ کے اندر ای میل ایڈریس، فون نمبر، کارڈ یا IBAN چھپا دیا جاتا ہے۔ - باڈیز چھوٹی رہتی ہیں۔ اسٹرنگز 512 حروف پر کاٹی جاتی ہیں، فہرستیں 20 آئٹمز پر، آبجیکٹس 50 کیز پر اور نیسٹنگ 6 سطحوں پر۔ پوری باڈی 4 KB پر کاٹی جاتی ہے اور اسے کٹا ہوا نشان زد کیا جاتا ہے۔
دو قسم کی کالز اس سے بھی کم رکھتی ہیں۔ وہ رابطے جو کسی شخص کی چیٹ کسی دوسری ایپ سے لائی، ایک نشان اور ایک تعداد کے طور پر لاگ ہوتے ہیں، باڈی کے طور پر کبھی نہیں۔ جو کال لاگ پڑھتی ہے وہ کوئی جواب نہیں رکھتی، کیونکہ جواب صرف لاگ کی دوسری قطاریں ہوتا۔
اب قیمت۔ چھپانا مستقل ہے، یہ ایسی انکرپشن نہیں جس کی کلید کسی کے پاس ہو۔ لاگ آپ کو وہ ای میل ایڈریس نہیں دکھا سکتا جس پر پیغام باؤنس ہوا۔ یہ آپ کو رابطے کی آئی ڈی دکھاتا ہے، اور رابطہ، اپنے اصولوں کے تحت، ایک کال کے فاصلے پر ہے۔ لاگ ورک اسپیس کے ڈیٹا مٹانے کے عمل سے باہر ہے، اسی لیے چھپانا اس عمل کا انتظار نہیں کر سکتا۔
لاگ آڈٹ ٹریل کیوں نہیں ہے
Tajo کے پاس پہلے سے ایک ایسا آڈٹ لاگ ہے جس میں صرف اضافہ کیا جا سکتا ہے۔ ہر قطار اپنے سے پہلے والی قطار کا ایک hash رکھتی ہے، اس لیے کہیں بھی ترمیم چین کو توڑ دیتی ہے۔ تو ٹول کالز وہاں کیوں نہ لکھی جائیں؟
کیونکہ چین کی ایک قیمت ہے۔ ہر اضافہ ورک اسپیس کی سطح پر ایک لاک لیتا ہے اور چین کو آگے بڑھانے کے لیے پچھلی قطار پڑھتا ہے۔ اگر ہر ریڈ اسی سے گزرے تو ورک اسپیس کی کالز ایک ہی لاک کے پیچھے قطار میں لگ جائیں گی۔ اس سے وہ اسٹیٹ تبدیلیاں بھی، جنہیں دکھانے کے لیے آڈٹ لاگ موجود ہے، ہزاروں ریڈز کے نیچے دب جائیں گی۔
اس لیے دونوں ریکارڈ سوال کے حساب سے الگ ہیں۔ ریکویسٹ لاگ بتاتا ہے کہ ایجنٹ نے کیا مانگا اور کیا ہوا، 30 دن تک۔ آڈٹ لاگ بتاتا ہے کہ کیا بدلا، اس کی اجازت کس نے دی، اور کیا تب سے کسی نے ریکارڈ میں ترمیم کی ہے۔
منظوریاں آڈٹ والی طرف ہیں۔ Tajo کے کنیکٹر پروفائلز پر، ایک propose ٹول ایک اعلان کردہ ایکشن تیار کرتا ہے اور ایک apply ٹول منظوری کے بعد اسے چلاتا ہے۔ جب تک تجویز منظور نہ ہو، کسی شخص کی طرف سے یا ورک اسپیس کے آن کیے گئے کسی اصول کے ذریعے، پرووائیڈر تک کچھ نہیں پہنچتا۔ propose کال کی قطار اپنے ریکارڈز میں اس منظوری کا نام لیتی ہے جو اس نے بنائی۔ منظوری خود بالکل اسی ان پٹ کے SHA-256 ڈائجسٹ سے بندھی ہوتی ہے۔ منظوری بالکل اسی ان پٹ کا احاطہ کرتی ہے جو آپ نے دیکھا: ایک فیلڈ بدلیں اور یہ مزید میچ نہیں کرتی۔ جب رائٹ مکمل ہوتی ہے تو اس کی آڈٹ قطار ان پٹ کا ڈائجسٹ اور پرووائیڈر کے جواب کا ڈائجسٹ رکھتی ہے، جواب کی ویلیوز کبھی نہیں۔
قطار کی قیمت کیا ہے
ایک قطار ڈیٹا بیس میں ایک رائٹ ہے، اور رائٹ کا ایک کمٹ ہوتا ہے۔ 8 اکتوبر 2026 تک ہر کال جواب سے پہلے اپنے کمٹ کا انتظار کرتی تھی، ہمارے ہوسٹ پر تقریباً 2.6 ms۔ ایک کلائنٹ کے لیے یہ ایک چھوٹی ٹول کال کا چوتھائی حصہ تھا۔
اب قطار کال ختم ہونے پر بنتی ہے اور کیو میں ڈال دی جاتی ہے۔ ایک فلش اس کیو کو زیادہ سے زیادہ 100 ms بعد لکھتا ہے، ہر ورک اسپیس کے لیے ایک ٹرانزیکشن، اس لیے بہت سی کالز ایک کمٹ میں شریک ہوتی ہیں۔ قطار کی کوئی چیز نہیں بدلتی، اس کا ٹائم اسٹیمپ بھی نہیں۔ اگر 5,000 قطاریں کیو میں انتظار کر رہی ہوں تو اگلی کال کوئی قطار گرانے کے بجائے فلش کا انتظار کرتی ہے۔
ریکارڈنگ کبھی کسی کال کو ناکام نہیں کرتی۔ جو رائٹ ناکام ہو اسے قطار بہ قطار دوبارہ آزمایا جاتا ہے، پھر لاگ کر کے گرا دیا جاتا ہے۔ پروسیس کو زبردستی ختم کرنے سے جو ضائع ہوتا ہے وہ وہی ہے جو کیو میں پڑا تھا: زیادہ سے زیادہ آخری 100 ms کی کالز۔
اسے واپس پڑھنا
logs.list ورک اسپیس کی کالز لوٹاتا ہے، سب سے نئی پہلے، باڈیز کے بغیر۔ یہ وقت، نتیجے یا HTTP اسٹیٹس، سورس (MCP یا REST API، جو یہی ٹیبل استعمال کرتا ہے) اور API کلید کے حساب سے فلٹر کرتا ہے۔ یہ بطور ڈیفالٹ ایک صفحے پر 50 دکھاتا ہے، زیادہ سے زیادہ 100۔ logs.get ایک کال لوٹاتا ہے، کلید کے موجودہ نام، اس کے اسٹیٹس، اس کے دورانیے، صاف کی گئی ریکویسٹ اور جواب، اور ان ریکارڈز کے ساتھ جنہیں اس نے چھوا۔
دونوں صرف کال کرنے والے کی ورک اسپیس پڑھتے ہیں۔ کسی دوسری ورک اسپیس کی قطار کی آئی ڈی نہیں ملتی۔
ٹول ایرر میں ریکویسٹ آئی ڈی ہوتی ہے۔ جب یہ آئی ڈی سرور نے بنائی ہو، یا یہ hex یا UUID کی شکل میں آئی ہو، تو یہی قطار کی ٹریس آئی ڈی ہے۔ جس ایجنٹ کو ایرر ملا وہ کسی شخص کو وہ ایک ویلیو دے سکتا ہے جو کال کی نشاندہی کرتی ہے۔
کیا بنا ہے، اور کیا نہیں
اس تحریر کے وقت تک جو بنا ہے:
- ورک اسپیس سرور اور ہر کنیکٹر سرور پر ہر
tools/callکے لیے ایک قطار، مسترد اور نامعلوم کالز سمیت۔ - کلید کی آئی ڈی، سرور، کنیکٹر، پروفائل، ٹول، اثر، نتیجہ، دورانیہ، نتیجے کا سائز، ٹریس آئی ڈی اور چھوئے گئے 20 تک ریکارڈز۔
- صاف کیے گئے آرگیومنٹس اور جوابات، ہر ایک زیادہ سے زیادہ 4 KB۔
logs.listاورlogs.get، ورک اسپیس تک محدود، 30 دن کے ریکارڈ کے ساتھ۔- ان پٹ ڈائجسٹ سے بندھی منظوریاں، اور hash چین والے آڈٹ لاگ میں ان پٹ اور آؤٹ پٹ ڈائجسٹ کے ساتھ درج کی گئی نافذ شدہ رائٹس۔
جو نہیں بنا، اور جس پر بھروسا کرنے سے پہلے جاننا ضروری ہے:
- کوئی ہیلتھ اسکور نہیں، ہر ٹول کا کوئی چارٹ نہیں اور بڑھتے ہوئے ایرر ریٹ پر کوئی الرٹ نہیں۔ کالز، ایررز اور سب سے سست دورانیوں کا ہر ٹول کا خلاصہ Tajo کے آپریٹرز کے لیے موجود ہے، کسی ایسی جگہ پر نہیں جسے آپ کھول سکیں۔
logs.listٹول کے نام یا ٹریس آئی ڈی کے حساب سے فلٹر نہیں کر سکتا۔ کسی ریکویسٹ آئی ڈی کے پیچھے والی قطار ڈھونڈنے کے لیے وقت اور کلید سے دائرہ تنگ کریں۔- قطاریں آپ کے اپنے چلائے ہوئے ٹریسنگ سسٹم میں ایکسپورٹ نہیں ہوتیں۔ ٹریس آئی ڈی صرف HTTP ہیڈرز سے پڑھی جاتی ہے، MCP کی اس
_metaفیلڈ سے نہیں جو گفتگو میں ٹریس کانٹیکسٹ لے جانے کے لیے استعمال ہوئی۔ - 30 دن بعد قطار حذف ہو جاتی ہے۔ کوئی آرکائیو یا ایکسپورٹ نہیں ہے۔
- جو چھپا دیا گیا وہ لاگ سے واپس حاصل نہیں کیا جا سکتا۔
- زبردستی بند کرنے سے آخری 100 ms کی قطاریں ضائع ہو سکتی ہیں۔
گفتگو اس بات پر ختم ہوئی کہ MCP میں آبزرویبلٹی “برابر تقسیم نہیں ہے”۔ آگے کا کوئی ڈیش بورڈ اسے ٹھیک نہیں کر سکتا، اور نہ ہی وہ ٹریس جو سرور کے دروازے پر رک جائے۔ ناکام ہونے والے سنک کو اپنے ریکارڈ کی ضرورت ہوتی ہے؛ اسی طرح ہر اس کال کو بھی جس نے کچھ مانگا۔
کال سرور نے دیکھی۔ کسی اور نے نہیں۔ اسے وہیں لکھیں۔
اکثر پوچھے گئے سوالات
MCP سرور کو ہر ٹول کال کے لیے کیا لاگ کرنا چاہیے؟
ہر کال کے لیے ایک قطار، جو سرور خود لکھے: کس API کلید نے کال کی، کون سا سرور اور کنیکٹر، اگر ٹول موجود ہو تو اس کا نام، اس کے اثر کی قسم، ok یا ایک مختصر ایرر کوڈ، دورانیہ، نتیجے کا سائز، ریکویسٹ کی ٹریس آئی ڈی، ان ریکارڈز کی آئی ڈیز جن کا کال نے نام لیا یا جو اس نے بنائے، اور آرگیومنٹس اور جواب جن میں سے سیکرٹس اور ذاتی ڈیٹا صاف کر دیا گیا ہو۔ Tajo کے MCP سرورز مسترد کی گئی کالز سمیت ہر tools/call کے لیے یہ قطار لکھتے ہیں اور اسے 30 دن رکھتے ہیں۔
کیا MCP ریکویسٹ لاگ کو ٹول کے آرگیومنٹس رکھنے چاہئیں؟
ہاں، صاف کر کے۔ آرگیومنٹس کے بغیر لاگ یہ نہیں بتا سکتا کہ کال کیوں ناکام ہوئی۔ Tajo نے 18 اکتوبر 2026 تک کوئی باڈی نہیں رکھی تھی اور اب ایک ڈیٹرمنسٹک مرحلے کے بعد دونوں رکھتا ہے: سیکرٹس [secret] بن جاتے ہیں، آزاد متن اور ذاتی فیلڈز [redacted] بن جاتی ہیں، ای میلز، فون، کارڈز اور IBAN چھپا دیے جاتے ہیں، اور ہر باڈی 4 KB پر کاٹ دی جاتی ہے۔ چھپانا مستقل ہے، اس لیے لاگ ریکارڈ کی نقل بنانے کے بجائے اس کی آئی ڈی سے اس کی طرف اشارہ کرتا ہے۔
MCP ٹول کال لاگ کو آڈٹ لاگ سے الگ کیوں رکھا جائے؟
کیونکہ دونوں مختلف سوالوں کے جواب مختلف قیمت پر دیتے ہیں۔ Tajo کا آڈٹ لاگ اسٹیٹ میں تبدیلیوں کی ایک hash چین ہے، اور ہر نئی قطار چین کو آگے بڑھانے کے لیے ورک اسپیس کی سطح پر ایک لاک لیتی ہے۔ اگر ہر ریڈ اسی سے گزرے تو ورک اسپیس کی کالز اس لاک کے پیچھے قطار میں لگ جائیں گی اور تبدیلیاں ریڈز کے درمیان دب جائیں گی۔ ٹول کالز ایک الگ، بغیر چین والی ٹیبل میں جاتی ہیں جو 30 دن رکھی جاتی ہے؛ کال جو رائٹس تیار کرتی ہے وہ اب بھی اپنی آڈٹ قطاریں چھوڑتی ہیں۔