Abílio Azevedo.

Construindo um Servidor MCP Remoto para o Google Sheets

Cover Image for Construindo um Servidor MCP Remoto para o Google Sheets
Abílio Azevedo
Abílio Azevedo

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:

  1. /.well-known/oauth-protected-resource — informa ao cliente que este recurso é protegido por OAuth
  2. /.well-known/oauth-authorization-server — fornece os metadados do servidor de autorização (endpoints, fluxos suportados)
  3. /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:

  1. /oauth/authorize recebe a solicitação de autenticação do cliente MCP e redireciona para a tela de consentimento do Google
  2. O usuário concede acesso ao Google Sheets e Drive
  3. /oauth/callback recebe os tokens do Google, armazena-os no Postgres e redireciona de volta ao cliente MCP com um código de autorização
  4. /oauth/token troca 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

  1. 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.

  2. 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.

  3. Chamar Ferramentas — Preencha parâmetros e execute ferramentas diretamente. Por exemplo, você pode chamar list_spreadsheets para ver suas planilhas do Google, depois chamar read_sheet com um ID de planilha e intervalo específicos.

  4. 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.

  5. 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.


Mais posts

Cover Image for UX/UI para desenvolvedores

UX/UI para desenvolvedores

UX/UI para Desenvolvedores — Guia pratico sobre design systems, comunicacao com Product Designers e quando reutilizar componentes. Aborda heuristicas de Nielsen, Atomic Design, bibliotecas de componentes Tailwind CSS como shadcn/ui e Radix UI, ferramentas de prototipagem como Figma e Origami Studio, boas praticas de acessibilidade, e uma curadoria de cursos, artigos e livros para desenvolvedores que querem construir melhores experiencias de usuario.

Abílio Azevedo
Abílio Azevedo
Cover Image for Ferramentas de IA para o Dia a Dia do Dev

Ferramentas de IA para o Dia a Dia do Dev

Aprenda a debugar de forma mais inteligente com prompts de IA, auditar SEO pelo terminal, ir de erros no Sentry a PRs em minutos e desbloquear recursos ocultos do Claude Code.

Abílio Azevedo
Abílio Azevedo

NewsLetter

Eu enviarei o conteúdo postado aqui no blog. Sem Spam =)