Programma
Il Model Context Protocol (MCP) è uno standard aperto che consente ai modelli linguistici di grandi dimensioni di interagire in modo dinamico con strumenti esterni, database e API tramite un'interfaccia standardizzata.
In questo blog ti guiderò nella creazione di un server per la revisione di PR basato su MCP che si integra con Claude Desktop. Questo server:
- Recupera i dettagli della PR e i file modificati da GitHub
- Analizza le modifiche al codice usando l'applicazione Claude Desktop
- Genera riepiloghi e suggerimenti per la revisione della PR
- Salva le revisioni su Notion
Useremo il Model Context Protocol (MCP) per standardizzare la comunicazione tra il server e Claude Desktop, rendendolo modulare e scalabile.
Teniamo i nostri lettori aggiornati sulle ultime novità dell'IA con The Median, la nostra newsletter gratuita del venerdì che riassume le notizie chiave della settimana. Iscriviti e resta sul pezzo in pochi minuti a settimana:
Che cos'è il Model Context Protocol (MCP)?
Il Model Context Protocol (MCP) è uno standard aperto sviluppato da Anthropic per facilitare un'integrazione semplice e standardizzata tra modelli di IA e strumenti esterni. Funziona come un connettore universale, permettendo ai large language model (LLM) di interagire in modo dinamico con API, database e applicazioni aziendali.
In origine creato per migliorare la capacità di Claude di interagire con sistemi esterni, Anthropic ha deciso di rendere open-source MCP all'inizio del 2024 per favorirne l'adozione a livello industriale. Rendendo MCP pubblico, l'obiettivo era creare un framework standardizzato per la comunicazione AI-strumenti, riducendo la dipendenza da integrazioni proprietarie e abilitando maggiore modularità e interoperabilità nelle applicazioni di IA.
MCP segue un'architettura client-server in cui:
- I client MCP (ad es., Claude Desktop) richiedono informazioni ed eseguono attività.
- I server MCP forniscono accesso a strumenti esterni e fonti di dati.
- Le applicazioni host usano MCP per comunicare tra modelli e strumenti.

Fonte: Model Context Protocol
Ecco perché potresti voler usare MCP nei tuoi progetti:
- Integrazione AI standardizzata: MCP fornisce un modo strutturato per collegare i modelli di IA agli strumenti.
- Flessibilità: permette di passare facilmente tra diversi modelli e vendor.
- Sicurezza: mantiene i tuoi dati all'interno della tua infrastruttura durante l'interazione con l'IA.
- Scalabilità: MCP supporta vari trasporti come stdio, WebSocket, HTTP SSE e socket UNIX.
Panoramica del progetto demo MCP: server di revisione PR
Il sistema di revisione delle PR automatizza l'analisi del codice e la documentazione usando Claude Desktop e Notion.
Ecco una sintesi della pipeline:
- Configurazione dell'ambiente: carica le credenziali di GitHub e Notion.
- Inizializzazione del server: avvia un server MCP per comunicare con Claude Desktop.
- Recupero dei dati della PR: ottiene le modifiche e i metadati della PR da GitHub.
- Analisi del codice: Claude Desktop analizza direttamente le modifiche al codice (nessuno strumento separato necessario).
- Documentazione su Notion: salva i risultati dell'analisi su Notion per il tracciamento.
Passaggio 1: configurazione dell'ambiente
Prima di iniziare, assicurati di avere installato Python 3.10+. Poi configuriamo l'ambiente e partiamo installando il gestore di pacchetti uv. Su Mac o Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh # Mac/Linux
Per Windows (PowerShell):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Poi creiamo una nuova directory di progetto e la inizializziamo con uv:
uv init pr_reviewer
cd pr_reviewer
Ora possiamo creare e attivare un ambiente virtuale. Su Mac o Linux:
uv venv
source .venv/bin/activate
Per Windows:
.venv\Scripts\activate
Ora installiamo le dipendenze richieste:
uv add "mcp[cli]" requests python-dotenv notion-client
Useremo uv al posto di conda per questo progetto perché è più veloce, leggero e focalizzato sulla gestione dei pacchetti Python. Ricapitoliamo cosa abbiamo appena fatto:
- Abbiamo configurato un ambiente di sviluppo per un server MCP di revisione PR di GitHub usando il gestore pacchetti uv
- Abbiamo inizializzato una nuova directory di progetto chiamata
pr_reviewere ci siamo spostati al suo interno. - Abbiamo creato un ambiente virtuale e lo abbiamo attivato per isolare le installazioni dei pacchetti.
Passaggio 2: installa le dipendenze
Una volta impostato l'ambiente, configuriamo le dipendenze con le chiavi API e gli altri requisiti. Crea un file requirements.txt e aggiungi i seguenti pacchetti Python:
# Core dependencies for PR Analyzer
requests>=2.31.0 # For GitHub API calls
python-dotenv>=1.0.0 # For environment variables
mcp[cli]>=1.4.0 # For MCP server functionality
notion-client>=2.3.0 # For Notion integration
# Optional: Pin versions for stability
# requests==2.31.0
# python-dotenv==1.0.0
# mcp[cli]==1.4.0
# notion-client==2.3.0
Il file requirements.txt contiene tutte le dipendenze principali richieste per il progetto. Per configurarle, esegui uno dei seguenti comandi (usa uv se lo hai installato prima).
uv pip install -r requirements.txt
pip install -r requirements.txt
Ora il tuo ambiente ha tutte le dipendenze richieste installate.
Passaggio 3: configurazione delle variabili d'ambiente
Ora creiamo un file .env che contiene tutte le chiavi e i token necessari per questo progetto.
Generare i token di GitHub
Per generare i token di GitHub:
- Accedi al tuo account GitHub e vai alle impostazioni.
- Vai su impostazioni sviluppatore → Personal Access Tokens.
- Clicca su Generate New Token e seleziona la versione classica.
- Assegna un nome al token e abilita le seguenti autorizzazioni:
- read:org
- read:repo_hook
- repo
- Clicca su Generate per creare il token.
- Copia e conserva il token in modo sicuro: servirà per l'autenticazione nelle richieste API.
Integrazioni Notion
- Accedi alla pagina delle integrazioni di Notion.
- Crea una nuova integrazione e compila il form. Mantieni il “type” su Internal e aggiungila al tuo workspace.

