Skip to main content
ai voice11 de março de 202616 min de leitura

Integrações com Servidor MCP Explicadas: Conectando Ferramentas de IA aos Seus Dados

O que são servidores MCP (Model Context Protocol), como funcionam e como construir um. Exemplo real da integração do HeySeo com Claude, Cursor e Windsurf.

Loic Bachellerie

Senior Product Engineer

Introdução

Imagine abrir o Claude e perguntar: "Quais landing pages estão perdendo mais tráfego orgânico esta semana?" e receber uma resposta real - com URLs específicas, quedas percentuais e as palavras-chave responsáveis. Não uma resposta genérica sobre SEO. Seus dados reais.

É isso que o MCP possibilita. O Model Context Protocol é a camada que faltava entre ferramentas de IA e os sistemas nos quais seu negócio realmente opera. Eu construí o servidor MCP para o HeySeo, um SaaS de analytics de SEO, e isso mudou a forma como uso Claude, Cursor e Windsurf todos os dias.

Neste guia, vou explicar o que é MCP, como a arquitetura funciona e como construir um do zero - com o código TypeScript real que uso em produção.

O Que É MCP?

MCP, abreviação de Model Context Protocol, é um padrão aberto criado pela Anthropic no final de 2024. A ideia central é simples: dar aos assistentes de IA uma forma padronizada de chamar ferramentas e ler dados de sistemas externos.

Antes do MCP, cada integração de ferramenta era feita sob medida. Você escreveria um plugin customizado para Claude, uma extensão para Cursor ou uma integração para Windsurf separadamente. Cada um tinha seu próprio contrato de API, seu próprio esquema de autenticação, seu próprio formato para passar contexto. Era o mesmo problema de duplicação que clientes de REST API tinham antes do OpenAPI - e o MCP resolve da mesma forma: com um protocolo compartilhado.

Um servidor MCP expõe ferramentas, recursos e prompts através de uma interface JSON-RPC padrão. Um cliente de IA (Claude Desktop, Cursor, Windsurf ou seu próprio app) se conecta a esse servidor e usa quaisquer capacidades que ele exponha. Construa o servidor uma vez, conecte a todos os clientes.

O que você pode expor via MCP:

  • Tools - funções chamáveis que a IA pode invocar (buscar analytics, pesquisar, executar queries)
  • Resources - fontes de dados legíveis às quais a IA pode se inscrever (métricas ao vivo, documentos)
  • Prompts - templates de prompt pré-construídos que seus usuários podem invocar pelo nome

Por Que o MCP Importa para Desenvolvedores

Se você está construindo um produto SaaS, uma ferramenta interna, ou até mesmo uma configuração pessoal de produtividade, o MCP é a forma mais prática de conectar IA aos dados que você possui.

Antes do MCP, eu copiava e colava dados na janela de contexto do Claude. Relatório mensal de tráfego? Exportar para CSV, colar as primeiras linhas, fazer perguntas. Tedioso, com perdas e limitado ao que cabe no contexto.

Depois do MCP, eu pergunto diretamente ao Claude. A IA chama meu servidor MCP, que consulta as tabelas certas do banco de dados, executa a análise e retorna dados estruturados. O Claude então sintetiza em uma resposta. O ciclo inteiro leva segundos.

A mudança é significativa de três formas:

  • Atualidade - a IA vê dados ao vivo, não uma exportação obsoleta da terça-feira passada
  • Profundidade - a IA pode fazer queries de acompanhamento sem que eu busque mais dados manualmente
  • Consistência - o mesmo servidor funciona em todas as ferramentas de IA que uso

Para o HeySeo especificamente, isso significou que nossos usuários podiam conectar Claude ou Cursor aos analytics do próprio site e receber conselhos de SEO genuinamente contextualizados - não boas práticas genéricas.

Visão Geral da Arquitetura

Antes de escrever qualquer código, é útil entender como as peças se conectam.

Arquitetura MCP

Como clientes de IA se conectam aos seus dados através de um protocolo padrão

AI Clients
Claude Desktop
Cursor
Windsurf
Slack (via bot)
Custom apps
MCP Server
Tools

Funções chamáveis

Resources

Streams de dados legíveis

Prompts

Templates de prompt nomeados

JSON-RPC 2.0
Seus Dados
PostgreSQL / Firestore
Google Search Console
Analytics APIs
Internal APIs
File systems
stdio transport
HTTP/SSE transport
WebSocket transport

