-
Notifications
You must be signed in to change notification settings - Fork 119
Description
Feature Request: Implement DevContainer for MCP Genmedia + Gemini CLI
This issue proposes a new container-based setup for the MCP Genmedia servers and Gemini CLI, leveraging DevContainers for a reproducible and consistent development environment. This approach would streamline local setup and provide a clear path for containerized deployments.
Motivation
The current setup relies on manual scripts run directly on a VM, which can lead to inconsistencies and is less reproducible. A DevContainer provides:
- Reproducibility: Ensures all developers work in an identical environment.
- Isolation: Keeps dependencies isolated from the host machine.
- Faster Setup: Pre-built images or cached layers speed up environment provisioning.
- Version Control: The entire environment definition is version-controlled.
- IDE-Agnostic: While compatible with VS Code, the core setup is generalized.
Proposed Solution
Implement a .devcontainer
directory with the following structure and files:
vertex-ai-creative-studio/experiments/mcp-genmedia/
??? .devcontainer/
? ??? devcontainer.json # Core DevContainer configuration
? ??? Dockerfile # Builds the base container image with dependencies
? ??? configs/ # Directory for static configuration files
? ? ??? gemini-extension.json # Template for Gemini CLI extension config
? ??? scripts/
? ??? configure-gemini.sh # Script to configure Gemini CLI wrapper and subsitute values in gemini-extension.json
1. .devcontainer/devcontainer.json
This file defines the DevContainer's properties, including the Dockerfile to use, features to install, and post-creation commands.
.devcontainer/devcontainer.json
{
"name": "MCP Genmedia + Gemini CLI DevContainer",
"dockerFile": "Dockerfile",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/devcontainers/features/gcloud-cli:1": {}
},
"postCreateCommand": "/home/vscode/.devcontainer/scripts/configure-gemini.sh",
"remoteUser": "vscode",
"mounts": [
"source=${localEnv:HOME}/.config/gcloud,target=/home/vscode/.config/gcloud,type=bind,consistency=cached"
],
"env": {
"PROJECT_ID": "${localEnv:PROJECT_ID}",
"LOCATION": "us-central1",
"GENMEDIA_BUCKET": "${localEnv:PROJECT_ID}-mcp-genmedia"
}
}
2. .devcontainer/Dockerfile
This Dockerfile builds the core image, installing Node.js, Go, essential tools, and pre-compiling the MCP Genmedia servers.
.devcontainer/Dockerfile
FROM mcr.microsoft.com/devcontainers/base:debian-11
# --- Install Node.js 20.x and npm ---
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get update \
&& apt-get install -y nodejs npm \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# --- Install Go 1.22.x ---
RUN wget https://golang.org/dl/go1.22.4.linux-amd64.tar.gz -O /tmp/go.tar.gz \
&& sudo tar -C /usr/local -xzf /tmp/go.tar.gz \
&& rm /tmp/go.tar.gz
# --- Set Go environment variables for the 'vscode' user ---
ENV PATH="/usr/local/go/bin:${PATH}"
ENV GOPATH="/home/vscode/go"
ENV PATH="${GOPATH}/bin:${PATH}"
# --- Install additional system tools ---
RUN apt-get update \
&& apt-get install -y git curl wget jq gettext-base \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# --- Clone and Build MCP Servers ---
WORKDIR /tmp/build
RUN git clone https://github.com/GoogleCloudPlatform/vertex-ai-creative-studio.git \
&& cd vertex-ai-creative-studio/experiments/mcp-genmedia/mcp-genmedia-go \
&& go work sync \
&& go install ./mcp-avtool-go ./mcp-chirp3-go ./mcp-imagen-go ./mcp-lyria-go ./mcp-veo-go \
&& rm -rf /tmp/build
# Ensure the workspace directory exists for the mounted project code
WORKDIR /workspace
# Copy scripts directory
COPY scripts/ /home/vscode/.devcontainer/scripts/
RUN chmod +x /home/vscode/.devcontainer/scripts/*.sh
# Copy static configuration files
COPY configs/ /home/vscode/.devcontainer/configs/
USER vscode
3. .devcontainer/configs/gemini-extension.json
This static file serves as a template for the Gemini CLI extension configuration. Environment variables will be substituted into it by the configure-gemini.sh
script.
.devcontainer/configs/gemini-extension.json
{
"name": "google-genmedia-extension",
"version": "1.0.0",
"mcpServers": {
"veo": {
"command": "${GOPATH}/bin/mcp-veo-go",
"env": {
"MCP_REQUEST_MAX_TOTAL_TIMEOUT": "240000",
"MCP_SERVER_REQUEST_TIMEOUT": "30000",
"GENMEDIA_BUCKET": "${GENMEDIA_BUCKET}",
"PROJECT_ID": "${PROJECT_ID}",
"LOCATION": "${LOCATION}"
}
},
"imagen": {
"command": "${GOPATH}/bin/mcp-imagen-go",
"env": {
"MCP_SERVER_REQUEST_TIMEOUT": "55000",
"GENMEDIA_BUCKET": "${GENMEDIA_BUCKET}",
"PROJECT_ID": "${PROJECT_ID}",
"LOCATION": "${LOCATION}"
}
},
"chirp3-hd": {
"command": "${GOPATH}/bin/mcp-chirp3-go",
"env": {
"MCP_SERVER_REQUEST_TIMEOUT": "55000",
"GENMEDIA_BUCKET": "${GENMEDIA_BUCKET}",
"PROJECT_ID": "${PROJECT_ID}",
"LOCATION": "${LOCATION}"
}
},
"lyria": {
"command": "${GOPATH}/bin/mcp-lyria-go",
"env": {
"GENMEDIA_BUCKET": "${GENMEDIA_BUCKET}",
"PROJECT_ID": "${PROJECT_ID}",
"MCP_SERVER_REQUEST_TIMEOUT": "55000",
"LOCATION": "${LOCATION}"
}
},
"avtool": {
"command": "${GOPATH}/bin/mcp-avtool-go",
"env": {
"PROJECT_ID": "${PROJECT_ID}",
"MCP_SERVER_REQUEST_TIMEOUT": "55000",
"LOCATION": "${LOCATION}"
}
}
}
}
4. .devcontainer/scripts/configure-gemini.sh
(Revised to use envsubst)
This script creates the Gemini CLI wrapper and substitutes environment variables into the gemini-extension.json
template.
.devcontainer/scripts/configure-gemini.sh
#!/bin/bash
set -e
echo "Configuring Gemini CLI for MCP Genmedia..."
# Create the `gemini` executable wrapper
sudo bash -c 'cat > /usr/local/bin/gemini << "EOL"
#!/bin/bash
exec npx https://github.com/google-gemini/gemini-cli "$@"
EOL'
sudo chmod +x /usr/local/bin/gemini
echo "? Gemini CLI wrapper created at /usr/local/bin/gemini."
# Create the Gemini CLI extensions directory
mkdir -p ~/.gemini/extensions/google-genmedia-extension/
echo "? Gemini extensions directory created."
# Substitute environment variables into the template and save the final config
# `envsubst` is used to replace shell variables in the JSON template.
# The list of variables needs to be explicitly provided to envsubst.
envsubst '$$GOPATH $$PROJECT_ID $$LOCATION $$GENMEDIA_BUCKET' < /home/vscode/.devcontainer/configs/gemini-extension.json \
> ~/.gemini/extensions/google-genmedia-extension/gemini-extension.json
echo "? Gemini extension configuration created with dynamic values."
echo "Gemini CLI configuration complete!"
Usage (Local Development):
- Clone the
vertex-ai-creative-studio
repository locally. - Ensure Docker is running on your local machine.
- Install the
devcontainer
CLI (if not already installed):npm install -g @devcontainers/cli
- Set your Google Cloud Project ID in your local terminal:
export PROJECT_ID="your-google-cloud-project-id"
- Navigate to the
experiments/mcp-genmedia
directory:cd vertex-ai-creative-studio/experiments/mcp-genmedia
- Build and start the DevContainer:
devcontainer up --workspace-folder .
- Attach to the running container (your IDE should prompt you, or use
devcontainer attach --workspace-folder .
). - Verify inside the container's terminal:
gemini --version /mcp
Production Deployment Strategy (Conceptual, for Future Implementation):
Once the DevContainer works reliably, the Dockerfile
from .devcontainer/Dockerfile
can be adapted for a production deployment. This would involve:
- Creating a dedicated
Dockerfile.production
: Potentially a smaller base image, less development tooling. - Building the image:
docker build -t gcr.io/your-project/mcp-genmedia-gemini:latest -f docker/Dockerfile.production .
- Pushing to Google Artifact Registry:
docker push gcr.io/your-project/mcp-genmedia-gemini:latest
- Deploying to a service:
- Cloud Run: For a serverless, scalable API endpoint (if exposing MCP servers via HTTP).
- Compute Engine (Container-Optimized OS): For a dedicated VM running the container, useful for SSH access and long-running tasks. This would include setting environment variables (
PROJECT_ID
,LOCATION
,GENMEDIA_BUCKET
) for the container at deployment time.
This plan focuses on setting up the fundamental DevContainer for a consistent development experience.