মডেল কনটেক্সট প্রোটোকল (MCP) দ্রুত বাহ্যিক সরঞ্জাম এবং ডেটা উত্সগুলির সাথে AI মডেলগুলিকে সংযুক্ত করার মানক উপায় হয়ে উঠছে। MCP গ্রহণ বৃদ্ধির সাথে সাথে, বিকাশকারীরা আবিষ্কার করছেন যে শক্তিশালী, উৎপাদন-প্রস্তুত MCP বাস্তবায়নের জন্য শুধুমাত্র বৈশিষ্ট্য অনুসরণ করার চেয়ে আরও বেশি কিছু প্রয়োজন:এর জন্য সঠিক পরিকাঠামো প্রয়োজন। এই পোস্টে, আমরা অন্বেষণ করব কিভাবে Redis তিনটি ভিন্ন MCP ব্যবহারের ক্ষেত্রে ক্ষমতা দেয়:Vercel এর SSE বাস্তবায়নে বিতরণ করা সার্ভারহীন ফাংশন সমন্বয় করা, দীর্ঘ-চলমান স্ট্রীমগুলির জন্য ইভেন্ট পুনঃসূচনাযোগ্যতা সক্ষম করা এবং Clerk-এর সাথে নিরাপদ OAuth প্রবাহ পরিচালনা করা।
MCP পরিবহন বোঝা
আমাদের উদাহরণগুলিতে ডুব দেওয়ার আগে, আসুন সংক্ষেপে কভার করি যে MCP কীভাবে যোগাযোগ পরিচালনা করে। MCP দুটি পরিবহন সমর্থন করে:Stdio স্থানীয় সার্ভার এবং স্ট্রিমেবল HTTP এর জন্য দূরবর্তী সার্ভারের জন্য। অতীতে, দূরবর্তী সার্ভারগুলির জন্য একটি SSE (সার্ভার-প্রেরিত ইভেন্ট) পরিবহনও ছিল, যা এখন অবমূল্যায়িত হয়েছে৷
SSE থেকে স্ট্রিমেবল HTTP-তে রূপান্তর MCP কীভাবে রিয়েল-টাইম যোগাযোগ পরিচালনা করে তার একটি বিবর্তন উপস্থাপন করে, কিন্তু অনেক বিদ্যমান বাস্তবায়ন এখনও SSE প্যাটার্নের উপর নির্ভর করে। আসুন দেখি কিভাবে Redis সেই মডেলের অন্যতম প্রধান চ্যালেঞ্জ সমাধান করতে সাহায্য করেছে।
কেস 1 ব্যবহার করুন:Redis Pub/Sub-এর সাথে SSE
যখন Vercel CTO Malte তাদের MCP হ্যান্ডলার তৈরি করেছিলেন, তখন তিনি একটি ক্লাসিক সার্ভারবিহীন চ্যালেঞ্জের মুখোমুখি হয়েছিলেন:যখন প্রতিটি অনুরোধ একটি ভিন্ন সার্ভারবিহীন ফাংশন দ্বারা পরিচালিত হতে পারে তখন আপনি একাধিক এন্ডপয়েন্টের মধ্যে কীভাবে সমন্বয় করবেন?
SSE ট্রান্সপোর্ট মডেলে, দুটি গুরুত্বপূর্ণ শেষ পয়েন্ট রয়েছে:/sse সংযোগ বজায় রাখার জন্য এবং /message ক্লায়েন্ট বার্তা গ্রহণের জন্য। এখানে সমস্যা:Vercel এর মত সার্ভারহীন পরিবেশে, এই শেষ পয়েন্টগুলি সম্পূর্ণ বিচ্ছিন্ন। তারা মেমরি ভাগ করে না, এবং /message করার অনুরোধ একটি হ্যান্ডলিং /sse থেকে সম্পূর্ণ ভিন্ন ফাংশন ইনস্ট্যান্স দ্বারা পরিচালিত হতে পারে .
সমাধান? রেডিস পাব/সাব। মাল্টে যেমন X:
এ ব্যাখ্যা করেছেন