O protocolo suporta dois modos de transporte:

  • stdio - o cliente inicia o servidor como um subprocesso e se comunica via stdin/stdout. Rápido, zero overhead de rede, ideal para ferramentas de desenvolvimento local como Claude Desktop, Cursor e Windsurf.
  • HTTP com SSE - o servidor roda como um serviço HTTP padrão. Melhor para deploys em produção onde múltiplos usuários precisam de acesso concorrente, ou onde o servidor deve ser hospedado separadamente do cliente.

Para o HeySeo, usamos stdio para desenvolvedores conectando através da IDE e HTTP/SSE para o servidor de produção ao qual nosso bot do Slack se conecta.

Construindo um Servidor MCP Passo a Passo

O SDK oficial para TypeScript é o @modelcontextprotocol/sdk. Ele gerencia o framing do protocolo, ciclo de vida da conexão e type safety, para que você possa focar na sua lógica de negócio.

Instalar Dependências

npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsx

Inicializar o Servidor

// src/server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
 
const server = new McpServer({
  name: "heyseo",
  version: "1.0.0",
});

A classe McpServer é a base. Você registra ferramentas e recursos nela, depois conecta um transporte.

Registrar Sua Primeira Ferramenta

Uma ferramenta é uma função que a IA pode chamar com parâmetros tipados. Aqui está uma ferramenta real do HeySeo que busca as palavras-chave de melhor desempenho para um site:

// src/tools/top-keywords.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { getTopKeywords } from "../data/keywords.js";
 
export function registerTopKeywordsTool(server: McpServer) {
  server.tool(
    "get_top_keywords",
    "Fetch the top-ranking keywords for a site, with click and impression data from Google Search Console.",
    {
      siteUrl: z
        .string()
        .url()
        .describe("The verified site URL, e.g. https://example.com"),
      limit: z
        .number()
        .int()
        .min(1)
        .max(100)
        .default(20)
        .describe("Number of keywords to return"),
      dateRange: z
        .enum(["7d", "28d", "90d"])
        .default("28d")
        .describe("Date range for the data"),
    },
    async ({ siteUrl, limit, dateRange }) => {
      const keywords = await getTopKeywords({ siteUrl, limit, dateRange });
 
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(keywords, null, 2),
          },
        ],
      };
    }
  );
}

O schema Zod tem dupla função: valida inputs em runtime e gera o JSON Schema que o cliente de IA usa para entender quais parâmetros a ferramenta aceita. Esse é um daqueles detalhes que importam na prática - se seu schema é vago, a IA vai chamar sua ferramenta com argumentos errados.

Registrar um Recurso

Recursos são diferentes de ferramentas. Uma ferramenta é imperativa (faça algo). Um recurso é declarativo (aqui estão dados que você pode ler). Pense nisso como um feed RSS ao qual a IA pode se inscrever.

// src/resources/site-overview.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { getSiteOverview } from "../data/overview.js";
 
export function registerSiteOverviewResource(server: McpServer) {
  server.resource(
    "site-overview",
    "heyseo://sites/{siteUrl}/overview",
    async (uri) => {
      const siteUrl = extractSiteUrl(uri.href);
      const overview = await getSiteOverview(siteUrl);
 
      return {
        contents: [
          {
            uri: uri.href,
            mimeType: "application/json",
            text: JSON.stringify(overview, null, 2),
          },
        ],
      };
    }
  );
}
 
function extractSiteUrl(href: string): string {
  const match = href.match(/heyseo:\/\/sites\/([^/]+)\/overview/);
  if (!match) {
    throw new Error(`Invalid resource URI: ${href}`);
  }
  return decodeURIComponent(match[1]);
}

Conectar o Transporte e Iniciar

// src/server.ts (continued)
import { registerTopKeywordsTool } from "./tools/top-keywords.js";
import { registerSiteOverviewResource } from "./resources/site-overview.js";
 
registerTopKeywordsTool(server);
registerSiteOverviewResource(server);
 
const transport = new StdioServerTransport();
await server.connect(transport);
 
// Keep alive - the server runs until the client disconnects

Para deploys HTTP em produção, troque o transporte:

import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import express from "express";
 
const app = express();
const transport = new SSEServerTransport("/messages", res);
app.get("/sse", (req, res) => server.connect(new SSEServerTransport("/messages", res)));
app.post("/messages", express.json(), (req, res) => transport.handlePostMessage(req, res));
app.listen(3000);

Conectando ao Claude Desktop

O Claude Desktop tem suporte nativo a MCP. Você configura servidores em ~/Library/Application Support/Claude/claude_desktop_config.json no macOS:

{
  "mcpServers": {
    "heyseo": {
      "command": "node",
      "args": ["/path/to/heyseo-mcp/dist/server.js"],
      "env": {
        "HEYSEO_API_KEY": "your-api-key"
      }
    }
  }
}

Reinicie o Claude Desktop após editar. Você verá um pequeno ícone de ferramentas na barra de input quando um servidor estiver conectado. A partir daí, qualquer conversa pode chamar suas ferramentas - o Claude decide autonomamente quando invocá-las com base no contexto.

Na prática, faço perguntas como "Quais páginas estão canibalizando umas às outras para a palavra-chave 'melhor crm para startups'?" e o Claude chama search_keyword_cannibalization no meu servidor MCP, recebe dados estruturados de volta e sintetiza uma recomendação clara. Sem necessidade de copiar e colar.

Conectando ao Cursor

O Cursor adicionou suporte a MCP na versão 0.43. A configuração fica em ~/.cursor/mcp.json:

{
  "mcpServers": {
    "heyseo": {
      "command": "node",
      "args": ["/path/to/heyseo-mcp/dist/server.js"],
      "env": {
        "HEYSEO_API_KEY": "your-api-key"
      }
    }
  }
}

Dentro do Cursor, as ferramentas MCP estão disponíveis nos painéis Composer (Cmd+I) e Chat (Cmd+L). A diferença principal em relação ao Claude Desktop é o contexto: quando você está trabalhando em código no Cursor, a IA também tem o contexto dos seus arquivos. Então você pode perguntar "com base nos analytics deste componente, quais dessas palavras-chave eu deveria mirar no copy?" e a IA pode raciocinar tanto sobre o código na tela quanto sobre os dados ao vivo do seu servidor MCP simultaneamente.

Para o HeySeo, uso isso ao construir novas landing pages. O servidor MCP me diz as oportunidades atuais de palavras-chave, e o Cursor me ajuda a implementar a estrutura de conteúdo que as mira.

Conectando ao Windsurf

O Windsurf (IDE agêntica da Codeium) usa o mesmo formato de configuração. Abra Settings, navegue até MCP e adicione a entrada do seu servidor. O agente Cascade do Windsurf é particularmente bom em tarefas multi-etapa que combinam mudanças de código com buscas de dados externos - que é exatamente o que o MCP possibilita.

Uma coisa que notei especificamente com o Windsurf: seu agente é mais agressivo em chamar ferramentas MCP automaticamente sem você pedir. Quando estou trabalhando em uma página que tem uma URL correspondente a algo no nosso sitemap, o Cascade busca proativamente dados de desempenho de palavras-chave e os exibe no painel de contexto. É algo pequeno, mas significa que os dados estão lá antes mesmo de você perceber que precisa deles.

Exemplo Real: Servidor MCP do HeySeo

O HeySeo é um SaaS de analytics de SEO que se conecta ao Google Search Console e GA4. A integração MCP que construímos expõe as capacidades analíticas centrais da plataforma para qualquer ferramenta de IA que o usuário prefira.

Aqui estão as ferramentas que disponibilizamos:

FerramentaO que faz
get_top_keywordsPrincipais palavras-chave por cliques, impressões, CTR
get_landing_pagesBreakdown de desempenho por página
get_ranking_historyPosição da palavra-chave ao longo do tempo
search_serpDados SERP ao vivo para qualquer consulta
get_opportunitiesGaps de palavras-chave e ganhos rápidos
run_onpage_auditAuditoria técnica de SEO para uma URL
query_gscQuery bruta do GSC com intervalo de datas e dimensões customizadas

Aqui está o buscador de oportunidades, que é uma das ferramentas mais úteis na prática:

// src/tools/find-opportunities.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { findKeywordOpportunities } from "../data/opportunities.js";
 
export function registerFindOpportunitiesTool(server: McpServer) {
  server.tool(
    "find_opportunities",
    "Find keyword opportunities for a site: queries with high impressions but low CTR (position 4-20), indicating quick wins with content improvements.",
    {
      siteUrl: z.string().url().describe("Site URL to analyze"),
      minImpressions: z
        .number()
        .int()
        .min(10)
        .default(100)
        .describe("Minimum impression threshold"),
      maxPosition: z
        .number()
        .min(1)
        .max(50)
        .default(20)
        .describe("Maximum average position to include"),
    },
    async ({ siteUrl, minImpressions, maxPosition }) => {
      const opportunities = await findKeywordOpportunities({
        siteUrl,
        minImpressions,
        maxPosition,
      });
 
      const formatted = opportunities.map((kw) => ({
        query: kw.query,
        impressions: kw.impressions,
        clicks: kw.clicks,
        ctr: `${(kw.ctr * 100).toFixed(1)}%`,
        position: kw.position.toFixed(1),
        estimatedTrafficGain: kw.estimatedGain,
      }));
 
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(
              {
                total: formatted.length,
                opportunities: formatted.slice(0, 50),
              },
              null,
              2
            ),
          },
        ],
      };
    }
  );
}

