انشر خادم MCP على AWS Lambda وAzure وCloud Run جنبًا إلى جنب

خادم MCP واحد عديم الحالة بلغة TypeScript، وثلاث منصات استضافة. اطّلع على إعداد Lambda Web Adapter بالتفصيل، وعلى ملف host.json في Azure Functions للخوادم المستضافة ذاتيًا، وعلى أمر النشر في Cloud Run، إضافةً إلى خيارات المصادقة والمهلات والمفاضلات المرتبطة بالبدء البارد التي تحدد المنصة المناسبة لمشروعك.

انشر خادم MCP على AWS Lambda وAzure وCloud Run جنبًا إلى جنب
Cristian Da Conceicao
مؤسس Picasso IA

يعمل خادم MCP الخاص بك بسلاسة على حاسوبك المحمول عبر stdio. ثم يطلب منك زميل رابطًا يمكنه لصقه في أحد العملاء، وهنا تبدأ المهمة الحقيقية. يحتاج الخادم البعيد إلى HTTPS ومصادقة وآلية نقل تتحمّل موازنات الأحمال، ومنصة لا تحاسبك وأنت لا تستخدمها. يأخذ هذا المقال خادم TypeScript صغيرًا واحدًا ويشغّله على ثلاث منصات: AWS Lambda وAzure Functions وGoogle Cloud Run. ستحصل على الإعداد الذي يهم في كل منصة، وعلى ضوابط الوصول التي تبقي الغرباء بعيدًا، ومقارنة واضحة تتيح لك اختيار المنصة في عشر دقائق بدلًا من أسبوع.

💡 النطاق: تفترض كل الأمثلة أدناه نقل Streamable HTTP. يُستخدم stdio للعمليات الفرعية المحلية، لذا يحتاج الخادم الذي يدعم stdio فقط إلى واجهة HTTP أمامية قبل أن تتمكن أي من هذه المنصات من تشغيله.

اختر آلية النقل قبل السحابة

لماذا يتفوق عديم الحالة في الحوسبة بلا خوادم

تبدأ منصات الحوسبة بلا خوادم النسخ وتوقفها متى شاءت. يصل الطلب الأول إلى النسخة A، والثاني إلى النسخة B، ويؤدي الثالث إلى بدء بارد في النسخة C. إذا كان خادمك يحتفظ بجلسة في الذاكرة، فسينكسر هذا التسلسل.

الحل هو خادم Streamable HTTP عديم الحالة: نقطة نهاية واحدة /mcp تقبل طلب POST وتجيب ثم تنسى. صُممت المنصات الثلاث حول هذا الشكل. تتيح المعاينة المستضافة ذاتيًا من Azure قبول الخوادم عديمة الحالة فقط عبر نقل streamable-http. توثّق Cloud Run أن SSE وStreamable HTTP هما الخياران البعيدان المدعومان لديها، مع بث استجابات HTTP مدمج. ويعمل Lambda بالطريقة نفسها بمجرد وضع محوّل ويب أمامه.

ما الذي غيّرته مواصفات يوليو 2026

سارت مراجعة مواصفات MCP بتاريخ 2026-07-28 في الاتجاه نفسه:

  • لا جلسات على مستوى البروتوكول. اختفت الترويسة Mcp-Session-Id من Streamable HTTP.
  • لا مصافحة. أُزيل تبادل initialize، وصار كل طلب يحمل إصدار البروتوكول وقدرات العميل في _meta.
  • الحالة عبر المقابض. يُنشئ الخادم الذي يحتاج إلى ذاكرة بين الاستدعاءات مقبضًا صريحًا ويمرره كوسيط أداة عادي.
  • لا استئناف للبث. إذا انقطع تدفق الاستجابة فقد الطلب الجاري، ويجب على العميل إرساله من جديد بمعرّف طلب جديد.
  • HTTP+SSE مُهمَل. ينبغي أن تستخدم الأعمال الجديدة Streamable HTTP.

