‫Gemini Enterprise مع إمكانية الخروج من Agent Gateway إلى خادم MCP مخصّص خاص باستخدام Agent Registry

1. مقدمة

يستكشف هذا الدرس التطبيقي حول الترميز إمكانية الاتصال الخاص والمحكوم بحركة البيانات الصادرة من Gemini Enterprise باستخدام Agent Gateway في وضع agent-to-anywhere (حركة البيانات الصادرة). ستضبط تطبيق Gemini Enterprise لاستدعاء خادم بروتوكول Model Context (MCP) مخصّص مستضاف على Cloud Run بشكل آمن من خلال توجيه حركة البيانات عبر Agent Gateway باستخدام واجهات Private Service Connect (PSC) للاتصال بنقطة نهاية PSC لواجهات Google APIs في شبكة VPC.

في بيئات المؤسسات، يؤدي منح الوكلاء المستقلين إذن الوصول المباشر إلى الشبكة إلى خطر استخراج البيانات وتنفيذ الأدوات غير المختبَرة. توفر Agent Gateway نقطة تنفيذ مركزية على مستوى النظام الأساسي لنهج الثقة المعدومة، وتفحص بشكل ديناميكي حمولات أدوات HTTP MCP القابلة للبث. تتم مصادقة الطلبات الصادرة باستخدام هوية وكيل يمكن التحقّق منها بشكلٍ مشفّر، ويتم تفويضها من خلال Identity-Aware Proxy (IAP) باستخدام سياسات الوصول الموحّدة (UAP) في "إدارة الهوية والوصول" مع قواعد Common Expression Language (CEL). يتيح ذلك التحكّم الدقيق في الوصول إلى أدوات وطُرق MCP معيّنة بدون عرض أحمال العمل الخلفية على الإنترنت العام.

ما يمكنك إنشاؤه

  • تعمل Agent Gateway في وضع الخروج (agent-to-anywhere) مع التحقّق من نقطة نهاية Agent Registry
  • خدمة Cloud Run تستضيف خادم MCP خاصًا قابلاً للبث عبر HTTP ‏ (--ingress=internal) ومسجّلاً مع مواصفات الأداة في Agent Registry
  • إضافة تفويض Identity-Aware Proxy (IAP) إلى Agent Gateway
  • سياسات الوصول الموحّدة (UAP) في "إدارة الهوية وإمكانية الوصول" مع شروط CEL لتفويض أداة MCP
  • تطبيق Gemini Enterprise مرتبط بـ Agent Gateway ومتصل بمخزن بيانات خادم MCP مخصّص تم استيراده من Agent Registry
  • موارد شبكة السحابة الافتراضية الخاصة (VPC) ومنطقة نظام أسماء النطاقات (Cloud DNS) ونقطة نهاية Private Service Connect (PSC) لواجهات Google APIs
  • ربط شبكة Private Service Connect (PSC) بحركة البيانات الصادرة من شبكة VPC الخاصة ببوابة الوكيل
  • قواعد سياسات Cloud Next Generation Firewall (NGFW) لتأمين زيارات شبكة VPC

figure1

الشكل 1. بنية الدرس التطبيقي حول الترميز

ما ستتعلمه

  • كيفية نشر خادم MCP خاص قابل للبث عبر HTTP من المصدر على Cloud Run وتسجيل نقطة النهاية ومخطط الأداة في Agent Registry
  • كيفية إعداد Agent Gateway باستخدام إدخالات السجل المتوافقة وتوجيه طلبات أدوات تطبيق Gemini Enterprise من خلال البوابة
  • كيفية إنشاء خروج خاص من سحابة VPC باستخدام مرفقات وواجهات شبكة PSC
  • كيفية تفويض إذن الوصول إلى Agent Gateway إلى Identity-Aware Proxy (IAP)
  • كيفية إنشاء سياسات الوصول الموحّد (UAP) في "إدارة الهوية وإمكانية الوصول" وربطها باستخدام سمات destination.agent_registry.* وdestination.is_registered في لغة CEL لحظر تنفيذ أداة MCP
  • كيفية التحقّق من تنفيذ السياسات والخروج من الشبكة باستخدام Cloud Logging

ما تحتاج إليه

  • مشروع Google Cloud تم تفعيل الفوترة فيه
  • ترخيص Gemini Enterprise نشط أو فترة تجريبية لمدة 30 يومًا
  • أذونات "إدارة الهوية وإمكانية الوصول" لتوفير خدمات الشبكات وموارد Gemini Enterprise وAgent Platform
  • برنامج shell متوافق مع POSIX (bash أو zsh) مثبّت عليه Google Cloud CLI (gcloud) وcurl وjq

بهذا نكون قد انتهينا من الجزء التمهيدي، وسننتقل الآن إلى قسم المفاهيم.

2. المفاهيم

تسلسل النشر

ينشر هذا الدرس التطبيقي حول الترميز البنية الأساسية أولاً حتى تكون مسارات الشبكة الخاصة وعناصر التحكّم في الإدارة جاهزة للتشغيل قبل تسجيل أدوات MCP وربطها بـ Gemini Enterprise:

  1. البنية الأساسية للشبكة: يمكنك توفير الشبكات الفرعية للسحابة الافتراضية الخاصة (VPC) ونقطة نهاية Private Service Connect (PSC) ومرفق شبكة PSC وقواعد سياسة Cloud NGFW ومناطق Cloud DNS الخاصة.
  2. Agent Gateway: يمكنك نشر Agent Gateway في وضع الخروج مع دمج Agent Registry (registries) والخروج الخاص من شبكة VPC (networkAttachment).
  3. سياسات التفويض: يمكنك ضبط إضافة تفويض IAP وسياسة Gateway Authz وسياسة الوصول الموحّد (UAP) في "إدارة الهوية وإمكانية الوصول" باستخدام شرطَي destination.is_registered وdestination.agent_registry.* في لغة التعبير المشترك (CEL).
  4. نشر خادم MCP وتسجيله: يمكنك نشر خادم MCP الخاص بالرياضيات من المصدر إلى Cloud Run (--ingress=internal) وتسجيل مواصفات الخدمة والأداة (add وsubtract) في Agent Registry.
  5. تطبيق Gemini Enterprise: أنشئ تطبيق Gemini Enterprise (Engine)، واضبط إعدادات الهوية وإمكانية المراقبة، واربط حركة الخروج الصادرة ببوابة الوكيل (agentGatewaySetting).
  6. استيراد أداة ربط بيانات MCP مخصّصة: أنشئ أداة ربط البيانات REGISTRY_MCP وفعّلها (:setUpDataConnector) لربط مخزن البيانات الأساسي لخادم MCP المسجَّل بتطبيق Gemini Enterprise.
  7. التحقّق من الصحة: اختبِر عمليات تنفيذ الأدوات المسموح بها والمحظورة في المحادثة، وتأكَّد من تطبيق السياسة على سجلّات Agent Gateway وDNS وجدار الحماية وCloud Run.

نقل البيانات من Gemini Enterprise

يوجّه Gemini Enterprise طلبات أدوات خادم MCP المخصّصة إلى Agent Gateway عندما يتم ضبط كل من agentGatewaySetting على Engine وuse_agent_gateway_egress: true على DataConnector.

figure2

الشكل 2. بنية خروج البيانات في Gemini Enterprise

ينظّم تطبيق Gemini Enterprise عملية توجيه الأدوات في أربعة مجالات رئيسية:

  1. الأداة (default_search_widget_config):
    • تعرض واجهة عميل الويب. يتلقّى التطبيق المصغّر طلبات من المستخدم ويبدأ جلسات محادثة مع المحرّك الأساسي.
  2. Core Assistant (assistants/default_assistant/agents/default/core_assistant):
    • وكيل الاستدلال الحواري الأساسي ضمن المحرّك عند تقييم طلب بحث من مستخدم، يحدّد "المساعد الأساسي" ما إذا كان يجب إجراء عملية حسابية، ويفحص الأدوات المتاحة، ويفوّض التنفيذ إلى الوكيل الفرعي الذي تم إنشاؤه في "بوابة الوكيل".
  3. مخزن البيانات وأداة ربط البيانات:
    • ‫DataStore: يتم توفيرها داخل Collection مخصّص عند تشغيل :setUpDataConnector، وتربط (dataStoreIds) مخططات أداة "سجلّ الوكلاء" المستوردة (add وsubtract) وأنواع الوسيطات وتعليمات الوكيل بـ Engine في Gemini Enterprise.
    • DataConnector: يدير اتصال إجراء REGISTRY_MCP (createBapConnection: true) بخادم MCP البعيد (instance_uri)، ويحلّ مورد خادم MCP في Agent Registry (registry_mcp_server_name)، ويتيح خروج Agent Gateway (use_agent_gateway_egress: true).
  4. هوية الوكيل وسجلّ الوكلاء وبوابة الوكلاء:
    • عندما ترسل "أداة ربط البيانات" طلبًا إلى الأداة الخارجية، فإنّها توجّه الزيارات إلى البوابة المحدّدة في agentGatewaySetting. يُصدر Core Assistant رمزًا مميزًا للهوية SPIFFE يؤكّد هويته: principal://agents.global.org-.../agents/default/core_assistant.
    • تتكامل Agent Gateway مع Agent Registry باستخدام الحقل registries لحلّ نقاط نهاية الوجهة ومخططات الأدوات المسجّلة بشكل ديناميكي. يتم ملء السمتَين destination.is_registered وdestination.agent_registry.* وتمريرهما إلى الإصدار 2 من IAP لتقييمهما استنادًا إلى قواعد لغة التعبير المشترك (CEL) الخاصة بسياسة الوصول الموحّدة (UAP) في "إدارة الهوية وإمكانية الوصول" قبل السماح بالعبور إلى شبكة VPC.

الاتصال بشبكة VPC عبر البوابة

تتيح Agent Gateway الاتصال بشبكة VPC الخاصة باستخدام حقلَي YAML:

  • networkConfig.egress.networkAttachment: يوجّه حركة بيانات عناوين IP الخاصة ليتم توجيهها من خلال مرفق شبكة PSC إلى شبكة VPC.
  • dnsPeeringConfig.domains: مطابقة نظام أسماء النطاقات الخاص بالأجهزة المتصلة بشبكة VPC مع منطقة Cloud DNS، وبالتالي يتم ربط أسماء المضيفين المستهدَفة (*.run.app) بعنوان IP الخاص بنقطة نهاية PSC المحدّدة في شبكة VPC.

القيود والمتطلبات

بهذا نكون قد انتهينا من جزء المفاهيم... لننتقل الآن إلى قسم الإعداد.

3- الإعداد

أدوار "إدارة الهوية وإمكانية الوصول" المطلوبة

يجب أن تتوفّر الأدوار التالية لإكمال Codelab:

النطاق

أدوار "إدارة الهوية وإمكانية الوصول" المطلوبة

المشروع وإدارة الهوية وإمكانية الوصول

roles/orgpolicy.policyAdmin
roles/resourcemanager.projectIamAdmin
roles/iam.accessPolicyAdmin
roles/serviceusage.serviceUsageAdmin
roles/iam.serviceAccountUser

الشبكات والبوابة

roles/networkservices.admin
roles/networksecurity.admin
roles/serviceextensions.admin
roles/compute.networkAdmin
roles/dns.admin

‫Gemini Enterprise و"قاعدة بيانات المسجّلين"

‫roles/discoveryengine.admin
roles/agentregistry.admin (أو roles/apphub.admin)

أحمال العمل والبناء

roles/run.admin
roles/cloudbuild.builds.editor
roles/artifactregistry.writer
roles/storage.admin

إمكانية تتبُّع البيانات

