Skip to content
Follow
← GitHub Copilot in Practice: Agentic Coding for Production Engineering Teams

Lesson 5 of 8 · 18 min read

Extending Copilot with the Model Context Protocol (MCP)

Model Context Protocol (MCP) is a client-server standard.

1. What MCP Is: Client-Server, Resources, and Tools

Model Context Protocol (MCP) is a client-server standard. In this course you'll meet it from the Copilot side: whether Copilot is running inside an IDE (the Agent mode surface from Chapter 1) or in one of the autonomous surfaces you'll use later in this chapter, Copilot itself acts as the MCP client. It connects out to one or more external MCP servers — separate processes or services that expose two kinds of things to the client:

  • Resources — readable context the client can pull in, such as documentation or logs.
  • Tools — callable actions with defined inputs and outputs, such as a tool that opens an issue in a tracker.

That's the whole mental model you need before touching a registry or a configuration file: Copilot connects (client), a server exposes resources to read and tools to call, and the client decides when to read a resource or invoke a tool as part of answering your request.

This is deliberately just the protocol shape. Server discovery, installation, and the approval behavior around tool calls each get their own section below — don't reach for configuration syntax yet.

2. The GitHub MCP Registry: Scale and Maturity

GitHub curates a registry of MCP servers at github.com/mcp, and it's built directly into VS Code and Visual Studio as the default way to discover and install a server rather than hunting for one yourself.

As of an August 2026 check of the live registry, it listed approximately 219 servers spanning categories like document conversion, infrastructure monitoring, web automation, code repositories, cloud platforms, and databases. Treat that number as a point-in-time count, not a fact to memorize — check the live registry page for the current figure and catalogue before you choose a server in the activity below.

The registry itself is still maturing. It launched in preview around 2025-09-08, with its API reaching a v0.1 freeze around 2025-10-24, and no general-availability designation had been confirmed as of the evidence's access date. Treat those dates as approximate rather than exact-to-the-day; check the registry's own changelog if you need precise figures. Practically, that still-stabilizing status means the servers themselves vary widely in maturity too: before installing one, check its publisher and maintenance signals (who built it, how recently it was updated) the way you would for any young, fast-moving ecosystem — this course does not endorse or catalogue specific third-party servers.

3. MCP Risk Patterns: Tool Confusion and Prompt Injection

Before you configure a single server, it's worth understanding two risk patterns that are especially relevant when MCP tools are involved. Neither pattern is exclusive to MCP — prompt injection in particular is a general risk of feeding a model untrusted tool output — but MCP's combination of multiple independently-authored servers and free-form tool responses is exactly where they tend to surface.

Tool confusion

When more than one running MCP server exposes tools with overlapping names or descriptions, Copilot's LLM-based tool selection can call the wrong one — an unintended tool executes with unintended consequences, even though nothing was misconfigured. This is a "which tool gets called" problem, driven purely by naming overlap across whatever servers happen to be active in a session.

Prompt injection via tool responses

A tool's response is just data that gets fed back to Copilot's model — and a compromised or malicious external system can disguise hidden instructions inside an otherwise normal-looking response (buried in what looks like ordinary log output or document text, for example). Copilot's model may then treat that hidden text as a valid instruction to act on. This is a "what does the response try to make Copilot do next" problem.

One thing worth being precise about: GitHub's own MCP overview and GitHub MCP server documentation pages have no dedicated security-considerations section — the only controls documented there are the org/enterprise policy and default token scoping covered in the next section. Treat the two risk patterns above as your working model for MCP security until you find something more specific in GitHub's current docs, and check those docs yourself before assuming this treatment is complete.

4. Configuring an MCP Server: Interactive and Repository-Level

MCP servers attach to Copilot in two different places, and you'll set up both in this chapter's activities.

Interactive IDE configuration

