Zoo MCP Server

Zoo MCP Server

A FastMCP-based server that provides tools for retrieving animal species lists and specific animal details from a fictional zoo. It serves as a reference for deploying and securing Model Context Protocol servers on Google Cloud Run.

Category
访问服务器

README

Deploy a Secure MCP Server on Cloud Run

A comprehensive tutorial for building and deploying a Model Context Protocol (MCP) server to Google Cloud Run.

About this Workshop

Subject Last Updated Written By
Cloud Run, MCP Oct 28, 2025 Luke Schlangen, Jack Wotherspoon

Table of Contents

  1. Introduction
  2. Project Setup
  3. Open Cloud Shell Editor
  4. Enable APIs
  5. Prepare Your Python Project
  6. Create the Zoo MCP Server
  7. Deploying to Cloud Run
  8. Add the Remote MCP Server to Gemini CLI
  9. (Optional) Verify Tool Calls in Server Logs
  10. (Optional) Add MCP Prompt to Server
  11. (Optional) Use Gemini Flash Lite for Faster Responses
  12. Conclusion

1. Introduction

Overview

In this lab, you will build and deploy a Model Context Protocol (MCP) server. MCP servers are useful for providing LLMs with access to external tools and services. You will configure it as a secure, production-ready service on Cloud Run that can be accessed from multiple clients. Then you will connect to the remote MCP server from Gemini CLI.

What You'll Do

We will use FastMCP to create a zoo MCP server that has two tools: get_animals_by_species and get_animal_details. FastMCP provides a quick, Pythonic way to build MCP servers and clients.

What You'll Learn

  • Deploy the MCP server to Cloud Run
  • Secure your server's endpoint by requiring authentication for all requests, ensuring only authorized clients and agents can communicate with it
  • Connect to your secure MCP server endpoint from Gemini CLI

2. Project Setup

  1. If you don't already have a Google Account, you must create a Google Account.

    Use a personal account instead of a work or school account. Work and school accounts may have restrictions that prevent you from enabling the APIs needed for this lab.

  2. Sign in to the Google Cloud Console.

  3. Enable billing in the Cloud Console.

    Completing this lab should cost less than $1 USD in Cloud resources. You can follow the steps at the end of this lab to delete resources to avoid further charges. New users are eligible for the $300 USD Free Trial.

  4. Create a new project or choose to reuse an existing project.


3. Open Cloud Shell Editor

  1. Click this link to navigate directly to Cloud Shell Editor.

    • If prompted to authorize at any point, click Authorize to continue.
    • If the terminal doesn't appear at the bottom of the screen, open it:
      • Click View
      • Click Terminal
  2. In the terminal, set your project with this command:

    Format:

    gcloud config set project [PROJECT_ID]
    

    Example:

    gcloud config set project lab-project-id-example
    
    • If you can't remember your project ID, you can list all your project IDs with:
      gcloud projects list | awk '/PROJECT_ID/{print $2}'
      
  3. You should see this message:

    Updated property [core/project].
    

    If you see a WARNING and are asked Do you want to continue (Y/n)?, then you have likely entered the project ID incorrectly. Press n, press Enter, and try to run the gcloud config set project command again.


4. Enable APIs

In the terminal, enable the necessary APIs:

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

If prompted to authorize, click Authorize to continue.

This command may take a few minutes to complete, but it should eventually produce a successful message similar to this one:

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

