Leerpad
Het Model Context Protocol (MCP) is een open standaard waarmee large language models via een gestandaardiseerde interface dynamisch kunnen communiceren met externe tools, databases en API’s.
In deze blog laat ik je stap voor stap zien hoe je een MCP-aangedreven PR-reviewserver bouwt die integreert met Claude Desktop. Deze server zal:
- PR-details en gewijzigde bestanden ophalen van GitHub
- Codewijzigingen analyseren met de Claude Desktop-applicatie
- Samenvattingen en suggesties voor PR-reviews genereren
- Reviews opslaan in Notion
We gebruiken het Model Context Protocol (MCP) om de communicatie tussen de server en Claude Desktop te standaardiseren, waardoor het modulair en schaalbaar wordt.
We houden onze lezers op de hoogte van het laatste AI-nieuws via The Median, onze gratis vrijdagse nieuwsbrief met de belangrijkste verhalen van de week. Abonneer je en blijf scherp in slechts een paar minuten per week:
Wat is het Model Context Protocol (MCP)?
Het Model Context Protocol (MCP) is een open standaard, ontwikkeld door Anthropic, die een eenvoudige en gestandaardiseerde integratie tussen AI-modellen en externe tools mogelijk maakt. Het fungeert als een universele connector, zodat large language models (LLM’s) dynamisch kunnen communiceren met API’s, databases en bedrijfsapplicaties.
MCP is oorspronkelijk gebouwd om Claude beter met externe systemen te laten communiceren. Anthropic besloot om MCP begin 2024 open-source te maken om brede adoptie in de industrie te stimuleren. Door MCP publiek beschikbaar te maken, wilden ze een gestandaardiseerd raamwerk creëren voor communicatie tussen AI en tools, zodat de afhankelijkheid van propriëtaire integraties afneemt en AI-toepassingen modularer en interoperabeler worden.
MCP volgt een client-serverarchitectuur waarbij:
- MCP-clients (zoals Claude Desktop) informatie opvragen en taken uitvoeren.
- MCP-servers toegang bieden tot externe tools en databronnen.
- Hostapplicaties MCP gebruiken om tussen modellen en tools te communiceren.

