1. Pengantar
Ringkasan
Di lab ini, Anda akan membangun dan men-deploy server Model Context Protocol (MCP). Server MCP berguna untuk memberi LLM akses ke alat dan layanan eksternal. Anda akan mengonfigurasinya sebagai layanan yang aman dan siap produksi di Cloud Run yang dapat diakses dari beberapa klien. Kemudian, Anda akan terhubung ke server MCP jarak jauh dari Gemini CLI.
Yang akan Anda lakukan
Kita akan menggunakan FastMCP untuk membuat server MCP kebun binatang yang memiliki dua alat: get_animals_by_species
dan get_animal_details
. FastMCP menyediakan cara cepat dan Pythonic untuk membangun server dan klien MCP.
Yang akan Anda pelajari
- Deploy server MCP ke Cloud Run.
- Amankan endpoint server Anda dengan mewajibkan autentikasi untuk semua permintaan, sehingga hanya klien dan agen yang diberi otorisasi yang dapat berkomunikasi dengannya.
- Menghubungkan ke endpoint server MCP aman dari Gemini CLI
2. Penyiapan Project
- Jika belum memiliki Akun Google, Anda harus membuat Akun Google.
- Gunakan akun pribadi, bukan akun kantor atau sekolah. Akun kantor dan sekolah mungkin memiliki batasan yang mencegah Anda mengaktifkan API yang diperlukan untuk lab ini.
- Login ke Konsol Google Cloud.
- Aktifkan penagihan di Konsol Cloud.
- Menyelesaikan lab ini akan dikenai biaya kurang dari $1 USD untuk resource Cloud.
- Anda dapat mengikuti langkah-langkah di akhir lab ini untuk menghapus resource agar tidak dikenai biaya lebih lanjut.
- Pengguna baru memenuhi syarat untuk mengikuti Uji Coba Gratis senilai$300 USD.
- Buat project baru atau pilih untuk menggunakan kembali project yang ada.
3. Buka Cloud Shell Editor
- Klik link ini untuk langsung membuka Cloud Shell Editor
- Jika diminta untuk memberikan otorisasi kapan saja hari ini, klik Authorize untuk melanjutkan.
- Jika terminal tidak muncul di bagian bawah layar, buka terminal:
- Klik Lihat
- Klik Terminal
- Di terminal, tetapkan project Anda dengan perintah ini:
- Format:
gcloud config set project [PROJECT_ID]
- Contoh:
gcloud config set project lab-project-id-example
- Jika Anda tidak ingat project ID Anda:
- Anda dapat mencantumkan semua project ID Anda dengan:
gcloud projects list | awk '/PROJECT_ID/{print $2}'
- Anda dapat mencantumkan semua project ID Anda dengan:
- Format:
- Anda akan melihat pesan ini:
Jika Anda melihatUpdated property [core/project].
WARNING
dan dimintaDo you want to continue (Y/n)?
, berarti Anda kemungkinan telah memasukkan ID project dengan salah. Tekann
, tekanEnter
, lalu coba jalankan perintahgcloud config set project
lagi.
4. Mengaktifkan API
Di terminal, aktifkan API:
gcloud services enable \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com
Jika diminta untuk memberikan otorisasi, klik Authorize untuk melanjutkan.
Pemrosesan perintah ini mungkin membutuhkan waktu beberapa menit, tetapi pada akhirnya akan menghasilkan pesan keberhasilan yang serupa dengan pesan berikut:
Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.
5. Menyiapkan project Python
- Buat folder bernama
mcp-on-cloudrun
untuk menyimpan kode sumber untuk deployment:mkdir mcp-on-cloudrun && cd mcp-on-cloudrun
- Buat project Python dengan alat
uv
untuk menghasilkan filepyproject.toml
: Perintahuv init --description "Example of deploying an MCP server on Cloud Run" --bare --python 3.13
uv init
akan membuat filepyproject.toml
untuk project Anda.Untuk melihat konten file, jalankan perintah berikut: Output-nya akan terlihat seperti berikut:cat pyproject.toml
[project] name = "mcp-on-cloudrun" version = "0.1.0" description = "Example of deploying an MCP server on Cloud Run" requires-python = ">=3.13" dependencies = []
6. Membuat server MCP kebun binatang
Untuk memberikan konteks berharga dalam meningkatkan penggunaan LLM dengan MCP, siapkan server MCP Zoo dengan FastMCP — framework standar untuk bekerja dengan Model Context Protocol. FastMCP menyediakan cara cepat untuk membangun server dan klien MCP dengan Python. Server MCP ini menyediakan data tentang hewan di kebun binatang fiktif. Untuk mempermudah, kita menyimpan data dalam memori. Untuk server MCP produksi, Anda mungkin ingin menyediakan data dari sumber seperti database atau API.
- Jalankan perintah berikut untuk menambahkan FastMCP sebagai dependensi dalam file
pyproject.toml
: Tindakan ini akan menambahkan fileuv add fastmcp==2.11.1 --no-sync
uv.lock
ke project Anda. - Buat dan buka file
server.py
baru untuk kode sumber server MCP: Perintahcloudshell edit server.py
cloudshell edit
akan membuka fileserver.py
di editor di atas terminal. - Tambahkan kode sumber server MCP zoo berikut dalam file
server.py
:import asyncio import logging import os from typing import List, Dict, Any from fastmcp import FastMCP logger = logging.getLogger(__name__) logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO) mcp = FastMCP("Zoo Animal MCP Server 🦁🐧🐻") # Dictionary of animals at the zoo ZOO_ANIMALS = [ { "species": "lion", "name": "Leo", "age": 7, "enclosure": "The Big Cat Plains", "trail": "Savannah Heights" }, { "species": "lion", "name": "Nala", "age": 6, "enclosure": "The Big Cat Plains", "trail": "Savannah Heights" }, { "species": "lion", "name": "Simba", "age": 3, "enclosure": "The Big Cat Plains", "trail": "Savannah Heights" }, { "species": "lion", "name": "King", "age": 8, "enclosure": "The Big Cat Plains", "trail": "Savannah Heights" }, { "species": "penguin", "name": "Waddles", "age": 2, "enclosure": "The Arctic Exhibit", "trail": "Polar Path" }, { "species": "penguin", "name": "Pip", "age": 4, "enclosure": "The Arctic Exhibit", "trail": "Polar Path" }, { "species": "penguin", "name": "Skipper", "age": 5, "enclosure": "The Arctic Exhibit", "trail": "Polar Path" }, { "species": "penguin", "name": "Chilly", "age": 3, "enclosure": "The Arctic Exhibit", "trail": "Polar Path" }, { "species": "penguin", "name": "Pingu", "age": 6, "enclosure": "The Arctic Exhibit", "trail": "Polar Path" }, { "species": "penguin", "name": "Noot", "age": 1, "enclosure": "The Arctic Exhibit", "trail": "Polar Path" }, { "species": "elephant", "name": "Ellie", "age": 15, "enclosure": "The Pachyderm Sanctuary", "trail": "Savannah Heights" }, { "species": "elephant", "name": "Peanut", "age": 12, "enclosure": "The Pachyderm Sanctuary", "trail": "Savannah Heights" }, { "species": "elephant", "name": "Dumbo", "age": 5, "enclosure": "The Pachyderm Sanctuary", "trail": "Savannah Heights" }, { "species": "elephant", "name": "Trunkers", "age": 10, "enclosure": "The Pachyderm Sanctuary", "trail": "Savannah Heights" }, { "species": "bear", "name": "Smokey", "age": 10, "enclosure": "The Grizzly Gulch", "trail": "Polar Path" }, { "species": "bear", "name": "Grizzly", "age": 8, "enclosure": "The Grizzly Gulch", "trail": "Polar Path" }, { "species": "bear", "name": "Barnaby", "age": 6, "enclosure": "The Grizzly Gulch", "trail": "Polar Path" }, { "species": "bear", "name": "Bruin", "age": 12, "enclosure": "The Grizzly Gulch", "trail": "Polar Path" }, { "species": "giraffe", "name": "Gerald", "age": 4, "enclosure": "The Tall Grass Plains", "trail": "Savannah Heights" }, { "species": "giraffe", "name": "Longneck", "age": 5, "enclosure": "The Tall Grass Plains", "trail": "Savannah Heights" }, { "species": "giraffe", "name": "Patches", "age": 3, "enclosure": "The Tall Grass Plains", "trail": "Savannah Heights" }, { "species": "giraffe", "name": "Stretch", "age": 6, "enclosure": "The Tall Grass Plains", "trail": "Savannah Heights" }, { "species": "antelope", "name": "Speedy", "age": 2, "enclosure": "The Tall Grass Plains", "trail": "Savannah Heights" }, { "species": "antelope", "name": "Dash", "age": 3, "enclosure": "The Tall Grass Plains", "trail": "Savannah Heights" }, { "species": "antelope", "name": "Gazelle", "age": 4, "enclosure": "The Tall Grass Plains", "trail": "Savannah Heights" }, { "species": "antelope", "name": "Swift", "age": 5, "enclosure": "The Tall Grass Plains", "trail": "Savannah Heights" }, { "species": "polar bear", "name": "Snowflake", "age": 7, "enclosure": "The Arctic Exhibit", "trail": "Polar Path" }, { "species": "polar bear", "name": "Blizzard", "age": 5, "enclosure": "The Arctic Exhibit", "trail": "Polar Path" }, { "species": "polar bear", "name": "Iceberg", "age": 9, "enclosure": "The Arctic Exhibit", "trail": "Polar Path" }, { "species": "walrus", "name": "Wally", "age": 10, "enclosure": "The Walrus Cove", "trail": "Polar Path" }, { "species": "walrus", "name": "Tusker", "age": 12, "enclosure": "The Walrus Cove", "trail": "Polar Path" }, { "species": "walrus", "name": "Moby", "age": 8, "enclosure": "The Walrus Cove", "trail": "Polar Path" }, { "species": "walrus", "name": "Flippers", "age": 9, "enclosure": "The Walrus Cove", "trail": "Polar Path" } ] @mcp.tool() def get_animals_by_species(species: str) -> List[Dict[str, Any]]: """ Retrieves all animals of a specific species from the zoo. Can also be used to collect the base data for aggregate queries of animals of a specific species - like counting the number of penguins or finding the oldest lion. Args: species: The species of the animal (e.g., 'lion', 'penguin'). Returns: A list of dictionaries, where each dictionary represents an animal and contains details like name, age, enclosure, and trail. """ logger.info(f">>> 🛠️ Tool: 'get_animals_by_species' called for '{species}'") return [animal for animal in ZOO_ANIMALS if animal["species"].lower() == species.lower()] @mcp.tool() def get_animal_details(name: str) -> Dict[str, Any]: """ Retrieves the details of a specific animal by its name. Args: name: The name of the animal. Returns: A dictionary with the animal's details (species, name, age, enclosure, trail) or an empty dictionary if the animal is not found. """ logger.info(f">>> 🛠️ Tool: 'get_animal_details' called for '{name}'") for animal in ZOO_ANIMALS: if animal["name"].lower() == name.lower(): return animal return {} if __name__ == "__main__": logger.info(f"🚀 MCP server started on port {os.getenv('PORT', 8080)}") asyncio.run( mcp.run_async( transport="http", host="0.0.0.0", port=os.getenv("PORT", 8080), ) )
Kode Anda sudah selesai! Sekarang saatnya men-deploy server MCP ke Cloud Run.
7. Men-deploy ke Cloud Run
Sekarang, deploy server MCP ke Cloud Run langsung dari kode sumber.
- Buat dan buka
Dockerfile
baru untuk men-deploy ke Cloud Run:cloudshell edit Dockerfile
- Sertakan kode berikut dalam Dockerfile untuk menggunakan alat
uv
dalam menjalankan fileserver.py
:# Use the official Python image FROM python:3.13-slim # Install uv COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ # Install the project into /app COPY . /app WORKDIR /app # Allow statements and log messages to immediately appear in the logs ENV PYTHONUNBUFFERED=1 # Install dependencies RUN uv sync EXPOSE $PORT # Run the FastMCP server CMD ["uv", "run", "server.py"]
- Jalankan perintah
gcloud
untuk men-deploy aplikasi ke Cloud Run Gunakan flaggcloud run deploy zoo-mcp-server \ --no-allow-unauthenticated \ --region=europe-west1 \ --source=. \ --labels=dev-tutorial=codelab-mcp
--no-allow-unauthenticated
untuk mewajibkan autentikasi. Hal ini penting karena alasan keamanan. Jika Anda tidak memerlukan autentikasi, siapa pun dapat memanggil server MCP Anda dan berpotensi menyebabkan kerusakan pada sistem Anda. - Konfirmasi pembuatan repositori Artifact Registry baru Karena ini adalah pertama kalinya Anda men-deploy ke Cloud Run dari kode sumber, Anda akan melihat:
KetikDeploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [europe-west1] will be created. Do you want to continue (Y/n)?
Y
dan tekanEnter
, tindakan ini akan membuat repositori Artifact Registry untuk deployment Anda. Hal ini diperlukan untuk menyimpan container Docker server MCP untuk layanan Cloud Run. - Setelah beberapa menit, Anda akan melihat pesan seperti:
Service [zoo-mcp-server] revision [zoo-mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.
Anda telah men-deploy server MCP. Sekarang Anda dapat menggunakannya.
8. Menambahkan Server MCP Jarak Jauh ke Gemini CLI
Setelah berhasil men-deploy server MCP jarak jauh, Anda dapat terhubung ke server tersebut menggunakan berbagai aplikasi seperti Google Code Assist atau Gemini CLI. Di bagian ini, kita akan membuat koneksi ke server MCP jarak jauh baru menggunakan Gemini CLI.
- Beri akun pengguna Anda izin untuk memanggil server MCP jarak jauh
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \ --member=user:$(gcloud config get-value account) \ --role='roles/run.invoker'
- Simpan kredensial Google Cloud dan nomor project Anda dalam variabel lingkungan untuk digunakan dalam file Setelan Gemini:
export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)") export ID_TOKEN=$(gcloud auth print-identity-token)
- Buka file Setelan Gemini CLI Anda
cloudshell edit ~/.gemini/settings.json
- Mengganti file setelan Gemini CLI untuk menambahkan server MCP Cloud Run
{ "mcpServers": { "zoo-remote": { "httpUrl": "https://zoo-mcp-server-$PROJECT_NUMBER.europe-west1.run.app/mcp/", "headers": { "Authorization": "Bearer $ID_TOKEN" } } }, "selectedAuthType": "cloud-shell", "hasSeenIdeIntegrationNudge": true }
- Mulai Gemini CLI di Cloud Shell
Anda mungkin perlu menekangemini
Enter
untuk menyetujui beberapa setelan default. - Meminta Gemini membuat daftar alat MCP yang tersedia untuknya dalam konteksnya
/mcp
- Minta Gemini untuk menemukan sesuatu di kebun binatang
Gemini CLI akan mengetahui cara menggunakan Server MCPWhere can I find penguins?
zoo-remote
dan akan menanyakan apakah Anda ingin mengizinkan eksekusi MCP. - Gunakan panah bawah, lalu tekan
Enter
untuk memilihYes, always allow all tools from server "zoo-remote"
Output harus menampilkan jawaban yang benar dan kotak tampilan yang menunjukkan bahwa server MCP digunakan.
Anda berhasil! Anda telah berhasil men-deploy server MCP jarak jauh ke Cloud Run dan mengujinya menggunakan Gemini CLI.
Jika Anda sudah siap mengakhiri sesi, ketik /quit
, lalu tekan Enter
untuk keluar dari Gemini CLI.
Proses debug
Jika Anda melihat error seperti ini:
🔍 Attempting OAuth discovery for 'zoo-remote'... ❌ 'zoo-remote' requires authentication but no OAuth configuration found Error connecting to MCP server 'zoo-remote': MCP server 'zoo-remote' requires authentication. Please configure OAuth or check server settings.
Kemungkinan Token ID telah habis masa berlakunya dan perlu menyetel ID_TOKEN
lagi.
- Ketik
/quit
, lalu tekanEnter
untuk keluar dari Gemini CLI. - Tetapkan project Anda di terminal
gcloud config set project [PROJECT_ID]
- Mulai ulang di langkah 2 di atas
9. (Opsional) Memverifikasi Panggilan Alat di Log Server
Untuk memverifikasi bahwa server MCP Cloud Run Anda dipanggil, periksa log layanan.
gcloud run services logs read zoo-mcp-server --region europe-west1 --limit=5
Anda akan melihat log output yang mengonfirmasi bahwa panggilan alat telah dilakukan. 🛠️
2025-08-05 19:50:31 INFO: 169.254.169.126:39444 - "POST /mcp/ HTTP/1.1" 200 OK 2025-08-05 19:50:31 [INFO]: Processing request of type CallToolRequest 2025-08-05 19:50:31 [INFO]: >>> 🛠️ Tool: 'get_animals_by_species' called for 'penguin'
10. (Opsional) Menambahkan perintah MCP ke Server
Perintah MCP dapat mempercepat alur kerja untuk perintah yang sering Anda jalankan dengan membuat singkatan untuk perintah yang lebih panjang.
Gemini CLI secara otomatis mengonversi perintah MCP menjadi perintah garis miring kustom sehingga Anda dapat memanggil perintah MCP dengan mengetik /prompt_name
, dengan prompt_name
adalah nama perintah MCP Anda.
Buat perintah MCP agar Anda dapat dengan cepat menemukan hewan di kebun binatang dengan mengetik /find animal
ke Gemini CLI.
- Tambahkan kode ini ke file
server.py
Anda di atas penjaga utama (if __name__ == "__main__":
)@mcp.prompt() def find(animal: str) -> str: """ Find which exhibit and trail a specific animal might be located. """ return ( f"Please find the exhibit and trail information for {animal} in the zoo. " f"Respond with '[animal] can be found in the [exhibit] on the [trail].'" f"Example: Penguins can be found in The Arctic Exhibit on the Polar Path." )
- Men-deploy ulang aplikasi Anda ke Cloud Run
gcloud run deploy zoo-mcp-server \ --no-allow-unauthenticated \ --region=europe-west1 \ --source=. \ --labels=dev-tutorial=codelab-mcp
- Memperbarui ID_TOKEN untuk server MCP jarak jauh
export ID_TOKEN=$(gcloud auth print-identity-token)
- Setelah versi baru aplikasi Anda di-deploy, mulai Gemini CLI.
gemini
- Di perintah, gunakan perintah kustom baru yang Anda buat:
/find --animal="lions"
Anda akan melihat bahwa Gemini CLI memanggil alat get_animals_by_species
dan memformat respons seperti yang diinstruksikan oleh perintah MCP.
╭───────────────────────────╮ │ > /find --animal="lion" │ ╰───────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────╮ │ ✔ get_animals_by_species (zoo-remote MCP Server) get_animals_by_species (zoo-remote MCP Server) │ │ │ │ [{"species":"lion","name":"Leo","age":7,"enclosure":"The Big Cat │ │ Plains","trail":"Savannah │ │ Heights"},{"species":"lion","name":"Nala","age":6,"enclosure":"The Big Cat │ │ Plains","trail":"Savannah │ │ Heights"},{"species":"lion","name":"Simba","age":3,"enclosure":"The Big Cat │ │ Plains","trail":"Savannah │ │ Heights"},{"species":"lion","name":"King","age":8,"enclosure":"The Big Cat │ │ Plains","trail":"Savannah Heights"}] │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯ ✦ Lions can be found in The Big Cat Plains on the Savannah Heights.
Tujuan Tambahan untuk Menguji Diri Sendiri
Untuk tantangan tambahan, lihat apakah Anda dapat mengikuti langkah-langkah yang sama untuk membuat perintah guna menampilkan fakta menarik tentang spesies hewan tertentu di kebun binatang.
Atau, untuk menguji apa yang telah Anda pelajari, buat ide untuk alat yang akan Anda gunakan secara rutin dan deploy server MCP jarak jauh kedua. Kemudian, tambahkan ke setelan Gemini CLI Anda untuk melihat apakah berfungsi.
11. Kesimpulan
Selamat! Anda telah berhasil men-deploy dan terhubung ke server MCP jarak jauh yang aman.
Lanjutkan ke lab berikutnya
Lab ini adalah lab pertama dalam seri tiga bagian. Di lab kedua, Anda akan menggunakan server MCP yang dibuat dengan Agen ADK.
Menggunakan Server MCP di Cloud Run dengan Agen ADK
(Opsional) Membersihkan
Jika Anda tidak melanjutkan ke lab berikutnya dan ingin menghapus apa yang telah Anda buat, Anda dapat menghapus project Cloud untuk menghindari biaya tambahan.
Meskipun Cloud Run tidak mengenakan biaya saat layanannya tidak digunakan, Anda mungkin tetap ditagih atas penyimpanan image container di Artifact Registry. Menghapus project Cloud akan menghentikan penagihan untuk semua resource yang digunakan dalam project tersebut.
Jika Anda ingin, hapus project:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Anda juga dapat menghapus resource yang tidak diperlukan dari disk cloudshell. Anda dapat:
- Hapus direktori project codelab:
rm -rf ~/mcp-on-cloudrun
- Peringatan! Tindakan berikutnya ini tidak dapat diurungkan. Jika ingin menghapus semua yang ada di Cloud Shell untuk mengosongkan ruang penyimpanan, Anda dapat menghapus seluruh direktori beranda. Berhati-hatilah agar semua yang ingin Anda simpan disimpan di tempat lain.
sudo rm -rf $HOME