5. Prepare Your Python Project

  1. Create a folder named mcp-on-cloudrun to store the source code for deployment:

    mkdir mcp-on-cloudrun && cd mcp-on-cloudrun
    
  2. Create a Python project with the uv tool to generate a pyproject.toml file:

    uv init --description "Example of deploying an MCP server on Cloud Run" --bare --python 3.13
    
  3. The uv init command creates a pyproject.toml file for your project. To view the contents of the file run the following:

    cat pyproject.toml
    

    The output should look like the following:

    [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. Create the Zoo MCP Server

To provide valuable context for improving the use of LLMs with MCP, set up a zoo MCP server with FastMCP — a standard framework for working with the Model Context Protocol. FastMCP provides a quick way to build MCP servers and clients with Python. This MCP server provides data about animals at a fictional zoo. For simplicity, we store the data in memory. For a production MCP server, you probably want to provide data from sources like databases or APIs.

  1. Run the following command to add FastMCP as a dependency in the pyproject.toml file:

    uv add fastmcp==2.12.4 --no-sync
    

    This will add a uv.lock file to your project.

  2. Create and open a new server.py file for the MCP server source code:

    cloudshell edit ~/mcp-on-cloudrun/server.py
    

    The cloudshell edit command will open the server.py file in the editor above the terminal.

  3. Add the zoo MCP server source code in the server.py file (see server.py in this repository).

    Your code is complete! It is time to deploy the MCP server to Cloud Run.


7. Deploying to Cloud Run

Now deploy an MCP server to Cloud Run directly from the source code.

  1. Create and open a new Dockerfile for deploying to Cloud Run:

    cloudshell edit ~/mcp-on-cloudrun/Dockerfile
    
  2. Include the following code in the Dockerfile to use the uv tool for running the server.py file (see Dockerfile in this repository).

  3. Create a service account named mcp-server-sa:

    gcloud iam service-accounts create mcp-server-sa --display-name="MCP Server Service Account"
    
  4. Run the gcloud command to deploy the application to Cloud Run:

    cd ~/mcp-on-cloudrun
    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 the --no-allow-unauthenticated flag to require authentication. This is important for security reasons. If you don't require authentication, anyone can call your MCP server and potentially cause damage to your system.

  5. Confirm the creation of a new Artifact Registry repository. Since it is your first time deploying to Cloud Run from source code, you will see:

    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)?
    

    Type Y and press Enter, this will create an Artifact Registry repository for your deployment. This is required for storing the MCP server Docker container for the Cloud Run service.

  6. After a few minutes, you will see a message like:

    Service [zoo-mcp-server] revision [zoo-mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.
    

    Note: If you try to visit the URL directly, you will see "Error Forbidden" because your MCP server requires authentication.

You have deployed your MCP server. Now you can use it.


8. Add the Remote MCP Server to Gemini CLI

Now that you've successfully deployed a remote MCP server, you can connect to it using various applications like Google Code Assist or Gemini CLI. In this section, we will establish a connection to your new remote MCP server using Gemini CLI.

Note: Gemini CLI comes pre-installed in Cloud Shell.

  1. Give your user account permission to call the remote MCP server:

    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member=user:$(gcloud config get-value account) \
        --role='roles/run.invoker'
    
  2. Save your Google Cloud credentials and project number in environment variables for use in the Gemini Settings file:

    export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)")
    export ID_TOKEN=$(gcloud auth print-identity-token)
    
  3. Make a .gemini folder if it has not already been created:

    mkdir -p ~/.gemini
    
  4. Open your Gemini CLI Settings file:

    cloudshell edit ~/.gemini/settings.json
    
  5. Replace your Gemini CLI settings file to add the Cloud Run MCP server:

    {
        "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"
            }
        }
    }
    
  6. Start the Gemini CLI in Cloud Shell:

    gemini
    

    You may need to press Enter to accept some default settings.

  7. Have Gemini list the MCP tools available to it within its context:

    /mcp
    
  8. Ask Gemini to find something in the zoo:

    Where can I find penguins?
    

    The Gemini CLI should know to use the zoo-remote MCP Server and will ask if you would like to allow execution of MCP.

  9. Use the down arrow, then press Enter to select:

    Yes, always allow all tools from server "zoo-remote"
    

    The output should show the correct answer and a display box showing that the MCP server was used.

You have done it! You have successfully deployed a remote MCP server to Cloud Run and tested it using Gemini CLI.

When you are ready to end your session, type /quit and then press Enter to exit Gemini CLI.

Debugging

If you see an error like this:

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

It is likely that the ID Token has timed out and requires setting the ID_TOKEN again.

  1. Type /quit and then press Enter to exit Gemini CLI.

  2. Set your project in your terminal:

    gcloud config set project [PROJECT_ID]
    
  3. Restart on step 2 above.


