MCP कनेक्टर्ससाठी OpenID कॉन्फिगरेशन फिक्स
या आठवड्यात एका रिमोट MCP कनेक्टरमधील त्रुटी सुधारण्यात माझा खूप वेळ गेला.
कनेक्टरला माझा OAuth सर्व्हर शोधण्यात वारंवार अपयश येत होते. सर्व्हर व्यवस्थित काम करत होता. समस्या फक्त एका गहाळ असलेल्या राऊट (route) आणि एका रिडायरेक्टमुळे (redirect) होती.
जेव्हा तुम्ही MCP सोबत OAuth वापरता, तेव्हा तुम्हाला डिस्कव्हरी डॉक्युमेंट्स (discovery documents) काम करतील अशी अपेक्षा असते. बहुतेक टूल्स खालील दोन पाथ (paths) शोधतात:
- /.well-known/oauth-authorization-server
- /.well-known/oauth-protected-resource
हे क्लायंट्सना ऑथोरायझेशन (authorization) आणि टोकन एंडपॉइंट्स (token endpoints) कोठे शोधायचे हे सांगतात.
समस्या अशी आहे की अनेक क्लायंट्स त्या विशिष्ट पाथ्सना शोधत नाहीत. त्याऐवजी, ते /.well-known/openid-configuration शोधतात.
हा OpenID Connect पाथ आहे. हे एक वेगळे स्पेसिफिकेशन (spec) आहे, परंतु ते त्याच ठिकाणी असते. माझ्या पॅकेजने हा पाथ रजिस्टर केला नव्हता कारण ते OAuth स्पेसिफिकेशनचे पालन करते, OIDC स्पेसिफिकेशनचे नाही.
क्लायंट अशा दरवाजावर थाप मारतो जो अस्तित्वातच नाही. त्याला 404 एरर मिळतो आणि तो थांबतो.
माझ्याकडे दोन पर्याय होते:
Nginx मध्ये रिव्हर्स-प्रॉक्सी रिडायरेक्ट (reverse-proxy redirect) वापरणे. हा एक सोपा पण तात्पुरता उपाय (lazy fix) आहे. यामुळे तुमचे लॉजिक कोडमधून बाहेर काढून इन्फ्रास्ट्रक्चरमध्ये जाते. याची चाचणी (test) करणे कठीण असते आणि डिप्लॉयमेंट दरम्यान यात बिघाड होण्याची शक्यता जास्त असते.
ॲप्लिकेशनमध्येच हे फिक्स करणे. हा अधिक चांगला मार्ग आहे.
मी ॲप्लिकेशनला या प्रश्नाचे उत्तर देण्यास सक्षम करण्याचा निर्णय घेतला. मी एक अलिआस (alias) तयार केला जो OpenID पाथला OAuth ऑथोरायझेशन पाथवर रिडायरेक्ट करतो.
मी 308 Permanent Redirect चा वापर केला.
302 रिडायरेक्टमुळे POST रिक्वेस्ट GET रिक्वेस्टमध्ये बदलू शकते. मात्र, 308 रिडायरेक्ट कडक (strict) असते. ते क्लायंटला नवीन URL वर जाण्यास सांगते आणि त्याच मेथड (method) आणि बॉडी (body) कायम ठेवण्यास सांगते. कायमस्वरूपी स्थलांतर (permanent move) हाताळण्याचा हा योग्य मार्ग आहे.
मी हे एका कॉन्फिगरेशन फ्लॅगच्या (configuration flag) मागे देखील ठेवले आहे. यामुळे वापरकर्त्यांना त्यांची स्वतःची OIDC डिस्कव्हरी चालवायची असल्यास हे बंद करण्याची सुविधा मिळते.
कोडमध्ये हे केल्यामुळे, मी चाचण्या (tests) लिहू शकतो:
- एक टेस्ट रिडायरेक्ट योग्यरित्या होते की नाही हे तपासते.
- दुसरी टेस्ट रिडायरेक्टचा पाठलाग करून मेटाडेटा (metadata) वैध असल्याची खात्री करते.
यामुळे मेटाडेटाची रचना बदलल्यास माझ्या टेस्ट्स लगेच फेल होतील याची खात्री मिळते. युजरला कनेक्ट होता येत नाही, त्याऐवजी मला माझ्या पाइपलाइनमध्येच त्रुटी सापडते.
प्रत्यक्षात स्पेसिफिकेशन्स अनेकदा वेगळी असू शकतात. दोन मानके (standards) समान उद्दिष्टे ठेवत असली तरी, क्लायंट्स वेगवेगळे पाथ निवडू शकतात. सर्व्हर डेव्हलपर म्हणून, तुम्ही दोन्ही दरवाजांना उत्तरे दिली पाहिजेत.
त्यांना एकाच खोलीकडे निर्देशित करा, योग्य रिडायरेक्ट कोड वापरा आणि चाचण्यांद्वारे (tests) त्याची पुष्टी करा.