GitHub Copilot MCP: Complete Guide
Everything so far in this cluster keeps Copilot inside your repository. MCP is how it reaches outside — your issue tracker, your monitoring, your database, your internal services.
That is the value and the entire problem. An agent that can read your repository gets things wrong locally. An agent that can call your deployment API gets things wrong in production.
Key takeaways
- MCP is a protocol, not a GitHub feature. Servers written for it work with any client that speaks it.
- A server exposes tools, resources and prompts. In practice, tools are what agents use.
- Configuration differs per client in ways that break copied examples — the most common failure is a VS Code file that Copilot CLI does not read.
- Tool permissions are the security model. Not the server, not the protocol.
- Organisation policy gates MCP for Copilot Business and Enterprise.
What MCP is
Before MCP, connecting an AI assistant to an external system meant a bespoke integration per assistant per system. Model Context Protocol replaces that with one interface: a server describes what it can do, a client asks it to do things, and neither needs to know anything specific about the other.
The consequence worth internalising is that MCP is not a Copilot feature. It is an open protocol with an ecosystem. A server built for one agentic tool works with Copilot; a server you write for Copilot works elsewhere. That portability is the reason to learn the protocol rather than the client.
Copilot is one client among many. What Copilot adds is where configuration lives, how approval works, and which policies gate it — and those are exactly the parts that differ from other clients.
The three primitives
What a server can expose
- ToolsCallable functions that perform a task. The part agents actually use.
- ResourcesData and context drawn from an external system.
- PromptsInstructions and guidance supplied by the server.
In practice the distribution is lopsided.
Tools do the work. A tool is a function the agent can call: create_issue,
query_database, get_alert. Almost every server worth adding is worth adding
for its tools.
Resources supply context. Data the client can pull in — a document, a record, a dataset. Useful, and less universally supported than tools. The Copilot cloud agent in particular supports only tools.
Prompts are guidance from the server. The least-used primitive, and the one most likely to be absent from a given client’s implementation.
How a call actually flows
- You ask for somethingHuman judgementOrdinary request, no MCP vocabulary needed.
- Copilot sees the available toolsNames, descriptions and parameters from each configured server.
- It picks a tool and argumentsThis is a model decision, not a deterministic lookup.
- Approval, on surfaces that have itHuman judgementThe CLI prompts. The cloud agent does not.
- The server executesYour credentials, your network, the server's own permissions.
- The result returns as contextText the model reads — and text can contain instructions.
- Copilot continuesAnswer, another tool call, or a file change.
Steps marked Human judgement are the ones that do not get delegated — they are where you decide whether what Copilot produced is actually right.
Two steps in that sequence deserve more attention than they usually get.
Tool selection is a model decision. Copilot chooses a tool by matching your request against tool descriptions. Poorly described tools get picked wrongly, and two tools with similar descriptions get picked interchangeably. This is the same selection problem as agents and skills, in a place with more consequences.
The result becomes input. Whatever the server returns is text the model reads and acts on. If a server can return content that other people control — an issue body, a page title, a log line, a customer’s name — then that content is reaching the model as instructions-shaped text. This is the injection surface, and it is structural rather than a bug in any particular server.
Local and remote servers
Servers come in two shapes and the difference matters for both security and setup.
Local servers run as a process on your machine, usually started by the client and communicating over standard input and output. They have your machine’s access: your filesystem, your network, your credentials. A local filesystem server can read what you can read.
Remote servers run somewhere else and are reached over HTTP. They have whatever access their own credentials grant, and the authentication question becomes real — OAuth or a token, and where that token is stored.
The practical implication: choose servers with your target surface in mind. A remote OAuth server is a good choice for editor work and not an option for the cloud agent.
Configuration by client
| Client | Configuration | Authentication | Remote OAuth |
|---|---|---|---|
| VS Code | .vscode/mcp.jsonTop-level key is `servers`. This file is not read by Copilot CLI. | OAuth or personal access token for remote servers | Supported |
| Copilot CLI | ~/.copilot/mcp-config.json, .mcp.json, or .github/mcp.jsonDoes not read .vscode/mcp.json. Migrating one requires reformatting. | Per-server; the built-in GitHub server uses the CLI's own session | Not documented |
| Copilot cloud agent | JSON in repository settings on GitHubNot a file in the repository — configured by a repository administrator in settings. | Tokens supplied in configuration; the default GitHub server uses a read-only repo-scoped token | Not supported |
| Visual Studio, JetBrains, Xcode, Eclipse | Per-IDE MCP configuration | OAuth or personal access token for remote servers | Supported |
- VS Code. A Start button appears above the server list; starting a server discovers its tools and stores them for later sessions.
- Copilot CLI. The GitHub MCP server is built in and needs no configuration. `copilot mcp add` manages others.
- Copilot cloud agent. Only tools are supported — not resources or prompts. Copilot uses available tools autonomously without asking for approval.
- Visual Studio, JetBrains, Xcode, Eclipse. GitHub lists growing remote-server support across these editors.
4 client families, and the differences are not cosmetic.
VS Code reads .vscode/mcp.json, whose top-level key is servers. Starting a
server discovers its tools and stores them for later sessions.
Copilot CLI reads ~/.copilot/mcp-config.json, .mcp.json or
.github/mcp.json — and does not read .vscode/mcp.json. The GitHub MCP
server is built in and needs no configuration at all.
The cloud agent takes JSON in repository settings on GitHub, entered by a repository administrator. There is no file to commit.
Connecting MCP servers covers each client’s configuration in full, including the migration between formats.
Tool descriptions are an interface
A detail that surprises people the first time it bites: the quality of a server’s tool descriptions determines how well it works, and there is nothing you can do about it from your side.
Copilot chooses a tool by reading its name, description and parameter schema.
Those come from the server. A tool called query with the description “runs a
query” will be selected for things it should not be selected for, and skipped for
things it should handle, and no amount of clearer phrasing in your request fully
compensates.
This has three practical consequences.
Server quality is legible before you install. Look at the tool list. Are the names specific? Do the descriptions say when to use each one? Do they say what each one does not cover? A server whose descriptions are careful is usually careful elsewhere.
Overlapping tools across servers cause confusion. Two servers that both expose
something called search will be picked between arbitrarily. This is a strong
argument against running several servers covering the same ground.
Your own servers should invest here. If you write an internal server, the descriptions are the user interface. Write them the way you would write an agent’s description: what it does, when to use it, what it is not for.
The security model
MCP’s security is not in the protocol. It is in which tools you enable and what those tools can do.
| Tool | Class | What that means |
|---|---|---|
search_issues | Read only | Retrieves information. Nothing changes as a result. |
get_deployment_status | Read only | Retrieves information. Nothing changes as a result. |
create_issue | Mutating | Changes state inside the system it belongs to. Usually reversible. |
post_comment | Mutating | Visible to other people, and not really undoable once seen. |
trigger_deployment | External effect | Causes something to happen outside the system, often visible to other people. |
rotate_service_credential | Privileged | Changes who can do what. Rarely reversible without an audit trail. |
These four classes are this site's editorial framework for reasoning about tool permissions. GitHub does not publish a tool risk classification.
Reading that table is the exercise. A server is not safe or unsafe; its individual tools are, and the interesting question is always which of them you have actually enabled.
Prompt injection through MCP
This deserves its own treatment because MCP widens the injection surface considerably.
Your repository is content you mostly control. A server’s responses are frequently content other people control — issue bodies from external contributors, ticket descriptions from customers, page titles from the web, log lines containing user input. All of it arrives as text the model reads and acts on.
An attacker who can write into any system your MCP servers read has a channel into your agent’s instructions. That is not exotic; for a support-ticket server it is the normal operating condition.
Approval, and where it is absent
How a tool call gets approved varies more between surfaces than anything else in MCP, and the variation is exactly where risk concentrates.
Copilot CLI prompts per tool call. You see what it wants to run and decide. Patterns can pre-approve or pre-deny categories, which is the finest-grained control available anywhere in Copilot — Cluster 5 covers it in full.
IDEs sit in the middle. Servers are started deliberately, and changes appear as diffs you accept.
The cloud agent does not ask. GitHub states plainly that Copilot will use available MCP tools autonomously and will not ask for approval before use.
That last one is not a gap to be worked around; it is a design decision consistent with the surface, whose approval point is the pull request. But it means the configuration is the only control. A tool that should require a human decision must not be configured on that surface, because there is no moment at which the human decision would be requested.
When MCP is worth it
MCP has real costs — configuration, credentials, review, context consumed by tool descriptions, and a genuine increase in what can go wrong. It is worth paying when the context is otherwise unreachable.
Worth it: your issue tracker, when you routinely paste issue text into chat. Your monitoring, when debugging means correlating code with alerts. Your database schema, when the schema is the context the model keeps guessing wrong. Internal documentation the model cannot see.
Not worth it: anything the model already knows. Public API documentation. Something you look up twice a year. Anything where copying and pasting the text yourself is perfectly fine.
What MCP is not
Three misconceptions cause most of the wasted effort.
It is not a plugin system that makes Copilot smarter. Adding servers does not improve reasoning. It adds reach. A model that misunderstands your architecture will misunderstand it just as thoroughly with access to your monitoring, only now it can act on the misunderstanding.
It is not a substitute for context you could simply provide. If the relevant information is a paragraph, paste the paragraph. MCP earns its cost when the context is large, changes constantly, or has to be queried rather than recalled.
It is not a security boundary. The protocol carries no authorisation model of its own. What a server can do is decided by the credentials it holds and the tools it exposes, and what your agent can do is decided by which of those you enabled. Everything protective is a configuration choice, not a property of MCP.
A fourth, less common but more expensive: MCP is not a way to give an agent production access safely. There is no configuration that makes an autonomous system with deployment credentials a low-risk arrangement. The safe pattern is the one the DevOps agent lesson builds — read everything, validate everything, apply nothing.
Choosing servers
Start with GitHub’s own. The GitHub MCP server is the highest-value first addition for most teams, is built into Copilot CLI, and is covered in its own lesson.
Prefer the registry. The GitHub MCP Registry lists vetted servers, which narrows the trust problem without eliminating it.
Prefer official servers from the vendor whose system you are connecting to. A vendor’s own server is maintained and is accountable in a way a community fork is not.
Read the source when you cannot do either. For a small server this is twenty minutes. Look at what tools it exposes, what credentials it wants, and what it does with the responses.
Add one at a time. Ten servers added in one sitting means ten candidates to blame the first time something behaves oddly, and a large enough tool list to degrade selection.
Writing your own server
For internal systems, no public server exists and writing one is often the right answer. The protocol is small enough that a useful first server is an afternoon’s work, and the design decisions matter more than the code.
Start read-only. A server that answers questions about your internal systems — what is deployed, which team owns this service, what the schema looks like — is where most of the value is and carries almost none of the risk. Resist adding write tools until the read-only version has been used for a while.
Make each tool do one thing. A single execute tool taking arbitrary
instructions is easy to write and impossible to reason about. Ten specific tools
give you ten specific decisions about what to enable.
Write descriptions as the interface. Name the trigger conditions, say what the tool does not cover, and describe parameters in the vocabulary your team uses.
Validate arguments server-side. The arguments come from a model. Treat them the way you would treat arguments from a browser: constrain, validate, and reject rather than interpret.
Decide what the server’s own credentials are. This is the security design. A server with a read-only database role is a fundamentally different object from one with an admin connection, regardless of which tools it exposes today.
Return small results. Everything a tool returns enters the context window. A tool that dumps a hundred rows crowds out the conversation and degrades everything after it. Summarise, paginate, or return identifiers the agent can follow up on.
Organisation policy
Context cost
Every enabled tool has a presence in the request whether or not it is used: its name, its description, its parameter schema. A dozen servers with thirty tools each is a substantial standing cost before you have said anything.
The effects are worth naming because they are easy to misattribute.
Selection gets worse as the list grows. More candidates means more chances to pick a near-match. Teams often experience this as “MCP made Copilot less reliable” when what actually happened is that they enabled two hundred tools.
Long tool results crowd out the conversation. A tool returning a large payload pushes earlier context out, and the degradation shows up several turns later where nobody connects it to the tool call.
The cost is paid on every request, including the ones that had nothing to do with any server.
The remedy is the same control that helps security: enable the toolsets you need and no more. It is unusual for a control to improve both quality and safety, which is why this one is worth actually doing rather than noting.
Governing MCP as a team
Once more than one person configures servers, MCP becomes shared infrastructure with security consequences, and the questions are organisational rather than technical.
Who decides which servers are approved? Somebody should. The default — everyone adds what they like — produces an inconsistent, unreviewed surface where the same prompt behaves differently on different machines.
Where do credentials come from? A server holding a shared write-capable token is a shared write-capable token. Prefer per-person credentials with per-person scopes where the server supports it.
What is committed? Server configuration that should be shared belongs in the repository, reviewed like code. Credentials never do.
Who re-reviews? Servers update. A server that was read-only when approved may gain tools in a later version, and nothing announces that.
Debugging MCP
MCP failures are unusually opaque because most of them are silent, so a systematic order saves time.
Is the configuration in a file this client reads? First question, every time. The VS Code file and the CLI’s files are different files, and a configuration in the wrong place produces no error at all.
Does the client see the server? Each surface offers a way to list configured servers. If yours is not listed, the problem is configuration, not the server, and nothing downstream is worth investigating yet.
Did the server start? A local server is a process that can fail to launch — a missing runtime, a bad path, a dependency that is not installed. Client logs usually say so.
Does the server expose the tools you expect? A server that started may still be exposing nothing useful, most often because a toolset restriction is narrower than intended or a credential grants less than expected.
Is Copilot choosing the tool? If the server is present and the tools are listed and nothing gets called, this is a selection problem. Naming the tool explicitly in your request distinguishes “cannot” from “did not choose to” in one turn.
Is a policy blocking it? In a work account, check this before rewriting anything. A disabled organisation policy looks like a broken configuration from the inside.
What a good server looks like
After configuring a few, the differences between servers become obvious, and they are mostly not about features.
Specific tools rather than one general one. A server exposing get_alert,
list_alerts and search_logs gives you three decisions. One exposing query
with a free-form argument gives you none, and grants everything the underlying
system can do.
Descriptions that say when, not only what. “Retrieves an alert by ID. Use when a specific alert is named. Does not search — use search_logs for that” is a description that produces correct selection. “Gets an alert” is not.
Small, structured results. A tool returning ten fields is usable. One returning a hundred rows of raw output crowds out the conversation and degrades everything downstream.
Clear separation between read and write. A server whose read tools and write
tools are obviously distinguishable is one you can configure confidently. One
where update_status might or might not notify people is one you have to read the
source to use safely.
A documented credential model. What access does it need, and what does it do with it? A server that asks for broad credentials without explaining why is telling you something.
Where MCP sits against the alternatives
Before adding a server, it is worth checking whether something simpler covers the need — because three cheaper mechanisms overlap with MCP more than people expect.
Pasting. Still the right answer for a one-off. A paragraph of context in a message costs nothing to set up and cannot be misconfigured.
Instructions and skills. Content that is stable belongs in a file, not behind a tool call. If the schema you keep explaining changes twice a year, a skill is a better home for it than a database server.
A script the agent can run. Where a surface offers shell access, a small script that queries your system and prints a summary is often a complete substitute for a server — and it is easier to read, review and constrain than a server you did not write.
MCP earns its place when the context is large, changes constantly, must be queried rather than recalled, and is needed often enough that the setup amortises. That is a real category, and it is smaller than the enthusiasm suggests.
Common questions
Is MCP GitHub-specific? No. It is an open protocol and Copilot is one client among several, which is why a server you write for an internal system keeps working if your team later adopts a different agentic tool.
Can I write my own server? Yes, and for internal systems it is often the right answer, since no public server exists for the thing you actually want to reach. Start read-only and add write tools only when a concrete need appears.
Does MCP work in every Copilot surface? Support and configuration differ. The matrix in the pillar and the client table above record the current position.
How many servers is too many? Beyond a handful, tool descriptions consume a real and permanent amount of context, and selection degrades. Fewer, well-scoped servers beat comprehensive coverage.
Do MCP calls cost premium requests? The tool call itself is not a model request, but agentic loops that use tools consume requests per iteration. Cluster 6 covers the mechanics.
Can one server’s tools be scoped to one agent? Yes — the mcp-servers field on
an agent profile scopes configuration to that agent, which is the cleanest way to
keep a powerful server available to exactly one narrow role rather than to every
session.
Are MCP servers audited by GitHub? The GitHub MCP Registry lists vetted servers, which is a meaningful narrowing and not a guarantee about any particular server’s future versions.
What if a server stops working? Check whether the client reads the file you edited before checking anything else. Silent non-reading is the most common failure and looks identical to a broken server.
A sane default configuration
If you want a starting point rather than a framework, this is one that holds up.
One server: GitHub’s. It covers issues, pull requests and code search, which is where most of the context gaps are. It is maintained, it is vetted, and on Copilot CLI it requires no configuration at all.
Read-only toolsets to begin with. Add write tools when you hit a specific case where reading is not enough, and add them one at a time.
Editor first, cloud agent later. The editor gives you approval steps and visible diffs while you build intuition. Configure MCP for the autonomous surface once you know what the tools actually do.
Nothing else until something hurts. The second server should be a response to a real, recurring gap — the thing you keep pasting — rather than an anticipation of one.
That configuration takes minutes, carries almost no risk, and covers the majority of the practical value. Everything more elaborate should be justified by something that happened, not by the elaborateness being available.
Next
The GitHub MCP server is the one to set up first. Connecting MCP servers covers per-client configuration in detail. And the cloud agent explains why the autonomous surface needs the most conservative MCP configuration of all.
Put this into practice
6-minute exercise
Read what a server is actually asking for
- Open the configuration of any MCP server you have connected.
- List the tools it exposes.
- For each one, write down what damage it could do if the model used it wrongly.
- Remove or restrict any tool you cannot justify.
How you know it worked You removed at least one, or you can state why every remaining tool is needed. Either is a pass; not having looked is not.
Full lab Build an MCP Integration for GitHub Copilot
Companion project MCP starter
Check your understanding
3 questions. Nothing is scored or recorded, and you can retry as often as you like.
Sources
Every version-sensitive claim on this page was checked against first-party documentation. Only sources actually used are listed.
Your progress
Saved in this browser only. No account, no server, and nothing leaves your device. Clearing site data resets it.Sync across devices if you want it everywhere.
Saved in this browser and synced to your account, so it follows you between devices. Manage or delete it.
Was this lesson helpful?
We record which lesson you rated and whether it helped. Nothing identifies you — no account, no cookie, no session.