From 87cf4fd46d4555b8ce4f1c39d5f4e42f9cf54ab3 Mon Sep 17 00:00:00 2001 From: saidsurucu Date: Sat, 12 Jul 2025 15:25:18 +0300 Subject: [PATCH] update docker, bugfix --- Dockerfile | 2 +- README.md | 9 +++-- bedesten_mcp_module/models.py | 2 +- mcp_server_main.py | 62 +++++++++++++++++++++++++++++++++-- 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index cacdf0e..111f909 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # -------- BASE IMAGE (includes Chromium & deps) ---------------------------- -FROM mcr.microsoft.com/playwright/python:v1.52.0-noble +FROM mcr.microsoft.com/playwright/python:v1.53.0-noble # -------- Runtime setup ---------------------------------------------------- WORKDIR /app diff --git a/README.md b/README.md index 1afdae0..47c8ec7 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Bu proje, çeşitli Türk hukuk kaynaklarına (Yargıtay, Danıştay, Emsal Kara * **KİK (Kamu İhale Kurulu):** Çeşitli kriterlerle Kurul kararlarını arama; uzun karar metinlerini (varsayılan 5.000 karakterlik) sayfalanmış Markdown formatında getirme. * **Rekabet Kurumu:** Çeşitli kriterlerle Kurul kararlarını arama; karar metinlerini Markdown formatında getirme. * **Sayıştay:** 3 karar türü ile kapsamlı denetim kararlarına erişim + **8 Daire Filtreleme** + **Tarih Aralığı & İçerik Arama** (Genel Kurul yorumlayıcı kararları, Temyiz Kurulu itiraz kararları, Daire ilk derece denetim kararları) + * **KVKK (Kişisel Verilerin Korunması Kurulu):** Brave Search API ile veri koruma kararlarını arama; uzun karar metinlerini (5.000 karakterlik) sayfalanmış Markdown formatında getirme + **Türkçe Arama** + **Site Hedeflemeli Arama** (kvkk.gov.tr kararları) * Karar metinlerinin daha kolay işlenebilmesi için Markdown formatına çevrilmesi. * Claude Desktop uygulaması ile `fastmcp install` komutu kullanılarak kolay entegrasyon. @@ -186,12 +187,16 @@ Bu FastMCP sunucusu aşağıdaki temel araçları sunar: * `get_sayistay_temyiz_kurulu_document_markdown(decision_id: str)`: Temyiz Kurulu kararının tam metnini Markdown formatında getirir * `get_sayistay_daire_document_markdown(decision_id: str)`: Daire kararının tam metnini Markdown formatında getirir +* **KVKK Araçları (Brave Search API + Türkçe Arama):** + * `search_kvkk_decisions(keywords, page, pageSize, ...)`: KVKK (Kişisel Verilerin Korunması Kurulu) kararlarını Brave Search API ile arar. **Türkçe arama** + **Site hedeflemeli** (`site:kvkk.gov.tr "karar özeti"`) + **Sayfalama desteği** + * `get_kvkk_document_markdown(decision_url: str, page_number: Optional[int] = 1)`: KVKK kararının tam metnini **sayfalanmış Markdown** formatında getirir (5.000 karakterlik sayfa) + --- ### **📊 Kapsamlı İstatistikler** -- **Toplam Mahkeme/Kurum:** 12 farklı hukuki kurum -- **Toplam MCP Tool:** 36+ arama ve belge getirme aracı +- **Toplam Mahkeme/Kurum:** 13 farklı hukuki kurum (KVKK dahil) +- **Toplam MCP Tool:** 38+ arama ve belge getirme aracı - **Daire/Kurul Filtreleme:** 87 farklı seçenek (52 Yargıtay + 27 Danıştay + 8 Sayıştay) - **Tarih Filtreleme:** 5 Bedesten API aracında ISO 8601 formatında tam tarih aralığı desteği - **Kesin Cümle Arama:** 5 Bedesten API aracında çift tırnak ile tam cümle arama (`"\"mülkiyet kararı\""` formatı) diff --git a/bedesten_mcp_module/models.py b/bedesten_mcp_module/models.py index dda0881..c5edbc3 100644 --- a/bedesten_mcp_module/models.py +++ b/bedesten_mcp_module/models.py @@ -125,7 +125,7 @@ class BedestenSearchDataResponse(BaseModel): start: int class BedestenSearchResponse(BaseModel): - data: BedestenSearchDataResponse + data: Optional[BedestenSearchDataResponse] metadata: Dict[str, Any] # Document Request/Response Models diff --git a/mcp_server_main.py b/mcp_server_main.py index 862a761..b7f55ee 100644 --- a/mcp_server_main.py +++ b/mcp_server_main.py @@ -1553,6 +1553,16 @@ async def search_yargitay_bedesten( try: response = await bedesten_client_instance.search_documents(search_request) + # Handle potential None data + if response.data is None: + return { + "decisions": [], + "total_records": 0, + "requested_page": pageNumber, + "page_size": pageSize, + "error": "No data returned from Bedesten API" + } + # Return simplified response format return { "decisions": [d.model_dump() for d in response.data.emsalKararList], @@ -1656,6 +1666,16 @@ async def search_danistay_bedesten( try: response = await bedesten_client_instance.search_documents(search_request) + # Handle potential None data + if response.data is None: + return { + "decisions": [], + "total_records": 0, + "requested_page": pageNumber, + "page_size": pageSize, + "error": "No data returned from Bedesten API" + } + # Return simplified response format return { "decisions": [d.model_dump() for d in response.data.emsalKararList], @@ -1749,6 +1769,16 @@ async def search_yerel_hukuk_bedesten( try: response = await bedesten_client_instance.search_documents(search_request) + # Handle potential None data + if response.data is None: + return { + "decisions": [], + "total_records": 0, + "requested_page": pageNumber, + "page_size": pageSize, + "error": "No data returned from Bedesten API" + } + # Return simplified response format return { "decisions": [d.model_dump() for d in response.data.emsalKararList], @@ -1857,6 +1887,16 @@ async def search_istinaf_hukuk_bedesten( try: response = await bedesten_client_instance.search_documents(search_request) + # Handle potential None data + if response.data is None: + return { + "decisions": [], + "total_records": 0, + "requested_page": pageNumber, + "page_size": pageSize, + "error": "No data returned from Bedesten API" + } + # Return simplified response format return { "decisions": [d.model_dump() for d in response.data.emsalKararList], @@ -1987,6 +2027,16 @@ async def search_kyb_bedesten( try: response = await bedesten_client_instance.search_documents(search_request) + # Handle potential None data + if response.data is None: + return { + "decisions": [], + "total_records": 0, + "requested_page": pageNumber, + "page_size": pageSize, + "error": "No data returned from Bedesten API" + } + # Return simplified response format return { "decisions": [d.model_dump() for d in response.data.emsalKararList], @@ -2828,6 +2878,11 @@ async def search( ) ) + # Handle potential None data + if search_results.data is None: + logger.warning(f"No data returned from Bedesten API for {court_name}") + continue + # Add results from this court type (limit to top 5 per court) for decision in search_results.data.emsalKararList[:5]: # For ChatGPT Deep Research, fetch document content for preview @@ -2872,7 +2927,10 @@ async def search( "url": f"https://mevzuat.adalet.gov.tr/ictihat/{decision.documentId}" }) - logger.info(f"Found {len(search_results.data.emsalKararList)} results from {court_name}") + if search_results.data: + logger.info(f"Found {len(search_results.data.emsalKararList)} results from {court_name}") + else: + logger.info(f"Found 0 results from {court_name} (no data returned)") except Exception as e: logger.warning(f"Bedesten API search error for {court_name}: {e}") @@ -2980,7 +3038,7 @@ async def fetch( ) ) - if search_results.data.emsalKararList: + if search_results.data and search_results.data.emsalKararList: decision = search_results.data.emsalKararList[0] if decision.documentId == id: # Build a proper title from metadata