roles/logging.viewer
roles/logging.logWriter

أو استخدِم دورًا أساسيًا واسع النطاق مثل roles/owner مع roles/orgpolicy.policyAdmin (لأنّ roles/owner وحده لا يمكنه تعديل سياسات المؤسسة).

الوصول إلى مشروعك

يستخدم هذا الدرس التطبيقي حول الترميز مشروعًا واحدًا على Google Cloud. تستخدم خطوات الضبط واجهة سطر الأوامر gcloud وأوامر shell في Linux.

ابدأ بالوصول إلى سطر الأوامر في مشروعك على Google Cloud:

ضبط رقم تعريف المشروع

gcloud config set project SET_YOUR_PROJECT_ID_HERE

مصادقة الجلسة

# login to gcloud cli
gcloud auth login
# login for gcloud api
gcloud auth application-default login

ضبط متغيرات بيئة shell

# set custom var for slug (eg, "foo") and region preference
export SLUG="foo"
export REGION="us-central1"

echo ${SLUG}
echo ${REGION}
# create project vars (automatic)
export PROJ_ID=$(gcloud config list --format="value(core.project)")
export PROJ_NO=$(gcloud projects describe ${PROJ_ID} --format="value(projectNumber)")
export ORG_ID=$(gcloud projects get-ancestors ${PROJ_ID} --format="value(id)" | tail -n 1)
export USER_IDENTITY=$(gcloud config get-value account)

echo ${PROJ_ID}
echo ${PROJ_NO}
echo ${ORG_ID}
echo ${USER_IDENTITY}
# create resource vars for agent platform (automatic)
export AGW_NAME="agw-${SLUG}-${REGION}-ata"
export AGW_URI="projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
export UAP_POLICY_NAME="uap-policy-${SLUG}"
export UAP_BINDING_NAME="uap-binding-${SLUG}"
export MCP_NAME="math-wizard"
export MCP_URL="https://${MCP_NAME}-${PROJ_NO}.${REGION}.run.app/mcp"

echo ${AGW_NAME}
echo ${AGW_URI}
echo ${UAP_POLICY_NAME}
echo ${UAP_BINDING_NAME}
echo ${MCP_NAME}
echo ${MCP_URL}
# create resource vars for gemini enterprise (automatic)
export GE_APP_DISPLAY_NAME="Codelab app"
export GE_APP_ORG_NAME="${SLUG}, Inc."
export GE_LOCATION="global"
export GE_APP_NAME="app-${SLUG}-${GE_LOCATION}"
export GE_APP_INIT="${GE_APP_NAME}_$(date +%s)"

echo ${GE_APP_DISPLAY_NAME}
echo ${GE_APP_ORG_NAME}
echo ${GE_LOCATION}
echo ${GE_APP_NAME}
echo ${GE_APP_INIT}

ضبط نطاقات موثوق بها لهوية الوكيل

يتحقّق بيان if-then-else مما إذا كان المشروع يتبع مؤسسة من أجل ضبط نطاق الثقة الصحيح لهويات الوكيل الأساسي.

# set var for trust domain
if [[ -n "${ORG_ID}" ]]; then
  export TRUST_DOMAIN="agents.global.org-${ORG_ID}.system.id.goog"
else
  export TRUST_DOMAIN="agents.global.proj-${PROJ_NO}.system.id.goog"
fi

echo "trust domain: ${TRUST_DOMAIN}"

ضبط مشروع الفوترة والحصة

# set cli quota project
gcloud config set billing/quota_project ${PROJ_ID}
# set api quota project
gcloud auth application-default set-quota-project ${PROJ_ID}

إنشاء دليل محلي لملفات الإعداد

# create config folder
mkdir -p cfg

في حال تنفيذ عملية تثبيت مُدارة ذاتيًا لحزمة تطوير البرامج (SDK) من Google Cloud (أي خارج Cloud Shell)، يجب تعديل المكوّنات إلى أحدث إصدار.

# update gcloud cli
gcloud components update

تفعيل خدمات واجهة برمجة التطبيقات

# enable google apis (part 1)
gcloud services enable \
  agentregistry.googleapis.com \
  agentidentity.googleapis.com \
  aiplatform.googleapis.com \
  apphub.googleapis.com \
  apptopology.googleapis.com \
  cloudapiregistry.googleapis.com \
  cloudtrace.googleapis.com \
  compute.googleapis.com \
  dataform.googleapis.com \
  iam.googleapis.com \
  iap.googleapis.com \
  logging.googleapis.com \
  modelarmor.googleapis.com \
  monitoring.googleapis.com \
  networksecurity.googleapis.com \
  networkservices.googleapis.com \
  notebooks.googleapis.com \
  observability.googleapis.com
# enable google apis (part 2)
gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  discoveryengine.googleapis.com \
  dns.googleapis.com \
  orgpolicy.googleapis.com \
  run.googleapis.com \
  saasservicemgmt.googleapis.com \
  securitycenter.googleapis.com \
  storage.googleapis.com \
  telemetry.googleapis.com \
  texttospeech.googleapis.com

سياسات المؤسسة

تفرض قيود سياسات المؤسسة المُدارة التلقائية في Google Cloud قيودًا على الميزات المستخدَمة في هذا الدرس العملي:

  • discoveryengine.managed.disableCustomMcpServerConnector:
    • تقييد إنشاء أدوات ربط البيانات التي تستخدم خادم MCP مخصّصًا (custom_mcp) كمصدر بيانات (يتم فرض هذا القيد تلقائيًا)
  • iam.managed.disableAccessPolicyBinding:
    • يحصر إلزامات سياسة الوصول في الإصدار 3 من "إدارة الهوية وإمكانية الوصول" على الموارد (يتم فرضها تلقائيًا).
  • discoveryengine.managed.allowedEgressFqdns:
    • يحظر نطاقات الخروج الصادرة (instance_uri أسماء النطاقات المؤهلة بالكامل) لموصلات البيانات عندما تكون عناصر التحكّم في خدمة سحابة VPC‏ (VPC-SC) نشطة أو عندما يكون المشروع مُدرَجًا في المَعلمة enforcedProjects الخاصة بالمؤسسة.
  • discoveryengine.managed.allowedDataSources:
    • يقيّد أنواع أدوات ربط البيانات المسموح بها (dataSource) عندما تكون خدمة VPC-SC نشطة أو عندما يكون المشروع مُدرَجًا في المَعلمة enforcedProjects الخاصة بالمؤسسة.

تجاوز أي قيود موروثة على مستوى المشروع في سياسة المؤسسة من خلال ضبط enforce: false بشكلٍ صريح.

إيقاف قيد MCP المخصّص

# disable data connector constraint (allow custom mcp servers)
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/discoveryengine.managed.disableCustomMcpServerConnector
spec:
  rules:
  - enforce: false
EOF
# verify org policy constraint on project
gcloud org-policies describe discoveryengine.managed.disableCustomMcpServerConnector \
  --project=${PROJ_ID} --effective

إيقاف قيد سياسة الوصول

# disable iam v3 constraint (allow v3 access policies)
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/iam.managed.disableAccessPolicyBinding
spec:
  rules:
  - enforce: false
EOF
# verify org policy constraint on project
gcloud org-policies describe iam.managed.disableAccessPolicyBinding \
  --project=${PROJ_ID} --effective

التحقّق من قيود أداة ربط البيانات الشرطية وإيقافها

بشكلٍ تلقائي، لا تحظر discoveryengine.managed.allowedEgressFqdns وdiscoveryengine.managed.allowedDataSources إنشاء الموصل إلا إذا كان مشروعك ضِمن محيط عناصر التحكّم في خدمة سحابة VPC‏ (VPC SC) أو إذا أضاف مشرف المؤسسة مشروعك إلى enforcedProjects.

أولاً، افحص السياسات السارية في مشروعك:

# check effective egress fqdn constraint on project
gcloud org-policies describe discoveryengine.managed.allowedEgressFqdns \
  --project=${PROJ_ID} --effective
# check effective data source constraint on project
gcloud org-policies describe discoveryengine.managed.allowedDataSources \
  --project=${PROJ_ID} --effective

~~IF~~ في حال فرض هذه القيود، ولضمان عدم حظر إعداد موصّل custom_mcp في شبكة VPC SC أو مؤسسة مقيّدة بالسياسات، اضبط enforce: false على كلتا السياسات لمشروعك:

# disable egress fqdn constraint on project
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/discoveryengine.managed.allowedEgressFqdns
spec:
  rules:
  - enforce: false
EOF
# disable allowed data sources constraint on project
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/discoveryengine.managed.allowedDataSources
spec:
  rules:
  - enforce: false
EOF
# verify both constraints are disabled on project
gcloud org-policies describe discoveryengine.managed.allowedEgressFqdns \
  --project=${PROJ_ID} --effective

gcloud org-policies describe discoveryengine.managed.allowedDataSources \
  --project=${PROJ_ID} --effective

أذونات "إدارة الهوية وإمكانية الوصول"

امنح أدوار IAM المطلوبة لحسابك وحساب الخدمة التلقائي في Compute Engine الذي تستخدمه Cloud Build:

  • حساب المستخدم (${USER_IDENTITY}):
    • يتطلّب أذونات لنشر خدمات Cloud Run واستدعائها (roles/run.admin وroles/run.invoker وroles/iam.serviceAccountUser) وإنشاء صور حاويات (roles/cloudbuild.builds.editor) وإدارة Gemini Enterprise (roles/discoveryengine.admin) وإنشاء "سياسات الوصول الموحّدة" (roles/iam.accessPolicyAdmin).
  • حساب الخدمة التلقائي في Compute Engine(${PROJ_NO}-compute@developer.gserviceaccount.com):
    • يتم استخدامها من قِبل Cloud Build لتنظيم الرمز المصدر في Cloud Storage (roles/storage.admin) وإرسال الصور إلى Artifact Registry (roles/artifactregistry.writer) وكتابة سجلات الإنشاء (roles/logging.logWriter).

نفِّذ الأوامر التالية لتعيين ربط الأدوار:

# grant roles to user account
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/run.admin"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/iam.serviceAccountUser"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/run.invoker"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/discoveryengine.admin"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/iam.accessPolicyAdmin"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/cloudbuild.builds.editor"
# grant roles to default compute (cloud build) service account
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com" \
  --role="roles/storage.admin"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com" \
  --role="roles/artifactregistry.writer"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com" \
  --role="roles/logging.logWriter"

التحقّق من أذونات "إدارة الهوية وإمكانية الوصول"

ابحث عن عمليات ربط الأدوار الستة (6) في حساب المستخدم.

# show iam policy on project for user account
gcloud projects get-iam-policy ${PROJ_ID} \
  --flatten="bindings[].members" \
  --filter="bindings.members:${USER_IDENTITY}" \
  --format="table(bindings.role:label=ROLE, bindings.members:label=PRINCIPAL_IDENTITY)"

ابحث عن عمليات ربط الأدوار الثلاث (3) في حساب خدمة Compute Engine التلقائي.

# show iam policy on project for default compute service account
gcloud projects get-iam-policy ${PROJ_ID} \
  --flatten="bindings[].members" \
  --filter="bindings.members:${PROJ_NO}-compute@developer.gserviceaccount.com" \
  --format="table(bindings.role:label=ROLE, bindings.members:label=PRINCIPAL_IDENTITY)"

التحقّق من عمليات ربط وكيل الخدمة (إجراء احترازي)

في مشروع جديد، يوفّر Google Cloud تلقائيًا وكيل خدمة Agent Gateway ويمنحه إذن roles/agentgateway.serviceAgent عند تفعيل networkservices.googleapis.com لأول مرة. إذا كنت تعيد استخدام مشروع حالي ربما أدت عملية التنظيف السابقة فيه إلى إزالة عمليات الربط التلقائية لوكيل الخدمة، نفِّذ الأوامر التالية كإجراء احتياطي لضمان بقاء ربط الهوية والدور سليمًا:

