Model Context Protocol (MCP): o protocolo que unifica as integrações de IA
Guia sobre o Model Context Protocol (MCP): arquitetura, vantagens e limitações, os servidores mais úteis, como criar o teu servidor em TypeScript e as diferenças entre OpenCode e Claude Desktop.
Imagina que tens um assistente de IA que precisa de ler ficheiros do teu projeto, consultar a base de dados, criar PRs no GitHub e ver erros no Sentry — tudo na mesma conversa. Até há bem pouco tempo, cada uma destas integrações era feita de forma ad-hoc, com código específico para cada combinação de modelo e ferramenta.
Foi para resolver este caos que a Anthropic criou o Model Context Protocol (MCP) — um protocolo aberto que standardiza a comunicação entre modelos de linguagem (LLMs) e sistemas externos. Desde o lançamento, em novembro de 2024, o MCP tornou-se o padrão mais usado para ligar IAs a ferramentas, com centenas de servidores disponíveis.
Uso o MCP todos os dias no OpenCode e no Claude Desktop. O que vais encontrar aqui: como funciona a arquitetura, vantagens reais, os servidores que não podem faltar, um passo-a-passo para criares o teu em TypeScript, e as diferenças de configuração entre OpenCode e Claude Desktop.
O que é o MCP?
O Model Context Protocol (MCP) é um protocolo aberto, desenvolvido pela Anthropic, que standardiza a forma como aplicações de IA se ligam a fontes de dados e ferramentas externas. Pensa nele como um LSP (Language Server Protocol) — mas para IAs em vez de editores de código.
O MCP define uma camada de comunicação baseada em JSON-RPC 2.0, onde aplicações de IA (os hosts) podem descobrir e invocar dinamicamente as capacidades expostas por servidores MCP. Isto inclui:
- Tools — funções que o LLM pode executar (ex: ler um ficheiro, fazer uma query à BD)
- Resources — dados e contexto que o LLM pode consultar (ex: schema da BD, documentação)
- Prompts — templates de mensagens para workflows reutilizáveis
O protocolo funciona sobre dois transportes: stdio para servidores locais (o servidor corre como processo filho) e Streamable HTTP para servidores remotos. O antigo transporte HTTP+SSE está obsoleto desde a versão 2025-03-26.
Nota (outubro de 2026): a versão mais recente da especificação é a de 28 de julho de 2026, que tornou o protocolo stateless: acabou o handshake
initialize(cada pedido leva a versão do protocolo e as capacidades do cliente) e há um novo métodoserver/discover. Os pedidos iniciados pelo servidor (sampling, elicitation, roots) foram substituídos por um padrão de várias idas e voltas, e o Roots, o Sampling e o Logging passaram a obsoletos. Clientes e servidores de versões anteriores continuam a poder interoperar.
Nota: O MCP é completamente open-source (Apache 2.0 / MIT) e independente de qualquer modelo ou fornecedor. Isto significa que podes usar o mesmo servidor MCP com Claude, GPT, Gemini, ou qualquer outro modelo compatível.
Arquitetura
A arquitetura do MCP segue um modelo cliente-servidor com três papéis distintos, inspirado no LSP. Cada componente tem responsabilidades bem definidas.
Componentes Principais
Host — é a aplicação que contém o ecossistema. Pode ser o Claude Desktop, o OpenCode, um IDE como o VS Code, ou qualquer app que queira usar MCP. O Host gere os clients, aplica políticas de segurança e coordena o ciclo de vida.
Client — cada client fala com um servidor MCP específico. É responsável por descobrir as suas capacidades e por encaminhar as mensagens entre o Host e o servidor. Um Host pode ter múltiplos clients ativos.
Server — cada servidor expõe tools, resources e prompts através do protocolo MCP. Pode ser um processo local (stdio) ou um serviço remoto (HTTP). Os servidores são altamente especializados: um para ficheiros, outro para base de dados, outro para GitHub, etc.
A comunicação é feita exclusivamente por JSON-RPC 2.0, com mensagens request/response. O cliente descobre as capacidades do servidor (com server/discover, nas versões recentes) e depois pode invocar tools ou aceder a resources dinamicamente.
Negociação de Capacidades
Cliente e servidor declaram o que suportam, para poderem evoluir de forma independente. Até à versão 2025-11-25 isto fazia-se num handshake initialize; desde a de 28 de julho de 2026, cada pedido leva a versão do protocolo e as capacidades do cliente, e o servidor anuncia as suas em server/discover:
- O servidor declara:
tools,resources,prompts - O cliente declara o que suporta (por exemplo,
elicitatione extensões) - Ambos respeitam os limites declarados
Isto permite que servidores e clientes evoluam independentemente, mantendo compatibilidade para trás. Um servidor antigo funciona com um cliente novo, e vice-versa.
Porquê MCP?
Antes do MCP, cada integração de IA com ferramentas externas era um caso único. Querias que o Claude lesse ficheiros? Escrevias código específico para o Claude. Querias que o GPT pesquisasse na base de dados? Outra integração. Cada modelo, cada ferramenta, cada cenário — tudo código diferente.
| Dimensão | Antes do MCP | Com MCP |
|---|---|---|
| Integrações | Ad-hoc, específicas de cada modelo | Protocolo universal |
| Descoberta | Tools definidas no código do cliente | Dinâmica (tools/list) |
| Reutilização | Nula — cada integração serve um modelo | Um servidor serve qualquer cliente |
| Segurança | Cada tool com o seu sistema | Isolamento por processo (sem sandbox por omissão) |
| Manutenção | N integrações x M modelos | N servidores, qualquer cliente |
| Ecossistema | Fragmentado | Muitos servidores disponíveis |
O MCP é um padrão de integração. Tal como o LSP unificou o suporte a linguagens de programação em todos os IDEs, o MCP unifica o acesso a ferramentas e dados por parte de todas as IAs.
Vantagens do MCP
1. Padronização
O MCP define um contrato claro entre clientes e servidores. Qualquer servidor MCP funciona com qualquer cliente MCP — Claude Desktop, OpenCode, VS Code, Cline. Um protocolo para todas as integrações.
2. Descoberta Dinâmica
O cliente não precisa de saber à partida o que cada servidor oferece. Na inicialização, faz tools/list e o servidor responde com as tools disponíveis e os seus schemas de input. O LLM descobre as ferramentas em runtime e decide quais usar com base na descrição.
3. Segurança
Cada servidor MCP corre no seu próprio processo, separado dos outros e do Host, e o Host pede o teu consentimento antes de executar tools. Mas atenção: um servidor local corre com as permissões do teu utilizador e, por omissão, não tem sandbox. Um servidor de ficheiros mal escrito (ou malicioso) pode ler tudo o que tu lês. Instala só servidores em que confias, restringe os diretórios que lhes dás e usa tokens com as permissões mínimas.
4. Extensibilidade
Qualquer pessoa pode criar um servidor MCP. Tens SDKs oficiais em TypeScript, Python, Go, Java, Rust, C#, Kotlin, Swift, PHP e Ruby. Basta implementares o protocolo JSON-RPC e expores as tuas tools.
5. Composabilidade
Podes ter múltiplos servidores no mesmo Host — um para filesystem, outro para base de dados, outro para GitHub. Cada um faz o seu trabalho, isolado dos outros, e o Host coordena tudo.
Desvantagens e Limitações
Nem tudo é perfeito. Uso MCP há meses e estas são as limitações que senti na prática:
1. Latência
Cada chamada a uma tool MCP passa por serialização JSON-RPC, transporte (stdio ou HTTP), deserialização, execução, e resposta. Para operações simples que precisam de rapidez, o overhead nota-se.
2. Complexidade
Para cenários simples — executar um comando ou ler um ficheiro — configurar um servidor MCP é mais trabalho do que fazer a chamada diretamente. O MCP compensa em ecossistemas complexos com múltiplas integrações, não em casos isolados.
3. Ecossistema Jovem
Há muitos servidores no MCP Registry, mas o ecossistema é recente (o protocolo foi lançado em novembro de 2024) e a especificação continua a mudar, como se viu na revisão de julho de 2026. Muitos servidores são experimentais e a qualidade varia, e vários servidores de referência foram arquivados e substituídos por versões dos próprios fabricantes. As REST APIs têm décadas de maturidade.
4. Debugging
Quando algo corre mal, tens de debuggar o fluxo completo: Cliente > JSON-RPC > stderr/stdout do servidor > ferramenta > resposta. Ferramentas como opencode mcp debug ajudam, mas ainda há caminho a percorrer.
5. Dependência do Runtime
Para correr servidores MCP locais, precisas de ter Node.js, Python, Go, ou o runtime apropriado instalado. Isto adiciona complexidade à configuração, especialmente em equipas ou ambientes CI/CD.
Servidores MCP Úteis
Estes são os servidores MCP mais úteis para quem trabalha com IAs agênticas. Repara que o repositório oficial arquivou vários dos antigos servidores de referência (GitHub, Puppeteer, PostgreSQL, SQLite, Sentry, Slack, entre outros), por isso a tabela indica o que se usa hoje:
| Servidor | Função | Transporte | Estado |
|---|---|---|---|
filesystem | Acesso a ficheiros locais | stdio | Servidor de referência, mantido |
git | Operações git | stdio | Servidor de referência, mantido |
github | PRs, issues, repositórios | HTTP (remoto) | Servidor oficial do GitHub (o do repositório de referência foi arquivado) |
playwright | Automação de browser | stdio | Mantido pela Microsoft (o de Puppeteer foi arquivado) |
| bases de dados | SQLite, PostgreSQL, etc. | stdio | Os de referência foram arquivados: procura no MCP Registry |
memory | Persistência de contexto | stdio | Servidor de referência, mantido |
fetch | Pedidos HTTP | stdio | Servidor de referência, mantido (em Python) |
sentry | Error tracking | HTTP (remoto) | Servidor remoto do Sentry |
linear | Gestão de tarefas | HTTP (remoto) | Servidor remoto do Linear |
Filesystem
O servidor de filesystem é a base de tudo. Permite ao LLM ler, escrever, pesquisar e listar ficheiros no sistema local. É essencial para qualquer interação com o projeto — sem ele, o modelo não consegue ver o teu código.
// opencode.json / claude_desktop_config.json
"mcp": {
"filesystem": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/caminho/do/projeto"]
}
}
GitHub
Gerir repositórios, criar e rever PRs, listar issues, fazer code review — tudo pelo teu assistente de IA. Usa o servidor oficial do GitHub, que é remoto; a autenticação faz-se com OAuth ou com um token pessoal (cria-o só com as permissões de que precisas).
"mcp": {
"github": {
"type": "remote",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer {env:GITHUB_TOKEN}"
}
}
}
Playwright
Browser automation: navegar em páginas web, tirar screenshots, extrair dados, preencher formulários. O servidor de Puppeteer da Anthropic foi arquivado; o do Playwright é mantido pela Microsoft.
"mcp": {
"playwright": {
"type": "local",
"command": ["npx", "@playwright/mcp@latest"]
}
}
SQLite / PostgreSQL
Acesso a bases de dados: executar queries e inspecionar schemas. Os servidores de referência de SQLite e PostgreSQL foram arquivados; procura no MCP Registry uma alternativa mantida (por exemplo, a do próprio fabricante da base de dados) e, sempre que possível, liga-te com uma conta só de leitura.
Memory
O servidor Memory mantém um grafo de conhecimento persistente entre sessões. O modelo “lembra-se” de preferências, decisões de arquitetura, e contexto entre conversas.
"mcp": {
"memory": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-memory"]
}
}
Fetch / Web
Fazer pedidos HTTP a APIs externas, obter documentação, consultar endpoints REST. É um servidor Python, por isso corre com o uvx.
"mcp": {
"fetch": {
"type": "local",
"command": ["uvx", "mcp-server-fetch"]
}
}
Terminal / Shell
Executar comandos no sistema. É a tool mais poderosa (e mais perigosa), e não há um servidor oficial para isto. Se instalares um de terceiros, revê o código, limita os comandos permitidos e mantém a confirmação manual ligada.
Sentry
Debug de erros em produção: listar issues, ver stack traces, analisar logs. É um servidor remoto, com OAuth.
"mcp": {
"sentry": {
"type": "remote",
"url": "https://mcp.sentry.dev/mcp",
"oauth": {}
}
}
Linear
Gestão de tarefas integrada no teu assistente de IA: criar issues, atualizar projetos, comentar em tarefas. O Jira (Atlassian) também tem o seu próprio servidor remoto.
"mcp": {
"linear": {
"type": "remote",
"url": "https://mcp.linear.app/mcp",
"oauth": {}
}
}
Como Criar um Servidor MCP Personalizado
Segue-se um servidor MCP em TypeScript que expõe tools para calcular métricas de código, como contagem de linhas e complexidade ciclomática. Serve de template para qualquer servidor personalizado.
1. Setup do Projeto
Os exemplos seguem o SDK TypeScript na versão 2 (pacote @modelcontextprotocol/server), que implementa a especificação de 28 de julho de 2026. O SDK antigo, @modelcontextprotocol/sdk, continua a receber correções na versão 1.
mkdir mcp-code-metrics && cd mcp-code-metrics
npm init -y
npm pkg set type=module
npm install @modelcontextprotocol/server zod glob
npm install -D typescript @types/node
npx tsc --init --outDir dist --rootDir src --module nodenext --moduleResolution nodenext --target es2022
2. Servidor MCP com Tools
// src/index.ts
import { McpServer } from "@modelcontextprotocol/server";
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
import * as z from "zod/v4";
import { readFileSync } from "node:fs";
import { glob } from "glob";
const server = new McpServer({ name: "code-metrics", version: "1.0.0" });
// --- Tool: contar linhas de um ficheiro ---
server.registerTool(
"count_lines",
{
description: "Conta linhas de código num ficheiro",
inputSchema: z.object({
path: z.string().describe("Caminho do ficheiro a analisar"),
}),
},
async ({ path }) => {
const lines = readFileSync(path, "utf-8").split("\n").length;
return {
content: [{ type: "text", text: `O ficheiro ${path} tem ${lines} linhas.` }],
};
},
);
// --- Tool: contar ficheiros que correspondem a um padrão ---
server.registerTool(
"count_files",
{
description: "Conta ficheiros que correspondem a um padrão glob",
inputSchema: z.object({
pattern: z.string().describe("Glob pattern (ex: src/**/*.ts)"),
}),
},
async ({ pattern }) => {
const files = await glob(pattern, { nodir: true });
return {
content: [{ type: "text", text: `Encontrei ${files.length} ficheiros para o padrão "${pattern}".` }],
};
},
);
// --- Arranque (stdio) ---
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Servidor MCP code-metrics pronto (stdio)"); // logs vão para stderr
}
main().catch((error) => {
console.error("Erro fatal:", error);
process.exit(1);
});
Cuidado: este exemplo lê qualquer caminho que o modelo pedir. Num servidor a sério, resolve o caminho e confirma que fica dentro da pasta do projeto antes de o abrir.
3. Compilar e Correr
npx tsc
node dist/index.js
4. Adicionar ao OpenCode ou Claude Desktop
"mcp": {
"code-metrics": {
"type": "local",
"command": ["node", "/caminho/absoluto/mcp-code-metrics/dist/index.js"]
}
}
// Claude Desktop (claude_desktop_config.json)
"mcpServers": {
"code-metrics": {
"command": "node",
"args": ["/caminho/absoluto/mcp-code-metrics/dist/index.js"]
}
}
E está pronto. O teu LLM pode agora contar linhas e ficheiros do projeto.
Dica: Para servidores Python, usa o SDK oficial
mcp(pip install mcp). A estrutura é semelhante: decoradores para tools/resources, e um transport (stdio ou Streamable HTTP).
MCP no OpenCode vs Claude Desktop
O OpenCode e o Claude Desktop são dois dos clientes MCP mais usados. Embora ambos suportem o mesmo protocolo, a configuração é diferente.
| Característica | OpenCode | Claude Desktop |
|---|---|---|
| Ficheiro config | opencode.json (projeto) ou ~/.config/opencode/opencode.json | claude_desktop_config.json em ~/Library/Application Support/Claude/ (servidores locais) |
| Chave no JSON | "mcp": { ... } | "mcpServers": { ... } |
| Servidores locais | type: "local" com command: [ ... ] | "command": "npx" com "args": [ ... ] |
| Servidores remotos | type: "remote" com url e headers | Em Definições > Conectores (não pelo ficheiro de configuração) |
| OAuth | Automático + opencode mcp auth | Gerido pelo próprio Claude ao ligares o conector |
| Glob patterns | "tools": { "mcp*": false } | Apenas disable individual |
| Per agent | Ativar/desativar MCP por agente | Global apenas |
| Variáveis de ambiente | "environment": { "KEY": "{env:VAR}" } | "env": { "KEY": "value" } |
A diferença fundamental está na filosofia: o OpenCode configura tudo num ficheiro JSON, com suporte a servidores remotos, OAuth e controlo granular por agente. No Claude Desktop os servidores locais configuram-se no ficheiro e os remotos através dos conectores, na interface.
Exemplo de configuração para OpenCode:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"filesystem": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."],
"enabled": true
},
"github": {
"type": "remote",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer {env:GITHUB_TOKEN}"
},
"enabled": true
},
"sentry": {
"type": "remote",
"url": "https://mcp.sentry.dev/mcp",
"oauth": {}
}
}
}
Exemplo de configuração para Claude Desktop:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"]
},
"github": {
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "<o-teu-token>"
}
}
}
}
Boas Práticas
Depois de meses a usar MCP no dia-a-dia, aqui estão as práticas que mais impacto tiveram na minha produtividade:
1. Um Servidor MCP por Responsabilidade
Cada servidor deve fazer uma coisa e fazê-la bem. Não cries um servidor monolítico que faz tudo — cria servidores especializados (filesystem, DB, GitHub, etc.) e combina-os no Host.
2. stdio para Local, Streamable HTTP para Remoto
Para servidores que correm na mesma máquina (filesystem, terminal, DB local), usa stdio transport — é mais rápido, mais seguro, e não precisas de gerir portas. Para servidores externos (GitHub, Sentry, Linear), usa Streamable HTTP (o SSE está obsoleto).
3. Schemas de Input Bem Tipados
Usa Zod (TypeScript) ou Pydantic (Python) para validar os parâmetros das tools. Um schema bem definido ajuda o LLM a perceber o que precisa de passar e evita erros de runtime. Inclui descrições claras em cada campo.
4. Timeout Razoável
O LLM fica à espera da resposta: uma tool que demora demasiado bloqueia a conversa, por isso mantém as operações curtas (idealmente abaixo de uns 60 segundos). Atenção ao timeout do cliente: no OpenCode é o tempo, em milissegundos, que se espera ao obter a lista de tools do servidor (5000 por omissão), e não o tempo máximo de cada chamada.
// Exemplo de timeout no OpenCode
"mcp": {
"meu-servidor": {
"type": "local",
"command": ["...", "..."],
"timeout": 30000 // espera até 30 s pela lista de tools
}
}
5. Logging Adequado
Os servidores MCP usam stderr para logging (o stdout é reservado para o protocolo JSON-RPC). Usa console.error() para logs de debug.
6. Tratar os Erros com Elegância
Todas as tools devem devolver respostas estruturadas mesmo em caso de erro. Isto permite ao LLM perceber o que correu mal e tentar de novo.
// Sempre devolver uma resposta estruturada
try {
const result = await operacaoRiscada();
return { content: [{ type: "text", text: result }] };
} catch (error) {
return {
content: [{ type: "text", text: `Erro: ${error.message}` }],
isError: true,
};
}
7. Tool Annotations
A especificação permite anotar as tuas tools com metadados que ajudam o LLM a decidir quando usá-las: readOnlyHint, idempotentHint, destructiveHint, openWorldHint. Isto melhora a qualidade das decisões do modelo.
Conclusão
O Model Context Protocol tornou-se o padrão mais usado para ligar IAs a ferramentas externas. Tal como o LSP unificou o suporte a linguagens nos IDEs, o MCP faz o mesmo para o acesso das IAs a ferramentas e dados.
As vantagens são claras: padronização, descoberta dinâmica, isolamento por processo, extensibilidade e composabilidade. O ecossistema já tem muitos servidores e continua a crescer.
Claro que não é perfeito. A latência do JSON-RPC, a complexidade inicial, e e uma especificação que ainda muda são fatores a considerar. Mas para quem trabalha com agentes de IA, vale a pena conhecê-lo.
Se usas Claude Desktop, começa por adicionar os servidores Filesystem e GitHub. Se usas OpenCode, explora a configuração de MCPs remotos com OAuth. Se tens uma ferramenta interna, cria o teu próprio servidor MCP — o SDK TypeScript é simples e bem documentado. E partilha os teus servidores no MCP Registry.
Recursos
Partilhar
Comentários 0
Ainda sem comentários — sê o primeiro.