8 min de leitura

Como a precedência da configuração MCP muda entre terminais e IDEs

A precedência da configuração MCP varia conforme o cliente. Descubra qual comando de servidor vence no Claude Code, VS Code, Cursor, plugins e agentes de terminal.

Como a precedência da configuração MCP muda entre terminais e IDEs

Conflitos de configuração do MCP não são um problema do MCP. São um problema do cliente, e essa distinção evita muito diagnóstico equivocado.

O protocolo diz a um cliente como conversar com um servidor depois que ele é iniciado. Ele não diz ao Claude Code, VS Code, Cursor, GitHub Copilot CLI ou a uma extensão qual arquivo JSON deve ser lido primeiro, se duas entradas com o mesmo nome devem ser mescladas ou se um plugin pode registrar um servidor depois que a configuração baseada em arquivos for carregada. Se você presumir uma hierarquia universal, poderá executar o binário errado com um nome de ferramenta que parece correto.

É fácil não perceber esse erro. A lista de ferramentas mostra github, o agente chama github.search_code e a chamada funciona. Enquanto isso, seu agente de terminal pode ter iniciado um wrapper do projeto contra uma conta de teste, enquanto o IDE iniciou um comando global contra sua conta pessoal. O nome coincidiu. O comando, não.

Esta é a regra prática que uso: resolva a configuração MCP por cliente, por processo e por nome de servidor. Trate o comando do servidor, os argumentos, o ambiente, o diretório de trabalho, a URL de transporte e a origem das credenciais como uma única definição de inicialização. Não deduza nada disso pelo rótulo mostrado no painel do agente.

O MCP não tem uma hierarquia de precedência compartilhada

O MCP padroniza mensagens e capacidades entre clientes e servidores. Ele não define um layout de arquivos portátil nem um vencedor quando as fontes de configuração entram em conflito. Um cliente pode usar arquivos JSON, um banco de configurações, uma API de plugins, uma política empresarial gerenciada, uma opção de linha de comando ou todos esses recursos.

Isso significa que quatro expressões frequentemente tratadas como equivalentes não são equivalentes:

  • Uma configuração do usuário é uma definição global específica do cliente para uma conta ou perfil.
  • Uma configuração do projeto é uma definição associada a um repositório ou workspace.
  • Uma configuração de plugin é um servidor registrado ou fornecido por uma extensão ou plugin instalado.
  • Uma configuração do editor é uma configuração pertencente ao editor, que pode ou não controlar a configuração de servidores MCP.

A última distinção causa mais problemas do que deveria. O VS Code tem uma hierarquia madura de configurações gerais: as configurações do workspace substituem as configurações do usuário para configurações comuns, e valores de objetos podem ser mesclados, enquanto valores primitivos e arrays substituem os anteriores. Esse é o comportamento real de settings.json. Ele não prova que .vscode/mcp.json siga as mesmas regras de mesclagem e colisão. O VS Code documenta a configuração MCP como seu próprio arquivo mcp.json, em um workspace ou perfil de usuário. Não transfira suposições do mecanismo de configurações para um formato separado.

A consequência prática é direta: «o workspace vence» não é uma resposta útil até que você acrescente o nome do cliente, a versão do cliente, o formato da configuração e o conflito exato. Um arquivo do workspace pode adicionar um servidor, ocultar um servidor global com o mesmo nome, coexistir com ele ou deixar de ser carregado porque o workspace não é confiável. São resultados diferentes, e um diagrama genérico de precedência esconde isso.

O nome do servidor é a unidade do conflito

A maioria dos clientes organiza a configuração MCP como um mapa: um nome de servidor à esquerda e uma definição de inicialização à direita. A chave do mapa costuma ser o que o cliente usa para decidir que duas declarações entram em conflito.

Considere estes dois arquivos:

// configuração do usuário
{
  "mcpServers": {
    "catalog": {
      "command": "node",
      "args": ["/Users/dev/bin/catalog-live.js"],
      "env": { "CATALOG_TARGET": "production" }
    }
  }
}
// configuração do projeto
{
  "mcpServers": {
    "catalog": {
      "command": "node",
      "args": ["./tools/catalog-fixture.js"],
      "env": { "CATALOG_TARGET": "fixture" }
    }
  }
}

