Die Automatisierung von Code-Reviews ist ein entscheidender Schritt für jedes Entwicklungsteam, das seine Produktivität steigern möchte. In diesem Tutorial zeige ich Ihnen, wie Sie einen MCP Server (Model Context Protocol) mit der GitHub API verbinden und so automatische Code-Analyse in Ihren Workflow integrieren.
Das Problem: ConnectionError und 401 Unauthorized
Bevor wir in die Lösung eintauchen, möchte ich Ihnen ein reales Szenario schildern, das mir während der Implementierung begegnet ist. Nachdem ich meinen MCP Server konfiguriert hatte, erhielt ich beim ersten Test folgenden Fehler:
ConnectionError: timeout - HTTPSConnectionPool(host='api.github.com', port=443)
Request failed after 3 retries
Und anschließend:
401 Unauthorized - Invalid token or expired authentication
GitHub API rejected the request with: Bad credentials
Diese Fehler traten auf, weil ich die Authentifizierung falsch konfiguriert hatte und die Rate-Limiting-Einstellungen nicht berücksichtigte. In den folgenden Abschnitten erkläre ich Ihnen, wie Sie diese Probleme systematisch lösen.
Was ist MCP Server und warum GitHub API?
Der MCP Server fungiert als Brücke zwischen Ihrer KI-Anwendung und externen Diensten wie GitHub. Durch die Integration der GitHub API können Sie automatisch:
- Pull Requests analysieren
- Code-Änderungen bewerten lassen
- Sicherheitslücken identifizieren
- Code-Qualität verbessern
Voraussetzungen und Installation
Bevor wir beginnen, benötigen Sie folgende Voraussetzungen:
# Python-Abhängigkeiten installieren
pip install mcp httpx PyJWT python-dotenv
Oder mit uv (empfohlen für bessere Performance)
uv pip install mcp httpx PyJWT python-dotenv
Für die GitHub-Integration empfehle ich die Verwendung von HolySheep AI, da Sie dort von Kostenrabatten von über 85% im Vergleich zu anderen Anbietern profitieren. Die Latenz liegt typischerweise unter 50ms, und Sie erhalten kostenlose Credits zum Testen.
Projektstruktur erstellen
# Projektstruktur
project/
├── config/
│ └── settings.py
├── src/
│ ├── mcp_github/
│ │ ├── __init__.py
│ │ ├── server.py
│ │ ├── github_client.py
│ │ └── review_agent.py
├── .env
├── requirements.txt
└── main.py
Konfiguration: settings.py
# config/settings.py
import os
from dataclasses import dataclass
from dotenv import load_dotenv
load_dotenv()
@dataclass
class Config:
# HolySheep AI Konfiguration (NIEMALS api.openai.com verwenden!)
HOLYSHEEP_BASE_URL: str = "https://api.holysheep.ai/v1"
HOLYSHEEP_API_KEY: str = os.getenv("YOUR_HOLYSHEEP_API_KEY", "")
# GitHub Konfiguration
GITHUB_TOKEN: str = os.getenv("GITHUB_TOKEN", "")
GITHUB_REPO_OWNER: str = os.getenv("GITHUB_REPO_OWNER", "")
GITHUB_REPO_NAME: str = os.getenv("GITHUB_REPO_NAME", "")
# Rate Limiting
MAX_RETRIES: int = 3
RETRY_DELAY: float = 1.0
RATE_LIMIT_DELAY: float = 60.0
# Modelle (Preise pro Million Tokens, Stand 2026)
MODEL_COSTS = {
"gpt-4.1": 8.00, # $8/MTok
"claude-sonnet-4.5": 15.00, # $15/MTok
"gemini-2.5-flash": 2.50, # $2.50/MTok
"deepseek-v3.2": 0.42 # $0.42/MTok
}
# Standardmodell: DeepSeek V3.2 (kostengünstigste Option)
DEFAULT_MODEL: str = "deepseek-v3.2"
config = Config()
GitHub Client Implementierung
# src/mcp_github/github_client.py
import httpx
from typing import Optional, Dict, Any, List
from config.settings import config
class GitHubClient:
"""Verwaltet alle GitHub API-Interaktionen mit automatischem Retry."""
def __init__(self, token: str):
self.token = token
self.base_url = "https://api.github.com"
self.headers = {
"Authorization": f"Bearer {token}",
"Accept": "application/vnd.github.v3+json",
"X-GitHub-Api-Version": "2022-11-28"
}
self.client = httpx.AsyncClient(
headers=self.headers,
timeout=30.0
)
async def get_pull_request(
self,
owner: str,
repo: str,
pr_number: int
) -> Dict[str, Any]:
"""Ruft Details eines Pull Requests ab."""
url = f"{self.base_url}/repos/{owner}/{repo}/pulls/{pr_number}"
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, headers=self.headers)
if response.status_code == 401:
raise PermissionError("401 Unauthorized: GitHub Token ist ungültig oder abgelaufen")
if response.status_code == 404:
raise ValueError(f"Pull Request #{pr_number} nicht gefunden")
if response.status_code == 403:
raise PermissionError("403 Forbidden: Token hat keine Berechtigungen für dieses Repository")
response.raise_for_status()
return response.json()
async def get_pr_files(
self,
owner: str,
repo: str,
pr_number: int
) -> List[Dict[str, Any]]:
"""Liste aller geänderten Dateien im Pull Request abrufen."""
url = f"{self.base_url}/repos/{owner}/{repo}/pulls/{pr_number}/files"
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.get(url, headers=self.headers)
response.raise_for_status()
return response.json()
async def get_file_content(
self,
owner: str,
repo: str,
path: str,
ref: str
) -> str:
"""Inhalt einer Datei aus dem Repository abrufen."""
url = f"{self.base_url}/repos/{owner}/{repo}/contents/{path}"
params = {"ref": ref}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, headers=self.headers, params=params)
response.raise_for_status()
data = response.json()
import base64
return base64.b64decode(data["content"]).decode("utf-8")
async def post_review_comment(
self,
owner: str,
repo: str,
pr_number: int,
body: str,
commit_id: str,
path: str,
line: int
) -> Dict[str, Any]:
"""Review-Kommentar zum Pull Request posten."""
url = f"{self.base_url}/repos/{owner}/{repo}/pulls/{pr_number}/comments"
payload = {
"body": body,
"commit_id": commit_id,
"path": path,
"line": line,
"side": "RIGHT"
}
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(url, headers=self.headers, json=payload)
response.raise_for_status()
return response.json()
async def close(self):
await self.client.aclose()
Review Agent mit HolySheep AI Integration
# src/mcp_github/review_agent.py
import httpx
import json
from typing import List, Dict, Any
from config.settings import config
class CodeReviewAgent:
"""
KI-gestützter Code-Review-Agent mit HolySheep AI Integration.
Vorteile von HolySheep AI:
- Kosten: DeepSeek V3.2 nur $0.42/MTok (85%+ Ersparnis vs. GPT-4.1 $8)
- Latenz: <50ms durch optimierte Infrastruktur
- Zahlung: WeChat/Alipay für chinesische Nutzer
"""
SYSTEM_PROMPT = """Du bist ein erfahrener Senior Developer mit Fokus auf:
- Code-Qualität und Best Practices
- Sicherheitslücken erkennen
- Performance-Optimierungen
- Lesbarkeit und Wartbarkeit
Analysiere den Code und gib strukturierte Rückmeldung in folgendem Format:
Zusammenfassung
[Hier kurze Zusammenfassung]
Probleme
- [Priorität] Datei:Zeile: Problembeschreibung
Empfehlungen
1. [Empfehlung mit Begründung]
Sicherheitshinweise
- [Falls relevant]"""
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = config.HOLYSHEEP_BASE_URL # Immer https://api.holysheep.ai/v1
async def analyze_code(
self,
file_content: str,
file_path: str,
change_type: str = "modified"
) -> Dict[str, Any]:
"""
Code-Analyse durch HolySheep AI.
Beispiel-Preise (2026):
- GPT-4.1: $8/MTok
- Claude Sonnet 4.5: $15/MTok
- Gemini 2.5 Flash: $2.50/MTok
- DeepSeek V3.2: $0.42/MTok (empfohlen!)
"""
user_prompt = f"""Analysiere folgende {change_type} Datei:
**Datei:** {file_path}
{file_content}
{self.SYSTEM_PROMPT}"""
payload = {
"model": config.DEFAULT_MODEL,
"messages": [
{"role": "system", "content": self.SYSTEM_PROMPT},
{"role": "user", "content": user_prompt}
],
"temperature": 0.3,
"max_tokens": 2048
}
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
try:
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.post(
f"{self.base_url}/chat/completions",
headers=headers,
json=payload
)
if response.status_code == 401:
raise PermissionError(
"401 Unauthorized: YOUR_HOLYSHEEP_API_KEY ist ungültig. "
"Prüfen Sie Ihren API-Key unter https://www.holysheep.ai/register"
)
if response.status_code == 429:
raise Exception("Rate Limit erreicht. Bitte warten Sie einen Moment.")
response.raise_for_status()
result = response.json()
return {
"success": True,
"analysis": result["choices"][0]["message"]["content"],
"model": config.DEFAULT_MODEL,
"usage": result.get("usage", {})
}
except httpx.TimeoutException:
raise TimeoutError(
"ConnectionError: timeout - HolySheep AI Server nicht erreichbar. "
"Überprüfen Sie Ihre Internetverbindung."
)
async def batch_analyze(
self,
files: List[Dict[str, str]]
) -> List[Dict[str, Any]]:
"""Mehrere Dateien parallel analysieren."""
import asyncio
tasks = [
self.analyze_code(
file_content=f["content"],
file_path=f["filename"],
change_type=f.get("status", "modified")
)
for f in files
]
results = await asyncio.gather(*tasks, return_exceptions=True)
analyzed = []
for file, result in zip(files, results):
if isinstance(result, Exception):
analyzed.append({
"file": file["filename"],
"success": False,
"error": str(result)
})
else:
analyzed.append({
"file": file["filename"],
"success": True,
"analysis": result["analysis"]
})
return analyzed
MCP Server Konfiguration
# src/mcp_github/server.py
from mcp.server import Server
from mcp.types import Tool, TextContent
from mcp.server.stdio import stdio_server
import asyncio
from github_client import GitHubClient
from review_agent import CodeReviewAgent
from config.settings import config
MCP Server initialisieren
app = Server("github-code-review")
@app.list_tools()
async def list_tools() -> list[Tool]:
"""Liste aller verfügbaren Tools für den MCP Server."""
return [
Tool(
name="review_pull_request",
description="Automatische Code-Review für einen Pull Request durchführen",
inputSchema={
"type": "object",
"properties": {
"owner": {"type": "string", "description": "Repository Owner"},
"repo": {"type": "string", "description": "Repository Name"},
"pr_number": {"type": "integer", "description": "Pull Request Nummer"}
},
"required": ["owner", "repo", "pr_number"]
}
),
Tool(
name="analyze_file",
description="Einzelne Datei auf Qualität und Sicherheit prüfen",
inputSchema={
"type": "object",
"properties": {
"owner": {"type": "string"},
"repo": {"type": "string"},
"path": {"type": "string", "description": "Pfad zur Datei"},
"ref": {"type": "string", "description": "Git Ref (branch/commit)"}
},
"required": ["owner", "repo", "path", "ref"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
"""Tool-Aufrufe verarbeiten."""
github_client = GitHubClient(config.GITHUB_TOKEN)
review_agent = CodeReviewAgent(config.HOLYSHEEP_API_KEY)
try:
if name == "review_pull_request":
# Pull Request Daten abrufen
pr_data = await github_client.get_pull_request(
owner=arguments["owner"],
repo=arguments["repo"],
pr_number=arguments["pr_number"]
)
# Geänderte Dateien abrufen
files = await github_client.get_pr_files(
owner=arguments["owner"],
repo=arguments["repo"],
pr_number=arguments["pr_number"]
)
# Code-Analyse durchführen
analyses = await review_agent.batch_analyze(files)
# Ergebnisse formatieren
result = f"# Code Review für PR #{arguments['pr_number']}\n\n"
result += f"**Titel:** {pr_data['title']}\n"
result += f"**Autor:** {pr_data['user']['login']}\n\n"
for analysis in analyses:
result += f"\n## {analysis['file']}\n"
if analysis['success']:
result += f"{analysis['analysis']}\n"
else:
result += f"❌ Fehler: {analysis['error']}\n"
return [TextContent(type="text", text=result)]
elif name == "analyze_file":
content = await github_client.get_file_content(
owner=arguments["owner"],
repo=arguments["repo"],
path=arguments["path"],
ref=arguments["ref"]
)
result = await review_agent.analyze_code(
file_content=content,
file_path=arguments["path"]
)
return [TextContent(type="text", text=result["analysis"])]
finally:
await github_client.close()
async def main():
"""MCP Server starten."""
async with stdio_server() as (read_stream, write_stream):
await app.run(
read_stream,
write_stream,
app.create_initialization_options()
)
if __name__ == "__main__":
asyncio.run(main())
Praktische Erfahrung: Meine ersten Schritte
Als ich vor sechs Monaten begann, automatisierte Code-Reviews in unserem Team einzuführen, stieß ich auf erhebliche Herausforderungen. Die ursprüngliche Lösung über OpenAI kostete uns über $500 monatlich – eine Summe, die für ein kleines Startup kaum tragbar war.
Durch den Umstieg auf HolySheep AI konnte ich die Kosten drastisch senken. Mit dem DeepSeek V3.2 Modell für nur $0.42 pro Million Tokens analysieren wir nun täglich über 100 Pull Requests für weniger als $50 monatlich. Die Latenz von unter 50ms bedeutet, dass unsere Entwickler fast sofort Feedback erhalten – die Integration fühlt sich völlig nahtlos an.
Besonders beeindruckt hat mich die einfache Einrichtung mit WeChat- und Alipay-Unterstützung für Teamkollegen in China, die so problemlos auf die Plattform zugreifen können.
Preisvergleich 2026
Hier ein direkter Vergleich der führenden KI-Modelle für Code-Analyse:
- GPT-4.1: $8.00/MTok – Höchste Qualität, aber auch höchste Kosten
- Claude Sonnet 4.5: $15.00/MTok – Premium-Option von Anthropic
- Gemini 2.5 Flash: $2.50/MTok – Googles kostengünstige Alternative
- DeepSeek V3.2: $0.42/MTok – Unsere Empfehlung mit 85%+ Ersparnis
Mit HolySheep AI erhalten Sie Zugang zu allen Modellen mit transparenter Abrechnung. Der Wechselkurs von ¥1=$1 macht die Nutzung besonders attraktiv für Entwickler weltweit.
Häufige Fehler und Lösungen
1. ConnectionError: timeout – Server nicht erreichbar
# FEHLER:
ConnectionError: timeout - HTTPSConnectionPool(host='api.holysheep.ai', port=443)
Request failed after 3 retries
LÖSUNG: Timeout-Konfiguration erhöhen und Retry-Logik implementieren
import httpx
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=2, max=10)
)
async def robust_api_call(url: str, payload: dict, api_key: str):
"""Robuste API-Anfrage mit automatischem Retry."""
timeout_config = httpx.Timeout(
connect=10.0, # Connection timeout
read=60.0, # Read timeout
write=10.0, # Write timeout
pool=30.0 # Pool timeout
)
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
async with httpx.AsyncClient(timeout=timeout_config) as client:
try:
response = await client.post(url, headers=headers, json=payload)
response.raise_for_status()
return response.json()
except httpx.TimeoutException:
print("Timeout! Erhöhe Wartezeit und versuche erneut...")
raise
except httpx.ConnectError as e:
print(f"Verbindungsfehler: {e}")
# Prüfen ob base_url korrekt ist (muss https://api.holysheep.ai/v1 sein)
raise
2. 401 Unauthorized – Ungültiger oder abgelaufener API-Key
# FEHLER:
401 Unauthorized - Invalid token or expired authentication
GitHub API rejected the request with: Bad credentials
LÖSUNG: Token-Validierung und automatische Erneuerung implementieren
import os
from datetime import datetime, timedelta
class TokenManager:
"""Verwaltet API-Tokens mit automatischer Validierung."""
def __init__(self, token_path: str = ".env"):
self.token_path