# Remova servidores MCP abandonados sem deixar acesso para trás

Servidores MCP abandonados merecem o mesmo tratamento que scripts de implantação abandonados: presuma que ainda funcionam até provar que não funcionam. Uma entrada antiga pode iniciar um comando local, direcionar um agente para um endpoint remoto, expor uma variável de ambiente antiga ou manter um caminho até uma credencial que já não tem responsável.

Já vi desenvolvedores excluírem um bloco de configuração, considerarem o trabalho concluído e descobrirem meses depois que a mesma ferramenta ainda era iniciada por uma extensão do editor ou por um arquivo do repositório. A solução não é uma planilha maior. Você precisa separar descoberta, revogação, remoção e a prova de que o caminho de acesso deixou de existir.

## Uma configuração removida não é um caminho de acesso revogado

Remover servidores MCP abandonados significa fechar todos os caminhos que permitem a um agente executar trabalho, não apenas esconder um servidor no menu de um cliente. A definição do servidor é apenas uma parte desse caminho.

Uma configuração local típica tem quatro partes: uma configuração do cliente, um comando de inicialização, a configuração ou o ambiente passados a esse comando e a autoridade no serviço de destino. Uma configuração remota troca o comando local por uma URL, mas ainda tem configuração do cliente e autoridade na outra ponta. As equipes costumam remover a primeira parte e deixar o restante intacto.

A especificação do Model Context Protocol descreve servidores como provedores de capacidades, como ferramentas, recursos e prompts. Ela também aceita diferentes transportes, incluindo stdio e conexões baseadas em HTTP. Essa distinção importa durante a aposentadoria. Um servidor stdio talvez só seja executado quando um cliente local inicia seu comando. Um serviço remoto pode continuar disponível depois que todos os desenvolvedores excluem a entrada local que apontava para ele.

Não misture estes conceitos:

- Um **registro de configuração** informa a um cliente específico onde encontrar um servidor.
- Um **inicializador** é o executável, script, comando de contêiner, extensão ou serviço que o inicia ou alcança.
- Uma **concessão de autoridade** é o token, identidade SSH, autorização OAuth, sessão de conta ou permissão de rede que permite a ação.
- Um **registro de execução** mostra que um cliente ou agente realmente usou o caminho.

Errar aqui produz dois resultados ruins. Você pode deixar uma ferramenta antiga alcançar dados de produção ou revogar uma credencial que uma ferramenta ativa ainda precisa, transformando uma limpeza de rotina em um incidente.

Comece com uma regra de aposentadoria firme: se um servidor não tem responsável atual, propósito documentado e evidências de uso intencional recente, desative-o enquanto investiga. «Talvez precisemos dele algum dia» não é responsabilidade. Se alguém precisar reconstruí-lo mais tarde, o repositório pode preservar a configuração sem credenciais novas.

## Faça o inventário dos clientes antes de pesquisar o disco

Seu primeiro inventário deve listar clientes, não servidores, porque cada cliente lê configurações de lugares diferentes. Os desenvolvedores costumam ter mais de um cliente de agente instalado, além de uma integração com o editor, um auxiliar de terminal e configurações específicas do projeto mantidas junto ao código.

Anote cada lugar que pode iniciar uma conexão MCP na máquina. Inclua aplicativos de desktop, agentes de linha de comando, extensões de IDE, scripts locais que invocam um agente e qualquer ambiente de desenvolvimento remoto que monte o diretório pessoal. Pergunte ao desenvolvedor o que ele realmente usa e depois confirme. A memória é uma evidência ruim quando a ferramenta foi executada uma vez durante um protótipo seis meses atrás.

Para cada cliente, registre a versão, os locais de configuração indicados na própria documentação e se ele aceita configurações no nível do usuário e do projeto. Não presuma um caminho porque outro cliente o usou. Os locais mudam, e um caminho inventado dá uma falsa sensação de segurança.

Uma linha útil do inventário tem detalhes suficientes para permitir uma decisão de aposentadoria depois:

| Campo | Registro |
|---|---|
| Cliente e caminho da configuração | Qual programa lê o arquivo e onde ele fica |
| Nome do servidor | O rótulo mostrado ao agente ou ao usuário |
| Transporte e inicializador | Comando stdio, URL, extensão, contêiner ou script |
| Responsável e propósito | A pessoa responsável e o trabalho ativo que ele apoia |
| Sistemas de destino | APIs, hosts, repositórios, armazenamentos de dados ou pastas locais alcançados |
| Fonte da autoridade | Armazenamento de tokens, variável de ambiente, identidade SSH, concessão OAuth ou identidade gerenciada |
| Decisão | Manter, substituir, suspender ou aposentar |