Uma pessoa vê dois serviços de catálogo. Um cliente vê dois valores na chave catalog. Se ele selecionar uma definição, em geral selecionará a definição inteira. Não espere que o cliente combine o comando global com os argumentos do projeto, nem o comando do projeto com o ambiente global. Alguns sistemas de configuração mesclam objetos; um cliente MCP não tem obrigação de fazer isso.

Por isso, substituições parciais são um projeto ruim. Um projeto que precisa de outro endpoint deve declarar o comando pretendido por completo. Um usuário que quer uma ferramenta pessoal deve usar outro nome. Uma substituição parcial dificulta saber se o cliente substituiu todo o objeto do servidor ou mesclou campos de uma forma que você não testou.

Use nomes que revelem propriedade e finalidade enquanto ainda estiver diagnosticando a configuração:

{
  "mcpServers": {
    "catalog-user-live": { "command": "node", "args": ["/Users/dev/bin/catalog-live.js"] },
    "catalog-repo-fixture": { "command": "node", "args": ["./tools/catalog-fixture.js"] }
  }
}

Esses nomes não são elegantes. São honestos. Depois que a equipe tiver uma única definição canônica, você poderá renomeá-la para catalog. Antes disso, um nome duplicado e conciso transforma cada chamada de ferramenta em um exercício de adivinhação.

Também separe nome duplicado de capacidade duplicada. Dois servidores podem expor uma ferramenta chamada search e continuar distintos porque seus nomes de servidor são diferentes. O agente pode se confundir com descrições parecidas, mas a configuração do cliente não está necessariamente em uma colisão de nomes. Resolva primeiro a resolução do cliente e depois melhore as descrições e os nomes das ferramentas.

O Claude Code tem uma ordem explícita de escopos MCP

O Claude Code é o caso mais simples porque sua documentação MCP informa a ordem para entradas de servidores com o mesmo nome. O escopo local vence o escopo do projeto, e o escopo do projeto vence o escopo do usuário. A terminologia atual importa: local é o padrão privado e específico do projeto; project grava um .mcp.json compartilhado; user se aplica a todos os projetos. A Anthropic usava nomes diferentes para alguns desses escopos no passado, por isso anotações antigas e o histórico do shell podem confundir.

Na prática, se os três escopos contiverem catalog, o Claude Code iniciará a definição local. A definição do .mcp.json compartilhado vem em seguida, e a definição do usuário funciona como fallback.

# privado para este checkout e este usuário
claude mcp add catalog --scope local -- node ./tools/catalog-fixture.js

# compartilhado com o repositório
claude mcp add catalog --scope project -- node ./tools/catalog-service.js

# disponível em todos os repositórios deste usuário
claude mcp add catalog --scope user -- node ~/bin/catalog-personal.js

O resultado esperado da inspeção é um único servidor efetivo chamado catalog, originado do escopo local quando os três existem. Execute o comando do cliente que lista ou obtém o servidor depois de cada alteração, em vez de confiar no arquivo que você acabou de editar:

claude mcp get catalog

O formato da saída deve identificar o servidor nomeado e mostrar os detalhes do transporte ou do comando configurado. Compare o comando, os argumentos e o ambiente reais com a definição esperada. Se o comando não for o que você editou, pare de alterar arquivos e descubra qual escopo ainda é proprietário do nome.

Não confunda essa regra de escopo MCP com a precedência mais ampla das configurações do Claude Code. A Anthropic documenta política empresarial gerenciada, argumentos de linha de comando, configurações locais do projeto, configurações compartilhadas do projeto e configurações do usuário para as configurações gerais do Claude Code. Uma configuração gerenciada pode restringir comportamentos relacionados ao uso do MCP sem funcionar como uma segunda definição de servidor MCP. As duas hierarquias respondem a perguntas diferentes.

