MCP na Prática: Como Parar de Colar Contexto Manualmente e Deixar sua IA Falar Direto com os Sistemas
Você já deve ter vivido essa cena: o agente de IA está no meio de uma tarefa, precisa checar o status de um ticket no Jira, olhar um log no Datadog ou consultar uma tabela no banco de produção — e você, sentado ali, vira o intermediário. Copia o resultado de uma consulta, cola no chat, espera a IA processar, copia a resposta de volta, aplica manualmente em outro sistema. O modelo é brilhante para raciocinar sobre o problema, mas está isolado atrás de uma caixa de texto, dependente de você para ser as mãos e os olhos dele no mundo real.
Esse gargalo tem nome técnico: falta de tool calling padronizado. Cada ferramenta de IA que você usa — Claude Desktop, Cursor, um agente customizado em Python — historicamente exigia sua própria integração proprietária para acessar arquivos, APIs ou bancos de dados. Resultado: você reescreve a mesma “cola” de integração N vezes, uma para cada par (modelo, ferramenta). É exatamente o problema que o MCP (Model Context Protocol) se propõe a resolver, e é sobre isso — a arquitetura, o protocolo em si e como implementar na prática — que vamos tratar aqui.
O que o MCP resolve, tecnicamente
O Model Context Protocol é um padrão aberto, criado pela Anthropic e hoje adotado por diversos players do ecossistema, que define como aplicações de IA se conectam a fontes de dados e ferramentas externas. A ideia central é simples de enunciar e poderosa na prática: em vez de cada integração ser um adaptador proprietário e único, o MCP define um protocolo comum — baseado em JSON-RPC — para que qualquer cliente compatível converse com qualquer servidor compatível.
💡 Dica do Mestre: O Google Cloud resume bem o valor arquitetural do protocolo: ele cria uma “conexão padronizada e bidirecional” entre aplicações de IA e fontes de dados, permitindo que LLMs se conectem facilmente a ferramentas diversas sem reinventar a integração a cada vez. Vale a leitura completa em cloud.google.com/discover/what-is-model-context-protocol.
A analogia mais precisa — e a que o próprio ecossistema usa — é a de uma porta USB-C para IA. Antes do USB-C, cada dispositivo tinha seu próprio conector: um para carregar, outro para transferir dados, outro para vídeo. O USB-C unificou isso em uma interface física comum. O MCP faz o equivalente no plano de software: unifica a interface entre “cérebro” (o modelo) e “mãos” (as ferramentas e dados), independente de quem fabricou cada lado.
As três peças do protocolo
Para implementar ou depurar MCP com segurança, você precisa ter claro o papel de cada componente:
- Host: a aplicação que o usuário final utiliza — Claude Desktop, Claude Code, Cursor, uma aplicação customizada construída com o SDK. É quem inicia as conexões.
- Client: vive dentro do host e mantém uma conexão 1:1 com um servidor MCP específico, cuidando do protocolo de comunicação.
- Server: o processo que expõe capacidades — tools (funções que o modelo pode chamar), resources (dados que podem ser lidos) e prompts (templates reutilizáveis). É aqui que mora a lógica de integração com o sistema real: seu banco, sua API, seu sistema de arquivos.
O ponto crucial, muitas vezes ignorado por quem começa a mexer com isso, é que o servidor MCP não decide sozinho quando será chamado. Ele apenas anuncia suas capacidades. Quem decide invocar uma tool é o modelo, com base na descrição que você escreveu para ela. Isso significa que a qualidade das suas descrições de tool é, na prática, sua interface de programação com o raciocínio do LLM — um ponto que volta a aparecer mais adiante, nas armadilhas.
Construindo um servidor MCP do zero
Vamos a um exemplo com contexto real: uma equipe que quer que o agente de IA consulte o status de deploys em um sistema interno, sem que o desenvolvedor precise copiar e colar logs manualmente. Usando o SDK oficial em TypeScript (há também SDKs em Python, Java, Kotlin e C#, todos documentados em modelcontextprotocol.io):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
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: "deploy-status-server", version: "1.0.0", }); server.registerTool( "get_deploy_status", { title: "Consulta status de deploy", description: "Retorna o status atual de um deploy pelo ID do serviço. " + "Use quando o usuário perguntar sobre o estado de uma implantação " + "em produção, staging ou homologação.", inputSchema: { serviceId: z.string().describe("Identificador do serviço, ex: 'checkout-api'"), environment: z.enum(["production", "staging", "homolog"]), }, }, async ({ serviceId, environment }) => { const status = await fetchDeployStatus(serviceId, environment); return { content: [ { type: "text", text: `Serviço ${serviceId} em ${environment}: ${status.state} ` + `(última atualização: ${status.updatedAt})`, }, ], }; } ); const transport = new StdioServerTransport(); await server.connect(transport); |
Repare em dois detalhes que fazem diferença em produção: o description da tool é escrito como uma instrução para o modelo, não como um comentário para o próximo desenvolvedor humano. E o inputSchema, validado com Zod, funciona como contrato — o servidor rejeita chamadas malformadas antes de tocar em qualquer lógica de negócio.
Conectando o servidor a um cliente real
Depois de construído, o servidor precisa ser registrado no host. No Claude Code, por exemplo, isso é feito via configuração de projeto ou globalmente:
|
1 2 3 4 5 6 7 8 9 10 11 |
{ "mcpServers": { "deploy-status": { "command": "node", "args": ["./mcp-servers/deploy-status/dist/index.js"] } } } |
A partir desse ponto, qualquer prompt no Claude Code que envolva “verificar o status do checkout-api em produção” pode disparar automaticamente a tool, sem que você precise sair do terminal para consultar um painel externo. O mesmo servidor, sem alteração de código, pode ser plugado no Claude Desktop, no Cursor ou em qualquer outro host compatível — esse é o ganho real de padronização.
💡 Dica do Mestre: A Backslash Security tem uma explicação direta sobre por que isso importa em termos de arquitetura de software: o MCP resolve o problema de “M integrações vezes N ferramentas”, transformando uma explosão combinatória de conectores customizados em uma única interface compartilhada. Leia em backslash.security/blog/what-is-mcp-model-context-protocol.
Servidores prontos: quando não reinventar a roda
Antes de escrever seu próprio servidor, vale checar o ecossistema de servidores de referência e comunitários mantidos em github.com/modelcontextprotocol/servers. Há implementações prontas para Git, PostgreSQL, Google Drive, Slack, Puppeteer, entre outras. Para um cenário generalista — um time que usa Python no backend, TypeScript no front e precisa que o agente acesse o repositório Git local — a configuração pode ser tão simples quanto:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "mcpServers": { "git": { "command": "uvx", "args": ["mcp-server-git", "--repository", "/caminho/do/projeto"] }, "postgres": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://usuario:senha@localhost/mydb"] } } } |
Com isso configurado, você pode pedir diretamente ao agente: “verifique se existe uma migration pendente que altera a tabela orders e me mostre o diff do último commit que tocou nela”. O modelo vai orquestrar chamadas às duas tools — Git e Postgres — sem que você precise escrever nenhum código de integração.
Armadilhas comuns e como depurar
Na teoria o fluxo é elegante. Na prática, alguns problemas aparecem com frequência quando times colocam MCP em produção.
1. Descrições de tool ambíguas geram chamadas erradas
Se duas tools têm descrições parecidas — por exemplo, search_users e find_user — o modelo pode escolher a errada, ou pior, chamar as duas em sequência desnecessariamente, gastando tokens e latência. O ajuste fino aqui é editorial: descrições devem ser mutuamente exclusivas e explicitar quando usar cada tool. Trate isso como você trataria nomes de métodos em uma API pública — ambiguidade no nome é dívida técnica.
2. Excesso de tools carregadas de uma vez
Cada tool registrada consome espaço no contexto do modelo com sua descrição e schema. Conectar dez servidores MCP simultaneamente, cada um expondo dezenas de tools, pode inflar o prompt de sistema a ponto de degradar a qualidade do raciocínio ou estourar limites de contexto. A prática recomendada é modular: ative apenas os servidores relevantes para a sessão de trabalho atual, e em ferramentas como o Claude Code, use escopos de configuração por projeto em vez de registrar tudo globalmente.
3. Falhas silenciosas de transporte
Servidores locais (transporte stdio) falham de forma diferente de servidores remotos (transporte HTTP com Server-Sent Events). Um erro comum é o processo do servidor morrer silenciosamente — por exemplo, uma exceção não tratada dentro do handler de uma tool — e o host simplesmente reportar “tool indisponível” sem stack trace útil. Para depurar, rode o servidor manualmente fora do host primeiro:
|
1 2 3 4 5 6 |
node ./dist/index.js # Envie uma requisição JSON-RPC manual via stdin para validar # se o servidor responde antes de conectar ao cliente |
Ferramentas como o MCP Inspector permitem testar chamadas de tool isoladamente, fora do fluxo do agente, isolando se o problema está no servidor ou na decisão do modelo.
4. Segurança: tools com poder demais
Um servidor MCP mal projetado que expõe uma tool genérica como execute_sql(query: string) abre a porta para o modelo (ou para um prompt injection vindo de um dado externo) executar comandos destrutivos. O princípio aqui é o mesmo de qualquer API exposta: privilégio mínimo. Prefira tools granulares (get_order_by_id, list_pending_invoices) a uma tool universal que aceita SQL arbitrário. Se seu servidor precisa de acesso de escrita, isole-o do de leitura e exija confirmação explícita do usuário nos hosts que suportam esse fluxo, como o Claude Code faz ao pedir aprovação antes de executar certas ações.
💡 Dica do Mestre: Um artigo recente resume bem essa mudança de mentalidade no título: pare de fazer hard-code das integrações de IA. A ideia é tratar cada capacidade externa como uma tool desacoplada e reutilizável, não como lógica embutida no prompt. Vale conferir em medium.com/@kapildevkhatik2.
5. Versionamento e compatibilidade entre clientes
O protocolo evolui, e diferentes hosts implementam versões distintas da especificação em ritmos diferentes. Um servidor que usa recursos mais recentes — como sampling, em que o servidor pode pedir ao modelo para gerar texto — pode não funcionar em um cliente mais antigo. Fixe a versão do SDK no seu package.json ou requirements.txt, e teste explicitamente contra os hosts que sua equipe realmente usa antes de considerar o servidor pronto para uso compartilhado.
MCP em contexto multi-linguagem
Um ponto que costuma passar despercebido: o servidor MCP não precisa ser escrito na mesma linguagem do seu projeto principal. Times que trabalham com Delphi em sistemas legados, por exemplo, podem expor uma camada de integração via um servidor MCP escrito em Python ou Node.js, que por sua vez conversa com a API REST ou com o banco de dados da aplicação Delphi — sem tocar uma linha do código legado. O protocolo é agnóstico de linguagem por design, exatamente porque a comunicação acontece via JSON-RPC sobre stdio ou HTTP, não por bibliotecas nativas compartilhadas.
Isso abre um padrão de arquitetura interessante: um “hub” de servidores MCP mantidos centralmente pela equipe de plataforma, cada um especializado em um domínio (billing, autenticação, observabilidade), consumidos por qualquer agente de IA que qualquer time decida usar — Claude Code, Cursor, ou um agente interno construído com o SDK. É a mesma lógica de microsserviços aplicada à camada de contexto de IA.
💡 Dica do Mestre: Para uma introdução em português sobre o motivo de o MCP estar ganhando tração como padrão de mercado, vale a leitura de Elisa Terumi: “O MCP visa criar um padrão universal para conectar modelos de IA a diversas fontes de dados e ferramentas, de forma segura e eficiente.” Disponível em elisaterumi.substack.com.
Aprofunde essa discussão na Comunidade Dev’s AI
MCP é um daqueles temas em que a teoria explica 20% do trabalho e a prática — depurar um servidor que falha silenciosamente, decidir onde colocar o limite entre tool granular e tool genérica, versionar SDKs entre projetos — resolve os outros 80%. Se você está implementando servidores MCP no seu fluxo de trabalho, ou avaliando se vale a pena migrar integrações proprietárias para esse padrão, vale trocar experiências com quem já passou pelas mesmas decisões.
Na Comunidade Dev’s AI discutimos exatamente esse tipo de decisão de arquitetura no dia a dia — com exemplos reais de projetos em produção, não apenas teoria de documentação oficial. Se você trabalha com Claude Code, Cursor ou está construindo seus próprios agentes, esse é o lugar para comparar notas e evitar repetir os mesmos erros que outras equipes já mapearam.
Conclusão
O MCP não é apenas mais uma sigla no vocabulário de IA generativa — é uma mudança estrutural em como aplicações de IA se conectam ao resto do seu ecossistema técnico. Ao padronizar a interface entre modelo e ferramenta, ele elimina a necessidade de reescrever integrações a cada nova combinação de cliente e sistema, e abre espaço para que equipes construam bibliotecas de capacidades reutilizáveis, testáveis e versionáveis, exatamente como já fazem com APIs internas.
Mas, como qualquer peça de infraestrutura nova, o diabo mora nos detalhes: descrições de tool malfeitas confundem o modelo, servidores com privilégios excessivos criam risco de segurança real, e a ausência de observabilidade adequada transforma qualquer falha em uma sessão frustrante de tentativa e erro. Trate seus servidores MCP com o mesmo rigor de engenharia que você aplicaria a qualquer serviço exposto em produção — porque, tecnicamente, é exatamente isso que eles são.