Skip to main content

25 - MCP in Copilot and Advanced Custom Instructions

Since March 2025, when GitHub introduced the Model Context Protocol (MCP) in preview in editors, the way developers configure Copilot has fundamentally changed. Custom instructions enable repository-level configuration, .prompt.md files provide reusable templates, and MCP servers extend Copilot with external APIs.

What do you think about this article?

At a Glance

Since March 2025, when GitHub introduced the Model Context Protocol (MCP) in preview in editors, the way developers configure Copilot has fundamentally changed. Custom instructions enable repository-level configuration, .prompt.md files provide reusable templates, and MCP servers extend Copilot with external APIs.

25 - MCP in Copilot and Advanced Custom Instructions

Since March 2025, when GitHub introduced the Model Context Protocol (MCP) in preview in editors equipped with Copilot, the way developers extend and customize their AI assistant has radically changed. In July 2025, MCP became generally available (GA) in VS Code 1.102. As of March 2026, the same protocol is now shared between VS Code and the Copilot CLI, with support for limited sandboxes on macOS and Linux.

Combined with the new hierarchy of custom instructions and files .prompt.md on-demand, MCP enables very powerful workflows: integrate personal databases directly into Copilot, connect business services, create specialized AI agents for specific tasks and build ecosystems of tools that multiply the team's productivity.

What You Will Learn

  • Configure MCP server in mcp.json (workspace and user settings)
  • Use public MCP servers (filesystems, GitHub, PostgreSQL, Slack)
  • Write effective custom instructions at repo level
  • Create templates on-demand with .prompt.md files
  • Define custom agents in .github/agents/
  • Implement MCP sandbox for security isolation
  • Configure MCP for production environments and teams
  • Migrate deprecated GitHub App Extensions to MCP

Complete Series Overview

#ItemFocus
1Claude as Technical PartnerSetup and first steps
2Project Context and SetupCLAUDE.md and configuration
3Concept and RequirementsMVP and user personas
4Backend and Frontend ArchitectureSpring Boot and Angular
5Structure of the CodeOrganization and conventions
6Advanced Engineering PromptAdvanced techniques
7Testing and qualityStrategies and test generation
8Professional DocumentationREADME, API, ADR
9Deploy and DevOpsDocker, CI/CD, monitoring
10Evolution and MaintenanceRefactoring and scalability
11Real Project IntegrationClaude Code in production
12Claude Code CLICommands and configuration
13Agent Skillsmodular capabilities
14Specialized SubagentsAgenti con ruoli specifici
15Hooks e AutomazioneEvent-driven workflows
16Ralph Wiggum MethodSviluppo guidato da test
17BMAD MethodGestione progetti strutturata
18Orchestrazione Multi-AgentePipeline di agenti
19Collaborative WorkTeam e pair programming AI
20Sicurezza e Best PracticeHardening e compliance
21Monitoring e ObservabilityMetriche e debugging
22GitHub Copilot ProFunzionalità avanzate
23Prompt CachingOttimizzazione costi e latenza
24Copilot WorkspaceSviluppo full-stack collaborativo
25MCP e Custom Instructions (sei qui)Estensioni e personalizzazione

1. Dal Paradigma delle Extensions al Model Context Protocol

Prima di marzo 2025, il modo di estendere GitHub Copilot era limitato e frammentato:

  • GitHub App Extensions (deprecate): sviluppatori dovevano registrare app OAuth separate, compilare manifest JSON, gestire token, e spesso l'integrazione era lenta e soggetta a ratifica.
  • Editor-specific integrations: VS Code Copilot funzionava diversamente da JetBrains Copilot, senza uno standard condiviso.
  • Assenza di tool standardizzati: Non c'era modo uniforme di dire a Copilot "qui ho un database", "usa questo API endpoint", "leggi da questo filesystem".

Il Model Context Protocol (MCP) è lo standard completamente nuovo che cambia il paradigma. Originariamente creato da Anthropic come protocollo aperto per collegare LLM a fonti di dati e tool, GitHub lo ha adottato come standard per Copilot. Questo significa:

Vantaggi del Paradigma MCP

  • Standard condiviso: VS Code, JetBrains, Copilot CLI, persino client custom usano lo stesso protocollo
  • Decoupling: i tool MCP sono indipendenti dall'editor - uno stesso server MCP funziona ovunque
  • Composizione: connetti più MCP server nello stesso workspace e il modello li usa tutti come toolbox unificato
  • Sandbox: (a marzo 2026) supporto per MCP server in ambienti isolati con accesso file/network limitato
  • Open source: hundreds di server MCP già implementati - database, filesystem, GitHub, Slack, Sentry, MongoDB, ecc.

2. MCP in VS Code 1.99 (Marzo 2025) - Agent Mode Preview

A marzo 2025, VS Code 1.99 ha introdotto la Agent Mode preview per Copilot. In questa modalità, Copilot non è solo un autocomplete o un chatbot - diventa un agente che può usare tool per completare i tuoi task.

.vscode/settings.json - Abilitare Agent Mode in preview
{
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "copilot.experimental.agentMode": true,
  "copilot.experimental.contextWindow": "extended"
}

Con Agent Mode abilitato, Copilot ha accesso ai tool registrati nel workspace. Per registrare i tool, crei un file mcp.json nella root del progetto oppure in ~/.vscode/extensions/copilot/mcp.json a livello user.

.vscode/mcp.json - MCP server registration in preview (March 2025)
{
  "mcpServers": {
    "filesystem": {
      "command": "node",
      "args": ["mcp-server-filesystem/index.js"],
      "disabled": false,
      "alwaysAllow": ["read", "list", "create"]
    },
    "github": {
      "command": "node",
      "args": ["mcp-server-github/index.js"],
      "env": {
        "GITHUB_TOKEN": "$GITHUB_TOKEN"
      },
      "disabled": false
    }
  }
}

In the preview implementation, Copilot queries each registered MCP server to list the available tools and (when required) uses them in his reasoning. For example:

Example: Copilot uses MCP tools in Agent Mode (preview)
Prompt: "Rileggi tutti i file TypeScript in src/ e segnala errori di type safety"

Copilot reasoning:
1. Utente chiede di leggere file TypeScript
2. Disponibili tool: [filesystem.read, filesystem.list, ...]
3. Esecuzione: filesystem.list("src/", pattern="*.ts") → 47 file
4. Per ogni file: filesystem.read("src/...") → analizza con TypeScript compiler
5. Segnala errori trovati

Output: "Trovati 3 type errors in src/components/ ..."

3. MCP Generally Available in VS Code 1.102 (July 14, 2025)

On July 14, 2025, GitHub made MCP generally available (GA) in VS Code 1.102. New features in the GA release include:

What's New in the GA Release (July 2025)

  • Stability and performance: optimization of tool requests, caching of results
  • OAuth for MCP remote: MCP servers on remote hosts (e.g. cloud) authenticated via OAuth
  • Personal Access Token (PAT): Simplified authentication with GitHub PAT for MCP servers
  • Robust error handling: timeout, retry policy, fallback on tool failure
  • Tool categorization: MCP tools are now categorized (read, write, execute) for better UI
  • Configuration validation: VS Code validates the configuration mcp.json at boot and reports errors
