Data-Labs MCP — Conecte GA4, Search Console, GTM e Google Ads a Qualquer Agente de IA
Plataforma SaaS multitenant de MCPs gerenciados para analytics e marketing. O cliente conecta as contas uma vez e recebe endpoints MCP remotos e seguros, com 28 tools governadas, prontos para Claude Desktop, Claude Code, ChatGPT ou agentes próprios.
Problema
Todo time que quer usar IA sobre os próprios dados de marketing esbarra na mesma parede: conectar GA4, Search Console, GTM e Google Ads a um agente exige escrever e hospedar um servidor MCP por ferramenta, lidar com OAuth do Google, guardar e rotacionar tokens, e — a parte que quase ninguém faz — controlar o que o agente pode executar. Sem isso, ou o projeto não sai do papel, ou nasce um script com credencial de produção em texto plano e permissão para gastar orçamento de mídia.
Solução
Uma plataforma onde o cliente conecta as contas uma única vez, por OAuth, e recebe endpoints MCP remotos prontos. Os tokens do Google ficam no Secret Manager e nunca chegam ao LLM. Cada instância tem política própria (recursos permitidos, período máximo, limite de linhas, teto de orçamento), e tools de risco exigem aprovação humana no painel antes de executar — uma única vez.
Resultados
No ar: onboarding em 3 etapas para GA4/GSC/GTM/Ads, gateway com 28 tools classificadas por risco, autenticação por PAT e por OAuth 2.1 com Dynamic Client Registration (fluxo completo da spec MCP, funcionando no Claude Desktop), aprovações human-in-the-loop, logs de execução com argumentos mascarados, medição de uso, equipe e convites — tudo sobre Postgres com RLS multitenant.
Data-Labs MCP
O objetivo
Conecte suas ferramentas uma vez e disponibilize capacidades seguras e prontas para qualquer agente de IA compatível com MCP.
O cliente conecta Google Analytics 4, Search Console, Google Tag Manager e Google Ads uma única vez pelo painel. A partir daí recebe endpoints MCP remotos que funcionam em Claude Desktop, Claude Code, ChatGPT ou em um agente próprio — sem desenvolver, hospedar ou manter nenhuma integração.

O painel de MCPs: cada conexão com suas tools, canal de release, último uso e o endpoint pronto para copiar.
O problema que ele resolve
O MCP resolveu o protocolo de conectar IA a ferramentas. Ele não resolveu a operação em volta.
Quem tenta montar isso internamente descobre a lista completa rápido:
- escrever um servidor MCP por ferramenta, e mantê-lo conforme as APIs mudam;
- hospedar e monitorar esses servidores;
- implementar OAuth do Google, guardar refresh tokens, rotacionar sem quebrar;
- resolver multitenancy se mais de um cliente ou time usa;
- governar o que o agente pode fazer.
O item 5 é o que quase ninguém constrói, e é o mais importante. Um agente com acesso ao Google Ads pode alterar orçamento. Um com acesso ao GTM pode publicar container em produção. "Confia no prompt" não é controle de acesso.
O atalho comum — um script local com credencial em texto plano e permissão total — é exatamente o que não passa em nenhuma revisão de segurança.
Como foi feito
Duas autenticações que não se misturam
Essa separação é o núcleo do desenho, e vale explicar com calma. São duas perguntas diferentes:
1. Quem está chamando o endpoint? (cliente MCP → plataforma)
- PAT (
dlp_…): token pessoal gerado no painel. É o caminho para Claude Code via--headere para automações. - OAuth 2.1 + Dynamic Client Registration (
dlat_…/dlrt_…): o fluxo completo da spec MCP. O Claude Desktop recebe 401, descobre os metadados do Authorization Server, se registra dinamicamente, o usuário dá consentimento na página/autorizardo painel, PKCE S256, refresh rotativo. Zero configuração manual do lado do usuário.
2. Com qual conta a tool executa? (plataforma → ferramenta externa)
OAuth do Google por conexão, com os tokens no Secret Manager
(org-…-conn-…-google) e refresh automático. E a regra que não se quebra:
o token externo nunca chega ao LLM. O modelo pede uma tool; o gateway executa com a
credencial certa e devolve só o resultado.
Confundir essas duas camadas é o erro clássico de quem monta MCP com acesso a dados de terceiros — e é o que faz o token de produção vazar num log de conversa.
Governança: catálogo, política e aprovação
Catálogo versionado (catalog.*): 4 produtos, 28 tools, cada uma com JSON Schema de entrada
e classificação de risco — leitura, análise, escrita, escrita financeira, publicação,
destrutiva. A classificação não é decorativa: ela define o comportamento do gateway.

O catálogo de conectores: cada produto versionado, com as tools disponíveis e a configuração de política por instância.
Política por instância: cada instância de MCP declara quais recursos são permitidos (quais propriedades GA4, quais sites do GSC, quais containers do GTM, quais contas de Ads), período máximo consultável, limite de linhas por resposta e teto de orçamento. Pedido fora da política não executa.
Aprovações human-in-the-loop: tools marcadas com confirmação obrigatória não executam direto. Elas criam uma solicitação com fingerprint dos argumentos. O responsável aprova no painel, e aquela chamada exata executa uma única vez — o fingerprint impede que a aprovação seja reaproveitada para argumentos diferentes.
Rastro: toda execução grava em observability.tool_executions com argumentos mascarados e
incrementa billing.usage_counters. A medição já está ativa; a cobrança vem depois.

