1. Giriş
Bu codelab'de, Python kullanarak özel bir MCP (Model Context Protocol) sunucusu oluşturma, bunu Google Cloud Run'a dağıtma ve doğal dili kullanarak gerçek Google Cloud Storage işlemleri yürütmek için Gemini CLI ile bağlama adımları açıklanmaktadır.
Mimari Akış: Gemini CLI → Cloud Run → MCP

Şunu hayal edin: Terminalinizi açıp bir yapay zeka aracına aşağıdaki gibi basit bir istem yazıyorsunuz:
List my GCS bucketsCreate a GCS bucket named <bucket-name>Tell me about the metadata of my GCS object
Bulutunuz saniyeler içinde dinler ve yürütür. Karmaşık komutlar yok. Sekmeler arasında sürekli geçiş yapmanıza gerek kalmaz. Sadece basit bir dil, gerçek bulut işlemlerine dönüşüyor.
Yapacaklarınız
Gemini KSA'yı Google Cloud Storage'a bağlayan özel bir MCP sunucusu oluşturup dağıtacaksınız.
Bu kurstan sonra:
- Python tabanlı bir MCP sunucusu oluşturma
- Uygulamayı kapsayıcıya alma
- Cloud Run'a dağıtma
- IAM ve kimlik jetonlarını kullanarak güvenliğini sağlama
- Gemini CLI ile bağlama
- Doğal dili kullanarak canlı GCS işlemleri yürütme
Neler öğreneceksiniz?
- MCP (Model Context Protocol) nedir ve nasıl çalışır?
- Python kullanarak araç çağırma özellikleri oluşturma
- Container mimarisine alınmış uygulamaları Cloud Run'a dağıtma
- Gemini CLI, harici MCP sunucularıyla nasıl entegre olur?
- Cloud Run hizmetlerinin kimliğini güvenli bir şekilde doğrulama
- Yapay zeka kullanarak gerçek Google Cloud Storage işlemlerini yürütme
Gerekenler
- Chrome web tarayıcısı
- Gmail hesabı
- Faturalandırmanın etkin olduğu bir Google Cloud projesi
- Gemini CLI (Google Cloud Shell ile birlikte önceden yüklenmiş olarak gelir)
- Python ve Google Cloud hakkında temel düzeyde bilgi sahibi olma
Bu codelab'de, kullanıcının temel Python bilgisine sahip olduğu varsayılır.
2. Başlamadan önce
Proje oluşturma
- Google Cloud Console'daki proje seçici sayfasında bir Google Cloud projesi seçin veya oluşturun.
- Cloud projeniz için faturalandırmanın etkinleştirildiğinden emin olun. Bir projede faturalandırmanın etkin olup olmadığını kontrol etmeyi öğrenin .
- bq'nun önceden yüklendiği, Google Cloud'da çalışan bir komut satırı ortamı olan Cloud Shell'i kullanacaksınız. Google Cloud Console'un üst kısmından Cloud Shell'i etkinleştir'i tıklayın.

- Cloud Shell'e bağlandıktan sonra aşağıdaki komutu kullanarak kimliğinizin doğrulandığını ve projenin proje kimliğinize ayarlandığını kontrol edin:
gcloud auth list
- gcloud komutunun projeniz hakkında bilgi sahibi olduğunu onaylamak için Cloud Shell'de aşağıdaki komutu çalıştırın.
gcloud config list project
- Projeniz ayarlanmamışsa ayarlamak için aşağıdaki komutu kullanın:
gcloud config set project <YOUR_PROJECT_ID>
- Aşağıdaki komutu kullanarak gerekli API'leri etkinleştirin. Bu işlem birkaç dakika sürebilir. Lütfen bekleyin.
gcloud services enable \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com
Yetkilendirmeniz istenirse devam etmek için Yetkilendir'i tıklayın.

