MCP কানেক্টরগুলোর জন্য OpenID কনফিগারেশন সমাধান

এই সপ্তাহে একটি রিমোট MCP কানেক্টর ঠিক করতে আমার অনেক সময় ব্যয় হয়েছে।

কানেক্টরটি বারবার আমার OAuth সার্ভারটি খুঁজে পেতে ব্যর্থ হচ্ছিল। সার্ভারটি ঠিকঠাক কাজ করছিল। সমস্যাটি ছিল একটি মিসিং রুট (missing route) এবং একটি রিডাইরেক্ট (redirect)-এর কারণে।

যখন আপনি MCP-এর সাথে OAuth ব্যবহার করেন, তখন আপনি আশা করেন যে discovery documents গুলো কাজ করবে। বেশিরভাগ টুল এই দুটি পাথ (path) খোঁজে:

  • /.well-known/oauth-authorization-server
  • /.well-known/oauth-protected-resource

এগুলো ক্লায়েন্টদের জানায় যে অথরাইজেশন (authorization) এবং টোকেন এন্ডপয়েন্ট (token endpoints) কোথায় পাওয়া যাবে।

সমস্যা হলো অনেক ক্লায়েন্ট সেই নির্দিষ্ট পাথগুলো খোঁজে না। পরিবর্তে, তারা /.well-known/openid-configuration খোঁজে।

এটি একটি OpenID Connect পাথ। এটি একটি ভিন্ন স্পেক (spec), কিন্তু এটি একই জায়গায় থাকে। আমার প্যাকেজটি এই পাথটি রেজিস্টার করেনি কারণ এটি OAuth স্পেক অনুসরণ করে, OIDC স্পেক নয়।

ক্লায়েন্ট এমন একটি দরজায় টোকা দেয় যার কোনো অস্তিত্ব নেই। ফলে এটি একটি 404 এরর পায় এবং কাজ বন্ধ করে দেয়।

আমার কাছে দুটি বিকল্প ছিল:

  1. Nginx-এ একটি reverse-proxy redirect ব্যবহার করা। এটি একটি সহজ বা আলসেমি মার্কা সমাধান (lazy fix)। এটি আপনার লজিক কোড থেকে সরিয়ে ইনফ্রাস্ট্রাকচারে নিয়ে যায়। এটি টেস্ট করা কঠিন এবং ডেপ্লয়মেন্টের সময় ভেঙে যাওয়ার সম্ভাবনা থাকে।

  2. অ্যাপ্লিকেশনের ভেতরে এটি ঠিক করা। এটিই হলো উন্নত পদ্ধতি।

আমি অ্যাপটিকে প্রব (probe)-এর উত্তর দেওয়ার উপযোগী করার সিদ্ধান্ত নিয়েছি। আমি একটি এলিয়াস (alias) তৈরি করেছি যা OpenID পাথটিকে OAuth অথরাইজেশন পাথে রিডাইরেক্ট করে।

আমি একটি 308 Permanent Redirect ব্যবহার করেছি।

একটি 302 রিডাইরেক্ট POST রিকোয়েস্টকে GET রিকোয়েস্টে পরিবর্তন করে দিতে পারে। কিন্তু একটি 308 রিডাইরেক্ট অত্যন্ত কঠোর (strict)। এটি ক্লায়েন্টকে নতুন URL-এ যেতে বলে এবং একই মেথড ও বডি বজায় রাখতে বলে। স্থায়ী পরিবর্তনের ক্ষেত্রে এটিই সঠিক পদ্ধতি।

আমি এটিকে একটি কনফিগারেশন ফ্ল্যাগ (configuration flag)-এর পেছনে রেখেছি। এর ফলে ব্যবহারকারীরা চাইলে এটি বন্ধ করে দিতে পারেন যদি তারা নিজস্ব OIDC discovery ব্যবহার করেন।

কোডের মাধ্যমে এটি করার ফলে আমি টেস্ট লিখতে পারি:

  • একটি টেস্ট চেক করে যে রিডাইরেক্টটি সঠিকভাবে হচ্ছে কি না।
  • একটি টেস্ট রিডাইরেক্টটি অনুসরণ করে নিশ্চিত করে যে মেটাডেটা (metadata) বৈধ কি না।

এটি নিশ্চিত করে যে যদি মেটাডেটা স্ট্রাকচার পরিবর্তন হয়, তবে আমার টেস্টগুলো সাথে সাথে ফেইল করবে। এর ফলে ইউজার কানেক্ট করতে না পারার আগেই আমি আমার পাইপলাইনে এররটি খুঁজে পাই।