# ensure network services service account has been created
gcloud beta services identity create \
  --service=networkservices.googleapis.com \
  --project="${PROJ_ID}"

# ensure network services service account has service agent roles applied
gcloud projects add-iam-policy-binding "${PROJ_ID}" \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-agentgateway.iam.gserviceaccount.com" \
  --role="roles/agentgateway.serviceAgent"

بهذا نكون قد انتهينا من جزء الإعداد... لننتقل الآن إلى قسم الشبكة.

4. الشبكة

في هذا القسم، ستنشئ شبكة VPC باستخدام الوضع المخصّص مع شبكة فرعية مخصّصة /28 (192.168.10.0/28) تتيح ربط الشبكة في Private Service Connect (PSC) لحركة البيانات الصادرة من Agent Gateway إلى شبكة VPC.

يتم نشر نقطة نهاية PSC لواجهات Google APIs باستخدام /32عنوان IPv4 داخلي عالمي واحد (172.16.20.20) لإتاحة الوصول الداخلي الخاص إلى واجهات Google APIs وخدماتها. في هذا الدرس التطبيقي حول الترميز، يستهدف Agent Gateway خدمة Cloud Run باستخدام نقطة نهاية PSC من خلال حلّ نطاق run.app. عن طريق ربط Cloud DNS.

إنشاء شبكات

أنشئ شبكة VPC عالمية.

# create vpc network
gcloud compute networks create vnet-${SLUG} --subnet-mode=custom

أنشئ شبكات فرعية لربط شبكة PSC بـ Agent Gateway:

# create subnet for agent gateway psc na
gcloud compute networks subnets create subnet-${REGION}-agw \
  --network=vnet-${SLUG} \
  --range=192.168.10.0/28 \
  --region=${REGION} \
  --enable-private-ip-google-access

إنشاء قواعد جدار الحماية

أنشئ سياسة جدار حماية للسماح بجميع زيارات الخروج مع تفعيل التسجيل. سيتم استخدام هذا الإعداد لمراقبة عدد الزيارات الخارجة من Agent Gateway إلى شبكة السحابة الخاصة الافتراضية (VPC). تتيح خدمة Cloud NGFW كلاً من مستويَي Essentials وStandard لأمان الشبكة ومراقبة حركة البيانات.

# create fw policy
gcloud compute network-firewall-policies create fw-policy-${SLUG} --global
# create fw policy rule
gcloud compute network-firewall-policies rules create 1001 \
  --description="allow all out and log" \
  --firewall-policy=fw-policy-${SLUG} \
  --global-firewall-policy \
  --action=allow \
  --direction=EGRESS \
  --layer4-configs=all \
  --dest-ip-ranges=0.0.0.0/0 \
  --enable-logging
# bind fw policy to network
gcloud compute network-firewall-policies associations create \
  --name=fw-policy-bind-${SLUG} \
  --firewall-policy=fw-policy-${SLUG} \
  --network=vnet-${SLUG} \
  --global-firewall-policy

إنشاء مرفق شبكة PSC

أنشئ مرفق شبكة Private Service Connect (PSC) تم ضبطه على قبول الاتصالات تلقائيًا من Agent Gateway. يُنشئ مرفق الشبكة جانب شبكة VPC المستهلك من الاتصال للربط بأمان مع جانب المنتج في Agent Gateway لحركة بيانات الخروج الصادرة. للحصول على معلومات إضافية حول متطلبات الشبكة الفرعية ومواصفات نطاق عناوين IP، يُرجى الاطّلاع على ضبط إعدادات الاتصال بشبكة VPC.

# create psc network attachment
gcloud compute network-attachments create psc-na-${REGION}-agw \
  --region=${REGION} \
  --subnets=subnet-${REGION}-agw \
  --connection-preference=ACCEPT_AUTOMATIC

تأكيد ربط شبكة PSC

# show psc network attachment details
gcloud compute network-attachments describe psc-na-${REGION}-agw --region=${REGION}

استرداد معرّف الموارد المنتظم (URI) لملحق شبكة PSC وتخزينه في متغيّر البيئة PSC_NA_URI سيتم الرجوع إلى معرّف الموارد المنتظم (URI) هذا في إعدادات "بوابة الوكيل" (networkConfig.egress.networkAttachment) لتوفير واجهة PSC لحركة البيانات الصادرة إلى شبكة VPC:

# fetch psc network attachment uri
export PSC_NA_URI=$(gcloud compute network-attachments describe psc-na-${REGION}-agw \
  --region=${REGION} \
  --format="value(selfLink.scope(v1))")
echo ${PSC_NA_URI}

إنشاء نقطة نهاية PSC

يتم استخدام نقطة نهاية Private Service Connect (PSC) لواجهات Google APIs من أجل Agent Gateway لإنشاء اتصال خاص بخادم MCP في Cloud Run عبر مسار شبكة داخلية بدون عرض حركة البيانات على الإنترنت المتاح للجميع. ستؤدي طلبات الأدوات الصادرة التي تخرج من Agent Gateway إلى شبكة VPC إلى حلّ عنوان URL لخدمة Cloud Run المستهدَفة (*.run.app) إلى عنوان IP لنقطة النهاية الخاصة هذه.

احجز عنوان IPv4 داخليًا عالميًا لنقطة نهاية PSC. يجب أن يكون عنوان IP الذي تم اختياره عنوان /32 لا يتداخل مع أي شبكات فرعية حالية في شبكة VPC:

# set env var for psc ep ip address
export PSC_EP_IP="172.16.20.20"
echo ${PSC_EP_IP}
# reserve internal global ipv4 address
gcloud compute addresses create ip-psc2gapis \
  --global \
  --purpose=PRIVATE_SERVICE_CONNECT \
  --addresses=${PSC_EP_IP} \
  --network=vnet-${SLUG}

أنشئ نقطة نهاية Private Service Connect لواجهات Google APIs باستخدام حزمة all-apis التي تتضمّن Cloud Run (run.app).

# create psc endpoint for google apis
gcloud compute forwarding-rules create psc2gapis \
  --global \
  --network=vnet-${SLUG} \
  --address=ip-psc2gapis \
  --target-google-apis-bundle=all-apis

نقطة نهاية تأكيد الهوية من خلال PSC

# show psc endpoint details
gcloud compute forwarding-rules describe psc2gapis --global

إنشاء منطقة نظام أسماء النطاقات وسجلات

يتم استخدام Cloud DNS لتمكين Agent Gateway من التواصل بشكل خاص مع خادم MCP المستضاف على Cloud Run. عندما يقيّم Agent Gateway طلبات الأدوات الصادرة التي تستهدف Cloud Run، يستخدم تبادل معلومات بين الشبكات عبر نظام أسماء النطاقات (dnsPeeringConfig.domains) لحلّ طلبات البحث لنظام أسماء النطاقات في *.run.app باستخدام منطقة نظام أسماء النطاقات الخاصة في Cloud DNS المرتبطة بشبكة السحابة الإلكترونية الخاصة الافتراضية (VPC). يعرض سجلّ نظام أسماء النطاقات الخاص طلب البحث مع عنوان IP الداخلي لنقطة نهاية Private Service Connect (172.16.20.20)، ما يسمح بتوجيه طلبات أداة MCP من خلال مسار شبكة خاصة.

أنشئ منطقة مُدارة خاصة في Cloud DNS للنطاق run.app.:

# create private dns zone
gcloud dns managed-zones create priv-zone-run \
  --description="private zone for run.app" \
  --dns-name="run.app." \
  --visibility=private \
  --networks=vnet-${SLUG}

أنشئ سجلّ نظام أسماء نطاقات (DNS) A حرف بدل للنطاق *.run.app. يشير إلى عنوان IP لنقطة نهاية PSC:

# create dns record
gcloud dns record-sets create "*.run.app." \
  --zone=priv-zone-run \
  --type=A \
  --ttl=300 \
  --rrdatas=${PSC_EP_IP}

أنشئ سياسة Cloud DNS لتفعيل تسجيل طلبات البحث في نظام أسماء النطاقات. تسجّل عملية تسجيل نظام أسماء النطاقات طلبات تحليل النطاقات الواردة من Agent Gateway ضِمن شبكة VPC، ما يوفّر إمكانية التدقيق ويسمح لك بالتأكّد من أنّ طلبات الأداة *.run.app يتم تحليلها بشكل صحيح إلى نقطة نهاية PSC الداخلية:

# create dns policy (logging)
gcloud dns policies create dns-policy-${SLUG} \
  --description="dns logging for vnet-${SLUG}" \
  --networks=vnet-${SLUG} \
  --enable-logging

بهذا نكون قد انتهينا من جزء الشبكة... ننتقل الآن إلى قسم بوابة الوكيل.

5- Agent Gateway

تحدّد Agent Gateway registries لمثيلات Agent Registry إلى جانب الحقول networkConfig التي تضبط إعدادات ربط شبكة PSC وإعدادات تبادل المعلومات بين نظام أسماء النطاقات للاتصال الخاص بشبكة VPC:

  • registries: يربط البوابة بما يصل إلى مثيلَين من Agent Registry: مثيل محلي (../locations/${REGION}) ومثيل عالمي (../locations/global). يؤدي ذلك إلى دمج Agent Gateway مع Agent Registry لحل عمليات النشر المحلية (مثل خوادم Cloud Run MCP في ${REGION}) والموارد العالمية (مثل وكلاء Gemini Enterprise ونقاط النهاية العالمية) لفرض سياسة IAP v2 الدقيقة. تحظى الإدخالات الإقليمية بالأولوية على الإدخالات العالمية عند تحديد عناوين URL للوجهات.
  • networkAttachment: يشير إلى مرفق شبكة PSC (psc-na-${REGION}-agw)، ويربط Agent Gateway بشبكة VPC لإتاحة الخروج الخاص.
  • dnsPeeringConfig.domains: يضبط run.app. لكي تستخدم طلبات البحث عن نظام أسماء النطاقات الواردة من Agent Gateway لخدمات Cloud Run ربط نظام أسماء النطاقات من أجل مطابقة أسماء المضيفين مع عنوان IP لنقطة نهاية PSC الخاصة بواجهات Google API (172.16.20.20) التي تم ضبطها في منطقة Cloud DNS الخاصة.

نشر Agent Gateway

أنشئ ملف إعداد Agent Gateway واستورِده.

# create agent gateway config file
cat > cfg/${AGW_NAME}-networkConfig.yaml << EOF
name: ${AGW_NAME}
protocols:
  - MCP
googleManaged:
  governedAccessPath: AGENT_TO_ANYWHERE
registries:
  - "//agentregistry.googleapis.com/projects/${PROJ_ID}/locations/${REGION}"
networkConfig:
  egress:
    networkAttachment: ${PSC_NA_URI}
  dnsPeeringConfig:
    domains:
      - run.app.
    targetProject: ${PROJ_ID}
    targetNetwork: projects/${PROJ_ID}/global/networks/vnet-${SLUG}
EOF
# import agent gateway config file (create gateway)
gcloud network-services agent-gateways import ${AGW_NAME} \
  --source="cfg/${AGW_NAME}-networkConfig.yaml" \
  --location=${REGION}

تأكيد نشر Agent Gateway

تأكَّد من سجلّ الوكيل وإعدادات الشبكة:

# show agent gateway registries and network config
gcloud network-services agent-gateways describe ${AGW_NAME} \
  --location=${REGION} \
  --format="yaml(registries,networkConfig)"