.vscode/mcp.json - Complete setup (GA, July 2025)
{
  "mcpServers": {
    "filesystem": {
      "command": "node",
      "args": ["path/to/mcp-server-filesystem.js"],
      "cwd": "${workspaceFolder}",
      "env": {
        "NODE_ENV": "production"
      },
      "disabled": false
    },
    "github": {
      "command": "node",
      "args": ["path/to/mcp-server-github.js"],
      "env": {
        "GITHUB_TOKEN": "${env:GITHUB_TOKEN}",
        "GITHUB_OWNER": "fedcal",
        "GITHUB_REPO": "PortfolioPersonaleAngular"
      },
      "disabled": false
    },
    "postgres": {
      "command": "node",
      "args": ["path/to/mcp-server-postgres.js"],
      "env": {
        "DATABASE_URL": "${env:DATABASE_URL}",
        "DB_USER": "${env:DB_USER}",
        "DB_PASSWORD": "${env:DB_PASSWORD}"
      },
      "disabled": false
    },
    "slack": {
      "command": "node",
      "args": ["path/to/mcp-server-slack.js"],
      "env": {
        "SLACK_BOT_TOKEN": "${env:SLACK_BOT_TOKEN}"
      },
      "disabled": false
    },
    "sentry": {
      "command": "python3",
      "args": ["-m", "mcp_server_sentry"],
      "env": {
        "SENTRY_AUTH_TOKEN": "${env:SENTRY_AUTH_TOKEN}",
        "SENTRY_ORG": "myorg",
        "SENTRY_PROJECT": "myproject"
      },
      "disabled": false
    }
  },
  "env": {
    "GITHUB_TOKEN": "ghp_xxxxx",
    "DATABASE_URL": "postgresql://user:pass@localhost:5432/mydb",
    "SLACK_BOT_TOKEN": "xoxb-xxxxx"
  }
}

This configuration connects 5 MCP servers simultaneously, allowing Copilot to:

  • filesystem: read, write, list files in the workspace
  • github: query issues, PRs, commits, workflows in the repository
  • postgres: query the database directly (SELECT, schema tables, data analysis)
  • slack: send messages, read histories, manage threads
  • sentry: Query errors in production, analyze breadcrumbs, get stack traces

4. MCP Shared between VS Code and Copilot CLI (March 2026)

In March 2026, GitHub unified MCP support between VS Code and the Copilot CLI. This means you can configure your own MCP servers once and use them everywhere: in the editor, from the terminal with the CLI, and also in automation scripts.

MCP configuration at user level (March 2026)
~/.copilot/mcp.json  - Configurazione globale (tutti i progetti)

~/.copilot/mcp.json:
{
  "mcpServers": {
    "github": {
      "command": "node",
      "args": ["/usr/local/lib/mcp-server-github/index.js"],
      "env": {
        "GITHUB_TOKEN": "${env:GITHUB_TOKEN}"
      }
    },
    "filesystem": {
      "command": "node",
      "args": ["/usr/local/lib/mcp-server-filesystem/index.js"]
    }
  }
}

With this global setup, six use cases become possible:

Unified Use Cases (March 2026)

ContextUseMCP tools available
VS Code editor Copilot: Inline Chat (Cmd+I) github + filesystem (global + workspace)
VS Code sidebar chat Cmd+L to open Copilot Chat github + filesystem (global + workspace)
CLI terminal copilot --model claude-opus-4 --with-tools github,filesystem "Crea PR con..." github + filesystem (global config)
Automation scripts copilot --print "Genera report..." --output json --tools postgres postgres (global config)
GitHub Actions github-action-copilot official with MCP support github + custom (in Action)

This paradigm abolishes the artificial distinction between "development in editor" and "CLI automation". Copilot becomes a consistent assistant wherever you are.

5. MCP Server Sandbox - Security Isolation (March 2026)

In March 2026, VS Code introduced support for Sandboxed MCP server on macOS and Linux. A sandboxed MCP server has limited access to the filesystem and network - this is critical when you use third-party MCP servers and want to protect your sensitive data.

.vscode/mcp.json - MCP server with sandbox enabled (March 2026)
{
  "mcpServers": {
    "untrusted-thirdparty-tool": {
      "command": "node",
      "args": ["path/to/unknown-mcp-server.js"],
      "sandbox": {
        "enabled": true,
        "allowedPaths": [
          "${workspaceFolder}/src",
          "${workspaceFolder}/docs"
        ],
        "blockedPaths": [
          "${workspaceFolder}/.env",
          "${workspaceFolder}/.env.prod",
          "${HOME}/.ssh",
          "${HOME}/.aws"
        ],
        "allowedNetworkDomains": ["api.example.com"],
        "blockedNetworkDomains": ["*"]
      },
      "disabled": false
    },
    "trusted-postgres": {
      "command": "node",
      "args": ["mcp-server-postgres"],
      "sandbox": {
        "enabled": false
      }
    }
  }
}