A camada de dados (findKeywordOpportunities) consulta nosso banco Firestore, que sincroniza do Google Search Console diariamente. O servidor MCP não se importa com o banco de dados - ele apenas chama funções e retorna dados estruturados. Essa separação mantém o servidor simples e a lógica de negócio testável.

A Integração com Slack

Para o bot do Slack, rodamos o servidor MCP do HeySeo via HTTP/SSE e o chamamos a partir de um handler de slash command do Slack. Usuários digitam /heyseo opportunities site:example.com no Slack, nosso bot faz POST para o servidor MCP, recebe os dados de volta e os formata em uma mensagem Slack Block Kit.

Foram cerca de 150 linhas de código em cima do servidor MCP existente. O servidor em si não precisou de nenhuma mudança - esse é o valor da abstração do protocolo.

Considerações de Segurança

Expor dados de negócio através de uma interface de ferramenta de IA introduz uma superfície de segurança real. Veja como penso sobre isso para o HeySeo.

Autenticação. Para transportes stdio (Claude Desktop, Cursor, Windsurf), o servidor roda como processo do usuário. Variáveis de ambiente para API keys são aceitáveis aqui - a chave nunca sai da máquina. Para transportes HTTP, use autenticação bearer token em cada requisição.

// src/middleware/auth.ts
export function requireApiKey(apiKey: string | undefined): void {
  const expectedKey = process.env.HEYSEO_API_KEY;
 
  if (!expectedKey) {
    throw new Error("HEYSEO_API_KEY environment variable is not set");
  }
 
  if (apiKey !== expectedKey) {
    throw new Error("Invalid API key");
  }
}

Limitação de escopo. Ferramentas devem expor apenas o necessário. Se um usuário conecta seu site pessoal, o servidor deve retornar dados apenas daquele site - não de qualquer outro site no sistema. Aplicamos isso vinculando cada API key a um siteUrl específico no nível do banco de dados.

Validação de input. Os schemas Zod nas definições das suas ferramentas são sua primeira linha de defesa. Trate todos os inputs de ferramentas como não confiáveis e valide-os rigorosamente. Nunca passe inputs de string brutos diretamente para uma query de banco de dados.

// Never do this
const results = await db.query(`SELECT * FROM keywords WHERE site = '${siteUrl}'`);
 
// Always do this
const results = await db.collection("keywords")
  .where("siteUrl", "==", siteUrl)
  .limit(100)
  .get();

Rate limiting. Ferramentas de IA podem chamar seu servidor MCP agressivamente, especialmente durante execuções de agentes multi-etapa. Adicione rate limiting por chave para proteger seu backend e suas cotas de API.

// src/middleware/rate-limit.ts
const requestCounts = new Map<string, { count: number; resetAt: number }>();
 
export function checkRateLimit(apiKey: string, maxPerMinute = 30): void {
  const now = Date.now();
  const entry = requestCounts.get(apiKey);
 
  if (!entry || entry.resetAt < now) {
    requestCounts.set(apiKey, { count: 1, resetAt: now + 60_000 });
    return;
  }
 
  if (entry.count >= maxPerMinute) {
    throw new Error("Rate limit exceeded. Try again in a minute.");
  }
 
  requestCounts.set(apiKey, { ...entry, count: entry.count + 1 });
}

Mensagens de erro. Não retorne stack traces internas ou mensagens de erro do banco de dados para o cliente de IA. Retorne strings de erro amigáveis que expliquem o que deu errado sem vazar detalhes de implementação.

Deploy em Produção

Para um servidor local (transporte stdio), o deploy é apenas publicar o pacote npm ou distribuir um binário. Usuários instalam e configuram seu cliente.

Para um servidor hospedado (transporte HTTP/SSE), eu rodo o servidor MCP do HeySeo no Railway com a seguinte configuração:

FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist/ ./dist/
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "dist/server.js"]

Algumas considerações de produção que valem mencionar:

Shutdown gracioso. Processos de servidor MCP precisam lidar com SIGTERM de forma limpa. Se um cliente está no meio de uma conversa e seu servidor morre sem uma desconexão limpa, o cliente pode entrar em estado quebrado.

process.on("SIGTERM", async () => {
  await server.close();
  process.exit(0);
});

