Direkt zum Inhalt

Model Context Protocol (MCP): Ein Leitfaden mit Demo-Projekt

Lerne, wie du einen MCP-Server mit dem Model Context Protocol von Anthropic aufbaust, um Claude mit GitHub und Notion zu verbinden.
Aktualisierte 17. März 2025  · 12 Min. Lesezeit

Das Model Context Protocol (MCP) ist ein offener Standard, der es großen Sprachmodellen ermöglicht, über eine standardisierte Schnittstelle dynamisch mit externen Tools, Datenbanken und APIs zu interagieren.

In diesem Blog führe ich dich durch den Aufbau eines MCP-gestützten PR-Review-Servers, der mit Claude Desktop integriert ist. Dieser Server wird:

  • PR-Details und geänderte Dateien von GitHub abrufen
  • Analysiere Codeänderungen mit der Claude Desktop Anwendung
  • Zusammenfassungen und Vorschläge für PR-Reviews erstellen
  • Bewertungen auf Notion speichern

Wir werden das Model Context Protocol (MCP) verwenden, um die Kommunikation zwischen dem Server und Claude Desktop zu standardisieren und damit modular und skalierbar zu machen.

Was ist das Model Context Protocol (MCP)?

Das Model Context Protocol (MCP) ist ein offener Standard, der von Anthropic entwickelt wurde, um eine einfache und standardisierte Integration zwischen KI-Modellen und externen Tools zu ermöglichen. Es fungiert als universeller Konnektor, der es großen Sprachmodellen (LLMs) ermöglicht, dynamisch mit APIs, Datenbanken und Geschäftsanwendungen zu interagieren.

Ursprünglich wurde MCP entwickelt, um die Interaktion von Claude mit externen Systemen zu verbessern. Anthropic beschloss, MCP Anfang 2024 als Open Source zu veröffentlichen, um eine branchenweite Verbreitung zu fördern. Indem sie MCP öffentlich zugänglich machten, wollten sie ein standardisiertes Framework für die Kommunikation zwischen KI und Tools schaffen, das die Abhängigkeit von proprietären Integrationen verringert und eine größere Modularität und Interoperabilität zwischen KI-Anwendungen ermöglicht.

MCP basiert auf einer Client-Server-Architektur:

  • MCP-Clients (z. B. Claude Desktop) fordern Informationen an und führen Aufgaben aus.
  • MCP-Server bieten Zugang zu externen Tools und Datenquellen.
  • Host-Anwendungen verwenden MCP, um zwischen Modellen und Tools zu kommunizieren.

Quelle: Modell-Kontext-Protokoll

Hier erfährst du, warum du MCP für deine Projekte nutzen solltest:

  • Standardisierte KI-Integration: MCP bietet einen strukturierten Weg, KI-Modelle mit Tools zu verbinden.
  • Flexibilität: Es ermöglicht einen einfachen Wechsel zwischen verschiedenen KI-Modellen und Anbietern.
  • Sicherheit: So bleiben deine Daten in deiner Infrastruktur, während du mit KI interagierst.
  • Skalierbarkeit: MCP unterstützt verschiedene Transportwege wie stdio, WebSockets, HTTP SSE und UNIX-Sockets.

MCP Demo-Projekt Übersicht: PR Review Server

Das PR-Review-System automatisiert die Codeanalyse und -dokumentation mit Claude Desktop und Notion.

Hier ist eine kurze Übersicht über die Pipeline:

  1. Umgebung einrichten: Lade die Anmeldedaten von GitHub und Notion.
  2. Server-Initialisierung: Starte einen MCP-Server, um mit Claude Desktop zu kommunizieren.
  3. Abruf von PR-Daten: Rufe die PR-Änderungen und Metadaten von GitHub ab.
  4. Code-Analyse: Claude Desktop analysiert Codeänderungen direkt (kein separates Tool erforderlich).
  5. Begriffsdokumentation: Speichere die Analyseergebnisse zur Nachverfolgung in Notion.

Schritt 1: Einrichten der Umgebung

Bevor wir beginnen, solltest du sicherstellen, dass du Python 3.10+ installiert hast. Dann richten wir unsere Umgebung ein und beginnen mit der Installation des uv Paketmanagers. Für Mac oder Linux: 

curl -LsSf https://astral.sh/uv/install.sh | sh  # Mac/Linux

