1. Прежде чем начать
Протокол контекста модели (MCP) — это открытый стандарт, позволяющий моделям и агентам ИИ безопасно получать доступ к инструментам, базам данных и корпоративному контексту. С момента своего появления в 2024 году протокол получил широкое распространение среди поставщиков облачных услуг и LLM-решений. Новейшая спецификация MCP Spec 2026-07-28 (MCP 2.0) определяет архитектуру без сохранения состояния, упрощенные транспортные протоколы и строгую типизацию результатов, оставаясь при этом обратно совместимой с более ранними версиями.
Официальный Python SDK для MCP ( mcp>=2.0.0 ) предоставляет MCPServer ( mcp.server.mcpserver.MCPServer ), который заменяет FastMCP в MCP 2.0 в качестве высокопроизводительной, удобной для разработчиков платформы для создания готовых к использованию MCP-серверов, соответствующих современной спецификации MCP (2026-07-28) с потоковой передачей HTTP-трафика и передачей событий с сервера (SSE) по протоколу SSL/TLS.
В этом практическом занятии вы создадите сервер MCP производственного уровня, используя MCPServer из Python SDK MCP 2.0 и систему управления зависимостями uv . Вы оснастите свой сервер MCP четырьмя инструментами Google Cloud (вызов Vertex AI Gemini, проверка Google Cloud Storage, запись аудита Cloud Logging и проверка работоспособности ресурсов Google Cloud). Затем вы контейнеризируете сервер и развернете его на двух целевых платформах Google Cloud: Cloud Run и Google Kubernetes Engine (GKE) Autopilot , а также зарегистрируете и будете использовать сервер MCP в Gemini Enterprise Agent Platform .
Что вы будете делать
- Создайте
MCPServerс использованием 4 инструментов Google Cloud на Python 3.12+ иuv, соответствующей спецификации MCP 2026-07-28 . - Создайте контейнер для сервера MCP, используя многоэтапную сборку Docker.
- Защитите и разверните сервер MCP в Cloud Run с принудительной аутентификацией IAM и использованием SSL/TLS.
- Защитите и разверните сервер MCP в GKE Autopilot , используя Workload Identity и API Kubernetes Gateway с протоколом TLS .
- Зарегистрируйте защищенную конечную точку сервера MCP в Gemini Enterprise Agent Platform, используя заголовки токенов носителя OIDC.
Что вам понадобится
- Проект Google Cloud с включенной функцией выставления счетов.
- Установлен и настроен Google Cloud SDK (
gcloudCLI). - Установлены Python 3.12+ и менеджер пакетов
uv. -
dockerустановлен. - Установлен инструмент командной строки
kubectl.
2. Настройка среды Google Cloud.
Перед созданием ресурсов необходимо аутентифицировать свою среду и включить необходимые API Google Cloud.
Аутентификация CLI gcloud
Войдите в свою учетную запись Google Cloud:
gcloud auth login
Укажите идентификатор вашего активного проекта Google Cloud:
export PROJECT_ID=$(gcloud config get-value project)
gcloud config set project ${PROJECT_ID}
Включите облачные сервисы Google.
Включите все необходимые API для Cloud Run, GKE, Vertex AI, Artifact Registry, Cloud Build, Cloud Logging, Storage и 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}"
Убедитесь, что API-интерфейсы успешно включены:
Operation "operations/..." finished successfully.
Аутентификация приложения с использованием учетных данных по умолчанию
Для обеспечения аутентификации вашей среды разработки, клиентские библиотеки Python смогут получать доступ к Vertex AI и Cloud Storage локально во время разработки:
gcloud auth application-default login
3. Создайте MCP-сервер с помощью MCPServer и uv.
На этом этапе вы инициализируете проект Python с помощью uv и создадите MCPServer , поддерживающий четыре возможности Google Cloud.
Инициализация проекта с помощью UV-развертки.
Создайте каталог сервера и инициализируйте uv :
mkdir -p mcp-server/src/mcp_server
cd mcp-server
uv init --lib
Скопируйте код в файл 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"]
Синхронизация зависимостей с использованием uv :
uv sync
Напишите код для MCPServer.
Создайте файл реализации сервера по адресу 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,
)
Протестируйте сервер MCP локально.
Шаг 1: Запустите сервер MCP.
В основном терминале запустите сервер с помощью uv :
uv run python -m src.mcp_server.server
В логах запуска должно отобразиться подтверждение того, что HTTP-сервер Streamable прослушивает порт 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)
Оставьте этот терминал открытым и запущенным.
Шаг 2: Проверьте HTTP-конечную точку Streamable с помощью curl.
В MCP 2.0 ( MCP Spec 2026-07-28 ) initialize с сохранением состояния и заголовок Mcp-Session-Id заменены запросами без сохранения состояния. Вы можете напрямую вызывать tools/list , передавая заголовки MCP-Protocol-Version и Mcp-Method вместе с метаданными клиента в params._meta .
Откройте второе окно терминала и отправьте 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 ответит HTTP/1.1 200 OK и вернет результат в формате JSON-RPC tools/list напрямую:
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",...}]}}
Шаг 3: Запустите тестовый клиент MCP.
Для проверки обнаружения и выполнения инструментов на вашем локальном сервере по протоколу Streamable HTTP создайте тестовый клиентский скрипт 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())
Запустите тестовый клиентский скрипт с помощью uv :
uv run python src/mcp_server/test_client.py
Вы должны увидеть вывод, подтверждающий успешное подключение, обнаружение инструмента и его выполнение:
[*] 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}
После проверки нажмите CTRL+C в основном терминале, чтобы остановить локальный сервер.
4. Контейнеризация сервера MCP
Для развертывания сервера MCP в Cloud Run и GKE Autopilot упакуйте сервер в минимальный образ контейнера, используя многоэтапный Dockerfile на основе uv .
Создайте Dockerfile
В файле 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"]
Создайте и загрузите образ в реестр артефактов.
Создайте репозиторий реестра артефактов:
gcloud artifacts repositories create mcp-servers \
--repository-format=docker \
--location=us-central1 \
--description="Docker repository for MCP Servers" \
--project="${PROJECT_ID}"
Предоставьте необходимые разрешения IAM вашей учетной записи пользователя и учетной записи службы Compute Engine по умолчанию, чтобы Cloud Build мог подготавливать исходные файлы, записывать журналы и отправлять образы в реестр артефактов:
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"
Отправьте сборку образа с помощью 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}"
После завершения процесса образ вашего контейнера будет надежно сохранен в реестре артефактов:
SUCCESS: Image published to us-central1-docker.pkg.dev/.../secure-mcp-server:latest
5. Развертывание в облаке с использованием IAM и HTTPS.
Cloud Run предоставляет полностью управляемую бессерверную среду с автоматическим аннулированием HTTPS/SSL-сертификатов и детальным контролем доступа Cloud IAM.
Создать выделенный сервисный аккаунт
Создайте учетную запись службы Google с минимальными привилегиями для 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"
Развертывание сервиса в облаке.
Разверните контейнер в Cloud Run с принудительной аутентификацией IAM ( --no-allow-unauthenticated ) и управляемым SSL по умолчанию:
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}"
Получите 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}"
Проверка безопасности конечной точки
Попытка несанкционированного запроса к HTTP-терминалу Streamable вернет 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
Сгенерируйте токен OIDC ID с помощью gcloud для проверки авторизованной связи:
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",...}]}}
Тестирование работы инструмента в режиме реального времени: Инспектор облачного хранилища
Теперь, когда удаленный сервер MCP аутентифицирован и отвечает, протестируйте выполнение инструмента gcs_bucket_inspector в инфраструктуре Google Cloud.
Шаг 1: Создайте тестовый сегмент облачного хранилища.
Создайте тестовый бакет и загрузите в него образец файла:
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"
Шаг 2: Создайте удаленный клиент тестирования GCS Tool.
Создайте тестовый клиентский скрипт с именем src/mcp_server/test_gcs_tool.py для аутентификации в Cloud Run и вызова инструмента 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())
Шаг 3: Запустите удаленный тестовый клиент GCS.
Запустите тестовый скрипт, используя uv :
uv run python src/mcp_server/test_gcs_tool.py
Вы должны увидеть метаданные объекта в реальном времени, возвращаемые сервером Cloud Run MCP:
[*] 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. Развертывание в GKE Autopilot с использованием идентификации рабочей нагрузки и TLS.
Для рабочих нагрузок Kubernetes GKE Autopilot управляет выделением узлов, а Workload Identity исключает использование статических ключей учетных записей служб.
Настройка кластера автопилота GKE
Настройка кластера 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}"
Настройка идентификации рабочей нагрузки
Создайте учетную запись службы Google (GSA) и учетную запись службы Kubernetes (KSA), а затем свяжите их с помощью 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}"
Применение API развертывания и шлюза Kubernetes с TLS
Шаг 1: Зарезервируйте статический IP-адрес и получите SSL-сертификат, управляемый Google, с помощью nip.io.
Зарезервируйте глобальный внешний IP-адрес и используйте DNS-сервис nip.io с подстановочными знаками. ) для установления действительного публичного доменного имени ( MCP_DOMAIN ) перед применением манифестов 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}"
Не нужно ждать завершения подготовки SSL-сертификата, прежде чем продолжить — фактически, сертификаты, управляемые Google, остаются в состоянии PROVISIONING до тех пор, пока они не будут подключены к балансировщику нагрузки шлюза на шаге 3. Немедленно переходите к следующим шагам.
Шаг 2: Создайте манифесты развертывания и обслуживания.
Создайте deployment.yaml , содержащий определения развертывания и внутренних служб. Поскольку MCP 2.0 ( MCP Spec 2026-07-28 ) является безсостоятельным, Service Kubernetes не требует привязки IP-адреса клиента к сеансу:
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
Замените MCP_DOMAIN на PROJECT_ID и выполните развертывание:
sed -e "s|MCP_DOMAIN|${MCP_DOMAIN}|g" \
-e "s|PROJECT_ID|${PROJECT_ID}|g" \
deployment.yaml | kubectl apply -f -
Шаг 3: Создайте манифесты Gateway API, HealthCheckPolicy и GCPBackendPolicy.
Создайте gateway.yaml , содержащий информацию о шлюзе, HTTPRoute, HealthCheckPolicy ) и политике бэкенда GCPBackendPolicy :
-
HealthCheckPolicy: Настраивает балансировщик нагрузки Google Cloud для проверки доступности/healthzна порту 8080. -
GCPBackendPolicy(Backend Timeout) : УстанавливаетtimeoutSec: 300в соответствии с 300-секундным таймаутом чтения потоков Streamable HTTP / SSE в MCP SDK v2 (GKE Gateway по умолчанию устанавливает 30 секунд, если этот параметр опущен).
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
Примените параметры Gateway, HTTPRoute, HealthCheckPolicy и GCPBackendPolicy:
sed "s/MCP_DOMAIN/${MCP_DOMAIN}/g" gateway.yaml | kubectl apply -f -
Шаг 4: Проверка развертывания и тестирование сервера MCP с использованием переадресации портов.
Поскольку для предоставления SSL-сертификатов, управляемых Google, и внешних балансировщиков нагрузки Google Cloud Application Load Balancer требуется от 5 до 15 минут для настройки маршрутизации DNS, вы можете немедленно протестировать работающие поды GKE с помощью kubectl port-forward .
Для начала убедитесь, что ваши поды и шлюз запущены:
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
Далее протестируйте работу сервиса GKE локально, используя переадресацию портов:
- В терминале перенаправьте локальный порт
8080на службу GKE ClusterIP:
kubectl port-forward svc/mcp-server-service 8080:80
- Во втором терминале создайте тестовый клиентский скрипт с именем
src/mcp_server/test_vertex_tool.pyдля вызова инструментаvertex_ai_generate_contentв GKE с использованием 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))
- Запустите тестовый скрипт на локальном экземпляре с переадресацией портов:
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.
Это подтверждает, что модули GKE работают корректно, Workload Identity успешно аутентифицируется в Vertex AI без статических учетных данных, а HTTP-транспорт Streamable функционирует должным образом!
Шаг 5: Проверка общедоступной конечной точки шлюза HTTPS.
Проверить статус предоставления сертификата можно с помощью:
gcloud compute ssl-certificates describe mcp-server-cert --global --format="value(managed.status)"
После ACTIVE сертификата проверьте доступ к общедоступной HTTPS-точке с помощью тестового клиента Python с флагом --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. Интеграция MCP Server с платформой Google Cloud Agent Platform.
Теперь, когда ваш MCPServer безопасно развернут на HTTPS-конечных точках в Cloud Run и GKE Autopilot, зарегистрируйте и найдите свои инструменты MCP в Google Cloud Agent Platform (реестр агентов), чтобы корпоративные агенты и модели ИИ могли динамически обнаруживать и вызывать их.
1. Зарегистрируйте пользовательский облачный сервер MCP на платформе агентов и протестируйте его с помощью обнаружения служб.
Шаг 1: Извлечение спецификаций инструмента ( toolspec.json )
Чтобы зарегистрировать внешний или пользовательский MCP-сервер в Agent Registry , выполните запрос tools/list на вашем работающем сервере MCP 2.0 без сохранения состояния, удалите _meta на уровне инструмента и сохраните результат в toolspec.json в рамках одного конвейера:
# 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
Шаг 2: Зарегистрируйте услугу в реестре агентов.
Используйте gcloud agent-registry services create для каталогизации вашего сервера 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"
Убедитесь, что услуга успешно зарегистрирована:
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
Шаг 3: Создайте и запустите тестовый клиент обнаружения служб.
Создайте скрипт на Python с именем src/mcp_server/test_agent_platform.py , который динамически определяет конечную точку из каталога mcp-servers в реестре агентов, проходит аутентификацию в Google Cloud IAM и запускает инструмент, использующий httpx2 и Client MCP 2.0:
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())
Выполните тестовый скрипт:
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. Автоматическое обнаружение и регистрация MCP-сервера в GKE.
Google Kubernetes Engine (GKE) обеспечивает автоматическую интеграцию с Agent Registry . Путем добавления меток и аннотаций к манифесту развертывания GKE, GKE автоматически выполняет сканирование сервера MCP, регистрирует инструменты в каталоге и предоставляет доступ к сервису на стороне потребителя без необходимости вручную создавать или загружать файл toolspec.json .
Шаг 1: Как работает автоматическое обнаружение GKE
После применения файла deployment.yaml , описанного в предыдущем разделе, следующие настройки включили автоматическое обнаружение:
-
registry.gke.io/functional-type: "MCP_SERVER": Уведомляет контроллер кластера GKE о необходимости зарегистрировать развертывание в реестре агентов Google Cloud. -
modelcontextprotocol.info/urls: Предоставляет внешнюю конечную точку HTTPS-шлюза (https://${MCP_DOMAIN}/mcp) для интроспекции контроллера и маршрутизации потребителя. -
modelcontextprotocol.info/capabilities: Объявляет конечную точку HTTP-транспорта (/mcp). -
iam.gke.io/spiffe-identity-type: agent-identity: Настраивает идентификацию рабочей нагрузки для агентской связи.
Шаг 2: Проверьте автоматическую регистрацию GKE в реестре агентов.
Убедитесь, что GKE автоматически обнаружил и зарегистрировал ваш MCP-сервер в региональном каталоге mcp-servers :
# 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
Шаг 3: Тестирование сервера GKE MCP с помощью обнаружения служб.
Проверьте развертывание GKE MCP, используя скрипт обнаружения служб по имени автоматически зарегистрированного сервера в 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. Очистка ресурсов
Чтобы избежать списания средств с вашего аккаунта Google Cloud за ресурсы, использованные в этом практическом задании, удалите службу Cloud Run, кластер GKE, учетные записи служб и репозиторий контейнеров.
Удалить службу Cloud Run
gcloud run services delete secure-mcp-server \
--platform=managed \
--region=us-central1 \
--quiet \
--project="${PROJECT_ID}"
Удалить кластер автопилота GKE
gcloud container clusters delete mcp-gke-cluster \
--location=us-central1 \
--quiet \
--project="${PROJECT_ID}"
Удаление учетных записей служб и привязок 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}"
Удалить репозиторий реестра артефактов
gcloud artifacts repositories delete mcp-servers \
--location=us-central1 \
--quiet \
--project="${PROJECT_ID}"
Удаление службы пользовательской настройки реестра агентов
gcloud agent-registry services delete secure-mcp-server \
--location=global \
--quiet \
--project="${PROJECT_ID}"
Удалить корзину облачного хранилища
gcloud storage rm --recursive "gs://${BUCKET_NAME}" --quiet
Удалить статический IP-адрес и 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}"
Проверка завершения очистки после удаления:
Deleted service [secure-mcp-server]. Deleted cluster [mcp-gke-cluster]. Deleted repository [mcp-servers].
9. Поздравляем!
Поздравляем! Вы успешно создали, защитили и развернули сервер MCP 2.0, используя MCPServer из MCP Python SDK и uv в Google Cloud!
Что вы осветили
- Создан
MCPServer, поддерживающий спецификацию MCP (28.07.2026) по протоколу потокового HTTP без сохранения состояния. - Разработаны 4 производственных инструмента Google Cloud, интегрирующие Vertex AI Gemini, Cloud Storage, Cloud Logging и Resource Health.
- Безопасное развертывание контейнеров в Cloud Run с принудительной аутентификацией IAM и SSL/TLS.
- Настроена аутентификация без использования секретных ключей в GKE Autopilot с Workload Identity и Kubernetes Gateway API с TLS .
- Зарегистрированы и обнаружены конечные точки сервера MCP в Gemini Enterprise Agent Platform (реестр агентов) с использованием заголовков авторизации OIDC.
Следующие шаги
- Для получения дополнительных ресурсов и определений подсказок ознакомьтесь со спецификацией протокола контекста модели (Model Context Protocol Specification) .
- Узнайте больше о MCP Python SDK .
- Подробный анализ безопасности Google Cloud Run и системы идентификации рабочих нагрузок GKE .