اگر آپ نے برسوں PHP ایپلی کیشنز کے اندر بزنس لاجک (business logic) کو برقرار رکھنے میں گزارے ہیں، تو Model Context Protocol کے ٹیوٹوریلز دیکھنا ایک بند دروازے کے باہر کھڑے ہونے کے مترادف محسوس ہو سکتا ہے۔ تقریباً ہر گائیڈ TypeScript یا Python کو فرض کر لیتی ہے۔ وہ آفیشل SDKs، npm انسٹالیشنز اور pip پیکیجز کے بارے میں بتاتی ہیں۔ اس کا نتیجہ یہ نکلتا ہے کہ بہت بڑی مقدار میں بزنس ڈیٹا—کسٹمر ریکارڈز، آرڈر ہسٹری، انوینٹری سسٹم—ایسے PHP کوڈ بیسز میں پڑا رہتا ہے جو AI ٹولنگ کی موجودہ لہر کے لیے ناقابلِ نظر نظر آتے ہیں۔

اچھی خبر یہ ہے کہ MCP کے لیے ان SDKs کی ضرورت نہیں ہے۔ MCP کوئی لائبریری نہیں ہے۔ یہ ایک وائر پروٹوکول (wire protocol) ہے۔ اگر آپ کا رن ٹائم (runtime) standard input سے ٹیکسٹ کی ایک لائن پڑھ سکتا ہے، JSON کو پارس (parse) کر سکتا ہے، اور واپس JSON لکھ سکتا ہے، تو وہ اس پروٹوکول کو سمجھ سکتا ہے۔ PHP تو LLMs کے وجود میں آنے سے بہت پہلے سے بالکل یہی کام کر رہا ہے۔

MCP اصل میں کیا ہے

MCP کا مطلب Model Context Protocol ہے۔ بنیادی طور پر، یہ AI اسسٹنٹس کو ڈیٹا، ٹولز اور بیرونی APIs سے جوڑنے کے لیے ایک اوپن اسٹینڈرڈ ہے۔ ہر اسسٹنٹ یا ماڈل کے لیے الگ سے کسٹم انٹیگریشن بنانے کے بجائے، آپ ایک ایسا انٹرفیس بناتے ہیں جو اس کے مطابق ہو۔ کوئی بھی کلائنٹ جو MCP کو سمجھتا ہے، وہ PHP، Laravel، یا آپ کے مخصوص ڈیٹا بیس اسکیما (database schema) کے بارے میں کچھ جانے بغیر آپ کے سرور سے بات کر سکتا ہے۔

اندرونی طور پر، MCP JSON-RPC 2.0 استعمال کرتا ہے۔ اس کا مطلب ہے کہ ہر ریکویسٹ (request) ایک سادہ JSON آبجیکٹ ہے جس میں میتھڈ کا نام، پیرامیٹرز اور ایک ID شامل ہوتی ہے۔ سرور ایک اور JSON آبجیکٹ کے ساتھ جواب دیتا ہے جس میں یا تو نتیجہ (result) ہوتا ہے یا کوئی ایرر (error)۔

ایک سرور تین بنیادی چیزیں (primitives) فراہم کرتا ہے:

  • Tools: وہ ایکشنز جنہیں ماڈل کال (invoke) کر سکتا ہے۔ ایک ٹول ڈیٹا بیس کو کوئری کر سکتا ہے، اسٹیٹس اپ ڈیٹ کر سکتا ہے، یا کسی تھرڈ پارٹی API کو کال کر سکتا ہے۔
  • Resources: اسٹیٹک یا نیم اسٹیٹک ڈیٹا جسے ماڈل URI کے ذریعے ریفرنس کر سکتا ہے۔ مثلاً فائلیں، کنفیگریشن دستاویزات، یا ریفرنس ڈیٹا سیٹس۔
  • Prompts: پہلے سے طے شدہ ٹیمپلیٹس جو صارف کو سسٹم کے ساتھ بات چیت کرنے میں مدد دیتے ہیں۔

یاد رکھنے کے لیے کنٹرول کا ایک اہم فرق ہے۔ Tools ماڈل کے کنٹرول میں ہوتے ہیں۔ اسسٹنٹ فیصلہ کرتا ہے کہ کب کسی ٹول کو کال کرنا ہے۔ Resources ایپلی کیشن کے کنٹرول میں ہوتے ہیں۔ سرور فیصلہ کرتا ہے کہ کون سا ڈیٹا دستیاب ہے اور ماڈل صرف وہی پڑھتا ہے جو اسے پیش کیا جاتا ہے۔ اس فرق کو درست رکھنا آپ کے آرکیٹیکچر کو قابلِ پیش گوئی (predictable) رکھتا ہے۔ آپ نہیں چاہیں گے کہ ماڈل ایسے ریسورسز کی تلاش کرے جنہیں ٹولز ہونا چاہیے تھا، یا اس کے برعکس۔

