Logo
Agentailor
Published on

Deploy Your MCP Server to Google Cloud Run (For Free)

Authors
  • avatar
    Name
    Ali Ibrahim
    Twitter
Deploy MCP Server to Cloud Run

Introduction

You've built an MCP server. It works on localhost. Your AI assistant can call tools, fetch data, and do useful things, as long as everything runs on your machine.

But what happens when you want to share it with your team? Or connect to it from a different device? Or just keep it running without your laptop open?

You need to deploy it.

This guide walks you through deploying a Streamable HTTP MCP server to Google Cloud Run, from scaffolding to a live URL in minutes. Streamable HTTP is the transport designed for remote deployments: it works over standard HTTPS, plays nicely with load balancers, and doesn't require the client to run your server as a subprocess.

Note: If you're working with a stdio MCP server, the deployment path is different. We'll cover that briefly at the end of this article.

If you've already built an MCP server using our first MCP server guide, you can deploy that project directly. Otherwise, we'll scaffold a fresh one below.

What you'll learn:

  • How to scaffold a deployment-ready MCP server
  • How to set up the Google Cloud CLI
  • How to deploy to Cloud Run with a single command
  • How to test your live server with MCP Inspector

Prerequisites:

  • Node.js 20 or later
  • A Google Cloud account (free to create)
  • Basic terminal familiarity

Why Google Cloud Run?

Cloud Run can deploy from a container image, a Dockerfile, or even raw source code (using buildpacks). The create-mcp-server scaffold includes a Dockerfile, so that's the path we'll use. If you're bringing your own server, any of these options work.

Here's why Cloud Run is a great fit for MCP servers:

  • Generous free tier — 2 million requests/month, 180,000 vCPU-seconds, and 360,000 GiB-seconds of memory. More than enough for development, testing, and light production use.
  • Build from source — No need to install Docker locally. Cloud Run uses Cloud Build to build your Dockerfile remotely.
  • HTTPS by default — Every deployed service gets an HTTPS URL automatically. MCP clients expect HTTPS for remote servers.
  • Scale to zero — When no one is calling your server, it scales down to zero instances. You pay nothing when idle.
  • No code changes — Streamable HTTP servers work as-is on Cloud Run. The POST /mcp endpoint maps directly to Cloud Run's request-based model.

In short: you get a free, secure, production-ready deployment with almost zero configuration.

Scaffold Your MCP Server

If you already have an MCP server project with a Dockerfile, skip ahead to Set Up the gcloud CLI.

Otherwise, let's scaffold a fresh one. Run:

# For more options, see https://github.com/agentailor/create-mcp-server
npx @agentailor/create-mcp-server --name=my-mcp-server

This creates a stateless MCP server using the Official TypeScript SDK. No interactive prompts, no choices needed. One command, one project.

We're using a stateless server here for simplicity, but you can deploy a stateful server to Cloud Run the same way. The deployment steps are identical.

The generated project structure:

my-mcp-server/
├── src/
│   ├── server.ts     # MCP server (tools, prompts, resources)
│   └── index.ts      # Express app and HTTP transport
├── Dockerfile        # Production-ready Docker build
├── package.json
├── tsconfig.json
├── .env.example
├── .gitignore
└── README.md

Install dependencies and verify it works locally:

cd my-mcp-server
npm install
npm run dev

You should see:

MCP Stateless HTTP Server listening on port 3000

Your server is running at http://localhost:3000/mcp. Stop it with Ctrl+C. We're ready to deploy.

Want to understand the scaffolded code in detail? See our Create Your First MCP Server guide.

The Dockerfile

The scaffold includes a production-ready Dockerfile. Here's what it does:

# Multi-stage build for production
FROM node:20-alpine AS builder

WORKDIR /app

# Copy package files
COPY package.json package-lock.json ./

# Install all dependencies (including dev)
RUN npm ci

# Copy source code
COPY . .

# Build the application
RUN npm run build

# Production stage
FROM node:20-alpine AS production

WORKDIR /app

# Copy package files
COPY package.json package-lock.json ./

# Install production dependencies only
RUN npm ci --omit=dev

# Copy built application from builder stage
COPY --from=builder /app/dist ./dist

# Expose the port the app runs on
EXPOSE 3000

# Start the application
CMD ["node", "dist/index.js"]

It's a multi-stage build: the first stage compiles TypeScript, the second stage copies only the compiled output and dependencies. This keeps the final image small.

The important part: it exposes port 3000, which matches the --port 3000 flag we'll use when deploying. Cloud Build will use this Dockerfile automatically. You don't need Docker installed on your machine.

Set Up the gcloud CLI

Install gcloud CLI

Windows (via winget):

winget install Google.CloudSDK

Or download the installer.

macOS (via Homebrew):

brew install --cask google-cloud-sdk

Linux:

curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-linux-x86_64.tar.gz
tar -xf google-cloud-cli-linux-x86_64.tar.gz
./google-cloud-sdk/install.sh

After installing, restart your terminal and authenticate:

gcloud init
gcloud auth login

Enable Billing

Cloud Run requires a billing account, even for the free tier. You won't be charged if you stay within the free limits.

