Como implantar um servidor MCP seguro do Genkit no Cloud Run

1. Introdução

Visão geral

Neste laboratório, você vai criar e implantar um servidor do Protocolo de Contexto de Modelo (MCP). Os servidores MCP são úteis para dar aos LLMs acesso a ferramentas e serviços externos. Você vai configurá-lo como um serviço seguro e pronto para produção no Cloud Run, que pode ser acessado de vários clientes. Em seguida, você vai se conectar ao servidor MCP remoto na CLI do Gemini.

Atividades deste laboratório

Vamos usar o Genkit para criar um servidor MCP do zoológico com duas ferramentas: get_animals_by_species e get_animal_details. O Genkit oferece uma maneira rápida de criar servidores e clientes do MCP com Node.js.

Gráfico do servidor MCP do zoológico

O que você vai aprender

  • Implante o servidor MCP no Cloud Run.
  • Proteja o endpoint do servidor exigindo autenticação para todas as solicitações, garantindo que apenas clientes e agentes autorizados possam se comunicar com ele.
  • Conectar-se ao endpoint do servidor MCP seguro na CLI do Gemini

2. Configuração do projeto

  1. Se você ainda não tiver uma Conta do Google, crie uma.
    • Use uma conta pessoal em vez de uma conta escolar ou de trabalho. As contas escolares e de trabalho podem ter restrições que impedem a ativação das APIs necessárias para este laboratório.
  2. Faça login no Console do Google Cloud.
  3. Ative o faturamento no console do Cloud.
    • A conclusão deste laboratório custa menos de US $1 em recursos do Cloud.
    • Siga as etapas no final deste laboratório para excluir recursos e evitar mais cobranças.
    • Novos usuários podem aproveitar o teste sem custos financeiros de US$300.
  4. Crie um projeto ou reutilize um projeto existente.
    • Se você receber um erro sobre a cota do projeto, reutilize ou exclua um projeto para criar outro.

3. Abrir editor do Cloud Shell

  1. Clique neste link para navegar diretamente até o editor do Cloud Shell.
  2. Se for preciso autorizar em algum momento, clique em Autorizar para continuar. Clique para autorizar o Cloud Shell
  3. Se o terminal não aparecer na parte de baixo da tela, abra-o:
    • Clique em Visualizar.
    • Clique em TerminalAbrir um novo terminal no editor do Cloud Shell.
  4. No terminal, defina o projeto com este comando:
    • Formato:
      gcloud config set project [PROJECT_ID]
      
    • Exemplo:
      gcloud config set project lab-project-id-example
      
    • Se você não se lembrar do ID do projeto:
      • Para listar todos os IDs de projeto, use:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      Definir o ID do projeto no terminal do Editor do Cloud Shell
  5. Você vai receber esta mensagem:
    Updated property [core/project].
    
    Se você vir um WARNING e for perguntado Do you want to continue (Y/n)?, provavelmente inseriu o ID do projeto incorretamente. Pressione n, Enter e tente executar o comando gcloud config set project novamente.

4. Ativar APIs

No terminal, ative as APIs:

gcloud services enable \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com

Se for preciso autorizar, clique em Autorizar para continuar. Clique para autorizar o Cloud Shell

Esse comando pode levar alguns minutos para ser concluído, mas vai gerar uma mensagem de sucesso semelhante a esta:

Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.

5. Preparar seu projeto JavaScript

  1. Crie uma pasta chamada mcp-on-cloudrun para armazenar o código-fonte da implantação:
    mkdir mcp-on-cloudrun && cd mcp-on-cloudrun
    
  2. Crie um projeto Node.js com a ferramenta npm para gerar um arquivo package.json:
    npm init es6 -y
    
    O comando npm init cria um arquivo package.json para seu projeto.
  3. Instale as dependências @modelcontextprotocol/sdk, express e zod:
    npm install @modelcontextprotocol/sdk express zod
    

6. Criar o servidor MCP do zoológico

