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.mdfiles - 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
| # | Item | Focus |
|---|---|---|
| 1 | Claude as Technical Partner | Setup and first steps |
| 2 | Project Context and Setup | CLAUDE.md and configuration |
| 3 | Concept and Requirements | MVP and user personas |
| 4 | Backend and Frontend Architecture | Spring Boot and Angular |
| 5 | Structure of the Code | Organization and conventions |
| 6 | Advanced Engineering Prompt | Advanced techniques |
| 7 | Testing and quality | Strategies and test generation |
| 8 | Professional Documentation | README, API, ADR |
| 9 | Deploy and DevOps | Docker, CI/CD, monitoring |
| 10 | Evolution and Maintenance | Refactoring and scalability |
| 11 | Real Project Integration | Claude Code in production |
| 12 | Claude Code CLI | Commands and configuration |
| 13 | Agent Skills | modular capabilities |
| 14 | Specialized Subagents | Agenti con ruoli specifici |
| 15 | Hooks e Automazione | Event-driven workflows |
| 16 | Ralph Wiggum Method | Sviluppo guidato da test |
| 17 | BMAD Method | Gestione progetti strutturata |
| 18 | Orchestrazione Multi-Agente | Pipeline di agenti |
| 19 | Collaborative Work | Team e pair programming AI |
| 20 | Sicurezza e Best Practice | Hardening e compliance |
| 21 | Monitoring e Observability | Metriche e debugging |
| 22 | GitHub Copilot Pro | Funzionalità avanzate |
| 23 | Prompt Caching | Ottimizzazione costi e latenza |
| 24 | Copilot Workspace | Sviluppo full-stack collaborativo |
| 25 | MCP 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.
{
"[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.
{
"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:
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.jsonat boot and reports errors
{
"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.
~/.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)
| Context | Use | MCP 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.
{
"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/edocs/, can't read.envo~/.ssh, and cannot connect to any domain exceptapi.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:
== 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)
| Service | MCP Server | Main 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
| Tiers | File | Brooms | Precedence | Auto-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.
# 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.
> 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:
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
{
"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/.
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:
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)
| Server | Package | Use case | Authentication |
|---|---|---|---|
| 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 |
#!/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.
#!/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()
{
"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:
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
{
"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.jsonavailable 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.
Commenti
Caricamento commenti...
Sign in to comment