Für Windows (PowerShell):

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Dann erstellen wir ein neues Projektverzeichnis und initialisieren es mit uv:

uv init pr_reviewer
cd pr_reviewer

Wir können jetzt eine virtuelle Umgebung erstellen und aktivieren. Für Mac oder Linux:

uv venv
source .venv/bin/activate

Für Windows:

.venv\Scripts\activate

Jetzt installieren wir die erforderlichen Abhängigkeiten:

uv add "mcp[cli]" requests python-dotenv notion-client

Wir werden uv gegenüber conda für dieses Projekt verwenden, weil es schneller und leichter ist und sich mehr auf die Verwaltung von Python-Paketen konzentriert. Lass uns rekapitulieren, was wir gerade getan haben:

  • Wir haben eine GitHub PR Review MCP Server Entwicklungsumgebung mit dem uv Paketmanager eingerichtet
  • Wir haben ein neues Projektverzeichnis mit dem Namen pr_reviewer angelegt und dorthin navigiert.
  • Wir haben eine virtuelle Umgebung erstellt und sie aktiviert, um sicherzustellen, dass die Paketinstallationen isoliert sind.

Schritt 2: Abhängigkeiten installieren

Sobald unsere Umgebung eingerichtet ist, richten wir unsere Abhängigkeiten mit den API-Schlüsseln und anderen Anforderungen ein. Erstelle eine requirements.txt Datei und füge ihr die folgenden Python-Pakete hinzu:

# 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

Die Datei requirements.txt enthält alle Kernabhängigkeiten, die für das Projekt benötigt werden. Um die Abhängigkeiten einzurichten, führe einen der folgenden Befehle aus (verwende uv, wenn du es bereits installiert hast).

uv pip install -r requirements.txt
pip install -r requirements.txt

Jetzt hat deine Umgebung alle erforderlichen Abhängigkeiten installiert.

Schritt 3: Einrichten der Umgebungsvariablen

Als Nächstes erstellen wir eine .env Datei, die alle für dieses Projekt benötigten Schlüssel und Token enthält. 

GitHub-Tokens generieren

So generierst du GitHub-Tokens:

  • Melde dich bei deinem GitHub-Konto an und gehe zu den Einstellungen.
  • Gehe zu Entwicklereinstellungen → Persönliche Zugangstoken.
  • Klicke auf Neuen Token generieren und wähle die klassische Version.
  • Gib einen Namen für das Token an und aktiviere die folgenden Berechtigungen:
    • lesen:org
    • read:repo_hook
    • repo
  • Klicke auf Erzeugen um das Token zu erstellen.
  • Kopiere das Token und bewahre es sicher auf, da es für die Authentifizierung bei API-Anfragen verwendet wird.

Notion Integrationen

  • Speichere die Integration und kopiere den Integrationslink https://www.notion.so/profile/integrations/internal/UUID. Die UUID am Ende der URL ist der Universally Unique Identifier, den du dir notieren und als Notion Page ID verwenden musst.
  • Nachdem die Integration erstellt wurde, klicke sie an und kopiere unter Konfiguration das Interne Integrationsgeheimnis, das ist dann dein Notion API-Schlüssel.

Erstellen einer .env Datei

Erstelle nun eine .env Datei und füge den folgenden Text zusammen mit den API-Schlüsseln und dem Token hinzu, die wir oben erstellt haben.

GITHUB_TOKEN=your_github_token
NOTION_API_KEY=your_notion_api_key
NOTION_PAGE_ID=your_notion_page_id

Schritt 4: GitHub Integration

Konfigurieren wir unser GitHub-Integrationsmodul, um PR-Änderungen aus einem GitHub-Repository zu verwalten und abzurufen.

Erstelle eine github_integration.py Datei und schreibe den folgenden Code (wir werden ihn gleich erklären).

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) 

Die Funktion fetch_pr_changes() ruft die Änderungen einer bestimmten GitHub-Pull-Anfrage ab und gibt sie zurück. Sie benötigt drei Parameter, nämlich repo_owner, repo_name und pr_number, und gibt eine strukturierte Liste von Datei-Änderungen zusammen mit PR-Metadaten zurück.

