GitPasha MCP Server - Ready for deployment

هذا الالتزام موجود في:
2025-11-22 16:18:29 +02:00
التزام fb1476f28a
35 ملفات معدلة مع 1545 إضافات و0 حذوفات

13
helpers/__init__.py Normal file
عرض الملف

@@ -0,0 +1,13 @@
from helpers.logger import log
from helpers.headers import get_headers
from helpers.descriptions import suggest_description
from helpers.error_formatter import format_error
from helpers.http_client import build_client
__all__ = [
"log",
"get_headers",
"suggest_description",
"format_error",
"build_client"
]

3
helpers/descriptions.py Normal file
عرض الملف

@@ -0,0 +1,3 @@
def suggest_description(name: str) -> str:
name = (name or "").strip()
return f"{name or 'test'}: Repository for testing and experiments"

عرض الملف

@@ -0,0 +1,15 @@
import httpx
def format_error(prefix: str, e: Exception) -> str:
if isinstance(e, httpx.HTTPStatusError):
code = e.response.status_code
text = e.response.text
if code in (301, 302, 307, 308):
return f"{prefix}: {code} - Redirect detected. Probably web UI, not API."
if "CSRF" in text:
return f"{prefix}: {code} - CSRF error. Wrong domain."
if code in (401, 403):
return f"{prefix}: {code} - Invalid or expired API key."
return f"{prefix}: {code} - {text}"
return f"{prefix}: {str(e)}"

10
helpers/headers.py Normal file
عرض الملف

@@ -0,0 +1,10 @@
import os
def get_headers():
api_key = os.getenv("GITPASHA_API_KEY", "")
return {
"Authorization": f"token {api_key}",
"Content-Type": "application/json",
"Accept": "application/json",
}

33
helpers/http_client.py Normal file
عرض الملف

@@ -0,0 +1,33 @@
import httpx
from helpers.logger import log
def log_request(req: httpx.Request):
safe_headers = {
k: ("<hidden>" if k.lower() == "authorization" else v)
for k, v in req.headers.items()
}
log.info(f"=> {req.method} {req.url}")
log.debug(f"Headers: {safe_headers}")
try:
log.debug(f"Body: {req.content.decode()[:1000]}")
except Exception:
pass
def log_response(res: httpx.Response):
log.info(f"<= {res.status_code} {res.request.method} {res.request.url}")
try:
if res.status_code >= 400:
content = res.read()
log.debug(f"Response: {content.decode()[:2000]}")
except Exception:
pass
def build_client() -> httpx.Client:
return httpx.Client(
follow_redirects=False,
timeout=120.0,
event_hooks={"request": [log_request], "response": [log_response]},
)

16
helpers/logger.py Normal file
عرض الملف

@@ -0,0 +1,16 @@
import os
import logging
LOG_LEVEL = os.getenv("LOG_LEVEL", "DEBUG").upper()
LOG_FILE = os.getenv("LOG_FILE", "logs/gitpasha.log")
logging.basicConfig(
level=getattr(logging, LOG_LEVEL, logging.DEBUG),
format="%(asctime)s | %(levelname)s | %(message)s",
handlers=[
logging.FileHandler(LOG_FILE, mode="a", encoding="utf-8"),
logging.StreamHandler()
],
)
log = logging.getLogger("gitpasha")