বাস্তবে স্পেকগুলো (specs) প্রায়ই ভিন্ন হয়। এমনকি দুটি স্ট্যান্ডার্ডের লক্ষ্য একই হলেও, ক্লায়েন্টরা ভিন্ন ভিন্ন পাথ বেছে নিতে পারে। একজন সার্ভার ডেভেলপার হিসেবে আপনার উচিত উভয় দরজাতেই সাড়া দেওয়া।

তাদের একই গন্তব্যে নিয়ে যান, সঠিক রিডাইরেক্ট কোড ব্যবহার করুন এবং টেস্টের মাধ্যমে তা নিশ্চিত করুন।

সেই পরিচিত OpenID কনফিগারেশন এলিয়াস যা MCP কানেক্টরগুলোকে কাজ করতে সহজ করে তোলে

আপনি যদি Model Context Protocol (MCP)-এর উত্থান অনুসরণ করে থাকেন, তবে আপনি জানেন যে এটি LLM-এর সাথে বাহ্যিক টুল এবং ডেটার মিথস্ক্রিয়া করার পদ্ধতি বদলে দিচ্ছে। কিন্তু একটি সমস্যা বারবার ফিরে আসে: অথেন্টিকেশন (authentication)

MCP কানেক্টর তৈরির সময়, ডেভেলপারদের প্রায়শই প্রতিটি সার্ভিসের জন্য ম্যানুয়ালি অথেন্টিকেশন ডিটেইলস কনফিগার করতে হয়। এটি অত্যন্ত ক্লান্তিকর এবং এতে ভুল হওয়ার সম্ভাবনা থাকে।

এখানেই সমাধান হিসেবে আসে .well-known/openid-configuration এন্ডপয়েন্ট।

সমস্যা: ম্যানুয়াল কনফিগারেশন

প্রতিবার যখন আপনি একটি MCP সার্ভারকে নতুন কোনো সার্ভিসের সাথে যুক্ত করেন, তখন আপনার জানা প্রয়োজন:

  • অথরাইজেশন এন্ডপয়েন্ট (authorization endpoint) কোথায়?
  • টোকেন এন্ডপয়েন্ট (token endpoint) কোথায়?
  • কোন স্কোপগুলো (scopes) প্রয়োজন?
  • সমর্থিত সাইনিং অ্যালগরিদমগুলো কী কী?

এই ম্যানুয়াল প্রক্রিয়াটি ডেভেলপার এবং ব্যবহারকারী উভয়ের জন্যই একটি বাধা।

সমাধান: OIDC ডিসকভারি

OpenID Connect (OIDC) একটি "Discovery" মেকানিজমের মাধ্যমে এই সমস্যার সমাধান করে। প্রতিটি ডিটেইলস হার্ডকোড করার পরিবর্তে, আপনার কেবল একটি জিনিস প্রয়োজন: Issuer URL

সেই ইশুইয়ারের (issuer) .well-known/openid-configuration এন্ডপয়েন্টে রিকোয়েস্ট পাঠানোর মাধ্যমে, ক্লায়েন্ট স্বয়ংক্রিয়ভাবে একটি JSON ডকুমেন্ট সংগ্রহ করতে পারে যাতে সমস্ত প্রয়োজনীয় মেটাডেটা থাকে।

MCP-এর জন্য এটি কেন গুরুত্বপূর্ণ

MCP কানেক্টরগুলো এটিকে ব্যবহার করে "plug-and-play" হতে পারে। ব্যবহারকারীর কাছ থেকে এক ডজন ভিন্ন ভিন্ন URL চাওয়ার পরিবর্তে, কানেক্টরটি কেবল Issuer URL চাইতে পারে এবং বাকি কাজ নিজেই সামলাতে পারে।

এটি MCP কানেক্টরগুলোকে করে তোলে:

  1. তৈরি করা সহজ: কম বয়েলারপ্লেট (boilerplate) কোড প্রয়োজন।
  2. আরও নির্ভরযোগ্য (robust): আইডেন্টিটি প্রোভাইডারের কনফিগারেশনে পরিবর্তন স্বয়ংক্রিয়ভাবে সামলে নিতে পারে।
  3. উন্নত ইউজার এক্সপেরিয়েন্স (UX): ব্যবহারকারী কেবল একটি URL প্রদান করেন এবং সবকিছু "সহজেই কাজ করে"।

উপসংহার

`.well-known/openid