ٹرانسپورٹ (Transport) کیسے کام کرتا ہے

MCP دو ٹرانسپورٹ میتھڈز کی وضاحت کرتا ہے، اور آپ کا انتخاب یہ طے کرتا ہے کہ آپ PHP والا حصہ کیسے لکھتے ہیں۔

stdio سب سے سادہ ہے۔ MCP کلائنٹ آپ کے PHP اسکرپٹ کو ایک سب پروسیس (subprocess) کے طور پر لانچ کرتا ہے۔ کلائنٹ آپ کے اسکرپٹ کے standard input پر JSON-RPC پیغامات لکھتا ہے، اور آپ کا اسکرپٹ standard output پر جوابات لکھتا ہے۔ یہاں نہ تو مینیج کرنے کے لیے کوئی ساکٹس (sockets) ہیں، نہ کھولنے کے لیے کوئی پورٹس، اور نہ ہی پارس کرنے کے لیے کوئی آتھنٹیکیشن ہیڈرز۔ اگر آپ کا ٹول اور کلائنٹ ایک ہی مشین پر ہیں، تو عام طور پر یہ آغاز کرنے کے لیے بہترین جگہ ہے۔

stdio پر چلنے کے لیے آپ کے PHP پروسیس پر دو سخت قوانین لاگو ہوتے ہیں۔ پہلا، آپ کی ایپلی کیشن کو کبھی بھی stdout پر نان-پروٹوکول (non-protocol) ڈیٹا نہیں لکھنا چاہیے۔ اگر آپ کوئی ڈیبگ اسٹیٹمنٹ (debug statement) ایکو (echo) کرتے ہیں یا کوئی PHP نوٹس (notice) لیک ہونے دیتے ہیں، تو آپ کلائنٹ کے پارسر کو توڑ دیں گے۔ تمام لاگنگ اور تشخیص (diagnostics) کو stderr پر بھیجیں۔ دوسرا، آؤٹ پٹ بفرنگ (output buffering) کو مکمل طور پر غیر فعال کر دیں۔ PHP، خاص طور پر CGI یا ویب سیاق و سباق میں، stdout کو بفر کرنا پسند کرتا ہے، لیکن CLI اسکرپٹس بھی ڈیٹا کو روک سکتے ہیں۔ ہر جواب کو فوری طور پر فلش (flush) کریں۔ اگر آپ اسٹریمز (streams) استعمال کر رہے ہیں، تو stream_set_write_buffer(STDOUT, 0) سیٹ کریں یا امپلیسٹ بفرنگ (implicit buffering) کو بند کر دیں تاکہ کلائنٹ کو نیو لائن (newline) اسی لمحے مل جائے جب آپ اسے بھیجیں۔

Streamable HTTP مختلف طریقے سے کام کرتا ہے۔ آپ کی PHP ایپلی کیشن ایک مستقل (persistent) HTTP اینڈ پوائنٹ کے طور پر چلتی ہے، جس تک عام طور پر POST ریکویسٹس کے ذریعے پہنچا جاتا ہے۔ یہ اس وقت مفید ہوتا ہے جب سرور کسی دوسرے ہوسٹ پر ہو، یا جب آپ ایک طویل عرصے تک چلنے والا ڈیمن (daemon) چاہتے ہوں جسے متعدد کلائنٹس تک رسائی حاصل ہو سکے۔ PHP میں، اس کا عام طور پر مطلب RoadRunner، FrankenPHP، یا اسی طرح کے پروسیس مینیجر کے تحت چلنا ہے، بجائے روایتی ریکویسٹ-رسپانس سائیکل کے جو ہر کال کے بعد ختم ہو جاتا ہے۔

اسے PHP میں بنانا

شروع کرنے کے لیے آپ کو کسی فریم ورک کی ضرورت نہیں ہے۔ PHP میں ایک کم سے کم (minimal) MCP سرور ایک لوپ ہے جو STDIN سے پڑھتا ہے، JSON کو ڈیکوڈ (decode) کرتا ہے، ہینڈلر (handler) کو بھیجتا ہے، اور نتیجے کو انکوڈ (encode) کرتا ہے۔

while ($line = fgets(STDIN)) {
    $request = json_decode($line, true);
    // route to tool or resource handler
    // write JSON-RPC response to STDOUT
}

اس لوپ کے اندر، اصل کام ایسے انٹرفیس بنانا ہے جو ماڈل کے لیے سمجھ میں آنے والے ہوں۔

