1. 📖 Pengantar
Dalam codelab sebelumnya , Anda mempelajari cara mendesain interaksi data multimodal di ADK. Sekarang kita akan mengambil langkah lebih lanjut tentang cara mendesain interaksi data multimodal dengan Server MCP menggunakan Toolset MCP. Kami akan memperluas kemampuan agen editor foto produk yang dikembangkan sebelumnya dengan kemampuan untuk membuat video pendek menggunakan model Veo yang memanfaatkan Server MCP Veo
Selama mengikuti codelab, Anda akan menggunakan pendekatan langkah demi langkah sebagai berikut:
- Menyiapkan project Google Cloud dan direktori agen dasar
- Mengonfigurasi Server MCP yang memerlukan data file sebagai input
- Melengkapi agen ADK untuk terhubung dengan Server MCP
- Merancang strategi perintah dan fungsi callback untuk mengubah permintaan panggilan fungsi ke Toolset MCP
- Merancang fungsi callback untuk menangani respons data multimodal dari MCP Toolset
Ringkasan Arsitektur
Keseluruhan interaksi dalam codelab ini ditunjukkan dalam diagram berikut

Prasyarat
- Nyaman bekerja dengan Python
- (Opsional) Codelab dasar tentang Agent Development Kit (ADK)
- (Opsional) Codelab ADK Multimodal Tool Part 1 : goo.gle/adk-multimodal-tool-1
Yang akan Anda pelajari
- Cara membuat video pendek menggunakan Veo 3.1 dengan perintah dan gambar awal
- Cara mengembangkan Server MCP Multimodal menggunakan FastMCP
- Cara menyiapkan ADK untuk menggunakan MCP Toolset
- Cara mengubah panggilan alat ke MCP Toolset melalui panggilan balik alat
- Cara mengubah respons alat dari MCP Toolset melalui callback alat
Yang Anda butuhkan
- Browser web Chrome
- Akun Gmail
- Project Cloud dengan akun penagihan diaktifkan
Codelab ini, yang dirancang untuk developer dari semua level (termasuk pemula), menggunakan Python dalam aplikasi contohnya. Namun, pengetahuan Python tidak diperlukan untuk memahami konsep yang disajikan.
2. 🚀 ( Opsional) Menyiapkan Penyiapan Pengembangan Workshop
Langkah 1: Pilih Project Aktif di Konsol Cloud
Di Konsol Google Cloud, di halaman pemilih project, pilih atau buat project Google Cloud (lihat bagian kiri atas konsol Anda)

Klik, dan Anda akan melihat daftar semua project Anda seperti contoh ini,

Nilai yang ditunjukkan oleh kotak merah adalah PROJECT ID dan nilai ini akan digunakan di seluruh tutorial.
Pastikan penagihan diaktifkan untuk project Cloud Anda. Untuk memeriksanya, klik ikon burger ☰ di panel kiri atas yang menampilkan Menu Navigasi, lalu temukan menu Penagihan

Jika Anda melihat "Akun Penagihan Uji Coba Google Cloud Platform" di bagian judul Penagihan / Ringkasan ( bagian kiri atas konsol cloud Anda ), project Anda siap digunakan untuk tutorial ini. Jika tidak, kembali ke awal tutorial ini dan tukarkan akun penagihan uji coba

Langkah 2: Pelajari Cloud Shell
Anda akan menggunakan Cloud Shell untuk sebagian besar tutorial. Klik Activate Cloud Shell di bagian atas konsol Google Cloud. Jika Anda diminta untuk memberikan otorisasi, klik Authorize.