- Salva l'integrazione e copia il link dell'integrazione (l'UUID alla fine dell'URL è l'Universally Unique Identifier che devi annotare e usare come Notion Page ID).
https://www.notion.so/profile/integrations/internal/UUID
- Dopo aver creato l'integrazione, cliccaci sopra e, nella configurazione, copia l'Internal Integration Secret, che sarà la tua chiave API di Notion.
Creare un file .env
Ora crea un file .env e aggiungi il seguente testo insieme alle chiavi API e al token che abbiamo generato sopra.
GITHUB_TOKEN=your_github_token
NOTION_API_KEY=your_notion_api_key
NOTION_PAGE_ID=your_notion_page_id
Passaggio 4: integrazione con GitHub
Configuriamo il nostro modulo di integrazione con GitHub per gestire e recuperare le modifiche delle PR da un repository GitHub.
Crea un file github_integration.py e scrivi il seguente codice (lo spiegheremo tra poco).
import os
import requests
import traceback
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
GITHUB_TOKEN = os.getenv('GITHUB_TOKEN')
def fetch_pr_changes(repo_owner: str, repo_name: str, pr_number: int) -> list:
"""Fetch changes from a GitHub pull request.
Args:
repo_owner: The owner of the GitHub repository
repo_name: The name of the GitHub repository
pr_number: The number of the pull request to analyze
Returns:
A list of file changes with detailed information about each change
"""
print(f" Fetching PR changes for {repo_owner}/{repo_name}#{pr_number}")
# Fetch PR details
pr_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/pulls/{pr_number}"
files_url = f"{pr_url}/files"
headers = {'Authorization': f'token {GITHUB_TOKEN}'}
try:
# Get PR metadata
pr_response = requests.get(pr_url, headers=headers)
pr_response.raise_for_status()
pr_data = pr_response.json()
# Get file changes
files_response = requests.get(files_url, headers=headers)
files_response.raise_for_status()
files_data = files_response.json()
# Combine PR metadata with file changes
changes = []
for file in files_data:
change = {
'filename': file['filename'],
'status': file['status'], # added, modified, removed
'additions': file['additions'],
'deletions': file['deletions'],
'changes': file['changes'],
'patch': file.get('patch', ''), # The actual diff
'raw_url': file.get('raw_url', ''),
'contents_url': file.get('contents_url', '')
}
changes.append(change)
# Add PR metadata
pr_info = {
'title': pr_data['title'],
'description': pr_data['body'],
'author': pr_data['user']['login'],
'created_at': pr_data['created_at'],
'updated_at': pr_data['updated_at'],
'state': pr_data['state'],
'total_changes': len(changes),
'changes': changes
}
print(f"Successfully fetched {len(changes)} changes")
return pr_info
except Exception as e:
print(f"Error fetching PR changes: {str(e)}")
traceback.print_exc()
return None
# Example usage for debugging
# pr_data = fetch_pr_changes('owner', 'repo', 1)
# print(pr_data)
La funzione fetch_pr_changes() recupera e restituisce le modifiche da una specifica pull request di GitHub. Accetta tre parametri, ovvero repo_owner, repo_name e pr_number, e restituisce un elenco strutturato di modifiche ai file insieme ai metadati della PR.
Il codice usa la libreria requests per inviare richieste HTTP GET autenticate, ottenendo sia i metadati generali della PR sia i dettagli delle modifiche a livello di file:
- La prima richiesta API recupera le informazioni di alto livello della PR, inclusi titolo, descrizione, dettagli dell'autore, timestamp e stato corrente.
- La seconda richiesta API recupera i dettagli su ciascun file modificato nella PR, come nome file, stato della modifica, numero di righe aggiunte o rimosse e URL per accedere ai contenuti dei file.
Una volta recuperati i dati, la funzione struttura e combina i metadati della PR con le modifiche ai file in un dizionario. Le modifiche ai file sono memorizzate in una lista, con ogni voce che contiene informazioni dettagliate su un file. La struttura finale include titolo e descrizione della PR, autore, timestamp, stato, conteggio totale dei file modificati e una panoramica dettagliata delle modifiche ai file.
Passaggio 5: implementare il server MCP
Ora che abbiamo tutte le dipendenze e le funzioni di supporto, configuriamo il nostro server MCP. Creiamo un file pr_analyzer.py, che:
- Inizializza un server MCP.
- Definisce strumenti per recuperare i dettagli della PR, analizzare il codice e archiviare i risultati su Notion.
- Espone questi strumenti a Claude Desktop per riassunti, soluzioni possibili e altro.
Aggiungiamo prima il codice e lo spieghiamo dopo
import sys
import os
import traceback
from typing import Any, List, Dict
from mcp.server.fastmcp import FastMCP
from github_integration import fetch_pr_changes
from notion_client import Client
from dotenv import load_dotenv
class PRAnalyzer:
def __init__(self):
# Load environment variables
load_dotenv()
# Initialize MCP Server
self.mcp = FastMCP("github_pr_analysis")
print("MCP Server initialized", file=sys.stderr)
# Initialize Notion client
self._init_notion()
# Register MCP tools
self._register_tools()
def _init_notion(self):
"""Initialize the Notion client with API key and page ID."""
try:
self.notion_api_key = os.getenv("NOTION_API_KEY")
self.notion_page_id = os.getenv("NOTION_PAGE_ID")
if not self.notion_api_key or not self.notion_page_id:
raise ValueError("Missing Notion API key or page ID in environment variables")
self.notion = Client(auth=self.notion_api_key)
print(f"Notion client initialized successfully", file=sys.stderr)
print(f"Using Notion page ID: {self.notion_page_id}", file=sys.stderr)
except Exception as e:
print(f"Error initializing Notion client: {str(e)}", file=sys.stderr)
traceback.print_exc(file=sys.stderr)
sys.exit(1)
def _register_tools(self):
"""Register MCP tools for PR analysis."""
@self.mcp.tool()
async def fetch_pr(repo_owner: str, repo_name: str, pr_number: int) -> Dict[str, Any]:
"""Fetch changes from a GitHub pull request."""
print(f"Fetching PR #{pr_number} from {repo_owner}/{repo_name}", file=sys.stderr)
try:
pr_info = fetch_pr_changes(repo_owner, repo_name, pr_number)
if pr_info is None:
print("No changes returned from fetch_pr_changes", file=sys.stderr)
return {}
print(f"Successfully fetched PR information", file=sys.stderr)
return pr_info
except Exception as e:
print(f"Error fetching PR: {str(e)}", file=sys.stderr)
traceback.print_exc(file=sys.stderr)
return {}
@self.mcp.tool()
async def create_notion_page(title: str, content: str) -> str:
"""Create a Notion page with PR analysis."""
print(f"Creating Notion page: {title}", file=sys.stderr)
try:
self.notion.pages.create(
parent={"type": "page_id", "page_id": self.notion_page_id},
properties={"title": {"title": [{"text": {"content": title}}]}},
children=[{
"object": "block",
"type": "paragraph",
"paragraph": {
"rich_text": [{
"type": "text",
"text": {"content": content}
}]
}
}]
)
print(f"Notion page '{title}' created successfully!", file=sys.stderr)
return f"Notion page '{title}' created successfully!"
except Exception as e:
error_msg = f"Error creating Notion page: {str(e)}"
print(error_msg, file=sys.stderr)
traceback.print_exc(file=sys.stderr)
return error_msg
def run(self):
"""Start the MCP server."""
try:
print("Running MCP Server for GitHub PR Analysis...", file=sys.stderr)
self.mcp.run(transport="stdio")
except Exception as e:
print(f"Fatal Error in MCP Server: {str(e)}", file=sys.stderr)
traceback.print_exc(file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
analyzer = PRAnalyzer()
analyzer.run()
Il codice sopra configura un server MCP per recuperare le modifiche delle PR di GitHub e archiviare i risultati dell'analisi su Notion. Vediamo i componenti chiave:
- Configurazione e inizializzazione dell'ambiente
- Il modulo
dotenvcarica le variabili d'ambiente, garantendo l'accesso sicuro a chiavi API e credenziali. - Poi, la classe
PRAnalyzerinizializza un server MCP usando la funzioneFastMCP()che avvia il server MCP con il nomegithub_pr_analysise abilita l'interazione con l'applicazione Claude Desktop. - Il client Notion è anch'esso configurato usando il pacchetto notion-client, che utilizza la chiave API di Notion e l'ID della pagina salvati nel file
.env. - Strumento MCP: recupero delle modifiche della PR
- La funzione
fetch_pr()recupera i metadati della pull request da GitHub usando il metodofetch_pr_changes()del filegithub_integration.py. Se ha successo, restituisce un dizionario con i dettagli della PR. - Puoi automatizzare questo processo usando la libreria Webhooks integrata in GitHub, in modo che ogni nuova PR creata sul tuo repository venga elaborata automaticamente dal server.
- Strumento MCP: crea una pagina Notion
- La funzione
create_notion_page()genera una pagina Notion con i risultati dell'analisi della PR. - Usa l'API di Notion per creare una nuova pagina sotto lo workspace Notion specificato.
- Esecuzione del server
- Il metodo
run()avvia il server MCP usando mcp.run(transport="stdio"), abilitando l'interazione tra Claude Desktop e gli strumenti di revisione PR.
Passaggio 6: eseguire il server MCP
Ora che abbiamo tutti i pezzi di codice pronti, eseguiamo il nostro server con il seguente comando da terminale:
python pr_analyzer.py


Una volta che il server è attivo e in esecuzione, apri l'applicazione Claude Desktop: vedrai un'icona della spina (🔌) nella casella di testo. Questa icona indica la presenza di un MCP nell'ambiente di Claude. Nella stessa casella di testo, noterai un'icona a forma di martello (🔨) che mostra tutti gli MCP disponibili, come illustrato di seguito.

Ora passa il link alla PR che vuoi analizzare e Claude farà il resto.

Claude analizzerà prima la PR e poi fornirà un riepilogo e una revisione. Chiederà all'utente se vuole caricare i dettagli sulla pagina Notion. Anche se puoi automatizzare questo processo, il codice attuale ti consente di rivedere il riepilogo prima di creare una nuova pagina Notion.

La pagina Notion aggiornata appare così:

Conclusione
Il nostro server per la revisione delle PR basato su MCP migliora l'analisi del codice e la documentazione, rendendo il processo di revisione più efficiente e organizzato. Grazie a MCP, all'API di GitHub e all'integrazione con Notion, questo sistema supporta l'analisi automatizzata delle PR, una collaborazione semplice e una documentazione strutturata. Con questa configurazione, gli sviluppatori possono recuperare rapidamente i dettagli delle PR, analizzare le modifiche al codice con Claude e archiviare gli insight su Notion per consultazioni future.
Per esplorare altri strumenti di IA recenti, ti consiglio questi blog:
Sono una Google Developers Expert in ML (Gen AI), una Kaggle 3x Expert e una Women Techmakers Ambassador con oltre 3 anni di esperienza nel tech. Ho co-fondato una startup health-tech nel 2020 e sto conseguendo un master in informatica al Georgia Tech, con specializzazione in machine learning.