Há outra armadilha no escopo do projeto. O Claude Code pede aprovação antes de usar um servidor fornecido por .mcp.json. Essa aprovação trata de o cliente poder usar o servidor fornecido pelo projeto. Ela não altera qual configuração de servidor com o mesmo nome tem prioridade. Não interprete um pedido de aprovação como prova de que o comando compartilhado venceu.

O VS Code mantém os arquivos MCP separados das configurações comuns

O VS Code oferece dois locais documentados para a configuração de servidores MCP: .vscode/mcp.json no workspace e um mcp.json no perfil do usuário, aberto pelo comando MCP: Open User Configuration. O arquivo do workspace foi feito para ser compartilhado pelo controle de versão, enquanto o arquivo do perfil acompanha o usuário e pode variar conforme o perfil do VS Code.

Esse layout cria uma expectativa razoável: a configuração de um repositório deve definir as ferramentas do repositório, e o perfil deve definir as ferramentas pessoais. Por si só, ele não documenta uma regra completa para resolver nomes duplicados. Em particular, a referência pública de configuração MCP descreve o esquema e os locais, mas não afirma que a precedência comum das configurações do VS Code se aplica campo a campo às entradas de servers.

É aqui que usuários experientes fazem um atalho equivocado. Eles sabem que as configurações do workspace substituem as configurações do usuário no VS Code. Colocam o mesmo nome de servidor MCP nas configurações do perfil e do workspace, alteram o comando do projeto e concluem que o comando do workspace deve ser executado. Pode ser que sim. Mas uma conclusão baseada em um subsistema de configurações próximo continua sendo uma conclusão, não um contrato documentado.

Trate uma colisão de nomes no VS Code como um requisito de teste. Torne os dois candidatos visivelmente diferentes e use um comando inofensivo que prove qual deles foi iniciado:

{
  "servers": {
    "precedence-probe": {
      "type": "stdio",
      "command": "sh",
      "args": ["-lc", "printf 'workspace probe started\\n' >&2; exec node ./tools/probe-server.js"]
    }
  }
}

Coloque um marcador diferente na configuração do perfil do usuário:

{
  "servers": {
    "precedence-probe": {
      "type": "stdio",
      "command": "sh",
      "args": ["-lc", "printf 'profile probe started\\n' >&2; exec node $HOME/bin/probe-server.js"]
    }
  }
}

Depois reinicie completamente o servidor pela interface de gerenciamento MCP do VS Code ou reinicie o editor se a interface não deixar claro o estado do processo. Inspecione a saída ou os logs do servidor MCP em busca do marcador. Não teste com um banco de dados real nem com um destino de implantação real. Uma verificação de precedência deve provar um caminho de inicialização, não alterar dados.

A mesma cautela vale para a ativação. O VS Code documenta que o estado de ativação e desativação é armazenado separadamente da configuração do servidor, portanto um arquivo de configuração compartilhado pode estar presente enquanto o servidor não é iniciado em um workspace. «Consigo vê-lo em mcp.json» e «este cliente o iniciou» são fatos diferentes.

Workspaces multi-root acrescentam outro ponto de falsa certeza. O VS Code tem escopos de workspace e de pasta do workspace para configurações gerais, mas um arquivo MCP vinculado a um workspace não é automaticamente uma declaração de servidor por pasta. Se uma ferramenta precisar de um comando relativo ao repositório, torne explícitos a raiz do workspace e o diretório de trabalho esperado no teste. Um comando que funciona em uma raiz pode falhar ou alcançar silenciosamente outro arquivo quando o editor abre várias pastas.

O Cursor combina caminhos de projeto, globais e de registro por extensão

Separe as chaves SSH dos agentes
Guarde as chaves SSH no cofre criptografado do Sallyport e execute SSH pelo auxiliar sp-ssh incluído.

O Cursor documenta a configuração MCP específica do projeto em .cursor/mcp.json e a configuração global em ~/.cursor/mcp.json. Ele também oferece uma API de extensões que pode registrar servidores MCP programaticamente. São três fontes distintas: arquivo do repositório, arquivo do usuário e código executado dentro de uma extensão.