Para fornecer um contexto valioso e melhorar o uso de LLMs com o MCP, configure um servidor MCP do zoológico com o Genkit, uma estrutura padrão para trabalhar com o Protocolo de Contexto de Modelo. O Genkit oferece uma maneira rápida de criar servidores e clientes do MCP com Node.js. Esse servidor MCP fornece dados sobre animais em um zoológico fictício. Para simplificar, armazenamos os dados na memória. Para um servidor MCP de produção, provavelmente você vai querer fornecer dados de fontes como bancos de dados ou APIs.

  1. Execute o comando a seguir para adicionar o Genkit como uma dependência no arquivo package.json:
    npm install genkit
    
    Isso vai adicionar um arquivo package-lock.json ao seu projeto.
  2. Execute o comando a seguir para adicionar a biblioteca MCP de IA do Genkit ao arquivo package.json:
    npm install @genkit-ai/mcp
    
  3. Crie e abra um novo arquivo index.js para o código-fonte do servidor MCP:
    cloudshell edit index.js
    
    O comando cloudshell edit vai abrir o arquivo index.js no editor acima do terminal.
  4. Adicione o seguinte código-fonte do servidor MCP do zoológico ao arquivo index.js:
    import express from 'express';
    import { genkit, z } from 'genkit';
    import { createMcpServer } from '@genkit-ai/mcp';
    import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
    
    // Dictionary of animals at the zoo
    const 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"
        }
    ];
    
    // Initialize Genkit
    const ai = genkit({});
    
    // Define tools using Genkit
    ai.defineTool(
        {
            name: 'get_animals_by_species',
            description: "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.",
            inputSchema: z.object({ species: z.string() }),
        },
        async ({ species }) => {
            console.log(`>>> 🛠️ Tool: 'get_animals_by_species' called for '${species}'`);
            const animals = ZOO_ANIMALS.filter(animal => animal.species.toLowerCase() === species.toLowerCase());
            return animals;
        }
    );
    
    ai.defineTool(
        {
            name: 'get_animal_details',
            description: "Retrieves the details of a specific animal by its name.",
            inputSchema: z.object({ name: z.string() }),
        },
        async ({ name }) => {
            console.log(`>>> 🛠️ Tool: 'get_animal_details' called for '${name}'`);
            const animal = ZOO_ANIMALS.find(a => a.name.toLowerCase() === name.toLowerCase());
            return animal;
        }
    );
    
    // Create Genkit MCP server wrapper
    const mcpWrapper = createMcpServer(ai, {
        name: 'zoo-animal-server',
        version: '1.0.0',
    });
    
    // HTTP server mode
    const app = express();
    app.use(express.json());
    
    // Initialize Genkit MCP server once
    const mcpServerPromise = mcpWrapper.setup().then(() => mcpWrapper.server);
    
    app.post('/mcp', async (req, res) => {
        console.log('/mcp Received:', req.body);
        console.log('Using HTTP transport mode.');
    
        const server = await mcpServerPromise;
    
        const transport = new StreamableHTTPServerTransport({
            sessionIdGenerator: undefined,
        });
    
        if (!server) {
            console.error('MCP Server not initialized correctly.');
            res.sendStatus(500);
            return;
        }
    
        await server.connect(transport);
        await transport.handleRequest(req, res, req.body);
    
        res.on('close', () => {
            console.log('Request closed');
            transport.close();
        });
    });
    
    app.get('/mcp', async (req, res) => {
        console.log('Received GET MCP request');
        res.sendStatus(405);
    });
    
    app.delete('/mcp', async (req, res) => {
        console.log('Received DELETE MCP request');
        res.sendStatus(405);
    });
    
    // Start the server
    const PORT = process.env.PORT || 8080;
    app.listen(PORT, () => {
        console.log(`Zoo Animal MCP server listening on port ${PORT}`);
    });
    

Seu código está completo! É hora de implantar o servidor MCP no Cloud Run.

7. Como implantar no Cloud Run