عمليًا، يمكنك كتابة الخادم كشيفرة طلب واستجابة عادية، ودع المنصة تشغّل أي عدد تريده من النسخ. تنبيه واحد: تتأخر إصدارات SDK عن مراجعات المواصفات، لذا ثبّت إصدار SDK الذي تستخدمه، واختبر مع العملاء الذين تهتم بهم قبل أن تثق بأي نشر.

يدا مطوّر ترسمان ثلاثة صناديق متصلة على لوح أبيض زجاجي

خادم واحد، ثلاث وجهات

المعالج المشترك بين جميع المنصات

يعرض خادم العرض التجريبي أداتين تتيحان الوصول إلى PicassoIA developer API: الأولى تبدأ مهمة توليد صورة، والثانية تتحقق من حالتها. تعمل API بأسلوب Replicate وبشكل غير متزامن، وعنوانها الأساسي https://api.picassoia.com/v1، مع مصادقة Bearer، وPOST /models/{owner}/{name}/predictions لبدء المهمة وGET /predictions/{id} لقراءتها. يُبقي تقسيم العمل إلى بدء وتحقق كل طلب قصيرًا، وهذا مناسب للمنصات التي تحتسب الرسوم بالمللي ثانية. تستهدف المهمة أدناه PicassoIA Image عبر المعرّف picassoia/picassoia-image.

import express from "express";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { z } from "zod";

const API = "https://api.picassoia.com/v1";
const auth = { Authorization: `Bearer ${process.env.PICASSOIA_API_TOKEN}` };

function buildServer() {
  const server = new McpServer({ name: "image-tools", version: "1.0.0" });

  server.registerTool(
    "start_image",
    { description: "Start an image generation", inputSchema: { prompt: z.string().max(4000) } },
    async ({ prompt }) => {
      const res = await fetch(`${API}/models/picassoia/picassoia-image/predictions`, {
        method: "POST",
        headers: { ...auth, "Content-Type": "application/json" },
        body: JSON.stringify({ input: { prompt, aspect_ratio: "16:9" } }),
      });
      const job = await res.json();
      return { content: [{ type: "text", text: JSON.stringify({ id: job.id, status: job.status }) }] };
    }
  );

  server.registerTool(
    "get_image",
    { description: "Check a generation by id", inputSchema: { id: z.string() } },
    async ({ id }) => {
      const res = await fetch(`${API}/predictions/${id}`, { headers: auth });
      return { content: [{ type: "text", text: await res.text() }] };
    }
  );
  return server;
}

const app = express();
app.use(express.json());

app.post("/mcp", async (req, res) => {
  const server = buildServer();
  const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
  res.on("close", () => { transport.close(); server.close(); });
  await server.connect(transport);
  await transport.handleRequest(req, res, req.body);
});

app.get("/health", (_req, res) => res.send("ok"));
app.listen(Number(process.env.PORT ?? 8080), "0.0.0.0");

إنشاء خادم ونقل جديدين لكل طلب هو النمط عديم الحالة (stateless) من أمثلة SDK، وتكلفته شبه معدومة لأن تسجيل أداتين أمر رخيص. تتغير أسماء الدوال بين إصدارات SDK، لذلك طابِق المقتطف مع الإصدار الذي تثبّته، وتحقق من حقول الطلب والاستجابة في وثائق PicassoIA API.

الأسرار تبقى خارج الصورة

لا تضمّن أي معلومات حساسة في الحاوية. اقرأ PICASSOIA_API_TOKEN من مخزن الأسرار لدى المنصة: AWS Secrets Manager أو SSM Parameter Store في Lambda، وإعداد تطبيق يشير إلى خزنة مُدارة في Azure، وGoogle Secret Manager في Cloud Run.