As duas primeiras são fáceis de entender quando os nomes são exclusivos. Coloque o serviço de desenvolvimento compartilhado do repositório em .cursor/mcp.json. Coloque uma ferramenta pessoal, como um serviço local de busca em notas, no arquivo global. A CLI do Cursor diz que detecta e respeita mcp.json, o que torna a configuração compartilhada útil quando o IDE e o agente de terminal realmente são executados no mesmo ambiente.

O caso difícil é um nome duplicado nas três fontes. A documentação pública de MCP do Cursor informa onde colocar os arquivos de projeto e globais, mas não publica um contrato completo para cada colisão que envolva configuração global, configuração do projeto e um servidor de extensão registrado dinamicamente. Não invente uma regra com base em uma publicação de fórum, uma nota de versão antiga ou um comportamento observado em uma única máquina.

O projeto seguro é evitar a colisão. Se uma extensão fornecer issue-tracker, não coloque uma segunda entrada issue-tracker em .cursor/mcp.json esperando que o comando do repositório a substitua. Dê ao servidor pertencente ao repositório outro nome, como issue-tracker-fixture, e deixe claro nas instruções do agente ou nas descrições das ferramentas quando ele deve ser usado.

Isso é especialmente importante para equipes que usam um plugin por conveniência e um arquivo por reprodutibilidade. O plugin pode cuidar da instalação, do OAuth, das atualizações ou do registro segundo seu próprio ciclo. Um arquivo do repositório fica visível na revisão de código. São modelos de propriedade diferentes. Decida qual deles é proprietário do servidor antes de tentar fazê-los coincidir por acaso.

Os limites de ambiente fazem os conflitos do Cursor parecerem mais estranhos do que são. Um editor de desktop pode ser executado em um sistema operacional, enquanto o terminal, o workspace remoto ou o contêiner de desenvolvimento são executados em outro lugar. Um arquivo global no diretório pessoal pode existir em um ambiente e não no outro. O comando em um arquivo do projeto pode resolver node, python ou um executável relativo por meio de valores diferentes de PATH. Antes de discutir precedência, anote onde o processo do cliente é executado e onde o processo do servidor é executado.

Para cada candidato, registre esta pequena ficha de inicialização:

cliente: Cursor desktop / Cursor CLI
ambiente do cliente: macOS local / WSL / host remoto / contêiner
fonte da configuração: ~/.cursor/mcp.json / .cursor/mcp.json / registro da extensão
nome do servidor: issue-tracker
comando: node ./tools/issue-mcp.js
diretório de trabalho: raiz do repositório
origem da credencial: OAuth / ambiente local / gateway externo

Um registro de cinco minutos como esse vale mais do que uma tarde alternando painéis de configurações.

O GitHub Copilot CLI documenta a resolução de MCP do projeto sobre o usuário

O GitHub Copilot CLI é mais explícito do que muitos clientes. Sua documentação diz que a configuração MCP no nível do projeto em .mcp.json ou .github/mcp.json tem precedência sobre uma definição com o mesmo nome em ~/.copilot/mcp-config.json. Essa é uma regra clara de projeto sobre usuário para nomes de servidores MCP na CLI.

Use-a como uma regra específica do cliente, não como uma verdade geral sobre o GitHub Copilot em todo editor. O Copilot CLI tem seu próprio diretório de configuração, configurações do repositório, configurações locais, suporte a plugins, armazenamento de permissões e processo de linha de comando. Uma sessão do Copilot no VS Code é outra superfície de cliente, com sua própria documentação de configuração MCP e seu próprio ciclo de vida.

Uma configuração limpa do Copilot CLI pode ser assim:

// ~/.copilot/mcp-config.json
{
  "mcpServers": {
    "docs": {
      "command": "node",
      "args": ["/Users/dev/bin/company-docs-mcp.js"]
    },
    "catalog": {
      "command": "node",
      "args": ["/Users/dev/bin/catalog-live.js"]
    }
  }
}
// .mcp.json no repositório
{
  "mcpServers": {
    "catalog": {
      "command": "node",
      "args": ["./tools/catalog-fixture.js"]
    }
  }
}

