MCP servers extend what GitHub Copilot can do by connecting it to external tools and data sources. Think of MCP as a plugin system for AI tools — it's a standard protocol that lets any MCP-compatible server provide new capabilities to Copilot.
This guide covers:
- What Is MCP?
- How MCP Works with Copilot
- Configuration Locations
- Configuring MCP Servers
- Managing MCP Servers in Copilot CLI
- Common MCP Server Examples
- MCP in Custom Agents
- Precedence & Loading Order
- Security Considerations
- Tips & Best Practices
- Further Reading
The Model Context Protocol (MCP) is an open standard that defines how AI agents communicate with external tool servers. It was created by Anthropic and has been widely adopted across the AI ecosystem.
An MCP server is a process (local or remote) that exposes tools — functions that the AI agent can call. For example:
- A database MCP server might expose
query,insert, andschematools - A GitHub MCP server might expose
list_issues,create_pr, andsearch_codetools - A Slack MCP server might expose
send_messageandlist_channelstools
Copilot CLI ships with the GitHub MCP server built in, giving it native access to your repos, issues, PRs, and more. You can add additional MCP servers to extend its capabilities.
┌──────────────┐ ┌──────────────────┐
│ Copilot CLI │ ──MCP──▶│ MCP Server │
│ (AI Agent) │◀────── │ (Tool Provider) │
└──────────────┘ └──────────────────┘
│ │
│ "Call the query tool" │
│ ──────────────────────▶ │
│ │ Executes query
│ Returns results │
│ ◀────────────────────── │
│ │
│ Uses results in │
│ response to user │
- You configure MCP servers in a JSON config file
- Copilot CLI starts the MCP server process (or connects to a remote one)
- The server advertises its available tools
- When relevant, Copilot calls these tools to accomplish tasks
- Tool results are fed back into the conversation context
| Scope | File | Description |
|---|---|---|
| Project | .mcp.json (repo root) |
MCP servers for this repo only |
| Project (alt) | .github/mcp.json |
Alternative project location |
| Personal | ~/.copilot/mcp-config.json |
Your global MCP servers |
| Agent-specific | Inside .agent.md frontmatter |
MCP servers for one agent only |
| Plugin | Referenced in plugin.json |
MCP servers bundled with a plugin |
| CLI flag | --additional-mcp-config |
Override at launch time |
Create a .mcp.json file in your project root:
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["-y", "@example/mcp-server"],
"env": {
"API_KEY": "${MY_API_KEY}"
}
}
}
}| Field | Type | Description |
|---|---|---|
command |
string | Command to run the server (for local/stdio servers) |
args |
string[] | Arguments passed to the command |
cwd |
string | Working directory for the server process |
env |
object | Environment variables (supports ${VAR} expansion) |
url |
string | URL for HTTP/SSE remote servers |
headers |
object | HTTP headers for remote servers (e.g., auth tokens) |
tools |
string[] | Which tools to expose (["*"] for all) |
timeout |
number | Connection timeout in milliseconds |
Local (stdio) — runs as a subprocess:
{
"mcpServers": {
"sqlite": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-sqlite", "./mydb.db"]
}
}
}Remote (HTTP/SSE) — connects to a URL:
{
"mcpServers": {
"remote-api": {
"url": "https://mcp.example.com/sse",
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}
}
}
}Use the /mcp command in Copilot CLI:
/mcp
This lets you:
- View configured MCP servers and their status
- Add new MCP servers
- Remove servers
- Test connectivity
/mcp add
Follow the interactive prompts to configure a new server.
Use /env to see all loaded MCP servers:
/env
This shows which servers are active, their tools, and the config source.
Copilot CLI ships with the GitHub MCP server by default. It provides tools like:
list_issues,create_issue,search_issueslist_pull_requests,create_pull_request,get_pull_request_diffsearch_code,get_file_contentslist_commits,get_commit
No configuration needed — it's always available.
Access files outside the working directory:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
}
}
}{
"mcpServers": {
"sqlite": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-sqlite", "./database.db"]
}
}
}{
"mcpServers": {
"brave-search": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-brave-search"],
"env": {
"BRAVE_API_KEY": "${BRAVE_API_KEY}"
}
}
}
}The Playwright MCP server (@playwright/mcp) gives Copilot the ability to control a real web browser — navigate pages, click elements, fill forms, take screenshots, and read page content. It uses Playwright's accessibility tree (not screenshots), making it fast, deterministic, and LLM-friendly.
Add to your .mcp.json or ~/.copilot/mcp-config.json:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
}Or add it interactively in Copilot CLI:
/mcp add
Pass options as additional args:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--browser", "chrome",
"--headless"
]
}
}
}| Option | Description |
|---|---|
--browser |
Browser to use: chrome, firefox, webkit, msedge |
--headless |
Run headless (no visible window) — great for CI |
--device |
Emulate a device, e.g., "iPhone 15" |
--port |
Run as SSE server on a port (for remote use) |
--caps vision |
Enable screenshot/vision capabilities |
--isolated |
Keep browser profile in memory only |
--ignore-https-errors |
Useful for testing against self-signed certs |
--storage-state |
Load saved auth state (cookies, localStorage) |
Once configured, Copilot gets access to browser automation tools:
| Tool | Description |
|---|---|
browser_navigate |
Navigate to a URL |
browser_snapshot |
Get accessibility snapshot of the page (structured) |
browser_click |
Click an element by reference |
browser_type |
Type text into an input field |
browser_fill_form |
Fill multiple form fields at once |
browser_select_option |
Select dropdown options |
browser_take_screenshot |
Capture a screenshot |
browser_press_key |
Press keyboard keys |
browser_hover |
Hover over an element |
browser_evaluate |
Run JavaScript on the page |
browser_wait_for |
Wait for text, element, or timeout |
browser_tabs |
Manage browser tabs |
browser_network_requests |
Inspect network traffic |
browser_console_messages |
Read browser console output |
This is where Playwright MCP really shines. You can ask Copilot to test your web application interactively — like having a QA tester who can also write code.
Start your server, then ask Copilot:
Start a browser, navigate to http://localhost:3000, and verify
the page shows "Hello, World!". Check there are no console errors.
Copilot will:
- Use
browser_navigateto open your app - Use
browser_snapshotto read the page content - Use
browser_console_messagesto check for errors - Report the results
Test the login flow:
1. Navigate to http://localhost:3000/login
2. Fill in email "test@example.com" and password "secret123"
3. Click the "Sign In" button
4. Verify we're redirected to the dashboard
5. Check the page shows "Welcome, Test User"
Copilot uses browser_fill_form, browser_click, browser_wait_for, and browser_snapshot to execute each step.
Test our homepage on iPhone 15:
1. Navigate to http://localhost:3000
2. Take a screenshot
3. Check that the navigation menu is a hamburger icon
4. Click the hamburger menu and verify the nav links appear
Use the --device "iPhone 15" option to emulate mobile viewport and user agent.
Test the signup form validation:
1. Go to /signup
2. Submit the form empty — verify error messages appear
3. Enter an invalid email — verify the email error
4. Fill everything correctly — verify successful submission
Navigate to /dashboard and monitor network requests.
Verify that:
1. An API call is made to /api/user/profile
2. The response status is 200
3. The dashboard displays the user's name from the API response
Copilot uses browser_network_requests to inspect the traffic.
You can also ask Copilot to write Playwright test files based on what it discovers:
Navigate to our app at http://localhost:3000 and explore the main
user flows. Then write Playwright test files (using @playwright/test)
that cover:
1. Homepage loads correctly
2. Navigation works
3. Search functionality
Write the tests to tests/e2e/ directory.
Copilot will use the browser to explore your app, understand its structure via accessibility snapshots, and then generate proper Playwright test code.
Microsoft also offers a Playwright CLI with Skills approach:
| Playwright MCP | Playwright CLI + Skills | |
|---|---|---|
| Approach | MCP tools, persistent browser session | CLI commands via skills |
| Token efficiency | Higher token usage (tool schemas + accessibility trees) | More token-efficient (concise CLI output) |
| Best for | Exploratory testing, long-running sessions, interactive debugging | High-throughput coding agents, large codebases |
| Browser context | Maintained across tool calls | Per-command |
Recommendation: Use MCP for interactive/exploratory testing and debugging. Use CLI + Skills for automated test generation in large projects.
Combine a custom agent with the Playwright MCP server for a dedicated QA agent:
.github/agents/qa-tester.agent.md:
---
name: qa-tester
description: QA testing agent that uses a real browser to test web applications
tools: ["playwright/*", "read", "edit", "shell"]
mcp-servers:
playwright:
command: npx
args: ["@playwright/mcp@latest", "--headless"]
---
You are a QA testing specialist. You test web applications using a real browser.
## Your Workflow
1. Start the app if it's not running (check with a quick HTTP request first)
2. Navigate to the app in the browser
3. Systematically test all user-facing functionality
4. Check for console errors, broken links, and accessibility issues
5. Report findings with screenshots for any issues found
6. Write Playwright test files for the flows you tested
## Testing Priorities
1. Critical user paths (login, signup, main features)
2. Form validation and error handling
3. Responsive design (test at different viewports)
4. Console errors and network failures
5. Accessibility (check for proper ARIA labels, keyboard navigation)Select this agent with /agent in Copilot CLI or from the VS Code agents dropdown.
Write your own MCP server in any language:
{
"mcpServers": {
"my-internal-tools": {
"command": "node",
"args": ["./tools/mcp-server.js"],
"cwd": ".",
"env": {
"DATABASE_URL": "${DATABASE_URL}"
}
}
}
}You can attach MCP servers to specific custom agents via their .agent.md frontmatter:
---
name: database-agent
description: Database specialist with direct SQL access
tools: ["sqlite/query", "sqlite/schema", "read", "edit"]
mcp-servers:
sqlite:
command: npx
args: ["-y", "@modelcontextprotocol/server-sqlite", "./app.db"]
---
You are a database specialist...This way, the MCP server only runs when this specific agent is selected.
When multiple configs define the same server name, last wins:
1. ~/.copilot/mcp-config.json ← lowest priority
2. Plugin MCP configs ← mid priority
3. .mcp.json / .github/mcp.json ← project level
4. Agent-specific mcp-servers ← agent level
5. --additional-mcp-config flag ← highest priority (override)
This is the opposite of agents/skills (which use first-wins). The rationale: project-level configs should override global defaults.
Never hardcode API keys or tokens in .mcp.json. Use environment variable references:
{
"env": {
"API_KEY": "${MY_SECRET_KEY}"
}
}MCP servers can execute arbitrary code. Before adding a server:
- Review its source code
- Check its npm/GitHub reputation
- Understand what tools it exposes
- Consider the principle of least privilege
Use the tools field to limit which tools a server exposes:
{
"mcpServers": {
"database": {
"command": "...",
"tools": ["query", "schema"]
}
}
}This is safer than "tools": ["*"].
If your .mcp.json references secrets via environment variables, that's fine. But don't commit actual secret values. Consider adding a .mcp.json.example and .gitignore-ing the real one if it contains sensitive paths.
- Start with the built-in GitHub MCP server — it's already configured and covers most GitHub workflows
- Use
npx -yfor official servers — no installation needed, always up-to-date - Scope MCP servers to agents when possible — don't load database tools for every task
- Test connectivity with
/mcp— verify servers are running before relying on them - Use environment variables — never hardcode secrets
- Check
/env— see what's actually loaded in your session - Use
--additional-mcp-configfor temporary overrides without modifying project config
VS Code stable + the GitHub Copilot Chat extension supports MCP servers out of the box.
| Scope | File / Setting |
|---|---|
| Workspace | .vscode/mcp.json |
| User | User settings.json → "mcp": { "servers": { ... } } (or MCP: Add Server… command) |
| Built-in | The GitHub MCP server is registered automatically |
The JSON shape inside .vscode/mcp.json mirrors .mcp.json:
{
"servers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
}
}
}Naming gotcha: VS Code uses
"servers"while Copilot CLI uses"mcpServers"— copy the structure carefully when porting between the two.
- MCP: List Servers — Command Palette command, shows status per server.
- MCP Servers view in the sidebar — start, stop, restart, view available tools.
- MCP: Add Server… — interactive walkthrough that writes the right config.
- Setting
chat.mcp.enabled(defaulttrue) — master enable/disable. - Setting
chat.mcp.discovery.enabled— auto-discover MCP servers from other tools' configs (e.g. Claude Desktop).
In Agent mode, MCP tools become regular tools the agent can call. You can also bias the agent toward a particular tool or server:
#tool:server-name/tool-name— "use this specific tool"#mcp:server-name— "prefer tools from this server"
User-level MCP config and workspace .vscode/mcp.json are merged. If the same server name is defined in both, workspace wins — same intuition as project-level .mcp.json overriding ~/.copilot/mcp-config.json in CLI.
| CLI | VS Code (Copilot Chat) |
|---|---|
.mcp.json (mcpServers) |
.vscode/mcp.json (servers) |
~/.copilot/mcp-config.json |
User settings.json → mcp.servers |
/mcp |
MCP: List Servers + MCP Servers view |
/mcp add |
MCP: Add Server… |
--additional-mcp-config |
No direct equivalent — edit user/workspace settings |