1. Avant de commencer
Le protocole MCP (Model Context Protocol) est une norme ouverte qui permet aux modèles et agents d'IA d'accéder de manière sécurisée à des outils, des bases de données et un contexte d'entreprise. Depuis son introduction en 2024, le protocole a été largement adopté par les fournisseurs de services cloud et de LLM. La dernière spécification MCP Spec 2026-07-28 (MCP 2.0) définit une architecture sans état, des transports simplifiés et un typage strict des résultats, tout en restant rétrocompatible avec les versions antérieures.
Le SDK Python MCP officiel (mcp>=2.0.0) fournit MCPServer (mcp.server.mcpserver.MCPServer), qui remplace FastMCP dans MCP 2.0 en tant que framework hautes performances et facile à utiliser pour les développeurs afin de créer des serveurs MCP prêts pour la production, conformément à la spécification MCP moderne (2026-07-28) avec des transports HTTP et SSE (Server-Sent Events) diffusables sur SSL/TLS.
Dans cet atelier de programmation, vous allez créer un serveur MCP de qualité production à l'aide de MCPServer du SDK MCP 2.0 pour Python et de la gestion des dépendances uv. Vous allez équiper votre serveur MCP de quatre outils Google Cloud (invocation Vertex AI Gemini, inspection Google Cloud Storage, écriture d'audit Cloud Logging et vérification de l'état des ressources Google Cloud). Vous allez ensuite conteneuriser le serveur et le déployer sur deux cibles d'exécution Google Cloud : Cloud Run et Google Kubernetes Engine (GKE) Autopilot. Vous allez également enregistrer et utiliser le serveur MCP dans Gemini Enterprise Agent Platform.
Objectifs de l'atelier
- Créez un
MCPServeravec quatre outils Google Cloud à l'aide de Python 3.12+ et deuvconforme à la spécification MCP 2026-07-28. - Conteneurisez le serveur MCP à l'aide d'une compilation Docker en plusieurs étapes.
- Sécurisez et déployez le serveur MCP sur Cloud Run avec l'authentification IAM et SSL/TLS appliquées.
- Sécurisez et déployez le serveur MCP sur GKE Autopilot à l'aide de Workload Identity et de l'API Kubernetes Gateway avec TLS.
- Enregistrez le point de terminaison du serveur MCP sécurisé avec Gemini Enterprise Agent Platform à l'aide d'en-têtes de jeton porteur OIDC.
Prérequis
- Un projet Google Cloud avec facturation activée.
- Google Cloud SDK (interface de ligne de commande
gcloud) installé et configuré. - Python 3.12 ou version ultérieure et le gestionnaire de packages
uvsont installés. dockerest installé.- L'outil de ligne de commande
kubectlest installé.
2. Configurer l'environnement Google Cloud
Avant de créer des ressources, authentifiez votre environnement et activez les API Google Cloud nécessaires.
Authentifier gcloud CLI
Connectez-vous à votre compte Google Cloud :
gcloud auth login
Définissez l'ID de votre projet Google Cloud actif :
export PROJECT_ID=$(gcloud config get-value project)
gcloud config set project ${PROJECT_ID}
Activer les services Google Cloud
Activez toutes les API requises pour Cloud Run, GKE, Vertex AI, Artifact Registry, Cloud Build, Cloud Logging, Storage et Compute Engine :
gcloud services enable \
agentregistry.googleapis.com \
run.googleapis.com \
container.googleapis.com \
artifactregistry.googleapis.com \
aiplatform.googleapis.com \
logging.googleapis.com \
storage.googleapis.com \
compute.googleapis.com \
iam.googleapis.com \
cloudbuild.googleapis.com \
--project="${PROJECT_ID}"
Vérifiez que les API ont bien été activées :
Operation "operations/..." finished successfully.
Authentifier les identifiants par défaut de l'application
Authentifiez votre environnement pour que les bibliothèques clientes Python puissent accéder à Vertex AI et Cloud Storage en local pendant le développement :
gcloud auth application-default login
3. Créer le serveur MCP avec MCPServer et uv
Dans cette étape, vous allez initialiser un projet Python à l'aide de uv et créer un MCPServer compatible avec quatre fonctionnalités Google Cloud.
Initialiser le projet avec uv
Créez le répertoire du serveur et initialisez uv :
mkdir -p mcp-server/src/mcp_server
cd mcp-server
uv init --lib
Copiez le code dans le fichier pyproject.toml :
[project]
name = "secure-mcp-gcp-server"
version = "0.1.0"
description = "MCP server with Google Cloud tools supporting MCP Spec 2026-07-28 over Streamable HTTP"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"mcp>=2.0.0",
"google-genai>=1.0.0",
"google-cloud-storage>=2.14.0",
"google-cloud-logging>=3.11.0",
"google-cloud-resource-manager>=1.12.0",
"uvicorn>=0.30.0",
"httpx2>=0.1.0",
"pydantic>=2.7.0",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/mcp_server"]
Synchronisez les dépendances à l'aide de uv :
uv sync
Écrire le code MCPServer
Créez le fichier d'implémentation du serveur à l'emplacement src/mcp_server/server.py :
import logging
import os
from typing import Any
from google import genai
from google.cloud import logging as cloud_logging
from google.cloud import storage
from mcp.server.mcpserver import MCPServer
from starlette.requests import Request
from starlette.responses import PlainTextResponse
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("mcp-gcp-server")
# Initialize MCPServer conforming to MCP Spec 2026-07-28
mcp = MCPServer(
"Google Cloud Production Tools",
instructions="MCP Server conforming to MCP Spec 2026-07-28 for Vertex AI, Cloud Storage, Audit Logging, and Health Inspection.",
)
@mcp.custom_route("/healthz", methods=["GET"])
async def health_check(request: Request) -> PlainTextResponse:
"""Kubernetes readiness and liveness probe health check endpoint."""
return PlainTextResponse("OK")
@mcp.tool(description="Generate content or answer questions using Vertex AI Gemini model.")
def vertex_ai_generate_content(
prompt: str,
model_name: str = "gemini-2.5-flash",
project_id: str | None = None,
location: str = "us-central1",
) -> str:
"""Invokes Vertex AI Gemini API using official google-genai SDK."""
target_project = project_id or os.getenv("GCP_PROJECT") or os.getenv("GOOGLE_CLOUD_PROJECT")
if not target_project:
return "Error: GCP project ID not configured."
try:
client = genai.Client(vertexai=True, project=target_project, location=location)
response = client.models.generate_content(
model=model_name,
contents=prompt,
)
return response.text or "No text returned from Gemini."
except Exception as e:
logger.error("Vertex AI Tool Error: %s", e)
return f"Error executing Vertex AI tool: {e!s}"
@mcp.tool(description="List objects and inspect metadata for a specified Google Cloud Storage bucket.")
def gcs_bucket_inspector(
bucket_name: str,
max_results: int = 10,
prefix: str | None = None,
) -> dict[str, Any]:
"""Inspects GCS bucket content and metadata conforming to MCP Spec 2026-07-28 resultType schema."""
try:
client = storage.Client()
bucket = client.bucket(bucket_name)
blobs = list(client.list_blobs(bucket, max_results=max_results, prefix=prefix))
items = [{"name": b.name, "size_bytes": b.size, "updated": str(b.updated)} for b in blobs]
return {
"resultType": "complete",
"bucket_name": bucket_name,
"object_count_sample": len(items),
"objects": items,
}
except Exception as e:
logger.error("GCS Inspector Error: %s", e)
return {"resultType": "complete", "error": f"Failed to inspect GCS bucket: {e!s}"}
@mcp.tool(description="Write structured operational or security audit log records to Google Cloud Logging.")
def cloud_logging_audit_writer(
log_name: str,
message: str,
severity: str = "INFO",
metadata: dict[str, Any] | None = None,
) -> dict[str, Any]:
"""Sends structured audit entry to Cloud Logging."""
try:
client = cloud_logging.Client()
logger_instance = client.logger(log_name)
payload = {"message": message, "metadata": metadata or {}, "source": "mcp-server-gcp"}
logger_instance.log_struct(payload, severity=severity.upper())
return {
"resultType": "complete",
"status": "success",
"log_name": log_name,
"recorded_message": message,
}
except Exception as e:
logger.error("Cloud Logging Error: %s", e)
return {"resultType": "complete", "error": f"Failed to record audit log: {e!s}"}
@mcp.tool(description="Check health and operational state of Google Cloud project resources.")
def gcp_resource_health_checker(project_id: str | None = None) -> dict[str, Any]:
"""Returns project resource summary and status."""
target_project = project_id or os.getenv("GOOGLE_CLOUD_PROJECT") or "unknown-project"
return {
"resultType": "complete",
"status": "HEALTHY",
"project_id": target_project,
"mcp_spec_version": "2026-07-28",
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/serverInfo": {"name": "mcp-gcp-server", "version": "0.1.0"},
},
"transports_enabled": ["Streamable HTTP"],
"ssl_tls_enabled": True,
}
if __name__ == "__main__":
port = int(os.getenv("PORT", "8080"))
logger.info("Starting MCPServer on port %d (Streamable HTTP Transport, Spec 2026-07-28)...", port)
mcp.run(
transport="streamable-http",
host="0.0.0.0",
port=port,
stateless_http=True,
json_response=True,
)
Tester le serveur MCP en local
Étape 1 : Démarrer le serveur MCP
Dans votre terminal principal, démarrez le serveur à l'aide de uv :
uv run python -m src.mcp_server.server
Vous devriez voir des journaux de démarrage confirmant que le serveur HTTP en flux continu écoute le port 8080 :
INFO:mcp-gcp-server:Starting MCPServer on port 8080 (Streamable HTTP Transport, Spec 2026-07-28)... INFO: Started server process [12345] INFO: Waiting for application startup. INFO:mcp.server.streamable_http_manager:StreamableHTTP session manager started INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
Gardez ce terminal ouvert et en cours d'exécution.
Étape 2 : Vérifier le point de terminaison HTTP Streamable à l'aide de curl
Dans MCP 2.0 (spécification MCP du 28/07/2026), la négociation initialize avec état et l'en-tête Mcp-Session-Id sont remplacés par des requêtes sans état. Vous pouvez appeler tools/list directement en transmettant les en-têtes MCP-Protocol-Version et Mcp-Method avec les métadonnées du client dans params._meta.
Ouvrez une deuxième fenêtre de terminal et envoyez une requête HTTP POST Streamable :
cd mcp-server
curl -i -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/list" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "curl-test",
"version": "1.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}'
MCPServer répondra avec HTTP/1.1 200 OK et renverra directement le résultat tools/list JSON-RPC :
HTTP/1.1 200 OK
date: Wed, 12 Aug 2026 14:55:00 GMT
server: uvicorn
content-type: application/json
{"jsonrpc":"2.0","id":1,"result":{"tools":[{"name":"vertex_ai_generate_content",...},{"name":"gcs_bucket_inspector",...},{"name":"cloud_logging_audit_writer",...},{"name":"gcp_resource_health_checker",...}]}}
Étape 3 : Exécutez le client de test MCP
Pour tester la découverte et l'exécution d'outils sur votre serveur local via HTTP diffusable, créez un script client de test src/mcp_server/test_client.py :
import asyncio
from mcp import Client
from mcp.types import TextContent
async def test_mcp_server() -> None:
"""Connects to the local MCP v2.0 server, lists tools, and invokes health check."""
server_url = "http://localhost:8080/mcp"
print(f"[*] Connecting to local MCPServer at {server_url} (Streamable HTTP)...")
async with Client(server_url) as client:
print(
f"[+] Connected (protocol: {client.protocol_version}, "
f"server: {client.server_info.name if client.server_info else 'unknown'})."
)
# List available tools
tools_response = await client.list_tools()
print("\n[*] Discovered MCP Tools:")
for tool in tools_response.tools:
print(f" - {tool.name}: {tool.description}")
# Invoke gcp_resource_health_checker tool
print("\n[*] Invoking tool: gcp_resource_health_checker...")
health_result = await client.call_tool("gcp_resource_health_checker", {})
print("[+] Result:")
for content in health_result.content:
if isinstance(content, TextContent):
print(content.text)
if __name__ == "__main__":
asyncio.run(test_mcp_server())
Exécutez le script du client de test à l'aide de uv :
uv run python src/mcp_server/test_client.py
Vous devriez voir un résultat indiquant que la connexion, la découverte et l'exécution de l'outil ont réussi :
[*] Connecting to local MCPServer at http://localhost:8080/mcp (Streamable HTTP)...
[+] Connected (protocol: 2026-07-28, server: Google Cloud Production Tools).
[*] Discovered MCP Tools:
- vertex_ai_generate_content: Generate content or answer questions using Vertex AI Gemini model.
- gcs_bucket_inspector: List objects and inspect metadata for a specified Google Cloud Storage bucket.
- cloud_logging_audit_writer: Write structured operational or security audit log records to Google Cloud Logging.
- gcp_resource_health_checker: Check health and operational state of Google Cloud project resources.
[*] Invoking tool: gcp_resource_health_checker...
[+] Result:
{"resultType": "complete", "status": "HEALTHY", "project_id": "my-gcp-project", "mcp_spec_version": "2026-07-28", "_meta": {"io.modelcontextprotocol/protocolVersion": "2026-07-28", "io.modelcontextprotocol/serverInfo": {"name": "mcp-gcp-server", "version": "0.1.0"}}, "transports_enabled": ["Streamable HTTP"], "ssl_tls_enabled": true}
Une fois la validation effectuée, appuyez sur CTRL+C dans votre terminal principal pour arrêter le serveur local.
4. Conteneuriser le serveur MCP
Pour déployer le serveur MCP sur Cloud Run et GKE Autopilot, empaquetez le serveur dans une image de conteneur minimal à l'aide d'un fichier Dockerfile à plusieurs étapes optimisé par uv.
Créer un fichier Dockerfile
Dans mcp-server/Dockerfile :
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS builder
WORKDIR /app
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
COPY pyproject.toml uv.lock* /app/
RUN uv sync --no-install-project --no-dev
COPY README.md /app/
COPY src /app/src
RUN uv sync --no-dev
FROM python:3.12-slim-bookworm
WORKDIR /app
COPY --from=builder /app /app
ENV PATH="/app/.venv/bin:$PATH"
ENV PORT=8080
ENV PYTHONUNBUFFERED=1
EXPOSE 8080
CMD ["python", "-m", "src.mcp_server.server"]
Créer et transférer une image vers Artifact Registry
Créer un dépôt Artifact Registry :
gcloud artifacts repositories create mcp-servers \
--repository-format=docker \
--location=us-central1 \
--description="Docker repository for MCP Servers" \
--project="${PROJECT_ID}"
Accordez les autorisations IAM requises à votre compte utilisateur et au compte de service Compute Engine par défaut pour que Cloud Build puisse préparer les sources, écrire des journaux et envoyer des images à Artifact Registry :
export USER_EMAIL=$(gcloud config get-value account)
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="user:${USER_EMAIL}" \
--role="roles/cloudbuild.builds.editor"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="user:${USER_EMAIL}" \
--role="roles/storage.admin"
export DEFAULT_SA=$(gcloud iam service-accounts list \
--filter="email:compute@developer.gserviceaccount.com" \
--format="value(email)" \
--project="${PROJECT_ID}")
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${DEFAULT_SA}" \
--role="roles/storage.objectViewer"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${DEFAULT_SA}" \
--role="roles/artifactregistry.writer"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${DEFAULT_SA}" \
--role="roles/logging.logWriter"
Envoyez la compilation de l'image à l'aide de Cloud Build :
export IMAGE_URI="us-central1-docker.pkg.dev/${PROJECT_ID}/mcp-servers/secure-mcp-server:latest"
gcloud builds submit . --tag="${IMAGE_URI}" --project="${PROJECT_ID}"
Une fois l'opération terminée, votre image de conteneur est stockée de manière sécurisée dans Artifact Registry :
SUCCESS: Image published to us-central1-docker.pkg.dev/.../secure-mcp-server:latest
5. Déployer sur Cloud Run avec IAM et HTTPS
Cloud Run fournit un environnement sans serveur entièrement géré avec arrêt automatique des certificats HTTPS / SSL et contrôle précis des accès Cloud IAM.
Créer un compte de service dédié
Créez un compte de service Google avec le principe du moindre privilège pour Cloud Run :
gcloud iam service-accounts create mcp-server-cr-sa \
--display-name="MCP Server Cloud Run SA" \
--project="${PROJECT_ID}"
export SA_EMAIL="mcp-server-cr-sa@${PROJECT_ID}.iam.gserviceaccount.com"
# Grant Vertex AI, Logging, and GCS permissions
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/aiplatform.user"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/logging.logWriter"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/storage.objectViewer"
Déployer un service sur Cloud Run
Déployez le conteneur sur Cloud Run avec l'authentification IAM forcée (--no-allow-unauthenticated) et le protocole SSL géré par défaut :
gcloud run deploy secure-mcp-server \
--image="${IMAGE_URI}" \
--platform=managed \
--region=us-central1 \
--service-account="${SA_EMAIL}" \
--set-env-vars="GOOGLE_CLOUD_PROJECT=${PROJECT_ID}" \
--no-allow-unauthenticated \
--ingress=all \
--project="${PROJECT_ID}"
Récupérez l'URL HTTPS :
export CLOUD_RUN_URL=$(gcloud run services describe secure-mcp-server --platform=managed --region=us-central1 --format='value(status.url)' --project="${PROJECT_ID}")
echo "Cloud Run HTTPS Endpoint: ${CLOUD_RUN_URL}"
Valider la sécurité des points de terminaison
Toute tentative d'envoi d'une requête non autorisée au point de terminaison HTTP Streamable renverra 403 Forbidden :
curl -i -X POST "${CLOUD_RUN_URL}/mcp" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/list" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "curl-test",
"version": "1.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}'
HTTP/2 403 content-type: text/html; charset=UTF-8 date: Mon, 11 Aug 2026 14:00:00 GMT
Générez un jeton d'ID OIDC à l'aide de gcloud pour valider la communication autorisée :
export ID_TOKEN=$(gcloud auth print-identity-token --audiences="${CLOUD_RUN_URL}")
curl -i -X POST "${CLOUD_RUN_URL}/mcp" \
-H "Authorization: Bearer ${ID_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/list" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "curl-test",
"version": "1.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}'
HTTP/2 200
content-type: application/json
{"jsonrpc":"2.0","id":1,"result":{"tools":[{"name":"vertex_ai_generate_content",...},{"name":"gcs_bucket_inspector",...},{"name":"cloud_logging_audit_writer",...},{"name":"gcp_resource_health_checker",...}]}}
Tester l'exécution de l'outil en direct : inspecteur Cloud Storage
Maintenant que le serveur MCP distant est authentifié et répond, testez l'exécution de l'outil gcs_bucket_inspector sur l'infrastructure Google Cloud.
Étape 1 : Créez un bucket Cloud Storage de test
Créez un bucket de test et importez un exemple de fichier :
export BUCKET_NAME="${PROJECT_ID}-mcp-demo"
# Create Cloud Storage bucket
gcloud storage buckets create "gs://${BUCKET_NAME}" \
--location=us-central1 \
--project="${PROJECT_ID}"
# Upload sample file
echo "Hello from Secure MCP on Google Cloud!" > sample.txt
gcloud storage cp sample.txt "gs://${BUCKET_NAME}/sample.txt"
Étape 2 : Créez le client de test de l'outil Remote GCS
Créez un script client de test nommé src/mcp_server/test_gcs_tool.py pour vous authentifier auprès de Cloud Run et appeler l'outil gcs_bucket_inspector :
import asyncio
import os
import subprocess
import httpx2
from mcp import Client
from mcp.client.streamable_http import streamable_http_client
from mcp.types import TextContent
async def test_gcs_tool() -> None:
"""Authenticates to Cloud Run via OIDC and invokes the gcs_bucket_inspector tool."""
cloud_run_url = os.getenv("CLOUD_RUN_URL")
bucket_name = os.getenv("BUCKET_NAME")
if not cloud_run_url or not bucket_name:
print("[!] Please set both CLOUD_RUN_URL and BUCKET_NAME environment variables.")
return
# Generate Google OIDC ID token for Cloud Run authentication
id_token = subprocess.check_output(
["gcloud", "auth", "print-identity-token", f"--audiences={cloud_run_url.rstrip('/')}"],
text=True,
).strip()
headers = {"Authorization": f"Bearer {id_token}"}
server_url = f"{cloud_run_url.rstrip('/')}/mcp"
print(f"[*] Connecting to remote Cloud Run MCP server at {server_url} (Streamable HTTP)...")
async with httpx2.AsyncClient(
headers=headers,
timeout=httpx2.Timeout(30.0, read=300.0),
) as http_client:
transport = streamable_http_client(server_url, http_client=http_client)
async with Client(transport) as client:
print(
f"[+] Authenticated and connected (protocol: {client.protocol_version})."
)
# List tools
tools_response = await client.list_tools()
print(f"[*] Verified {len(tools_response.tools)} available tools on Cloud Run.")
# Invoke gcs_bucket_inspector tool
print(f"\n[*] Invoking tool: gcs_bucket_inspector on '{bucket_name}'...")
result = await client.call_tool(
"gcs_bucket_inspector", {"bucket_name": bucket_name}
)
print("[+] Response from Cloud Run MCP Server:")
for content in result.content:
if isinstance(content, TextContent):
print(content.text)
if __name__ == "__main__":
asyncio.run(test_gcs_tool())
Étape 3 : Exécutez le client de test GCS à distance
Exécutez le script de test à l'aide de uv :
uv run python src/mcp_server/test_gcs_tool.py
Vous devriez voir les métadonnées de l'objet actif renvoyées par le serveur MCP Cloud Run :
[*] Connecting to remote Cloud Run MCP server at https://secure-mcp-server-...-uc.a.run.app/mcp (Streamable HTTP)...
[+] Authenticated and connected (protocol: 2026-07-28).
[*] Verified 4 available tools on Cloud Run.
[*] Invoking tool: gcs_bucket_inspector on 'my-project-mcp-demo'...
[+] Response from Cloud Run MCP Server:
{"resultType":"complete","bucket_name":"my-project-mcp-demo","object_count_sample":1,"objects":[{"name":"sample.txt","size_bytes":39,"updated":"..."}]}
6. Déployer sur GKE Autopilot avec Workload Identity et TLS
Pour les charges de travail Kubernetes, GKE Autopilot gère le provisionnement des nœuds, tandis que Workload Identity élimine les clés de compte de service statiques.
Provisionner un cluster GKE Autopilot
Provisionnez un cluster GKE Autopilot :
gcloud container clusters create-auto mcp-gke-cluster \
--location=us-central1 \
--project="${PROJECT_ID}"
gcloud container clusters get-credentials mcp-gke-cluster \
--location=us-central1 \
--project="${PROJECT_ID}"
Configurer Workload Identity
Créez un compte de service Google (GSA) et un compte de service Kubernetes (KSA), puis associez-les à l'aide de Workload Identity :
# 1. Create GSA
gcloud iam service-accounts create mcp-gke-sa \
--display-name="GKE MCP Service Account" \
--project="${PROJECT_ID}"
export GSA_EMAIL="mcp-gke-sa@${PROJECT_ID}.iam.gserviceaccount.com"
# 2. Grant IAM Roles to GSA
gcloud projects add-iam-policy-binding "${PROJECT_ID}" --member="serviceAccount:${GSA_EMAIL}" --role="roles/aiplatform.user"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" --member="serviceAccount:${GSA_EMAIL}" --role="roles/logging.logWriter"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" --member="serviceAccount:${GSA_EMAIL}" --role="roles/storage.objectViewer"
# 3. Create KSA
kubectl create serviceaccount mcp-server-ksa --namespace default
# 4. Annotate KSA
kubectl annotate serviceaccount mcp-server-ksa \
--namespace default \
iam.gke.io/gcp-service-account="${GSA_EMAIL}"
# 5. Bind KSA to GSA
gcloud iam service-accounts add-iam-policy-binding "${GSA_EMAIL}" \
--role="roles/iam.workloadIdentityUser" \
--member="serviceAccount:${PROJECT_ID}.svc.id.goog[default/mcp-server-ksa]" \
--project="${PROJECT_ID}"
Appliquer le déploiement Kubernetes et l'API Gateway avec TLS
Étape 1 : Réserver une adresse IP statique et provisionner un certificat SSL géré par Google avec nip.io
Réservez une adresse IP externe globale et utilisez le service DNS générique nip.io () pour établir un nom de domaine public valide (MCP_DOMAIN) avant d'appliquer les manifestes Kubernetes :
# Reserve global static IP address for GKE Gateway Load Balancer
gcloud compute addresses create mcp-server-ip \
--global \
--project="${PROJECT_ID}"
export MCP_IP=$(gcloud compute addresses describe mcp-server-ip --global --format="value(address)" --project="${PROJECT_ID}")
export MCP_DOMAIN="mcp.${MCP_IP}.nip.io"
echo "Reserved Static IP: ${MCP_IP}"
echo "Configured nip.io Domain: ${MCP_DOMAIN}"
# Provision Google-managed SSL certificate
gcloud compute ssl-certificates create mcp-server-cert \
--domains="${MCP_DOMAIN}" \
--global \
--project="${PROJECT_ID}"
Vous n'avez pas besoin d'attendre la fin du provisionnement du certificat SSL avant de continuer. En effet, les certificats gérés par Google restent à l'état PROVISIONING jusqu'à ce qu'ils soient associés à l'équilibreur de charge de passerelle à l'étape 3. Passez immédiatement aux étapes suivantes.
Étape 2 : Créez le fichier manifeste de déploiement et de service
Créez deployment.yaml contenant les définitions de déploiement et de service interne. Étant donné que MCP 2.0 (MCP Spec 2026-07-28) est sans état, le Service Kubernetes ne nécessite pas d'affinité de session basée sur les adresses IP client :
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-server-deployment
namespace: default
labels:
app: mcp-server
# GKE takes this label and registers the deployment as an MCP server to Agent Registry
registry.gke.io/functional-type: "MCP_SERVER"
annotations:
# Endpoint URL where the GKE controller can access this MCP server
modelcontextprotocol.info/urls: |
- https://MCP_DOMAIN/mcp
# Defines structural capabilities for the MCP server card
modelcontextprotocol.info/capabilities: |
card:
endpoint: "/mcp"
protocol: "HTTP"
spec:
replicas: 2
selector:
matchLabels:
app: mcp-server
template:
metadata:
labels:
app: mcp-server
annotations:
# Workload Identity annotation for identity and access management
iam.gke.io/spiffe-identity-type: agent-identity
spec:
serviceAccountName: mcp-server-ksa
containers:
- name: mcp-server
image: us-central1-docker.pkg.dev/PROJECT_ID/mcp-servers/secure-mcp-server:latest
ports:
- containerPort: 8080
name: http
env:
- name: PORT
value: "8080"
- name: GOOGLE_CLOUD_PROJECT
value: "PROJECT_ID"
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "1000m"
memory: "1Gi"
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 15
---
apiVersion: v1
kind: Service
metadata:
name: mcp-server-service
namespace: default
labels:
app: mcp-server
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
name: http
selector:
app: mcp-server
Remplacez MCP_DOMAIN et PROJECT_ID, puis appliquez le déploiement :
sed -e "s|MCP_DOMAIN|${MCP_DOMAIN}|g" \
-e "s|PROJECT_ID|${PROJECT_ID}|g" \
deployment.yaml | kubectl apply -f -
Étape 3 : Créez le fichier manifeste Gateway API, HealthCheckPolicy et GCPBackendPolicy
Créez gateway.yaml contenant la passerelle, HTTPRoute, un HealthCheckPolicy et un GCPBackendPolicy :
HealthCheckPolicy: configure l'équilibreur de charge Google Cloud pour qu'il teste/healthzsur le port 8080.GCPBackendPolicy(Délai avant expiration du backend) : définittimeoutSec: 300pour l'aligner sur le délai avant expiration de lecture de 300 secondes du SDK MCP v2 pour les flux HTTP / SSE diffusables (GKE Gateway est défini par défaut sur 30 secondes si cette valeur est omise).
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: mcp-gateway
namespace: default
spec:
gatewayClassName: gke-l7-global-external-managed
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
options:
networking.gke.io/pre-shared-certs: mcp-server-cert
addresses:
- type: NamedAddress
value: mcp-server-ip
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: mcp-http-route
namespace: default
spec:
parentRefs:
- name: mcp-gateway
hostnames:
- "MCP_DOMAIN"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: mcp-server-service
port: 80
---
apiVersion: networking.gke.io/v1
kind: HealthCheckPolicy
metadata:
name: mcp-health-check-policy
namespace: default
spec:
default:
checkIntervalSec: 15
timeoutSec: 5
healthyThreshold: 1
unhealthyThreshold: 2
config:
type: HTTP
httpHealthCheck:
port: 8080
requestPath: /healthz
targetRef:
group: ""
kind: Service
name: mcp-server-service
---
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
name: mcp-backend-policy
namespace: default
spec:
default:
# Aligns with MCP SDK v2's 300s read timeout for Streamable HTTP / SSE streams
# (GKE Gateway defaults to 30s if omitted)
timeoutSec: 300
targetRef:
group: ""
kind: Service
name: mcp-server-service
Appliquez les ressources Gateway, HTTPRoute, HealthCheckPolicy et GCPBackendPolicy :
sed "s/MCP_DOMAIN/${MCP_DOMAIN}/g" gateway.yaml | kubectl apply -f -
Étape 4 : Vérifiez le déploiement et testez le serveur MCP à l'aide du transfert de port
Étant donné que les certificats SSL gérés par Google et les équilibreurs de charge d'application Google Cloud externes mettent 5 à 15 minutes à provisionner et à établir le routage DNS, vous pouvez tester immédiatement les pods GKE en cours d'exécution à l'aide de kubectl port-forward.
Tout d'abord, vérifiez que vos pods et votre passerelle sont en cours d'exécution :
kubectl get pods -l app=mcp-server
kubectl get gateway mcp-gateway
NAME READY STATUS RESTARTS AGE mcp-server-deployment-7b8f9495c5-x2n8q 1/1 Running 0 45s mcp-server-deployment-7b8f9495c5-z4k9p 1/1 Running 0 45s NAME CLASS ADDRESS PROGRAMMED AGE mcp-gateway gke-l7-global-external-managed 34.120.x.x True 2m
Ensuite, testez le service GKE en direct localement à l'aide du transfert de port :
- Dans votre terminal, transférez le port local
8080vers le service ClusterIP GKE :
kubectl port-forward svc/mcp-server-service 8080:80
- Dans un deuxième terminal, créez un script client de test nommé
src/mcp_server/test_vertex_tool.pypour appeler l'outilvertex_ai_generate_contentsur GKE à l'aide de Workload Identity :
import argparse
import asyncio
import os
from mcp import Client
from mcp.types import TextContent
async def test_vertex_tool(server_url: str) -> None:
"""Connects to the MCP v2.0 server and invokes the vertex_ai_generate_content tool."""
print(f"[*] Connecting to MCPServer at {server_url} (Streamable HTTP)...")
async with Client(server_url) as client:
print(
f"[+] Connected (protocol: {client.protocol_version}, "
f"server: {client.server_info.name if client.server_info else 'unknown'})."
)
# List available tools
tools_response = await client.list_tools()
print(f"[*] Discovered {len(tools_response.tools)} MCP Tools:")
for tool in tools_response.tools:
print(f" - {tool.name}")
# Invoke vertex_ai_generate_content tool
prompt = "Explain in 2 sentences why Model Context Protocol (MCP) Streamable HTTP is great for cloud deployments."
print(f"\n[*] Invoking tool: vertex_ai_generate_content with prompt: '{prompt}'...")
result = await client.call_tool(
"vertex_ai_generate_content",
{
"prompt": prompt,
"model_name": "gemini-2.5-flash",
},
)
print("\n[+] Response from Vertex AI Gemini:")
for content in result.content:
if isinstance(content, TextContent):
print(content.text)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Test Vertex AI MCP Tool on MCPServer.")
parser.add_argument(
"--host",
default=os.getenv("MCP_URL", "http://localhost:8080/mcp"),
help="MCP Server host or URL (default: http://localhost:8080/mcp or $MCP_URL)",
)
args = parser.parse_args()
# Normalize URL format
url = args.host
if not url.startswith("http://") and not url.startswith("https://"):
url = f"https://{url}"
if not url.endswith("/mcp"):
url = f"{url.rstrip('/')}/mcp"
asyncio.run(test_vertex_tool(url))
- Exécutez le script du test sur l'instance locale avec transfert de port :
uv run python src/mcp_server/test_vertex_tool.py --host="http://localhost:8080/mcp"
[*] Connecting to MCPServer at http://localhost:8080/mcp (Streamable HTTP)... [+] Connected (protocol: 2026-07-28, server: Google Cloud Production Tools). [*] Discovered 4 MCP Tools: - vertex_ai_generate_content - gcs_bucket_inspector - cloud_logging_audit_writer - gcp_resource_health_checker [*] Invoking tool: vertex_ai_generate_content with prompt: 'Explain in 2 sentences why Model Context Protocol (MCP) Streamable HTTP is great for cloud deployments.'... [+] Response from Vertex AI Gemini: MCP Streamable HTTP enables lightweight, stateless HTTP interactions that scale effortlessly across cloud-native platforms like GKE and Cloud Run. It simplifies infrastructure management by using standard HTTP/HTTPS protocols while preserving rich bidirectional streaming for AI agents.
Cela confirme que les pods GKE sont opérationnels, que Workload Identity s'authentifie correctement auprès de Vertex AI sans identifiants statiques et que le transport HTTP Streamable fonctionne comme prévu.
Étape 5 : Valider le point de terminaison de la passerelle HTTPS publique
Vérifiez l'état du provisionnement du certificat avec la commande suivante :
gcloud compute ssl-certificates describe mcp-server-cert --global --format="value(managed.status)"
Une fois le certificat ACTIVE, testez le point de terminaison HTTPS public à l'aide du client de test Python avec l'indicateur --host :
uv run python src/mcp_server/test_vertex_tool.py --host="https://${MCP_DOMAIN}/mcp"
[*] Connecting to MCPServer at https://mcp.34.120.x.x.nip.io/mcp (Streamable HTTP)... [+] Connected (protocol: 2026-07-28, server: Google Cloud Production Tools). [*] Discovered 4 MCP Tools: - vertex_ai_generate_content - gcs_bucket_inspector - cloud_logging_audit_writer - gcp_resource_health_checker [*] Invoking tool: vertex_ai_generate_content with prompt: 'Explain in 2 sentences why Model Context Protocol (MCP) Streamable HTTP is great for cloud deployments.'... [+] Response from Vertex AI Gemini: MCP Streamable HTTP enables lightweight, stateless HTTP interactions that scale effortlessly across cloud-native platforms like GKE and Cloud Run. It simplifies infrastructure management by using standard HTTP/HTTPS protocols while preserving rich bidirectional streaming for AI agents.
7. Intégrer le serveur MCP à Google Cloud Agent Platform
Maintenant que votre MCPServer est déployé de manière sécurisée sur des points de terminaison HTTPS sur Cloud Run et GKE Autopilot, enregistrez et découvrez vos outils MCP avec Google Cloud Agent Platform (Agent Registry) afin que les agents d'entreprise et les modèles d'IA puissent les découvrir et les appeler de manière dynamique.
1. Enregistrer un serveur MCP Cloud Run personnalisé sur Agent Platform et le tester à l'aide de la découverte de services
Étape 1 : Extraire les spécifications de l'outil (toolspec.json)
Pour enregistrer un serveur MCP externe ou personnalisé dans Agent Registry, interrogez tools/list sur votre serveur MCP 2.0 sans état en production, supprimez les champs _meta au niveau de l'outil et enregistrez le résultat dans toolspec.json dans un seul pipeline :
# 1. Generate identity token
export ID_TOKEN=$(gcloud auth print-identity-token --audiences="${CLOUD_RUN_URL}")
# 2. Query, parse, sanitize and save in one single pipeline
curl -s -X POST "${CLOUD_RUN_URL}/mcp" \
-H "Authorization: Bearer ${ID_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/list" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "cli",
"version": "1.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}' \
| sed -n 's/^data: //p; /^{/p' \
| jq '.result | del(.tools[]._meta)' > toolspec.json
Étape 2 : Enregistrez le service dans le registre d'agents
Utilisez gcloud agent-registry services create pour cataloguer votre serveur MCP :
export SERVER_NAME="secure-mcp-server"
export DISPLAY_NAME="Google Cloud MCPServer"
export REGION="global"
gcloud agent-registry services create "${SERVER_NAME}" \
--project="${PROJECT_ID}" \
--location="${REGION}" \
--display-name="${DISPLAY_NAME}" \
--mcp-server-spec-type="tool-spec" \
--mcp-server-spec-content=toolspec.json \
--interfaces="url=${CLOUD_RUN_URL}/mcp,protocolBinding=jsonrpc"
Vérifiez que le service a bien été enregistré :
gcloud agent-registry services describe "${SERVER_NAME}" --location="${REGION}"
name: projects/PROJECT_ID/locations/global/services/secure-mcp-server displayName: Google Cloud MCPServer interfaces: - protocolBinding: JSONRPC url: https://secure-mcp-server-xxxx.a.run.app/mcp mcpServerSpec: type: TOOL_SPEC
Étape 3 : Créer et exécuter le client de test Service Discovery
Créez un script Python nommé src/mcp_server/test_agent_platform.py qui résout dynamiquement le point de terminaison à partir du catalogue mcp-servers d'Agent Registry, s'authentifie auprès de Google Cloud IAM et appelle un outil à l'aide de httpx2 et de MCP 2.0 Client :
import asyncio
import os
import subprocess
import httpx2 # MCP SDK 2.x utilizes httpx2 instead of httpx
from mcp import Client
from mcp.client.streamable_http import streamable_http_client
async def main() -> None:
server_name = os.getenv("SERVER_NAME", "secure-mcp-server")
location = os.getenv("REGION", "global")
# 1. Discover endpoint URL from Google Cloud Agent Registry (mcp-servers catalog)
print(f"[*] Discovering '{server_name}' in '{location}' from Agent Registry...")
url = subprocess.check_output(
[
"gcloud",
"agent-registry",
"mcp-servers",
"list",
f"--location={location}",
f"--filter=displayName='{server_name}' OR mcpServerId ~ ':{server_name}$'",
"--format=value(interfaces[0].url)",
"--limit=1",
],
text=True,
).strip()
if not url:
raise RuntimeError(
f"No endpoint URL found for '{server_name}' in location '{location}'. "
"Verify the server is registered and has an interface URL configured."
)
print(f"[+] Discovered Endpoint: {url}")
# 2. Generate IAM identity token if connecting to Cloud Run
headers: dict[str, str] = {}
if "run.app" in url:
audience = url.split("/mcp")[0]
token = subprocess.check_output(
["gcloud", "auth", "print-identity-token", f"--audiences={audience}"],
text=True,
).strip()
headers["Authorization"] = f"Bearer {token}"
# 3. Configure a custom httpx2 Client with MCP-safe timeouts
# We set read to 300s to ensure the long-lived SSE/GET stream stays open
async with httpx2.AsyncClient(
headers=headers,
timeout=httpx2.Timeout(30.0, read=300.0),
) as http_client:
# 4. Initialize Streamable HTTP Transport (yielding a 2-tuple in MCP v2.x)
transport = streamable_http_client(url, http_client=http_client)
# 5. Connect using the clean high-level Client interface
async with Client(transport) as client:
print("[+] Session active. Connected successfully.")
# Verify tools registered in the catalog (Attributes are snake_case in MCP v2)
tools_response = await client.list_tools()
print(f"[+] Discovered {len(tools_response.tools)} tools:")
for tool in tools_response.tools:
print(f" - {tool.name}")
# Test executing the health check tool
print("\n[*] Invoking tool: gcp_resource_health_checker...")
result = await client.call_tool("gcp_resource_health_checker", {})
print(f"[+] Tool Output from Agent Platform:\n{result.content[0].text}")
if __name__ == "__main__":
asyncio.run(main())
Exécutez le script de test :
uv run python src/mcp_server/test_agent_platform.py
[*] Discovering 'secure-mcp-server' in 'global' from Agent Registry...
[+] Discovered Endpoint: https://secure-mcp-server-xxxx.a.run.app/mcp
[+] Session active. Connected successfully.
[+] Discovered 4 tools:
- vertex_ai_generate_content
- gcs_bucket_inspector
- cloud_logging_audit_writer
- gcp_resource_health_checker
[*] Invoking tool: gcp_resource_health_checker...
[+] Tool Output from Agent Platform:
{"resultType": "complete", "status": "HEALTHY", "mcp_spec_version": "2026-07-28"}
2. Découverte et enregistrement automatiques du serveur MCP avec GKE
Google Kubernetes Engine (GKE) fournit une intégration automatique à Agent Registry. En ajoutant des libellés et des annotations à votre fichier manifeste de déploiement GKE, GKE effectue automatiquement une analyse d'introspection sur le serveur MCP, enregistre les outils dans le catalogue et projette le service côté consommateur sans avoir à générer ni à importer manuellement un fichier toolspec.json.
Étape 1 : Fonctionnement de la découverte automatique GKE
Lorsque votre deployment.yaml a été appliqué dans la section précédente, les configurations suivantes ont activé la découverte automatique :
registry.gke.io/functional-type: "MCP_SERVER": indique au contrôleur de cluster GKE d'enregistrer le déploiement dans Google Cloud Agent Registry.modelcontextprotocol.info/urls: fournit le point de terminaison de passerelle HTTPS externe (https://${MCP_DOMAIN}/mcp) pour l'introspection du contrôleur et le routage des consommateurs.modelcontextprotocol.info/capabilities: déclare le point de terminaison de transport HTTP (/mcp).iam.gke.io/spiffe-identity-type: agent-identity: configure Workload Identity pour la communication agentique.
Étape 2 : Vérifiez l'enregistrement automatique de GKE dans le registre des agents
Vérifiez que GKE a automatiquement détecté et enregistré votre serveur MCP dans le catalogue mcp-servers régional :
# List the automatically registered GKE MCP server in us-central1
gcloud agent-registry mcp-servers list \
--location=us-central1 \
--format="table(displayName, tools.len():label=TOOLS)"
DISPLAY_NAME TOOLS mcp-server-deployment 4
Étape 3 : Tester le serveur MCP GKE à l'aide de la découverte de services
Testez votre déploiement GKE MCP à l'aide du script de découverte de service par rapport au nom de serveur enregistré automatiquement dans us-central1 :
SERVER_NAME="mcp-server-deployment" \
REGION=us-central1 \
uv run python src/mcp_server/test_agent_platform.py
[*] Discovering 'mcp-server-deployment' in 'us-central1' from Agent Registry...
[+] Discovered Endpoint: https://mcp.34.120.x.x.nip.io/mcp
[+] Session active. Connected successfully.
[+] Discovered 4 tools:
- vertex_ai_generate_content
- gcs_bucket_inspector
- cloud_logging_audit_writer
- gcp_resource_health_checker
[*] Invoking tool: gcp_resource_health_checker...
[+] Tool Output from Agent Platform:
{"resultType": "complete", "status": "HEALTHY", "mcp_spec_version": "2026-07-28"}
8. Effectuer un nettoyage des ressources
Pour éviter que les ressources utilisées dans cet atelier de programmation ne soient facturées sur votre compte Google Cloud, supprimez le service Cloud Run, le cluster GKE, les comptes de service et le dépôt de conteneurs.
Supprimer le service Cloud Run
gcloud run services delete secure-mcp-server \
--platform=managed \
--region=us-central1 \
--quiet \
--project="${PROJECT_ID}"
Supprimer un cluster GKE Autopilot
gcloud container clusters delete mcp-gke-cluster \
--location=us-central1 \
--quiet \
--project="${PROJECT_ID}"
Supprimer des comptes de service et des liaisons IAM
gcloud iam service-accounts delete "mcp-server-cr-sa@${PROJECT_ID}.iam.gserviceaccount.com" --quiet --project="${PROJECT_ID}"
gcloud iam service-accounts delete "mcp-gke-sa@${PROJECT_ID}.iam.gserviceaccount.com" --quiet --project="${PROJECT_ID}"
Supprimer un dépôt Artifact Registry
gcloud artifacts repositories delete mcp-servers \
--location=us-central1 \
--quiet \
--project="${PROJECT_ID}"
Supprimer le service personnalisé Agent Registry
gcloud agent-registry services delete secure-mcp-server \
--location=global \
--quiet \
--project="${PROJECT_ID}"
Supprimer le bucket Cloud Storage
gcloud storage rm --recursive "gs://${BUCKET_NAME}" --quiet
Supprimer l'adresse IP statique et le certificat SSL
gcloud compute ssl-certificates delete mcp-server-cert --global --quiet --project="${PROJECT_ID}"
gcloud compute addresses delete mcp-server-ip --global --quiet --project="${PROJECT_ID}"
Vérifiez que le nettoyage de la suppression est terminé :
Deleted service [secure-mcp-server]. Deleted cluster [mcp-gke-cluster]. Deleted repository [mcp-servers].
9. Félicitations
Félicitations ! Vous avez créé, sécurisé et déployé un serveur MCP 2.0 à l'aide de MCPServer à partir du SDK Python MCP et de uv sur Google Cloud.
Sujets abordés
- Construit un
MCPServerprenant en charge la spécification MCP (2026-07-28) sur HTTP Streamable sans état. - Création de quatre outils de production Google Cloud intégrant Vertex AI Gemini, Cloud Storage, Cloud Logging et Resource Health.
- Déploiements de conteneurs sécurisés sur Cloud Run avec authentification IAM et SSL/TLS forcées.
- Authentification sans secrets configurée sur GKE Autopilot avec Workload Identity et l'API Kubernetes Gateway avec TLS.
- Points de terminaison du serveur MCP enregistrés et détectés avec Gemini Enterprise Agent Platform (Agent Registry) à l'aide d'en-têtes d'autorisation OIDC.
Étapes suivantes
- Consultez la spécification du protocole Model Context Protocol pour obtenir des ressources avancées et des définitions de requêtes.
- En savoir plus sur le SDK Python MCP
- Découvrez en détail la sécurité de Google Cloud Run et GKE Workload Identity.