Nesse repositório, o Copilot CLI deve usar a definição de projeto de catalog e manter a definição de usuário de docs, pois nenhuma entrada do projeto entra em conflito com docs. Esse é o modelo útil: substitua apenas o nome que pertence ao projeto e deixe as ferramentas pessoais não relacionadas intactas.

Os plugins complicam o cenário porque podem trazer seu próprio comportamento de agente e ciclo de vida de servidores MCP. A documentação de configuração do GitHub descreve plugins ativados no repositório como pertencentes ao escopo do repositório e diz que o cliente encerra o servidor MCP de um plugin quando o repositório deixa de ativá-lo. Isso indica que o servidor do plugin está ligado à ativação do plugin, não simplesmente copiado para o arquivo MCP do usuário.

Se um servidor fornecido por plugin e um servidor fornecido por arquivo usarem o mesmo nome, não adivinhe qual comando vence. Inspecione o estado visível dos servidores na CLI, o estado do plugin e a saída de inicialização. Se a documentação da versão instalada não declarar o comportamento da colisão, renomeie uma definição ou remova um dos produtores. O conselho popular de «simplesmente substituir o servidor do plugin no repositório» parece atraente porque é curto. Ele está errado quando o plugin controla o registro depois do carregamento dos arquivos ou fornece estado adicional de ciclo de vida.

O editor e o terminal são clientes MCP separados

Um terminal dentro de um IDE parece fazer parte do editor. Ainda assim, ele é um processo de shell. Quando você executa claude, copilot ou cursor-agent, esse comando pode ler seus próprios arquivos, diretório atual, ambiente, diretório pessoal e variáveis de substituição de configuração. A extensão de chat do editor é outro processo, com outra implementação de cliente.

Essa é a origem do relato conhecido: «O servidor MCP funciona no IDE, mas não no terminal». Há várias explicações comuns:

  • O editor abriu um arquivo do workspace, enquanto o terminal começou em um subdiretório ou checkout vizinho.
  • O editor usa um host remoto ou contêiner, enquanto o comando do terminal é executado localmente.
  • O terminal herdou um PATH, HOME, proxy ou variável de credencial específica do shell.
  • O editor ativou um servidor de plugin que a CLI nunca carrega.
  • A CLI encontrou um servidor de projeto com o mesmo nome e substituiu a entrada no nível do usuário.

Não comece copiando todos os arquivos de configuração para todos os locais. Isso cria uma superfície maior de colisão e esconde a causa inicial.

Em vez disso, execute um cliente por vez e reúna evidências. Para clientes de terminal, use o comando incorporado que lista ou obtém servidores MCP. Para clientes de editor, use a visualização de gerenciamento de servidores MCP e sua saída ou seus logs. Registre o nome do servidor, o comando, os argumentos, o local do processo e o horário de inicialização. Se o terminal e o editor mostrarem o mesmo nome, mas comandos diferentes, você encontrou um problema de resolução de configuração. Se mostrarem o mesmo comando, mas comportamentos diferentes, investigue o diretório de trabalho, as credenciais, o acesso à rede ou o próprio servidor.

Um teste útil é substituir temporariamente o comando pretendido do servidor por um wrapper que escreva um marcador inequívoco na saída de erro padrão antes de executar o servidor real. Mantenha-o somente leitura e remova-o depois do teste.

#!/bin/sh
printf '%s client=%s cwd=%s\n' \
  "MCP probe started" \
  "${MCP_CLIENT_LABEL:-unknown}" \
  "$PWD" >&2
exec node "$(dirname "$0")/real-server.js"

Não imprima tokens, cabeçalhos, valores de credenciais, despejos completos do ambiente nem payloads de requisições. Os logs muitas vezes sobrevivem à sessão do terminal, e uma verificação de precedência não deve criar um vazamento de segredo enquanto tenta explicar outro.

O registro de um plugin não é uma substituição de arquivo de configuração

Estabeleça um limite para as ações
Use o aplicativo de barra de menus do Mac como limite de ação entre agentes compatíveis com MCP e sistemas externos.