💡 تتيح حسابات PicassoIA 5 مهام متزامنة، مشتركة عبر التوكنات واتصالات MCP. حدّد مدى التوازي لدى المنصة المضيفة باستخدام Lambda reserved concurrency، أو Cloud Run --max-instances و --concurrency، أو الحد الأقصى لعدد النسخ في Azure، بدلًا من اكتشاف الحد الأعلى في بيئة الإنتاج.

منظر علوي لمكتب من خشب البلوط عليه حاسوب محمول ودفتر وكوب شاي

النشر على AWS Lambda

إعداد Lambda Web Adapter

أخفّ طريقة تُبقي تطبيق Express الخاص بك كما هو عبر Lambda Web Adapter. بالنسبة إلى صورة حاوية، يتطلب ذلك سطرًا إضافيًا واحدًا:

FROM public.ecr.aws/docker/library/node:22-slim
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:1.1.0 /lambda-adapter /opt/extensions/lambda-adapter
ENV PORT=8080 AWS_LWA_INVOKE_MODE=response_stream AWS_LWA_READINESS_CHECK_PATH=/health
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY dist ./dist
CMD ["node", "dist/server.js"]

تفضّل حزم zip؟ أرفق طبقة المحوّل، واضبط AWS_LAMBDA_EXEC_WRAPPER على /opt/bootstrap، ووجّه المعالج إلى نص بدء تشغيل. يقرأ المحوّل المنفذ من AWS_LWA_PORT (ويعود إلى PORT، الافتراضي 8080)، ويفحص مسار الجاهزية قبل أن يمرر حركة المرور.

عنوان URL للدالة وبث الاستجابة

ضع Function URL في المقدمة، واضبط وضع الاستدعاء على RESPONSE_STREAM، بما يطابق متغير المحوّل أعلاه. يحتفظ الوضع المخزّن مؤقتًا الافتراضي بالاستجابة كاملةً حتى ينتهي إنجاز الأداة، وهذا يُبطل البث. يمنحك Lambda حتى 15 دقيقة لكل استدعاء، وحتى 10 غيغابايت من الذاكرة، وهو أكثر بكثير مما تحتاجه أداة البدء والتحقق.

توجد مساران للوصول:

  • AWS_IAM Function URL. يوقّع المستدعون الطلبات بـ SigV4. مناسب لحركة المرور بين الخدمات، لكنه مزعج لعملاء MCP على سطح المكتب.
  • NONE مع تحقق خاص بك. شغّل OAuth داخل الخادم أو ضع مفوّضًا أمامه. يُعد Cognito أو مفوّض Lambda عبر API Gateway الخيار المعتاد، لكن مهلة التكامل الافتراضية فيه تقارب 30 ثانية، لذا تُفضَّل Function URL مع المهام الطويلة.

يستطيع Serverless Framework الإصدار 4 توصيل هذا كله بعدد قليل من أسطر YAML:

mcp:
  servers:
    images:
      server: index.ts

💡 تشير تلك المقالة إلى نقطتين تستحقان الانتباه: يحتاج تسجيل الدخول التفاعلي عبر OAuth إلى نطاق مخصص في الجذر بدلًا من عنوان execute-api الافتراضي، وليس لدى Cognito تسجيل ديناميكي للعملاء.

ممر طويل من خزائن الخوادم في مركز بيانات، وفني يبتعد عنه

النشر على Azure Functions

ملف host.json المهم

تشغّل Azure خوادم مبنية بـ SDK بوصفها معالجات مخصصة: يستقبل مضيف Functions الطلب ويمرره إلى عمليتك. تقدم وثائق Microsoft للخوادم المستضافة ذاتيًا ملفًا أدنى كهذا لخادم TypeScript، ويعرضه دليل البدء السريع لـ Node في مشروع يعمل:

{
  "version": "2.0",
  "configurationProfile": "mcp-custom-handler",
  "customHandler": {
    "description": {
      "defaultExecutablePath": "npm",
      "arguments": ["run", "start"]
    },
    "port": "8080"
  }
}