বাস্তবায়নটি রেডিস চ্যানেলগুলিকে শেষ পয়েন্টগুলির মধ্যে সমন্বয় করতে ব্যবহার করে। যখন একজন ক্লায়েন্ট /message এ একটি বার্তা পাঠায় , সেই এন্ডপয়েন্টটি একটি Redis চ্যানেলে প্রকাশ করে যেটি /sse শেষ পয়েন্ট সাবস্ক্রাইব করা হয়. /sse এন্ডপয়েন্ট অনুরোধটি প্রক্রিয়া করে এবং /message অন্য চ্যানেলের মাধ্যমে প্রতিক্রিয়া প্রকাশ করে শুনছে৷

এই প্যাটার্নটি কার্যকরভাবে রেডিসকে একটি বার্তা বাসে পরিণত করে যা বিচ্ছিন্ন সার্ভারহীন ফাংশনগুলির মধ্যে ব্যবধান পূরণ করে, যাতে তারা একই প্রক্রিয়ার অংশ হিসাবে একসাথে কাজ করতে দেয়। যদিও SSE এখন স্ট্রিমেবল HTTP-এর পক্ষে উপেক্ষিত হয়েছে (অর্থাৎ নতুন MCP বাস্তবায়নের জন্য আধুনিক পরিবহন ব্যবহার করা উচিত), এটি বিচ্ছিন্ন সার্ভারহীন ফাংশনগুলির মধ্যে সমন্বয়ের জন্য Redis ব্যবহার করার একটি চমৎকার উদাহরণ হিসেবে রয়ে গেছে।
কেস 2 ব্যবহার করুন:পুনরায় শুরু করার জন্য ইভেন্ট স্টোর
MCP এর স্ট্রিমেবল এইচটিটিপি ট্রান্সপোর্টের সবচেয়ে শক্তিশালী বৈশিষ্ট্যগুলির মধ্যে একটি হল পুনঃসূচনাযোগ্যতার জন্য এটির সমর্থন। এই বৈশিষ্ট্যটি ক্লায়েন্টদের সংযোগ বিচ্ছিন্ন হওয়ার ক্ষেত্রে যেখান থেকে ছেড়ে গেছে সেখান থেকে একটি স্ট্রিম চালিয়ে যেতে দেয়। এটি উত্পাদন অ্যাপ্লিকেশনগুলির জন্য গুরুত্বপূর্ণ যেখানে নেটওয়ার্ক বাধা অনিবার্য৷
MCP স্ট্রীম বোঝা
কেন পুনরুদ্ধারযোগ্যতা গুরুত্বপূর্ণ তা বোঝার জন্য, আমাদের বুঝতে হবে যে MCP স্ট্রীমগুলি কী নিয়ে গঠিত। কিছু অপারেশন, যেমন একটি সাধারণ টুল কল করা, একটি একক প্রতিক্রিয়া প্রদান করে। কিন্তু সার্ভার.sendLoggingMessage-এর মতো পদ্ধতি ব্যবহার করে এক্সিকিউশনের সময় টুলগুলি একাধিক ইভেন্টও ফিরিয়ে দিতে পারে। এই মাল্টি-ইভেন্ট স্ট্রীম যেখানে পুনঃসূচনাযোগ্যতা গুরুত্বপূর্ণ হয়ে ওঠে। যদি কোনও ক্লায়েন্ট অর্ধেক পথের মধ্যে সংযোগ বিচ্ছিন্ন করে, তবে এটি আবার শুরু করার পরিবর্তে যেখান থেকে ছেড়েছিল তা তুলে নিতে সক্ষম হওয়া উচিত।
Redis এর সাথে ইভেন্টস্টোর বাস্তবায়ন করা হচ্ছে
MCP SDK একটি ইভেন্টস্টোর ইন্টারফেস সংজ্ঞায়িত করে যার জন্য দুটি পদ্ধতির প্রয়োজন:storeEvent ইভেন্ট এবং replayEventsAfter যোগ করার জন্য একটি নির্দিষ্ট ইভেন্ট আইডি থেকে শুরু করে ইভেন্ট পুনরুদ্ধার করার জন্য। SDK একটি ইন-মেমরি বাস্তবায়ন অন্তর্ভুক্ত করে, কিন্তু উত্পাদন ব্যবহারের জন্য, আপনার অবিরাম স্টোরেজ প্রয়োজন৷
এখানে ইভেন্টস্টোরের একটি রেডিস-ভিত্তিক বাস্তবায়ন রয়েছে:
import { Redis } from '@upstash/redis';
import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
import { EventStore } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
export class RedisEventStore implements EventStore {
private redis: Redis;
constructor(params: ConstructorParameters<typeof Redis>[0]) {
this.redis = new Redis(params);
}
/**
* Stores an event in a Redis Stream
* Implements EventStore.storeEvent
*/
async storeEvent(streamId: string, message: JSONRPCMessage): Promise<string> {
const eventId = await this.redis.xadd(`stream:${streamId}`, '*', {
message: JSON.stringify(message),
});
return eventId;
}
/**
* Replays events that occurred after a specific event ID
* Implements EventStore.replayEventsAfter
*/
async replayEventsAfter(
lastEventId: string,
{ send }: { send: (eventId: string, message: JSONRPCMessage) => Promise<void> }
): Promise<string> {
if (!lastEventId) {
return '';
}
// Extract the stream ID from the lastEventId
const streamId = lastEventId.split('-')[0]; // Assuming the stream ID is part of the key
if (!streamId) {
return '';
}
let nextId = lastEventId;
while (true) {
// Fetch events from the stream starting AFTER the next ID (exclusive)
const events = await this.redis.xrange(`stream:${streamId}`, `(${nextId}`, '+', 10);
// Convert the returned object to an array of entries
const eventEntries = Object.entries(events);
if (eventEntries.length === 0) {
break; // No more events to replay
}
for (const [eventId, fields] of eventEntries) {
// Ensure fields.message exists and parse it
if (fields && typeof fields === 'object' && 'message' in fields && typeof fields.message === 'string') {
const message = JSON.parse(fields.message) as JSONRPCMessage;
await send(eventId, message);
nextId = eventId; // Update the next ID to the current event ID
}
}
}
return streamId;
}
} এই বাস্তবায়ন রেডিস স্ট্রিম ব্যবহার করে, যা এই ব্যবহারের ক্ষেত্রে উপযুক্ত।
একটি সীমাবদ্ধতা
সচেতন হওয়ার জন্য একটি গুরুত্বপূর্ণ সতর্কতা রয়েছে:যখন একটি টুল একাধিক ইভেন্ট পাঠায়, তখন স্ট্রিমআইডি _GET_stream সেট করা হয় , এবং এই ধ্রুবক বিভিন্ন স্ট্রীম এবং ব্যবহারকারীদের মধ্যে একই থাকে। এর মানে হল যে যদি দুইজন ব্যবহারকারী একই টুল ব্যবহার করে যা একাধিক ইভেন্ট পাঠায়, তাদের ইভেন্টগুলি একই স্ট্রীমে মিশ্রিত হতে পারে।
আমি অফিসিয়াল রিপোজিটরিতে এই সম্পর্কে একটি সমস্যা খুলেছি। রেজোলিউশনের উপর নির্ভর করে, আমাদের বাস্তবায়ন সামঞ্জস্য করতে হতে পারে, এবং প্রয়োজন হলে আমি সেই অনুযায়ী এই পোস্টটি আপডেট করব।
কেস 3 ব্যবহার করুন:ক্লার্কের MCP OAuth বাস্তবায়ন
MCP স্পেসিফিকেশন প্রমাণীকরণ এবং অনুমোদনের জন্য সমর্থন অন্তর্ভুক্ত করে, MCP সার্ভারগুলিকে নিরাপদে ক্লায়েন্টদের প্রমাণীকরণ করতে এবং সংস্থানগুলিতে অ্যাক্সেস নিয়ন্ত্রণ করতে দেয়। স্পেকটি একাধিক প্রমাণীকরণ স্কিম সমর্থন করে, যার মধ্যে রয়েছে OAuth 2.0, যা বিদ্যমান পরিচয় প্রদানকারীদের সাথে একীভূত করার জন্য এবং সরঞ্জাম এবং ডেটাতে ব্যবহারকারীর সুযোগ সুবিধা সক্ষম করার জন্য বিশেষভাবে কার্যকর৷
ক্লার্ক MCP SDK থেকে OAuthClientProvider ইন্টারফেস প্রয়োগ করে MCP-এর জন্য একটি ব্যাপক OAuth ক্লায়েন্ট তৈরি করেছে। তাদের বাস্তবায়ন MCP অ্যাপ্লিকেশনগুলিতে Redis-এর জন্য আরেকটি গুরুত্বপূর্ণ ব্যবহারের ক্ষেত্রে দেখায়। আপনি যদি তাদের MCP সরঞ্জামগুলি দিয়ে শুরু করতে চান তবে তাদের ডেমো সংগ্রহস্থলটি দেখুন যা একটি দুর্দান্ত সূচনা পয়েন্ট প্রদান করে৷
OAuth-এর জন্য কেন স্টোরেজ গুরুত্বপূর্ণ
ক্লার্ক তাদের mcp-tools এ ব্যাখ্যা করেছেন দুটি মূল কারণে MCP OAuth বাস্তবায়নের জন্য সংগ্রহস্থল, স্থায়ী সঞ্চয়স্থান অপরিহার্য:
- OAuth ফ্লো একাধিক এন্ডপয়েন্টকে বিস্তৃত করে - প্রারম্ভিকতা, OAuth কলব্যাক, এবং MCP অনুরোধগুলি শেয়ার করা মেমরি ছাড়াই বিভিন্ন সার্ভারহীন ফাংশন দ্বারা পরিচালনা করা যেতে পারে
- MCP সংযোগগুলি দীর্ঘস্থায়ী৷ - ইন-মেমরি স্টোরেজের উপর নির্ভর করলে অ্যাপ্লিকেশন স্কেল হিসাবে মেমরির প্রয়োজনীয়তাগুলি ফুলে যায়, এবং যে কোনও সার্ভার পুনরায় চালু হলে সমস্ত সেশনগুলি বাতিল হয়ে যাবে
Redis-এ কি সংরক্ষিত হয়
ক্লার্কের রেডিস স্টোর তিন ধরনের ডেটা পরিচালনা করে, প্রতিটিরই OAuth প্রবাহে একটি নির্দিষ্ট উদ্দেশ্য রয়েছে:
PKCE যাচাইকারী (pkce_verifier_<...> )OAuth প্রবাহ শুরু করার সময় এগুলি সংরক্ষণ করা হয় এবং ব্যবহারকারীর অ্যাক্সেস মঞ্জুর করার পরে আবার পড়া হয়৷ এগুলি PKCE (কোড এক্সচেঞ্জের জন্য প্রুফ কী) প্রবাহের অংশ, যা সর্বজনীন ক্লায়েন্টগুলিতে OAuth-এর জন্য অতিরিক্ত নিরাপত্তা প্রদান করে যাতে প্রবাহ শুরু করা অ্যাপ্লিকেশনটি এটি সম্পূর্ণ করে (RFC 7636-এ সংজ্ঞায়িত করা হয়েছে)।
{
"value": "XoYQ...",
"created_at": "2025-10-03T06:27:06.928Z",
"updated_at": "2025-10-03T06:27:06.928Z"
}
সেশন ডেটা (session_<...> )এটি একটি MCP সেশনের জন্য সমস্ত কনফিগারেশন এবং অবস্থা সঞ্চয় করে। প্রাথমিকভাবে, এতে MCP এন্ডপয়েন্ট, OAuth কনফিগারেশন এবং ক্লায়েন্ট শংসাপত্র রয়েছে। ব্যবহারকারী অ্যাক্সেস মঞ্জুর করার পরে, এটি অ্যাক্সেস এবং রিফ্রেশ টোকেন সহ আপডেট করা হয়। অবশেষে, একটি authComplete প্রবাহ শেষ হলে পতাকা যোগ করা হয়।
{
"value": {
"mcpEndpoint": "http://localhost:3001/mcp",
"oauthRedirectUrl": "http://localhost:3000/oauth_callback",
"oauthScopes": "openid profile email",
"mcpClientName": "Clerk MCP Demo",
"mcpClientVersion": "0.0.1",
"oauthClientUri": "http://example.com",
"oauthPublicClient": false,
"clientId": "8Yb2...",
"clientSecret": "64YG..."
},
"created_at": "2025-10-03T06:27:06.882Z",
"updated_at": "2025-10-03T06:27:06.882Z"
}
স্টেট প্যারামিটার (state_<...> )এই ম্যাপ OAuth স্টেট প্যারামিটারগুলি সেশন আইডিতে, এটি একটি স্টেট আইডি ব্যবহার করে সেশন ডেটা পাওয়া সম্ভব করে তোলে:
{
"value": "dX61...",
"created_at": "2025-10-03T06:27:03.585Z",
"updated_at": "2025-10-03T06:27:03.585Z"
} এই আর্কিটেকচারটি নিরাপত্তা এবং সেশনের অখণ্ডতা বজায় রেখে OAuth প্রবাহকে বিতরণ করা সার্ভারহীন ফাংশন জুড়ে নির্বিঘ্নে কাজ করার অনুমতি দেয়৷
কেন Redis MCP-এর জন্য পারফেক্ট
তিনটি উদাহরণ জুড়ে, আমরা সাধারণ প্যাটার্নগুলি দেখতে পাই যা Redis কে MCP পরিকাঠামোর জন্য একটি আদর্শ পছন্দ করে তোলে:
কম লেটেন্সি :MCP অপারেশন প্রায়ই দ্রুত হতে হবে. রেডিসের ইন-মেমরি আর্কিটেকচার রিয়েল-টাইম এআই ইন্টারঅ্যাকশনের জন্য প্রয়োজনীয় প্রতিক্রিয়া সময় প্রদান করে।
পাব/সাব ক্ষমতা :আমরা যেমন Vercel এর বাস্তবায়নের সাথে দেখেছি, Redis Pub/Sub একটি সম্পূর্ণ বার্তা সারির জটিলতা ছাড়াই বিতরণ করা উপাদানগুলির মধ্যে মার্জিত সমন্বয় সক্ষম করে৷
সমৃদ্ধ ডেটা স্ট্রাকচার :ইভেন্ট স্ট্রীমগুলির জন্য স্ট্রীম, সেশন ডেটার জন্য হ্যাশ এবং রাজ্যের জন্য সাধারণ কী-মান জোড়া৷ Redis প্রতিটি ব্যবহারের ক্ষেত্রে সঠিক তথ্য কাঠামো প্রদান করে।
অন্তর্নির্মিত মেয়াদ শেষ হওয়া :TTL এর মাধ্যমে স্বয়ংক্রিয় পরিস্কার। OAuth টোকেন, ইভেন্ট স্ট্রীম এবং সেশন ডেটা সবই ম্যানুয়াল আবর্জনা সংগ্রহ ছাড়াই স্বয়ংক্রিয়ভাবে শেষ হয়ে যেতে পারে।
সার্ভারহীন-বান্ধব :Upstash Redis-এর মতো সমাধানগুলির সাথে, আপনি একটি সম্পূর্ণরূপে পরিচালিত, সার্ভারহীন রেডিস পান যা ব্যবহার না করার সময় শূন্যে স্কেল করে। পরিবর্তনশীল কাজের চাপ থাকতে পারে এমন MCP বাস্তবায়নের জন্য উপযুক্ত।
এমসিপি বিশেষ বৈশিষ্ট্যের বাইরে:বিস্তৃত এআই ইকোসিস্টেমে রিডিস
যদিও আমরা এমসিপি স্পেসিফিকেশনে স্পষ্টভাবে সংজ্ঞায়িত বৈশিষ্ট্যগুলিতে ফোকাস করেছি, রেডিসের ইউটিলিটি AI পাওয়ার করার ক্ষেত্রে আমরা যে নিদর্শনগুলি অন্বেষণ করেছি তার থেকে অনেক বেশি প্রসারিত। আমাদের সাম্প্রতিক ব্লগ পোস্টগুলি এই নিদর্শনগুলির মধ্যে কয়েকটি প্রদর্শন করে:
- AI SDK ইন্টিগ্রেশন - Vercel AI SDK উন্নত করতে Redis ব্যবহার করা
- চ্যাটের ইতিহাস - মেসেজিং ইতিহাস স্থির
আমাদের নিজস্ব উদাহরণের বাইরে, সম্প্রদায় এআই অ্যাপ্লিকেশনের জন্য চিত্তাকর্ষক রেডিস-চালিত সরঞ্জাম তৈরি করেছে। মিডডে থেকে ai-sdk-tools স্যুটে একটি টুল ফলাফল ক্যাশিং প্যাকেজ রয়েছে যা AI SDK টুল ফলাফল ক্যাশে করতে Redis ব্যবহার করে, যেমন এই উদাহরণে দেখানো হয়েছে, নাটকীয়ভাবে কর্মক্ষমতা উন্নত করা এবং খরচ কমানো:

আপনি এমসিপি সার্ভার, এআই এজেন্ট বা সম্পূর্ণ এআই অ্যাপ্লিকেশন তৈরি করছেন না কেন, রেডিস একটি পরিকাঠামো স্তর সরবরাহ করে যা আপনার সিস্টেমকে উত্পাদন-প্রস্তুত, পরিমাপযোগ্য এবং পারফরম্যান্ট করে।
উপসংহার
মডেল কনটেক্সট প্রোটোকল এখনও তরুণ, কিন্তু এটি দ্রুত এআই অ্যাপ্লিকেশনের জন্য প্রয়োজনীয় পরিকাঠামো হয়ে উঠছে। আমরা এই তিনটি উদাহরণের মাধ্যমে দেখেছি, রেডিস এমসিপি বাস্তবায়নকে শক্তিশালী এবং উৎপাদন-প্রস্তুত করার ক্ষেত্রে গুরুত্বপূর্ণ ভূমিকা পালন করে:
- গতি এবং নমনীয়তা :এর গতি, নমনীয়তা, এবং সার্ভারহীন-বান্ধব আর্কিটেকচারের সমন্বয়
- খরচ হ্রাস :ক্যাশিং ক্ষমতা যা ব্যয়বহুল API কল এবং গণনা হ্রাস করে
আপনি যদি MCP দিয়ে তৈরি করেন, সার্ভার বা ক্লায়েন্ট সাইডেই হোক না কেন, Redis আপনার টুলকিটে MCP-চালিত AI অ্যাপ্লিকেশনের জন্য নিখুঁত সহচর হিসেবে থাকা উচিত। Upstash Redis এর সাথে, আপনি আজ সেকেন্ডের মধ্যে শুরু করতে পারেন একটি বিশ্বব্যাপী উপলব্ধ, সার্ভারবিহীন রেডিস যা ব্যবহার না করার সময় শূন্যে স্কেল করে।