الناتج المتوقّع:

networkConfig:
  dnsPeeringConfig:
    domains:
    - run.app.
    targetNetwork: projects/${PROJ_ID}/global/networks/vnet-${SLUG}
    targetProject: ${PROJ_ID}
  egress:
    networkAttachment: projects/${PROJ_ID}/regions/${REGION}/networkAttachments/psc-na-${REGION}-agw
registries:
- //agentregistry.googleapis.com/projects/${PROJ_ID}/locations/${REGION}

تأكَّد من أنّ الناتج يعرض تفاصيل الإعداد المطلوبة:

  • registries: تعرض هذه السمة معرّف الموارد المنتظم (URI) الإقليمي (${REGION}) الخاص بـ "سجلّ الوكلاء" والمرتبط بالبوابة.
  • استبدِل egress.networkAttachment بما يلي: يحدّد معرّف الموارد المنتظم (URI) لربط شبكة PSC بخروج شبكة VPC.
  • dnsPeeringConfig.domains: يحتوي على run.app. يشير إلى targetNetwork لحلّ النطاق الخاص.

افحص مرفق شبكة PSC للتأكّد من اتصال البوابة:

# show psc network attachment details
gcloud compute network-attachments describe psc-na-${REGION}-agw \
  --region=${REGION} \
  --format="yaml(connectionEndpoints)"

تأكَّد من توفّر نقطة نهاية اتصال مقبولة:

connectionEndpoints:
- ipAddress: 192.168.10.2
  projectIdOrNum: '<AGW_TENANT_PROJ_NO>'
  status: ACCEPTED
  subnetwork: https://www.googleapis.com/compute/v1/projects/${PROJ_ID}/regions/${REGION}/subnetworks/subnet-${REGION}-agw

تفويض الإذن

تؤمّن Agent Gateway حركة بيانات الأدوات الصادرة وتتحكّم فيها باستخدام سياسات التفويض (networksecurity.authzPolicies) المدمجة مع سياسات الوصول الموحّدة (UAP) في Identity-Aware Proxy (IAP).

على الرغم من أنّ Agent Gateway يتيح استخدام قواعد ALLOW وDENY الأساسية المضمّنة، تتطلّب بيئات المؤسسات حوكمة مركزية تستند إلى الهوية. باستخدام "سياسات الوصول الموحَّدة" في "إدارة الهوية وإمكانية الوصول" (أو سياسات الوصول)، يمكنك إدارة قواعد الوصول إلى الخارج باستخدام سياسات الوصول العادية في الإصدار 3 من "إدارة الهوية وإمكانية الوصول".

figure3

الشكل 3. بنية التفويض

تربط عملية التفويض ثلاثة مكوّنات:

  1. سياسة تفويض البوابة (authzPolicy):
    • مورد إقليمي يستهدف Agent Gateway
    • تم إعدادها باستخدام policyProfile: REQUEST_AUTHZ وaction: CUSTOM لتوجيه جميع عمليات التحقّق من التفويض الصادر إلى إضافة IAP Authz.
  2. إضافة خدمة داخل التطبيق (authzExtension):
    • مورد إقليمي يفوّض عملية منح الإذن بالطلبات إلى خدمة Identity-Aware Proxy (iap.googleapis.com).
    • تقيّم السياسات في وضع ENFORCE باستخدام إصدار السياسة V2.
  3. سياسة الوصول الموحّد والربط في "إدارة الهوية وإمكانية الوصول" (accessPolicy وpolicyBinding):
    • موارد الإصدار 3 من "إدارة الهوية وإمكانية الوصول" العامة التي تحتوي على قواعد وصول دقيقة
    • تتم مصادقة هوية SPIFFE الأساسية للوكيل الذي يجري الاتصال، والتحقّق من إذن iap.googleapis.com/resources.egressViaIAP الشامل، وتقييم شروط "لغة التعبير الشائعة" (CEL) مقابل سمات الوجهة.

نشر إضافة التفويض

أنشئ إعدادات service-extensions لإضافة التفويض التي تفوّض قرارات التفويض إلى خدمة "الشراء داخل التطبيق":

# create authz extension config file
cat > cfg/${AGW_NAME}-svc-ext-authz-iap.yaml << EOF
name: ${AGW_NAME}-svc-ext-authz-iap
service: iap.googleapis.com
failOpen: false
timeout: 1s
metadata:
  iapPolicyVersion: "V2"
EOF
# import iap authz extension (create authz extension)
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-iap \
  --source=cfg/${AGW_NAME}-svc-ext-authz-iap.yaml \
  --location=${REGION}

التحقّق من تمديد التفويض

تحقَّق من أنّ إضافة التفويض نشطة:

# list authz extensions
gcloud service-extensions authz-extensions list \
  --location=${REGION} \
  --format="table(
    name.basename():label=NAME,
    createTime.date(tz=LOCAL):label=CREATED,
    updateTime.date(tz=LOCAL):label=MODIFIED,
    service:label=SERVICE,
    metadata:label=METADATA,
    timeout:label=TIMEOUT
  )"

نشر سياسة التفويض

أنشئ إعدادات سياسة تفويض network-security تستهدف Agent Gateway وتفوّض عملية التحقّق من الطلبات إلى إضافة التفويض في IAP:

# create authz policy config file
cat > cfg/${AGW_NAME}-authz-policy-iap.yaml << EOF
name: ${AGW_NAME}-authz-policy-iap
target:
  resources:
    - "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
policyProfile: REQUEST_AUTHZ
action: CUSTOM
customProvider:
  authzExtension:
    resources:
      - "projects/${PROJ_ID}/locations/${REGION}/authzExtensions/${AGW_NAME}-svc-ext-authz-iap"
EOF
# import authz policy config file (create authz policy)
gcloud network-security authz-policies import ${AGW_NAME}-authz-policy-iap \
  --source=cfg/${AGW_NAME}-authz-policy-iap.yaml \
  --location=${REGION}

التحقّق من سياسة التفويض

تحقَّق من أنّ سياسة التفويض نشطة:

# list authz policies
gcloud network-security authz-policies list \
  --location=${REGION} \
  --format="table(
    name.basename():label=NAME,
    action:label=ACTION,
    customProvider.list().sub('\W.*', ''):label=CUSTOM_PROVIDER_TYPE,
    policyProfile:label=POLICY_PROFILE,
    customProvider.authzExtension.resources[0].basename():label=CUSTOM_PROVIDER_RESOURCE
  )"

إنشاء سياسات وصول في "إدارة الهوية وإمكانية الوصول"

يُفوض Agent Gateway الآن عمليات التحقّق من التفويض إلى IAP ويحلّ البيانات الوصفية للوجهة من Agent Registry. بعد ذلك، حدِّد قاعدة سياسة الوصول الموحَّدة في "إدارة الهوية وإمكانية الوصول" للتحكّم في تنفيذ الأدوات الصادرة.

يقيّم IAP تعبيرات سمات CEL مقابل سمات الوجهة التالية في "سجلّ الوكلاء":

  • حالة التسجيل (destination.is_registered):
    • قيمة منطقية (true/false) تشير إلى ما إذا كان قد تم تصنيف الوجهة في Agent Registry.
  • اسم خادم MCP (destination.agent_registry.mcp_server.name):
    • اسم مورد خادم MCP المتعارف عليه المسجَّل في Agent Registry
  • طريقة MCP (destination.agent_registry.mcp_server.method):
    • طريقة MCP التي يتم استدعاؤها (مثل tools/call أو tools/list أو initialize)
  • اسم الأداة (destination.agent_registry.mcp_server.tool.name):
    • اسم الأداة المحدّدة التي تم استدعاؤها (مثل subtract أو add)، ما يتيح الحصول على إذن دقيق على مستوى الأداة على خوادم MCP المسجَّلة.

تحديد قاعدة سياسة الوصول في "إدارة الهوية وإمكانية الوصول"

يحدّد بيان قاعدة سياسة "إدارة الهوية وإمكانية الوصول" ما يلي:

  • الجهات الرئيسية: هوية الجهة الرئيسية في SPIFFE التي تمثّل وكيل المساعد الأساسي في Gemini Enterprise.
  • الأذونات: إذن iap.googleapis.com/resources.egressViaIAP الشامل المطلوب لجميع زيارات الخروج التي تحكمها ميزة "حماية الهوية" (IAP).
  • الشروط: تعبير CEL (destination.is_registered == true) يضمن ألا يتمكّن الوكيل من استدعاء نقاط النهاية المدرَجة في "سجلّ الوكلاء" فقط.

أنشئ ملف بيان قاعدة السياسة:

# create access policy rule file
cat > cfg/${UAP_POLICY_NAME}-rules.json << EOF
[
  {
    "description": "allow ge assistant to any registered service",
    "effect": "ALLOW",
    "principals": [
      "principal://${TRUST_DOMAIN}/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_INIT}/assistants/default_assistant/agents/default/core_assistant"
    ],
    "operation": {
      "permissions": [
        "iap.googleapis.com/resources.egressViaIAP"
      ]
    },
    "conditions": {
      "iap.googleapis.com": {
        "expression": \
        "destination.is_registered == true"
      }
    }
  }
]
EOF

نشر سياسة الوصول إلى "إدارة الهوية وإمكانية الوصول"

أنشئ سياسة الوصول العامة لإدارة الهوية وإمكانية الوصول باستخدام القواعد المحدّدة في ملف البيان:

# create iam access policy
gcloud iam access-policies create ${UAP_POLICY_NAME} \
  --details-rules=cfg/${UAP_POLICY_NAME}-rules.json \
  --project=${PROJ_ID} \
  --location=global

التحقّق من سياسة الوصول في "إدارة الهوية وإمكانية الوصول"

تأكَّد من إنشاء سياسة الوصول إلى "إدارة الهوية وإمكانية الوصول" بنجاح، وافحص تفاصيل القاعدة:

# show iam access policy details
gcloud iam access-policies describe ${UAP_POLICY_NAME} \
  --project=${PROJ_ID} \
  --location=global

الناتج المتوقّع:

details:
  rules:
  - conditions:
      iap.googleapis.com:
        expression: destination.is_registered == true
    description: allow ge assistant to any registered service
    effect: ALLOW
    operation:
      permissions:
      - iap.googleapis.com/resources.egressViaIAP
    principals:
    - principal://agents.global.org-${ORG_ID}.system.id.goog/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_INIT}/assistants/default_assistant/agents/default/core_assistant
name: projects/${PROJ_ID}/locations/global/accessPolicies/${UAP_POLICY_NAME}

ربط سياسة الوصول في "إدارة الهوية وإمكانية الوصول" بالمشروع

لتفعيل التنفيذ في جميع "بوابات الوكيل" في مشروعك، أنشئ ربط سياسة يربط سياسة الوصول إلى "إدارة الهوية وإمكانية الوصول" بمورد المشروع:

# bind iam access policy to project resource
gcloud iam policy-bindings create ${UAP_BINDING_NAME} \
  --policy="projects/${PROJ_ID}/locations/global/accessPolicies/${UAP_POLICY_NAME}" \
  --target-resource="//cloudresourcemanager.googleapis.com/projects/${PROJ_ID}" \
  --project=${PROJ_ID} \
  --location=global

التحقّق من ربط سياسة الوصول في "إدارة الهوية وإمكانية الوصول"

تحقَّق من نقاط ربط السياسة النشطة بالسياسة والهدف الصحيحَين:

# show policy binding details
gcloud iam policy-bindings describe ${UAP_BINDING_NAME} \
  --project=${PROJ_ID} \
  --location=global

الناتج المتوقّع:

name: projects/${PROJ_ID}/locations/global/policyBindings/${UAP_BINDING_NAME}
policy: projects/${PROJ_ID}/locations/global/accessPolicies/${UAP_POLICY_NAME}
policyKind: ACCESS
target:
  resource: //cloudresourcemanager.googleapis.com/projects/${PROJ_ID}

بهذا نكون قد انتهينا من جزء "بوابة الوكيل"، وسننتقل الآن إلى قسم خادم MCP.

6. خادم MCP

في هذا القسم، ستنشئ خادم FastMCP مخصّصًا يعرض أدوات add وsubtract، وستنشره على Cloud Run مباشرةً من المصدر. أثناء نشر المصدر (--source)، ستحزّم خدمة Cloud Build صورة الحاوية باستخدام Dockerfile وuv المضمّنتَين (اللتان تثبّتان التبعيات المحدّدة في pyproject.toml وتطلقان server.py).

بعد نشر خدمة Cloud Run، عليك تسجيل خادم MCP في Agent Registry مع مواصفات أدواته (toolspec.json) ليتمكّن Gemini Enterprise من العثور على أدواته واستخدامها.

إنشاء تطبيق خادم MCP

أنشئ دليل مشروع math-wizard للرمز البرمجي للتطبيق:

# create directory for code
mkdir -p math-wizard

اكتب ملف بيان مشروع Python:

# create python project manifest file
cat > math-wizard/pyproject.toml << 'EOF'
[project]
name = "math-wizard"
version = "0.1.0"
description = "math wizard mcp server"
requires-python = ">=3.12"
dependencies = [
    "fastmcp==2.13.1",
]
EOF

يتم تضمين بعض وظائف القياس الإضافية في الرمز البرمجي لتسجيل عناوين HTTP الواردة (mcp-session-id وx-forwarded-for وuser-agent وx-cloud-trace-context) من أجل التحقّق من صحة Cloud Logging وCloud Trace.

اكتب ملف الرمز البرمجي للتطبيق:

# create mcp server application code
cat > math-wizard/server.py << 'EOF'
import asyncio
import json
import logging
import os
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_http_headers
from mcp.types import ToolAnnotations

logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)

mcp = FastMCP("math wizard mcp server")

def log_network_context(tool_name: str, a: int, b: int) -> None:
    headers = get_http_headers()
    print(json.dumps({
        "severity": "INFO",
        "message": f">>> 🛠️ Tool: '{tool_name}' called with numbers '{a}' and '{b}'",
        "tool": tool_name,
        "mcp_session_id": headers.get("mcp-session-id"),
        "x_forwarded_for": headers.get("x-forwarded-for"),
        "user_agent": headers.get("user-agent"),
        "trace_header": headers.get("x-cloud-trace-context"),
    }), flush=True)

@mcp.tool(
    annotations=ToolAnnotations(
        readOnlyHint=True,
    )
)
def add(a: int, b: int) -> int:
    """Use this to add two numbers together.

    Args:
        a: The first number.
        b: The second number.

    Returns:
        The sum of the two numbers.
    """
    logger.info(f">>> 🛠️ Tool: 'add' called with numbers '{a}' and '{b}'")
    log_network_context("add", a, b)
    return a + b

@mcp.tool(
    annotations=ToolAnnotations(
        readOnlyHint=True,
    )
)
def subtract(a: int, b: int) -> int:
    """Use this to subtract two numbers.

    Args:
        a: The first number.
        b: The second number.

    Returns:
        The difference of the two numbers.
    """
    logger.info(f">>> 🛠️ Tool: 'subtract' called with numbers '{a}' and '{b}'")
    log_network_context("subtract", a, b)
    return a - b

if __name__ == "__main__":
    logger.info(f"🚀 MCP server started on port {os.getenv('PORT', 8080)}")
    asyncio.run(
        mcp.run_async(
            transport="streamable-http",
            host="0.0.0.0",
            port=int(os.getenv("PORT", 8080)),
        )
    )
EOF

اكتب Dockerfile لتحديد تعليمات إنشاء صورة الحاوية وأوامر بدء التشغيل:

# create dockerfile
cat > math-wizard/Dockerfile << 'EOF'
# use official python 3.12 image
FROM python:3.12-slim

# install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# install the project into /app
COPY . /app
WORKDIR /app

# allow statements and log messages to immediately appear in the logs
ENV PYTHONUNBUFFERED=1

# install dependencies
RUN uv sync

EXPOSE 8080

# run the mcp server
CMD ["uv", "run", "server.py"]
EOF

نشر الخدمة على Cloud Run

يمكنك نشر خادم MCP من المصدر باستخدام Cloud Build (الذي يستخدم حساب خدمة الحوسبة التلقائي للمشروع ${PROJ_NO}-compute@developer.gserviceaccount.com):

# deploy cloud run service
gcloud run deploy ${MCP_NAME} \
  --source math-wizard \
  --region=${REGION} \
  --no-invoker-iam-check \
  --ingress=internal \
  --quiet

التحقّق من عملية النشر على Cloud Run

تحقَّق من تفاصيل خدمة Cloud Run للتأكّد من إعدادها النشط:

# show cloud run service details
gcloud run services describe ${MCP_NAME} --region=${REGION}

الناتج المتوقّع:

<snip>
✔ Service math-wizard in region ${REGION}

URL:     https://math-wizard-${PROJ_NO}.${REGION}.run.app
Ingress: internal
Traffic:
  100% LATEST (currently math-wizard-00001-<id>)
</snip>

تسجيل خادم MCP في Agent Registry

للسماح لـ Gemini Enterprise باكتشاف الأدوات المتاحة على خادم MCP، يجب تقديم ملف مواصفات الأداة (toolspec.json) أثناء التسجيل في Agent Registry.

إنشاء مواصفات أداة MCP

# create tool spec file
cat > cfg/toolspec.json << 'EOF'
{
  "tools": [
    {
      "name": "add",
      "description": "Use this to add two numbers together.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "a": { "type": "integer", "description": "The first number." },
          "b": { "type": "integer", "description": "The second number." }
        },
        "required": ["a", "b"]
      },
      "isReadOnly": true,
      "isDestructive": false,
      "isIdempotent": true,
      "isOpenWorld": false
    },
    {
      "name": "subtract",
      "description": "Use this to subtract two numbers.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "a": { "type": "integer", "description": "The first number." },
          "b": { "type": "integer", "description": "The second number." }
        },
        "required": ["a", "b"]
      },
      "isReadOnly": true,
      "isDestructive": false,
      "isIdempotent": true,
      "isOpenWorld": false
    }
  ]
}
EOF

تسجيل خادم MCP في Agent Registry

# register mcp server in agent registry
gcloud agent-registry services create ${MCP_NAME} \
  --project=${PROJ_ID} \
  --location=${REGION} \
  --display-name="${MCP_NAME}-${PROJ_NO}.${REGION}.run.app" \
  --description="MANDATORY MATH & ARITHMETIC AGENT: You MUST ALWAYS invoke \
this tool for ANY mathematical calculation, addition (+), subtraction (-), \
sum, difference, or arithmetic question (including simple questions like \
'what is 67 + 345?'). NEVER compute arithmetic yourself and NEVER transfer \
math queries to file_and_coding_agent / code interpreter. Always delegate \
every math question to this tool." \
  --mcp-server-spec-type=tool-spec \
  --mcp-server-spec-content=cfg/toolspec.json \
  --interfaces=protocolBinding=JSONRPC,url="${MCP_URL}"

التحقّق من خادم MCP في Agent Registry

تأكَّد من أنّ خدمة Cloud Run التي تم نشرها مُدرَجة كخادم MCP مسجَّل في المنطقة مع عنوان URL لنقطة النهاية والأدوات المتاحة:

# list registered mcp servers in agent registry
gcloud agent-registry mcp-servers list \
  --location=${REGION} \
  --project=${PROJ_ID} \
  --format="table(
    name.basename():label=REGISTRY_ID,
    displayName:label=DISPLAY_NAME,
    interfaces[0].url:label=ENDPOINT_URL,
    tools[].name.list():label=TOOLS
  )"

الناتج المتوقّع:

REGISTRY_ID                                         DISPLAY_NAME                                  ENDPOINT_URL                                              TOOLS
agentregistry-00000000-0000-0000-0012-3456789abcde  math-wizard-${PROJ_NO}.${REGION}.run.app      https://math-wizard-${PROJ_NO}.${REGION}.run.app/mcp      add,subtract

اطّلِع على مواصفات إعداد الخدمة للتأكّد من أنّها تسجّل تعريفات الأدوات ومخططات الإدخال وتصنيفات السلوك لكل أداة:

# describe mcp server tool specs
gcloud agent-registry services describe ${MCP_NAME} \
  --location=${REGION} \
  --project=${PROJ_ID} \
  --format="yaml(mcpServerSpec.content.tools)"

بهذا نكون قد انتهينا من جزء خادم MCP... لننتقل الآن إلى قسم Gemini Enterprise.

7. Gemini Enterprise

في هذا القسم، ستنشئ تطبيق Gemini Enterprise ومورد مخزن بيانات خادم MCP مخصّص مرتبطًا به، ثم ستضبط إعداداتهما.

نموذج موارد Discovery Engine

تطبيق Gemini Enterprise (يتم تمثيله كمورد Engine في Discovery Engine API) هو طبقة التنسيق المركزية وواجهة المحادثة للمستخدمين النهائيين. تدير هذه الخدمة جلسات المحادثات مع المستخدمين، وتستند إلى نماذج الذكاء الاصطناعي التوليدي في بيانات المؤسسة، وتنسّق تنفيذ الأدوات الديناميكية.

تتفاعل تطبيقات Gemini Enterprise مع البيانات والأنظمة من خلال مخازن البيانات:

  • مخازن بيانات المعرفة: يمكنك استيعاب المحتوى الثابت وفهرسته (مثل Cloud Storage وGoogle Drive وBigQuery) من أجل إنشاء المحتوى باستخدام أسلوب الاسترجاع المعزّز (RAG).
  • موصلات البيانات (مقدّمو الإجراءات): يمكنك الربط بواجهات برمجة تطبيقات ديناميكية تابعة لجهات خارجية أو مخصّصة. يعرض مخزن بيانات خادم MCP مخصّص الأدوات المحدّدة بموجب "بروتوكول سياق النموذج" (MCP)، ما يتيح للنموذج استدعاء وظائف خارجية بشكل ديناميكي أثناء المحادثة.

توجيه حركة الخروج من خلال Agent Gateway

بشكلٍ تلقائي، يوجّه Gemini Enterprise حركة بيانات تنفيذ الموصلات والأدوات عبر الشبكات العامة. ومع ذلك، بالنسبة إلى مهام العمل الخاصة بشبكة VPC الخاصة وإدارة الثقة المعدومة، يمكن ضبط المحرك لتوجيه حركة البيانات الصادرة من خلال Agent Gateway:

  • عند إنشاء مخزن بيانات خادم MCP مخصّص في وقت لاحق من هذا المختبر، عليك تفعيل توجيه الخروج من خلال Agent Gateway في إعدادات مخزن البيانات.
  • يؤدي ذلك إلى ربط طلبات الأدوات الصادرة من المحرك ببوابة الوكيل الإقليمية، ما يضمن أن تحمل جميع طلبات بروتوكول سياق النموذج (MCP) Agent Identity للتطبيق، وأن تخضع لعملية تفويض وقت التشغيل باستخدام سياسات الوصول الموحّدة (UAP) في شراء داخل التطبيق (IAP) وإدارة الهوية وإمكانية الوصول (IAM)، وأن تنتقل عبر مرفق شبكة PSC إلى سحابة VPC الخاصة بك.

إنشاء تطبيق Gemini Enterprise