يفعّل ملف التعريف mcp-custom-handler الوكالة عبر HTTP، ويوجّه كل مسار ({*route}) إلى خادمك، ويزيل بادئة المسار، فيصل /mcp دون تعديل. اجعل قيمة port مطابقة للمنفذ الذي يستمع إليه خادمك. اختبر محليًا باستخدام func start، لأن مصحح F5 غير مدعوم حتى الآن، ثم انشر باستخدام func azure functionapp publish <APP_NAME>.

حدود المعاينة وتسجيل الدخول عبر Entra

اقرأ الشروط الدقيقة قبل الالتزام: هذه الميزة في المعاينة العامة. تدعم خوادم streamable-http عديمة الحالة فقط، المكتوبة بحزم SDK الخاصة بـ Python وTypeScript وC# وJava، ويجب أن يعمل التطبيق على خطة Flex Consumption. إذا احتجت إلى حالة، توجّهك Microsoft إلى امتداد MCP الخاص بـ Functions بدلًا من ذلك. يستطيع Flex Consumption الإبقاء على نسخ جاهزة دائمًا لتقليل البدء البارد، مقابل دفع ثمن السعة الخاملة.

المصادقة هي نقطة تفوّق Azure. تنفّذ المصادقة المدمجة للخادم متطلبات تفويض MCP نيابةً عنك: إذ تُصدر تحدي 401، وتنشر وثيقة Protected Resource Metadata، وتوجّه العملاء إلى Microsoft Entra ID لتسجيل الدخول. يضبط host.json الموسّع في الوثائق defaultAuthorizationLevel على anonymous، ويترك تسجيل الدخول لطبقة المنصة، لذا فعّله قبل أن يصل الرابط إلى الجمهور.

يد تضغط كابل ألياف بصرية أصفر في مفتاح شبكة

النشر على Cloud Run

أمر واحد من المصدر

تحتاج Cloud Run إلى أقل قدر من الإجراءات. إذا كان لديك ملف Dockerfile أو مشروع Node في المجلد:

gcloud run deploy mcp-images --source . --region us-central1 \
  --set-secrets PICASSOIA_API_TOKEN=picassoia-token:latest \
  --max-instances 3

لديك صورة جاهزة؟ يؤدي gcloud run deploy --image IMAGE_URL --port PORT المهمة. تحقن Cloud Run القيمة PORT، ويجب أن يرتبط الخادم بـ 0.0.0.0، وهذا ما يفعله المعالج المشترك أصلًا. سطر المحوّل في Dockerfile من قسم Lambda ملف غير فعّال هنا، لذا يمكن لصورة واحدة أن تخدم المنصتين.

خاص افتراضيًا

يتطلب عنوان Cloud Run الجديد دور IAM باسم Cloud Run Invoker (roles/run.invoker) في كل طلب. للعميل المحلي، توصي وثائق Google بوكيل يحقن هويتك:

gcloud run services proxy mcp-images --region us-central1 --port=3000

ثم وجّه العميل إلى http://localhost:3000/mcp. يستطيع المستدعون الآليون إرسال رمز هوية OIDC بوصفه Authorization: Bearer <token>، مع ضبط الجمهور على عنوان run.app الخاص بالخدمة. ولدى المستدعين الذين يعملون على Cloud Run خيارات أكثر، منها الحاوية الجانبية والمصادقة القياسية بين الخدمات أو Cloud Service Mesh. أما الخادم العام الموجّه للمستهلكين فيحتاج إلى --allow-unauthenticated إضافةً إلى OAuth داخل تطبيقك، وهذا قرار يُتخذ عن قصد لا افتراضيًا.

النسخ الدافئة والمهلات

تتوسع Cloud Run إلى الصفر افتراضيًا. أضف --min-instances 1 إذا كان البدء البارد يؤذيك، واحسب تكلفة النسخة الخاملة. يمكن أن تستمر الطلبات حتى 60 دقيقة باستخدام --timeout (الافتراضي 5 دقائق)، وهو أطول سقف بين المنصات الثلاث، ولا يحتاج بث استجابات HTTP إلى مفتاح إضافي.

