O Model Context Protocol tornou fácil dar mãos a um assistente de IA. Acrescenta umas linhas de JSON, reinicia o editor ou o cliente de chat, e o assistente passa a conseguir ler tickets, consultar uma base de dados ou abrir pull requests. Essa conveniência é o objetivo. É também por isso que vale a pena perguntar, sem rodeios, a que é que cada um desses servidores consegue realmente chegar.
A resposta curta: um servidor MCP local é só um programa a correr com o seu utilizador. Chega a tudo aquilo a que o seu utilizador chega, mais o que lhe passar explicitamente.
Anatomia de um servidor MCP
A maioria dos servidores MCP nos portáteis dos programadores é lançada pelo cliente como processo filho via stdio. O cliente lê uma config JSON, corre um comando como npx, uvx ou um binário local, e passa variáveis de ambiente. Também existem servidores remotos, acedidos por HTTP, mas hoje o padrão local é o mais comum.
Quatro coisas definem o raio de impacto:
- Ferramentas. As funções que o servidor anuncia ao modelo:
read_file,run_query,create_issue. É o modelo que decide quando as chamar. - Tokens. API keys e personal access tokens passados em
env. Um servidor com um token alargado pode fazer tudo o que esse token permite, diga o que disser a sua lista de ferramentas. - Sistema de ficheiros. Um servidor stdio corre com as permissões do seu utilizador. A menos que esteja em sandbox, pode ler as suas chaves SSH, credenciais de cloud e histórico da shell.
- Rede. Pode abrir ligações de saída para qualquer sítio onde o seu portátil chegue, incluindo serviços internos na VPN.
Note que as ferramentas anunciadas são uma promessa, não uma fronteira. O próprio processo é a fronteira e, por omissão, essa fronteira é a sua conta inteira.
Prompt injection através do output de ferramentas
O risco menos óbvio não é o servidor portar-se mal. São os dados que o servidor devolve. O output das ferramentas volta ao modelo como contexto, e o modelo não consegue distinguir de forma fiável instruções de conteúdo.
- PlantarUm atacante escreve texto em algo que uma ferramenta vai ler: um comentário numa issue, um README, uma página web, uma linha de base de dados.
- ObterUm programador pede ao assistente que resuma as issues abertas. O servidor de tickets devolve o texto plantado.
- DesviarO texto diz ao modelo para chamar outra ferramenta, por exemplo para ler um ficheiro de credenciais ou fazer push de um branch.
- AgirSe estiver ligado um segundo servidor com acesso alargado, o modelo pode seguir a instrução usando a identidade do programador.
- ExfiltrarOs resultados saem através de qualquer ferramenta que consiga escrever para fora: um comentário, um commit, um pedido HTTP.
A combinação perigosa é um servidor que lê input não confiável lado a lado com um servidor que consegue escrever ou chegar a secrets. Cada um, sozinho, pode estar bem. Juntos, formam uma linha do texto do atacante até às suas credenciais.
Inventariar configs MCP num portátil
Os clientes MCP guardam as listas de servidores em JSON, normalmente sob uma chave mcpServers de topo, no diretório home do utilizador, numa pasta de suporte de aplicações ou dentro de um projeto como dotfile. Não precisa de conhecer todos os clientes. Procure a chave.
# macOS / Linux: find JSON files that declare MCP servers
grep -rl --include="*.json" '"mcpServers"' \
~/.config ~/Library/Application\ Support ~ 2>/dev/null \
| sort -u
# Also check project-level configs in your source tree
find ~/src -maxdepth 4 -name "*mcp*.json" -not -path "*/node_modules/*"
Depois liste o que cada um corre e o que lhe é dado:
jq -r '.mcpServers | to_entries[] |
[.key, .value.command, ((.value.args // []) | join(" ")),
((.value.env // {}) | keys | join(","))] | @tsv' path/to/config.json
Uma entrada típica é assim. Repare no token em texto simples na configuração.
{
"mcpServers": {
"tickets": {
"command": "npx",
"args": ["-y", "example-tickets-mcp"],
"env": { "TICKETS_TOKEN": "PLACEHOLDER_NOT_A_REAL_TOKEN" }
}
}
}
Três coisas a assinalar: npx -y ou semelhante sem versão fixada (corre o que for mais recente no arranque), tokens guardados inline e servidores que ninguém na equipa sabe explicar.
Restrinja tokens e use uma allowlist de servidores
Trate cada servidor MCP como uma nova dependência com credenciais associadas.
- Um token por servidor. Crie um token dedicado, fine-grained, com os scopes mínimos e uma data de expiração. Nunca reutilize o seu personal access token principal.
- Só de leitura por omissão. A maior parte do uso do assistente é consulta. Conceda scopes de escrita apenas a servidores que precisem mesmo deles, e mantenha os pedidos de confirmação ativos.
- Fixar versões. Substitua
npx -y packagepornpx -y package@1.4.2, ou instale localmente um build revisto. - Manter os segredos fora do JSON. Carregue tokens a partir do keychain do sistema operativo ou de um wrapper de gestor de segredos, em vez de valores
envinline. - Publicar uma allowlist. Uma lista curta de servidores aprovados, as suas versões fixadas e os scopes permitidos. Tudo o resto é uma conversa, não um bloqueio à vista.
- Sessões separadas. Evite ligar um servidor que lê input público na mesma sessão que um que pode tocar em produção ou em segredos.
Verifique o seu em 10 minutos
- Corra o
grepacima no seu portátil e conte as configs. - Para cada servidor, anote: comando, versão fixada ou não, scopes dos tokens e se pode escrever.
- Revogue qualquer token amplo encontrado inline e emita um novo com scope.
- Remova os servidores que não usa. Menos estações na linha significa menos sítios onde uma avaria pode começar.
- Partilhe o resultado com a sua equipa e comece a allowlist a partir do que as pessoas realmente usam.
Nada disto exige banir assistentes. Aplica apenas o mesmo raciocínio que já usa para dependências e tokens de CI a um tipo de ferramenta mais recente.
Onde isto fica na linha
Na torre (em desenvolvimento):