MCP em produção — 97M downloads, design patterns do arxiv, e o que ainda quebra
-
Diego Hartmann - 30 Mar, 2026
Em novembro de 2024, quando a Anthropic lançou o Model Context Protocol, os SDKs tinham 2 milhões de downloads mensais e a maioria das pessoas nem sabia o que era. Eu lembro de olhar a spec e pensar “isso é interessante, mas quem vai adotar?”. Dezesseis meses depois, são 97 milhões de downloads mensais e eu preciso admitir que estava errado.
MCP virou o protocolo padrão de conexão entre LLMs e ferramentas externas. Claude, GPT-5.4, Gemini — todos suportam. São 5.800+ servers no ecossistema. 4.750% de crescimento. E agora saiu um paper no arxiv que finalmente documenta o que funciona e o que não funciona quando você tenta colocar isso em produção.
O paper: arxiv 2603.13417
O paper “Bridging Protocol and Production: Design Patterns for Deploying AI Agents with MCP” é exatamente o tipo de documento que faltava. Não é um paper teórico sobre a beleza do protocolo — é um catálogo de design patterns extraídos de deploys reais de agentes usando MCP.
Os patterns que mais me interessaram:
1. Gateway Pattern
Em vez de cada agente se conectar diretamente a N MCP servers, você coloca um gateway na frente que gerencia conexões, auth e rate limiting. Parece óbvio, mas 90% dos tutoriais mostram conexão direta. Em produção com 10+ servers, sem gateway você vai ter um pesadelo de configuração e debug.
2. Tool Composition Pattern
Combinar ferramentas de múltiplos MCP servers em uma única chamada do agente. O paper mostra que a melhor abordagem é composição declarativa — o agente declara o que precisa, e o orquestrador resolve quais servers chamar. Tentativas de composição imperativa (o agente decidindo a sequência de chamadas) são frágeis e difíceis de debugar.
3. Fallback Chain Pattern
Quando um MCP server não responde, ter uma cadeia de fallback com servers alternativos. O paper documenta três estratégias: retry simples, fallback para server alternativo, e degradação graceful (retornar resultado parcial). Na prática, já implementei a terceira e é a que menos frustra o usuário final.
4. Context Window Management
O pattern mais técnico e mais útil. MCP servers podem retornar quantidades enormes de contexto — um server de database pode devolver milhares de linhas. O paper propõe um context budget por tool call, onde o orquestrador limita o output de cada server para caber no context window do modelo. Sem isso, um server guloso come o contexto inteiro e o agente perde acesso às outras ferramentas.
Hands-on: criando um MCP server
Chega de teoria. Vamos montar um MCP server básico que expõe uma API de busca para um agente.
TypeScript (SDK oficial)
npm install @modelcontextprotocol/sdk
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: "search-server",
version: "1.0.0",
});
// Registra uma tool que o agente pode chamar
server.tool(
"search_docs",
"Busca na documentação interna",
{
query: z.string().describe("Termo de busca"),
limit: z.number().default(5).describe("Máximo de resultados"),
},
async ({ query, limit }) => {
// Aqui vai sua lógica real — Elasticsearch, pgvector, whatever
const results = await searchIndex(query, limit);
return {
content: [
{
type: "text",
text: JSON.stringify(results, null, 2),
},
],
};
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
Python (SDK via PyPI)
pip install mcp
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import TextContent, Tool
server = Server("search-server")
@server.tool()
async def search_docs(query: str, limit: int = 5) -> list[TextContent]:
"""Busca na documentação interna."""
results = await search_index(query, limit)
return [TextContent(type="text", text=str(results))]
async def main():
async with stdio_server() as (read, write):
await server.run(read, write, server.create_initialization_options())
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Ambos os SDKs usam stdio como transport padrão — o client spawna o server como processo filho e se comunica via stdin/stdout. Isso é simples para desenvolvimento, mas em produção você vai querer HTTP/SSE (Server-Sent Events), que ambos os SDKs já suportam.
Conectando no Claude Desktop (teste rápido)
Edite o claude_desktop_config.json:
{
"mcpServers": {
"search-docs": {
"command": "node",
"args": ["./dist/server.js"]
}
}
}
Reinicie o Claude Desktop e a tool search_docs aparece disponível. O agente pode invocá-la naturalmente durante a conversa.
O que ainda quebra em produção
Aqui é onde eu troco o chapéu de entusiasta pelo de engenheiro cansado. MCP em produção tem problemas reais que o hype esconde.
Auth cross-server
O maior gap. Cada MCP server gerencia sua própria autenticação. Se você tem 15 servers, o usuário precisa autenticar em cada um separadamente. Não existe um padrão de SSO ou token federation nativo no protocolo. O blog da WorkOS documenta bem esse problema e propõe soluções, mas nenhuma é oficial ainda.
Na prática, o que eu faço é injetar tokens via variáveis de ambiente no momento do spawn do server. Funciona, mas é um hack — e não escala para cenários onde o token precisa ser refreshed durante a sessão.
Session state
MCP sessions são stateless por padrão. Se o server crashar e reiniciar, todo o contexto acumulado se perde. O paper do arxiv propõe um State Checkpoint Pattern, mas ninguém implementou isso nos SDKs oficiais ainda. Se seu agente depende de estado acumulado ao longo de uma conversa (e a maioria depende), você precisa implementar persistência por conta própria.
Streaming
O suporte a streaming de respostas longas é inconsistente entre implementações. O SDK TypeScript lida bem com SSE, mas o SDK Python tem edge cases com backpressure que podem causar memory leaks em sessões longas. Já perdi horas debugando isso.
Observabilidade
Não existe um padrão de tracing entre client e servers MCP. Se uma cadeia de 5 tool calls falha, boa sorte descobrindo onde foi. Eu adaptei OpenTelemetry manualmente nos meus servers, mas deveria ser built-in.
Roadmap 2026: o que vem por aí
O The New Stack publicou o roadmap que a comunidade está trabalhando. Os pontos mais relevantes:
- Auth padronizado: OAuth 2.1 como padrão de autenticação para MCP servers. Finalmente.
- Streamable HTTP transport: substituição do SSE por um transport mais robusto para produção.
- Registry protocol: um padrão para discovery de MCP servers — tipo um DNS para ferramentas de agentes.
- Elicitation: capacidade do server pedir informação adicional ao usuário via o client, sem interromper o fluxo do agente.
Se o auth padronizado e o registry saírem no Q2 como prometido, MCP vira um protocolo enterprise-ready de verdade. Até lá, prepare-se para escrever bastante glue code.
Veredito
MCP não é mais experimental. 97 milhões de downloads mensais e suporte universal dos providers transformaram o protocolo em padrão de facto. O paper arxiv 2603.13417 é leitura obrigatória para quem está deployando agentes — os design patterns economizam semanas de tentativa e erro.
Mas “padrão de facto” não significa “maduro”. Auth, state e observabilidade são problemas reais que você vai enfrentar. O roadmap promete resolver boa parte disso em 2026, e a velocidade da comunidade (de 2M para 97M downloads em 16 meses) me dá alguma confiança.
Se você ainda não tem MCP servers no seu stack de agentes, comece com o Gateway Pattern e um server simples como o exemplo acima. Mantenha o escopo pequeno, instrumente tudo, e prepare-se para reescrever o auth quando o padrão OAuth 2.1 sair.
Paper: arxiv.org/abs/2603.13417. SDK TypeScript: @modelcontextprotocol/sdk. SDK Python: mcp no PyPI. Vai lá, monta um server, quebra em produção, e me conta o que deu errado.