Setelah terhubung ke Cloud Shell, kita perlu memeriksa apakah shell ( atau terminal) sudah diautentikasi dengan akun kita
gcloud auth list
Jika Anda melihat Gmail pribadi Anda seperti contoh output di bawah, semuanya baik-baik saja
Credentialed Accounts
ACTIVE: *
ACCOUNT: alvinprayuda@gmail.com
To set the active account, run:
$ gcloud config set account `ACCOUNT`
Jika tidak, coba muat ulang browser Anda dan pastikan Anda mengklik Izinkan saat diminta ( mungkin terganggu karena masalah koneksi)
Selanjutnya, kita juga perlu memeriksa apakah shell sudah dikonfigurasi ke PROJECT ID yang benar yang Anda miliki. Jika Anda melihat ada nilai di dalam ( ) sebelum ikon $ di terminal ( pada screenshot di bawah, nilainya adalah "adk-multimodal-tool"), nilai ini menunjukkan project yang dikonfigurasi untuk sesi shell aktif Anda.

Jika nilai yang ditampilkan sudah benar, Anda dapat melewati perintah berikutnya. Namun, jika tidak benar atau tidak ada, jalankan perintah berikut
gcloud config set project <YOUR_PROJECT_ID>
Kemudian, clone direktori kerja template untuk codelab ini dari GitHub dengan menjalankan perintah berikut. Perintah ini akan membuat direktori kerja di direktori adk-multimodal-tool
git clone https://github.com/alphinside/adk-mcp-multimodal.git adk-multimodal-tool
Langkah 3: Pahami Editor Cloud Shell dan Siapkan Direktori Kerja Aplikasi
Sekarang, kita dapat menyiapkan editor kode untuk melakukan beberapa hal terkait coding. Kita akan menggunakan Cloud Shell Editor untuk melakukannya
Klik tombol Open Editor, dan Cloud Shell Editor akan terbuka 
Setelah itu, buka bagian atas Cloud Shell Editor, klik File->Open Folder, temukan direktori username Anda, lalu temukan direktori adk-multimodal-tool, lalu klik tombol OK. Tindakan ini akan menjadikan direktori yang dipilih sebagai direktori kerja utama. Dalam contoh ini, nama penggunanya adalah alvinprayuda, sehingga jalur direktori ditampilkan di bawah


Sekarang, direktori kerja Cloud Shell Editor Anda akan terlihat seperti ini ( di dalam adk-multimodal-tool)

Sekarang, buka terminal untuk editor. Anda dapat melakukannya dengan mengklik Terminal -> New Terminal di panel menu, atau menggunakan Ctrl + Shift + C , yang akan membuka jendela terminal di bagian bawah browser