Komut başarıyla yürütüldüğünde aşağıda gösterilene benzer bir mesaj görürsünüz:
Operation "operations/..." finished successfully.
Herhangi bir API atlanırsa uygulama sırasında istediğiniz zaman etkinleştirebilirsiniz.
gcloud komutları ve kullanımı için belgelere bakın.
Python projenizi hazırlama
Bu bölümde, MCP sunucunuza ev sahipliği yapacak Python projesini oluşturacak ve bağımlılıklarını Cloud Run'a dağıtım için yapılandıracaksınız.
Proje dizinini oluşturma
Kaynak kodunuzu depolamak için mcp-on-cloudrun adlı yeni bir klasör oluşturarak başlayın:
mkdir gcs-mcp-server && cd gcs-mcp-server
requirements.txt dosyasını oluşturma
touch requirements.txt
cloudshell edit ~/gcs-mcp-server/requirements.txt
Dosyaya aşağıdaki içeriği ekleyin:
fastmcp
google-cloud-storage
google-api-core
pydantic
Dosyayı kaydedin.
3. MCP sunucusunu oluşturma
Bu bölümde, Google Cloud Storage işlemlerini çağrılabilir araçlar olarak kullanıma sunan MCP sunucusunu oluşturacaksınız.
Bu sunucu:
- MCP araçlarını kaydetme
- Google Cloud Storage'a bağlanma
- HTTP üzerinden çalıştırma
- Cloud Run'a dağıtılabilir olmalıdır.
Şimdi main.py içinde temel MCP mantığımızı oluşturalım.
Aşağıda, paketleri listelemek ve oluşturmaktan blob'ları yüklemek, indirmek ve yönetmeye kadar Google Cloud Storage'ı yönetmeye yönelik birden fazla aracı tanımlayan tam kod yer almaktadır.
Ana uygulama dosyasını oluşturma
mcp-on-cloudrun dizininde main.py adlı yeni bir dosya oluşturun:
touch main.py
Dosyayı Cloud Shell Düzenleyici'yi kullanarak açın:
cloudshell edit ~/gcs-mcp-server/main.py
main.py dosya içeriğine aşağıdaki kaynağı ekleyin:
import asyncio
import logging
import os
from datetime import timedelta
from typing import List, Dict, Any
from fastmcp import FastMCP
from google.cloud import storage
from google.api_core import exceptions
# ---------------------------------------------------------
# 🌐 Initialize MCP
# ---------------------------------------------------------
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
logger = logging.getLogger(__name__)
mcp = FastMCP(name="MyEnhancedGCSMCPServer")
# ---------------------------------------------------------
# 1️⃣ Simple Greeting
# ---------------------------------------------------------
@mcp.tool
def sayhi(name: str) -> str:
"""Returns a friendly greetings"""
return f"Hello {name}! It's a pleasure to connect from your enhanced MCP Server."
# ---------------------------------------------------------
# 2️⃣ List all GCS buckets
# ---------------------------------------------------------
@mcp.tool
def list_gcs_buckets() -> List[str]:
"""Lists all GCS buckets in the project."""
try:
storage_client = storage.Client()
buckets = storage_client.list_buckets()
return [bucket.name for bucket in buckets]
except exceptions.Forbidden as e:
return [f"Error: Permission denied to list buckets. Details: {e}"]
except Exception as e:
return [f"An unexpected error occurred: {e}"]
# ---------------------------------------------------------
# 3️⃣ Create a new bucket
# ---------------------------------------------------------
@mcp.tool
def create_bucket(bucket_name: str, location: str = "US") -> str:
"""Creates a new GCS bucket. Bucket names must be globally unique."""
try:
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
bucket.location = location
storage_client.create_bucket(bucket)
return f"✅ Bucket '{bucket_name}' created successfully in '{location}'."
except exceptions.Conflict:
return f"⚠️ Error: Bucket '{bucket_name}' already exists."
except exceptions.Forbidden as e:
return f"❌ Error: Permission denied to create bucket. Details: {e}"
except Exception as e:
return f"❌ Unexpected error: {e}"
# ---------------------------------------------------------
# 4️⃣ Delete a bucket
# ---------------------------------------------------------
@mcp.tool
def delete_bucket(bucket_name: str) -> str:
"""Deletes a GCS bucket."""
try:
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
bucket.delete(force=True)
return f"🗑️ Bucket '{bucket_name}' deleted successfully."
except exceptions.NotFound:
return f"⚠️ Error: Bucket '{bucket_name}' not found."
except exceptions.Forbidden as e:
return f"❌ Error: Permission denied to delete bucket. Details: {e}"
except Exception as e:
return f"❌ Unexpected error: {e}"
# ---------------------------------------------------------
# 5️⃣ List objects in a bucket
# ---------------------------------------------------------
@mcp.tool
def list_objects(bucket_name: str) -> List[str]:
"""Lists all objects in a specified GCS bucket."""
try:
storage_client = storage.Client()
blobs = storage_client.list_blobs(bucket_name)
return [blob.name for blob in blobs]
except exceptions.NotFound:
return [f"⚠️ Error: Bucket '{bucket_name}' not found."]
except Exception as e:
return [f"❌ Unexpected error: {e}"]
# ---------------------------------------------------------
# Delete file from a bucket
# ---------------------------------------------------------
@mcp.tool
def delete_blob(bucket_name: str, blob_name: str) -> str:
"""Deletes a blob from a GCS bucket."""
try:
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(blob_name)
blob.delete()
return f"🗑️ Blob '{blob_name}' deleted from bucket '{bucket_name}'."
except exceptions.NotFound:
return f"⚠️ Error: Bucket '{bucket_name}' or blob '{blob_name}' not found."
except exceptions.Forbidden as e:
return f" Permission denied. Details: {e}"
except Exception as e:
return f" Unexpected error: {e}"
# ---------------------------------------------------------
# Get bucket metadata
# ---------------------------------------------------------
@mcp.tool
def get_bucket_metadata(bucket_name: str) -> Dict[str, Any]:
"""Retrieves metadata for a GCS bucket."""
try:
storage_client = storage.Client()
bucket = storage_client.get_bucket(bucket_name)
return {
"id": bucket.id,
"name": bucket.name,
"location": bucket.location,
"storage_class": bucket.storage_class,
"created": bucket.time_created.isoformat() if bucket.time_created else None,
"updated": bucket.updated.isoformat() if bucket.updated else None,
"versioning_enabled": bucket.versioning_enabled,
}
except exceptions.NotFound:
return {"error": f" Bucket '{bucket_name}' not found."}
except Exception as e:
return {"error": f" Unexpected error: {e}"}
# ---------------------------------------------------------
# Get object metadata
# ---------------------------------------------------------
@mcp.tool
def get_blob_metadata(bucket_name: str, blob_name: str) -> Dict[str, Any]:
"""Retrieves metadata for a specific blob."""
try:
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
blob = bucket.get_blob(blob_name)
if not blob:
return {"error": f" Blob '{blob_name}' not found in '{bucket_name}'."}
return {
"name": blob.name,
"bucket": blob.bucket.name,
"size": blob.size,
"content_type": blob.content_type,
"updated": blob.updated.isoformat() if blob.updated else None,
"storage_class": blob.storage_class,
"crc32c": blob.crc32c,
"md5_hash": blob.md5_hash,
}
except exceptions.NotFound:
return {"error": f" Bucket '{bucket_name}' not found."}
except Exception as e:
return {"error": f" Unexpected error: {e}"}
# ---------------------------------------------------------
# 🚀 Entry Point
# ---------------------------------------------------------
if __name__ == "__main__":
port = int(os.getenv("PORT", 8080))
logger.info(f"🚀 Starting Enhanced GCS MCP Server on port {port}")
asyncio.run(
mcp.run_async(
transport="http",
host="0.0.0.0",
port=port,
)
)
Kodu ekledikten sonra dosyayı kaydedin.
Proje yapınız artık şu şekilde görünmelidir:
gcs-mcp-server/
├── requirements.txt
└── main.py
Kodu kısaca açıklayalım:
İçe Aktarma ve Kurulum:
Kod, gerekli kitaplıkları içe aktararak başlar.
- Standart Kitaplıklar:
asyncioeşzamansız yürütme,loggingdurum mesajları çıkışı veosortam değişkenleri için. - FastMCP: Model Context Protocol sunucusunu oluşturmak için kullanılan temel çerçeve.
- Google Cloud Storage: GCS ile etkileşim için
google.cloud.storagekitaplığı, hata işleme için deexceptionskitaplığı içe aktarılır.
İlk kullanıma hazırlama:
Sunucunun kimliğini ayıklamaya ve izlemeye yardımcı olması için günlük biçimini yapılandırırız. Ayrıca, FastMCP adlı MyEnhancedGCSMCPServer örneğini de yapılandırıyoruz. Bu nesne (mcp), sunucunun kullanıma sunduğu tüm araçları (işlevleri) kaydetmek için kullanılır. Aşağıdaki araçları tanımlıyoruz:
list_gcs_buckets: İlişkili Google Cloud projesindeki tüm depolama paketlerinin listesini alır.create_bucket: Belirli bir ad ve konumla yeni bir paket oluşturur.delete_bucket: Mevcut bir paketi siler.list_objects: Belirli bir paketin içindeki tüm dosyaları (blob'lar) listeler.delete_blob: Bir paketteki tek bir dosyayı siler.get_bucket_metadata: Paketle ilgili teknik ayrıntıları (Konum, Depolama Sınıfı, Sürüm Oluşturma durumu, Oluşturma zamanı) döndürür.get_blob_metadata: Belirli bir dosya hakkında teknik ayrıntıları (Boyut, İçerik Türü, MD5 Hash, Son Güncelleme) döndürür.
Giriş noktası:
Bu, bağlantı noktasını yapılandırır. Ayarlanmamışsa varsayılan olarak 8080 kullanılır. Ardından, sunucuyu mcp.run_async ile eşzamansız olarak başlatmak için asyncio.run() kullanılır. Son olarak, sunucuyu HTTP üzerinden çalışacak şekilde yapılandırır (host 0.0.0.0) ve gelen ağ istekleri için erişilebilir hale getirir.
4. MCP sunucusunu kapsayıcıya yerleştirme
Bu bölümde, MCP sunucunuzun Cloud Run'a dağıtılabilmesi için bir Dockerfile oluşturacaksınız.
Cloud Run için kapsayıcıya alınmış bir uygulama gerekir. Uygulamanızın nasıl oluşturulacağını ve başlatılacağını tanımlarsınız.
Dockerfile'ı oluşturma
Dockerfile adlı yeni bir dosya oluşturun:
touch Dockerfile
Cloud Shell Düzenleyici'de açın:
cloudshell edit ~/gcs-mcp-server/Dockerfile
Docker yapılandırması ekleme
Aşağıdaki içeriği Dockerfile içine yapıştırın:
FROM python:3.11-slim
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /app
RUN apt-get update && apt-get install -y \
build-essential \
gcc \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --upgrade pip
COPY . .
RUN pip install -r requirements.txt
ENV PORT=8080
EXPOSE 8080
CMD ["python", "main.py"]
İçeriği ekledikten sonra dosyayı kaydedin. Proje yapınız artık şu şekilde görünmelidir:
gcs-mcp-server/
├── requirements.txt
├── main.py
└── Dockerfile
5. Cloud Run'a dağıtma
Artık MCP sunucunuzu doğrudan kaynaktan dağıtabilirsiniz.
Cloud Shell'de aşağıdaki komutu çalıştırın:
gcloud run deploy gcs-mcp-server \
--no-allow-unauthenticated \
--region=us-central1 \
--source=. \
--labels=session=buildersdayblr
İstendiğinde
- Kimliği doğrulanmamış çağrılara izin verilsin mi? → Hayır
Cloud Build:
- Container görüntüsünü oluşturma
- Artifact Registry'ye aktarın.
- Cloud Run'a dağıtma
Artifact Registry deposunun oluşturulabileceğini onaylamak için Y yazın.
Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-central1] will be created.
Do you want to continue (Y/n)? Y
Dağıtım başarılı olduktan sonra Cloud Run hizmeti URL'sini içeren bir başarı mesajı görürsünüz.
Dağıtımı Cloud Run → Servicesbölümündeki Google Cloud Console'unuzdan da doğrulayabilirsiniz.