Logging estruturado. Para servidores stdio, toda saída para stdout se torna parte do protocolo MCP. Nunca use console.log para stdout em um servidor stdio - use console.error ou um logger estruturado que escreve apenas em arquivo ou stderr.

Health checks. Para deploys HTTP, exponha um endpoint /health que verifica a conexão do banco de dados e quaisquer dependências de API upstream. Railway e Fly.io usarão isso para rotear tráfego e reiniciar instâncias não saudáveis.

Versionamento. A versão do servidor MCP que você declara no construtor importa. Clientes a usam para decidir se devem re-cachear schemas de ferramentas. Incremente a versão sempre que adicionar, remover ou mudar a assinatura de uma ferramenta.

O Que Vem a Seguir para o MCP

O MCP alcançou a versão 1.0 no início de 2025 e o ecossistema cresceu rapidamente. Algumas coisas que estou acompanhando:

Composição multi-servidor. Hoje, cada cliente se conecta a servidores independentemente. Há trabalho inicial em servidores proxy que agregam múltiplos servidores MCP atrás de um único endpoint - útil quando você tem dez ferramentas internas e não quer configurar cada IDE separadamente.

Sampling e streaming. O protocolo já suporta respostas em streaming, mas a maioria dos servidores retorna tudo de uma vez. Conforme os tamanhos de dados crescem, streaming incremental vai importar mais. O SDK tem os hooks; a maioria dos servidores simplesmente ainda não os implementou.

Autenticação padronizada. A comunidade está convergindo para OAuth 2.0 como o padrão para servidores MCP remotos, o que tornará a conexão a servidores MCP de terceiros muito mais simples do que compartilhar API keys brutas.

Painéis nativos de IA nas IDEs. Tanto Cursor quanto Windsurf estão construindo superfícies de UI mais profundas para dados MCP - não apenas respostas em texto, mas gráficos, diffs e visualizações estruturadas. O HeySeo está experimentando retornar tabelas Markdown e dados de gráficos que renderizam diretamente na IDE.

A trajetória é clara: o MCP está se tornando a camada padrão de conexão entre ferramentas de IA e os sistemas com os quais elas precisam interagir. Se você está construindo um produto SaaS em 2026, disponibilizar um servidor MCP está rapidamente se tornando requisito básico - da mesma forma que disponibilizar uma REST API se tornou esperado em 2015.

FAQ

P: Preciso construir um servidor MCP para usar MCP? R: Não. Existem centenas de servidores MCP pré-construídos para ferramentas comuns (GitHub, Notion, PostgreSQL, Slack e mais). Confira o registro oficial em modelcontextprotocol.io/servers. Você só precisa construir um quando tem dados customizados ou APIs proprietárias para expor.

P: O MCP é apenas para o Claude da Anthropic? R: Não. O MCP é um padrão aberto e qualquer cliente de IA pode implementá-lo. Cursor (que usa modelos Claude e OpenAI), Windsurf (Codeium) e vários outros já suportam. A OpenAI ainda não o adotou até o momento desta escrita, mas a pressão da comunidade está crescendo.

P: Meu servidor MCP pode lidar com múltiplos usuários? R: Sim, com transporte HTTP/SSE. Cada conexão de cliente recebe sua própria sessão. Você autentica por conexão e limita o acesso a dados às permissões daquele usuário. O transporte stdio é inerentemente mono-usuário já que roda como processo do próprio usuário.

P: Como o MCP se compara ao function calling ou spec de plugin da OpenAI? R: O function calling da OpenAI é uma funcionalidade de API por requisição. O MCP é um protocolo de conexão persistente. O MCP também funciona com múltiplos provedores de IA sem nenhuma mudança no seu servidor, que é a principal vantagem prática.

P: O que acontece quando meu servidor MCP está fora do ar? R: O cliente de IA falha graciosamente e informa ao usuário que a ferramenta está indisponível. Claude Desktop, Cursor e Windsurf todos lidam com isso corretamente. Implemente health checks e reinícios rápidos para minimizar o tempo fora do ar.


Construir o servidor MCP do HeySeo levou um final de semana e mudou imediatamente como a equipe usa ferramentas de IA. Se seu produto tem dados que poderiam informar melhores decisões assistidas por IA - analytics de SEO, registros de CRM, métricas de código, dados financeiros - o investimento vale absolutamente a pena.

Se você quer conversar sobre sua integração MCP, entre em contato e vamos construir juntos.

Share:

Receba insights práticos de engenharia

Agentes de voz com IA, fluxos de automação e entregas rápidas. Sem spam, cancele quando quiser.