MCP (Model Context Protocol): Conectando IA às Suas Ferramentas de Verdade
Imagine a seguinte cena. Você está usando um assistente de IA para acelerar seu trabalho e pede algo simples: “verifique se existe algum ticket aberto no nosso sistema de suporte relacionado a esse erro de timeout”. A resposta vem educada, bem escrita, mas completamente inútil: “não tenho acesso ao seu sistema de suporte, mas posso te ajudar a pensar em possíveis causas do erro”. Você copia manualmente informações do ticket, cola no chat, espera a análise, copia a resposta, cola de volta no sistema. Repita esse ciclo dez vezes ao dia, com dez ferramentas diferentes — Jira, banco de dados, GitHub, planilhas, sistema de logs — e você percebe que está gastando mais tempo fazendo a ponte entre a IA e suas ferramentas do que efetivamente sendo ajudado por ela.
Esse é o problema estrutural que a maioria dos assistentes de IA carregava até pouco tempo atrás: eles são excelentes para raciocinar sobre texto, mas isolados do mundo real das ferramentas que você usa todos os dias. Cada integração era um projeto próprio, com autenticação própria, formato de dados próprio e manutenção própria. Não existia um padrão comum — era como se cada fabricante de eletrônico exigisse um plugue diferente na parede.
O Model Context Protocol (MCP) nasceu exatamente para resolver isso. É um protocolo aberto, criado pela Anthropic e hoje adotado por diversos players do ecossistema, que define uma forma padronizada de conectar modelos de IA a fontes de dados e ferramentas externas. Neste artigo, vamos entender o que é o MCP, como ele funciona por dentro, e construir exemplos práticos de servidores e clientes MCP em código.
O problema da integração fragmentada
Antes de entrar no MCP propriamente, vale entender por que ele existe. Historicamente, quando você queria que um LLM interagisse com um sistema externo — um banco de dados, uma API de terceiros, o sistema de arquivos local — você tinha duas opções:
- Function calling proprietário: cada provedor de LLM (OpenAI, Anthropic, Google) tem seu próprio formato de definição de ferramentas, exigindo código de integração específico para cada plataforma.
- Plugins ou extensões fechadas: soluções amarradas a uma ferramenta específica de IA, sem reaproveitamento em outros contextos.
O resultado prático era o que na engenharia de software chamamos de problema N×M: se você tem N assistentes de IA e M ferramentas, seria necessário construir N×M integrações diferentes. Toda vez que surgia um novo assistente, era preciso reescrever as integrações do zero.
💡 Dica do Mestre: o problema N×M é o mesmo motivo pelo qual o USB substituiu conectores proprietários no mundo do hardware, e por que o SQL padronizou o acesso a bancos de dados relacionais diferentes. Padrões abertos reduzem custo de integração de forma multiplicativa, não apenas somada. Veja a especificação oficial em modelcontextprotocol.io.
O que é o MCP, na prática
O MCP resolve o problema N×M transformando-o em um problema N+M. Em vez de cada assistente de IA precisar conhecer os detalhes de cada ferramenta, existe um protocolo comum: qualquer ferramenta que “fale” MCP pode ser usada por qualquer assistente que “entenda” MCP.
A arquitetura tem três peças centrais:
- Host: a aplicação de IA que o usuário interage diretamente (Claude Desktop, Claude Code, um editor com IA integrada, um agente customizado).
- Client MCP: o componente embutido no host que gerencia a comunicação com os servidores MCP, mantendo uma conexão dedicada com cada um.
- Server MCP: um processo independente que expõe capacidades — dados, ferramentas, prompts — seguindo o protocolo. É o servidor que sabe conversar com o Postgres, com o GitHub, com o sistema de arquivos, etc.
A comunicação segue o padrão JSON-RPC 2.0, podendo trafegar via stdin/stdout (para servidores locais) ou HTTP com Server-Sent Events (para servidores remotos). O protocolo define três tipos principais de capacidades que um servidor pode expor:
- Tools: funções que o modelo pode invocar, como
query_databaseoucreate_issue. - Resources: dados que podem ser lidos e injetados no contexto, como o conteúdo de um arquivo ou o resultado de uma consulta.
- Prompts: templates reutilizáveis que padronizam interações comuns, como um prompt de revisão de código com parâmetros pré-definidos.
Uma analogia útil
Pense no MCP como o padrão HTTP para navegadores. O navegador (host) não precisa saber os detalhes internos de cada site; ele apenas fala HTTP, e qualquer servidor que implemente HTTP corretamente é acessível. O MCP faz o mesmo para assistentes de IA e ferramentas: o assistente não precisa de código customizado para cada integração, apenas precisa saber falar MCP.
Construindo seu primeiro servidor MCP
Vamos construir um exemplo prático em Python, usando o SDK oficial. O cenário: um servidor MCP simples que expõe uma ferramenta para consultar o status de builds em um pipeline de CI fictício.
|
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 |
# pip install mcp from mcp.server.fastmcp import FastMCP mcp = FastMCP("ci-status-server") # Simulação de um banco de dados de builds BUILDS = { "build-101": {"status": "success", "branch": "main", "duration_seconds": 142}, "build-102": {"status": "failed", "branch": "feature/mcp", "duration_seconds": 58}, } @mcp.tool() def get_build_status(build_id: str) -> dict: """Retorna o status de um build específico do pipeline de CI.""" build = BUILDS.get(build_id) if not build: return {"error": f"Build {build_id} não encontrado"} return build @mcp.tool() def list_failed_builds() -> list: """Lista todos os builds com status de falha.""" return [ {"id": build_id, **info} for build_id, info in BUILDS.items() if info["status"] == "failed" ] if __name__ == "__main__": mcp.run(transport="stdio") |
Esse código, com poucas linhas, já expõe duas ferramentas que qualquer host compatível com MCP pode descobrir e invocar automaticamente. Não é necessário escrever prompts explicando “aqui estão as funções disponíveis” — o protocolo cuida da descoberta e da negociação de capacidades.
O SDK oficial está documentado em github.com/modelcontextprotocol/python-sdk, e há também versões para TypeScript, ampliando o alcance para quem trabalha no ecossistema Node.
Conectando o servidor a um host
Para usar esse servidor no Claude Desktop, por exemplo, basta declarar sua execução no arquivo de configuração:
|
1 2 3 4 5 6 7 8 9 10 11 |
{ "mcpServers": { "ci-status": { "command": "python", "args": ["/caminho/para/ci_server.py"] } } } |
Ao reiniciar o host, ele inicia o processo do servidor, realiza o handshake do protocolo e passa a expor as ferramentas get_build_status e list_failed_builds como opções que o modelo pode acionar durante a conversa, sem que você precise reescrever prompts a cada sessão.
Servidores MCP para casos reais de desenvolvimento
A força do MCP está no ecossistema de servidores já disponíveis para as ferramentas que você provavelmente já usa. Alguns exemplos mantidos oficialmente ou pela comunidade:
- Filesystem: leitura e escrita controlada de arquivos locais — repositório oficial.
- GitHub: consulta e manipulação de issues, pull requests e repositórios — servidor GitHub.
- PostgreSQL: execução de queries em bancos relacionais com controle de acesso — servidor Postgres.
- Puppeteer: automação de navegador para scraping ou testes end-to-end.
A lista completa de servidores de referência está em github.com/modelcontextprotocol/servers, e vale revisitar periodicamente, já que o ecossistema cresce rápido.
Exemplo: consultando um banco de dados via MCP
Suponha que você queira que seu assistente de IA responda perguntas sobre o schema e os dados do seu banco Postgres sem que você precise copiar e colar resultados de query manualmente. Com o servidor de Postgres configurado, a interação fica assim, do ponto de vista do host:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "mcpServers": { "postgres": { "command": "npx", "args": [ "-y", "@modelcontextprotocol/server-postgres", "postgresql://usuario:senha@localhost:5432/meubanco" ] } } } |
A partir daí, uma pergunta como “quais são as tabelas com mais de um milhão de registros no schema public?” é traduzida pelo modelo em chamadas de ferramentas expostas pelo servidor — sem que você precise escrever a query manualmente nem alternar de contexto para o terminal do banco.
MCP e agentes: por que isso importa mais do que parece
Se você já experimentou construir ou usar agentes de IA para tarefas de desenvolvimento, sabe que a maior limitação prática não é o raciocínio do modelo — é o acesso confiável e padronizado a ferramentas externas. Um agente que não consegue consultar o estado real de um sistema é um agente que “alucina” contexto, respondendo com suposições em vez de fatos.
O MCP resolve isso ao fornecer uma camada de acesso a ferramentas que é:
- Descoberta automática: o host pergunta ao servidor quais capacidades ele oferece, sem hardcoding.
- Tipada: cada ferramenta declara seu schema de entrada e saída, reduzindo erros de interpretação pelo modelo.
- Independente de linguagem: um servidor escrito em Python pode ser consumido por um host escrito em TypeScript, e vice-versa.
- Reaproveitável: o mesmo servidor MCP funciona em diferentes clientes — Claude Desktop, Claude Code, editores de código, agentes customizados — sem alterações.
Exemplo: um servidor MCP para um sistema legado
Um cenário comum no dia a dia de quem trabalha com sistemas corporativos: um ERP legado, sem API REST moderna, mas com um banco de dados acessível. É possível expor operações seguras desse sistema via MCP sem alterar o legado, criando uma camada de leitura controlada:
|
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 |
from mcp.server.fastmcp import FastMCP import pyodbc mcp = FastMCP("erp-legado-server") def get_connection(): return pyodbc.connect( "DRIVER={ODBC Driver 17 for SQL Server};" "SERVER=servidor_erp;DATABASE=ERP_PROD;" "UID=usuario_leitura;PWD=senha_segura" ) @mcp.tool() def consultar_estoque(codigo_produto: str) -> dict: """Consulta a quantidade em estoque de um produto pelo código.""" conn = get_connection() cursor = conn.cursor() cursor.execute( "SELECT DESCRICAO, QUANTIDADE FROM ESTOQUE WHERE CODIGO = ?", codigo_produto, ) row = cursor.fetchone() conn.close() if not row: return {"error": "Produto não encontrado"} return {"descricao": row.DESCRICAO, "quantidade": row.QUANTIDADE} if __name__ == "__main__": mcp.run(transport="stdio") |
Note que o usuário de conexão é de leitura, e a ferramenta é intencionalmente restrita a uma única consulta parametrizada. Isso ilustra um ponto essencial ao expor sistemas legados ou críticos via MCP: o protocolo dá poder de acesso, mas a responsabilidade de limitar esse poder ao mínimo necessário continua sendo do desenvolvedor que constrói o servidor.
💡 Dica do Mestre: ao projetar servidores MCP para produção, trate cada ferramenta exposta como uma rota de API pública. Aplique o princípio do menor privilégio, valide entradas rigorosamente e nunca exponha operações destrutivas (DELETE, DROP, comandos de shell irrestritos) sem camadas explícitas de confirmação. A própria especificação de segurança do protocolo trata desse tema em detalhe: boas práticas de segurança do MCP.
Consumindo MCP diretamente em código: o lado cliente
Além de criar servidores, é útil entender como um cliente consome o protocolo, especialmente se você está construindo um agente customizado. Um exemplo mínimo em Python usando o SDK cliente:
|
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 |
import asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def main(): server_params = StdioServerParameters( command="python", args=["ci_server.py"], ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() # Descobre as ferramentas disponíveis dinamicamente tools = await session.list_tools() print("Ferramentas disponíveis:", [t.name for t in tools.tools]) # Invoca uma ferramenta específica result = await session.call_tool( "get_build_status", arguments={"build_id": "build-102"} ) print("Resultado:", result.content) asyncio.run(main()) |
Esse trecho mostra o núcleo do valor do MCP: o cliente não precisa saber, em tempo de compilação, quais ferramentas existem. Ele descobre isso em tempo de execução, via list_tools(), e invoca dinamicamente. Isso é o que permite que um mesmo agente se adapte a diferentes conjuntos de servidores sem alteração de código.
Onde o MCP se encaixa no seu fluxo de trabalho
Se você já usa ferramentas como Claude Code para desenvolvimento assistido, o MCP é a camada que expande o alcance do assistente para além do código-fonte local: ele passa a poder consultar o Jira para entender o contexto de uma tarefa, verificar o status de um deploy, ler documentação interna, ou consultar métricas de observabilidade — tudo dentro da mesma conversa, sem trocar de janela.
Vale reforçar que o MCP não é exclusivo de um único fornecedor de IA. É um protocolo aberto, com especificação pública, e a expectativa é que ele se torne um padrão de mercado semelhante ao que LSP (Language Server Protocol) representou para editores de código: uma camada de integração que qualquer editor, e agora qualquer assistente de IA, pode implementar.
💡 Dica do Mestre: a analogia com o LSP não é acidental — o Model Context Protocol foi conscientemente inspirado nesse modelo de sucesso. Assim como o LSP libertou editores de código de precisarem implementar suporte específico para cada linguagem, o MCP liberta assistentes de IA de precisarem implementar suporte específico para cada ferramenta. Leia mais sobre a origem do LSP em microsoft.github.io/language-server-protocol.
Participe da Comunidade Dev’s AI
Entender o MCP na teoria é o primeiro passo, mas o verdadeiro aprendizado acontece quando você constrói seus próprios servidores, integra ferramentas do seu dia a dia e troca experiências com quem está enfrentando os mesmos desafios de integração de IA em ambientes reais de desenvolvimento. Na Comunidade Dev’s AI discutimos exatamente isso: implementações práticas de MCP, agentes de IA aplicados ao desenvolvimento de software, e casos de uso reais compartilhados por desenvolvedores de diferentes linguagens e stacks. Se você quer sair da teoria e colocar a mão no protocolo, essa é a sua próxima parada.
Conclusão
O Model Context Protocol resolve um problema estrutural que travava a evolução prática dos assistentes de IA: a fragmentação de integrações. Ao padronizar a forma como modelos descobrem e invocam ferramentas, dados e prompts, o MCP transforma assistentes de IA de “conversadores isolados” em agentes capazes de operar com contexto real sobre os sistemas que você efetivamente usa no trabalho.
Como todo protocolo de integração poderoso, ele exige responsabilidade no design dos servidores — especialmente quando eles tocam sistemas de produção. Mas o ganho de produtividade de eliminar cópias manuais de dados entre a IA e suas ferramentas, e de reaproveitar integrações entre diferentes hosts e agentes, justifica o investimento em entender e aplicar o protocolo hoje. O ecossistema está em expansão acelerada, e quem começar a construir e consumir servidores MCP agora estará em vantagem quando essa camada de integração se tornar, como tudo indica, um padrão consolidado do mercado.