As configurações de projeto causam as maiores surpresas. Um desenvolvedor pode limpar sua configuração pessoal e ainda iniciar um servidor sempre que abre um repositório antigo. Pesquise a branch atual, os arquivos ignorados usados na configuração local, os arquivos de configuração de exemplo e os scripts de integração. Inspecione também repositórios compartilhados de dotfiles. Um servidor antigo costuma sobreviver porque alguém copiou um trecho conveniente para um modelo.

Não trate o inventário como um documento de conformidade. Use-o para orientar ações. Se não conseguir identificar o sistema de destino e a fonte de autoridade de um servidor, marque-o como não resolvido e impeça seu uso casual até conseguir.

## Pesquise inicializadores, não apenas arquivos chamados MCP

Uma busca textual por «mcp» encontra configurações óbvias, mas os inicializadores podem estar escondidos sob nomes genéricos de scripts e binários de pacotes. Pesquise o rótulo do servidor, o nome do comando, o hostname, a porta, o nome do pacote e os nomes das variáveis de ambiente revelados pelo inventário.

No macOS, este comando fornece uma lista inicial limitada de prováveis arquivos de configuração JSON no diretório pessoal. Ele ignora deliberadamente a árvore de cache, que de outro modo produziria muitos metadados de pacotes irrelevantes.

```sh
find "$HOME" -type f \( -name '.mcp.json' -o -name 'mcp.json' -o -name '*mcp*.json' \) \
  -not -path "$HOME/Library/Caches/*" \
  -print 2>/dev/null
```

Espere uma saída parecida com esta:

```text
/Users/dev/work/acme-api/.mcp.json
/Users/dev/Library/Application Support/example-client/settings.json
/Users/dev/.config/example-agent/mcp.json
```

A lista é uma evidência, não uma lista de exclusão. Abra cada arquivo e identifique qual cliente é responsável por ele. Um nome de arquivo com `mcp` pode ser documentação, um experimento arquivado ou um arquivo de bloqueio gerado. Por outro lado, um arquivo de configurações com nome genérico pode conter a definição real do servidor.

Para arquivos JSON cujo esquema usa um objeto `mcpServers`, este comando imprime uma tabela compacta para revisão. Ele não modifica os arquivos.

```sh
jq -r '
  .mcpServers // empty
  | to_entries[]?
  | [.key, (.value.command // .value.url // "unknown"),
     ((.value.args // []) | join(" "))]
  | @tsv
' path/to/config.json
```

Um resultado típico se parece com isto:

```text
issue-tracker	npx	-y @example/issues-mcp
legacy-reporting	https://reports.internal.example/mcp	
```

Se o comando não produzir nada, não conclua que está seguro. O arquivo pode usar outro esquema, o cliente pode armazenar as configurações em outro lugar ou o serviço pode chegar por meio de uma extensão.

Depois, inspecione as superfícies de inicialização que sobrevivem à limpeza normal dos arquivos. No Mac, verifique perfis do shell, configurações de tarefas do editor, binários globais do gerenciador de pacotes e launch agents do usuário. `launchctl print gui/$(id -u)` pode revelar processos iniciados pelo usuário conectado, mas a saída pode expor argumentos de comandos ou valores de ambiente. Visualize-a localmente e não a cole em um chamado ou conversa.

Pesquise o conteúdo com termos específicos, em vez de examinar e exportar todo o diretório pessoal. Por exemplo, depois de descobrir que um servidor abandonado chama `old-report`, pesquise esse nome literal, o hostname antigo e o executável. Assim você encontra wrappers como `scripts/agent-tools.sh` sem transformar uma revisão de limpeza em uma coleta de dados privados.

## Classifique cada servidor pela autoridade atual

Um servidor pode parecer morto e ainda manter autoridade ativa, portanto classifique como ele se autentica antes de mexer nos arquivos. O mesmo nome de servidor pode usar credenciais diferentes em máquinas diferentes, por isso uma remoção em toda a equipe precisa de evidências por máquina.

Use cinco categorias práticas. Elas descrevem onde está o poder, não como o servidor é apresentado.

