Aggiungere un server MCP: quattro superfici, quattro punti di configurazione
Il Model Context Protocol (MCP) è uno standard aperto che definisce come le applicazioni condividono contesto con i modelli linguistici. Per un agente un server MCP è soprattutto una fonte di strumenti: dichiari dove sta il server e quali dei suoi strumenti l’agente può chiamare. Il punto delicato è che ogni superficie ha un posto diverso in cui questa dichiarazione vive.
Nella Copilot CLI aggiungi un server con il comando interattivo /mcp add, che apre un modulo da compilare, oppure dal terminale con copilot mcp add SERVER-NAME -- COMMAND [ARGS...] per un server locale e copilot mcp add --transport http SERVER-NAME URL per uno remoto. La configurazione utente sta in ~/.copilot/mcp-config.json; a livello di progetto la CLI legge .mcp.json oppure .github/mcp.json, e la configurazione più vicina alla directory di lavoro prevale su quella utente. I server dichiarati nel progetto richiedono la conferma di fiducia sulla cartella prima di essere caricati.
Sul cloud agent la configurazione è per repository, sotto Settings > Copilot > MCP servers, e i server dichiarati lì sono disponibili sia al cloud agent sia a Copilot code review. Nel Copilot SDK i server si passano invece alla creazione della sessione, tramite il parametro mcpServers (disponibile in TypeScript, Python, Go e .NET). Lo schema JSON è però lo stesso in tutte e tre le superfici: un oggetto mcpServers, e per ogni server la chiave type con valore local o stdio, http, sse; command e args per i server locali; url e headers per quelli remoti; env per le variabili d’ambiente; e tools.
Il campo tools è il primo livello di restrizione e va letto con attenzione: il valore asterisco abilita tutti gli strumenti del server, un elenco esplicito abilita solo quei nomi. Sul cloud agent conta doppio, perché una volta configurato il server Copilot usa i suoi strumenti in autonomia, senza chiedere approvazione. Nella CLI la granularità a runtime passa invece dai flag --allow-tool e --deny-tool, con la sintassi ServerName(tool_name) per gli strumenti MCP; il deny prevale sempre sull’allow e i flag valgono solo per la sessione corrente.
Locale o remoto: il caso del GitHub remote MCP server
Un server locale gira sulla tua macchina come sottoprocesso e comunica su standard input e output; un server remoto è raggiunto via HTTP. Il GitHub remote MCP server è ospitato da GitHub e risponde su https://api.githubcopilot.com/mcp/: non richiede installazioni locali e l’autenticazione consigliata è OAuth, con il personal access token come alternativa passata in un header Authorization. Esiste anche la variante locale del GitHub MCP server, indicata quando serve personalizzare il setup o soddisfare requisiti di sicurezza specifici, ma alcuni toolsets sono disponibili solo nella versione remota.
I toolsets servono ad accendere solo le porzioni di superficie che ti servono: repos, issues e pull_requests sono attivi per impostazione predefinita, mentre actions, code_security, secret_protection, stargazers e altri vanno abilitati esplicitamente; le parole chiave all e default fanno da scorciatoia. Sul server remoto si selezionano con parametri nel percorso dell’URL quando ne serve uno solo, o con header HTTP quando ne servono più di uno; su quello locale con flag da riga di comando o variabili d’ambiente, e queste ultime prevalgono sui flag.
Sul cloud agent il GitHub MCP server è già presente, e questo è il dettaglio da ricordare: la configurazione predefinita usa un token dallo scope ristretto, in sola lettura sul repository corrente. Accanto c’è il Playwright MCP server, che per impostazione predefinita raggiunge solo localhost e 127.0.0.1. Se un tuo server ha bisogno di credenziali, tieni presente che solo i secret e le variabili Agents il cui nome inizia con COPILOT_MCP_ sono visibili alla configurazione MCP: si impostano in Secrets and variables della sezione Agents e si referenziano con la sintassi di sostituzione, che ammette anche un valore di fallback. Il cloud agent, inoltre, supporta gli strumenti MCP ma non le resources o i prompts esposti dal server.
Tre livelli di governo che non sono la stessa cosa
Alla base c’è la policy MCP servers in Copilot: è l’interruttore che decide se i server MCP funzionano nei client Copilot, e va abilitato perché i controlli più fini abbiano senso.
Il secondo livello è il registry: un elenco di server approvati che l’azienda ospita per conto proprio, esponendo endpoint HTTPS che descrivono i server e le loro versioni con gli header CORS richiesti. L’URL si inserisce in Enterprise settings, AI controls, MCP, nel campo MCP Registry URL; a livello di organizzazione il campo equivalente sta in Organization Settings, Copilot, Policies. Configurare il registry, da solo, si limita a mostrare quei server.
Il terzo livello è l’enforcement del registry privato, cioè il menù Restrict MCP access to registry servers con le opzioni Allow all e Registry only. È in public preview e i suoi limiti sono espliciti: la corrispondenza avviene solo per nome o ID e si può aggirare modificando i file di configurazione, l’installazione di server esterni non è ancora impedita, e il cloud agent non è fra le superfici coperte. Se un utente ha seat in più organizzazioni, l’enterprise prevale sull’organizzazione e Registry only prevale su Allow all.
Il controllo più solido è la allow list enterprise in managed-settings.json, tipicamente ospitato in un repository .github-private o distribuito via MDM.
{
"allowedMcpServers": [
{ "serverUrl": "https://api.githubcopilot.com/*" },
{ "serverCommand": ["npx", "@playwright/mcp@latest"] }
],
"deniedMcpServers": [
{ "serverName": "filesystem-root" }
]
}
Le regole di corrispondenza sono tre e non interscambiabili: serverName confronta l’etichetta in modo esatto e senza caratteri jolly, serverUrl accetta l’asterisco per sottodomini e prefissi di percorso, serverCommand richiede comando e argomenti esatti. Il deny prevale sempre sull’allow. Con più sorgenti di impostazioni, gli allow si intersecano e i deny si uniscono.
Che cosa verifica l’esame
L’errore che GH-600 punisce più spesso è la confusione fra livelli. Primo: nel file managed-settings.json sia allowedMcpServers sia deniedMcpServers identificano server, per nome, URL o comando — non accettano specificatori di strumenti; per bloccare un singolo strumento servono il campo tools nella configurazione del server oppure i flag di permesso della CLI. Secondo: registry e allow list non sono sinonimi, hanno forza e superfici diverse, e in uno scenario che coinvolge il cloud agent l’enforcement basato sul registry non è la risposta giusta. Terzo: non dare per scontato che l’agente possa scrivere su GitHub solo perché il GitHub MCP server è attivo, perché la configurazione predefinita del cloud agent è in sola lettura sul repository corrente.