add bedesten module
This commit is contained in:
@@ -9,9 +9,14 @@ Bu proje, çeşitli Türk hukuk kaynaklarına (Yargıtay, Danıştay, Emsal Kara
|
|||||||
🎯 **Temel Özellikler**
|
🎯 **Temel Özellikler**
|
||||||
|
|
||||||
* Çeşitli Türk hukuk veritabanlarına programatik erişim için standart bir MCP arayüzü.
|
* Çeşitli Türk hukuk veritabanlarına programatik erişim için standart bir MCP arayüzü.
|
||||||
|
* **Kapsamlı Mahkeme Daire/Kurul Filtreleme:** 79 farklı daire/kurul filtreleme seçeneği
|
||||||
|
* **Dual/Triple API Desteği:** Her mahkeme için birden fazla API kaynağı ile maksimum kapsama
|
||||||
* Aşağıdaki kurumların kararlarını arama ve getirme yeteneği:
|
* Aşağıdaki kurumların kararlarını arama ve getirme yeteneği:
|
||||||
* **Yargıtay:** Detaylı kriterlerle karar arama ve karar metinlerini Markdown formatında getirme.
|
* **Yargıtay:** Detaylı kriterlerle karar arama ve karar metinlerini Markdown formatında getirme. **Dual API** (Ana + Bedesten) + **52 Daire/Kurul Filtreleme** (Hukuk/Ceza Daireleri, Genel Kurullar)
|
||||||
* **Danıştay:** Anahtar kelime bazlı ve detaylı kriterlerle karar arama; karar metinlerini Markdown formatında getirme.
|
* **Danıştay:** Anahtar kelime bazlı ve detaylı kriterlerle karar arama; karar metinlerini Markdown formatında getirme. **Triple API** (Keyword + Detailed + Bedesten) + **27 Daire/Kurul Filtreleme** (İdari Daireler, Vergi/İdare Kurulları, Askeri Yüksek İdare Mahkemesi)
|
||||||
|
* **Yerel Hukuk Mahkemeleri:** Bedesten API ile yerel hukuk mahkemesi kararlarına erişim
|
||||||
|
* **İstinaf Hukuk Mahkemeleri:** Bedesten API ile istinaf mahkemesi kararlarına erişim
|
||||||
|
* **Kanun Yararına Bozma (KYB):** Bedesten API ile olağanüstü kanun yoluna erişim
|
||||||
* **Emsal (UYAP):** Detaylı kriterlerle emsal karar arama ve karar metinlerini Markdown formatında getirme.
|
* **Emsal (UYAP):** Detaylı kriterlerle emsal karar arama ve karar metinlerini Markdown formatında getirme.
|
||||||
* **Uyuşmazlık Mahkemesi:** Form tabanlı kriterlerle karar arama ve karar metinlerini (URL ile erişilen) Markdown formatında getirme.
|
* **Uyuşmazlık Mahkemesi:** Form tabanlı kriterlerle karar arama ve karar metinlerini (URL ile erişilen) Markdown formatında getirme.
|
||||||
* **Anayasa Mahkemesi (Norm Denetimi):** Kapsamlı kriterlerle norm denetimi kararlarını arama; uzun karar metinlerini (5.000 karakterlik) sayfalanmış Markdown formatında getirme.
|
* **Anayasa Mahkemesi (Norm Denetimi):** Kapsamlı kriterlerle norm denetimi kararlarını arama; uzun karar metinlerini (5.000 karakterlik) sayfalanmış Markdown formatında getirme.
|
||||||
@@ -75,15 +80,33 @@ Bu bölüm, Yargı MCP aracını 5ire gibi Claude Desktop dışındaki MCP istem
|
|||||||
|
|
||||||
Bu FastMCP sunucusu aşağıdaki temel araçları sunar:
|
Bu FastMCP sunucusu aşağıdaki temel araçları sunar:
|
||||||
|
|
||||||
|
### **Yargıtay Araçları (Dual API + 52 Daire Filtreleme)**
|
||||||
|
* **Ana API:**
|
||||||
|
* `search_yargitay_detailed(arananKelime, birimYrgKurulDaire, ...)`: Yargıtay kararlarını detaylı kriterlerle arar. **52 daire/kurul seçeneği** (Hukuk/Ceza Daireleri 1-23, Genel Kurullar, Başkanlar Kurulu)
|
||||||
|
* `get_yargitay_document_markdown(id: str)`: Belirli bir Yargıtay kararının metnini Markdown formatında getirir.
|
||||||
|
* **Bedesten API (Alternatif):**
|
||||||
|
* `search_yargitay_bedesten(phrase, birimAdi, ...)`: Bedesten API ile Yargıtay kararlarını arar. **Aynı 52 daire filtreleme**
|
||||||
|
* `get_yargitay_bedesten_document_markdown(documentId: str)`: Bedesten'den karar metni (HTML/PDF → Markdown)
|
||||||
|
|
||||||
* **Yargıtay Araçları:**
|
### **Danıştay Araçları (Triple API + 27 Daire Filtreleme)**
|
||||||
* `search_yargitay_detailed(search_query: YargitayDetailedSearchRequest) -> CompactYargitaySearchResult`: Yargıtay kararlarını detaylı kriterlerle arar.
|
* **Ana API'lar:**
|
||||||
* `get_yargitay_document_markdown(id: str) -> YargitayDocumentMarkdown`: Belirli bir Yargıtay kararının metnini Markdown formatında getirir.
|
* `search_danistay_by_keyword(andKelimeler, orKelimeler, ...)`: Danıştay kararlarını anahtar kelimelerle arar.
|
||||||
|
* `search_danistay_detailed(daire, esasYil, ...)`: Danıştay kararlarını detaylı kriterlerle arar.
|
||||||
|
* `get_danistay_document_markdown(id: str)`: Belirli bir Danıştay kararının metnini Markdown formatında getirir.
|
||||||
|
* **Bedesten API (Alternatif):**
|
||||||
|
* `search_danistay_bedesten(phrase, birimAdi, ...)`: Bedesten API ile Danıştay kararlarını arar. **27 daire/kurul seçeneği** (1-17. Daireler, Vergi/İdare Kurulları, Askeri Mahkemeler)
|
||||||
|
* `get_danistay_bedesten_document_markdown(documentId: str)`: Bedesten'den karar metni
|
||||||
|
|
||||||
* **Danıştay Araçları:**
|
### **Diğer Mahkemeler (Bedesten API)**
|
||||||
* `search_danistay_by_keyword(search_query: DanistayKeywordSearchRequest) -> CompactDanistaySearchResult`: Danıştay kararlarını anahtar kelimelerle arar.
|
* **Yerel Hukuk Mahkemeleri:**
|
||||||
* `search_danistay_detailed(search_query: DanistayDetailedSearchRequest) -> CompactDanistaySearchResult`: Danıştay kararlarını detaylı kriterlerle arar.
|
* `search_yerel_hukuk_bedesten(phrase, pageSize, ...)`: Yerel hukuk mahkemesi kararlarını arar
|
||||||
* `get_danistay_document_markdown(id: str) -> DanistayDocumentMarkdown`: Belirli bir Danıştay kararının metnini Markdown formatında getirir.
|
* `get_yerel_hukuk_bedesten_document_markdown(documentId: str)`: Karar metni
|
||||||
|
* **İstinaf Hukuk Mahkemeleri:**
|
||||||
|
* `search_istinaf_hukuk_bedesten(phrase, pageSize, ...)`: İstinaf mahkemesi kararlarını arar
|
||||||
|
* `get_istinaf_hukuk_bedesten_document_markdown(documentId: str)`: Karar metni
|
||||||
|
* **Kanun Yararına Bozma (KYB):**
|
||||||
|
* `search_kyb_bedesten(phrase, pageSize, ...)`: Olağanüstü kanun yolu kararlarını arar
|
||||||
|
* `get_kyb_bedesten_document_markdown(documentId: str)`: Karar metni
|
||||||
|
|
||||||
* **Emsal Karar Araçları:**
|
* **Emsal Karar Araçları:**
|
||||||
* `search_emsal_detailed_decisions(search_query: EmsalSearchRequest) -> CompactEmsalSearchResult`: Emsal (UYAP) kararlarını detaylı kriterlerle arar.
|
* `search_emsal_detailed_decisions(search_query: EmsalSearchRequest) -> CompactEmsalSearchResult`: Emsal (UYAP) kararlarını detaylı kriterlerle arar.
|
||||||
@@ -109,6 +132,27 @@ Bu FastMCP sunucusu aşağıdaki temel araçları sunar:
|
|||||||
* `get_rekabet_kurumu_document(karar_id: str, page_number: Optional[int] = 1) -> RekabetDocument`: Belirli bir Rekabet Kurumu kararını `karar_id` ile alır. Kararın PDF formatındaki orijinalinden istenen sayfayı ayıklar ve Markdown formatında döndürür.
|
* `get_rekabet_kurumu_document(karar_id: str, page_number: Optional[int] = 1) -> RekabetDocument`: Belirli bir Rekabet Kurumu kararını `karar_id` ile alır. Kararın PDF formatındaki orijinalinden istenen sayfayı ayıklar ve Markdown formatında döndürür.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### **📊 Kapsamlı İstatistikler**
|
||||||
|
- **Toplam Mahkeme/Kurum:** 11 farklı hukuki kurum
|
||||||
|
- **Toplam MCP Tool:** 30+ arama ve belge getirme aracı
|
||||||
|
- **Daire/Kurul Filtreleme:** 79 farklı seçenek (52 Yargıtay + 27 Danıştay)
|
||||||
|
- **API Kaynağı:** Dual/Triple API desteği ile maksimum kapsama
|
||||||
|
- **Tam Türk Adalet Sistemi:** Yerel mahkemelerden en yüksek mahkemelere kadar
|
||||||
|
|
||||||
|
**🏛️ Desteklenen Mahkeme Hiyerarşisi:**
|
||||||
|
```
|
||||||
|
Yerel Mahkemeler → İstinaf → Yargıtay/Danıştay → Anayasa Mahkemesi
|
||||||
|
↓ ↓ ↓ ↓
|
||||||
|
Bedesten API Bedesten API Dual/Triple API Norm+Bireysel API
|
||||||
|
```
|
||||||
|
|
||||||
|
**⚖️ Kapsamlı Daire Filtreleme:**
|
||||||
|
- **Yargıtay:** 52 seçenek (1-23 Hukuk, 1-23 Ceza, Genel Kurullar, Başkanlar Kurulu)
|
||||||
|
- **Danıştay:** 27 seçenek (1-17 Daireler, İdare/Vergi Kurulları, Askeri Mahkemeler)
|
||||||
|
- **Toplam:** 79 farklı mahkeme dairesi/kurulu
|
||||||
|
|
||||||
📜 **Lisans**
|
📜 **Lisans**
|
||||||
|
|
||||||
Bu proje MIT Lisansı altında lisanslanmıştır. Detaylar için `LICENSE` dosyasına bakınız.
|
Bu proje MIT Lisansı altında lisanslanmıştır. Detaylar için `LICENSE` dosyasına bakınız.
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
# bedesten_mcp_module/__init__.py
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
# bedesten_mcp_module/client.py
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
import base64
|
||||||
|
from typing import Optional
|
||||||
|
import logging
|
||||||
|
from markitdown import MarkItDown
|
||||||
|
import tempfile
|
||||||
|
import os
|
||||||
|
|
||||||
|
from .models import (
|
||||||
|
BedestenSearchRequest, BedestenSearchResponse,
|
||||||
|
BedestenDocumentRequest, BedestenDocumentResponse,
|
||||||
|
BedestenDocumentMarkdown, BedestenDocumentRequestData
|
||||||
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class BedestenApiClient:
|
||||||
|
"""
|
||||||
|
API Client for Bedesten (bedesten.adalet.gov.tr) - Alternative legal decision search system.
|
||||||
|
Currently used for Yargıtay decisions, but can be extended for other court types.
|
||||||
|
"""
|
||||||
|
BASE_URL = "https://bedesten.adalet.gov.tr"
|
||||||
|
SEARCH_ENDPOINT = "/emsal-karar/searchDocuments"
|
||||||
|
DOCUMENT_ENDPOINT = "/emsal-karar/getDocumentContent"
|
||||||
|
|
||||||
|
def __init__(self, request_timeout: float = 60.0):
|
||||||
|
self.http_client = httpx.AsyncClient(
|
||||||
|
base_url=self.BASE_URL,
|
||||||
|
headers={
|
||||||
|
"Accept": "*/*",
|
||||||
|
"Accept-Language": "tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7",
|
||||||
|
"AdaletApplicationName": "UyapMevzuat",
|
||||||
|
"Content-Type": "application/json; charset=utf-8",
|
||||||
|
"Origin": "https://mevzuat.adalet.gov.tr",
|
||||||
|
"Referer": "https://mevzuat.adalet.gov.tr/",
|
||||||
|
"Sec-Fetch-Dest": "empty",
|
||||||
|
"Sec-Fetch-Mode": "cors",
|
||||||
|
"Sec-Fetch-Site": "same-site",
|
||||||
|
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
|
||||||
|
},
|
||||||
|
timeout=request_timeout
|
||||||
|
)
|
||||||
|
|
||||||
|
async def search_documents(self, search_request: BedestenSearchRequest) -> BedestenSearchResponse:
|
||||||
|
"""
|
||||||
|
Search for documents using Bedesten API.
|
||||||
|
Currently supports: YARGITAYKARARI, DANISTAYKARARI, YERELHUKMAHKARARI, etc.
|
||||||
|
"""
|
||||||
|
logger.info(f"BedestenApiClient: Searching documents with phrase: {search_request.data.phrase}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = await self.http_client.post(
|
||||||
|
self.SEARCH_ENDPOINT,
|
||||||
|
json=search_request.model_dump()
|
||||||
|
)
|
||||||
|
response.raise_for_status()
|
||||||
|
response_json = response.json()
|
||||||
|
|
||||||
|
# Parse and return the response
|
||||||
|
return BedestenSearchResponse(**response_json)
|
||||||
|
|
||||||
|
except httpx.RequestError as e:
|
||||||
|
logger.error(f"BedestenApiClient: HTTP request error during search: {e}")
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"BedestenApiClient: Error processing search response: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
async def get_document_as_markdown(self, document_id: str) -> BedestenDocumentMarkdown:
|
||||||
|
"""
|
||||||
|
Get document content and convert to markdown.
|
||||||
|
Handles both HTML (text/html) and PDF (application/pdf) content types.
|
||||||
|
"""
|
||||||
|
logger.info(f"BedestenApiClient: Fetching document for markdown conversion (ID: {document_id})")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Prepare request
|
||||||
|
doc_request = BedestenDocumentRequest(
|
||||||
|
data=BedestenDocumentRequestData(documentId=document_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get document
|
||||||
|
response = await self.http_client.post(
|
||||||
|
self.DOCUMENT_ENDPOINT,
|
||||||
|
json=doc_request.model_dump()
|
||||||
|
)
|
||||||
|
response.raise_for_status()
|
||||||
|
response_json = response.json()
|
||||||
|
doc_response = BedestenDocumentResponse(**response_json)
|
||||||
|
|
||||||
|
# Decode base64 content
|
||||||
|
content_bytes = base64.b64decode(doc_response.data.content)
|
||||||
|
mime_type = doc_response.data.mimeType
|
||||||
|
|
||||||
|
logger.info(f"BedestenApiClient: Document mime type: {mime_type}")
|
||||||
|
|
||||||
|
# Convert to markdown based on mime type
|
||||||
|
if mime_type == "text/html":
|
||||||
|
html_content = content_bytes.decode('utf-8')
|
||||||
|
markdown_content = self._convert_html_to_markdown(html_content)
|
||||||
|
elif mime_type == "application/pdf":
|
||||||
|
markdown_content = self._convert_pdf_to_markdown(content_bytes)
|
||||||
|
else:
|
||||||
|
logger.warning(f"Unsupported mime type: {mime_type}")
|
||||||
|
markdown_content = f"Unsupported content type: {mime_type}. Unable to convert to markdown."
|
||||||
|
|
||||||
|
return BedestenDocumentMarkdown(
|
||||||
|
documentId=document_id,
|
||||||
|
markdown_content=markdown_content,
|
||||||
|
source_url=f"{self.BASE_URL}/document/{document_id}",
|
||||||
|
mime_type=mime_type
|
||||||
|
)
|
||||||
|
|
||||||
|
except httpx.RequestError as e:
|
||||||
|
logger.error(f"BedestenApiClient: HTTP error fetching document {document_id}: {e}")
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"BedestenApiClient: Error processing document {document_id}: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def _convert_html_to_markdown(self, html_content: str) -> Optional[str]:
|
||||||
|
"""Convert HTML to Markdown using MarkItDown"""
|
||||||
|
if not html_content:
|
||||||
|
return None
|
||||||
|
|
||||||
|
temp_file_path = None
|
||||||
|
try:
|
||||||
|
md_converter = MarkItDown()
|
||||||
|
|
||||||
|
# Write HTML to temp file
|
||||||
|
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".html", encoding="utf-8") as tmp:
|
||||||
|
tmp.write(html_content)
|
||||||
|
temp_file_path = tmp.name
|
||||||
|
|
||||||
|
# Convert
|
||||||
|
result = md_converter.convert(temp_file_path)
|
||||||
|
markdown_content = result.text_content
|
||||||
|
|
||||||
|
logger.info("Successfully converted HTML to Markdown")
|
||||||
|
return markdown_content
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error converting HTML to Markdown: {e}")
|
||||||
|
return f"Error converting HTML content: {str(e)}"
|
||||||
|
finally:
|
||||||
|
if temp_file_path and os.path.exists(temp_file_path):
|
||||||
|
os.remove(temp_file_path)
|
||||||
|
|
||||||
|
def _convert_pdf_to_markdown(self, pdf_bytes: bytes) -> Optional[str]:
|
||||||
|
"""Convert PDF to Markdown using MarkItDown"""
|
||||||
|
if not pdf_bytes:
|
||||||
|
return None
|
||||||
|
|
||||||
|
temp_file_path = None
|
||||||
|
try:
|
||||||
|
# MarkItDown supports PDF with markitdown[pdf]
|
||||||
|
md_converter = MarkItDown()
|
||||||
|
|
||||||
|
# Write PDF to temp file
|
||||||
|
with tempfile.NamedTemporaryFile(mode="wb", delete=False, suffix=".pdf") as tmp:
|
||||||
|
tmp.write(pdf_bytes)
|
||||||
|
temp_file_path = tmp.name
|
||||||
|
|
||||||
|
# Convert
|
||||||
|
result = md_converter.convert(temp_file_path)
|
||||||
|
markdown_content = result.text_content
|
||||||
|
|
||||||
|
logger.info("Successfully converted PDF to Markdown")
|
||||||
|
return markdown_content
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error converting PDF to Markdown: {e}")
|
||||||
|
return f"Error converting PDF content: {str(e)}. The document may be corrupted or in an unsupported format."
|
||||||
|
finally:
|
||||||
|
if temp_file_path and os.path.exists(temp_file_path):
|
||||||
|
os.remove(temp_file_path)
|
||||||
|
|
||||||
|
async def close_client_session(self):
|
||||||
|
"""Close HTTP client session"""
|
||||||
|
await self.http_client.aclose()
|
||||||
|
logger.info("BedestenApiClient: HTTP client session closed.")
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
# bedesten_mcp_module/models.py
|
||||||
|
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from typing import List, Optional, Dict, Any, Literal, Union
|
||||||
|
|
||||||
|
# Import YargitayBirimEnum for chamber filtering
|
||||||
|
from yargitay_mcp_module.models import YargitayBirimEnum
|
||||||
|
|
||||||
|
# Danıştay Chamber/Board Options
|
||||||
|
DanistayBirimEnum = Literal[
|
||||||
|
"", # Empty string for "All" chambers
|
||||||
|
# Main Councils
|
||||||
|
"Büyük Gen.Kur.", # Grand General Assembly
|
||||||
|
"İdare Dava Daireleri Kurulu", # Administrative Cases Chambers Council
|
||||||
|
"Vergi Dava Daireleri Kurulu", # Tax Cases Chambers Council
|
||||||
|
"İçtihatları Birleştirme Kurulu", # Precedents Unification Council
|
||||||
|
"İdari İşler Kurulu", # Administrative Affairs Council
|
||||||
|
"Başkanlar Kurulu", # Presidents Council
|
||||||
|
# Chambers
|
||||||
|
"1. Daire", "2. Daire", "3. Daire", "4. Daire", "5. Daire",
|
||||||
|
"6. Daire", "7. Daire", "8. Daire", "9. Daire", "10. Daire",
|
||||||
|
"11. Daire", "12. Daire", "13. Daire", "14. Daire", "15. Daire",
|
||||||
|
"16. Daire", "17. Daire",
|
||||||
|
# Military High Administrative Court
|
||||||
|
"Askeri Yüksek İdare Mahkemesi",
|
||||||
|
"Askeri Yüksek İdare Mahkemesi Daireler Kurulu",
|
||||||
|
"Askeri Yüksek İdare Mahkemesi Başsavcılığı",
|
||||||
|
"Askeri Yüksek İdare Mahkemesi 1. Daire",
|
||||||
|
"Askeri Yüksek İdare Mahkemesi 2. Daire",
|
||||||
|
"Askeri Yüksek İdare Mahkemesi 3. Daire"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Search Request Models
|
||||||
|
class BedestenSearchData(BaseModel):
|
||||||
|
pageSize: int
|
||||||
|
pageNumber: int
|
||||||
|
itemTypeList: List[str]
|
||||||
|
phrase: str
|
||||||
|
birimAdi: Optional[Union[YargitayBirimEnum, DanistayBirimEnum]] = Field(None, description="""
|
||||||
|
Chamber/Board filter (optional). Available options depend on itemTypeList:
|
||||||
|
|
||||||
|
For YARGITAYKARARI (52 options):
|
||||||
|
- None/null for ALL chambers
|
||||||
|
- 'Hukuk Genel Kurulu', '1. Hukuk Dairesi' through '23. Hukuk Dairesi'
|
||||||
|
- 'Ceza Genel Kurulu', '1. Ceza Dairesi' through '23. Ceza Dairesi'
|
||||||
|
- 'Hukuk Daireleri Başkanlar Kurulu', 'Ceza Daireleri Başkanlar Kurulu'
|
||||||
|
- 'Büyük Genel Kurulu'
|
||||||
|
|
||||||
|
For DANISTAYKARAR (27 options):
|
||||||
|
- None/null for ALL chambers
|
||||||
|
- 'Büyük Gen.Kur.', 'İdare Dava Daireleri Kurulu', 'Vergi Dava Daireleri Kurulu'
|
||||||
|
- '1. Daire' through '17. Daire'
|
||||||
|
- 'İçtihatları Birleştirme Kurulu', 'İdari İşler Kurulu', 'Başkanlar Kurulu'
|
||||||
|
- Military courts: 'Askeri Yüksek İdare Mahkemesi' variants
|
||||||
|
""")
|
||||||
|
sortFields: List[str] = ["KARAR_TARIHI"]
|
||||||
|
sortDirection: str = "desc"
|
||||||
|
|
||||||
|
class BedestenSearchRequest(BaseModel):
|
||||||
|
data: BedestenSearchData
|
||||||
|
applicationName: str = "UyapMevzuat"
|
||||||
|
paging: bool = True
|
||||||
|
|
||||||
|
# Search Response Models
|
||||||
|
class BedestenItemType(BaseModel):
|
||||||
|
name: str
|
||||||
|
description: str
|
||||||
|
|
||||||
|
class BedestenDecisionEntry(BaseModel):
|
||||||
|
documentId: str
|
||||||
|
itemType: BedestenItemType
|
||||||
|
birimId: Optional[str] = None
|
||||||
|
birimAdi: Optional[str]
|
||||||
|
esasNoYil: int
|
||||||
|
esasNoSira: int
|
||||||
|
kararNoYil: int
|
||||||
|
kararNoSira: int
|
||||||
|
kararTuru: Optional[str] = None
|
||||||
|
kararTarihi: str
|
||||||
|
kararTarihiStr: str
|
||||||
|
kesinlesmeDurumu: Optional[str] = None
|
||||||
|
kararNo: str
|
||||||
|
esasNo: str
|
||||||
|
|
||||||
|
class BedestenSearchDataResponse(BaseModel):
|
||||||
|
emsalKararList: List[BedestenDecisionEntry]
|
||||||
|
total: int
|
||||||
|
start: int
|
||||||
|
|
||||||
|
class BedestenSearchResponse(BaseModel):
|
||||||
|
data: BedestenSearchDataResponse
|
||||||
|
metadata: Dict[str, Any]
|
||||||
|
|
||||||
|
# Document Request/Response Models
|
||||||
|
class BedestenDocumentRequestData(BaseModel):
|
||||||
|
documentId: str
|
||||||
|
|
||||||
|
class BedestenDocumentRequest(BaseModel):
|
||||||
|
data: BedestenDocumentRequestData
|
||||||
|
applicationName: str = "UyapMevzuat"
|
||||||
|
|
||||||
|
class BedestenDocumentData(BaseModel):
|
||||||
|
content: str # Base64 encoded HTML or PDF
|
||||||
|
mimeType: str
|
||||||
|
version: int
|
||||||
|
|
||||||
|
class BedestenDocumentResponse(BaseModel):
|
||||||
|
data: BedestenDocumentData
|
||||||
|
metadata: Dict[str, Any]
|
||||||
|
|
||||||
|
class BedestenDocumentMarkdown(BaseModel):
|
||||||
|
documentId: str = Field(..., description="The document ID from Bedesten")
|
||||||
|
markdown_content: Optional[str] = Field(None, description="The decision content converted to Markdown")
|
||||||
|
source_url: str = Field(..., description="The source URL of the document")
|
||||||
|
mime_type: Optional[str] = Field(None, description="Original content type (text/html or application/pdf)")
|
||||||
+349
-5
@@ -36,7 +36,13 @@ from fastmcp import FastMCP
|
|||||||
# --- Module Imports ---
|
# --- Module Imports ---
|
||||||
from yargitay_mcp_module.client import YargitayOfficialApiClient
|
from yargitay_mcp_module.client import YargitayOfficialApiClient
|
||||||
from yargitay_mcp_module.models import (
|
from yargitay_mcp_module.models import (
|
||||||
YargitayDetailedSearchRequest, YargitayDocumentMarkdown, CompactYargitaySearchResult
|
YargitayDetailedSearchRequest, YargitayDocumentMarkdown, CompactYargitaySearchResult,
|
||||||
|
YargitayBirimEnum
|
||||||
|
)
|
||||||
|
from bedesten_mcp_module.client import BedestenApiClient
|
||||||
|
from bedesten_mcp_module.models import (
|
||||||
|
BedestenSearchRequest, BedestenSearchData,
|
||||||
|
BedestenDocumentMarkdown, DanistayBirimEnum
|
||||||
)
|
)
|
||||||
from danistay_mcp_module.client import DanistayApiClient
|
from danistay_mcp_module.client import DanistayApiClient
|
||||||
from danistay_mcp_module.models import (
|
from danistay_mcp_module.models import (
|
||||||
@@ -97,6 +103,7 @@ anayasa_norm_client_instance = AnayasaMahkemesiApiClient()
|
|||||||
anayasa_bireysel_client_instance = AnayasaBireyselBasvuruApiClient()
|
anayasa_bireysel_client_instance = AnayasaBireyselBasvuruApiClient()
|
||||||
kik_client_instance = KikApiClient()
|
kik_client_instance = KikApiClient()
|
||||||
rekabet_client_instance = RekabetKurumuApiClient()
|
rekabet_client_instance = RekabetKurumuApiClient()
|
||||||
|
bedesten_client_instance = BedestenApiClient()
|
||||||
|
|
||||||
|
|
||||||
KARAR_TURU_ADI_TO_GUID_ENUM_MAP = {
|
KARAR_TURU_ADI_TO_GUID_ENUM_MAP = {
|
||||||
@@ -120,9 +127,20 @@ async def search_yargitay_detailed(
|
|||||||
• +"phrase1" +"phrase2" = Multiple required phrases
|
• +"phrase1" +"phrase2" = Multiple required phrases
|
||||||
• +"required" -"excluded" = Include and exclude
|
• +"required" -"excluded" = Include and exclude
|
||||||
Examples: arsa payı | "arsa payı" | +"arsa payı" +"bozma sebebi" | bozma*"""),
|
Examples: arsa payı | "arsa payı" | +"arsa payı" +"bozma sebebi" | bozma*"""),
|
||||||
birimYrgKurulDaire: str = Field("", description="Yargitay Board Unit (e.g., 'Hukuk Genel Kurulu')."),
|
birimYrgKurulDaire: YargitayBirimEnum = Field("", description="""
|
||||||
birimYrgHukukDaire: str = Field("", description="Yargitay Civil Chamber (e.g., '1. Hukuk Dairesi')."),
|
Yargıtay chamber/board selection. Available options:
|
||||||
birimYrgCezaDaire: str = Field("", description="Yargitay Criminal Chamber."),
|
• Empty string ('') for ALL chambers
|
||||||
|
• Hukuk Genel Kurulu (Civil General Assembly)
|
||||||
|
• 1. Hukuk Dairesi through 23. Hukuk Dairesi (Civil Chambers 1-23)
|
||||||
|
• Hukuk Daireleri Başkanlar Kurulu (Civil Chambers Presidents Board)
|
||||||
|
• Ceza Genel Kurulu (Criminal General Assembly)
|
||||||
|
• 1. Ceza Dairesi through 23. Ceza Dairesi (Criminal Chambers 1-23)
|
||||||
|
• Ceza Daireleri Başkanlar Kurulu (Criminal Chambers Presidents Board)
|
||||||
|
• Büyük Genel Kurulu (Grand General Assembly)
|
||||||
|
Total: 49 possible values
|
||||||
|
"""),
|
||||||
|
birimYrgHukukDaire: str = Field("", description="Legacy field - use birimYrgKurulDaire instead"),
|
||||||
|
birimYrgCezaDaire: str = Field("", description="Legacy field - use birimYrgKurulDaire instead"),
|
||||||
esasYil: str = Field("", description="Case year for 'Esas No'."),
|
esasYil: str = Field("", description="Case year for 'Esas No'."),
|
||||||
esasIlkSiraNo: str = Field("", description="Starting sequence number for 'Esas No'."),
|
esasIlkSiraNo: str = Field("", description="Starting sequence number for 'Esas No'."),
|
||||||
esasSonSiraNo: str = Field("", description="Ending sequence number for 'Esas No'."),
|
esasSonSiraNo: str = Field("", description="Ending sequence number for 'Esas No'."),
|
||||||
@@ -756,6 +774,331 @@ async def get_rekabet_kurumu_document(
|
|||||||
logger.exception(f"Error in tool 'get_rekabet_kurumu_document'. Karar ID: {karar_id}")
|
logger.exception(f"Error in tool 'get_rekabet_kurumu_document'. Karar ID: {karar_id}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
# --- MCP Tools for Bedesten (Alternative Yargitay Search) ---
|
||||||
|
@app.tool()
|
||||||
|
async def search_yargitay_bedesten(
|
||||||
|
phrase: str = Field(..., description="Aranacak kavram/kelime"),
|
||||||
|
pageSize: int = Field(10, ge=1, le=100, description="Sayfa başına sonuç sayısı"),
|
||||||
|
pageNumber: int = Field(1, ge=1, description="Sayfa numarası"),
|
||||||
|
birimAdi: Optional[YargitayBirimEnum] = Field(None, description="""
|
||||||
|
Yargıtay chamber/board filter (optional). Available options:
|
||||||
|
• None for ALL chambers
|
||||||
|
• 'Hukuk Genel Kurulu' (Civil General Assembly)
|
||||||
|
• '1. Hukuk Dairesi' through '23. Hukuk Dairesi' (Civil Chambers 1-23)
|
||||||
|
• 'Hukuk Daireleri Başkanlar Kurulu' (Civil Chambers Presidents Board)
|
||||||
|
• 'Ceza Genel Kurulu' (Criminal General Assembly)
|
||||||
|
• '1. Ceza Dairesi' through '23. Ceza Dairesi' (Criminal Chambers 1-23)
|
||||||
|
• 'Ceza Daireleri Başkanlar Kurulu' (Criminal Chambers Presidents Board)
|
||||||
|
• 'Büyük Genel Kurulu' (Grand General Assembly)
|
||||||
|
Total: 49 chamber options
|
||||||
|
""")
|
||||||
|
) -> dict:
|
||||||
|
"""
|
||||||
|
Searches Yargıtay decisions using Bedesten API (alternative source).
|
||||||
|
This complements search_yargitay_detailed for comprehensive coverage.
|
||||||
|
Always use BOTH Yargıtay search tools for complete results.
|
||||||
|
|
||||||
|
Returns a simplified response with decision list and metadata.
|
||||||
|
"""
|
||||||
|
search_data = BedestenSearchData(
|
||||||
|
pageSize=pageSize,
|
||||||
|
pageNumber=pageNumber,
|
||||||
|
itemTypeList=["YARGITAYKARARI"], # Only Yargıtay decisions
|
||||||
|
phrase=phrase,
|
||||||
|
birimAdi=birimAdi
|
||||||
|
)
|
||||||
|
|
||||||
|
search_request = BedestenSearchRequest(data=search_data)
|
||||||
|
|
||||||
|
logger.info(f"Tool 'search_yargitay_bedesten' called: phrase='{phrase}', birimAdi='{birimAdi}', page={pageNumber}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = await bedesten_client_instance.search_documents(search_request)
|
||||||
|
|
||||||
|
# Return simplified response format
|
||||||
|
return {
|
||||||
|
"decisions": [d.model_dump() for d in response.data.emsalKararList],
|
||||||
|
"total_records": response.data.total,
|
||||||
|
"requested_page": pageNumber,
|
||||||
|
"page_size": pageSize
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in tool 'search_yargitay_bedesten'")
|
||||||
|
raise
|
||||||
|
|
||||||
|
@app.tool()
|
||||||
|
async def get_yargitay_bedesten_document_markdown(
|
||||||
|
documentId: str = Field(..., description="Document ID from Bedesten search results")
|
||||||
|
) -> BedestenDocumentMarkdown:
|
||||||
|
"""
|
||||||
|
Retrieves a Yargıtay decision document from Bedesten API and converts to Markdown.
|
||||||
|
Supports both HTML and PDF content types.
|
||||||
|
Use documentId from search_yargitay_bedesten results.
|
||||||
|
"""
|
||||||
|
logger.info(f"Tool 'get_yargitay_bedesten_document_markdown' called for ID: {documentId}")
|
||||||
|
|
||||||
|
if not documentId or not documentId.strip():
|
||||||
|
raise ValueError("Document ID must be a non-empty string.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
return await bedesten_client_instance.get_document_as_markdown(documentId)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in tool 'get_yargitay_bedesten_document_markdown'")
|
||||||
|
raise
|
||||||
|
|
||||||
|
# --- MCP Tools for Bedesten (Alternative Danıştay Search) ---
|
||||||
|
@app.tool()
|
||||||
|
async def search_danistay_bedesten(
|
||||||
|
phrase: str = Field(..., description="Aranacak kavram/kelime"),
|
||||||
|
pageSize: int = Field(10, ge=1, le=100, description="Sayfa başına sonuç sayısı"),
|
||||||
|
pageNumber: int = Field(1, ge=1, description="Sayfa numarası"),
|
||||||
|
birimAdi: Optional[DanistayBirimEnum] = Field(None, description="""
|
||||||
|
Danıştay chamber/board filter (optional). Available options:
|
||||||
|
• None for ALL chambers
|
||||||
|
• Main Councils: 'Büyük Gen.Kur.', 'İdare Dava Daireleri Kurulu', 'Vergi Dava Daireleri Kurulu'
|
||||||
|
• Chambers: '1. Daire' through '17. Daire' (17 administrative chambers)
|
||||||
|
• Special Councils: 'İçtihatları Birleştirme Kurulu', 'İdari İşler Kurulu', 'Başkanlar Kurulu'
|
||||||
|
• Military: 'Askeri Yüksek İdare Mahkemesi' and its chambers/councils
|
||||||
|
Total: 27 chamber options
|
||||||
|
""")
|
||||||
|
) -> dict:
|
||||||
|
"""
|
||||||
|
Searches Danıştay decisions using Bedesten API (alternative source).
|
||||||
|
This complements existing Danıştay search tools (search_danistay_by_keyword, search_danistay_detailed)
|
||||||
|
for comprehensive coverage. Always use ALL Danıştay search tools for complete results.
|
||||||
|
|
||||||
|
Returns a simplified response with decision list and metadata.
|
||||||
|
"""
|
||||||
|
search_data = BedestenSearchData(
|
||||||
|
pageSize=pageSize,
|
||||||
|
pageNumber=pageNumber,
|
||||||
|
itemTypeList=["DANISTAYKARAR"], # Only Danıştay decisions
|
||||||
|
phrase=phrase,
|
||||||
|
birimAdi=birimAdi
|
||||||
|
)
|
||||||
|
|
||||||
|
search_request = BedestenSearchRequest(data=search_data)
|
||||||
|
|
||||||
|
logger.info(f"Tool 'search_danistay_bedesten' called: phrase='{phrase}', birimAdi='{birimAdi}', page={pageNumber}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = await bedesten_client_instance.search_documents(search_request)
|
||||||
|
|
||||||
|
# Return simplified response format
|
||||||
|
return {
|
||||||
|
"decisions": [d.model_dump() for d in response.data.emsalKararList],
|
||||||
|
"total_records": response.data.total,
|
||||||
|
"requested_page": pageNumber,
|
||||||
|
"page_size": pageSize
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in tool 'search_danistay_bedesten'")
|
||||||
|
raise
|
||||||
|
|
||||||
|
@app.tool()
|
||||||
|
async def get_danistay_bedesten_document_markdown(
|
||||||
|
documentId: str = Field(..., description="Document ID from Bedesten search results")
|
||||||
|
) -> BedestenDocumentMarkdown:
|
||||||
|
"""
|
||||||
|
Retrieves a Danıştay decision document from Bedesten API and converts to Markdown.
|
||||||
|
Supports both HTML and PDF content types.
|
||||||
|
Use documentId from search_danistay_bedesten results.
|
||||||
|
"""
|
||||||
|
logger.info(f"Tool 'get_danistay_bedesten_document_markdown' called for ID: {documentId}")
|
||||||
|
|
||||||
|
if not documentId or not documentId.strip():
|
||||||
|
raise ValueError("Document ID must be a non-empty string.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
return await bedesten_client_instance.get_document_as_markdown(documentId)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in tool 'get_danistay_bedesten_document_markdown'")
|
||||||
|
raise
|
||||||
|
|
||||||
|
# --- MCP Tools for Bedesten (Yerel Hukuk Mahkemesi Search) ---
|
||||||
|
@app.tool()
|
||||||
|
async def search_yerel_hukuk_bedesten(
|
||||||
|
phrase: str = Field(..., description="Aranacak kavram/kelime"),
|
||||||
|
pageSize: int = Field(10, ge=1, le=100, description="Sayfa başına sonuç sayısı"),
|
||||||
|
pageNumber: int = Field(1, ge=1, description="Sayfa numarası")
|
||||||
|
) -> dict:
|
||||||
|
"""
|
||||||
|
Searches Yerel Hukuk Mahkemesi (Local Civil Court) decisions using Bedesten API.
|
||||||
|
This provides access to local court decisions that are not available through other APIs.
|
||||||
|
Currently the only available tool for searching Yerel Hukuk Mahkemesi decisions.
|
||||||
|
|
||||||
|
Returns a simplified response with decision list and metadata.
|
||||||
|
"""
|
||||||
|
search_data = BedestenSearchData(
|
||||||
|
pageSize=pageSize,
|
||||||
|
pageNumber=pageNumber,
|
||||||
|
itemTypeList=["YERELHUKUK"], # Local Civil Court decisions
|
||||||
|
phrase=phrase
|
||||||
|
)
|
||||||
|
|
||||||
|
search_request = BedestenSearchRequest(data=search_data)
|
||||||
|
|
||||||
|
logger.info(f"Tool 'search_yerel_hukuk_bedesten' called: phrase='{phrase}', page={pageNumber}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = await bedesten_client_instance.search_documents(search_request)
|
||||||
|
|
||||||
|
# Return simplified response format
|
||||||
|
return {
|
||||||
|
"decisions": [d.model_dump() for d in response.data.emsalKararList],
|
||||||
|
"total_records": response.data.total,
|
||||||
|
"requested_page": pageNumber,
|
||||||
|
"page_size": pageSize
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in tool 'search_yerel_hukuk_bedesten'")
|
||||||
|
raise
|
||||||
|
|
||||||
|
@app.tool()
|
||||||
|
async def get_yerel_hukuk_bedesten_document_markdown(
|
||||||
|
documentId: str = Field(..., description="Document ID from Bedesten search results")
|
||||||
|
) -> BedestenDocumentMarkdown:
|
||||||
|
"""
|
||||||
|
Retrieves a Yerel Hukuk Mahkemesi decision document from Bedesten API and converts to Markdown.
|
||||||
|
Supports both HTML and PDF content types.
|
||||||
|
Use documentId from search_yerel_hukuk_bedesten results.
|
||||||
|
"""
|
||||||
|
logger.info(f"Tool 'get_yerel_hukuk_bedesten_document_markdown' called for ID: {documentId}")
|
||||||
|
|
||||||
|
if not documentId or not documentId.strip():
|
||||||
|
raise ValueError("Document ID must be a non-empty string.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
return await bedesten_client_instance.get_document_as_markdown(documentId)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in tool 'get_yerel_hukuk_bedesten_document_markdown'")
|
||||||
|
raise
|
||||||
|
|
||||||
|
# --- MCP Tools for Bedesten (İstinaf Hukuk Mahkemesi Search) ---
|
||||||
|
@app.tool()
|
||||||
|
async def search_istinaf_hukuk_bedesten(
|
||||||
|
phrase: str = Field(..., description="Aranacak kavram/kelime"),
|
||||||
|
pageSize: int = Field(10, ge=1, le=100, description="Sayfa başına sonuç sayısı"),
|
||||||
|
pageNumber: int = Field(1, ge=1, description="Sayfa numarası")
|
||||||
|
) -> dict:
|
||||||
|
"""
|
||||||
|
Searches İstinaf Hukuk Mahkemesi (Civil Court of Appeals) decisions using Bedesten API.
|
||||||
|
This provides access to appellate court decisions that are not available through other APIs.
|
||||||
|
Currently the only available tool for searching İstinaf Hukuk Mahkemesi decisions.
|
||||||
|
|
||||||
|
İstinaf courts are intermediate appellate courts in the Turkish judicial system,
|
||||||
|
handling appeals from local civil courts before cases reach Yargıtay.
|
||||||
|
|
||||||
|
Returns a simplified response with decision list and metadata.
|
||||||
|
"""
|
||||||
|
search_data = BedestenSearchData(
|
||||||
|
pageSize=pageSize,
|
||||||
|
pageNumber=pageNumber,
|
||||||
|
itemTypeList=["ISTINAFHUKUK"], # Civil Court of Appeals decisions
|
||||||
|
phrase=phrase
|
||||||
|
)
|
||||||
|
|
||||||
|
search_request = BedestenSearchRequest(data=search_data)
|
||||||
|
|
||||||
|
logger.info(f"Tool 'search_istinaf_hukuk_bedesten' called: phrase='{phrase}', page={pageNumber}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = await bedesten_client_instance.search_documents(search_request)
|
||||||
|
|
||||||
|
# Return simplified response format
|
||||||
|
return {
|
||||||
|
"decisions": [d.model_dump() for d in response.data.emsalKararList],
|
||||||
|
"total_records": response.data.total,
|
||||||
|
"requested_page": pageNumber,
|
||||||
|
"page_size": pageSize
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in tool 'search_istinaf_hukuk_bedesten'")
|
||||||
|
raise
|
||||||
|
|
||||||
|
@app.tool()
|
||||||
|
async def get_istinaf_hukuk_bedesten_document_markdown(
|
||||||
|
documentId: str = Field(..., description="Document ID from Bedesten search results")
|
||||||
|
) -> BedestenDocumentMarkdown:
|
||||||
|
"""
|
||||||
|
Retrieves an İstinaf Hukuk Mahkemesi decision document from Bedesten API and converts to Markdown.
|
||||||
|
Supports both HTML and PDF content types.
|
||||||
|
Use documentId from search_istinaf_hukuk_bedesten results.
|
||||||
|
"""
|
||||||
|
logger.info(f"Tool 'get_istinaf_hukuk_bedesten_document_markdown' called for ID: {documentId}")
|
||||||
|
|
||||||
|
if not documentId or not documentId.strip():
|
||||||
|
raise ValueError("Document ID must be a non-empty string.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
return await bedesten_client_instance.get_document_as_markdown(documentId)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in tool 'get_istinaf_hukuk_bedesten_document_markdown'")
|
||||||
|
raise
|
||||||
|
|
||||||
|
# --- MCP Tools for Bedesten (Kanun Yararına Bozma Search) ---
|
||||||
|
@app.tool()
|
||||||
|
async def search_kyb_bedesten(
|
||||||
|
phrase: str = Field(..., description="Aranacak kavram/kelime"),
|
||||||
|
pageSize: int = Field(10, ge=1, le=100, description="Sayfa başına sonuç sayısı"),
|
||||||
|
pageNumber: int = Field(1, ge=1, description="Sayfa numarası")
|
||||||
|
) -> dict:
|
||||||
|
"""
|
||||||
|
Searches Kanun Yararına Bozma (KYB - Extraordinary Appeal) decisions using Bedesten API.
|
||||||
|
This provides access to extraordinary appeal decisions that are not available through other APIs.
|
||||||
|
Currently the only available tool for searching KYB decisions.
|
||||||
|
|
||||||
|
KYB decisions are extraordinary appeals in the Turkish judicial system,
|
||||||
|
where the Public Prosecutor's Office can request review of finalized decisions
|
||||||
|
in favor of the law and defendants.
|
||||||
|
|
||||||
|
Returns a simplified response with decision list and metadata.
|
||||||
|
"""
|
||||||
|
search_data = BedestenSearchData(
|
||||||
|
pageSize=pageSize,
|
||||||
|
pageNumber=pageNumber,
|
||||||
|
itemTypeList=["KYB"], # Kanun Yararına Bozma decisions
|
||||||
|
phrase=phrase
|
||||||
|
)
|
||||||
|
|
||||||
|
search_request = BedestenSearchRequest(data=search_data)
|
||||||
|
|
||||||
|
logger.info(f"Tool 'search_kyb_bedesten' called: phrase='{phrase}', page={pageNumber}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = await bedesten_client_instance.search_documents(search_request)
|
||||||
|
|
||||||
|
# Return simplified response format
|
||||||
|
return {
|
||||||
|
"decisions": [d.model_dump() for d in response.data.emsalKararList],
|
||||||
|
"total_records": response.data.total,
|
||||||
|
"requested_page": pageNumber,
|
||||||
|
"page_size": pageSize
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in tool 'search_kyb_bedesten'")
|
||||||
|
raise
|
||||||
|
|
||||||
|
@app.tool()
|
||||||
|
async def get_kyb_bedesten_document_markdown(
|
||||||
|
documentId: str = Field(..., description="Document ID from Bedesten search results")
|
||||||
|
) -> BedestenDocumentMarkdown:
|
||||||
|
"""
|
||||||
|
Retrieves a Kanun Yararına Bozma (KYB) decision document from Bedesten API and converts to Markdown.
|
||||||
|
Supports both HTML and PDF content types.
|
||||||
|
Use documentId from search_kyb_bedesten results.
|
||||||
|
"""
|
||||||
|
logger.info(f"Tool 'get_kyb_bedesten_document_markdown' called for ID: {documentId}")
|
||||||
|
|
||||||
|
if not documentId or not documentId.strip():
|
||||||
|
raise ValueError("Document ID must be a non-empty string.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
return await bedesten_client_instance.get_document_as_markdown(documentId)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in tool 'get_kyb_bedesten_document_markdown'")
|
||||||
|
raise
|
||||||
|
|
||||||
# --- Application Shutdown Handling ---
|
# --- Application Shutdown Handling ---
|
||||||
def perform_cleanup():
|
def perform_cleanup():
|
||||||
logger.info("MCP Server performing cleanup...")
|
logger.info("MCP Server performing cleanup...")
|
||||||
@@ -775,7 +1118,8 @@ def perform_cleanup():
|
|||||||
globals().get('anayasa_norm_client_instance'),
|
globals().get('anayasa_norm_client_instance'),
|
||||||
globals().get('anayasa_bireysel_client_instance'),
|
globals().get('anayasa_bireysel_client_instance'),
|
||||||
globals().get('kik_client_instance'),
|
globals().get('kik_client_instance'),
|
||||||
globals().get('rekabet_client_instance')
|
globals().get('rekabet_client_instance'),
|
||||||
|
globals().get('bedesten_client_instance')
|
||||||
]
|
]
|
||||||
async def close_all_clients_async():
|
async def close_all_clients_async():
|
||||||
tasks = []
|
tasks = []
|
||||||
|
|||||||
@@ -1,7 +1,32 @@
|
|||||||
# yargitay_mcp_module/models.py
|
# yargitay_mcp_module/models.py
|
||||||
|
|
||||||
from pydantic import BaseModel, Field, HttpUrl
|
from pydantic import BaseModel, Field, HttpUrl
|
||||||
from typing import List, Optional, Dict, Any
|
from typing import List, Optional, Dict, Any, Literal
|
||||||
|
|
||||||
|
# Yargıtay Chamber/Board Options
|
||||||
|
YargitayBirimEnum = Literal[
|
||||||
|
"", # Empty string for "All" chambers
|
||||||
|
# Hukuk (Civil) Chambers
|
||||||
|
"Hukuk Genel Kurulu",
|
||||||
|
"1. Hukuk Dairesi", "2. Hukuk Dairesi", "3. Hukuk Dairesi", "4. Hukuk Dairesi",
|
||||||
|
"5. Hukuk Dairesi", "6. Hukuk Dairesi", "7. Hukuk Dairesi", "8. Hukuk Dairesi",
|
||||||
|
"9. Hukuk Dairesi", "10. Hukuk Dairesi", "11. Hukuk Dairesi", "12. Hukuk Dairesi",
|
||||||
|
"13. Hukuk Dairesi", "14. Hukuk Dairesi", "15. Hukuk Dairesi", "16. Hukuk Dairesi",
|
||||||
|
"17. Hukuk Dairesi", "18. Hukuk Dairesi", "19. Hukuk Dairesi", "20. Hukuk Dairesi",
|
||||||
|
"21. Hukuk Dairesi", "22. Hukuk Dairesi", "23. Hukuk Dairesi",
|
||||||
|
"Hukuk Daireleri Başkanlar Kurulu",
|
||||||
|
# Ceza (Criminal) Chambers
|
||||||
|
"Ceza Genel Kurulu",
|
||||||
|
"1. Ceza Dairesi", "2. Ceza Dairesi", "3. Ceza Dairesi", "4. Ceza Dairesi",
|
||||||
|
"5. Ceza Dairesi", "6. Ceza Dairesi", "7. Ceza Dairesi", "8. Ceza Dairesi",
|
||||||
|
"9. Ceza Dairesi", "10. Ceza Dairesi", "11. Ceza Dairesi", "12. Ceza Dairesi",
|
||||||
|
"13. Ceza Dairesi", "14. Ceza Dairesi", "15. Ceza Dairesi", "16. Ceza Dairesi",
|
||||||
|
"17. Ceza Dairesi", "18. Ceza Dairesi", "19. Ceza Dairesi", "20. Ceza Dairesi",
|
||||||
|
"21. Ceza Dairesi", "22. Ceza Dairesi", "23. Ceza Dairesi",
|
||||||
|
"Ceza Daireleri Başkanlar Kurulu",
|
||||||
|
# General Assembly
|
||||||
|
"Büyük Genel Kurulu"
|
||||||
|
]
|
||||||
|
|
||||||
class YargitayDetailedSearchRequest(BaseModel):
|
class YargitayDetailedSearchRequest(BaseModel):
|
||||||
"""
|
"""
|
||||||
@@ -10,11 +35,17 @@ class YargitayDetailedSearchRequest(BaseModel):
|
|||||||
Based on the payload provided by the user.
|
Based on the payload provided by the user.
|
||||||
"""
|
"""
|
||||||
arananKelime: Optional[str] = Field("", description="Keyword to search for.")
|
arananKelime: Optional[str] = Field("", description="Keyword to search for.")
|
||||||
# Department/Board selection. Based on user provided payload.
|
# Department/Board selection - Complete Yargıtay chamber hierarchy
|
||||||
# birimYrg* fields seem to be the ones used for filtering.
|
birimYrgKurulDaire: YargitayBirimEnum = Field("", description="""
|
||||||
birimYrgKurulDaire: Optional[str] = Field("", description="Yargitay Board Unit (e.g., 'Hukuk Genel Kurulu').")
|
Yargıtay chamber/board selection. Options include:
|
||||||
birimYrgHukukDaire: Optional[str] = Field("", description="Yargitay Civil Chamber (e.g., '1. Hukuk Dairesi').")
|
- Empty string ('') for ALL chambers
|
||||||
birimYrgCezaDaire: Optional[str] = Field("", description="Yargitay Criminal Chamber.")
|
- Civil: 'Hukuk Genel Kurulu', '1. Hukuk Dairesi' through '23. Hukuk Dairesi', 'Hukuk Daireleri Başkanlar Kurulu'
|
||||||
|
- Criminal: 'Ceza Genel Kurulu', '1. Ceza Dairesi' through '23. Ceza Dairesi', 'Ceza Daireleri Başkanlar Kurulu'
|
||||||
|
- General: 'Büyük Genel Kurulu'
|
||||||
|
Total: 49 possible values (including empty string for all chambers)
|
||||||
|
""")
|
||||||
|
birimYrgHukukDaire: Optional[str] = Field("", description="Legacy field - use birimYrgKurulDaire instead")
|
||||||
|
birimYrgCezaDaire: Optional[str] = Field("", description="Legacy field - use birimYrgKurulDaire instead")
|
||||||
|
|
||||||
esasYil: Optional[str] = Field("", description="Case year for 'Esas No'.")
|
esasYil: Optional[str] = Field("", description="Case year for 'Esas No'.")
|
||||||
esasIlkSiraNo: Optional[str] = Field("", description="Starting sequence number for 'Esas No'.")
|
esasIlkSiraNo: Optional[str] = Field("", description="Starting sequence number for 'Esas No'.")
|
||||||
|
|||||||
Reference in New Issue
Block a user