کوڈ سے ٹول اسکیمائیں (schemas) تیار کریں۔ مسائل پیدا کرنے کا ایک تیز ترین طریقہ اپنے ٹول پیرامیٹرز کے لیے دستی طور پر JSON Schemas لکھنا ہے اور انہیں اپنے اصل ویلیڈیشن لاجک سے الگ چھوڑ دینا ہے۔ PHP میں ریفلیکشن (reflection) کی بھرپور صلاحیتیں موجود ہیں۔ اپنے میتھڈ سگنیچرز (method signatures) کا معائنہ کریں، اپنے فارمز یا کمانڈ آبجیکٹس سے موجودہ ویلیڈیشن رولز پڑھیں، اور ان پابندیوں (constraints) سے اسکیمہ تیار کریں۔ اگر آپ کا اندرونی کوڈ ایک درست ای میل فارمیٹ کا تقاضا کرتا ہے، تو آپ کے MCP اسکیمہ کو بھی وہی کہنا چاہیے۔ جب ویلیڈیشن رولز تبدیل ہوتے ہیں، تو اسکیمہ خود بخود اپ ڈیٹ ہو جاتا ہے۔ نہ کوئی فرق (drift) پڑے گا، نہ ہی خاموش ناکامیاں (silent failures) ہوں گی۔

پروٹوکول ایررز (errors) کو ٹول ایررز سے الگ کریں۔ JSON-RPC کا اپنا ایرر اسپیس (error space) ہے۔ اسے خراب پروٹوکول کے لیے استعمال کریں: جیسے کہ غلط فارمیٹ والا JSON، نامعلوم میتھڈز، یا گمشدہ ریکویسٹ آئی ڈیز۔ جب کوئی ٹول صحیح طریقے سے چلتا ہے لیکن کسی کاروباری مسئلے (business problem) کا سامنا کرتا ہے، تو پے لوڈ (payload) کے اندر ایک ایرر فلیگ کے ساتھ نارمل رزلٹ واپس کریں۔ اگر کسٹمر لک اپ ٹول کو کوئی مماثل ریکارڈ نہیں ملتا، تو یہ پروٹوکول کریش نہیں ہے۔ ایک اسٹرکچرڈ رزلٹ جیسے کہ {"found": false} واپس کرنے سے ماڈل سمجھ پاتا ہے کہ کیا ہوا اور وہ اگلا قدم چن سکتا ہے۔ وہ شاید زیادہ وسیع سرچ کرنے کی کوشش کرے، یا صارف سے وضاحت مانگ لے۔ اگر آپ اس کے بجائے JSON-RPC ایرر پھینکتے ہیں، تو ماڈل اکثر سیاق و سباق (context) کھو دیتا ہے۔

طویل عرصے تک چلنے والے کاموں کے لیے منصوبہ بندی کریں۔ PHP مختصر ریکویسٹس کے لیے بنایا گیا ہے۔ ایک ویب ریکویسٹ تیس سیکنڈ میں ٹائم آؤٹ ہو سکتی ہے، اور یہاں تک کہ CLI اسکرپٹس بھی میموری یا صبر ختم کر سکتی ہیں۔ اگر کسی ٹول کو مکمل ہونے میں منٹ درکار ہوں—مثلاً وہ ایک بڑی رپورٹ کمپائل کرتا ہے یا سسٹم کے درمیان ڈیٹا سنک (sync) کرتا ہے—تو ماڈل کو انتظار نہ کروائیں۔ فوری طور پر ایک جاب آئیڈنٹیفائر (job identifier) واپس کریں۔ پھر اسی آئی ڈی کے ذریعے اسٹیٹس چیک کرنے کے لیے دوسرا ٹول فراہم کریں۔ آپ پروگریس کو Redis، ڈیٹا بیس ٹیبل، یا اگر حجم کم ہو تو ایک سادہ فائل (flat file) میں بھی اسٹور کر سکتے ہیں۔ ماڈل آئی ڈی وصول کرتا ہے، بعد میں دوبارہ چیک کرتا ہے، اور آخر کار مکمل رزلٹ حاصل کر لیتا ہے۔

جب ماڈل کے پاس کیز (keys) ہوں تو سیکیورٹی

کسی AI ماڈل کو ٹول تک رسائی دینا کسی انسانی صارف کو رسائی دینے جیسا نہیں ہے۔ ایک ماڈل لفظی طور پر بہت تیزی سے کام کرتا ہے، اور وہ تفصیلات کی غلط تشریح کر سکتا ہے۔ ہر ظاہر کیے گئے ٹول کو پرائیلیج ایسکلیشن (privilege escalation) کے خطرے کے طور پر دیکھیں۔