Auditoria de execuções: dá para ver qual cliente de IA chamou qual tool, com que resultado e em quanto tempo — com os argumentos mascarados.
Arquitetura
GitHub (main) ──push──► Cloud Build (trigger por pasta) ──► Artifact Registry ──► Cloud Run
│
┌──────────────────┬─────────────────────┬─────────────────────┘
▼ ▼ ▼
web (React SPA) api (FastAPI) mcp-gateway (FastAPI)
│ │ │ JSON-RPC MCP + OAuth 2.1 AS
│ ▼ ▼
│ Cloud SQL Postgres 16 (11 schemas, RLS multitenant)
│ │ │
│ │ ├─► Secret Manager (tokens OAuth por conexão)
│ │ ├─► APIs Google (GA4, GSC, GTM, Ads)
│ │ └─► observability.* + billing.usage_counters
│ └─► Identity Platform (login + verificação de e-mail)
└─► Cloud Storage (exports) · BigQuery mcp_analytics (histórico/agregados)
Três serviços independentes no Cloud Run: o painel React, a API REST do painel, e o gateway MCP — que é também o Authorization Server OAuth 2.1. Cada um com seu pipeline de build, disparado por path no push.
Banco: RLS multitenant e uma armadilha real
Postgres 16 com 11 schemas: identity, tenancy, catalog, integrations, mcp_runtime,
authz, observability, audit, billing, notifications, approvals.
(authz se chama assim porque authorization é palavra reservada no Postgres — descoberta
que custou uma migration.)
O isolamento é por Row Level Security, e o tenant vem sempre do token validado, nunca do
body da requisição. A API e o gateway setam GUCs por transação:
app.current_user, app.current_org, app.current_email, app.endpoint_slug.
Aqui mora a armadilha mais cara do projeto: GUC customizado em pool de conexões reverte para
string vazia após o SET LOCAL, não para NULL. Uma política RLS escrita do jeito óbvio
compara com NULL, a comparação dá NULL, e o comportamento fica silenciosamente errado. A
correção foi envolver tudo em NULLIF(..., '') nas políticas. É o tipo de bug que não aparece
em teste local com conexão única e só se manifesta sob concorrência.
Segredos nunca ficam no banco — só referências ao Secret Manager.
Regra de ouro do frontend
Zero dados simulados. Toda tela do painel consome a API real; sem dados, mostra empty state. Nada de mock que "depois a gente troca" — porque nunca se troca, e o produto passa a mentir sobre o que funciona.
Para manter isso honesto, existe um docs/GLOSSARIO-ROTAS.md que mapeia cada elemento de tela
para a rota, a tabela e o campo que o alimentam.
CI/CD e privilégio mínimo
Push na main dispara triggers por path (deploy-api, deploy-web, deploy-mcp-gateway,
deploy-db) → build → deploy. Sem passo manual. As migrations rodam automaticamente como um
Cloud Run Job.
Cada serviço tem sua service account com o mínimo necessário: api-sa, gateway-sa,
migrate-sa, deploy-sa. O runner de migration roda como postgres — e é justamente por isso
que o RLS é aplicado ao papel datalabs_app, não ao superusuário.
Coisas que só se aprende em produção
/healthzé interceptado pela borda do Cloud Run. Usamos/health.- A API key do Identity Platform precisa liberar
securetoken.googleapis.com, não sóidentitytoolkit— senão o login funciona e o refresh de sessão falha depois. Form(...)no FastAPI exigepython-multipartno requirements, e o erro não diz isso.- Cloud SQL com tier custom exige
--edition=enterprise.
Stack
Frontend: React + Vite + TypeScript + Tailwind (TS estrito faz papel de linter) Backend: FastAPI (API do painel e gateway MCP), Python Dados: Cloud SQL Postgres 16 com RLS, BigQuery para histórico e agregados Infra: Cloud Run, Cloud Build, Artifact Registry, Secret Manager, Identity Platform, Cloud Storage Protocolos: MCP (JSON-RPC), OAuth 2.1 + PKCE S256 + Dynamic Client Registration
Status atual
No ar: onboarding em 3 etapas (GA4/GSC/GTM/Ads), gateway com 28 tools, PAT + OAuth DCR, aprovações, logs, uso, saúde, changelog, equipe e convites, verificação de e-mail no cadastro.
Pendências externas (dependem de terceiros, não de código): developer token do Google Ads via API Center da MCC; verificação do OAuth consent screen na Google — hoje em modo Testing, limitado a 100 test users; domínio próprio.
Backlog: cobrança e integração com PSP (a medição já roda), Central de ajuda, permissões por grupo, e-mail transacional próprio, export agendado para BigQuery, e métodos adicionais de autenticação de conexões (service account, BYO client, developer token).
Quer testar antes de todo mundo?
Estou abrindo um grupo pequeno de primeiros testers — pessoas que vão usar a plataforma de verdade, com acompanhamento direto meu na configuração e no primeiro caso de uso real. Em troca, quero feedback honesto sobre o que funciona e o que ainda não funciona.
Se isso faz sentido pro seu time:
👉 Falar comigo no WhatsApp — (11) 96552-1585
Manda uma mensagem dizendo qual é o seu cenário e eu respondo com os próximos passos.