Chapter 1 introduced Agent mode and had you record whether your IDE supports it — if your Chapter 1 record shows your IDE lacks agent mode, use the second IDE you chose in Chapter 1 for this session instead. If you're working in VS Code or Visual Studio, github.com/mcp is built directly into the editor as the default way to discover and install a server: inside an Agent mode session, you can browse the registry and add a server directly to your session configuration. In any other agent-mode IDE, that built-in flow doesn't exist — browse github.com/mcp directly in a browser instead, and add the chosen server to your interactive session using your IDE's current documented MCP configuration method, recording what you did. Either way, this is the fastest way to get a tool available to you personally, in one editor session — no re-explanation of Agent mode itself needed here, only that this is where the server gets attached.

Repository-level configuration

Separately, you can configure an MCP server at the repository level so it becomes available to Copilot surfaces that don't run inside your interactive editor at all — specifically the Copilot cloud agent (Chapter 3) and Copilot code review (Chapter 4). This is a parallel path, not a replacement for the interactive one: the same server can be attached both ways, and in the activities below you'll do exactly that on the shared reference project.

Token scope

However you attach it, the GitHub MCP server's token defaults to read-only access on the current repository. That default is customizable to a broader scope if a task genuinely needs it, but read-only-on-current-repo is what you get out of the box.

The org/enterprise gate

Before attempting any MCP configuration — interactive or repository-level — confirm your own account's or organization's current Copilot settings for MCP access. If you're in a Business or Enterprise organization, know that the "MCP servers in Copilot" policy is disabled by default — an administrator has to explicitly turn it on before members can use MCP at all in that context, not only at the point of repository-level configuration. That confirmed default applies to Business/Enterprise; on a personal account, checking your own settings directly is still the fastest way to know where you stand. Activity 1 checks this gate before your first attachment attempt and tells you what to record if it isn't open to you.

Two related mechanisms live outside this chapter's scope and are worth naming only in passing: repository custom instructions (owned in full by Chapter 4) and the broader family of context-supply mechanisms including Copilot Spaces (owned in full by Chapter 6). Nothing about them is taught here beyond this pointer.

5. Tool-Call Approval Is Surface-Dependent, Not Universal

This is the section that resolves an apparent contradiction you may already have sensed: does Copilot ask permission before calling an MCP tool, or does it just act? The honest answer is both — depending on the surface, and the two statements below are compatible, not in tension.

Interactive editors still gate on approval. Interactive IDE Copilot Chat or Agent mode sessions — with a human present, including VS Code, Visual Studio, and JetBrains — request explicit approval before Copilot executes an MCP tool call by default, at least the first time you use that tool. In VS Code and Visual Studio specifically, that approval surfaces as the documented Allow/Skip prompt with scope options; other interactive editors aren't documented at that same level of UI detail, but the approval-by-default behavior itself still applies to them. This remains true today; nothing about it has been superseded.

Unattended surfaces act autonomously. For a repository-level MCP server configured for the Copilot cloud agent or for Copilot code review, current first-party documentation states plainly that Copilot uses the configured tools autonomously and does not ask for approval. The reason is that these are unattended surfaces with no interactive session for Copilot to prompt through — not that they are less careful. You've already met both of these unattended surfaces: Chapter 3's cloud agent and Chapter 4's code review, and this is the specific reason MCP behaves differently there.

Put the two together and you get one durable rule, not a contradiction: approval behavior tracks the surface, not the server or the protocol. The same MCP server, attached both ways, will prompt you in an interactive session and act on its own in an unattended one. Interactive sessions do offer an optional session/workspace auto-approval relaxation if you want to stop being prompted for a trusted tool — but that's a deliberate choice you make, not a change to the underlying default.

Because no per-call check occurs on the unattended path, treat repository-level MCP configuration as a higher-oversight-risk setup than the interactive one. The mitigation is upstream of any single call: limit and curate which MCP servers and tools you configure for that surface in the first place, and scope each server's toolset narrowly, rather than relying on a per-call check that will never come.

Activity 1: Connect an MCP Server in an Interactive Agent Mode Session

Goal: Attach your first MCP server to the reference project through an interactive Agent mode session, and observe the approval gate this chapter's next activity will contrast against an unattended surface.

