Large Language ModelsGenerate imagesGenerate videos

GitHub Copilot MCP Server Setup: Registry, Allowlist and Config

Connect MCP servers to GitHub Copilot without the guesswork. See where mcp.json lives, how the GitHub MCP Registry works, how admins enforce allowedMcpServers and deniedMcpServers in managed settings, and how to fix the errors that silently block your tools.

GitHub Copilot MCP Server Setup: Registry, Allowlist and Config
Cristian Da Conceicao
Founder of Picasso IA

Your first MCP server in GitHub Copilot connects in about two minutes. Getting that same server approved by security, listed in a registry and pinned to an allowlist takes the rest of the week, unless you know which setting does what. This article follows the three layers in order: the config file a developer writes, the registry a team browses, and the allowlist an admin enforces. Every JSON sample matches the current GitHub and VS Code documentation, and every limitation is flagged exactly where it bites.

💡 Short version: developers write mcp.json, teams pick servers from a registry, and admins enforce allowedMcpServers in managed-settings.json. Three files, three owners, and a bug in any one of them looks like "Copilot has no tools."

What MCP Does Inside Copilot

Hands plugging a cable into a laptop port

The Model Context Protocol (MCP) is the open standard that lets Copilot call tools that live outside the editor: a database query, a Sentry issue lookup, a browser session, a ticket tracker. Without MCP, Copilot only sees what your editor shows it. With MCP, agent mode can read the failing issue, query the data behind it, then edit the code that caused the problem, all in one conversation.

Each server exposes tools, and Copilot asks for your approval before the agent runs one. Local servers talk over stdio, meaning Copilot launches a process on your machine. Remote servers talk over streamable HTTP or the older SSE transport, meaning Copilot connects to a URL. That single difference, a command versus a URL, drives almost every setup decision later: it decides which JSON fields you write, how authentication works and how an allowlist can match the server.

Which Clients Support It

MCP setup is not identical across Copilot surfaces. The file and the format change at each one:

Copilot surfaceWhere the config livesFormat notes
VS Code workspace.vscode/mcp.jsonservers, plus optional inputs
VS Code user profileMCP: Open User ConfigurationSame format, applies to every workspace
Portable files.mcp.json in the workspace root, or ~/.copilot/mcp-config.jsonListed in the VS Code reference as the portable format
Copilot CLI~/.copilot/mcp-config.json, or /mcp add in a sessionAdd servers without leaving the terminal
Copilot cloud agentRepository settings on GitHubmcpServers, plus a required tools list

Config Files and Where They Live

Flat lay of a developer desk with folders and notebook

Put the file in the wrong place and Copilot ignores it without a loud error. Start by deciding who should get the server.

Workspace vs User Scope

.vscode/mcp.json lives in the repository, so everyone who clones it gets the same servers. That makes it the right home for project tools such as a database inspector or a Playwright browser. Your user profile config applies to every workspace on your machine. Open it from the Command Palette with MCP: Open User Configuration and keep personal tools there.

A simple rule works: if a teammate would be confused by the server's absence, commit it. If only you use it, keep it in your profile.

Portable Files for Other Clients

The VS Code MCP configuration reference also lists a portable format: .mcp.json in the workspace root, or ~/.copilot/mcp-config.json for your user. Reach for it when the same repository is opened from more than one Copilot client and you want one definition instead of three.

Every server entry is built from the same small set of fields:

FieldApplies toPurpose
typeAll serversstdio, http or sse
command, argsstdioThe executable and its arguments
env, envFilestdioEnvironment variables inline or from a file
cwdstdioWorking directory for the process
urlhttp, sseThe server endpoint
headershttp, sseStatic headers, such as an Authorization header
oauthhttp, sseOAuth settings object
devstdioDevelopment mode, including dev.watch restart patterns

Two extras exist on macOS and Linux only: a top-level sandbox object (file system and network rules) and a per-server sandboxEnabled switch.

Write Your First mcp.json

Over-the-shoulder view of a developer typing config

You can write the file by hand or run MCP: Add Server from the Command Palette and let VS Code generate the entry. Writing it once by hand is worth it, because every later problem is easier to spot when you know what a healthy file looks like.

A Local stdio Server

This entry launches the Playwright MCP server through npx whenever Copilot needs it:

{
  "servers": {
    "playwright": {
      "type": "stdio",
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}

Save the file and VS Code shows Start, Stop and Restart actions above the entry. Start it, open Copilot Chat in agent mode, and check the tools picker: the server's tools should now be listed and ready to switch on.

A Remote HTTP Server

A remote server needs a URL instead of a command. This one points at the hosted GitHub MCP server:

{
  "servers": {
    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/"
    }
  }
}

If the server supports OAuth, VS Code opens a sign-in flow the first time a tool runs. If it expects a static token, send it through headers, and never paste the token itself into a committed file.

Keep Secrets Out of Config

A steel vault door with a padlock

VS Code solves this with input variables. You declare an input once, mark it as a password, and reference it with ${input:id}:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "sentry-token",
      "description": "Sentry auth token",
      "password": true
    }
  ],
  "servers": {
    "sentry": {
      "type": "stdio",
      "command": "npx",
      "args": ["@sentry/mcp-server@latest"],
      "env": { "SENTRY_TOKEN": "${input:sentry-token}" }
    }
  }
}

VS Code asks for the value the first time the server starts, so the repository only ever contains the placeholder. Inputs come in three types: promptString for typed text, pickString for a dropdown, and command for a value produced by running a command. Each input needs a type, an id and a description.

💡 A committed .vscode/mcp.json with a pasted token is the most common MCP leak. If you use envFile, add that file to .gitignore in the same commit.

Find Servers in the Registry

Wooden card catalogue with drawers

Hand-writing JSON for every server gets old fast. The registry exists so you don't have to.

The GitHub MCP Registry

github.com/mcp lists servers from the community that connect models to files, APIs and databases. At the time of writing it shows 375 servers, from Microsoft's Markitdown to Stripe and Figma, each with an Install button. Installing adds an entry to your config, so read it before you start the server: check the command, the package name and the URL.

VS Code also lists MCP servers inside the editor. Type @mcp in the Extensions view search box to browse them, install one, and VS Code adds the entry to your user or workspace config. Treat a registry listing as a starting point, not a security review.

Run Your Own Registry

Organizations can host their own MCP registry and point Copilot at it. If you build it on Azure API Center, enter the base URL in this shape:

https://SERVICE-NAME.data.REGION.azure-apicenter.ms/workspaces/WORKSPACE-NAME

Do not add a route suffix such as /v0.1/servers. Copilot appends the MCP v0.1 path itself, and a suffix makes the registry error out. Enterprise owners set the URL under AI controls, then MCP. Organization owners set it under Copilot, then Policies.

Lock Servers Down With Allowlists

Office lobby with badge turnstiles

Admins have two ways to decide which servers developers may run. They are not equal, so pick on purpose.

managed-settings.jsonRegistry only policy
StatusGenerally available since August 6, 2026Public preview
Where it livescopilot/managed-settings.json in .github-privateEnterprise AI controls, or organization Copilot policies
Matches onServer URL, local command or nameName or ID
Weak spotFails closed on bad configUsers can edit config files to dodge it
Enforced inGitHub Copilot app, Copilot CLI, VS CodeSupported IDEs and Copilot CLI

GitHub's own docs call managed settings the more secure, generally available method, and describe the registry policy as not the recommended one.

The Managed Settings Method

Add either or both of allowedMcpServers and deniedMcpServers to copilot/managed-settings.json in your organization's .github-private repository, then commit to the default branch:

{
  "allowedMcpServers": [
    { "serverUrl": "https://api.githubcopilot.com/*" },
    { "serverCommand": ["npx", "@playwright/mcp@latest"] }
  ],
  "deniedMcpServers": [
    { "serverUrl": "https://untrusted.example/*" }
  ]
}

There are three matcher types:

  • serverUrl matches remote HTTP and SSE servers, supports * wildcards and canonicalizes URLs to prevent evasion.
  • serverCommand matches a local stdio server by its exact command and arguments.
  • serverName matches the label a user typed in their config. It is a convenience, not a security boundary.

How Matching Works

Copilot evaluates a server in a fixed order:

  1. Built-in defaults are always permitted.
  2. The deny list blocks anything that matches.
  3. If an allowlist exists, the server must match an entry or it is blocked.
  4. Any unresolved ${VARIABLE} in the config blocks the server.

With no allowlist at all, a server runs unless it is denied or contains an unresolved variable. When several managed-settings.json sources apply, every setting applies and a deny rule from any source blocks the server. You can mark settings overridable so a team can customize its own layer.

💡 Command matching is exact. If you allow ["npx", "@playwright/mcp@latest"], a developer who runs npx -y @playwright/mcp@latest does not match, because the arguments differ. Publish the exact entry you want people to copy.

The Registry Only Policy

Still on the preview path? Enable the MCP servers in Copilot policy, enter your registry URL, then set Restrict MCP access to registry servers to Registry only. The change applies immediately. Because it matches on name or ID, treat it as a guardrail for honest mistakes, and move high-risk environments to managed settings. The full steps are in GitHub's MCP access documentation.

Cloud Agent and CLI Setup