Agora implante um servidor MCP no Cloud Run diretamente do código-fonte.

  1. Crie uma conta de serviço chamada mcp-server-sa:
    gcloud iam service-accounts create mcp-server-sa --display-name="MCP Server Service Account"
    
  2. Execute o comando gcloud para implantar o aplicativo no Cloud Run.
    gcloud run deploy zoo-mcp-server \
        --service-account=mcp-server-sa@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
        --no-allow-unauthenticated \
        --region=europe-west1 \
        --source=. \
        --labels=dev-tutorial=codelab-mcp
    
    Use a flag --no-allow-unauthenticated para exigir autenticação. Isso é importante por motivos de segurança. Se você não exigir autenticação, qualquer pessoa poderá chamar seu servidor MCP e causar danos ao sistema.
  3. Confirme a criação de um novo repositório do Artifact Registry. Como é a primeira vez que você implanta no Cloud Run usando o código-fonte, vai aparecer:
    Deploying 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)?
    
    Digite Y e pressione Enter. Isso vai criar um repositório do Artifact Registry para sua implantação. Isso é necessário para armazenar o contêiner Docker do servidor MCP para o serviço do Cloud Run.
  4. Depois de alguns minutos, você vai ver uma mensagem como esta:
    Service [zoo-mcp-server] revision [zoo-mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.
    

Você implantou o servidor MCP. Agora você pode usar.

8. Adicionar o servidor MCP remoto à CLI do Gemini

Agora que você implantou um servidor MCP remoto, é possível se conectar a ele usando vários aplicativos, como o Google Code Assist ou a CLI do Gemini. Nesta seção, vamos estabelecer uma conexão com o novo servidor MCP remoto usando a CLI do Gemini.

  1. Conceda à sua conta de usuário permissão para chamar o servidor MCP remoto
    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member=user:$(gcloud config get-value account) \
        --role='roles/run.invoker'
    
  2. Salve suas credenciais do Google Cloud e o número do projeto em variáveis de ambiente para usar no arquivo de configurações do Gemini:
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    export ID_TOKEN=$(gcloud auth print-identity-token)
    
  3. Abra o arquivo de configurações da CLI do Gemini
    cloudshell edit ~/.gemini/settings.json
    
  4. Substitua o arquivo de configurações da CLI do Gemini para adicionar o servidor MCP do Cloud Run
    {
        "ide": {
            "hasSeenNudge": true
        },
        "mcpServers": {
            "zoo-remote": {
                "httpUrl": "https://zoo-mcp-server-$PROJECT_NUMBER.europe-west1.run.app/mcp",
                "headers": {
                    "Authorization": "Bearer $ID_TOKEN"
                }
            }
        },
        "security": {
            "auth": {
                "selectedType": "cloud-shell"
            }
        }
    }
    

  1. Iniciar a CLI do Gemini no Cloud Shell
    gemini
    
    Talvez seja necessário pressionar Enter para aceitar algumas configurações padrão.Visualização inicial da CLI do Gemini
  2. Pedir para o Gemini listar as ferramentas do MCP disponíveis no contexto
    /mcp
    
  3. Peça ao Gemini para encontrar algo no zoológico
    Where can I find penguins?
    
    A CLI do Gemini deve saber usar o servidor MCP zoo-remote e perguntar se você quer permitir a execução do MCP.
  4. Use a seta para baixo e pressione Enter para selecionar.
    Yes, always allow all tools from server "zoo-remote"
    
    Permitir ferramentas remotas do zoo na CLI do Gemini

A saída deve mostrar a resposta correta e uma caixa de exibição indicando que o servidor MCP foi usado.

Resultado do servidor MCP do zoológico da CLI do Gemini

Você conseguiu! Você implantou um servidor MCP remoto no Cloud Run e o testou usando a CLI do Gemini.

Quando quiser encerrar a sessão, digite /quit e pressione Enter para sair da CLI do Gemini.

Depuração

Se você receber um erro como este:

🔍 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.

É provável que o token de ID tenha expirado e precise ser definido novamente com ID_TOKEN.

  1. Digite /quit e pressione Enter para sair da CLI do Gemini.
  2. Definir o projeto no terminal
    gcloud config set project [PROJECT_ID]
    
  3. Execute novamente o comando de credenciais do Google Cloud para receber um novo ID_TOKEN, já que o seu pode ter expirado.
    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    export ID_TOKEN=$(gcloud auth print-identity-token)
    

9. (Opcional) Verificar chamadas de função nos registros do servidor

Para verificar se o servidor MCP do Cloud Run foi chamado, confira os registros do serviço.

gcloud run services logs read zoo-mcp-server --region europe-west1 --limit=5

Você vai ver um registro de saída que confirma que foi feita uma chamada de ferramenta. 🛠️

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. (Opcional) Adicionar solicitação de MCP ao servidor

Um comando do MCP pode acelerar seu fluxo de trabalho para comandos que você executa com frequência, criando uma abreviação para um comando mais longo.

A CLI do Gemini converte automaticamente os comandos do MCP em comandos de barra personalizados para que você possa invocar um comando do MCP digitando /prompt_name, em que prompt_name é o nome do comando do MCP.

Crie um comando do MCP para encontrar rapidamente um animal no zoológico digitando /find animal na CLI do Gemini.

  1. Adicione este código ao arquivo index.js acima da linha // Create Genkit MCP server wrapper:
    ai.definePrompt(
        {
            name: 'find',
            description: 'Find which exhibit and trail a specific animal is located.',
            inputSchema: z.object({ animal: z.string() }),
        },
        async ({ animal }) => {
            console.log(`>>> 💬 Prompt: 'find' called'`);
            return {
                messages: [
                    {
                        role: 'user',
                        content: [
                            { text: `Please find the exhibit and trail information for ${animal} in the zoo. Respond with '[animal] can be found in the [exhibit] on the [trail].' Example: Penguins can be found in The Arctic Exhibit on the Polar Path.` }
                        ]
                    }
                ]
            };
        }
    );
    
  2. Reimplantar o aplicativo no Cloud Run
    gcloud run deploy zoo-mcp-server \
        --service-account=mcp-server-sa@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
        --no-allow-unauthenticated \
        --region=europe-west1 \
        --source=. \
        --labels=dev-tutorial=codelab-mcp
    
  3. Atualize o ID_TOKEN do seu servidor MCP remoto.
    export ID_TOKEN=$(gcloud auth print-identity-token)
    
  4. Depois que a nova versão do aplicativo for implantada, inicie a CLI do Gemini.
    gemini
    
  5. No comando, use o novo comando personalizado que você criou:
    /find --animal="lions"
    

Você vai ver que a CLI do Gemini chama a ferramenta get_animals_by_species e formata a resposta conforme as instruções do comando do 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.

11. (Opcional) Use o Gemini Flash Lite para respostas mais rápidas

Com a CLI do Gemini, você pode escolher o modelo que está usando.

  • O Gemini 2.5 Pro é o modelo de raciocínio mais avançado do Google, capaz de resolver problemas complexos em programação, matemática e STEM, além de analisar grandes conjuntos de dados, bases de código e documentos usando contexto longo.
  • O Gemini 2.5 Flash é o melhor modelo do Google em termos de custo-benefício, oferecendo recursos abrangentes. O 2.5 Flash é ideal para processamento em grande escala, baixa latência, tarefas de alto volume que exigem pensamento e casos de uso de agentes.
  • O Gemini 2.5 Flash Lite é o modelo flash mais rápido do Google, otimizado para eficiência de custo e alta capacidade de processamento.

Como as solicitações relacionadas a encontrar os animais do zoológico não exigem raciocínio, tente acelerar as coisas usando um modelo Rápido.

Crie um comando do MCP para encontrar rapidamente um animal no zoológico digitando /find animal na CLI do Gemini.

  1. Depois que a nova versão do aplicativo for implantada, inicie a CLI do Gemini.
    gemini --model=gemini-2.5-flash-lite
    
  2. No comando, use o novo comando personalizado que você criou:
    /find --animal="lions"
    

Você ainda vai ver que a CLI do Gemini chama a ferramenta get_animals_by_species e formata a resposta conforme as instruções do comando do MCP, mas a resposta vai aparecer muito mais rápido.

╭───────────────────────────╮
│  > /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.

Metas ambiciosas para testar seus conhecimentos

Para um desafio extra, siga as mesmas etapas para criar um comando que retorne curiosidades sobre espécies de animais específicas no zoológico.

Ou, para testar ainda mais o que você aprendeu, crie uma ideia para uma ferramenta que você usaria com frequência e implante um segundo servidor MCP remoto. Em seguida, adicione-o às configurações da CLI do Gemini para ver se funciona.

Depuração

Se você receber um erro como este:

✕ Unknown command: /find --animal="lions"

Tente executar /mcp. Se ele gerar zoo-remote - Disconnected, talvez seja necessário reimplantar ou executar os seguintes comandos novamente:

gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
    --member=user:$(gcloud config get-value account) \
    --role='roles/run.invoker'

export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
export ID_TOKEN=$(gcloud auth print-identity-token)

12. Conclusão

Parabéns! Você implantou e se conectou a um servidor MCP remoto seguro.

Continuar para o próximo laboratório

Este é o primeiro laboratório de uma série de três partes. No segundo laboratório, você vai usar o servidor do MCP criado com um agente do ADK.

Usar um servidor MCP no Cloud Run com um agente do ADK

(Opcional) Limpar

Se você não vai continuar para o próximo laboratório e quer liberar espaço no que criou, exclua o projeto na nuvem para evitar cobranças adicionais.

O Cloud Run não gera custos quando o serviço não está em uso, mas você ainda pode receber cobranças pelo armazenamento da imagem do contêiner no Artifact Registry. A exclusão do projeto na nuvem interrompe o faturamento de todos os recursos usados nele.

Se quiser, exclua o projeto:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

Você também pode excluir recursos desnecessários do disco do Cloud Shell. Você pode:

  1. Exclua o diretório do projeto do codelab:
    rm -rf ~/mcp-on-cloudrun
    
  2. Aviso: Não é possível desfazer a próxima ação. Se você quiser excluir tudo no Cloud Shell para liberar espaço, exclua todo o diretório principal. Tenha cuidado para que tudo o que você quer manter seja salvo em outro lugar.
    sudo rm -rf $HOME