For the original README, see https://github.com/googleanalytics/google-analytics-mcp/blob/main/README.md
For a consistent and cross-platform experience, you can run the MCP server inside a Docker container. This avoids potential OS-specific dependency issues (e.g., gRPC on Windows) and doesn't require a local Python installation.
- Docker Desktop installed and running.
- Google Cloud CLI installed and authenticated (
gcloud auth loginandgcloud auth application-default login).
These instructions explain how to build a Docker image that is compatible with both linux/amd64 (for Intel/AMD CPUs) and linux/arm64 (for Apple Silicon) and publish it to Google Artifact Registry.
-
Enable the Artifact Registry API in your Google Cloud project (one-time setup):
gcloud services enable artifactregistry.googleapis.com --project=YOUR_PROJECT_ID -
Create a Docker repository in Artifact Registry (one-time setup):
gcloud artifacts repositories create YOUR_REPO_NAME --repository-format=docker --location=YOUR_REGION --project=YOUR_PROJECT_ID
-
Authenticate Docker with the repository:
gcloud auth configure-docker YOUR_REGION-docker.pkg.dev
-
Set up a
buildxbuilder. This enables multi-platform builds.docker buildx create --name mybuilder --use docker buildx inspect --bootstrap
-
Build and push the multi-platform image. This single command builds for both
amd64andarm64and pushes the resulting image to your repository. Replace the placeholders accordingly.docker buildx build --platform linux/amd64,linux/arm64 \ -t YOUR_REGION-docker.pkg.dev/YOUR_PROJECT_ID/YOUR_REPO_NAME/google-analytics-mcp:latest \ --push .
Once published, you can configure your Gemini client to use the image. See the platform-specific examples below.
Utilizzare questa configurazione:
"mcpServers": {
"analytics-mcp": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-v",
"C:/Users/YOUR_USER/AppData/Roaming/gcloud/application_default_credentials.json:/app/credentials.json:ro",
"-e",
"GOOGLE_APPLICATION_CREDENTIALS=/app/credentials.json",
"<DOCKER_IMAGE_ANALYTICS_MCP>"
]
}
}
Il problema specifico di Windows in questo caso era un'incompatibilità a basso livello tra il trasporto di rete gRPC e l'ambiente di esecuzione di Windows, quando utilizzato all'interno del server MCP.
Analizziamolo in dettaglio:
- I Due Metodi di Comunicazione: gRPC vs. REST
Le librerie client di Google (come google-analytics-admin) sono progettate per essere flessibili. Possono parlare con le API di Google in due "lingue" diverse: ~
- gRPC (il default): È un protocollo di comunicazione moderno, ad alte prestazioni, sviluppato da Google. È molto efficiente, veloce e ottimo per la comunicazione tra microservizi. Usa tecnologie avanzate come HTTP/2. È la scelta predefinita della t) libreria.
- REST (l'alternativa): È il protocollo standard del web, basato su HTTP/1.1. È universalmente compatibile, più semplice e più "trasparente" per firewall e proxy. Praticamente ogni cosa su internet sa come parlare REST.
- Il "Conflitto" su Windows
Il problema non era in gRPC in sé, né nella libreria di Google, né in Windows da soli. Il problema nasceva dalla combinazione di tutti questi elementi:
- Complessità di gRPC: Sotto il cofano, gRPC è molto più complesso di REST. Si affida a dipendenze scritte in C (chiamate "C-extensions") e ha una gestione della rete e dei processi molto sofisticata per essere così performante.
- Gestione dei Processi e dell'I/O su Windows: Windows gestisce l'I/O di rete (Input/Output), i thread e i processi in modo diverso rispetto a macOS o Linux. Il server MCP, a sua volta, usa asyncio di Python, che ha un suo modo di gestire eventi e operazioni asincrone.
- L'Innesco del Blocco: Quando il server MCP su Windows chiedeva alla libreria di Google di fare una chiamata, la libreria
usava gRPC (il default). A questo punto, è molto probabile che si sia verificato un deadlock (stallo):
- La parte C di gRPC stava aspettando un segnale o una risorsa di rete.
- Il gestore di eventi (asyncio) di Python, in esecuzione su Windows, non ha mai fornito quel segnale, o lo ha gestito in un modo che gRPC non si aspettava.
- Risultato: Il processo si è semplicemente "congelato" in attesa di un evento che non sarebbe mai arrivato. Ecco perché non vedevi un errore, ma solo un timeout.