Voltar as noticias
Como Construir um Servidor MCP que Realmente é Utilizado
MCP ProtocolAltaEN

Como Construir um Servidor MCP que Realmente é Utilizado

Dev.to - MCP·7 de junho de 2026

Como Construir um Servidor MCP que Realmente é Usado

Um guia técnico de alguém que construiu 10 deles.

Meu último post foi sobre o problema de distribuição — por que construir servidores MCP não significa que alguém os usará. Este post é o companheiro técnico: como construir um bem, para que quando a distribuição funcionar, o servidor não te envergonhe.

Eu construí 10 servidores MCP em uma semana. Alguns são bons. Alguns eu reescreveria. Aqui está o que aprendi sobre a arquitetura, as armadilhas e os padrões que realmente importam.

O que Faz um Bom Servidor MCP

Um servidor MCP é uma ponte entre um LLM e um serviço externo. O LLM chama suas ferramentas; suas ferramentas chamam a API. Simples em conceito. Os detalhes são onde as coisas dão errado.

Três coisas importam mais do que qualquer outra:

  1. Descrições de ferramentas que o LLM pode realmente usar. Não documentações de API. Não referências para desenvolvedores. Descrições que dizem ao LLM quando chamar esta ferramenta e o que ela retorna.

  2. Mensagens de erro que ajudam o LLM a se recuperar. Quando uma ferramenta falha, a mensagem de erro volta para o LLM. Se disser "Erro 500", o LLM não tem ideia do que fazer a seguir. Se disser "Limite de taxa — aguarde 30 segundos e tente novamente", o LLM pode lidar com isso.

  3. Validação de entrada que captura erros antes que cheguem à API. LLMs alucinam parâmetros. Seu servidor deve rejeitar entradas ruins de forma elegante, não encaminhá-las para a API e retornar um erro críptico.

A Arquitetura

Todo servidor MCP que construí segue o mesmo padrão:

src/
├── index.ts          # Ponto de entrada do servidor, registro de ferramentas
├── tools/            # Um arquivo por ferramenta (ou grupo de ferramentas relacionadas)
│   ├── coingecko.ts
│   ├── defillama.ts
│   └── ...
├── utils/
│   ├── api-client.ts # Cliente HTTP com retry, limitação de taxa
│   └── validation.ts # Auxiliares de validação de entrada
└── types.ts          # Tipos TypeScript compartilhados

Por que um arquivo por ferramenta: Quando você tem 18 ferramentas (como o servidor MCP Resend), colocar todas em um arquivo torna a base de código ilegível. Um arquivo por ferramenta significa que você pode encontrar, editar e testar cada ferramenta de forma independente.

Por que um cliente API compartilhado: Cada API externa precisa de lógica de retry, limitação de taxa e tratamento de erros. Construa uma vez, use em todos os lugares.

Descrições de Ferramentas: O Código Mais Importante que Você Escreverá

Aqui está a coisa que ninguém te diz: a descrição da ferramenta é mais importante do que a implementação da ferramenta. O LLM decide se deve chamar sua ferramenta com base na descrição. Se a descrição for vaga, o LLM não a chamará. Se for muito específica, o LLM não a chamará nas situações corretas.

Descrição ruim: ""

description: "Obter preço do token"

Descrição boa: ""

description: "Obter o preço atual de um token de criptomoeda pelo seu ID do CoinGecko. Retorna preço em USD, capitalização de mercado e mudança em 24h. Use isso quando o usuário perguntar sobre o preço atual de um token específico ou dados de mercado. O parâmetro coin_id deve ser o identificador do CoinGecko (por exemplo, 'bitcoin', 'ethereum', 'solana')."

A boa descrição diz ao LLM:

  • O que a ferramenta faz (obter preço atual)
  • O que ela retorna (preço, capitalização de mercado, mudança em 24h)
  • Quando usá-la (usuário pergunta sobre preço atual)
  • O que os parâmetros significam (ID do CoinGecko, não símbolo)

Minha regra prática: Escreva a descrição como se estivesse explicando a um colega inteligente quando eles devem usar esta função. Não documentações de API. Não um changelog. Um guia de uso.

Tratamento de Erros que Ajuda o LLM

Quando uma ferramenta falha, o erro volta para o LLM como uma resposta da ferramenta. O LLM então decide o que fazer — tentar novamente, tentar uma ferramenta diferente ou dizer ao usuário que algo deu errado.

A chave insight: Sua mensagem de erro é um prompt para o LLM. Faça-a útil.

// Ruim
throw new Error("Erro da API");

// Bom
throw new Error(`API do CoinGecko limitada. Aguarde ${retryAfter} segundos antes de tentar novamente. O nível gratuito permite 10-30 chamadas/minuto.`);
// Ruim
throw new Error("Entrada inválida");

// Bom
throw new Error(`coin_id inválido "${coinId}". Use a ferramenta de busca primeiro para encontrar o ID correto do CoinGecko. Exemplos: "bitcoin", "ethereum", "solana".`);

Validação de Entrada: Capturando Parâmetros Alucinatórios

LLMs alucinam parâmetros. Eles passarão undefined onde uma string é esperada, ou "BTC" onde um ID do CoinGecko é necessário. Seu servidor deve capturar isso de forma elegante.

// Validar campos obrigatórios
if (!args.coin_id || typeof args.coin_id !== 'string') {
  return {
    content: [{
      type: 'text',
      text: 'Erro: coin_id é obrigatório e deve ser uma string. Use a ferramenta de busca para encontrar o ID correto do CoinGecko.'
    }]
  };
}

Não lance exceções para entradas ruins. Retorne uma mensagem de erro útil como resposta da ferramenta. O LLM pode lê-la e tentar novamente com os parâmetros corretos. Lançar exceções pode cr

Contexto Triplo Up

Empresas brasileiras que desejam implementar servidores MCP podem se beneficiar deste guia prático, que destaca a importância de descrições claras e validação de entrada. Isso pode aumentar a eficiência na integração de LLMs com serviços externos.

Noticias relacionadas

Gostou do conteudo?

Receba toda semana as principais novidades sobre WebMCP.