1. **Sem autoridade remota.** O servidor lê arquivos locais não sensíveis ou produz saída local. Ainda pode criar um problema de cadeia de fornecimento ou privacidade, mas a revogação geralmente significa remover suas permissões de processo e configuração.
2. **Autoridade baseada em ambiente.** O inicializador recebe um token de API, senha ou string de conexão por meio de um perfil do shell, arquivo `.env`, configuração do IDE ou configuração de inicialização.
3. **Autoridade baseada em arquivo.** O inicializador lê uma chave privada SSH, certificado de cliente, arquivo de conta de serviço ou banco de credenciais local.
4. **Autoridade gerenciada pelo provedor.** O servidor usa OAuth, uma instalação de aplicativo, login de dispositivo ou identidade gerenciada. O provedor, e não um arquivo de texto local, controla a concessão.
5. **Autoridade de rede e conta.** O servidor não precisa de um segredo explícito porque uma rede corporativa, conta local, sessão VPN ou endereço permitido lhe dá acesso a um serviço. Essa categoria é fácil de esquecer e difícil de aposentar corretamente.

Registre a conta, o escopo e o destino exatos de cada fonte de autoridade. «Token do Git» não basta. Você precisa saber se pertence a uma conta pessoal, conta de bot ou identidade compartilhada da máquina, e se pode ler repositórios, criar issues, disparar implantações ou acessar APIs administrativas.

É aqui que a limpeza revela atalhos desconfortáveis. Um comando MCP local que recebe um token pessoal amplo por meio de `~/.zshrc` não se torna inofensivo porque o desenvolvedor deixou de usá-lo. O token também pode alimentar outros scripts, portanto revogá-lo exige coordenação. Isso não é motivo para adiar o trabalho. É motivo para mapear as dependências antes da revogação.

Mantenha o inventário factual. Não coloque valores de tokens, chaves privadas, cabeçalhos de autorização completos ou cópias de configurações nele. Uma referência como «entrada de credencial chamada reporting-read» ou «impressão digital SSH terminada em 3f:91» permite que a pessoa certa encontre a autoridade sem criar outro repositório de segredos.

## Revogue no serviço antes de excluir as evidências locais

Revogue a autoridade ativa no provedor ou serviço de destino antes de remover a configuração local. Essa ordem impede que uma configuração copiada, outra máquina ou um inicializador esquecido continue usando a mesma concessão.

Para tokens de API, use a interface de gerenciamento de tokens do provedor ou o endpoint de revogação documentado. Confirme qual token está revogando pelo identificador, rótulo, conta, dados de criação ou registro do último uso, quando o provedor disponibilizar essas informações. Depois remova o valor dos arquivos locais e dos armazenamentos de credenciais. Nunca teste um token revogado colando-o em um formulário web ou em um comando do shell que possa salvá-lo no histórico.

OAuth exige atenção especial. A RFC 7009 define uma solicitação de revogação de token enviada ao endpoint de revogação do servidor de autorização. Ela também permite que o servidor devolva uma resposta de sucesso mesmo quando o token é inválido, evitando que os chamadores descubram se um token existe. Por isso, um status 200 isolado não prova que a concessão pretendida foi revogada. Verifique a autorização ou a lista de aplicativos conectados no provedor e faça uma chamada controlada pelo caminho antigo apenas se as práticas normais de segurança permitirem.

Para SSH, remova a chave pública ou a chave de implantação de todos os lugares que a aceitam. Isso pode incluir chaves autorizadas de uma conta, configurações de chaves de implantação de um repositório, uma conta de bastion, um serviço de CI e uma fonte de gerenciamento de configuração que repovoa `authorized_keys`. Excluir `~/.ssh/old_agent_key` remove apenas uma cópia local. Não faz nada com outra cópia nem com a autorização no servidor.

Para instalações de aplicativos e contas de serviço, desative ou exclua a instalação, alterne o segredo do cliente ou a credencial privada se houver possibilidade de exposição e remova as associações de funções que existiam apenas para o servidor aposentado. Trate funções amplas como item de limpeza mesmo se a conta de serviço continuar ativa. Uma ferramenta de agente raramente precisa do mesmo acesso que um administrador humano.

O acesso baseado em rede exige outra conversa. Remova entradas antigas de listas permitidas, regras de firewall, associação a grupos VPN ou rotas DNS internas apenas depois de identificar o responsável e os consumidores. Não use um chamado de limpeza do MCP como autorização para quebrar uma integração sem relação. Em vez disso, isole a regra específica e defina um prazo para que o responsável confirme seu uso.