Der Code verwendet die Bibliothek requests, um authentifizierte HTTP-GET-Anfragen zu senden und sowohl allgemeine PR-Metadaten als auch detaillierte Änderungen auf Dateiebene abzurufen:

  • Die erste API-Anfrage ruft die wichtigsten PR-Informationen ab, darunter Titel, Beschreibung, Autorendetails, Zeitstempel und den aktuellen Status.
  • Die zweite API-Anfrage holt Details zu jeder in der PR geänderten Datei ein, z. B. den Dateinamen, den Änderungsstatus, die Anzahl der hinzugefügten oder entfernten Zeilen und die URLs für den Zugriff auf die Dateiinhalte.

Sobald die Daten abgerufen sind, strukturiert die Funktion die PR-Metadaten und kombiniert sie mit den Datei-Änderungen in einem Wörterbuch. Die Datei-Änderungen werden in einer Liste gespeichert, wobei jeder Eintrag detaillierte Informationen über eine Datei enthält. Die endgültige Datenstruktur enthält den PR-Titel, die Beschreibung, den Autor, die Zeitstempel, den Status, die Gesamtzahl der geänderten Dateien und eine detaillierte Aufschlüsselung der Dateiänderungen.

Schritt 5: Implementierung des MCP-Servers

Nachdem wir nun alle Abhängigkeiten und Zusatzfunktionen eingerichtet haben, richten wir unseren MCP-Server ein. Wir erstellen eine pr_anayzer.py Datei, die:

  • Initialisiere einen MCP-Server.
  • Definiere Werkzeuge, um PR-Details abzurufen, den Code zu analysieren und die Ergebnisse in Notion zu speichern.
  • Stelle diese Tools auf Claude Desktop vor, um sie zusammenzufassen, mögliche Lösungen zu finden und mehr.

Fügen wir zuerst den Code ein und erklären ihn danach 

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() 

Der obige Code richtet einen MCP Server ein, um GitHub PR-Änderungen abzurufen und speichert die Analyseergebnisse in Notion. Schauen wir uns die wichtigsten Komponenten an:

  1. Einrichtung und Initialisierung der Umgebung
    • Das Modul dotenv lädt Umgebungsvariablen und sorgt dafür, dass der Zugriff auf API-Schlüssel und Anmeldedaten sicher ist. 
    • Dann initialisiert die Klasse PRAnalyzer einen MCP-Server mit der Funktion FastMCP(), die den MCP-Server mit dem Namen github_pr_analysis initialisiert und die Interaktion mit der Claude Desktop Anwendung ermöglicht.
    • Der Notion-Client wird ebenfalls mit dem notion-client-Paket eingerichtet, das den Notion-API-Schlüssel und die in der Datei .env gespeicherte Seiten-ID verwendet.
  2. MCP-Tool: PR-Änderungen abrufen
    • Die Funktion fetch_pr() ruft Pull Request-Metadaten von GitHub ab, indem sie die Methode fetch_pr_changes() aus der Datei github_integration.py verwendet. Wenn sie erfolgreich ist, gibt sie ein Wörterbuch mit den PR-Details zurück.
    • Du kannst diesen Prozess mit Hilfe der Webhooks Bibliothek in GitHub automatisieren, so dass jeder neue PR, der in deinem Repository erstellt wird, automatisch vom Server verarbeitet wird.
  3. MCP-Tool: Erstellen einer Notion-Seite
    • Die Funktion create_notion_page() erstellt eine Notion-Seite mit den Ergebnissen der PR-Analyse.
    • Sie verwendet die Notion-API, um eine neue Seite unter dem angegebenen Notion-Arbeitsbereich zu erstellen.
  4. Server Ausführung
    • Die Methode run() startet den MCP-Server über mcp.run(transport="stdio") und ermöglicht die Interaktion zwischen Claude Desktop und den PR-Review-Tools.

Schritt 6: Den MCP-Server ausführen

Nachdem wir nun alle Teile des Codes fertiggestellt haben, starten wir unseren Server mit folgendem Terminalbefehl:

python pr_analyzer.py

Terminal für den Betrieb des MCP-Servers

Terminal für den Betrieb des MCP-Servers

Sobald der Server läuft, öffnest du die Anwendung Claude Desktop und siehst ein Steckersymbol (🔌) im Textfeld. Dieser Stecker zeigt an, dass ein MCP in der Claude-Umgebung vorhanden ist. In demselben Textfeld siehst du ein hammerähnliches Symbol (🔨), das alle verfügbaren MCPs anzeigt, wie unten abgebildet.