Bron: Model Context Protocol
Waarom zou je MCP in je projecten gebruiken?
- Gestandaardiseerde AI-integratie: MCP biedt een gestructureerde manier om AI-modellen met tools te verbinden.
- Flexibiliteit: Je kunt eenvoudig wisselen tussen verschillende AI-modellen en -leveranciers.
- Veiligheid: Je data blijft binnen je eigen infrastructuur terwijl je met AI werkt.
- Schaalbaarheid: MCP ondersteunt verschillende transports zoals stdio, WebSockets, HTTP SSE en UNIX-sockets.
MCP-demoprojectoverzicht: PR-reviewserver
Het PR-reviewsysteem automatiseert codeanalyse en documentatie met Claude Desktop en Notion.
Hier is een beknopt overzicht van de pipeline:
- Omgevingsinstellingen: Laad de GitHub- en Notion-inloggegevens.
- Serverinitialisatie: Start een MCP-server om met Claude Desktop te communiceren.
- PR-gegevens ophalen: Haal de PR-wijzigingen en metadata op van GitHub.
- Codeanalyse: Claude Desktop analyseert direct de codewijzigingen (geen aparte tool nodig).
- Notion-documentatie: Sla de analyseresultaten op in Notion voor opvolging.
Stap 1: De omgeving instellen
Zorg dat je Python 3.10+ hebt geïnstalleerd voordat je begint. Daarna richten we de omgeving in en starten we met het installeren van de pakketmanager uv. Voor Mac of Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh # Mac/Linux
Voor Windows (PowerShell):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Maak vervolgens een nieuwe projectmap aan en initialiseer deze met uv:
uv init pr_reviewer
cd pr_reviewer
We kunnen nu een virtuele omgeving aanmaken en activeren. Voor Mac of Linux:
uv venv
source .venv/bin/activate
Voor Windows:
.venv\Scripts\activate
Installeer nu de vereiste dependencies:
uv add "mcp[cli]" requests python-dotenv notion-client
We gebruiken uv in plaats van conda voor dit project omdat het sneller en lichter is en zich meer richt op Python-pakketbeheer. Even samenvatten wat we zojuist hebben gedaan:
- We hebben een ontwikkelomgeving opgezet voor een GitHub PR Review MCP-server met de uv-pakketmanager
- We hebben een nieuwe projectmap
pr_revieweraangemaakt en ernaartoe genavigeerd. - We hebben een virtuele omgeving aangemaakt en geactiveerd, zodat pakketinstallaties geïsoleerd zijn.
Stap 2: Dependencies installeren
Zodra onze omgeving staat, zetten we onze dependencies klaar met de API-sleutels en andere vereisten. Maak een bestand requirements.txt en voeg de volgende Python-pakketten toe:
# 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
Het bestand requirements.txt bevat alle kerndependencies voor het project. Voer een van de volgende commando’s uit om de dependencies te installeren (gebruik uv als je dat eerder hebt geïnstalleerd).
uv pip install -r requirements.txt
pip install -r requirements.txt
Je omgeving heeft nu alle vereiste dependencies geïnstalleerd.
Stap 3: Omgevingsvariabelen instellen
Maak vervolgens een .env-bestand aan met alle sleutels en tokens die voor dit project nodig zijn.
GitHub-tokens genereren
Zo genereer je GitHub-tokens:
- Log in op je GitHub-account en ga naar Instellingen.
- Ga naar Developer settings → Personal Access Tokens.
- Klik op Generate New Token en kies de klassieke versie.
- Geef het token een naam en zet de volgende permissies aan:
- read:org
- read:repo_hook
- repo
- Klik op Generate om het token te maken.
- Kopieer en bewaar het token veilig; het wordt gebruikt voor authenticatie bij API-verzoeken.
Notion-integraties
- Log in op Notion’s integratiepagina.
- Maak een nieuwe integratie en vul het formulier in. Laat “type” op Internal staan en voeg deze toe aan je workspace.