تستخدم الطريقة التالية واجهة برمجة التطبيقات discoveryengine.googleapis.com لإنشاء موارد تطبيق Gemini Enterprise وإعداداته. لإعداد التطبيق باستخدام واجهة مستخدم Google Cloud Console، يُرجى الاطّلاع على إنشاء تطبيق للحصول على التعليمات.

# create engine (ge app)
curl -s -X POST "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines?engineId=${GE_APP_INIT}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "displayName": "${GE_APP_DISPLAY_NAME}",
  "dataStoreIds": [],
  "solutionType": "SOLUTION_TYPE_SEARCH",
  "industryVertical": "GENERIC",
  "appType": "APP_TYPE_INTRANET",
  "searchEngineConfig": {
    "searchTier": "SEARCH_TIER_ENTERPRISE",
    "searchAddOns": [
      "SEARCH_ADD_ON_LLM"
    ]
  },
  "commonConfig": {
    "companyName": "${GE_APP_ORG_NAME}"
  }
}
EOF

تأكيد إنشاء التطبيق

# fetch engine (ge app) id
export GE_APP_ID=$(curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq -r --arg name "${GE_APP_DISPLAY_NAME}" '.engines[] | select(.displayName==$name) | .name | split("/") | last')

echo "engine (ge app) id: ${GE_APP_ID}"

اطّلِع على تفاصيل المحرّك للاطّلاع على الإعداد الذي تم إنشاؤه:

# get engine (ge app) details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

يُرجى ملاحظة الخصائص التالية التي يملأها الخادم في استجابة JSON:

  • استبدِل name بمسار المورد الأساسي (projects/${PROJ_NO}/locations/global/collections/default_collection/engines/${GE_APP_ID}).
  • sessionConfig.sessionManagementPolicy: القيمة التلقائية هي "VERTEX_AI_MANAGED"، التي تحتفظ بحالة المحادثات المترابطة واستدعاء الأدوات في "منصة الوكيل" (المعروفة سابقًا باسم Vertex AI).
  • observabilityConfig.observabilityEnabled: القيمة التلقائية هي true للمقاييس الأساسية (يتم تفعيل تسجيل الطلبات التفصيلية وحِزم بيانات الأدوات في خطوة لاحقة).

تفعيل موفِّر الهوية

فعِّل "هوية Google" كموفِّر هوية لمصادقة المستخدمين النهائيين على تطبيق Gemini Enterprise.

تستخدِم الطريقة التالية واجهة برمجة التطبيقات discoveryengine.googleapis.com لإعداد موفِّر هوية تطبيق Gemini Enterprise. لضبط الإعدادات باستخدام واجهة مستخدم Google Cloud Console، يُرجى الاطّلاع على ضبط موفّر الهوية للحصول على التعليمات.

# set identity provider
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/aclConfig" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "idpConfig": {
    "idpType": "GSUITE"
  }
}
EOF

التحقّق من موفِّر الهوية

# show identity provider
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/aclConfig" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

يتوافق الناتج "idpType": "GSUITE" مع موفِّر الهوية في Google.

(اختياري) تفعيل ترخيص تجريبي لـ Gemini Enterprise

إذا كنت تستخدم مشروعًا تمّ تعيين تراخيص Gemini Enterprise له، يمكنك تخطّي هذه الخطوة. إذا كنت تستخدم مشروعًا جديدًا بدون ترخيص، يمكنك المتابعة واتّباع هذه الخطوات.

أنشئ موردًا لإعدادات الترخيص لمنح مقاعد مستخدمي Gemini Enterprise لمدة 30 يومًا. سيؤدي ذلك إلى ضبط الترخيص التلقائي على الفترة التجريبية الجديدة، وبالتالي سيتم منح أي مستخدم يسجّل الدخول مقعدًا تلقائيًا:

# configure free trial subscription
curl -s -X POST "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/licenseConfigs?licenseConfigId=free_trial_gemini" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "subscriptionTier": "SUBSCRIPTION_TIER_SEARCH_AND_ASSISTANT",
  "freeTrial": true
}
EOF

التأكّد من تطبيق الترخيص

# show license config
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/licenseConfigs/free_trial_gemini" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

ابحث عن "subscriptionTerm": "SUBSCRIPTION_TERM_ONE_MONTH" و"freeTrial": true.

# verify auto-registration enabled on default user store
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/userStores/default_user_store" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

ابحث عن ../free_trial_gemini" و"enableLicenseAutoRegister": true.

تفعيل إعدادات إمكانية تتبّع البيانات

يتيح لك تفعيل إمكانية المراقبة على مستوى تطبيق (محرك) Gemini Enterprise الاطّلاع على تفاعلات المساعد الأساسي مع بيانات المقاييس في "مستكشف المقاييس" وربط عمليات التتبُّع الشاملة في Cloud Trace.

# set observability on engine (ge app)
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}?updateMask=observabilityConfig" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "observabilityConfig": {
    "observabilityEnabled": true,
    "sensitiveLoggingEnabled": true
  }
}
EOF

التحقّق من إعدادات إمكانية المراقبة

# verify observability is enabled on engine (ge app)
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq '{observabilityConfig: .observabilityConfig}'

ابحث عن "sensitiveLoggingEnabled": true.

الربط بـ Agent Gateway

يؤدي توجيه الزيارات الصادرة من Gemini Enterprise من خلال Agent Gateway إلى إنشاء حدود مركزية لإدارة الأمان والتحكّم فيه بدون ثقة لجميع عمليات استدعاء أدوات وكلاء الذكاء الاصطناعي:

  • فرض السياسات بشكل مركزي: تعمل Agent Gateway كخادم وكيل مضمّن يقيّم طلبات الأدوات الصادرة وفقًا لسياسات الأذونات وعناصر التحكّم في الحوكمة قبل أن تغادر الزيارات بيئة الوكيل.
  • حركة البيانات الصادرة من الشبكة الخاصة: يضمن ربط Gemini Enterprise بـ Agent Gateway توجيه طلبات الأدوات التي تستهدف خوادم MCP الخاصة على Cloud Run بأمان من خلال Private Service Connect (PSC)، ما يؤدي إلى تجاوز الإنترنت العام.
  • إمكانية التدقيق الموحّدة: توفّر هذه الميزة تسجيل الطلبات عن بُعد بشكل مركزي، بالإضافة إلى بيانات القياس عن بُعد وسجلات التدقيق على جميع خوادم MCP والأدوات الخارجية المرتبطة.

من خلال إعداد agentGatewaySetting في تطبيق Gemini Enterprise، يتم تلقائيًا توجيه المكالمات الصادرة من الأدوات والوكلاء التي بدأها المستخدمون النهائيون (مثل المكالمات إلى خوادم MCP المخصّصة التي تم استيرادها من Agent Registry ووكلاء A2A) عبر Agent Gateway.

يجب تصحيح المحرّك agentGatewaySetting لتفعيل ما يلي:

# bind engine (ge app) to agent gateway
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}?updateMask=agentGatewaySetting.defaultEgressAgentGateway.name" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "agentGatewaySetting": {
    "defaultEgressAgentGateway": {
      "name": "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
    }
  }
}
EOF

التحقّق من ربط Agent Gateway

استرداد إعدادات التطبيق لتأكيد ربط agentGatewaySetting:

# verify engine (ge app) agent gateway configuration
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq '{name: .name, displayName: .displayName, agentGatewaySetting: .agentGatewaySetting}'

الناتج المتوقّع:

{
  "name": "projects/${PROJ_NO}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}",
  "displayName": "${GE_APP_DISPLAY_NAME}",
  "agentGatewaySetting": {
    "defaultEgressAgentGateway": {
      "name": "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
    }
  }
}

إنشاء مستودع بيانات مخصّص لخادم MCP

في هذا القسم، ستربط خادم MCP بـ Gemini Enterprise من خلال إنشاء مخزن بيانات MCP مخصّص.

باستخدام Discovery Engine API، تتألف العملية من خطوتَين:

  1. إنشاء (:setUpDataConnector): ينشئ هذا الإجراء مورد Collection مخصّصًا (${MCP_NAME}-%timestamp-collection)، ويربط DataConnector (custom_mcp)، ويوفر DataStore (..._mcp_data) الأساسي.
  2. التفعيل (PATCH .../dataConnector?updateMask=actionConfig): يفعّل وقت تشغيل إجراء الموصل (actionState: "ACTIVE") باستخدام مواصفات أداة "سجلّ الوكلاء" ويربط DataStore (dataStoreIds) بـ Engine في Gemini Enterprise.
# fetch mcp server agent registry resource name
export MCP_REGISTRY_URI=$(gcloud agent-registry mcp-servers list \
  --location=${REGION} \
  --project=${PROJ_ID} \
  --filter="displayName:${MCP_NAME}" \
  --format="value(name)")

echo "mcp registry name: ${MCP_REGISTRY_URI}"
echo "mcp url: ${MCP_URL}"

إنشاء أداة ربط البيانات

# create custom mcp data connector from agent registry and link to engine
curl -s -X POST "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}:setUpDataConnector" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "collectionId": "${MCP_NAME}-$(date +%s)-collection",
  "collectionDisplayName": "${MCP_NAME}-collection",
  "dataConnector": {
    "dataSource": "custom_mcp",
    "dataSourceVersion": 1,
    "params": {
      "oauth_access_token": "unused"
    },
    "refreshInterval": "86400s",
    "entities": [
      {
        "entityName": "mcp_data"
      }
    ],
    "connectorModes": [
      "FEDERATED"
    ],
    "actionConfig": {
      "isActionConfigured": true,
      "createBapConnection": true,
      "actionParams": {
        "auth_type": "NO_AUTH",
        "instance_uri": "${MCP_URL}",
        "mcp_server_source": "REGISTRY_MCP",
        "registry_mcp_server_name": "${MCP_REGISTRY_URI}",
        "mcp_agent_instructions": "MANDATORY MATH & ARITHMETIC AGENT: Always invoke this tool for any mathematical calculation, addition (+), subtraction (-), sum, or difference.",
        "use_agent_gateway_egress": true,
        "agent_gateway_engine": "projects/${PROJ_ID}/locations/global/collections/default_collection/engines/${GE_APP_ID}"
      }
    }
  }
}
EOF

التحقّق من إنشاء أداة ربط البيانات

# fetch collection id
export GE_COLLECTION_ID=$(curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq -r --arg dname "${MCP_NAME}-collection" '.collections[] | select(.displayName == $dname) | .name | split("/") | last' | head -n 1)

echo "ge collection id: ${GE_COLLECTION_ID}"

تأكَّد من أنّ الحقل "registry_mcp_server_name" يتضمّن المعرّف الفريد العالمي (UUID) لخادم MCP في Agent Registry:

# show data connector details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/${GE_COLLECTION_ID}/dataConnector" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq '{name, state, actionState, connectorModes, bapConfig, registry_mcp_server_name: .actionConfig.actionParams.registry_mcp_server_name}'

عرض إدخال سجلّ خادم MCP في واجهة مستخدم Google Cloud Console:

echo "mcp server registry page url: https://console.cloud.google.com/agent-platform/agent-registry/mcp-servers/${REGION}/${MCP_REGISTRY_URI##*/}/overview?project=${PROJ_ID}"

تفعيل أداة ربط البيانات

