This tutorial shows you how to build and deploy a remote Model Context Protocol (MCP) server on Cloud Run using the streamable HTTP transport. With streamable HTTP transport, the MCP server operates as an independent process that can handle multiple client connections.
Prepare your Python project
The following steps describe how to set up your Python project with the uv
package manager.
Create a folder named
mcp-on-cloudrun
to store the source code for deployment:mkdir mcp-on-cloudrun cd mcp-on-cloudrun
Create a Python project with the
uv
tool to generate apyproject.toml
file:uv init --name "mcp-on-cloudrun" --description "Example of deploying an MCP server on Cloud Run" --bare --python 3.10
The
uv init
command creates the followingpyproject.toml
file:[project] name = "mcp-server" version = "0.1.0" description = "Example of deploying an MCP server on Cloud Run" readme = "README.md" requires-python = ">=3.10" dependencies = []
Create the following additional new files:
server.py
for the MCP server source codetest_server.py
to test the remote server- A Dockerfile for deploying to Cloud Run
touch server.py test_server.py Dockerfile
Your project directory should contain the following structure:
├── mcp-on-cloudrun │ ├── pyproject.toml │ ├── server.py │ ├── test_server.py │ └── Dockerfile
Create an MCP server for math operations
To provide valuable context for improving the use of LLMs with MCP, set up a math MCP server with FastMCP. FastMCP provides a quick way to build MCP servers and clients with Python.
Follow these steps to create an MCP server for math operations such as addition and subtraction.
Run the following command to add FastMCP as a dependency in the
pyproject.toml
file:uv add fastmcp==2.8.0 --no-sync
Add the following math MCP server source code in the
server.py
file:Include the following code in the Dockerfile to use the
uv
tool for running theserver.py
file:
Deploy to Cloud Run
You can deploy the MCP server as a container image or as source code:
Container image
To deploy an MCP server packaged as a container image, follow these instructions.
Create an Artifact Registry repository to store the container image:
gcloud artifacts repositories create remote-mcp-servers \ --repository-format=docker \ --location=us-central1 \ --description="Repository for remote MCP servers" \ --project=PROJECT_ID
Build the container image and push it to Artifact Registry with Cloud Build:
gcloud builds submit --region=us-central1 --tag us-central1-docker.pkg.dev/PROJECT_ID/remote-mcp-servers/mcp-server:latest
Deploy the MCP server container image to Cloud Run:
gcloud run deploy mcp-server \ --image us-central1-docker.pkg.dev/PROJECT_ID/remote-mcp-servers/mcp-server:latest \ --region=us-central1 \ --no-allow-unauthenticated
Source
You can deploy remote MCP servers to Cloud Run from their sources.
Deploy from source by running the following command:
gcloud run deploy mcp-server --no-allow-unauthenticated --region=us-central1 --source .
Authenticate MCP client
If you deployed your service with the --no-allow-unauthenticated
flag, any MCP client
that connects to your remote MCP server must authenticate.
Grant the Cloud Run Invoker (
roles/run.invoker
) role to the service account. This Identity and Access Management policy binding makes sure that a strong security mechanism is used to authenticate your local MCP client.Run the Cloud Run proxy to create an authenticated tunnel to the remote MCP server on your local machine:
gcloud run services proxy mcp-server --region=us-central1
If the Cloud Run proxy is not yet installed, this command prompts you to download the proxy. Follow the prompts to download and install the proxy.
Cloud Run authenticates all traffic to http://127.0.0.1:8080
and forwards
requests to the remote MCP server.
Test the remote MCP server
You test and connect to the remote MCP server by using the FastMCP client and accessing
the URL http://127.0.0.1:8080/mcp
.
To test and invoke the add and subtract mechanism, follow these steps:
Before running the test server, run the Cloud Run proxy.
Create a test file called
test_server.py
and add the following code:In a new terminal, run the test server:
uv run test_server.py
You should see the following output:
🛠️ Tool found: add 🛠️ Tool found: subtract 🪛 Calling add tool for 1 + 2 ✅ Result: 3 🪛 Calling subtract tool for 10 - 3 ✅ Result: 7