منظر من زاوية منخفضة لغيوم بيضاء فوق تل أخضر مع توربين رياح

مقارنة جنبًا إلى جنب

السؤالAWS LambdaAzure FunctionsCloud Run
التغليفصورة حاوية مع Web Adapter، أو zip مع طبقةمعالج مخصص مع host.jsonصورة حاوية أو نشر من المصدر
الخوادم ذات الحالةتجنّبهاغير مدعومة في المعاينة المستضافة ذاتيًاتجنّبها
أطول طلب15 دقيقةتحدده خطة Flex Consumption60 دقيقة
خيارات تسجيل الدخولFunction URL عبر IAM، أو Cognito، أو مفوّض Lambdaمصادقة مدمجة مع Entra IDدور Invoker أو رمز هوية OIDC
النسخ الدافئةالتزامن المخصصنسخ جاهزة دائمًا--min-instances
الحالة لخوادم MCP المستضافة ذاتيًايعمل عبر المحوّلمعاينة عامةمسار استضافة موثّق

أي منصة تناسب أي فريق؟

  • إذا كنت تعمل بالفعل على AWS مع حركة مرور متقلبة: Lambda. تدفع مقابل كل طلب، ولا تدفع شيئًا وأنت خامل.
  • فريق يعمل على Microsoft مع Entra ID: Azure Functions. تغنيك المصادقة المدمجة عن كتابة طبقة OAuth، بشرط أن تكون ميزة المعاينة مقبولة لديك.
  • فريق صغير مع استدعاءات أدوات طويلة: Cloud Run. أقل قدر من الإجراءات وأطول مهلة.

إذا لم تستطع الحسم، فابنِ صورة حاوية واحدة أولًا. تعمل كما هي على Cloud Run، وتعمل على Lambda عبر المحوّل، وتعمل الشيفرة نفسها خلف معالج Azure المخصص.

مهندسان يقارنان أوراقًا مطبوعة على طاولة خشبية عالية

اختبر نقطة النهاية قبل أن يختبرها العملاء

شغّل MCP Inspector باستخدام npx @modelcontextprotocol/inspector، واختر Streamable HTTP، والصق عنوان /mcp، ثم اعرض الأدوات. بعد ذلك نفّذ الاختبار الذي يتجاهله الناس: استدعِ العنوان دون بيانات اعتماد.

curl -i -X POST "$URL/mcp" -H "Content-Type: application/json" -d '{}'

تعني الاستجابة 401 أو 403 أن الباب الأمامي يصمد. أي استجابة أخرى تعني أن الطلب تجاوز مصادقتك، وسيدفع حسابك لدى مزوّد الخدمة تكلفة ما يفعله هذا المستدعي بعد ذلك.

3 أخطاء شائعة

  1. الربط بـ localhost. 127.0.0.1 يعمل على الحاسوب المحمول لكنه يفشل خلف كل منصة من هذه المنصات. اربط الخادم بـ 0.0.0.0.
  2. الاحتفاظ بالحالة في الذاكرة. عداد أو ذاكرة تخزين مؤقت تعيش داخل العملية تختفي عند البدء البارد التالي. استخدم مقابض صريحة أو مخزنًا خارجيًا.
  3. تخزين البث مؤقتًا. وضع الاستدعاء الافتراضي في Lambda مخزّن مؤقتًا، ويمكن لوكيل في الوسط أن يفعل الشيء نفسه. إذا وصلت رسائل التقدم دفعة واحدة، فابحث عن المخزن المؤقت.

لقطة مقرّبة جدًا لأصابع تكتب أثناء اختبار نقطة النهاية

اكتب وأنشئ الصور مع PicassoIA

المنصة نفسها التي تمنح خادمك شيئًا يستدعيه تستطيع أيضًا كتابة الشيفرة المحيطة به وإنشاء الصور لتوثيقه.

