1. 📖 Introdução
No codelab anterior , você aprendeu a criar uma interação de dados multimodal no ADK. Agora vamos dar mais um passo em como projetar uma interação de dados multimodal com o servidor MCP usando o conjunto de ferramentas MCP. Vamos ampliar os recursos do editor de fotos de produtos desenvolvido anteriormente com a capacidade de gerar vídeos curtos usando o modelo Veo e o servidor MCP do Veo.
Durante o codelab, você vai usar uma abordagem gradual da seguinte forma:
- Preparar o projeto do Google Cloud e o diretório do agente de base
- Configurar um servidor MCP que exige dados de arquivo como entrada
- Equipar o agente do ADK para se conectar ao servidor MCP
- Projete uma estratégia de comando e uma função de callback para modificar a solicitação de chamada de função para o conjunto de ferramentas do MCP
- Projete uma função de callback para processar a resposta de dados multimodais do conjunto de ferramentas do MCP.
Visão geral da arquitetura
A interação geral neste codelab é mostrada no diagrama a seguir

Pré-requisitos
- Conhecimento de Python
- (Opcional) Codelabs básicos sobre o Kit de Desenvolvimento de Agente (ADK)
- (Opcional) Codelab da parte 1 da ferramenta multimodal do ADK : goo.gle/adk-multimodal-tool-1
O que você vai aprender
- Como criar vídeos curtos usando o Veo 3.1 com um comando e uma imagem inicial
- Como desenvolver um servidor MCP multimodal usando o FastMCP
- Como configurar o ADK para usar o conjunto de ferramentas do MCP
- Como modificar a chamada de ferramenta para o conjunto de ferramentas do MCP usando o callback de ferramenta
- Como modificar a resposta da ferramenta do conjunto de ferramentas do MCP usando um callback de ferramenta
O que é necessário
- Navegador da Web Google Chrome
- Uma conta do Gmail
- Um projeto do Cloud com uma conta de faturamento ativada
Este codelab, criado para desenvolvedores de todos os níveis (inclusive iniciantes), usa Python no aplicativo de exemplo. No entanto, não é necessário ter conhecimento de Python para entender os conceitos apresentados.
2. 🚀 ( Opcional) Preparar a configuração de desenvolvimento do workshop
Etapa 1: selecionar "Projeto ativo" no Console do Cloud
No console do Google Cloud, na página de seletor de projetos, selecione ou crie um projeto do Google Cloud (consulte a seção no canto superior esquerdo do console).

Clique nele para ver uma lista de todos os seus projetos, como neste exemplo:

O valor indicado pela caixa vermelha é o ID DO PROJETO, que será usado em todo o tutorial.
Verifique se o faturamento está ativado para seu projeto do Cloud. Para verificar, clique no ícone de hambúrguer ☰ na barra superior esquerda, que mostra o menu de navegação, e encontre o menu "Faturamento".

Se você encontrar a "Conta de faturamento de teste do Google Cloud Platform" no título Faturamento / Visão geral ( seção superior esquerda do console da nuvem), seu projeto está pronto para ser usado neste tutorial. Caso contrário, volte ao início deste tutorial e resgate a conta de faturamento de teste.

Etapa 2: conhecer o Cloud Shell
Você vai usar o Cloud Shell na maior parte dos tutoriais. Clique em "Ativar o Cloud Shell" na parte de cima do console do Google Cloud. Se for preciso autorizar, clique em Autorizar.


Depois de se conectar ao Cloud Shell, precisamos verificar se o shell ( ou terminal) já está autenticado com nossa conta.
gcloud auth list
Se você vir seu Gmail pessoal como no exemplo de saída abaixo, tudo está certo.
Credentialed Accounts
ACTIVE: *
ACCOUNT: alvinprayuda@gmail.com
To set the active account, run:
$ gcloud config set account `ACCOUNT`
Caso contrário, atualize o navegador e clique em Autorizar quando solicitado. A autorização pode ser interrompida devido a um problema de conexão.
Em seguida, também precisamos verificar se o shell já está configurado para o ID DO PROJETO correto. Se você vir um valor entre parênteses antes do ícone $ no terminal (na captura de tela abaixo, o valor é "adk-multimodal-tool"), esse valor mostra o projeto configurado para sua sessão de shell ativa.

Se o valor mostrado já estiver correto, pule o próximo comando. No entanto, se não estiver correto ou estiver faltando, execute o seguinte comando:
gcloud config set project <YOUR_PROJECT_ID>
Em seguida, clone o diretório de trabalho do modelo para este codelab do GitHub executando o seguinte comando: Ele vai criar o diretório de trabalho no diretório adk-multimodal-tool.
git clone https://github.com/alphinside/adk-mcp-multimodal.git adk-multimodal-tool
Etapa 3: conhecer o editor do Cloud Shell e configurar o diretório de trabalho do aplicativo
Agora, podemos configurar nosso editor de código para fazer algumas coisas de programação. Vamos usar o editor do Cloud Shell para isso.
Clique no botão Abrir editor para abrir um editor do Cloud Shell
.
Depois disso, acesse a seção superior do editor do Cloud Shell e clique em Arquivo->Abrir pasta, encontre o diretório nome de usuário e o diretório adk-multimodal-tool. Em seguida, clique no botão "OK". Isso vai definir o diretório escolhido como o principal de trabalho. Neste exemplo, o nome de usuário é alvinprayuda. Portanto, o caminho do diretório é mostrado abaixo.