With this configuration:

  • untrusted-thirdparty-tool: has access ONLY to src/ e docs/, can't read .env o ~/.ssh, and cannot connect to any domain except api.example.com
  • trusted-postgres: no sandbox (default configuration), full access

Sandbox Availability and Limitations

Availability (March 2026): sandbox is supported on macOS 12+ e Linux (via coccomp + namespaces). On Windows, sandbox is not yet available (WSL2 limitation).

Mechanism: on macOS use App Sandbox (entitlements), on Linux uses Seccomp filter + kernel namespaces. Performance has ~5-10% overhead for file system and network.

6. End of GitHub App Extensions (10 November 2025)

On November 10, 2025, GitHub officially deprecated support for GitHub App-based Copilot Extensions. This means that any extension developed with the old OAuth paradigm GitHub App stops working on January 1, 2026.

Extension developers (Sentry, Docker, MongoDB, Stripe, etc.) have migrated to MCP during 2025. The migration path from GitHub App Extension to MCP server is straightforward:

Migration: GitHub App Extension → MCP Server
== PRIMA (GitHub App Extension - DEPRECATA) ==
❌ github-app/manifest.json (OAuth setup complesso)
❌ Registrazione manuale in GitHub Marketplace
❌ Ogni editor supportava il protocollo diversamente
❌ Nessun sandbox, accesso non ristretto

== DOPO (MCP Server - NUOVO STANDARD) ==
✅ mcp.json con server command + args
✅ Zero registrazione GitHub, basta installare il package npm
✅ Funziona ovunque: VS Code, JetBrains, CLI, custom client
✅ Sandbox support on demand

== ESEMPIO: Migrazione Sentry Extension ==

Prima (GitHub App):
1. Registra GitHub App OAuth
2. Installa extension da Marketplace
3. Extension autentica con GitHub
4. Sentry API calls via OAuth token

Dopo (MCP):
1. npm install mcp-server-sentry
2. Aggiungi a .vscode/mcp.json o ~/.copilot/mcp.json:
   {
     "sentry": {
       "command": "node",
       "args": ["-m", "mcp_server_sentry"],
       "env": { "SENTRY_AUTH_TOKEN": "${env:SENTRY_AUTH_TOKEN}" }
     }
   }
3. Usa in Copilot Chat: "Mostra i 10 errori più recenti da Sentry"
4. MCP server chiama Sentry API con token

Most "known" extensions have already implemented an equivalent MCP server:

Official Third Party MCP Servers (excerpt, April 2026)

ServiceMCP ServerMain functionality
Sentry mcp-server-sentry (official) Error queries, breadcrumb analysis, release management
Docker mcp-server-docker (official) Management of containers, images, volumes
MongoDB mcp-server-mongodb (official) Database queries, aggregation, schema introspection
Stripe mcp-server-stripe (official) Query transactions, subscription, customer management
AWS mcp-server-aws (official) CloudFormation, EC2, S3, DynamoDB
Slack mcp-server-slack (official) Messages, channel, user, workflow automation
GitHub mcp-server-github (official) Issue, PR, commit, workflows, releases

7. Custom Instructions Hierarchy - Three Tiers

In addition to MCP tools, Copilot supports custom instructions that they specify how the model should behave in your specific context. There are three configuration tiers, with decreasing precedence:

Custom Instructions Tier

TiersFileBroomsPrecedenceAuto-attach
1. Prompt Files .prompt.md (in any dir) On-demand, triggered by commands Maximum (explicit) No, explicitly invoked
2. Repo Instructions .github/copilot-instructions.md All repo developers High (auto) Yes, on every inline chat
3. Workspace Settings .vscode/settings.json (config key) Local dev + CI/CD environment Average Yes, at startup
4. User Global ~/.copilot/instructions.md All user projects Low (default) Yes, global fallback

Tier 1: Repo-scoped Instructions (.github/copilot-instructions.md)

The file .github/copilot-instructions.md contains rules, conventions and guidelines that Copilot must follow automatically in every chat within the repository.

.github/copilot-instructions.md - Spring Boot repo guidelines
# Copilot Instructions for PortfolioPersonaleAngular Backend