Terminal aktif Anda saat ini harus berada di dalam direktori kerja adk-multimodal-tool. Kita akan menggunakan Python 3.12 dalam codelab ini dan kita akan menggunakan pengelola project python uv untuk menyederhanakan kebutuhan pembuatan dan pengelolaan versi python serta lingkungan virtual. Paket uv ini sudah diinstal sebelumnya di Cloud Shell.
Jalankan perintah ini untuk menginstal dependensi yang diperlukan ke lingkungan virtual di direktori .venv
uv sync --frozen
Periksa pyproject.toml untuk melihat dependensi yang dideklarasikan untuk tutorial ini, yaitu google-adk, and python-dotenv.
Sekarang, kita perlu mengaktifkan API yang diperlukan melalui perintah yang ditunjukkan di bawah. Proses ini memerlukan waktu beberapa saat.
gcloud services enable aiplatform.googleapis.com
Setelah perintah berhasil dieksekusi, Anda akan melihat pesan yang mirip dengan yang ditampilkan di bawah:
Operation "operations/..." finished successfully.
Struktur agen template sudah disediakan untuk Anda di dalam direktori part2_starter_agent di repositori yang di-clone. Sekarang, kita perlu mengganti namanya terlebih dahulu agar siap untuk tutorial ini
mv part1_ckpt_agent product_photo_editor
Setelah itu, salin product_photo_editor/.env.example ke product_photo_editor/.env
cp product_photo_editor/.env.example product_photo_editor/.env
Saat membuka file product_photo_editor/.env, Anda akan melihat konten seperti yang ditunjukkan di bawah
GOOGLE_GENAI_USE_VERTEXAI=1
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=global
Kemudian, Anda harus memperbarui nilai your-project-id dengan project ID Anda yang benar. Sekarang kita siap untuk langkah berikutnya
3. 🚀 Lakukan Inisialisasi Server MCP Veo
Pertama, buat direktori layanan MCP menggunakan perintah ini
mkdir veo_mcp
Kemudian, buat veo_mcp/main.py menggunakan perintah ini
touch veo_mcp/main.py
Setelah itu, salin kode berikut ke veo_mcp/main.py
from fastmcp import FastMCP
from typing import Annotated
from pydantic import Field
import base64
import asyncio
import os
from google import genai
from google.genai import types
from dotenv import load_dotenv
import logging
# Load environment variables from .env file
load_dotenv()
mcp = FastMCP("Veo MCP Server")
@mcp.tool
async def generate_video_with_image(
prompt: Annotated[
str, Field(description="Text description of the video to generate")
],
image_data: Annotated[
str, Field(description="Base64-encoded image data to use as starting frame")
],
negative_prompt: Annotated[
str | None,
Field(description="Things to avoid in the generated video"),
] = None,
) -> dict:
"""Generates a professional product marketing video from text prompt and starting image using Google's Veo API.
This function uses an image as the first frame of the generated video and automatically
enriches your prompt with professional video production quality guidelines to create
high-quality marketing assets suitable for commercial use.
AUTOMATIC ENHANCEMENTS APPLIED:
- 4K cinematic quality with professional color grading
- Smooth, stabilized camera movements
- Professional studio lighting setup
- Shallow depth of field for product focus
- Commercial-grade production quality
- Marketing-focused visual style
PROMPT WRITING TIPS:
Describe what you want to see in the video. Focus on:
- Product actions/movements (e.g., "rotating slowly", "zooming into details")
- Desired camera angles (e.g., "close-up of the product", "wide shot")
- Background/environment (e.g., "minimalist white backdrop", "lifestyle setting")
- Any specific details about the product presentation
The system will automatically enhance your prompt with professional production quality.
Args:
prompt: Description of the video to generate. Focus on the core product presentation
you want. The system will automatically add professional quality enhancements.
image_data: Base64-encoded image data to use as the starting frame
negative_prompt: Optional prompt describing what to avoid in the video
Returns:
dict: A dictionary containing:
- status: 'success' or 'error'
- message: Description of the result
- video_data: Base64-encoded video data (on success only)
"""
try:
# Initialize the Gemini client
client = genai.Client(
vertexai=True,
project=os.getenv("GOOGLE_CLOUD_PROJECT"),
location=os.getenv("GOOGLE_CLOUD_LOCATION"),
)
# Decode the image
image_bytes = base64.b64decode(image_data)
print(f"Successfully decoded image data: {len(image_bytes)} bytes")
# Create image object
image = types.Image(image_bytes=image_bytes, mime_type="image/png")
# Prepare the config
config = types.GenerateVideosConfig(
duration_seconds=8,
number_of_videos=1,
)
if negative_prompt:
config.negative_prompt = negative_prompt
# Enrich the prompt for professional marketing quality
enriched_prompt = enrich_prompt_for_marketing(prompt)
# Generate the video (async operation)
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt=enriched_prompt,
image=image,
config=config,
)
# Poll until the operation is complete
poll_count = 0
while not operation.done:
poll_count += 1
print(f"Waiting for video generation to complete... (poll {poll_count})")
await asyncio.sleep(5)
operation = client.operations.get(operation)
# Download the video and convert to base64
video = operation.response.generated_videos[0]
# Get video bytes and encode to base64
video_bytes = video.video.video_bytes
video_base64 = base64.b64encode(video_bytes).decode("utf-8")
print(f"Video generated successfully: {len(video_bytes)} bytes")
return {
"status": "success",
"message": f"Video with image generated successfully after {poll_count * 5} seconds",
"complete_prompt": enriched_prompt,
"video_data": video_base64,
}
except Exception as e:
logging.error(e)
return {
"status": "error",
"message": f"Error generating video with image: {str(e)}",
}
def enrich_prompt_for_marketing(user_prompt: str) -> str:
"""Enriches user prompt with professional video production quality enhancements.
Adds cinematic quality, professional lighting, smooth camera work, and marketing-focused
elements to ensure high-quality product marketing videos.
"""
enhancement_prefix = """Create a high-quality, professional product marketing video with the following characteristics:
TECHNICAL SPECIFICATIONS:
- 4K cinematic quality with professional color grading
- Smooth, stabilized camera movements
- Professional studio lighting setup with soft, even illumination
- Shallow depth of field for product focus
- High dynamic range (HDR) for vibrant colors
VISUAL STYLE:
- Clean, minimalist aesthetic suitable for premium brand marketing
- Elegant and sophisticated presentation
- Commercial-grade production quality
- Attention to detail in product showcase
USER'S SPECIFIC REQUIREMENTS:
"""
enhancement_suffix = """
ADDITIONAL QUALITY GUIDELINES:
- Ensure smooth transitions and natural motion
- Maintain consistent lighting throughout
- Keep the product as the clear focal point
- Use professional camera techniques (slow pans, tracking shots, or dolly movements)
- Apply subtle motion blur for cinematic feel
- Ensure brand-appropriate tone and style"""
return f"{enhancement_prefix}{user_prompt}{enhancement_suffix}"
if __name__ == "__main__":
mcp.run()
Kode berikut melakukan hal-hal berikut:
- Membuat server FastMCP yang mengekspos alat pembuatan video Veo 3.1 ke agen ADK
- Menerima gambar berenkode base64,perintah teks,dan perintah negatif sebagai input
- Membuat video berdurasi 8 detik secara asinkron dengan mengirimkan permintaan ke Veo 3.1 API dan melakukan polling setiap 5 detik hingga selesai
- Menampilkan data video berenkode base64 beserta perintah yang ditingkatkan
Alat Veo MCP ini akan memerlukan variabel lingkungan yang sama dengan agen kami, jadi kita cukup menyalin dan menempelkan file .env. Jalankan perintah berikut untuk melakukannya
cp product_photo_editor/.env veo_mcp/
Sekarang, kita dapat menguji apakah server MCP berjalan dengan benar dengan menjalankan perintah ini
uv run veo_mcp/main.py
Dan log konsol akan ditampilkan seperti ini
╭────────────────────────────────────────────────────────────────────────────╮
│ │
│ _ __ ___ _____ __ __ _____________ ____ ____ │
│ _ __ ___ .'____/___ ______/ /_/ |/ / ____/ __ \ |___ \ / __ \ │
│ _ __ ___ / /_ / __ `/ ___/ __/ /|_/ / / / /_/ / ___/ / / / / / │
│ _ __ ___ / __/ / /_/ (__ ) /_/ / / / /___/ ____/ / __/_/ /_/ / │
│ _ __ ___ /_/ \____/____/\__/_/ /_/\____/_/ /_____(*)____/ │
│ │
│ │
│ FastMCP 2.0 │
│ │
│ │
│ 🖥️ Server name: Veo MCP Server │
│ 📦 Transport: STDIO │
│ │
│ 🏎️ FastMCP version: 2.12.5 │
│ 🤝 MCP SDK version: 1.16.0 │
│ │
│ 📚 Docs: https://gofastmcp.com │
│ 🚀 Deploy: https://fastmcp.cloud │
│ │
╰────────────────────────────────────────────────────────────────────────────╯
[10/22/25 08:28:53] INFO Starting MCP server 'Veo MCP Server' with server.py:1502
transport 'stdio'
Sekarang hentikan proses layanan MCP menggunakan CTRL+C. Perintah ini akan dipanggil dari ADK MCP Toolset nanti. Kita dapat melanjutkan ke langkah berikutnya untuk mengizinkan agen kita menggunakan alat MCP ini
4. 🚀 Menghubungkan Server MCP Veo ke Agen ADK
Sekarang, hubungkan server MCP Veo agar dapat digunakan oleh agen kita. Pertama, buat skrip lain untuk memuat toolset, jalankan perintah berikut
touch product_photo_editor/mcp_tools.py
Kemudian, salin kode berikut ke product_photo_editor/mcp_tools.py
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
from mcp import StdioServerParameters
mcp_toolset = MCPToolset(
connection_params=StdioConnectionParams(
server_params=StdioServerParameters(
command="uv",
args=[
"run",
"veo_mcp/main.py",
],
),
timeout=120, # seconds
),
)
# Option to connect to remote MCP server
# from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
# mcp_toolset = MCPToolset(
# connection_params=StreamableHTTPConnectionParams(
# url="http://localhost:8000/mcp",
# timeout=120,
# ),
# )
Kode di atas menunjukkan cara kita dapat terhubung ke server MCP menggunakan MCPToolset ADK. Dalam contoh ini, kita terhubung ke server MCP menggunakan saluran komunikasi STDIO. Dalam perintah, kita menentukan cara menjalankan server MCP dan menyetel parameter waktu tunggu.
5. 🚀 Modifikasi Parameter Panggilan Alat
Dalam deklarasi alat server MCP, kami mendesain alat generate_video_with_image yang menentukan string base64 sebagai parameter alat. Kita tidak dapat meminta LLM untuk melakukannya, sehingga kita perlu merancang strategi khusus untuk menanganinya.
Di lab sebelumnya, kita menangani gambar respons alat dan yang diupload pengguna di before_model_callback untuk disimpan sebagai artefak, yang juga tercermin dalam template agen yang disiapkan sebelumnya. Kita akan memanfaatkannya dan melakukan strategi berikut:
- Instruksikan LLM untuk selalu mengirim nilai artifact_id jika parameter alat tertentu mengharuskannya mengirim data string base64
- Menyadap pemanggilan panggilan alat di
before_tool_callbackdan mengubah parameter dari artifact_id ke konten byte-nya dengan memuat artefak dan mengganti argumen alat
Lihat gambar di bawah untuk visualisasi bagian yang akan kami cegah

Pertama, siapkan fungsi before_tool_callback, buat file baru product_photo_editor/tool_callbacks.py dengan menjalankan perintah berikut
touch product_photo_editor/tool_callbacks.py
Kemudian, salin kode berikut ke file
# product_photo_editor/tool_callbacks.py
from google.genai.types import Part
from typing import Any
from google.adk.tools.tool_context import ToolContext
from google.adk.tools.base_tool import BaseTool
from google.adk.tools.mcp_tool.mcp_tool import McpTool
import base64
import logging
import json
from mcp.types import CallToolResult
async def before_tool_modifier(
tool: BaseTool, args: dict[str, Any], tool_context: ToolContext
):
# Identify which tool input should be modified
if isinstance(tool, McpTool) and tool.name == "generate_video_with_image":
logging.info("Modify tool args for artifact: %s", args["image_data"])
# Get the artifact filename from the tool input argument
artifact_filename = args["image_data"]
artifact = await tool_context.load_artifact(filename=artifact_filename)
file_data = artifact.inline_data.data
# Convert byte data to base64 string
base64_data = base64.b64encode(file_data).decode("utf-8")
# Then modify the tool input argument
args["image_data"] = base64_data
Kode di atas menunjukkan langkah-langkah berikut:
- Periksa apakah alat yang dipanggil adalah objek McpTool dan merupakan panggilan alat yang ditargetkan yang ingin kita ubah
- Dapatkan nilai argumen
image_datayang merupakan argumen yang diminta dalam format base64, tetapi kami meminta LLM untuk menampilkan artifact_id di dalamnya - Muat artefak dengan memanfaatkan layanan artefak di
tool_context - Timpa argumen
image_datadengan data base64
Sekarang, kita perlu menambahkan callback ini ke agen dan juga sedikit mengubah petunjuk agar agen selalu mengisi argumen alat base64 dengan ID artefak.
Buka product_photo_editor/agent.py dan ubah kontennya dengan kode berikut
# product_photo_editor/agent.py
from google.adk.agents.llm_agent import Agent
from product_photo_editor.custom_tools import edit_product_asset
from product_photo_editor.mcp_tools import mcp_toolset
from product_photo_editor.model_callbacks import before_model_modifier
from product_photo_editor.tool_callbacks import before_tool_modifier
from product_photo_editor.prompt import AGENT_INSTRUCTION
root_agent = Agent(
model="gemini-2.5-flash",
name="product_photo_editor",
description="""A friendly product photo editor assistant that helps small business
owners edit and enhance their product photos. Perfect for improving photos of handmade
goods, food products, crafts, and small retail items""",
instruction=AGENT_INSTRUCTION
+ """
**IMPORTANT: Base64 Argument Rule on Tool Call**
If you found any tool call arguments that requires base64 data,
ALWAYS provide the artifact_id of the referenced file to
the tool call. NEVER ask user to provide base64 data.
Base64 data encoding process is out of your
responsibility and will be handled in another part of the system.
""",
tools=[
edit_product_asset,
mcp_toolset,
],
before_model_callback=before_model_modifier,
before_tool_callback=before_tool_modifier,
)
Baiklah, sekarang mari kita coba berinteraksi dengan agen untuk menguji modifikasi ini. Jalankan perintah berikut untuk menjalankan UI dev web
uv run adk web --port 8080
Perintah ini akan menghasilkan output seperti contoh berikut, yang berarti kita sudah dapat mengakses antarmuka web
INFO: Started server process [xxxx] INFO: Waiting for application startup. +-----------------------------------------------------------------------------+ | ADK Web Server started | | | | For local testing, access at http://127.0.0.1:8080. | +-----------------------------------------------------------------------------+ INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8080 (Press CTRL+C to quit)
Sekarang, untuk memeriksanya, Anda dapat menekan Ctrl + Klik pada URL atau mengklik tombol Web Preview di area atas Cloud Shell Editor dan memilih Preview on port 8080

Anda akan melihat halaman web berikut tempat Anda dapat memilih agen yang tersedia di tombol drop-down kiri atas ( dalam kasus ini, agennya adalah product_photo_editor) dan berinteraksi dengan bot.
Kemudian, upload gambar berikut dan minta agen untuk membuat klip promosi dari gambar tersebut
Generate a slow zoom in and moving from left and right animation

Anda akan mengalami error berikut

Mengapa? Karena alat ini juga menampilkan hasil langsung dalam bentuk string base64, hal itu akan melebihi token maksimum. Sekarang, mari kita tangani error ini di bagian berikutnya.
6. 🚀 Modifikasi Respons Alat
Di bagian ini, kita akan menangani respons alat dari respons MCP. Kami akan melakukan hal-hal berikut:
- Menyimpan respons video oleh alat di layanan artefak
- Mengembalikan ID artefak ke agen
Sebagai pengingat, kita akan mengetuk runtime agen berikut

Pertama, mari kita terapkan fungsi callback, buka product_photo_editor/tool_callbacks.py dan ubah untuk menerapkan after_tool_modifier
# product_photo_editor/tool_callbacks.py
from google.genai.types import Part
from typing import Any
from google.adk.tools.tool_context import ToolContext
from google.adk.tools.base_tool import BaseTool
from google.adk.tools.mcp_tool.mcp_tool import McpTool
import base64
import logging
import json
from mcp.types import CallToolResult
async def before_tool_modifier(
tool: BaseTool, args: dict[str, Any], tool_context: ToolContext
):
# Identify which tool input should be modified
if isinstance(tool, McpTool) and tool.name == "generate_video_with_image":
logging.info("Modify tool args for artifact: %s", args["image_data"])
# Get the artifact filename from the tool input argument
artifact_filename = args["image_data"]
artifact = await tool_context.load_artifact(filename=artifact_filename)
file_data = artifact.inline_data.data
# Convert byte data to base64 string
base64_data = base64.b64encode(file_data).decode("utf-8")
# Then modify the tool input argument
args["image_data"] = base64_data
async def after_tool_modifier(
tool: BaseTool,
args: dict[str, Any],
tool_context: ToolContext,
tool_response: dict | CallToolResult,
):
if isinstance(tool, McpTool) and tool.name == "generate_video_with_image":
tool_result = json.loads(tool_response.content[0].text)
# Get the expected response field which contains the video data
video_data = tool_result["video_data"]
artifact_filename = f"video_{tool_context.function_call_id}.mp4"
# Convert base64 string to byte data
video_bytes = base64.b64decode(video_data)
# Save the video as artifact
await tool_context.save_artifact(
filename=artifact_filename,
artifact=Part(inline_data={"mime_type": "video/mp4", "data": video_bytes}),
)
# Remove the video data from the tool response
tool_result.pop("video_data")
# Then modify the tool response to include the artifact filename and remove the base64 string
tool_result["video_artifact_id"] = artifact_filename
logging.info(
"Modify tool response for artifact: %s", tool_result["video_artifact_id"]
)
return tool_result
Setelah itu, kita perlu melengkapi agen dengan fungsi ini. Buka product_photo_editor/agent.py dan ubah ke kode berikut
# product_photo_editor/agent.py
from google.adk.agents.llm_agent import Agent
from product_photo_editor.custom_tools import edit_product_asset
from product_photo_editor.mcp_tools import mcp_toolset
from product_photo_editor.model_callbacks import before_model_modifier
from product_photo_editor.tool_callbacks import (
before_tool_modifier,
after_tool_modifier,
)
from product_photo_editor.prompt import AGENT_INSTRUCTION
root_agent = Agent(
model="gemini-2.5-flash",
name="product_photo_editor",
description="""A friendly product photo editor assistant that helps small business
owners edit and enhance their product photos. Perfect for improving photos of handmade
goods, food products, crafts, and small retail items""",
instruction=AGENT_INSTRUCTION
+ """
**IMPORTANT: Base64 Argument Rule on Tool Call**
If you found any tool call arguments that requires base64 data,
ALWAYS provide the artifact_id of the referenced file to
the tool call. NEVER ask user to provide base64 data.
Base64 data encoding process is out of your
responsibility and will be handled in another part of the system.
""",
tools=[
edit_product_asset,
mcp_toolset,
],
before_model_callback=before_model_modifier,
before_tool_callback=before_tool_modifier,
after_tool_callback=after_tool_modifier,
)
Selesai, sekarang Anda dapat meminta agen untuk tidak hanya membantu Anda mengedit foto, tetapi juga membuat video untuk Anda. Jalankan perintah berikut lagi
uv run adk web --port 8080
Kemudian, coba buat video menggunakan gambar ini
Generate a slow zoom in and moving from left and right animation

Anda akan melihat video yang dibuat seperti contoh yang ditunjukkan di bawah dan sudah disimpan sebagai artefak

7. ⭐ Ringkasan
Sekarang, mari kita lihat kembali apa yang telah kita lakukan selama codelab ini. Berikut adalah pembelajaran utamanya:
- Penanganan Data Multimodal (I/O Alat): Memperkuat strategi untuk mengelola data multimodal (seperti gambar dan video) untuk input dan output alat dengan menggunakan layanan Artefak ADK dan callback khusus, bukan meneruskan data byte mentah secara langsung.
- Integrasi Toolset MCP: Mengembangkan dan mengintegrasikan Server MCP Veo eksternal menggunakan FastMCP melalui Toolset MCP ADK untuk menambahkan kemampuan pembuatan video ke agen.
- Modifikasi Input Alat (before_tool_callback): Menerapkan callback untuk mencegat panggilan alat generate_video_with_image, mengubah artifact_id file (yang dipilih oleh LLM) menjadi data gambar berenkode base64 yang diperlukan untuk input server MCP.
- Modifikasi Output Alat (after_tool_callback): Menerapkan callback untuk mencegat respons video berenkode base64 berukuran besar dari server MCP, menyimpan video sebagai artefak baru, dan menampilkan referensi video_artifact_id yang bersih ke LLM.
8. 🧹 Membersihkan
Agar tidak menimbulkan biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam codelab ini, ikuti langkah-langkah berikut:
- Di konsol Google Cloud, buka halaman Manage resources.
- Dalam daftar project, pilih project yang ingin Anda hapus, lalu klik Delete.
- Pada dialog, ketik project ID, lalu klik Shut down untuk menghapus project.