Agora, o diretório de trabalho do editor do Cloud Shell deve ficar assim ( dentro de adk-multimodal-tool):

Agora, abra o terminal do editor. Para fazer isso, clique em Terminal -> Novo terminal na barra de menus ou use Ctrl + Shift + C. Isso vai abrir uma janela de terminal na parte de baixo do navegador.

O terminal ativo atual precisa estar no diretório de trabalho adk-multimodal-tool. Vamos usar o Python 3.12 neste codelab e o gerenciador de projetos Python uv para simplificar a necessidade de criar e gerenciar a versão do Python e o ambiente virtual. O pacote uv já está pré-instalado no Cloud Shell.
Execute este comando para instalar as dependências necessárias no ambiente virtual no diretório .venv
uv sync --frozen
Confira o arquivo pyproject.toml para ver as dependências declaradas deste tutorial, que são google-adk, and python-dotenv.
Agora, vamos ativar as APIs necessárias usando o comando mostrado abaixo. Isso pode levar algum tempo.
gcloud services enable aiplatform.googleapis.com
Após a execução do comando, você vai ver uma mensagem semelhante à mostrada abaixo:
Operation "operations/..." finished successfully.
A estrutura do agente de modelo já está disponível para você no diretório part2_starter_agent do repositório clonado. Agora, vamos renomeá-lo para preparar este tutorial.
mv part1_ckpt_agent product_photo_editor
Depois disso, copie product_photo_editor/.env.example para product_photo_editor/.env
cp product_photo_editor/.env.example product_photo_editor/.env
Ao abrir o arquivo product_photo_editor/.env, você vai encontrar um conteúdo como o mostrado abaixo.
GOOGLE_GENAI_USE_VERTEXAI=1
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=global
Em seguida, atualize o valor your-project-id com o ID do projeto correto. Agora estamos prontos para a próxima etapa
3. 🚀 Inicializar o servidor MCP do Veo
Primeiro, crie o diretório de serviço do MCP usando este comando:
mkdir veo_mcp
Em seguida, crie o veo_mcp/main.py usando este comando:
touch veo_mcp/main.py
Depois disso, copie o seguinte código no 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()
O código a seguir faz o seguinte:
- Cria um servidor FastMCP que expõe uma ferramenta de geração de vídeo do Veo 3.1 para agentes do ADK.
- Aceita imagens codificadas em base64, comandos de texto e comandos negativos como entrada
- Gera vídeos de 8 segundos de forma assíncrona enviando solicitações à API Veo 3.1 e fazendo pesquisas a cada 5 segundos até a conclusão.
- Retorna dados de vídeo codificados em base64 junto com o comando enriquecido.
Essa ferramenta Veo MCP vai exigir a mesma variável de ambiente com nosso agente. Portanto, basta copiar e colar o arquivo .env. Execute o comando a seguir para fazer isso:
cp product_photo_editor/.env veo_mcp/
Agora, podemos testar se o servidor MCP está funcionando corretamente executando este comando
uv run veo_mcp/main.py
e vai mostrar o registro do console assim:
╭────────────────────────────────────────────────────────────────────────────╮
│ │
│ _ __ ___ _____ __ __ _____________ ____ ____ │
│ _ __ ___ .'____/___ ______/ /_/ |/ / ____/ __ \ |___ \ / __ \ │
│ _ __ ___ / /_ / __ `/ ___/ __/ /|_/ / / / /_/ / ___/ / / / / / │
│ _ __ ___ / __/ / /_/ (__ ) /_/ / / / /___/ ____/ / __/_/ /_/ / │
│ _ __ ___ /_/ \____/____/\__/_/ /_/\____/_/ /_____(*)____/ │
│ │
│ │
│ 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'
Agora, encerre o processo de serviço do MCP usando CTRL+C. Esse comando será invocado mais tarde no conjunto de ferramentas ADK MCP. Podemos passar para a próxima etapa para permitir que nosso agente use essas ferramentas do MCP.
4. 🚀 Conectar o servidor MCP da Veo ao agente do ADK
Agora, vamos conectar o servidor MCP do Veo para que ele possa ser usado pelo nosso agente. Primeiro, vamos criar um script diferente para conter o conjunto de ferramentas. Execute o seguinte comando:
touch product_photo_editor/mcp_tools.py
Em seguida, copie o código a seguir para 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,
# ),
# )
O código acima mostra como se conectar a um servidor MCP usando o ADK MCPToolset. Neste exemplo, nos conectamos ao servidor MCP usando o canal de comunicação STDIO. No comando, especificamos como executar o servidor MCP e definir o parâmetro de tempo limite.
5. 🚀 Modificação de parâmetros de chamada de função
Na declaração da ferramenta do servidor MCP, projetamos a ferramenta generate_video_with_image, que especifica a string base64 como os parâmetros da ferramenta. Não podemos pedir que o LLM faça isso por nós. Portanto, precisamos criar uma estratégia específica para lidar com isso.
No laboratório anterior, processamos a imagem enviada pelo usuário e a resposta da ferramenta no before_model_callback para ser salva como um artefato, o que também se reflete no modelo de agente preparado anteriormente. Vamos usar isso e seguir as seguintes estratégias:
- Instrua o LLM a sempre enviar o valor "artifact_id" se um parâmetro de ferramenta específico exigir o envio de dados de string base64.
- Intercepte a invocação de chamada de ferramenta no
before_tool_callbacke transforme o parâmetro de artifact_id para o conteúdo de bytes dele carregando o artefato e substituindo os argumentos da ferramenta.
Confira na imagem abaixo a visualização da parte que vamos interceptar.

Primeiro, vamos preparar a função before_tool_callback e criar um novo arquivo product_photo_editor/tool_callbacks.py executando o seguinte comando:
touch product_photo_editor/tool_callbacks.py
Em seguida, copie o código abaixo no arquivo
# 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
O código acima mostra as seguintes etapas:
- Verifique se a ferramenta invocada é um objeto McpTool e se é a chamada de ferramenta de destino que queremos modificar.
- Receba o valor dos argumentos
image_data, que é o argumento solicitado no formato base64, mas pedimos ao LLM para retornar artifact_id nele. - Carregue o artefato usando o serviço de artefato no
tool_context - Substitua os argumentos
image_datapelos dados base64.
Agora, precisamos adicionar esse callback ao agente e modificar um pouco as instruções para que ele sempre preencha os argumentos da ferramenta base64 com o ID do artefato.
Abra product_photo_editor/agent.py e modifique o conteúdo com o seguinte código:
# 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,
)
Agora, vamos interagir com o agente para testar essa modificação. Execute o comando a seguir para iniciar a interface de desenvolvimento da Web:
uv run adk web --port 8080
Ele vai gerar uma saída como o exemplo a seguir, o que significa que já podemos acessar a interface da 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)
Agora, para verificar, Ctrl + clique no URL ou clique no botão Visualização da Web na área superior do Cloud Shell Editor e selecione Visualizar na porta 8080.

Você vai ver a seguinte página da Web, em que é possível selecionar os agentes disponíveis no botão suspenso no canto superior esquerdo ( no nosso caso, product_photo_editor) e interagir com o bot.
Em seguida, faça upload da imagem a seguir e peça ao agente para gerar um clipe promocional com ela.
Generate a slow zoom in and moving from left and right animation

Você vai encontrar o seguinte erro:

Por quê? Como a ferramenta também retornou resultados diretamente na forma de string base64, isso vai exceder o token máximo. Agora, vamos resolver esse erro na próxima seção.
6. 🚀 Modificação da resposta da ferramenta
Nesta seção, vamos processar a resposta da ferramenta na resposta do MCP. Vamos fazer o seguinte:
- Armazenar a resposta de vídeo da ferramenta no serviço de artefato
- Retorne o identificador do artefato para o agente
Vamos usar o seguinte tempo de execução do agente:

Primeiro, vamos implementar a função de callback. Abra product_photo_editor/tool_callbacks.py e modifique-o para implementar o 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
Depois disso, precisamos equipar nosso agente com essa função. Abra o arquivo product_photo_editor/agent.py e modifique-o para o seguinte código:
# 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,
)
Pronto! Agora você pode pedir ao agente para ajudar a editar a foto e gerar um vídeo para você. Execute o comando a seguir novamente:
uv run adk web --port 8080
Em seguida, tente criar um vídeo usando essa imagem.
Generate a slow zoom in and moving from left and right animation

O vídeo gerado vai aparecer como no exemplo abaixo e já salvo como artefato.

7. ⭐ Resumo
Agora vamos recapitular o que já fizemos neste codelab. Este é o principal aprendizado:
- Processamento de dados multimodais (E/S da ferramenta): reforçamos a estratégia para gerenciar dados multimodais (como imagens e vídeos) para entrada e saída de ferramentas usando o serviço de artefatos do ADK e callbacks especializados em vez de transmitir dados de bytes brutos diretamente.
- Integração do conjunto de ferramentas do MCP: desenvolvemos e integramos um servidor MCP externo do Veo usando o FastMCP pelo conjunto de ferramentas do MCP do ADK para adicionar recursos de geração de vídeo ao agente.
- Modificação da entrada da ferramenta (before_tool_callback): implementamos um callback para interceptar a chamada da ferramenta generate_video_with_image, transformando o artifact_id do arquivo (selecionado pelo LLM) nos dados de imagem codificados em base64 necessários para a entrada do servidor MCP.
- Modificação da saída da ferramenta (after_tool_callback): implementamos um callback para interceptar a grande resposta de vídeo codificada em base64 do servidor MCP, salvar o vídeo como um novo artefato e retornar uma referência clean video_artifact_id para o LLM.
8. 🧹 Limpeza
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados neste codelab, siga estas etapas:
- No console do Google Cloud, acesse a página Gerenciar recursos.
- Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir.
- Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.