Construindo um Servidor MCP Remoto para o Google Sheets

Construindo um Servidor MCP Remoto para Google Sheets: Do Zero à Produção
O que é MCP?
O Model Context Protocol (MCP) é um padrão aberto que permite que assistentes de IA — como Claude, ChatGPT e outros — se conectem a ferramentas externas e fontes de dados através de uma interface unificada. Pense nele como uma porta USB-C para IA: um protocolo, muitas ferramentas.
Em vez de cada cliente de IA implementar integrações personalizadas para cada serviço, o MCP define uma linguagem comum. Um servidor expõe ferramentas (funções que a IA pode chamar), e qualquer cliente compatível com MCP pode descobri-las e usá-las automaticamente.
Isso significa que você pode construir um servidor MCP e ele funciona em qualquer lugar — Claude Code, Claude.ai, Cursor, VS Code e qualquer outro cliente que fale o protocolo.
Por que Google Sheets?
O Google Sheets é uma das ferramentas mais utilizadas para gerenciamento de dados, e conectá-lo a assistentes de IA abre fluxos de trabalho poderosos:
- Pedir ao Claude para "ler os dados de vendas do Q1 da minha planilha e resumir tendências"
- Fazer uma IA adicionar linhas a uma planilha de acompanhamento como parte de um fluxo automatizado
- Criar novas planilhas com dados estruturados sem sair do terminal
O desafio? O Google Sheets requer autenticação OAuth, e a maioria dos servidores MCP roda localmente. Queríamos algo diferente: um servidor MCP remoto que qualquer pessoa pode usar apenas adicionando uma URL — sem chaves de API, sem configuração local, sem arquivos de configuração.
Visão Geral da Arquitetura
O servidor é construído com Next.js implantado na Vercel, usando Neon Postgres para armazenamento de sessões. O ponto-chave é um fluxo OAuth de duas camadas:
┌─────────────┐ MCP OAuth ┌──────────────────┐ Google OAuth ┌─────────────┐
│ Cliente MCP │ ◄──────────────────► │ Servidor MCP │ ◄─────────────────► │ APIs Google │
│ (Claude, │ Bearer tokens, │ (Next.js na │ Tokens de acesso/ │ (Sheets, │
│ Cursor) │ PKCE, registro │ Vercel) │ refresh, tela de │ Drive) │
│ │ dinâmico de client │ │ consentimento │ │
└─────────────┘ └──────────────────┘ └─────────────┘
│
▼
┌──────────────┐
│ Neon Postgres │
│ (sessões, │
│ códigos auth,│
│ clientes) │
└──────────────┘
Camada 1: MCP OAuth (Cliente ↔ Servidor)
Quando um cliente MCP se conecta, ele descobre os requisitos de autenticação via endpoints well-known padrão:
/.well-known/oauth-protected-resource— informa ao cliente que este recurso é protegido por OAuth/.well-known/oauth-authorization-server— fornece os metadados do servidor de autorização (endpoints, fluxos suportados)/oauth/register— registro dinâmico de cliente (o cliente se registra automaticamente)
Isso segue a especificação MCP, então qualquer cliente compatível lida com isso de forma transparente. PKCE é suportado para segurança.
Camada 2: Google OAuth (Servidor ↔ Google)
Quando o usuário precisa se autenticar:
/oauth/authorizerecebe a solicitação de autenticação do cliente MCP e redireciona para a tela de consentimento do Google- O usuário concede acesso ao Google Sheets e Drive
/oauth/callbackrecebe os tokens do Google, armazena-os no Postgres e redireciona de volta ao cliente MCP com um código de autorização/oauth/tokentroca o código por um token de acesso de sessão
O resultado final: o cliente MCP recebe um Bearer token, e o servidor mantém as credenciais do Google de forma segura.
O Endpoint MCP
O núcleo do servidor é um único Route Handler do Next.js em POST /mcp. Cada requisição cria uma nova instância de McpServer com um WebStandardStreamableHTTPServerTransport:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
export async function POST(request: NextRequest) {
const token = request.headers.get("authorization")?.replace("Bearer ", "");
if (!token) return unauthorizedResponse();
const server = new McpServer({
name: "google-sheets",
version: "0.1.0",
});
registerTools(server, () => resolveGoogleAuth(token));
const transport = new WebStandardStreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
await server.connect(transport);
return await transport.handleRequest(request);
}
O WebStandardStreamableHTTPServerTransport é a peça-chave — ele funciona com as APIs Web Standard Request/Response que os Route Handlers do Next.js utilizam, tornando a implantação em plataformas serverless como a Vercel algo simples.
Ferramentas Expostas
O servidor registra 8 ferramentas que cobrem todo o espectro de operações do Google Sheets:
| Ferramenta | Descrição |
|---|---|
list_spreadsheets |
Pesquisa e lista planilhas do Google Drive |
get_spreadsheet |
Obtém metadados da planilha (nomes das abas, dimensões) |
read_sheet |
Lê dados de um intervalo (retorna tabela formatada) |
write_sheet |
Escreve dados em um intervalo específico (sobrescreve) |
append_rows |
Adiciona linhas ao final de uma aba |
update_cells |
Atualiza células individuais em posições específicas |
create_spreadsheet |
Cria uma nova planilha |
batch_get |
Lê múltiplos intervalos em uma única requisição |
Cada ferramenta usa schemas Zod para validação de entrada e inclui descrições que ajudam os clientes de IA a entender quando e como usá-las:
server.registerTool(
"read_sheet",
{
description: "Read data from a spreadsheet range. Returns a formatted table.",
inputSchema: {
spreadsheet_id: z.string().describe("The spreadsheet ID"),
range: z.string().describe("A1 notation range, e.g. 'Sheet1!A1:D10'"),
},
},
async ({ spreadsheet_id, range }) => {
const auth = await getAuth();
const data = await sheetsLib.readSheet(auth, spreadsheet_id, range);
// Formata como tabela legível...
return { content: [{ type: "text", text }] };
}
);
Stack Tecnológica
- Next.js 15 — App Router com Route Handlers para todos os endpoints
- Vercel — Implantação serverless com deploy via git push
- Neon Postgres — PostgreSQL serverless para armazenamento de sessões/tokens
- Prisma — ORM com três tabelas:
oauth_clients,auth_codes,sessions - @modelcontextprotocol/sdk — SDK oficial do MCP para TypeScript
- googleapis — Cliente oficial do Google para Node.js para as APIs Sheets e Drive
- Zod — Validação de schemas para entradas das ferramentas
Implantação
O projeto é implantado automaticamente a cada push para master. O comando de build cuida de tudo:
prisma generate && prisma migrate deploy && next build
As migrações do Prisma rodam automaticamente durante o build, então mudanças no schema do banco de dados são implantadas junto com as mudanças de código de forma transparente.
Como Usar
Adicionando ao Claude Code
Adicione a URL do servidor à configuração do seu cliente MCP:
{
"mcpServers": {
"google-sheets": {
"url": "https://mcp-google-sheets.vercel.app/mcp"
}
}
}
É só isso. Na primeira vez que você usar uma ferramenta de planilhas, o fluxo OAuth é iniciado — seu navegador abre, você concede acesso ao Google Sheets e está conectado.
Adicionando ao Claude.ai
Vá em Configurações > Servidores MCP > Adicionar Servidor e cole a URL:
https://mcp-google-sheets.vercel.app/mcp
O Claude lidará com o fluxo de autenticação automaticamente.
Inspecionando e Depurando com o MCP Inspector
O MCP Inspector é uma ferramenta essencial para desenvolver e depurar servidores MCP. Ele fornece uma interface web onde você pode ver as capacidades do servidor, testar ferramentas interativamente e inspecionar as mensagens do protocolo.
Executando o Inspector
Para inspecionar nosso servidor MCP remoto, execute:
npx @modelcontextprotocol/inspector https://mcp-google-sheets-delta.vercel.app/mcp
Isso inicia uma interface web local (geralmente em http://localhost:6274) que se conecta ao servidor remoto.
O que Você Pode Fazer com o Inspector
-
Autenticar — O Inspector suporta o fluxo completo de OAuth do MCP. Clique em "Connect" e ele guiará você pela autenticação do Google, assim como um cliente MCP real faria.
-
Listar Ferramentas — Veja todas as 8 ferramentas que o servidor expõe, junto com suas descrições e schemas de entrada. Ótimo para verificar se suas definições de ferramentas estão corretas.
-
Chamar Ferramentas — Preencha parâmetros e execute ferramentas diretamente. Por exemplo, você pode chamar
list_spreadsheetspara ver suas planilhas do Google, depois chamarread_sheetcom um ID de planilha e intervalo específicos. -
Inspecionar Mensagens do Protocolo — Veja as mensagens JSON-RPC brutas trocadas entre cliente e servidor. Isso é invaluável para depurar problemas com chamadas de ferramentas, autenticação ou transporte.
-
Testar Tratamento de Erros — Tente chamar ferramentas com parâmetros inválidos para verificar se suas respostas de erro fazem sentido.
Exemplo de Fluxo de Trabalho com o Inspector
1. Execute: npx @modelcontextprotocol/inspector https://mcp-google-sheets-delta.vercel.app/mcp
2. Abra http://localhost:6274 no seu navegador
3. Clique em "Connect" → Complete o OAuth do Google no popup
4. Navegue até a aba "Tools" → Veja todas as 8 ferramentas registradas
5. Selecione "list_spreadsheets" → Clique em "Run" → Veja suas planilhas
6. Selecione "read_sheet" → Insira um spreadsheet_id e intervalo → Veja os dados
O Inspector também é útil para desenvolvimento local:
# Inicie o servidor de desenvolvimento
pnpm dev
# Em outro terminal, aponte o inspector para o localhost
npx @modelcontextprotocol/inspector http://localhost:3100/mcp
Lições Aprendidas
1. Normalização do Header Accept
Alguns clientes MCP enviam Accept: */* em vez dos tipos de conteúdo específicos que o SDK espera (application/json, text/event-stream). Tivemos que normalizar o header nas requisições de entrada para evitar que o transporte rejeitasse requisições válidas.
2. Não Feche o Servidor Cedo Demais
O WebStandardStreamableHTTPServerTransport retorna um stream SSE (Server-Sent Events). O corpo da resposta é populado de forma assíncrona — se você chamar server.close() imediatamente após obter a resposta, ele mata o stream antes do cliente lê-lo. Deixe o ciclo de vida natural da função serverless cuidar da limpeza.
3. CORS Importa para Servidores Remotos
Diferente de servidores MCP locais, um servidor remoto precisa de headers CORS adequados. Clientes MCP rodando em navegadores (como o Claude.ai) precisam fazer requisições cross-origin para o seu servidor. Todo endpoint — incluindo preflight OPTIONS — precisa dos headers corretos.
4. Refresh de Token é Crítico
Tokens de acesso do Google expiram após ~1 hora. O servidor verifica a expiração do token em cada requisição e faz o refresh de forma transparente usando o refresh token armazenado. Sem isso, os usuários precisariam se reautenticar constantemente.
Conclusão
Construir um servidor MCP remoto é uma forma poderosa de dar aos assistentes de IA acesso a serviços externos. O protocolo MCP lida com a complexidade da descoberta de ferramentas e autenticação, enquanto plataformas como Vercel e Neon tornam a implantação e o armazenamento de dados algo simples.
A principal vantagem de um servidor remoto sobre um local é zero configuração para os usuários finais — eles adicionam uma URL e se autenticam uma vez. Sem chaves de API para gerenciar, sem processos locais para rodar, sem arquivos de configuração para manter.