6. Gemini CLI Yapılandırması
Şimdiye kadar MCP sunucumuzu Cloud Run'da oluşturup dağıttık.
Şimdi eğlenceli kısma geçme zamanı: Gemini CLI ile bağlayıp doğal dil istemlerinizi gerçek bulut işlemlerine dönüştürme.
Cloud Run Invoker izni verme
Cloud Run hizmetimiz özel olduğundan kimlik doğrulama için kimlik jetonu kullanıp doğru IAM izinlerini atayacağız.
Hizmeti --no-allow-unauthenticated ile dağıttık. Bu nedenle, hizmeti çağırmak için izin vermeniz gerekir.
Projenizin kimliğini belirleyin:
export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
Kendinize Cloud Run Çağırıcı rolünü verin:
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
--member=user:$(gcloud config get-value account) \
--role='roles/run.invoker'
Bu, hesabınızın Cloud Run hizmetini güvenli bir şekilde çağırmasına olanak tanır.
Kimlik jetonu oluşturma
Cloud Run, kimliği doğrulanmış erişim için kimlik jetonu gerektirir.
Oluşturma:
export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
export ID_TOKEN=$(gcloud auth print-identity-token)
Doğrulayın:
echo $PROJECT_NUMBER
echo $ID_TOKEN
Bu jetonu Gemini CLI yapılandırmasında kullanacaksınız.
Gemini KSA'da MCP sunucusunu yapılandırma
Gemini CLI ayarları dosyasını açın:
cloudshell edit ~/.gemini/settings.json
Aşağıdaki yapılandırmayı ekleyin:
{
"ide": {
"enabled": true,
"hasSeenNudge": true
},
"mcpServers": {
"my-cloudrun-server": {
"httpUrl": "https://gcs-mcp-server-$PROJECT_NUMBER.asia-south1.run.app/mcp",
"headers": {
"Authorization": "Bearer $ID_TOKEN"
}
}
},
"security": {
"auth": {
"selectedType": "cloud-shell"
}
}
}
Gemini KSA'da yapılandırılan MCP sunucularını doğrulama
Aşağıdaki komutu kullanarak Cloud Shell terminalinde Gemini CLI'yı başlatın:
gemini
Aşağıdaki çıkışı görürsünüz.