اسکوپ (scope) کو سختی سے محدود کریں۔ کبھی بھی ایک عام run_sql ٹول ظاہر نہ کریں۔ مخصوص اور محدود ٹولز بنائیں جیسے کہ find_customer_by_email یا update_order_status۔ ماڈل کو صرف وہی کرنے کے قابل ہونا چاہیے جو آپ نے نام دیا ہے، اور صرف وہی پیرامیٹرز کے ساتھ جو آپ نے متعین کیے ہیں۔

ریڈ (read) اور رائٹ (write) راستوں کو الگ کریں۔ ریڈ-اونلی (read-only) ٹولز میں خطرہ کم ہوتا ہے۔ کسی بھی تباہ کن عمل (destructive action) کو ایک واضح تصدیقی میکانزم کے پیچھے رکھیں، یا اسے مکمل طور پر دوسرے سرور تک محدود کر دیں۔ اگر آپ کا کلائنٹ اس کی اجازت دیتا ہے، تو رائٹ ٹول کے چلنے سے پہلے انسانی منظوری کا مرحلہ لازمی بنائیں۔

ٹول کی تفصیلات ایسے لکھیں جیسے کہ وہ اضافی ہدایات ہوں، کیونکہ وہ حقیقت میں ہدایات ہی ہیں۔ اس بارے میں بالکل درست رہیں کہ ماڈل کو کب ٹول کال کرنا چاہیے۔ اگر کوئی ٹول قیمتوں کا پتہ لگاتا ہے، تو واضح طور پر بتائیں۔ اگر اسے کسٹمر آئی ڈی کی تصدیق کے بعد ہی استعمال کیا جانا چاہیے، تو اسے واضح طور پر بیان کریں۔ مبہم تفصیلات مبہم رویے کا باعث بنتی ہیں۔

اپنے آؤٹ پٹ کو فلٹر کریں۔ پورے Eloquent ماڈل یا Doctrine entity کو سیریلائز (serialize) کر کے رزلٹ میں نہ ڈالیں۔ صرف وہی فیلڈز واپس کریں جن کی ماڈل کو واقعی ضرورت ہے۔ اندرونی فیلڈز—جیسے لاگت کی قیمتیں، ملازمین کے نوٹس، ڈیٹا بیس آئی ڈیز جو اندرونی رہنی چاہئیں—کا نیٹ ورک پر آنا مناسب نہیں ہے۔ اپنے ریٹرن شیپ (return shape) کے بارے میں واضح رہیں۔

آخر میں، ہر چیز کو لاگ (log) کریں۔ ٹول کا نام، پاس کیے گئے آرگیومنٹس (arguments)، اور نتیجہ ریکارڈ کریں۔ اگر کوئی ماڈل کسی مہنگے کوئری (expensive query) پر لوپ کرنا شروع کر دے یا غیر متوقع ترتیب میں ٹولز کو چیک کرنے لگے، تو آپ کے لاگز ہی وہ واحد ذریعہ ہوں گے جس سے آپ کو اس کا پتہ چلے گا۔

کہاں سے شروع کریں

اپنی PHP ایپلی کیشن کو AI اسسٹنٹ سے جوڑنے کے لیے آپ کو کسی SDK مینٹینر کی اجازت کی ضرورت نہیں ہے۔ آپ کو صرف JSON-RPC، ایک لوپ، اور stdout کے حوالے سے کچھ نظم و ضبط کی ضرورت ہے۔

پہلے ہی دن اپنی پوری API کو MCP ٹولز کے طور پر دوبارہ بنانے کی خواہش سے بچیں۔ تین ایسے ریڈ-اونلی (read-only) آپریشنز کا انتخاب کریں جن کے بارے میں آپ کے ادارے میں کوئی بار بار پوچھتا ہو۔ شاید وہ آرڈر اسٹیٹس چیک کرنا ہو، کسٹمر سمری نکالنا ہو، یا حالیہ انوائسز کی فہرست دکھانا ہو۔ انہیں ٹولز کے طور پر تیار کریں، انہیں stdio کے ذریعے فراہم کریں، اور کسی ایک ساتھی کو انہیں استعمال کرنے دیں۔ دیکھیں کہ ماڈل کیا اچھا کرتا ہے اور کہاں غلطی کرتا ہے۔ آپ ان تین ٹولز سے اس سے کہیں زیادہ سیکھیں گے جتنا کہ تیس (30) ٹولز کی منصوبہ بندی کرنے سے سیکھ سکیں گے۔

MCP ایک پل ہے، آپ کی ایپلی کیشن کا متبادل نہیں ہے۔ آپ کا PHP کوڈ پہلے سے ہی آپ کے