Registre o resultado da revogação como um evento: quem a realizou, qual identificador de autoridade foi revogado, onde isso aconteceu e como foi verificado. Evite registrar segredos ou capturas de tela que os contenham. Esse registro importa quando um repositório falha mais tarde e alguém pergunta se a limpeza causou o problema.

## Remova as definições locais em uma sequência reversível

Remova as definições locais depois da revogação externa, usando uma sequência que preserve um caminho privado de recuperação sem preservar credenciais ativas. Uma desinstalação descuidada pode deixar um projeto sem explicação sobre suas dependências. Um arquivo arquivado com excesso de cautela pode manter um token utilizável em uma pasta esquecida. Separe configuração de material secreto.

Use esta sequência para um servidor de cada vez:

1. Pare o cliente de agente e a extensão do editor relevantes. Um cliente em execução pode manter um processo filho ativo ou reescrever suas configurações ao sair.
2. Copie os campos não secretos da configuração do servidor para o registro de aposentadoria: nome, comando ou URL, argumentos, destino esperado, responsável e data de remoção. Substitua valores secretos por uma descrição de onde estavam armazenados.
3. Revogue a autoridade no serviço de destino e registre os detalhes da confirmação.
4. Remova a entrada do servidor de todas as configurações identificadas no nível do usuário e do projeto. Exclua variáveis de ambiente e referências a arquivos de credenciais aposentados.
5. Desinstale o pacote dedicado, a extensão, a imagem do contêiner ou o script wrapper se nenhum servidor ativo o usar. Se outros trabalhos usarem o pacote, remova apenas o comando abandonado e documente a dependência compartilhada.

Evite editar com uma substituição ampla. Vírgulas JSON, aspas do shell e blocos de ambiente compartilhados punem edições casuais. Use a interface de configurações do cliente quando ela gravar configurações válidas de forma previsível. Caso contrário, faça um backup com permissões restritas, edite um objeto por vez e valide o resultado antes de abrir o cliente novamente.

Para JSON, `jq` oferece uma verificação simples de sintaxe:

```sh
jq empty path/to/config.json && echo "valid JSON"
```

Isso prova que o JSON pode ser analisado. Não prova que o cliente aceita o esquema nem que você removeu todas as referências. Leia o objeto relevante depois da edição e use o cliente para inspecionar sua lista de servidores configurados.

Não arquive um `.env` completo, uma chave privada ou um arquivo de configurações com um token bearer em uma pasta `archive` do projeto. Controle de versão, backup na nuvem e busca do desktop fazem esse erro viajar longe. Preserve um registro redigido e use o histórico de auditoria do provedor para comprovar que a credencial anterior existia.

A remoção de pacotes também exige cuidado. Um pacote de runtime instalado globalmente pode oferecer suporte a várias ferramentas ativas. Antes de excluí-lo, descubra qual nome de executável cada configuração ativa invoca. Já vi uma limpeza remover uma dependência de runtime compartilhada e obrigar outra equipe a investigar uma sessão de agente quebrada, porque a mensagem de erro mencionava um pacote ausente, e não a ferramenta excluída.

## Prove que nada inicia ou alcança o servidor aposentado

Uma aposentadoria está completa quando os clientes relevantes não conseguem descobrir, iniciar ou autenticar no servidor. A revisão da configuração, sozinha, não prova nenhuma dessas coisas.

Reinicie completamente o cliente. Fechar uma janela pode não parar um auxiliar da barra de menus, o host do editor ou um processo filho. Abra o cliente novamente e inspecione sua lista de servidores usando os diagnósticos normais. Se o servidor aposentado aparecer, você perdeu uma fonte de configuração ou um mecanismo de sincronização o restaurou.

Em seguida, faça um teste de inicialização restrito. Abra o repositório que antes fornecia a configuração do servidor, inicie o agente e peça uma ação inofensiva sem relação com o servidor aposentado. Observe a atividade dos processos locais em busca do nome do executável aposentado e verifique os logs do cliente em busca de tentativas de conexão com o hostname anterior. Não invoque a ferramenta aposentada contra um destino de produção ativo apenas para ver se ela falha.

Para endpoints remotos, use registros de auditoria do provedor, logs de acesso ou atividade da conta para verificar tentativas de uso após a revogação. Uma solicitação negada depois de um teste controlado prova que a autoridade não funciona mais. O silêncio em um log é uma evidência mais fraca, porque o cliente talvez nunca tenha tentado a conexão.