Um plugin produz configuração de servidor, não é apenas outra pasta onde há JSON. Ele pode registrar um servidor dinamicamente, gerenciar autenticação, escolher uma versão, reagir a alterações do workspace ou parar o servidor quando o plugin é desativado.

Isso torna inseguras duas recomendações populares.

A primeira é «coloque o mesmo nome no arquivo do projeto para substituir o plugin». Isso só funciona quando o cliente documenta que os arquivos são carregados depois dos plugins e que uma colisão de mesmo nome substitui o registro do plugin. Sem esse contrato, a duplicação pode gerar um erro, uma substituição oculta, duas ferramentas com descrições parecidas ou um comportamento que muda depois de uma atualização.

A segunda é «desative o servidor na interface e o projeto estará limpo». O estado de ativação pode ficar fora do arquivo compartilhado. O VS Code separa explicitamente seu estado de ativação ou desativação da configuração MCP. Um colega pode clonar o repositório, receber o mesmo arquivo e ainda ter um conjunto diferente de servidores ativos.

Use um destes modelos de propriedade:

  1. Servidor pertencente ao arquivo: o repositório versiona a definição do servidor. Todos usam o arquivo, e nenhum plugin registra o mesmo serviço.
  2. Servidor pertencente ao plugin: o plugin gerencia o registro e a autenticação. O repositório não declara uma duplicata.
  3. Funções de servidor separadas: um plugin é proprietário de tracker-live; um arquivo do projeto é proprietário de tracker-fixture. Os nomes, as descrições e as permissões deixam os destinos distintos.

A terceira opção costuma ser a menos atraente e a mais segura. As equipes frequentemente precisam de um serviço pessoal ativo e de um fixture do repositório ao mesmo tempo. Fingir que são um único servidor porque ambos conversam com um rastreador de problemas só torna mais provável uma chamada acidental ao ambiente ativo.

Uma forma repetível de provar qual comando venceu

Você pode provar a resolução da configuração sem depender do comportamento do agente. O método abaixo usa um servidor stdio ou wrapper inofensivo e funciona tanto quando o cliente inicia um comando local quanto quando aponta para um serviço remoto.

Crie uma verificação com duas fontes

Escolha um nome de servidor, como precedence-probe. Defina-o exatamente em duas fontes que você quer comparar. Faça cada candidato produzir um marcador diferente antes de iniciar o mesmo servidor de teste inofensivo.

Para um servidor baseado em comando, diferencie todas as partes importantes:

{
  "mcpServers": {
    "precedence-probe": {
      "command": "sh",
      "args": ["-lc", "printf 'SOURCE=PROJECT CWD=%s\\n' \"$PWD\" >&2; exec node ./tools/probe.js"],
      "env": { "MCP_PROBE_SOURCE": "project" }
    }
  }
}

O candidato do usuário deve imprimir SOURCE=USER e apontar para outro arquivo conhecido. Não dependa apenas de uma variável de ambiente se o cliente puder ocultá-la, filtrá-la ou iniciar um processo obsoleto. Coloque também um marcador visível no caminho do comando e na saída.

Reinicie o servidor, não apenas o chat

Os servidores MCP muitas vezes são processos filhos de longa duração. Editar o JSON enquanto o servidor continua em execução não prova nada sobre a próxima requisição. Use o controle do cliente que interrompe e reinicia o servidor. Se esse controle não estiver claro, feche completamente o cliente relevante e reabra o workspace.

Depois, inspecione primeiro os logs do lado do cliente. A evidência esperada tem este formato:

MCP probe started
SOURCE=PROJECT
CWD=/path/to/repository

Se nenhum marcador aparecer, o cliente pode ter rejeitado a configuração antes de iniciar o processo, usado um transporte remoto ou mantido um servidor antigo em execução. Esse resultado é útil. Ele reduz a pergunta de «qual configuração vence?» para «esta configuração foi carregada e este cliente iniciou um processo?»

Altere um limite por vez

Execute a verificação no cliente de terminal e depois no cliente do IDE. Altere o diretório de trabalho somente depois de obter uma linha de base. Desative o plugin apenas depois de medir o comportamento somente com arquivos. Teste as fontes do usuário e do projeto antes de adicionar substituições locais ou configurações gerenciadas.