Nun gibst du den Link an den PR weiter, den du analysieren möchtest, und Claude erledigt den Rest für dich.

Claude erzeugt eine Zusammenfassung

Claude wird die PR zunächst analysieren und dann eine Zusammenfassung und Bewertung abgeben. Es fragt die Nutzer, ob sie die Details auf die Notion-Seite hochladen wollen. Du kannst diesen Prozess zwar automatisieren, aber der aktuelle Code ermöglicht es dir, die Zusammenfassung zu überprüfen, bevor du eine neue Notion-Seite erstellst.

Claude lädt die Zusammenfassung in die Notion hoch

Die aktualisierte Notion-Seite sieht so aus:

Begriffsseite erstellt von Claude MCP

Fazit

Unser PR Review MCP-basierter Server verbessert die Codeanalyse und -dokumentation und steigert so die Effizienz und Organisation des Review-Prozesses. Durch den Einsatz von MCP, der GitHub-API und der Notion-Integration unterstützt dieses System die automatische PR-Analyse, die einfache Zusammenarbeit und die strukturierte Dokumentation. Mit dieser Konfiguration können Entwickler schnell PR-Details abrufen, Codeänderungen mit Claude analysieren und die Erkenntnisse in Notion für spätere Referenzen speichern.

Um mehr über neuere KI-Tools zu erfahren, empfehle ich diese Blogs:


Aashi Dutt's photo
Author
Aashi Dutt
LinkedIn
Twitter

Ich bin ein Google Developers Expert in ML (Gen AI), ein Kaggle 3x Expert und ein Women Techmakers Ambassador mit mehr als 3 Jahren Erfahrung im Tech-Bereich. Ich habe 2020 ein Startup im Bereich Gesundheitstechnologie mitbegründet und mache einen Master in Informatik an der Georgia Tech, der sich auf maschinelles Lernen spezialisiert.

Themen

Lerne KI mit diesen Kursen!

Lernpfad

Developing AI Applications

23hrs hr
Learn to create AI-powered applications with the latest AI developer tools, including the OpenAI API, Hugging Face, and LangChain.
Siehe DetailsRight Arrow
Kurs starten
Mehr anzeigenRight Arrow
Verwandt

Der Blog

Top 30 Generative KI Interview Fragen und Antworten für 2024

Dieser Blog bietet eine umfassende Sammlung von Fragen und Antworten zu generativen KI-Interviews, die von grundlegenden Konzepten bis hin zu fortgeschrittenen Themen reichen.
Hesam Sheikh Hassani's photo

Hesam Sheikh Hassani

15 Min.

Der Blog

Lehrer/innen und Schüler/innen erhalten das Premium DataCamp kostenlos für ihre gesamte akademische Laufbahn

Keine Hacks, keine Tricks. Schüler/innen und Lehrer/innen, lest weiter, um zu erfahren, wie ihr die Datenerziehung, die euch zusteht, kostenlos bekommen könnt.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

4 Min.

Der Blog

2022-2023 DataCamp Classrooms Jahresbericht

Zu Beginn des neuen Schuljahres ist DataCamp Classrooms motivierter denn je, das Lernen mit Daten zu demokratisieren. In den letzten 12 Monaten sind über 7.650 neue Klassenzimmer hinzugekommen.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

8 Min.

Der Blog

Die 50 besten AWS-Interview-Fragen und Antworten für 2025

Ein kompletter Leitfaden zur Erkundung der grundlegenden, mittleren und fortgeschrittenen AWS-Interviewfragen, zusammen mit Fragen, die auf realen Situationen basieren.
Zoumana Keita 's photo

Zoumana Keita

15 Min.

Der Blog

Q2 2023 DataCamp Donates Digest

DataCamp Donates hat im zweiten Quartal 2023 über 20.000 Stipendien an unsere gemeinnützigen Partner vergeben. Erfahre, wie fleißige benachteiligte Lernende diese Chancen in lebensverändernde berufliche Erfolge verwandelt haben.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

Der Blog

Die 20 besten Snowflake-Interview-Fragen für alle Niveaus

Bist du gerade auf der Suche nach einem Job, der Snowflake nutzt? Bereite dich mit diesen 20 besten Snowflake-Interview-Fragen vor, damit du den Job bekommst!
Nisha Arya Ahmed's photo

Nisha Arya Ahmed

15 Min.

Mehr anzeigenMehr anzeigen