## Architecture
- Follow Clean Architecture 4-layer pattern (domain, application, infrastructure, presentation)
- Domain layer: ZERO framework dependencies
- Application layer: orchestrate domain + infrastructure, implement use cases
- Infrastructure layer: implement domain ports, handle external integrations
- Presentation layer: REST controllers, error handling, DTOs

## Code Style
- Language: Java 21, Spring Boot 3.4
- Pattern: Records for DTOs (immutability first)
- Validation: use @Validated and custom validators
- Exception Handling: create domain exceptions, not generic RuntimeException

## Testing
- Framework: JUnit 5 + Mockito + Testcontainers
- Coverage: target 80%+ on business logic
- Test naming: method_givenContext_thenExpectation
- Integration tests use Testcontainers for PostgreSQL + Redis

## Database
- ORM: Spring Data JPA + Hibernate 6
- Migrations: Flyway (V001..VnNN pattern)
- Transactions: use @Transactional only on service layer
- Caching: @Cacheable on read-heavy queries

## API Design
- REST endpoints: /api/v1/resource
- DTOs: request/response separation
- Pagination: use Spring Data Page
- Error responses: standardized ErrorResponse envelope

## Security
- Authentication: JWT proprietario (HS256)
- Role hierarchy: GUEST < USER < PRO < MODERATOR < ADMIN < SUPER_ADMIN
- Rate limiting: Bucket4j via Redis
- CORS: whitelist federicocalo.dev + localhost dev

Tier 2: On-demand .prompt.md Files

The files .prompt.md they are on-demand templates that you can invoke explicitly with commands. Each file becomes a "saved prompt" that Copilot loads when you request it.