Gemini CLI'da şu komutu çalıştırın:
/mcp refresh
/mcp list
gcs-cloudrun-server'nizin kaydedildiğini göreceksiniz. Örnek ekran görüntüsü aşağıda gösterilmiştir:

7. Doğal dil kullanarak Google Storage işlemlerini çağırma
Paket oluşturma
Create a bucket named my-ai-bucket in asia-south1 region
Bu işlem, MCP sunucusundan create_bucket aracını çağırmak için izninizi ister.

Bir kez İzin Ver'i tıkladığınızda paketiniz, istediğiniz bölgede başarıyla oluşturulur.
Paketleri listeleme
Grupları listelemek için aşağıdaki istemi girin:
List all my GCS buckets
Paketi silme
Bir paketi silmek için aşağıdaki istemi girin (<your_bucket_name> yerine paketinizin adını yazın):
Delete the bucket <your_bucket_name>
Paketin meta verilerini alma
Bir paketin meta verilerini almak için aşağıdaki istemi girin (<your_bucket_name> yerine paketinizin adını yazın):
Give me metadata of the <your_bucket_name>
8. Temizleme
Bu işlem genellikle geri alınamaz olduğundan, Google Cloud projesini silmeye karar vermeden önce bu bölümün tamamını okuyun.
Bu codelab'de kullanılan kaynaklar için Google Cloud hesabınızın ücretlendirilmesini istemiyorsanız şu adımları uygulayın:
- Google Cloud Console'da Kaynakları yönetin sayfasına gidin.
- Proje listesinde, silmek istediğiniz projeyi seçin.
- Sil'i tıklayın.
İletişim kutusunda Proje kimliği'ni yazın ve ardından projeyi kalıcı olarak silmek için Kapat'ı tıklayın.
Projenin silinmesi, Cloud Run hizmetleri ve Artifact Registry'de depolanan kapsayıcı görüntüleri de dahil olmak üzere bu projede kullanılan tüm kaynaklar için faturalandırmayı durdurur.
Alternatif olarak, projeyi tutmak ancak dağıtılan hizmeti kaldırmak istiyorsanız:
- Google Cloud Console'da Cloud Run'a gidin.
- gcs-mcp-server hizmetini seçin.
- Hizmeti kaldırmak için Sil'i tıklayın.
veya Cloud Shell terminalinde aşağıdaki gcloud komutunu verin.
gcloud run services delete gcs-mcp-server --region=us-central1
9. Sonuç
🎉 Tebrikler! İlk yapay zeka destekli bulut iş akışınızı oluşturdunuz.
Uyguladığınız:
- Özel Python tabanlı bir MCP sunucusu
- Google Cloud Storage için araç çağırma özellikleri
- Docker kullanarak konteynerleştirme
- Cloud Run'a güvenli dağıtım
- Kimlik tabanlı kimlik doğrulama
- Gemini CLI ile entegrasyon
Artık bu mimariyi BigQuery, Pub/Sub veya Compute Engine gibi ek Google Cloud hizmetlerini destekleyecek şekilde genişletebilirsiniz.
Bu kalıp, yapay zeka sistemlerinin yapılandırılmış araç çağırma yoluyla bulut altyapısıyla nasıl güvenli bir şekilde etkileşim kurabileceğini gösterir.