Mantenha uma pequena tabela de resultados no issue do repositório ou nas notas da equipe:

ClienteAmbienteFontes candidatasMarcador observadoComando efetivo
Claude Codeshell locallocal, projeto, usuárioLOCALnode ./tools/probe-local.js
VS Codecontêiner de desenvolvimentoworkspace, perfilWORKSPACEnode ./tools/probe-workspace.js
Cursordesktopprojeto, global, extensãomarcador da extensãogerenciado pelo plugin

A tabela deve relatar o comportamento observado, não o comportamento esperado. Uma equipe pode agir com base no comportamento observado. Um diagrama copiado de outro cliente é apenas uma hipótese.

Mantenha as credenciais fora da disputa de precedência

Veja qual processo quer acesso
Aprove um novo processo de agente uma vez, com a autoridade de assinatura do código exibida no cartão de aprovação.

Um conflito de comandos é um problema de execução. Um conflito de credenciais é um problema de segurança. Não resolva o primeiro espalhando segredos entre configurações do projeto, do plugin, do usuário e do editor até alguma coisa funcionar.

A configuração de projeto versionada normalmente deve conter um comando de servidor, informações de endpoint não sensíveis e instruções para obter credenciais. Ela não deve conter um bearer token de longa duração em env, o caminho de uma chave privada SSH que nenhum colega possui ou um valor de cabeçalho personalizado que conceda acesso à produção. Um arquivo do projeto se torna um convite à execução para cada clone e cada agente que o cliente permitir usar.

Se um servidor precisar de um segredo, escolha um limite de credencial compatível com o trabalho:

  • OAuth é apropriado quando o servidor e o cliente oferecem suporte e o usuário deve conceder o acesso de forma interativa.
  • Um gerenciador local de segredos ou uma injeção de ambiente é apropriado para uma definição de servidor pessoal.
  • Um fixture do repositório deve usar credenciais que não sejam de produção e tenham permissões restritas.
  • Um gateway de ações é apropriado quando um agente deve solicitar uma ação sem nunca receber a API subjacente ou a credencial SSH.

É aqui que um comando de servidor pode parecer inofensivo e ainda ser perigoso. npx some-mcp-server pode resolver uma versão instalada diferente entre máquinas. node ./tools/server.js pode herdar AWS_PROFILE, GH_TOKEN ou um proxy corporativo do processo pai. Uma declaração do projeto pode ser revisada, enquanto a origem real da credencial continua invisível.

Quando agentes precisam de acesso HTTP ou SSH, o Sallyport pode manter a credencial de API ou SSH em seu cofre criptografado enquanto o agente se conecta pelo shim sp mcp e recebe apenas os resultados das ações. Isso não decide qual configuração do cliente vence, mas impede que o comando vencedor também entregue credenciais brutas ao agente.

Não trate a precedência de configuração como um sistema de permissões. Uma definição de projeto pode selecionar um comando; ela não prova que o comando deve ter permissão para agir sem revisão. Mantenha aprovação, armazenamento de credenciais e evidências de auditoria como controles separados.

Torne óbvio o comando canônico

As equipes precisam de uma resposta para uma pergunta simples: qual comando o agente deste repositório deve iniciar para esse serviço? Se a resposta estiver escondida entre arquivos do usuário, comportamento de plugins, trechos de README e configurações do editor, a estrutura já está solta demais.

Escreva a definição compartilhada canônica em um único lugar. Dê a ela um nome de servidor estável. Declare quais clientes a aceitam e qual fonte é sua proprietária. Coloque variantes pessoais sob nomes diferentes. Se um plugin precisar ser o proprietário do serviço, documente que ele é canônico e não distribua uma definição de arquivo concorrente.

Depois, mantenha no repositório um pequeno comando de verificação ou uma sonda. Alterações de configuração merecem testes, assim como scripts de implantação. Um servidor que inicia o comando errado pode ler os arquivos errados, chamar o endpoint errado ou herdar a credencial errada antes que o agente diga qualquer coisa.