استخدم Claude Sonnet 5 على PicassoIA

يوصلك نموذج البرمجة من المقتطفات أعلاه إلى خادم يطابق أدواتك. يتعامل Claude Sonnet 5 مع مهام البرمجة متعددة الخطوات واستخدام الأدوات، ويقرأ الصور، لذا يمكن إدخال لقطة شاشة لنشر فاشل مباشرة في الطلب.

  1. افتح Claude Sonnet 5 على PicassoIA.
  2. الصق أمرًا نصيًا يذكر آلية النقل والأدوات والمنصة، مثلًا: "اكتب خادم MCP بلغة TypeScript يعمل بنقل Streamable HTTP عديم الحالة، مع أداتين هما start_job وget_job، جاهز لـ Cloud Run."
  3. املأ الأمر النظامي مرة واحدة حتى تلتزم كل إجابة بقواعدك: عديم الحالة، واربط بالعنوان 0.0.0.0، واقرأ PORT، ولا جلسات في الذاكرة.
  4. اختر مستوى الجهد الذي يناسب المهمة، باستخدام الجدول أدناه.
  5. اترك max_tokens على الافتراضي 8,192 للإجابات المكوّنة من ملف واحد، واطلب ملفًا واحدًا في كل مرة إذا قُطعت إجابة.
  6. أرفق صورة عندما تملك لقطة شاشة لسجل. يكون الإعداد max_image_resolution افتراضيًا 0.5 ميغابكسل، ويصغّرها قبل الإرسال.
المعاملالإعداد المقترحاستخدمه من أجل
effortlow (الافتراضي)تعديلات الإعداد وإصلاحات السطر الواحد
efforthigh أو maxتدفقات المصادقة والأخطاء التي تمس عدة ملفات
max_tokens8192 (الافتراضي)ملف واحد في كل رد
system_promptقواعد الاستضافة لديكمخرجات متسقة عبر المشروع
imageلقطة شاشة للخطأتصحيح سجلات النشر

للحصول على رأي ثانٍ في خطأ مصادقة معقد، شغّل الأمر نفسه عبر GPT 5.6 Sol وقارن الإجابتين.

مصمم عند مكتب عريض وأمامه شاشة تعرض صورة جبل

أنشئ صورك الخاصة

بعد أن يعمل الخادم، يحتاج إلى ترويسة README وخلفية للرسم التخطيطي وبطاقة للتواصل الاجتماعي. يحوّل PicassoIA Image أمرًا نصيًا بسيطًا إلى صورة كاملة خلال ثوانٍ، مع سبع نسب عرض إلى ارتفاع من 1:1 حتى 16:9، وقيمة بذرة قابلة للقفل لنتائج قابلة للتكرار، ومخرجات بصيغة JPG أو PNG أو WebP، وحتى نسختين بديلتين في كل تشغيل. يُوصف بأنه غير محدود، دون سقف لكل صورة، لذا يمكنك التكرار بحرية. وعندما تستحق صورة ثابتة أن تتحرك، يحوّلها PicassoIA Video إلى مقطع قصير.

جرّب هذا الأمر النصي: مكتب هادئ في مبنى مخصص للعمل عند الغسق، حاسوب محمول مفتوح على مكتب من البلوط، ضوء نافذة ناعم، صورة فوتوغرافية بعدسة 35 ملم، حبيبات فيلم. غيّر تفصيلًا واحدًا، واقفل البذرة، وأعد التوليد، ثم قارن بين الاثنين. افتح Picasso IA، وشغّل أول أمر نصي لديك، واطّلع على شكل صورتك القادمة. ستجد كل النماذج في picassoia.com/en/all-models، لذا فهناك الكثير لتجربته.

شخص عند طاولة قرب نافذة في مساحة عمل مشتركة هادئة عند الغسق

شارك هذا المقال

اختر لغتك

مقالات ذات صلة