A long data center aisle with server racks

The Copilot cloud agent (formerly the coding agent) runs on GitHub's infrastructure, so it cannot read your local .vscode/mcp.json. It has its own configuration, and that is where most copy-paste mistakes happen.

Open the repository, go to Settings, choose Copilot under Code & automation, and edit the MCP configuration box:

{
  "mcpServers": {
    "sentry": {
      "type": "local",
      "command": "npx",
      "args": ["@sentry/mcp-server@latest"],
      "tools": ["list_issues"],
      "env": { "SENTRY_TOKEN": "$COPILOT_MCP_SENTRY_TOKEN" }
    }
  }
}

Five rules separate this from the VS Code format:

  • The top-level field is mcpServers, not servers.
  • type accepts local, stdio, http or sse.
  • tools is required. Use ["*"] for everything, or list tool names to keep the agent on a short leash.
  • Secrets must be added as agent secrets or variables whose names start with COPILOT_MCP_, and the config must reference those exact names.
  • Only tools are supported, and remote servers cannot use OAuth.

The GitHub and Playwright MCP servers are already enabled in every repository, so you only add what is missing. Read the cloud agent MCP documentation before adding anything that writes data.

Copilot CLI. The CLI reads ~/.copilot/mcp-config.json. Inside an interactive session, /mcp add walks you through adding a server without editing JSON by hand. Allowlists from managed settings are enforced here too, so a server that works in VS Code but is blocked in the terminal usually points at a policy mismatch, not a broken install.

Fix Common Errors Fast

A developer frowning at a laptop at night

Most failures come down to five causes. Match your symptom to the table before you reinstall anything.

SymptomLikely causeFix
Server never shows in VS CodeTop-level field is mcpServersRename it to servers
Server starts, picker shows no toolsTools switched off in the pickerEnable the tools in agent mode
Cloud agent ignores a tooltools list missing or too narrowAdd the tool name or ["*"]
Cloud agent sees an empty secretName lacks COPILOT_MCP_Rename the secret and the reference
Works for you, blocked for a teammateAllowlist entry does not matchCompare URL, command and arguments

Server Starts but No Tools

Run MCP: List Servers, pick the server and open its output. A crash on launch usually shows a missing runtime (Node or Python not on the path) or a wrong package name. If the process is healthy, open the tools picker in agent mode and confirm the tools are switched on.

Blocked by Policy

A blocked server almost always has one of three causes: the allowlist exists and nothing matches, a deny rule from another managed-settings.json source applies, or the config contains an unresolved ${VARIABLE}. Because policies fail closed, a malformed settings file blocks servers instead of letting them through. Ask the admin which source blocked it before you edit your own config.

Pasted snippets from other clients. A snippet copied from another MCP client's docs almost always uses mcpServers. Paste it into .vscode/mcp.json and nothing loads, with no complaint. Rename the field, add type explicitly, and move secrets to inputs while you are there.

Put PicassoIA to Work

Four colleagues reviewing a document at a table

A second pair of eyes catches the boring bugs: a wrong field name, a missing tools list, an argument that breaks an exact match. You can get one in a minute.

Use Claude Sonnet 5 on PicassoIA

Claude Sonnet 5 reads config, reasons through multi-step problems and accepts an image, so it suits this job well. Here is a repeatable way to use it:

  1. Open the Claude Sonnet 5 page on PicassoIA.
  2. In System Prompt, set the role once: "You review GitHub Copilot MCP configs. Check the top-level field, the transport type, the tools list, secret handling and exact-match allowlist entries."
  3. Paste your mcp.json or managed-settings.json into Prompt. Replace every real token with a placeholder first.
  4. Set Effort to high for allowlist logic. The default low is fine for a typo check and returns in seconds.
  5. Leave Max Tokens at 8192, which is plenty for a full review.
  6. Attach a screenshot of the error in the Image field if you have one, since the model reads images.
  7. Run it, then apply the fixes one at a time and restart the server after each.

For a second opinion, send the same prompt to GPT 5.6 Sol, Gemini 3.1 Pro or Kimi K2.6 and compare where they disagree. Disagreement usually marks the line worth reading yourself.

Make Your Own Images Next

Rolling this out to a team means a wiki page, a slide for the security review and a header image that doesn't look like stock clip art. Picasso IA generates all of it from a text prompt. Try Qwen Image 3 for photorealistic scenes, Seedream 5 Pro for sharp 2K output, or GPT Image 2.5 Flare when you need a fast draft. Describe the scene, pick a 16:9 ratio, and iterate until it fits your doc. Open Picasso IA, write your first prompt, and see what your next rollout post looks like with a real header image.

Share this article