.prompt.md example - /generate-rest-controller
> getAll(
    @ParameterObject @PageableDefault(size = 20, sort = "id", direction = Sort.Direction.DESC) Pageable pageable
  ) {
    return ResponseEntity.ok(service.findAll(pageable));
  }

  @GetMapping("/{id}")
  public ResponseEntity<{ResourceName}Response> getById(@PathVariable Long id) {
    return ResponseEntity.ok(service.findById(id));
  }

  @PostMapping
  @ResponseStatus(HttpStatus.CREATED)
  public ResponseEntity<{ResourceName}Response> create(@Valid @RequestBody {ResourceName}Request request) {
    return ResponseEntity.status(HttpStatus.CREATED).body(service.create(request));
  }

  @PutMapping("/{id}")
  public ResponseEntity<{ResourceName}Response> update(
    @PathVariable Long id,
    @Valid @RequestBody {ResourceName}Request request
  ) {
    return ResponseEntity.ok(service.update(id, request));
  }

  @DeleteMapping("/{id}")
  @ResponseStatus(HttpStatus.NO_CONTENT)
  public void delete(@PathVariable Long id) {
    service.delete(id);
  }
}
\`\`\`

## Usage in Copilot
Type in chat: `@.prompt /generate-rest-controller ResourceName=User`

Copilot will:
1. Generate the controller class
2. Generate request/response DTOs
3. Create the service interface
4. Add unit test class

To use this template, write in Copilot Chat:

Using .prompt.md in Copilot Chat
Copilot Chat prompt:
> @.prompt /generate-rest-controller ResourceName=Product Category=ProductCategory

Copilot interpretation:
1. Carica template .prompt.md "generate-rest-controller"
2. Sostituisce variabili: {ResourceName} → Product, {ResourceName}Response → ProductResponse
3. Executes template logic: genera controller, DTOs, service, test
4. Output: 4 file Java creati con codice completo

Tier 3: Workspace Settings in .vscode/settings.json

.vscode/settings.json - Copilot settings for workspace
{
  "copilot.codeReviewAuto": true,
  "copilot.contextWindow": "extended",
  "copilot.customInstructions": {
    "languages": ["java", "typescript", "markdown"],
    "tone": "concise and technical",
    "targetAudience": "senior developers"
  },
  "copilot.disabledInComments": false,
  "copilot.inlineCompletions.enabled": true,
  "copilot.chat.runCommandWithSelection": true
}

8. Custom Agents in .github/agents/

In addition to the instructions, you can define custom agents which I am complete person with prompt, tool restriction and specialization. Each agent is a YAML file in .github/agents/.

.github/agents/security-reviewer.yml - Security expert agent
name: security-reviewer
displayName: Security Reviewer
description: Analyzes code for security vulnerabilities and compliance issues

systemPrompt: |
  You are a security expert reviewing code for vulnerabilities.

  Your analysis focuses on:
  1. OWASP Top 10 vulnerabilities (SQL injection, XSS, CSRF, etc.)
  2. Authentication & authorization flaws
  3. Sensitive data exposure (credentials, PII)
  4. Insecure cryptography
  5. Access control misconfigurations

  Output format:
  - Severity: CRITICAL / HIGH / MEDIUM / LOW
  - CWE reference: link to CWE database
  - Vulnerability description
  - Proof of concept (if applicable)
  - Remediation steps

allowedTools:
  - filesystem:read    # Can read code files
  - filesystem:list    # Can list directories
  - github:searchCode  # Can search code in repo
  - github:getPullRequest # Can analyze PR diffs

restrictedTools:
  - filesystem:write   # Cannot modify code
  - filesystem:delete  # Cannot delete files
  - github:approve     # Cannot approve PRs (advisory only)

context:
  - "src/**/*.java"
  - "src/**/*.ts"
  - "backend/src/**/*"
  - "frontend/src/**/*"

ignorePatterns:
  - "node_modules/**"
  - "dist/**"
  - "*.lock"
  - "*.log"

To use a custom agent, invoke the name in Copilot Chat:

Invocation of custom agent
Copilot Chat:
> @security-reviewer analyze src/main/java/dev/federicocalo/portfolio/presentation/controller/AuthController.java

Copilot behavior:
1. Carica agent "security-reviewer" da .github/agents/security-reviewer.yml
2. Applica systemPrompt
3. Usa SOLO tool in allowedTools (filesystem:read, github, ecc.)
4. Blocca tool in restrictedTools (filesystem:write)
5. Limita context a "src/**/*.java"
6. Output: security report dettagliato

Sample output:
---
🔴 CRITICAL: SQL Injection in AuthController.java:142
CWE-89: Improper Neutralization of Special Elements used in an SQL Command

Vulnerability:
String query = "SELECT * FROM users WHERE email = '" + email + "'";
This concatenates user input directly into SQL query.

Remediation:
Use parameterized queries (PreparedStatement):
String query = "SELECT * FROM users WHERE email = ?";
PreparedStatement ps = conn.prepareStatement(query);
ps.setString(1, email);

---
🟡 MEDIUM: Missing CSRF token validation in POST endpoints
CWE-352: Cross-Site Request Forgery (CSRF)

Recommendation:
Enable @EnableWebSecurity with .csrf(csrf -> csrf.disable()) removed.
Use @GetMapping for idempotent operations, @PostMapping for state changes.
---

9. MCP Public Servers - Practical Guide

There are hundreds of open-source MCP servers ready to use. Here are the most useful ones for developers.

Essential MCP Servers (April 2026)

ServerPackageUse caseAuthentication
Filesystem mcp-server-filesystem Read, list, create files in the workspace None (sandbox for security)
GitHub mcp-server-github Issue, PR, commit, workflows GitHub PAT or OAuth
PostgreSQL mcp-server-postgres Database queries, schema introspection DATABASE_URL env var
Slack mcp-server-slack Messages, channels, threads, user lookup SLACK_BOT_TOKEN
MongoDB mcp-server-mongodb Query, aggregation, index management MONGODB_URL env var
Sentry mcp-server-sentry Production errors, breadcrumbs, releases SENTRY_AUTH_TOKEN
Docker mcp-server-docker Management of containers, images, logs Docker socket access
AWS mcp-server-aws CloudFormation, EC2, S3, Lambda, DynamoDB AWS_ACCESS_KEY_ID + SECRET
Installing Useful MCP Servers (npm + Python)
#!/bin/bash
# Installa server MCP globali in ~/.local/bin/mcp/

mkdir -p ~/.local/bin/mcp
cd ~/.local/bin/mcp

# 1. Node.js-based servers
npm install -g mcp-server-filesystem
npm install -g mcp-server-github
npm install -g mcp-server-postgres
npm install -g mcp-server-slack
npm install -g mcp-server-mongodb
npm install -g mcp-server-docker
npm install -g mcp-server-aws

# 2. Python-based servers (optional)
pip install mcp-server-sentry

# Verifica installazione
which mcp-server-filesystem
which mcp-server-github
which mcp-server-postgres

10. Implement Custom MCP Server

To integrate a personal system (e.g. corporate CRM, proprietary API, custom database), you can write your own MCP server in a few hours. Here's a quickstart in Python.

mcp_server_crm.py - Custom MCP server for CRM
#!/usr/bin/env python3
import json
import asyncio
from typing import Any
from mcp.server import Server
from mcp.types import Tool, TextContent, ToolResult

# Custom CRM API client
class CRMClient:
    def __init__(self, api_key: str, base_url: str = "https://api.mycrm.com"):
        self.api_key = api_key
        self.base_url = base_url

    async def search_customers(self, query: str) -> list[dict]:
        """Search customers by name, email, or phone"""
        # Mock implementation (replace with real API calls)
        return [
            {"id": "cust_123", "name": "Acme Corp", "email": "contact@acme.com"},
            {"id": "cust_456", "name": "TechCorp Ltd", "email": "sales@techcorp.com"}
        ]

    async def get_customer_history(self, customer_id: str) -> dict:
        """Get order history and interactions"""
        return {
            "customer_id": customer_id,
            "orders": [{"id": "ord_001", "date": "2024-01-15", "amount": 2500}],
            "interactions": [
                {"type": "email", "date": "2024-04-20", "subject": "Renewal discussion"}
            ]
        }

    async def create_opportunity(self, customer_id: str, deal_value: float, description: str) -> dict:
        """Create new sales opportunity"""
        return {
            "opp_id": "opp_789",
            "customer_id": customer_id,
            "deal_value": deal_value,
            "description": description,
            "status": "open"
        }

# Initialize MCP server
mcp = Server("crm-server")
crm = CRMClient(api_key="$CRMAPIKEY")  # Load from env

# Register tools
@mcp.tool()
async def search_customers(query: str) -> ToolResult:
    """Search for customers in the CRM by name, email, or phone number"""
    results = await crm.search_customers(query)
    return ToolResult(
        content=[TextContent(type="text", text=json.dumps(results, indent=2))],
        is_error=False
    )

@mcp.tool()
async def get_customer_history(customer_id: str) -> ToolResult:
    """Get complete customer history: orders, interactions, notes"""
    history = await crm.get_customer_history(customer_id)
    return ToolResult(
        content=[TextContent(type="text", text=json.dumps(history, indent=2))],
        is_error=False
    )

@mcp.tool()
async def create_opportunity(customer_id: str, deal_value: float, description: str) -> ToolResult:
    """Create a new sales opportunity for a customer"""
    opp = await crm.create_opportunity(customer_id, deal_value, description)
    return ToolResult(
        content=[TextContent(type="text", text=json.dumps(opp, indent=2))],
        is_error=False
    )

if __name__ == "__main__":
    mcp.run()
Registration of the custom MCP server in .vscode/mcp.json
{
  "mcpServers": {
    "crm": {
      "command": "python3",
      "args": ["/path/to/mcp_server_crm.py"],
      "env": {
        "CRMAPIKEY": "${env:CRM_API_KEY}",
        "CRM_BASE_URL": "https://api.mycompany.crm"
      },
      "disabled": false
    }
  }
}

You can now use your custom MCP server in Copilot Chat:

Use of the custom CRM MCP server
Copilot Chat:
> @mcp-crm Cerca clienti "Acme" e mostra loro cronologia ordini

Copilot behavior:
1. Invoca tool search_customers("Acme")
2. Riceve [cust_123, cust_456]
3. Invoca get_customer_history("cust_123")
4. Riceve order + interaction history
5. Formatta risposta

Output:
---
Ho trovato 2 clienti Acme:

1. **Acme Corp** (cust_123)
   Email: contact@acme.com
   Ordini recenti:
   - Ord_001: 25 gennaio 2024 - €2.500
   Ultime interazioni:
   - Email: 20 aprile 2024 - "Renewal discussion"

2. **TechCorp Ltd** (cust_456)
   ...
---

11. MCP Security - Design Flaw (April 2026) and Mitigations

In April 2026, a security report identified a critical design flaw in the MCP protocol same: many MCP servers in use (~200K on GitHub) do not validate remote commands correctly. This allows a “compromised” AI agent to perform unintended actions.

CVE-Equivalent Design Issue (April 2026)

Problem: One MCP server receives tool requests from Copilot, but many servers they do not validate whether the request was sent by official Copilot or by a malicious client.

Impact: If an attacker compromises the local Copilot client (e.g. via malicious extension), could command third-party MCP servers without authorization.

Mitigation (implemented in v2.5+): - MCP servers now require authentication handshake (JWT) - Sandbox filesystem + network limits (see section 5) - Allowlist of tools available for each client

MCP-secure configuration with aggressive limitations
{
  "mcpServers": {
    "postgres-prod": {
      "command": "node",
      "args": ["/usr/local/lib/mcp-server-postgres-secure.js"],
      "env": {
        "DATABASE_URL": "${env:DATABASE_URL}",
        "DB_USER": "${env:DB_USER}",
        "DB_PASSWORD": "${env:DB_PASSWORD}",
        "ALLOWED_TABLES": "users,orders,payments",
        "ALLOW_WRITES": "false",
        "ALLOW_DELETES": "false",
        "MAX_ROWS_PER_QUERY": "1000"
      },
      "sandbox": {
        "enabled": true,
        "allowedNetworkDomains": ["database.internal.mycompany.com"],
        "blockedNetworkDomains": ["*"]
      }
    },
    "untrusted-third-party": {
      "command": "node",
      "args": ["some-unknown-mcp-server"],
      "sandbox": {
        "enabled": true,
        "allowedPaths": ["${workspaceFolder}/public"],
        "blockedPaths": ["${workspaceFolder}/.env*", "${HOME}/.ssh"]
      }
    }
  }
}

MCP Security Best Practices

  • Third-party sandboxes: Any unofficial MCP server must run in a sandbox
  • Read-only by default: Enable write/delete only when necessary
  • Network domain whitelist: Restrict connections to known hosts
  • Audit logs: Log all MCP tool invocations (optional in settings)
  • Rotate secrets: API key, DB password, token required for MCP server must be rotated monthly
  • Minimal permissions: Use DB account with grant SELECT only, no ALTER/DROP

Conclusion

The Model Context Protocol represents a fundamental change in the way LLMs they access the context and use tools. Combined with custom instructions and specialized agents, MCP transforms Copilot from intelligent autocomplete a full-stack assistant that knows your codebase, your infrastructure, your databases, and your team tools.

Key Points

  • MCP is the standard: VS Code, JetBrains, Copilot CLI use the same protocol
  • One time setup: MCP server in ~/.copilot/mcp.json available everywhere
  • Hundreds of public servers: PostgreSQL, GitHub, Slack, Docker, Sentry, AWS, MongoDB
  • Custom server in a few hours: Python or Node.js, simple registration
  • Custom instructions hierarchy: Repo-scoped + on-demand .prompt.md + workspace settings
  • Custom agents: Specialized person with tool restriction and systemPrompt
  • Sandbox for security: Filesystem + network isolation for untrusted servers
  • Migration from GitHub App Extensions: completed by November 2025

In the next article we will explore the Copilot's advanced security: Proprietary JWT authentication, audit log, GDPR compliance, and best practices for enterprise environments. We will discover how Copilot integrates with corporate hardening policies.

Try These Tools

Free developer tools related to this topic.

Commenti

Caricamento commenti...

Sign in to comment

Discuss this article in the community

Join the Telegram group to discuss with other developers, ask questions and share your experiences.

Did you like this article?

Explore other content on the blog or discover my projects