Verifique também se a credencial antiga não aparece onde não deveria. Pesquise o rótulo do token, o nome da variável de ambiente, o hostname conhecido, o nome do arquivo e a impressão digital da chave pública SSH. Não pesquise o valor completo de um segredo se ele puder parar no histórico do shell, na tela do terminal ou em um log de comandos. O rótulo e a referência geralmente bastam.

Um caso de falha que vale reconhecer é este: um desenvolvedor remove `legacy-reporting` da configuração pessoal do agente, reinicia o agente e não vê nada. Uma semana depois, abre um repositório antigo. As configurações locais executam `npx` com um pacote antigo, o script carrega `REPORTING_TOKEN` de um perfil do shell e a API remota ainda aceita o token. Cada verificação individual pareceu limpa porque examinou apenas a configuração pessoal. O inventário deveria ter relacionado a configuração do repositório, o inicializador, a fonte do ambiente e a concessão da API antes do início da remoção.

## Preserve evidências sem criar outro cache de segredos

Mantenha evidências suficientes para explicar uma aposentadoria, mas não transforme sua pasta de auditoria em um arquivo de acesso utilizável. O registro deve permitir que outro engenheiro responda o que existia, o que podia alcançar, quem aprovou a remoção e qual prova a encerrou.

Um registro compacto de aposentadoria pode incluir o identificador do servidor, os locais removidos, o comando ou endpoint sem credenciais, o serviço de destino, o tipo de autoridade, o identificador da concessão ou a impressão digital, a data da revogação, o responsável e o resultado da validação. Coloque notas operacionais com controle de acesso onde sua equipe já mantém registros de segurança. Não crie um novo documento compartilhado cheio de configurações copiadas.

O histórico de execução pode revelar dependências que o inventário não mostra. Procure o histórico de sessões do agente, logs do cliente, histórico de instalação do gerenciador de pacotes, alterações no controle de código-fonte que adicionaram configurações e atividade do serviço de destino. Trate os horários com cuidado. Um log pode mostrar que um processo foi executado, mas talvez não prove que uma ferramenta concluiu uma ação privilegiada.

O Sallyport registra execuções de agentes e chamadas HTTP ou SSH individuais em diários separados, projetados a partir de um log de auditoria criptografado e sem possibilidade de escrita. Se uma equipe o utiliza, `sp audit verify` pode verificar offline essa cadeia de auditoria sobre o texto cifrado, sem precisar da chave do cofre, o que ajuda a preservar evidências durante uma revisão de acesso.

Não confunda evidência de adulteração com um inventário completo. Um log só registra ações que passaram pelo ponto de registro. Ele não revelará um servidor antigo executado fora dele, uma configuração esquecida que ninguém iniciou ou um token copiado usado diretamente por outro script.

## Faça a responsabilidade expirar antes que as ferramentas virem achados arqueológicos

A limpeza menos dolorosa acontece quando as equipes definem um responsável e uma data de revisão no momento da instalação. A regra parece administrativa até você precisar descobrir por que um agente ainda alcança uma API cujo projeto original terminou anos atrás.

Peça um plano curto de aposentadoria sempre que alguém adicionar um servidor com acesso de escrita, visibilidade de produção ou amplo alcance em repositórios. O plano deve informar o responsável, os repositórios previstos, o tipo de autoridade, os sistemas de destino e o evento que dispara a remoção. Um protótipo pode ter uma data de revisão próxima. Uma ferramenta compartilhada pode ter um mantenedor nomeado. Nenhum dos dois deve ter uma exceção permanente sem responsável.

Use configurações no nível do repositório com moderação. Um servidor no nível do projeto faz sentido quando o projeto realmente precisa dele e sua configuração não contém credenciais. É um lugar ruim para experimentos pessoais de um desenvolvedor. Mantenha experimentos em um local privado e descartável. Depois, promova-os com um responsável ou remova-os antes que o worktree vire um modelo.

Faça revisões depois de mudanças no cliente de agente, trocas de equipe, arquivamento de repositórios e rotações de credenciais. Esses eventos revelam desvios com mais confiabilidade do que um ritual de calendário arbitrário. Quando a revisão encontra um servidor desconhecido, suspenda primeiro seu caminho até sistemas sensíveis e depois rastreie seu responsável e suas dependências. Uma ferramenta que ninguém consegue explicar não deve manter permissão para agir.

A próxima limpeza deve começar com uma máquina real e um cliente ativo. Monte o inventário até que cada servidor tenha um responsável, um caminho de inicialização e uma fonte de autoridade. As entradas que não conseguem atender a esse padrão já lhe disseram o que deve ser aposentado.
