Ga naar hoofdinhoud

Model Context Protocol (MCP): een gids met demoproject

Leer hoe je een MCP-server bouwt met Anthropics Model Context Protocol om Claude te verbinden met GitHub en Notion.
Bijgewerkt 2 jun 2026  · 12 min lezen

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:

  1. Omgevingsinstellingen: Laad de GitHub- en Notion-inloggegevens.
  2. Serverinitialisatie: Start een MCP-server om met Claude Desktop te communiceren.
  3. PR-gegevens ophalen: Haal de PR-wijzigingen en metadata op van GitHub.
  4. Codeanalyse: Claude Desktop analyseert direct de codewijzigingen (geen aparte tool nodig).
  5. 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_reviewer aangemaakt 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:

  1. Omgevingsinstellingen en initialisatie
    • De module dotenv laadt omgevingsvariabelen, zodat API-sleutels en inloggegevens veilig toegankelijk zijn. 
    • Vervolgens initialiseert de klasse PRAnalyzer een MCP-server met de functie FastMCP(), met de naam github_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.
  2. MCP-tool: PR-wijzigingen ophalen
    • De functie fetch_pr() haalt PR-metadata op van GitHub via de methode fetch_pr_changes() uit het bestand github_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. 
  3. 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.
  4. 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

Terminal voor het draaien van de MCP-server

Terminal voor het draaien van MCP-server

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 genereert samenvatting

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.

Claude uploadt samenvatting naar Notion

De bijgewerkte Notion-pagina ziet er zo uit:

Notion-pagina gemaakt door Claude MCP

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:


Aashi Dutt's photo
Author
Aashi Dutt
LinkedIn
Twitter

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.

Onderwerpen

Leer AI met deze cursussen!

Leerpad

AI-toepassingen ontwikkelen

21 Hr
Leer AI-apps maken met de nieuwste AI-ontwikkelaarstools, zoals de OpenAI API, Hugging Face en LangChain.
Bekijk detailsRight Arrow
Begin met de cursus
Meer zienRight Arrow
Gerelateerd

blog

AI vanaf nul leren in 2026: een complete gids van de experts

Ontdek alles wat je moet weten om in 2026 AI te leren, van tips om te beginnen tot handige resources en inzichten van industrie-experts.
Adel Nehme's photo

Adel Nehme

15 min

Meer zienMeer zien