Steps:

  1. Before anything else, check whether MCP is actually available to you. If you're in a Business or Enterprise organization, confirm whether an administrator has enabled the "MCP servers in Copilot" policy — it's disabled by default, and until it's turned on, MCP can't be used at all in that context, including this interactive session. On a personal account, check your own Copilot settings directly.
    • If MCP is blocked (Business/Enterprise, policy not enabled, no admin path available to you): stop here. Record "MCP access blocked — organization policy not enabled" as this activity's outcome, note it in your reference-project notes, then continue to Activity 2, which has its own short blocked-path record to complete, before moving on to Activity 3.
    • If MCP is available, continue with the steps below.
  2. Open the shared reference project in an Agent mode session in your IDE — if your Chapter 1 record shows your IDE lacks agent mode, open this session in the second IDE you chose in Chapter 1 instead, since this activity needs agent mode.
  3. If you're working in VS Code or Visual Studio, browse the built-in github.com/mcp registry inside your Agent mode session and choose one server relevant to the reference project's stack — check the registry's current approximate scale (don't rely on the ~219 figure quoted earlier in this chapter) and its still-stabilizing, no-confirmed-GA status while choosing. In any other agent-mode IDE, that built-in flow doesn't exist: browse github.com/mcp directly in a browser instead, using those same scale and maturity signals to choose a server.
  4. If you're working in VS Code or Visual Studio, add the chosen server to your interactive session configuration using the registry's built-in add flow. In any other agent-mode IDE, add the chosen server to your interactive session using your IDE's current documented MCP configuration method, and record what you did.
  5. Give Copilot a task that requires one of the server's tools and watch for the approval prompt before the tool call executes. Interactive IDE sessions with a human present — including VS Code, Visual Studio, and JetBrains — request explicit approval by default, per Section 5; in VS Code and Visual Studio specifically, that's the documented Allow/Skip prompt with scope options. If you're using VS Code, Visual Studio, or JetBrains, expect this default to apply to you and record the specific prompt or approval behavior you see. If you're on a different editor (one not named above, for example Eclipse or Xcode), that documented default isn't confirmed for your editor: give Copilot the same kind of task anyway, but record what you actually observe — a prompt, no prompt, or something else — as an open observation about your editor, not as evidence of a misconfiguration.
  6. Record which approval scope you chose (once / session / always) and why, or, if no documented prompt applied to your editor, record what you observed instead.

Expected outputs:

  • On the available path: the server configured and active in your interactive session on the reference project, plus a short note describing the prompt you saw and the scope you picked.
  • On the blocked path: a plainly recorded "MCP access blocked" note explaining why.

Hints:

  • If no prompt appears and you're on VS Code or Visual Studio, check whether auto-approval was already enabled for that server or tool — under the documented model that's expected behavior for a session with prior approval, not a break in the approval default.
  • If no prompt appears and you're on an editor other than VS Code, Visual Studio, or JetBrains (for example, Eclipse or Xcode), don't diagnose it as an auto-approval issue — the approval default simply isn't confirmed for your editor. Record that gap directly instead.

Checkpoint: On the available path using VS Code, Visual Studio, or JetBrains, you should be able to name the specific approval prompt or behavior you saw and explain why it appeared before the tool executed. On the available path using an editor other than VS Code, Visual Studio, or JetBrains (for example, Eclipse or Xcode), your notes should record what you actually observed rather than assuming a missing prompt means a configuration problem. On the blocked path, your notes should plainly record the access blocker rather than assuming a server was attached. Whichever path you took, this establishes the interactive baseline — MCP attached, or blocked — that Activity 2 will build on.

Activity 2: Configure the Same Server at the Repository Level and Observe Autonomous Use

Goal: Produce this chapter's key direct observation — the same MCP tooling behaves differently on an unattended, repository-level surface than it did in the interactive session — or, if no unattended surface is available to you, reason through what that observation would look like; or, if Activity 1 recorded an access blocker, close out that blocked state so later chapters have a clear, durable record to work from.

