GitHub Copilot MCP allowlists: what managed settings cover and what they miss
How allowedMcpServers and deniedMcpServers match servers, how the deployment methods combine, which Copilot surfaces the allowlist skips, and the local activity GitHub's audit log does not record.
GitHub Copilot's MCP allowlist is allowedMcpServers plus deniedMcpServers in your enterprise managed-settings.json. Servers match on a URL, a stdio command array, or a name; a deny entry always wins; and any server matching no allow entry is blocked. It is generally available and it is the mechanism GitHub recommends over a private registry. The details below come from GitHub's enterprise documentation for Copilot on GitHub Enterprise Cloud.
Before the allowlist does anything
Neither prerequisite is in the allowlist file.
The MCP servers in Copilot policy has to be enabled for the enterprise, or for the organizations where MCP should run. That policy is the switch for MCP at all. If the enterprise currently restricts MCP to a custom registry, GitHub recommends turning that restriction off first, setting Restrict MCP access to registry servers to Allow all and clearing the MCP Registry URL, so the allowlist is the single source of truth.
Where the file lives
managed-settings.json is deployed three ways, and they differ in where the file is read from and who it reaches.
Server-managed is the default for most enterprises. Create a .github-private repository, add copilot/managed-settings.json, and commit to the default branch. It applies to every client, including the cloud agent, for users who receive a Copilot license from your enterprise, and changes reach clients within about an hour, or immediately on a restart or sign-in. Per-team overrides work through copilot/team-mappings.json and files under copilot/teams/, for keys marked {"overridable": "<default>"}.
MDM applies to local clients regardless of where the license comes from, and ships values rather than a file: strings under HKEY_LOCAL_MACHINE\SOFTWARE\Policies\GitHubCopilot on Windows, forced managed preferences in the com.github.copilot domain on macOS, with dot-separated keys and JSON text for arrays and objects. Linux has no native MDM path.
File-based delivery uses these paths:
| Operating system | File location |
|---|---|
| macOS | /Library/Application Support/GitHubCopilot/managed-settings.json |
| Windows | %ProgramFiles%\GitHubCopilot\managed-settings.json |
| Linux | /etc/github-copilot/managed-settings.json |
For Copilot CLI on macOS and Linux the file has to be a regular file owned by root, not group- or world-writable, and not a symbolic link. The CLI rejects anything else, which is a useful property: the policy is either in force or visibly absent.
Writing the list
{
"allowedMcpServers": [
{ "serverUrl": "https://api.githubcopilot.com/*" },
{ "serverCommand": ["npx", "-y", "@playwright/mcp@latest"] }
],
"deniedMcpServers": [
{
"serverCommand": [
"npx",
"-y",
"@modelcontextprotocol/server-filesystem",
"/"
]
}
]
}
Match remote servers by serverUrl and local servers by the exact serverCommand array. Entries are compared as arguments, so ["npx", "@playwright/mcp@latest"] is a different entry from ["npx", "-y", "@playwright/mcp@latest"].
Evaluation order
Clients apply the list in a documented order:
- Built-in default servers, such as the built-in GitHub MCP server, are always allowed.
- A server matching any
deniedMcpServersentry is blocked. - If
allowedMcpServersis present, a server matching no entry is blocked. - A server whose URL or command contains an unresolved variable, such as
${VARIABLE}, is blocked, because the client cannot verify it.
When a client receives settings from more than one deployment method, all of them apply. A deny from any source blocks the server, and a server has to match an allow entry at every layer that defines one. Both documented failure modes are conservative: a malformed file is treated as an empty allowedMcpServers list, which blocks everything except built-in defaults, and a client that cannot determine a policy layer keeps the previously enforced policy, so it can become stricter but not looser.
Connectors are remote MCP servers
If you do not define allowedMcpServers, connectors are allowed unless a deny entry matches. The moment you define an allowlist, connectors are blocked unless their URLs match an entry, which surprises people who wrote a list for locally configured servers only. The wildcard covering every current and future connector is:
{
"allowedMcpServers": [
{ "serverUrl": "https://api.github.com/copilot-connectors/api/v1/connectors/*/mcp" }
]
}
Combine that with deniedMcpServers entries for the connectors you do not want. Deny takes precedence, so the pair allows the catalog and blocks the exceptions.
What the allowlist does not cover
Repository custom agent profiles. GitHub states that allowedMcpServers and deniedMcpServers apply to servers defined in user settings and repository settings, and do not apply to servers defined in repository custom agent profiles. The documented workaround is to stop those servers from starting by making sure the domains they need are not allowed by the organization or repository-level custom firewall. That is a network control doing the work of a configuration control, and it only holds if the firewall policy is set.
The private registry route, mostly. Registry enforcement is in public preview, is not the recommended method, matches on server name or ID only, and GitHub states that it can be bypassed by editing configuration files. Strict enforcement that prevents installation of non-registry servers is not available, and registry enforcement does not apply to Copilot in the cloud. If you use it, treat it as a naming convention rather than a boundary.
Local session content. The Copilot audit log covers Copilot settings, policy and license events plus agent activity on GitHub.com, retained 180 days and streamable to a SIEM. GitHub's documentation is specific about the boundary: the audit log does not include client session data such as the prompts a user sends to Copilot locally, and it suggests a custom solution such as Copilot CLI hooks that send events to your own logging service. Those Copilot CLI hooks run synchronously and can block execution, which makes them the natural place to add local decisions to a record.
Other agents. The allowlist governs Copilot clients. The Codex CLI, Cursor and Claude Code on the same laptop keep their own configuration, and their MCP servers, including stdio servers that never touch the network, are outside this file.
Two more managed keys
The same file carries permissions.disableBypassPermissionsMode, which disables bypass or allow-all behavior on clients that support it, and sandbox, which enforces minimum local sandbox restrictions for command execution, filesystem and network access, credentials, and local MCP and LSP servers. Unlike the allowlist, sandbox and the permissions keys compose in the most restrictive direction across deployment methods, so an MDM policy that tightens them cannot be loosened by a server-managed file. telemetry configures OpenTelemetry export so Copilot usage data reaches a collector you control.
Checking that it took effect
Server-managed settings are validated automatically. Open the enterprise, then AI controls, then the Agents tab, and look for the Copilot settings validation section. Each issue names the affected file and JSON path, and the section is absent when the configuration is clean. On a client, test a server you allowed and one you did not on the surfaces you deploy.
Where Alyria Beacon adds a layer
Alyria Beacon runs beside Copilot as a signed, user-space agent on macOS, Linux and Windows, with no kernel driver, and installs read-only in monitor mode first. It inventories every AI tool, version and MCP server configured on the endpoint, including the stdio servers the allowlist matches but no network control observes, and keeps that inventory current across Copilot, Codex, Cursor and Claude Code. Lyra policy is evaluated locally on every model and tool call, so a rule applies to the local agent activity GitHub's audit log says it does not record, and each decision is signed into one hash-chained audit chain that Spectra routes to your SIEM over OpenTelemetry. Umbra brokers short-lived credential leases so an agent uses a credential at the moment of use rather than holding the standing key.
Keep the allowlist and keep it current; it is the right control for the client it governs.
A rollout order
- Enable MCP servers in Copilot, and retire registry-only restriction so one mechanism is authoritative.
- Publish
allowedMcpServersanddeniedMcpServersincopilot/managed-settings.json, matching URLs and exact command arrays. - Cover connectors deliberately, by wildcard plus denies or entry by entry.
- Add
permissions.disableBypassPermissionsModeandsandboxin the same file, and confirm client versions that support them. - Publish the firewall rule that stops custom agent profile servers, or accept that profile-defined servers run.
- Inventory the fleet read-only, and compare what is installed with what you approved.
Frequently asked questions
Does the allowlist block a server a developer already configured? Yes, on clients that enforce your restrictions: a server matching no allow entry is blocked when allowedMcpServers is present. The exceptions are the surfaces GitHub names, which include servers defined in repository custom agent profiles.
Should we use the private registry instead? GitHub does not recommend it. It is in public preview, matches by name or ID, can be bypassed by editing configuration files, and does not apply to Copilot in the cloud. Use managed-settings.json, and keep a registry for discovery if it helps.
How long until a settings change reaches a laptop? About an hour for server-managed settings, with a client restart or fresh sign-in forcing an immediate refresh. MDM clients check hourly, and file-based settings load when the client restarts.
Do we still need endpoint tooling if the allowlist covers Copilot? If Copilot is the only agent on your laptops, the allowlist plus the audit log may be enough. Where developers also run the Codex CLI, Cursor or Claude Code, the allowlist does not see those servers, and that is the gap an endpoint collector fills.
/integrations/github-copilot lists the Copilot controls beside the endpoint layer. Keeping coding agents away from .env files, SSH keys and cloud credentials covers the read side that no MCP allowlist addresses.