- Sla de integratie op en kopieer de integratielink (de UUID aan het einde van de URL is de Universally Unique Identifier die je moet noteren en gebruiken als de Notion Page ID).
https://www.notion.so/profile/integrations/internal/UUID
- Klik na het maken van de integratie erop en kopieer onder configuration het Internal Integration Secret, dit is je Notion API key.
Een .env-bestand maken
Maak nu een .env-bestand en voeg de volgende tekst toe, samen met de API-sleutels en het token die we hierboven hebben gegenereerd.
GITHUB_TOKEN=your_github_token
NOTION_API_KEY=your_notion_api_key
NOTION_PAGE_ID=your_notion_page_id
Stap 4: GitHub-integratie
Laten we onze GitHub-integratiemodule configureren om PR-wijzigingen uit een GitHub-repository te beheren en op te halen.
Maak een bestand github_integration.py en schrijf de volgende code (we leggen het zo uit).
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)
De functie fetch_pr_changes() haalt wijzigingen op uit een opgegeven GitHub-pullrequest en geeft ze terug. Ze neemt drie parameters, namelijk repo_owner, repo_name en pr_number, en retourneert een gestructureerde lijst met bestandswijzigingen plus PR-metadata.
De code gebruikt de requests-bibliotheek om geauthenticeerde HTTP GET-verzoeken te versturen en zowel algemene PR-metadata als gedetailleerde bestandswijzigingen op te halen:
- Het eerste API-verzoek haalt PR-informatie op hoog niveau op, waaronder titel, beschrijving, auteur, tijdstempels en huidige status.
- Het tweede API-verzoek haalt details op over elk gewijzigd bestand in de PR, zoals bestandsnaam, wijzigingsstatus, aantal toegevoegde of verwijderde regels en URL’s om de inhoud te benaderen.
Zodra de gegevens zijn opgehaald, structureert de functie de PR-metadata samen met de bestandswijzigingen in een dictionary. De bestandswijzigingen worden opgeslagen in een lijst, waarbij elk item gedetailleerde informatie over een bestand bevat. De uiteindelijke datastructuur omvat de PR-titel, beschrijving, auteur, tijdstempels, status, totaal aantal gewijzigde bestanden en een gedetailleerd overzicht van de bestandsmodificaties.
Stap 5: De MCP-server implementeren
Nu we alle dependencies en extra functies hebben, richten we onze MCP-server in. We maken een bestand pr_analyzer.py, dat het volgende doet:
- Een MCP-server initialiseren.
- Tools definiëren om PR-details op te halen, code te analyseren en resultaten in Notion op te slaan.
- Deze tools beschikbaar maken voor Claude Desktop voor samenvattingen, mogelijke oplossingen en meer.
Laten we eerst de code toevoegen en die daarna toelichten
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()
De bovenstaande code zet een MCP-server op om GitHub-PR-wijzigingen op te halen en de analyseresultaten in Notion op te slaan. De belangrijkste onderdelen:
- Omgevingsinstellingen en initialisatie
- De module
dotenvlaadt omgevingsvariabelen, zodat API-sleutels en inloggegevens veilig toegankelijk zijn. - Vervolgens initialiseert de klasse
PRAnalyzereen MCP-server met de functieFastMCP(), met de naamgithub_pr_analysis, waarmee interactie met de Claude Desktop-app mogelijk wordt. - De Notion-client wordt ingesteld met het notion-client-pakket en gebruikt de Notion API key en page ID uit het
.env-bestand. - MCP-tool: PR-wijzigingen ophalen
- De functie
fetch_pr()haalt PR-metadata op van GitHub via de methodefetch_pr_changes()uit het bestandgithub_integration.py. Bij succes retourneert ze een dictionary met PR-details. - Je kunt dit proces automatiseren met de Webhooks-bibliotheek in GitHub, zodat elke nieuwe PR in je repository automatisch door de server wordt verwerkt.
- MCP-tool: een Notion-pagina maken
- De functie
create_notion_page()maakt een Notion-pagina met de PR-analyseresultaten. - Ze gebruikt de Notion API om een nieuwe pagina te maken in de opgegeven Notion-werkruimte.
- Serveruitvoering
- De methode
run()start de MCP-server met mcp.run(transport="stdio"), waardoor interactie tussen Claude Desktop en de PR-reviewtools mogelijk wordt.
Stap 6: De MCP-server draaien
Nu alle code op z’n plek staat, starten we onze server met het volgende terminalcommando:
python pr_analyzer.py


Zodra de server draait, open je de Claude Desktop-applicatie. Je ziet een stekkerpictogram (🔌) in het tekstveld. Deze stekker geeft aan dat er een MCP aanwezig is in de Claude-omgeving. In hetzelfde tekstveld zie je een hamerachtig pictogram (🔨) dat alle beschikbare MCP’s toont, zoals hieronder weergegeven.

Geef nu de link door naar de PR die je wilt analyseren en Claude doet de rest.

Claude analyseert eerst de PR en geeft vervolgens een samenvatting en review. Daarna vraagt hij of je de details naar de Notion-pagina wilt uploaden. Je kunt dat proces automatiseren, maar met de huidige code kun je de samenvatting eerst beoordelen voordat je een nieuwe Notion-pagina aanmaakt.

De bijgewerkte Notion-pagina ziet er zo uit:

Conclusie
Onze op MCP gebaseerde PR-reviewserver verbetert codeanalyse en documentatie, waardoor het reviewproces efficiënter en georganiseerder wordt. Met MCP, de GitHub-API en Notion-integratie ondersteunt dit systeem geautomatiseerde PR-analyse, eenvoudige samenwerking en gestructureerde documentatie. Met deze configuratie kunnen developers snel PR-details ophalen, codewijzigingen met Claude analyseren en inzichten in Notion opslaan voor later gebruik.
Wil je meer recente AI-tools verkennen? Dan raad ik deze blogs aan:
Ik ben een Google Developers Expert in ML (Gen AI), een Kaggle 3x Expert en een Women Techmakers Ambassador met meer dan 3 jaar ervaring in tech. In 2020 heb ik een healthtech-startup mee opgericht en ik volg een master computer science aan Georgia Tech, met als specialisatie machine learning.