Gating checks:

  1. Check what you recorded in Activity 1. If you recorded "MCP access blocked," your path is Blocked.
  2. If Activity 1 succeeded, check whether you have an available unattended surface: recall your Chapter 3 notes for whether the cloud agent was genuinely blocked for you, and your Chapter 4 notes for whether code review is not available to you (recorded on Chapter 4's Path B).
    • If at least one of the cloud agent or code review is available to you, your path is Attached and observed.
    • If the cloud agent was recorded as genuinely blocked in Chapter 3 and code review is not available to you (recorded on Chapter 4's Path B), your path is Attached and reasoned.

Follow only the path section below that matches you.

Path: Attached and observed

Steps:

  1. Configure the same MCP server you chose in Activity 1 at the repository level on the reference project, so it's available to whichever of the Copilot cloud agent and/or Copilot code review is actually available to you.

  2. Check the server's token scope (default: read-only, current repository) and note whether you changed it.

  3. Check your Chapter 4 notes for the recorded disposition of the pull request from the Chapter 3 workflow, and weigh it against which unattended surface(s) the gating check above found available to you:

    • If the cloud agent is available to you, trigger a new bounded cloud-agent task on the reference project that exercises the MCP tool — this works regardless of the pull request's disposition.
    • If code review is your only available surface: reuse the Chapter 3/4 pull request directly for a code-review run if your Chapter 4 notes recorded it as left open. If your notes recorded it as merged instead, first open a small new pull request on the reference project, then trigger a code-review run against that new pull request.

    Observe and record that the tool call executes with no per-call approval prompt.

Expected output: the server configured at the repository level for the reference project, plus a short comparison note that attributes the absence of a prompt specifically to the surface (unattended cloud agent / code review), not to the server or to a general "MCP is autonomous" claim.

Hint: If code review is your only available surface and the Chapter 3/4 pull request was merged, open a small new pull request on the reference project before triggering the review run — a code-review run needs an open pull request to act on, unlike the cloud agent, which opens its own.

Checkpoint: your note correctly attributes the difference to surface — unattended vs. interactive — never to server identity or to a single universal MCP rule.

Path: Attached and reasoned

Steps:

  1. State plainly which surface(s) are unavailable to you and why: the cloud agent, if it was recorded as genuinely blocked in Chapter 3; code review, if it is not available to you (recorded on Chapter 4's Path B); or both — carrying forward the specific reason you already recorded in Chapter 3 and/or Chapter 4.
  2. Reasoning from Section 5's surface-dependent approval model, write down what the approval behavior would be on each unavailable unattended surface if it were available to you, and why. This is a written prediction, not an observation — don't claim you watched a tool call execute if you didn't.
  3. Record your disposition for this chapter as: "MCP attached interactively; unattended surface unavailable — approval contrast reasoned, not observed."

Expected output: a note naming the unavailable surface(s) and the Chapter 3/4 reason behind them, your written reasoning about the approval behavior each surface would show, and the recorded disposition from step 3.

Checkpoint: your reasoning is grounded explicitly in Section 5's surface-dependent model and does not claim an observation you didn't make.

Path: Blocked

Steps:

  1. Record "MCP access blocked — organization policy not enabled" again as this activity's outcome — the org/enterprise policy gates MCP use overall, not only repository-level configuration.
  2. Note in your reference-project notes that no MCP server was attached to the reference project this chapter.

Expected output: a recorded note confirming MCP access remains blocked and that no server was attached to the reference project this chapter.

Checkpoint: your notes record the access blocker as a durable state rather than silently assuming a server got attached.

Whichever path you took, this closes out the before/after contrast — Attached and observed, Attached and reasoned, or Blocked — that Chapter 6 assumes when it discusses context-supply mechanisms.

Activity 3: Spot the Risk: Tool Confusion vs. Prompt Injection

Goal: Confirm you can distinguish MCP's two core risk patterns and reason about mitigations before scaling up server usage on real projects.

Steps:

  1. Consider two scenarios: (a) two running MCP servers each expose a tool with an overlapping name or description; (b) a tool response contains a hidden instruction disguised inside otherwise normal-looking data.
  2. For each scenario, identify which risk pattern it illustrates and why.
  3. For each scenario, name one concrete mitigation available with current tooling — for example, avoiding redundant overlapping servers/toolsets, scoping the MCP token narrowly, or limiting and curating which MCP servers and tools are configured for unattended surfaces.
  4. Write one sentence stating what current first-party MCP documentation does and does not cover on this topic: GitHub's MCP overview and GitHub MCP server pages have no dedicated security-considerations section, beyond the org/enterprise policy and default token scoping described in this chapter.

Expected outputs: a short written mapping of each scenario to its risk pattern and mitigation, plus the one-sentence coverage statement.

Hints:

  • Tool confusion is about which tool gets called; prompt injection is about what a tool's response tries to make Copilot do next.
  • Optionally, briefly assess whether the server you chose in Activity 1 has tool names that could plausibly overlap with another common server — skip this if Activity 1 recorded an MCP access blocker instead of an attached server.

Checkpoint: both scenarios correctly labeled, each paired with a mitigation consistent with the tool-confusion and prompt-injection definitions taught in this chapter.

Reference Project Continuity — Chapter 5

Starting state: the reference project already carries the Chapter 1 initial Copilot-assisted change, the Chapter 2 plan choice, and the pull request/change produced by the Chapter 3 workflow and reviewed and triaged in Chapter 4 with scoped custom instructions. Chapter 4 also determined and recorded whether that pull request was merged or deliberately left open — check your own Chapter 4 notes for that recorded outcome before starting Activity 2 below.

What this chapter adds: Activity 1 opens by checking whether MCP is actually available to you — the org/enterprise "MCP servers in Copilot" policy is disabled by default for Business/Enterprise, and it gates MCP use overall, not just repository-level configuration. If it's open to you, Activity 1 attaches an MCP server to the reference project through the interactive IDE Agent mode surface and captures the approval behavior that appears there — the documented default that applies on VS Code, Visual Studio, and JetBrains, or the open observation you record instead on any other editor; if you recorded a blocker, Activity 1 routes you into Activity 2's own short blocked-path record before Activity 3. Activity 2 then attaches the same server at the repository level so it's usable by the Copilot cloud agent and/or Copilot code review: it triggers a new bounded cloud-agent task if the cloud agent is available to you, regardless of the Chapter 3/4 pull request's disposition, or, if code review is your only available unattended surface, reuses that pull request if your Chapter 4 notes recorded it as left open, or opens a small new pull request if they recorded it as merged — either way capturing the absence of an approval prompt on that unattended surface. If you have MCP available but the cloud agent was recorded as genuinely blocked in Chapter 3 and code review is not available to you (recorded on Chapter 4's Path B), Activity 2 instead has you name the unavailable surface(s), reason in writing from Section 5 about what the approval behavior would be on each, and record that contrast as reasoned rather than observed. If MCP is blocked for you instead, Activity 1 and Activity 2 have you record an explicit "MCP access blocked" state so later chapters know not to assume a server was ever attached.

Ending state: the reference project ends this chapter in one of three recorded states:

  • Attached and observed — an MCP server attached on two surfaces — the interactive IDE session and the repository level — together with a learner-authored comparison note that correctly attributes the observed approval-behavior difference to surface, not to server identity.
  • Attached and reasoned — an MCP server attached only on the interactive IDE session, with the cloud agent recorded as genuinely blocked in Chapter 3 and code review not available to you (recorded on Chapter 4's Path B), together with a note naming the unavailable surface(s) and a written, surface-dependent reasoning about the approval contrast that could not be directly observed.
  • Blocked — if you were blocked by the org/enterprise policy, a plainly recorded "MCP access blocked" note instead, with no server attached.

In all three cases, this is the course's first direct, hands-on (or reasoned) evidence of the surface-dependent tool-approval model, or of its documented access gate, and Chapter 6 assumes whichever of these three states you recorded when it turns to context-supply mechanisms.

Sources