# activate and bind data connector
curl -s -X PATCH "https://discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/global/collections/${GE_COLLECTION_ID}/dataConnector?updateMask=actionConfig" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "name": "projects/${PROJ_ID}/locations/global/collections/${GE_COLLECTION_ID}/dataConnector",
  "actionConfig": {
    "isActionConfigured": true,
    "createBapConnection": true,
    "actionParams": {
      "auth_type": "NO_AUTH",
      "instance_uri": "${MCP_URL}",
      "mcp_server_source": "REGISTRY_MCP",
      "registry_mcp_server_name": "${MCP_REGISTRY_URI}",
      "mcp_agent_instructions": "MANDATORY MATH & ARITHMETIC AGENT: Always invoke this tool for any mathematical calculation, addition (+), subtraction (-), sum, or difference.",
      "use_agent_gateway_egress": true,
      "agent_gateway_engine": "projects/${PROJ_ID}/locations/global/collections/default_collection/engines/${GE_APP_ID}"
    }
  }
}
EOF

التحقّق من عمليات ربط خادم MCP المخصّصة

# show engine (ge app) details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq '{name: .name, dataStoreIds: .dataStoreIds, agentGatewaySetting: .agentGatewaySetting}'

ابحث عن مستودع البيانات المرتبط "dataStoreIds": "collection-math-wizard-_mcp_data".

# show collection details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq --arg app "${GE_APP_ID}" '.collections[] | select(.dataConnector.actionConfig.actionParams.agent_gateway_engine // "" | endswith($app)) | .dataConnector | {name: .name, state: .state, actionState: .actionState, connectorModes: .connectorModes, actionParams: .actionConfig.actionParams}'

ابحث عن "state": "ACTIVE" مع ملء جميع المَعلمات.

إجراءات الأداة

عند فحص مستودع بيانات math-wizard-collection في لوحة بيانات Gemini Enterprise، ستلاحظ أنّه لا يتم استخدام علامة التبويب الإجراءات وأنّ الزر ↻ إعادة تحميل الإجراءات المخصّصة غير مفعّل. هذا السلوك متوقّع.

عرض صفحة تفاصيل مستودع البيانات في واجهة مستخدم Google Cloud Console:

echo "data store details page url: https://console.cloud.google.com/gemini-enterprise/locations/${GE_LOCATION}/collections/${GE_COLLECTION_ID}/connector/details?project=${PROJ_ID}"

استنادًا إلى طريقة ربط خادم MCP مخصّص بـ Gemini Enterprise، يتم التعامل مع اكتشاف الأدوات وإدارتها بإحدى الطريقتَين التاليتَين:

  • بروتوكول سياق النموذج (MCP) المخصّص المباشر (سير عمل BYO_MCP): عند إعداد خادم MCP مخصّص مباشرةً داخل Gemini Enterprise بدون Agent Registry، يدير مخزن البيانات نفسه قائمة الأدوات (connectorModes: ["FEDERATED", "ACTIONS"]). عليك فتح علامة التبويب الإجراءات والنقر على ↻ إعادة تحميل الإجراءات المخصّصة لجلب مخطط tools/list، ثم تفعيل الأدوات الفردية (add وsubtract) أو إيقافها يدويًا في واجهة المستخدم.
  • استيراد Agent Registry (REGISTRY_MCP سير العمل المستخدَم في هذا الدرس التطبيقي حول الترميز): عند استيراد خادم MCP من Agent Registry، يعمل Agent Registry كمصدر موثوق للحصول على معلومات دقيقة حول نقطة نهاية MCP وبياناتها الوصفية الخاصة بالواجهة وقائمة الأدوات (connectorModes: ["FEDERATED"]). تفعّل Gemini Enterprise تلقائيًا أدوات MCP المسجّلة في وقت التشغيل من خلال Agent Gateway في المحرّك بدون الحاجة إلى إعادة تحميل الإجراءات أو تبديلها يدويًا في واجهة مستخدم مخزن البيانات.

بهذا نكون قد انتهينا من جزء تطبيق Gemini Enterprise... لننتقل الآن إلى قسم التحقّق من الصحة.

8. التحقق من الصحة

في هذا القسم، ستفعّل طلبات مباشرة لأدوات MCP من تطبيق Gemini Enterprise على الويب وتتتبّع مسار الطلب على مستوى Agent Gateway وCloud DNS وجدار الحماية لشبكة VPC وسجلات Cloud Run. بعد ذلك، عليك تشديد سياسة الوصول الموحّد في "إدارة الهوية وإمكانية الوصول" للسماح بـ subtract مع حظر add، والتحقّق من تنفيذ الثقة المعدومة عند البوابة.

دخول المستخدم

أنشئ عنوان URL لتطبيق Gemini Enterprise على الويب:

# fetch app user url
export GE_WIDGET_ID=$(curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}/widgetConfigs/default_search_widget_config" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  -H "Content-Type: application/json" \
  | jq -r '.configId')

export GE_APP_USER_URL="https://vertexaisearch.cloud.google.com/home/cid/${GE_WIDGET_ID}"

echo "app user url: ${GE_APP_USER_URL}"

اتّبِع الرابط لفتح واجهة محادثة تطبيق Gemini Enterprise للويب في المتصفّح، ثم انقر على البدء.

اختبار طلبات الوكيل في المحادثة

في واجهة مستخدم المحادثة، تأكَّد من تفعيل math-wizard-collection أداة ربط البيانات من خلال النقر على رمز قطعة الألغاز أدوات الربط في أسفل مربّع المحادثة. سيظهر لك زر تبديل يكون مفعّلاً (ملوّنًا).

جرِّب طلبات البحث الاختبارية التالية:

what is 2342345 - 98234798324?
what is 72347234 + 234234?

تأكَّد من أنّ المساعد يعرض الإجابات الصحيحة وشارة اقتباس الإجراء التفاعلية (مثل Math Calculation (8s) 🤖 Agentgateway Agent) أسفل كل ردّ، ما يؤكّد تنفيذ الأداة.

فحص السجلات في Cloud Logging

تأكَّد من أنّ Gemini Enterprise قد وجّه طلبات الأدوات من خلال Agent Gateway وشبكة VPC الخاصة عن طريق فحص السجلات في Cloud Logging.

1. التحقّق من تفويض Agent Gateway وIAP

تأكَّد من أنّ Agent Gateway اعترض الطلب، وحلّ الهدف في Agent Registry، وفوض IAP بمنح الإذن، وسمح باستدعاء الأداة:

# show agent gateway logs
gcloud logging read 'resource.type="networkservices.googleapis.com/Gateway"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="table( \
    timestamp.date(tz=LOCAL):label=TIMESTAMP, \
    httpRequest.status:label=STATUS, \
    httpRequest.serverIp:label=SERVER_IP, \
    jsonPayload.agentGatewayInfo.mcpInfo.method:label=MCP_METHOD, \
    jsonPayload.agentGatewayInfo.mcpInfo.parameter:label=TOOL, \
    jsonPayload.authzPolicyInfo.result:label=AUTHZ, \
    jsonPayload.agentGatewayInfo.agentRegistryResource.basename():label=REGISTRY_MCP
  )"

تأكَّد من أنّ الناتج يحتوي على ما يلي:

  • STATUS: 200 (التنفيذ الناجح) و202 (notifications/initialized المصافحة).
  • SERVER_IP: عنوان IP لنقطة نهاية PSC في Google APIs (172.16.20.20:443)
  • ‫MCP_METHOD وTOOL: تسلسل بروتوكول MCP (notifications/initialized وtools/list وtools/call مع add أو subtract)
  • استبدِل AUTHZ بما يلي: ALLOWED (يُسمح بالخروج من خلال تفويض IAP).
  • ‫REGISTRY_MCP: رقم تعريف مورد "سجلّ الوكلاء" الذي تمّت تسويته (agentregistry-...).

2. التحقّق من عبور نظام أسماء النطاقات وجدار الحماية

تأكَّد من أنّ خدمة Cloud DNS قد حلّت اسم المضيف إلى نقطة نهاية PSC وأنّ جدار الحماية سمح بالزيارات من واجهة Agent Gateway:

# show dns logs
gcloud logging read 'resource.type="dns_query"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="table( \
    timestamp.date(tz=LOCAL):label=TIMESTAMP, \
    jsonPayload.queryName:label=QUERY_NAME, \
    jsonPayload.queryType:label=TYPE, \
    jsonPayload.responseCode:label=RCODE, \
    jsonPayload.rdata:label=RDATA
  )"
# show firewall logs
gcloud logging read 'logName:"compute.googleapis.com%2Ffirewall"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="table( \
    timestamp.date(tz=LOCAL):label=TIMESTAMP, \
    jsonPayload.connection.src_ip:label=SRC_IP, \
    jsonPayload.connection.dest_ip:label=DEST_IP, \
    jsonPayload.connection.dest_port:label=PORT, \
    jsonPayload.rule_details.reference.basename():label=RULE, \
    jsonPayload.disposition:label=DISPOSITION
  )"

تحقَّق من القيم التالية:

  • نظام أسماء النطاقات QUERY_NAME وRDATA: يحوّل math-wizard-...run.app. (سجلّ A، NOERROR) إلى 172.16.20.20.
  • جدار الحماية SRC_IP وDEST_IP: من 192.168.10.2 (عنوان IP لواجهة Agent Gateway PSC) إلى 172.16.20.20:443
  • جدار الحماية RULE وDISPOSITION: تمّت مطابقة firewallPolicy:fw-policy-... مع ALLOWED.

3- التحقّق من تنفيذ أداة Cloud Run

تأكَّد من أنّ حاوية Cloud Run تلقّت طلب استدعاء الأداة وعالجته:

# show cloud run logs
gcloud logging read 'resource.type="cloud_run_revision"
  AND textPayload:"Tool:"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="value(timestamp.date(tz=LOCAL), textPayload)"

تأكَّد من أنّ textPayload يعرض إدخالات تنفيذ الأداة (مثل >>> 🛠️ Tool: 'subtract' called with numbers '[x]' and '[y]').

اختبار فرض سياسة الحدّ الأدنى من الأذونات المميّزة

في سياسة الوصول الأولية في "إدارة الهوية وإمكانية الوصول"، كان يُسمح بأي طريقة أو أداة طالما تم تسجيل الوجهة (destination.is_registered == true). في هذه الخطوة، عدِّل السياسة لفرض مبدأ الحدّ الأدنى من الامتيازات من خلال السماح بأداة subtract فقط مع حظر add.

تعديل سياسة الوصول في "إدارة الهوية وإمكانية الوصول"

عند حظر تنفيذ أداة MCP، استخدِم نمطًا من قاعدتَين:

  1. القاعدة 1 (اكتشاف بروتوكول سياق النموذج (MCP) والمصافحة): تسمح بطُرق دورة حياة بروتوكول سياق النموذج (MCP) غير المرتبطة باستدعاء الأدوات (destination.is_registered == true وdestination.agent_registry.mcp_server.method != 'tools/call'). بما أنّ Gemini Enterprise يتفاوض على إعداد البث واكتشافه (initialize وnotifications/initialized وtools/list) قبل استدعاء أداة، وبما أنّه لا تتم تعبئة destination.agent_registry.mcp_server.tool.name إلا أثناء tools/call، فإنّ القاعدة 1 ضرورية للحفاظ على عمل تهيئة الجلسة واكتشاف الفهرس.
  2. القاعدة 2 (قيود على مستوى الأداة): تقيّد تنفيذ tools/call بحيث لا يُسمح إلا باستخدام الأداة subtract (destination.is_registered == true وdestination.agent_registry.mcp_server.method == 'tools/call' وdestination.agent_registry.mcp_server.tool.name == 'subtract').

عدِّل ملف البيان الخاص بقاعدة سياسة الوصول باستخدام كلتا القاعدتين:

# create access policy rule file (update: allow subtract only)
cat > cfg/${UAP_POLICY_NAME}-rule-update.json << EOF
[
  {
    "description": "allow ge assistant to any registered endpoint to perform mcp discovery and handshake",
    "effect": "ALLOW",
    "principals": [
      "principal://${TRUST_DOMAIN}/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_ID}/assistants/default_assistant/agents/default/core_assistant"
    ],
    "operation": {
      "permissions": [
        "iap.googleapis.com/resources.egressViaIAP"
      ]
    },
    "conditions": {
      "iap.googleapis.com": {
        "expression": \
        "destination.is_registered == true && \
         destination.agent_registry.mcp_server.method != 'tools/call'"
      }
    }
  },
  {
    "description": "allow ge assistant to any registered mcp server with tool call subtract",
    "effect": "ALLOW",
    "principals": [
      "principal://${TRUST_DOMAIN}/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_ID}/assistants/default_assistant/agents/default/core_assistant"
    ],
    "operation": {
      "permissions": [
        "iap.googleapis.com/resources.egressViaIAP"
      ]
    },
    "conditions": {
      "iap.googleapis.com": {
        "expression": \
        "destination.is_registered == true && \
         destination.agent_registry.mcp_server.method == 'tools/call' && \
         destination.agent_registry.mcp_server.tool.name == 'subtract'"
      }
    }
  }
]
EOF

طبِّق القواعد المعدَّلة على سياسة الوصول في "إدارة الهوية وإمكانية الوصول" (IAM):

# update iam access policy
gcloud iam access-policies update ${UAP_POLICY_NAME} \
  --details-rules=cfg/${UAP_POLICY_NAME}-rule-update.json \
  --project=${PROJ_ID} \
  --location=global

التحقّق من سياسة الوصول في "إدارة الهوية وإمكانية الوصول"

تأكَّد من تطبيق سياسة الوصول الجديدة في "إدارة الهوية وإمكانية الوصول" والسماح باستخدام أداة الطرح فقط:

# show iam access policy details
gcloud iam access-policies describe ${UAP_POLICY_NAME} \
  --project=${PROJ_ID} \
  --location=global \
  --flatten="details.rules[]" \
  --format="table( \
    details.rules.principals[0].scope(engines).sub('assistants/default_assistant/agents/default', '...'):label=PRINCIPAL, \
    details.rules.effect:label=EFFECT, \
    details.rules.conditions.'iap.googleapis.com'.expression.sub('\s*&&\s*', '\n&& ').sub('\s*\|\|\s*', '\n|| '):label=EXPRESSION
  )"

اختبار طلب أداة محظور

ارجع إلى واجهة مستخدم المحادثة في تطبيق Gemini Enterprise للويب وجرِّب طلب اختبار آخر:

what is 100 plus 20?

يحاول المساعد استدعاء add، ولكن يقيّم كلّ من Agent Gateway وIAP شرط سياسة إدارة الهوية وإمكانية الوصول على أنّه false ويرفضان طلب الخروج مع HTTP 403 Forbidden. في واجهة مستخدم المحادثة، ستلاحظ أنّ "المساعد" يعرض Calculate Sum ويدور على 🤖 Agentgateway Agent ... Working on it. أثناء إعادة محاولة تنفيذ طلب الأداة المحظور. هذا السلوك متوقّع. ويؤكّد أنّ Agent Gateway وIAP يعترضان بنشاط تنفيذ الأدوات غير المسموح بها على مستوى الشبكة ويرفضانها.

إعادة فحص السجلات في Cloud Logging

اطّلِع على إدخالات سجلّ Agent Gateway ولاحظ إدخالات 403 الجديدة التي تتوافق مع استدعاء الأداة add غير المسموح به:

# show agent gateway logs
gcloud logging read 'resource.type="networkservices.googleapis.com/Gateway"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="table( \
    timestamp.date(tz=LOCAL):label=TIMESTAMP, \
    httpRequest.status:label=STATUS, \
    httpRequest.serverIp:label=SERVER_IP, \
    jsonPayload.agentGatewayInfo.mcpInfo.method:label=MCP_METHOD, \
    jsonPayload.agentGatewayInfo.mcpInfo.parameter:label=TOOL, \
    jsonPayload.authzPolicyInfo.result:label=AUTHZ, \
    jsonPayload.agentGatewayInfo.agentRegistryResource.basename():label=REGISTRY_MCP
  )"

الناتج المتوقّع:

TIMESTAMP            STATUS  SERVER_IP         MCP_METHOD                 TOOL  AUTHZ    REGISTRY_MCP
YYYY-MM-DDTHH:MM:SS  403                       tools/call                 add   DENIED   agentregistry-00000000-0000-0000-0012-3456789abcde
YYYY-MM-DDTHH:MM:SS  403
YYYY-MM-DDTHH:MM:SS  202     172.16.20.20:443  notifications/initialized        ALLOWED  agentregistry-00000000-0000-0000-0012-3456789abcde
YYYY-MM-DDTHH:MM:SS          172.16.20.20:443                                   ALLOWED  agentregistry-00000000-0000-0000-0012-3456789abcde
YYYY-MM-DDTHH:MM:SS  200     172.16.20.20:443  initialize                       ALLOWED  agentregistry-00000000-0000-0000-0012-3456789abcde

تأكَّد من أنّ الطلب الإضافي لم يصل مطلقًا إلى الخلفية في Cloud Run:

# show cloud run logs
gcloud logging read 'resource.type="cloud_run_revision"
  AND textPayload:"Tool:"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="value(timestamp.date(tz=LOCAL), textPayload)"

لا يعرض الأمر أي إدخالات جديدة، ما يؤكّد أنّ Agent Gateway فرض سياسة الوصول إلى "إدارة الهوية وإمكانية الوصول" بنجاح.

بهذا نكون قد انتهينا من جزء التحقّق من الصحة... ننتقل الآن إلى قسم التنظيف.

9. تنظيف

اتّبِع الخطوات التالية لحذف الموارد وعمليات الضبط التي تم إنشاؤها في هذا المختبر.

إزالة مكوّنات Gemini Enterprise

# delete gemini enterprise engine (app)
curl -s -X DELETE "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

# delete custom mcp collection, data connector, and backing data store
curl -s -X DELETE "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/${GE_COLLECTION_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

# reset identity provider configuration
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/aclConfig" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  -H "Content-Type: application/json" \
  -d '{"idpConfig":{"idpType":"IDP_TYPE_UNSPECIFIED"}}'

إزالة مكوّنات خادم MCP

# delete agent registry service
gcloud -q agent-registry services delete ${MCP_NAME} \
  --location=${REGION} \
  --project=${PROJ_ID}

# delete cloud run service, source-deploy artifact registry repo, and staging bucket
gcloud -q run services delete ${MCP_NAME} \
  --region=${REGION} \
  --project=${PROJ_ID}

gcloud -q artifacts repositories delete cloud-run-source-deploy \
  --location=${REGION} \
  --project=${PROJ_ID}

gcloud -q storage rm --recursive gs://run-sources-${PROJ_ID}-${REGION} \
  --project=${PROJ_ID}

إزالة "بوابة الوكيل" وسياسات الوصول إلى "إدارة الهوية وإمكانية الوصول"

# delete gateway authorization policy, iap extension, and agent gateway
gcloud -q network-security authz-policies delete ${AGW_NAME}-authz-policy-iap \
  --location=${REGION} \
  --project=${PROJ_ID}

gcloud -q service-extensions authz-extensions delete ${AGW_NAME}-svc-ext-authz-iap \
  --location=${REGION} \
  --project=${PROJ_ID}

gcloud -q network-services agent-gateways delete ${AGW_NAME} \
  --location=${REGION} \
  --project=${PROJ_ID}
# delete iam policy binding and access policy
gcloud -q iam policy-bindings delete ${UAP_BINDING_NAME} \
  --location=global \
  --project=${PROJ_ID}

gcloud -q iam access-policies delete ${UAP_POLICY_NAME} \
  --location=global \
  --project=${PROJ_ID}

إزالة مكوّنات نظام أسماء النطاقات والجدار الناري

# delete dns record set, managed zone, and policy
gcloud -q dns record-sets delete "*.run.app." \
  --type=A \
  --zone=priv-zone-run \
  --project=${PROJ_ID}

gcloud -q dns managed-zones delete priv-zone-run \
  --project=${PROJ_ID}

gcloud -q dns policies update dns-policy-${SLUG} \
  --networks="" \
  --project=${PROJ_ID}

gcloud -q dns policies delete dns-policy-${SLUG} \
  --project=${PROJ_ID}
# delete firewall policy association, rule, and policy
gcloud -q compute network-firewall-policies associations delete \
  --name=fw-policy-bind-${SLUG} \
  --firewall-policy=fw-policy-${SLUG} \
  --global-firewall-policy \
  --project=${PROJ_ID}

gcloud -q compute network-firewall-policies rules delete 1001 \
  --firewall-policy=fw-policy-${SLUG} \
  --global-firewall-policy \
  --project=${PROJ_ID}

gcloud -q compute network-firewall-policies delete fw-policy-${SLUG} \
  --global \
  --project=${PROJ_ID}

إزالة مكوّنات شبكة PSC وVPC

# delete psc forwarding rule and internal ip address
gcloud -q compute forwarding-rules delete psc2gapis \
  --global \
  --project=${PROJ_ID}

gcloud -q compute addresses delete ip-psc2gapis \
  --global \
  --project=${PROJ_ID}
# delete psc network attachment, subnet, and vpc network
gcloud -q compute network-attachments delete psc-na-${REGION}-agw \
  --region=${REGION} \
  --project=${PROJ_ID}

gcloud -q compute networks subnets delete subnet-${REGION}-agw \
  --region=${REGION} \
  --project=${PROJ_ID}

gcloud -q compute networks delete vnet-${SLUG} \
  --project=${PROJ_ID}

إزالة عمليات إلغاء سياسات المؤسسة والملفات المحلية

# delete project-level organization policy overrides
gcloud -q org-policies delete discoveryengine.managed.disableCustomMcpServerConnector --project=${PROJ_ID}
gcloud -q org-policies delete iam.managed.disableAccessPolicyBinding --project=${PROJ_ID}
# remove local project files
rm -rf cfg math-wizard

بهذا نكون قد انتهينا من عملية التنظيف... لننتقل الآن إلى الخاتمة.

10. الخاتمة

تهانينا! لقد أنشأت بنية شاملة تتيح لتطبيق Gemini Enterprise اكتشاف الأدوات واستخدامها بأمان على خادم MCP مخصّص خاص:

  • خادم MCP مخصّص وAgent Registry: تم نشر خدمة FastMCP خاصة على Cloud Run (--ingress=internal) وتم تسجيل نقطة النهاية ومخطط الأداة (add وsubtract) في Agent Registry.
  • عملية الربط بـ Gemini Enterprise: تم توفير تطبيق Gemini Enterprise، وربط عدد الزيارات إلى الأدوات الخارجية بـ Agent Gateway، وإرفاق خادم MCP المسجّل كأداة ربط بيانات REGISTRY_MCP.
  • الخروج من السحابة الافتراضية الخاصة (VPC) الخاصة وإدارة الثقة المعدومة: يتم تنفيذ الأدوات التي تم توجيهها بشكل خاص عبر Private Service Connect (172.16.20.20) ويتم فرض مبدأ الحدّ الأدنى من الامتيازات على مستوى الأداة باستخدام سياسات الوصول الموحّدة في خدمة "إدارة الهوية وإمكانية الوصول" (IAM) وخدمة "الوصول إلى التطبيقات الداخلية" (IAP) (destination.agent_registry.*).

cosmopup

يرى Cosmpup أنّ دروس Codelabs التطبيقية هي الأفضل على الإطلاق!

ما هي الخطوة التالية؟

يمكنك تقديم تعليقات أو طرح أسئلة أو اقتراح تصحيحات باستخدام نموذج الملاحظات هذا.

شكرًا