Option 1: Via the console

  1. Go to Google Cloud Billing
  2. Click Link a billing account (or Create account if you don't have one)
  3. Add a payment method
  4. Select your project and link it to the billing account

Option 2: Via CLI (if you already have a billing account):

gcloud billing accounts list
gcloud billing projects link YOUR_PROJECT_ID --billing-account=YOUR_BILLING_ACCOUNT_ID

Deploy to Cloud Run

Create a New Project

We recommend creating a dedicated project for this tutorial. This keeps your demo isolated from existing resources, so cleanup commands won't accidentally affect your other projects or container images.

gcloud projects create my-mcp-project --name="My MCP Server"
gcloud config set project my-mcp-project

Project IDs must be globally unique. If my-mcp-project is taken, choose something else.

Enable Required APIs

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

This enables three services:

  • Cloud Run: hosts your container
  • Artifact Registry: stores your container image
  • Cloud Build: builds your Dockerfile remotely

Deploy from Source

Make sure you're in your project directory (my-mcp-server/), then run:

gcloud run deploy my-mcp-server \
  --source . \
  --region us-central1 \
  --allow-unauthenticated \
  --port 3000

Here's what each flag does:

  • --source .: sends your source code to Cloud Build, which builds the container using your Dockerfile
  • --region us-central1: deploys to a US region (or choose another region closer to you)
  • --allow-unauthenticated: makes your /mcp endpoint publicly accessible
  • --port 3000: tells Cloud Run which port your container listens on

The first deploy takes a couple of minutes as Cloud Build pulls the base image and builds your container. Subsequent deploys are faster thanks to layer caching.

Get Your Service URL

gcloud run services describe my-mcp-server --region us-central1 --format='value(status.url)'

This outputs something like:

https://my-mcp-server-abc123xyz.us-central1.run.app

Your MCP endpoint is now live at https://<service-url>/mcp.

Troubleshooting: Invalid Host Error

If you get an error like "Invalid Host: my-mcp-server-abc123xyz.us-central1.run.app", it means the server is validating the Host header and rejecting the Cloud Run domain.

Fix it by setting the ALLOWED_HOSTS environment variable:

gcloud run services update my-mcp-server \
  --region us-central1 \
  --set-env-vars ALLOWED_HOSTS=my-mcp-server-abc123xyz.us-central1.run.app

Replace the domain with your actual service URL (without https://).

Test Your Deployed Server

Let's verify everything works. Open a terminal and run:

npx @modelcontextprotocol/inspector

Once the inspector opens in your browser:

  1. Change the transport type to Streamable HTTP
  2. Enter your Cloud Run URL: https://<service-url>/mcp
  3. Click Connect

You should see your server's tools listed. Click on any tool, fill in the parameters, and run it.

That's it. Your MCP server is live on the internet, accessible from any MCP-compatible client, anywhere.

Cleanup

If you want to remove the deployed resources:

# Delete the Cloud Run service
gcloud run services delete my-mcp-server --region us-central1

# Delete the container image from Artifact Registry
gcloud artifacts docker images list us-central1-docker.pkg.dev/my-mcp-project --format='value(IMAGE)' | xargs -I {} gcloud artifacts docker images delete {} --quiet

# Optionally delete the entire project (removes everything)
gcloud projects delete my-mcp-project

Note: Cloud Build stores your container image in Artifact Registry, which charges for storage after the first 500MB free. Deleting the project removes everything, but if you're keeping the project, clean up the images separately.

If you're staying within the free tier, there's no urgency to clean up. But it's good practice to remove resources you no longer need.

What's Next?

Now that your server is deployed, here are some ideas:

Add authentication: secure your deployed server with OAuth using our OAuth for MCP Servers guide.

Build real tools: replace the placeholder tools with your own by following our first MCP server guide.

Try FastMCP: build with a different framework using our FastMCP guide.

Connect your IDE: point your VS Code or Cursor MCP configuration at your Cloud Run URL instead of localhost.

Set up a custom domain: configure a custom domain in Cloud Run for a cleaner URL.

What About Stdio Servers?

Everything in this guide applies to Streamable HTTP servers, the transport designed for cloud deployment. But not all MCP servers use HTTP.

Stdio servers communicate via stdin/stdout and run as local subprocesses. They can't be deployed as web services. Instead, they're distributed so clients can run them locally: via npm (npx your-server), PyPI (uvx your-server), or Docker Hub (pull and run via Docker).

We'll cover stdio distribution in detail in a future article. Stay tuned.

Conclusion

You just went from a scaffolded project to a live, publicly accessible MCP server, in minutes, for free. No Docker installed locally, no infrastructure to manage, just a single gcloud run deploy --source . command.

With Cloud Run, your MCP server is always available, scales automatically, and costs nothing while idle. That's a pretty good deal for getting your AI tools off localhost and into the real world.

If you found create-mcp-server useful, consider giving it a star on GitHub and sharing it with others who are building MCP servers. It helps the project grow and helps more developers get started quickly.

Enjoying content like this? Sign up for Agent Briefings, where I share insights and news on building and scaling MCP Servers and AI agents.

Resources

Agent Briefings

Level up your agent-building skills with weekly deep dives on MCP, prompting, tools, and production patterns.