9. (Optional) Verify Tool Calls in Server Logs

To verify that your Cloud Run MCP server was called, check the service logs.

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

You should see an output log that confirms a tool call was made.

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. (Optional) Add MCP Prompt to Server

An MCP prompt can speed up your workflow for prompts you run often by creating a shorthand for a longer prompt. Gemini CLI automatically converts MCP prompts into custom slash commands so that you can invoke an MCP prompt by typing /prompt_name where prompt_name is the name of your MCP prompt.

Create an MCP prompt so you can quickly find an animal in the zoo by typing /find animal into Gemini CLI.

  1. Add this code to your server.py file above the main guard (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."
        )
    
  2. Re-deploy your application to Cloud Run:

    gcloud run deploy zoo-mcp-server \
        --region=europe-west1 \
        --source=. \
        --labels=dev-tutorial=codelab-mcp
    
  3. Refresh your ID_TOKEN for your remote MCP server:

    export ID_TOKEN=$(gcloud auth print-identity-token)
    
  4. After the new version of your application is deployed, start Gemini CLI:

    gemini
    
  5. In the prompt use the new custom command that you created:

    /find --animal="lions"
    

    OR

    /find lions
    

    You should see that Gemini CLI calls the get_animals_by_species tool and formats the response as instructed by the MCP prompt!


11. (Optional) Use Gemini Flash Lite for Faster Responses

Gemini CLI lets you choose the model you are using.

  • Gemini 2.5 Pro is Google's state-of-the-art thinking model, capable of reasoning over complex problems in code, math, and STEM, as well as analyzing large datasets, codebases, and documents using long context.
  • Gemini 2.5 Flash is Google's best model in terms of price-performance, offering well-rounded capabilities. 2.5 Flash is best for large scale processing, low-latency, high volume tasks that require thinking, and agentic use cases.
  • Gemini 2.5 Flash Lite is Google's fastest flash model optimized for cost-efficiency and high throughput.

Since the requests related to finding the zoo animals don't require thinking or reasoning, try speeding things up by using a faster model.

  1. Start Gemini CLI, specifying the faster model:

    gemini --model=gemini-2.5-flash-lite
    
  2. In the prompt use the custom command you created:

    /find lions
    

    You should still see that Gemini CLI calls the get_animals_by_species tool and formats the response as instructed by the MCP prompt, but the answer should appear much faster!

Debugging

If you see an error like this:

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

Try to run /mcp and if it outputs zoo-remote - Disconnected, you might have to re-deploy, or run the following commands again to refresh permissions and the token:

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

Congratulations! You have successfully deployed and connected to a secure remote MCP server.

Continue to the Next Lab

This lab is the first lab in a three-part series. In the second lab, you will use the MCP server you created with an ADK Agent.

(Optional) Clean Up

If you are not continuing on to the next lab and you would like to clean up what you have created, you can delete your Cloud project to avoid incurring additional charges.

While Cloud Run does not charge when the service is not in use, you might still be charged for storing the container image in Artifact Registry. Deleting your Cloud project stops billing for all the resources used within that project.

  1. If you would like, delete the project:

    gcloud projects delete $GOOGLE_CLOUD_PROJECT
    
  2. You may also want to delete unnecessary resources from your Cloud Shell disk. You can:

    • Delete the codelab project directory:

      rm -rf ~/mcp-on-cloudrun
      
    • Warning! This next action can't be undone! If you would like to delete everything on your Cloud Shell to free up space, you can delete your whole home directory. Be careful that everything you want to keep is saved somewhere else.

      sudo rm -rf $HOME
      

Repository Structure

mcp-cloudrun-workshop/
├── README.md           # This file
├── server.py          # MCP server implementation
├── Dockerfile         # Container configuration
├── pyproject.toml     # Python project configuration
└── .gitignore         # Git ignore file

License

This workshop is based on Google Cloud documentation and is provided as-is for educational purposes.

Contributing

Feel free to open issues or submit pull requests if you find any problems or have suggestions for improvements.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选