O resultado útil não é um gráfico universal de precedência. É uma configuração em que cada cliente tem um caminho de inicialização observável, cada nome de servidor tem um único proprietário e ninguém precisa adivinhar qual comando o agente vai executar.

FAQ

O MCP define uma ordem padrão de precedência de configuração?

Não. O MCP define o protocolo entre um cliente e um servidor, não uma hierarquia universal de configuração para todos os clientes. Claude Code, VS Code, Cursor e GitHub Copilot CLI decidem onde leem a configuração e como resolvem nomes duplicados.

O que acontece quando duas configurações MCP usam o mesmo nome de servidor?

Normalmente, o nome duplicado do servidor é o ponto de conflito, não o caminho do executável. Se duas entradas chamadas github apontarem para comandos diferentes, trate-as como definições concorrentes até que o cliente específico demonstre o contrário.

Qual escopo MCP vence no Claude Code?

O Claude Code dá prioridade ao escopo local sobre o escopo do projeto, e ao escopo do projeto sobre o escopo do usuário para servidores MCP com o mesmo nome. A hierarquia geral de configurações é separada e também inclui políticas gerenciadas e configurações de linha de comando para os itens que elas controlam.

A configuração MCP do workspace do VS Code substitui a configuração do usuário?

O VS Code documenta arquivos de configuração MCP no workspace e no perfil do usuário, mas as regras comuns de precedência do settings.json não documentam automaticamente como entradas com o mesmo nome em dois arquivos mcp.json são mescladas. Teste a versão instalada em vez de presumir que o arquivo do workspace substitui a entrada do perfil.

Como o Cursor resolve servidores MCP globais e de projeto?

O Cursor documenta a configuração do projeto em .cursor/mcp.json, a configuração global em ~/.cursor/mcp.json e o registro dinâmico pela API de extensões. A página pública sobre MCP não apresenta uma regra completa para conflitos quando um servidor duplicado é fornecido por todas essas fontes. Por isso, use nomes exclusivos quando uma extensão participar.

A configuração MCP do projeto substitui a configuração do usuário no Copilot CLI?

O GitHub Copilot CLI documenta que as definições MCP do projeto em .mcp.json ou .github/mcp.json têm precedência sobre definições do usuário com o mesmo nome em ~/.copilot/mcp-config.json. Essa regra é específica do Copilot CLI e não deve ser aplicada a outro cliente.

Por que meu IDE usa um servidor MCP diferente do meu terminal?

Uma extensão do editor pode iniciar um cliente MCP dentro do editor, enquanto um comando do terminal pode iniciar outro cliente em um processo filho. Eles podem ler arquivos diferentes, herdar variáveis de ambiente diferentes e mostrar o mesmo nome de servidor enquanto executam comandos diferentes.

É seguro versionar uma configuração MCP com variáveis de ambiente?

Não coloque chaves de API de longa duração em um arquivo MCP de projeto versionado. Mantenha o comando compartilhado e os padrões inofensivos no controle de versão, e guarde as credenciais em um gerenciador local de segredos, variável de entrada, fluxo OAuth ou gateway de ações que mantenha as credenciais fora do processo do agente.

Como posso testar a precedência MCP sem tocar em ferramentas de produção?

Primeiro reduza a configuração a um nome de servidor e dois comandos intencionalmente diferentes que imprimam um marcador claro. Depois, inspecione a lista de servidores ou os logs de cada cliente após uma reinicialização completa. Alterar o comando e o nome ao mesmo tempo dificulta a interpretação do resultado.

Os servidores MCP do projeto e do usuário devem ter nomes diferentes?

Use nomes distintos para diferentes limites de propriedade, como github-personal, github-repo e github-plugin. Só renomeie depois de decidir qual definição será canônica. Um nome curto não compensa um caminho de execução ambíguo.

Sallyport

O Sallyport executa chamadas de API e comandos SSH pelo seu agente de IA. As chaves ficam em um cofre local no seu Mac; você aprova cada execução e toda ação vai para um registro selado.

© 2026 Sallyport · Código aberto sob Apache-2.0 · Oleg Sotnikov