optimize token usage
This commit is contained in:
+20
@@ -192,3 +192,23 @@ scripts/deploy-flyio.sh
|
||||
docs/DEPLOYMENT_FLYIO.md
|
||||
setup_jwt_template.py
|
||||
mcp_server_main.py.backup
|
||||
mcp_overhead_content.json
|
||||
ANTHROPIC_TEST_README.md
|
||||
extract_mcp_overhead.py
|
||||
mcp_overhead_content.txt
|
||||
mcp_overhead_summary.txt
|
||||
run_http_server.py
|
||||
run_local_test.py
|
||||
|
||||
# MCP overhead analysis files
|
||||
mcp_overhead_*.json
|
||||
mcp_overhead_*.txt
|
||||
mcp_test_results_*.json
|
||||
mcp_quick_test_*.json
|
||||
|
||||
# General text files (temporary notes, etc)
|
||||
*.txt
|
||||
analyze_playwright_mcp.py
|
||||
measure_mcp_directly.py
|
||||
playwright_mcp_overhead.json
|
||||
simple_test.py
|
||||
|
||||
@@ -90,59 +90,59 @@ class AnayasaNormDenetimiSearchRequest(BaseModel):
|
||||
keywords_any: Optional[List[str]] = Field(default_factory=list, description="Keywords for OR logic (HerhangiBirKelimeAra[]).")
|
||||
keywords_exclude: Optional[List[str]] = Field(default_factory=list, description="Keywords to exclude (BulunmayanKelimeAra[]).")
|
||||
period: Optional[AnayasaDonemEnum] = Field(default=AnayasaDonemEnum.TUMU, description="Constitutional period (Donemler_id).")
|
||||
case_number_esas: Optional[str] = Field(None, description="Case registry number (EsasNo), e.g., '2023/123'.")
|
||||
decision_number_karar: Optional[str] = Field(None, description="Decision number (KararNo), e.g., '2023/456'.")
|
||||
first_review_date_start: Optional[str] = Field(None, description="First review start date (IlkIncelemeTarihiIlk), format DD/MM/YYYY.")
|
||||
first_review_date_end: Optional[str] = Field(None, description="First review end date (IlkIncelemeTarihiSon), format DD/MM/YYYY.")
|
||||
decision_date_start: Optional[str] = Field(None, description="Decision start date (KararTarihiIlk), format DD/MM/YYYY.")
|
||||
decision_date_end: Optional[str] = Field(None, description="Decision end date (KararTarihiSon), format DD/MM/YYYY.")
|
||||
case_number_esas: str = Field("", description="Case registry number (EsasNo), e.g., '2023/123'.")
|
||||
decision_number_karar: str = Field("", description="Decision number (KararNo), e.g., '2023/456'.")
|
||||
first_review_date_start: str = Field("", description="First review start date (IlkIncelemeTarihiIlk), format DD/MM/YYYY.")
|
||||
first_review_date_end: str = Field("", description="First review end date (IlkIncelemeTarihiSon), format DD/MM/YYYY.")
|
||||
decision_date_start: str = Field("", description="Decision start date (KararTarihiIlk), format DD/MM/YYYY.")
|
||||
decision_date_end: str = Field("", description="Decision end date (KararTarihiSon), format DD/MM/YYYY.")
|
||||
application_type: Optional[AnayasaBasvuruTuruEnum] = Field(default=AnayasaBasvuruTuruEnum.TUMU, description="Type of application (BasvuruTurler_id).")
|
||||
applicant_general_name: Optional[str] = Field(None, description="General applicant name (BasvuranGeneller_id).")
|
||||
applicant_specific_name: Optional[str] = Field(None, description="Specific applicant name (BasvuranOzeller_id).")
|
||||
official_gazette_date_start: Optional[str] = Field(None, description="Official Gazette start date (ResmiGazeteTarihiIlk), format DD/MM/YYYY.")
|
||||
official_gazette_date_end: Optional[str] = Field(None, description="Official Gazette end date (ResmiGazeteTarihiSon), format DD/MM/YYYY.")
|
||||
official_gazette_number_start: Optional[str] = Field(None, description="Official Gazette starting number (ResmiGazeteSayisiIlk).")
|
||||
official_gazette_number_end: Optional[str] = Field(None, description="Official Gazette ending number (ResmiGazeteSayisiSon).")
|
||||
applicant_general_name: str = Field("", description="General applicant name (BasvuranGeneller_id).")
|
||||
applicant_specific_name: str = Field("", description="Specific applicant name (BasvuranOzeller_id).")
|
||||
official_gazette_date_start: str = Field("", description="Official Gazette start date (ResmiGazeteTarihiIlk), format DD/MM/YYYY.")
|
||||
official_gazette_date_end: str = Field("", description="Official Gazette end date (ResmiGazeteTarihiSon), format DD/MM/YYYY.")
|
||||
official_gazette_number_start: str = Field("", description="Official Gazette starting number (ResmiGazeteSayisiIlk).")
|
||||
official_gazette_number_end: str = Field("", description="Official Gazette ending number (ResmiGazeteSayisiSon).")
|
||||
has_press_release: Optional[AnayasaVarYokEnum] = Field(default=AnayasaVarYokEnum.TUMU, description="Press release available (BasinDuyurusu).")
|
||||
has_dissenting_opinion: Optional[AnayasaVarYokEnum] = Field(default=AnayasaVarYokEnum.TUMU, description="Dissenting opinion exists (KarsiOy).")
|
||||
has_different_reasoning: Optional[AnayasaVarYokEnum] = Field(default=AnayasaVarYokEnum.TUMU, description="Different reasoning exists (FarkliGerekce).")
|
||||
attending_members_names: Optional[List[str]] = Field(default_factory=list, description="List of attending members' exact names (Uyeler_id[]).")
|
||||
rapporteur_name: Optional[str] = Field(None, description="Rapporteur's exact name (Raportorler_id).")
|
||||
rapporteur_name: str = Field("", description="Rapporteur's exact name (Raportorler_id).")
|
||||
norm_type: Optional[AnayasaNormTuruEnum] = Field(default=AnayasaNormTuruEnum.TUMU, description="Type of the reviewed norm (NormunTurler_id).")
|
||||
norm_id_or_name: Optional[str] = Field(None, description="Number or name of the norm (NormunNumarasiAdlar_id).")
|
||||
norm_article: Optional[str] = Field(None, description="Article number of the norm (NormunMaddeNumarasi).")
|
||||
norm_id_or_name: str = Field("", description="Number or name of the norm (NormunNumarasiAdlar_id).")
|
||||
norm_article: str = Field("", description="Article number of the norm (NormunMaddeNumarasi).")
|
||||
review_outcomes: Optional[List[AnayasaIncelemeSonucuEnum]] = Field(default_factory=list, description="List of review types and outcomes (IncelemeTuruKararSonuclar_id[]).")
|
||||
reason_for_final_outcome: Optional[AnayasaSonucGerekcesiEnum] = Field(default=AnayasaSonucGerekcesiEnum.TUMU, description="Main reason for the decision outcome (KararSonucununGerekcesi).")
|
||||
basis_constitution_article_numbers: Optional[List[str]] = Field(default_factory=list, description="List of supporting Constitution article numbers (DayanakHukmu[]).")
|
||||
results_per_page: Optional[int] = Field(10, ge=1, le=10, description="Results per page.")
|
||||
page_to_fetch: Optional[int] = Field(1, ge=1, description="Page number to fetch for results list.")
|
||||
sort_by_criteria: Optional[str] = Field("KararTarihi", description="Sort criteria. Options: 'KararTarihi', 'YayinTarihi', 'Toplam' (keyword count).")
|
||||
results_per_page: int = Field(10, ge=1, le=10, description="Results per page.")
|
||||
page_to_fetch: int = Field(1, ge=1, description="Page number to fetch for results list.")
|
||||
sort_by_criteria: str = Field("KararTarihi", description="Sort criteria. Options: 'KararTarihi', 'YayinTarihi', 'Toplam' (keyword count).")
|
||||
|
||||
class AnayasaReviewedNormInfo(BaseModel):
|
||||
"""Details of a norm reviewed within an AYM decision summary."""
|
||||
norm_name_or_number: Optional[str] = None
|
||||
article_number: Optional[str] = None
|
||||
review_type_and_outcome: Optional[str] = None
|
||||
outcome_reason: Optional[str] = None
|
||||
norm_name_or_number: str = Field("", description="Norm name or number")
|
||||
article_number: str = Field("", description="Article number")
|
||||
review_type_and_outcome: str = Field("", description="Review type and outcome")
|
||||
outcome_reason: str = Field("", description="Outcome reason")
|
||||
basis_constitution_articles_cited: List[str] = Field(default_factory=list)
|
||||
postponement_period: Optional[str] = None
|
||||
postponement_period: str = Field("", description="Postponement period")
|
||||
|
||||
class AnayasaDecisionSummary(BaseModel):
|
||||
"""Model for a single Anayasa Mahkemesi (Norm Denetimi) decision summary from search results."""
|
||||
decision_reference_no: Optional[str] = None
|
||||
decision_page_url: Optional[HttpUrl] = None
|
||||
keywords_found_count: Optional[int] = None
|
||||
application_type_summary: Optional[str] = None
|
||||
applicant_summary: Optional[str] = None
|
||||
decision_outcome_summary: Optional[str] = None
|
||||
decision_date_summary: Optional[str] = None
|
||||
decision_reference_no: str = Field("", description="Decision reference number")
|
||||
decision_page_url: str = Field("", description="Decision page URL")
|
||||
keywords_found_count: int = Field(0, description="Keywords found count")
|
||||
application_type_summary: str = Field("", description="Application type summary")
|
||||
applicant_summary: str = Field("", description="Applicant summary")
|
||||
decision_outcome_summary: str = Field("", description="Decision outcome summary")
|
||||
decision_date_summary: str = Field("", description="Decision date summary")
|
||||
reviewed_norms: List[AnayasaReviewedNormInfo] = Field(default_factory=list)
|
||||
|
||||
class AnayasaSearchResult(BaseModel):
|
||||
"""Model for the overall search result for Anayasa Mahkemesi Norm Denetimi decisions."""
|
||||
decisions: List[AnayasaDecisionSummary]
|
||||
total_records_found: Optional[int] = None
|
||||
retrieved_page_number: Optional[int] = None
|
||||
total_records_found: int = Field(0, description="Total records found")
|
||||
retrieved_page_number: int = Field(1, description="Retrieved page number")
|
||||
|
||||
class AnayasaDocumentMarkdown(BaseModel):
|
||||
"""
|
||||
@@ -150,10 +150,10 @@ class AnayasaDocumentMarkdown(BaseModel):
|
||||
and pagination information.
|
||||
"""
|
||||
source_url: HttpUrl
|
||||
decision_reference_no_from_page: Optional[str] = Field(None, description="E.K. No parsed from the document page.")
|
||||
decision_date_from_page: Optional[str] = Field(None, description="Decision date parsed from the document page.")
|
||||
official_gazette_info_from_page: Optional[str] = Field(None, description="Official Gazette info parsed from the document page.")
|
||||
markdown_chunk: Optional[str] = Field(None, description="A 5,000 character chunk of the Markdown content.") # Corrected chunk size
|
||||
decision_reference_no_from_page: str = Field("", description="E.K. No parsed from the document page.")
|
||||
decision_date_from_page: str = Field("", description="Decision date parsed from the document page.")
|
||||
official_gazette_info_from_page: str = Field("", description="Official Gazette info parsed from the document page.")
|
||||
markdown_chunk: str = Field("", description="A 5,000 character chunk of the Markdown content.") # Corrected chunk size
|
||||
current_page: int = Field(description="The current page number of the markdown chunk (1-indexed).")
|
||||
total_pages: int = Field(description="Total number of pages for the full markdown content.")
|
||||
is_paginated: bool = Field(description="True if the full markdown content is split into multiple pages.")
|
||||
@@ -168,27 +168,27 @@ class AnayasaBireyselReportSearchRequest(BaseModel):
|
||||
|
||||
class AnayasaBireyselReportDecisionDetail(BaseModel):
|
||||
"""Details of a specific right/claim within a Bireysel Başvuru decision summary in a report."""
|
||||
hak: Optional[str] = Field(None, description="İhlal edildiği iddia edilen hak (örneğin, Mülkiyet hakkı).")
|
||||
mudahale_iddiasi: Optional[str] = Field(None, description="İhlale neden olan müdahale iddiası.")
|
||||
sonuc: Optional[str] = Field(None, description="İnceleme sonucu (örneğin, İhlal, Düşme).")
|
||||
giderim: Optional[str] = Field(None, description="Kararlaştırılan giderim (örneğin, Yeniden yargılama).")
|
||||
hak: str = Field("", description="İhlal edildiği iddia edilen hak (örneğin, Mülkiyet hakkı).")
|
||||
mudahale_iddiasi: str = Field("", description="İhlale neden olan müdahale iddiası.")
|
||||
sonuc: str = Field("", description="İnceleme sonucu (örneğin, İhlal, Düşme).")
|
||||
giderim: str = Field("", description="Kararlaştırılan giderim (örneğin, Yeniden yargılama).")
|
||||
|
||||
class AnayasaBireyselReportDecisionSummary(BaseModel):
|
||||
"""Model for a single Anayasa Mahkemesi (Bireysel Başvuru) decision summary from a 'Karar Arama Raporu'."""
|
||||
title: Optional[str] = Field(None, description="Başvurunun başlığı (e.g., 'HASAN DURMUŞ Başvurusuna İlişkin Karar').")
|
||||
decision_reference_no: Optional[str] = Field(None, description="Başvuru Numarası (e.g., '2019/19126').")
|
||||
decision_page_url: Optional[HttpUrl] = Field(None, description="URL to the full decision page.")
|
||||
decision_type_summary: Optional[str] = Field(None, description="Karar Türü (Başvuru Sonucu) (e.g., 'Esas (İhlal)').")
|
||||
decision_making_body: Optional[str] = Field(None, description="Kararı Veren Birim (e.g., 'Genel Kurul', 'Birinci Bölüm').")
|
||||
application_date_summary: Optional[str] = Field(None, description="Başvuru Tarihi (DD/MM/YYYY).")
|
||||
decision_date_summary: Optional[str] = Field(None, description="Karar Tarihi (DD/MM/YYYY).")
|
||||
application_subject_summary: Optional[str] = Field(None, description="Başvuru konusunun özeti.")
|
||||
title: str = Field("", description="Başvurunun başlığı (e.g., 'HASAN DURMUŞ Başvurusuna İlişkin Karar').")
|
||||
decision_reference_no: str = Field("", description="Başvuru Numarası (e.g., '2019/19126').")
|
||||
decision_page_url: str = Field("", description="URL to the full decision page.")
|
||||
decision_type_summary: str = Field("", description="Karar Türü (Başvuru Sonucu) (e.g., 'Esas (İhlal)').")
|
||||
decision_making_body: str = Field("", description="Kararı Veren Birim (e.g., 'Genel Kurul', 'Birinci Bölüm').")
|
||||
application_date_summary: str = Field("", description="Başvuru Tarihi (DD/MM/YYYY).")
|
||||
decision_date_summary: str = Field("", description="Karar Tarihi (DD/MM/YYYY).")
|
||||
application_subject_summary: str = Field("", description="Başvuru konusunun özeti.")
|
||||
details: List[AnayasaBireyselReportDecisionDetail] = Field(default_factory=list, description="İncelenen haklar ve sonuçlarına ilişkin detaylar.")
|
||||
|
||||
class AnayasaBireyselReportSearchResult(BaseModel):
|
||||
"""Model for the overall search result for Anayasa Mahkemesi 'Karar Arama Raporu'."""
|
||||
decisions: List[AnayasaBireyselReportDecisionSummary]
|
||||
total_records_found: Optional[int] = Field(None, description="Raporda bulunan toplam karar sayısı.")
|
||||
total_records_found: int = Field(0, description="Raporda bulunan toplam karar sayısı.")
|
||||
retrieved_page_number: int = Field(description="Alınan rapor sayfa numarası.")
|
||||
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ class DanistayApiClient:
|
||||
mevzuatNumarasi=params.mevzuatNumarasi or "",
|
||||
mevzuatAdi=params.mevzuatAdi or "",
|
||||
madde=params.madde or "",
|
||||
siralama=params.siralama,
|
||||
siralamaDirection=params.siralamaDirection,
|
||||
siralama="1",
|
||||
siralamaDirection="desc",
|
||||
pageSize=params.pageSize,
|
||||
pageNumber=params.pageNumber
|
||||
)
|
||||
|
||||
@@ -51,20 +51,18 @@ class DanistayDetailedSearchRequestData(BaseModel): # Internal data model for de
|
||||
|
||||
class DanistayDetailedSearchRequest(DanistayBaseSearchRequest): # MCP tool will accept this
|
||||
"""Model for detailed search request for Danistay."""
|
||||
daire: Optional[str] = Field(None, description="Chamber")
|
||||
esasYil: Optional[str] = Field(None, description="Case year")
|
||||
esasIlkSiraNo: Optional[str] = Field(None, description="Start case no")
|
||||
esasSonSiraNo: Optional[str] = Field(None, description="End case no")
|
||||
kararYil: Optional[str] = Field(None, description="Decision year")
|
||||
kararIlkSiraNo: Optional[str] = Field(None, description="Start decision no")
|
||||
kararSonSiraNo: Optional[str] = Field(None, description="End decision no")
|
||||
baslangicTarihi: Optional[str] = Field(None, description="Start date")
|
||||
bitisTarihi: Optional[str] = Field(None, description="End date")
|
||||
mevzuatNumarasi: Optional[str] = Field(None, description="Law number")
|
||||
mevzuatAdi: Optional[str] = Field(None, description="Law name")
|
||||
madde: Optional[str] = Field(None, description="Article")
|
||||
siralama: str = Field("1", description="Sort by")
|
||||
siralamaDirection: str = Field("desc", description="Direction")
|
||||
daire: str = Field("", description="Chamber")
|
||||
esasYil: str = Field("", description="Case year")
|
||||
esasIlkSiraNo: str = Field("", description="Start case no")
|
||||
esasSonSiraNo: str = Field("", description="End case no")
|
||||
kararYil: str = Field("", description="Decision year")
|
||||
kararIlkSiraNo: str = Field("", description="Start decision no")
|
||||
kararSonSiraNo: str = Field("", description="End decision no")
|
||||
baslangicTarihi: str = Field("", description="Start date")
|
||||
bitisTarihi: str = Field("", description="End date")
|
||||
mevzuatNumarasi: str = Field("", description="Law number")
|
||||
mevzuatAdi: str = Field("", description="Law name")
|
||||
madde: str = Field("", description="Article")
|
||||
# Add a general keyword field if detailed search also supports it
|
||||
# arananKelime: Optional[str] = Field(None, description="General keyword for detailed search.")
|
||||
|
||||
@@ -76,11 +74,11 @@ class DanistayApiDecisionEntry(BaseModel):
|
||||
id: str
|
||||
# The API response for keyword search uses "daireKurul", detailed search example uses "daire".
|
||||
# We use an alias to handle both and map to a consistent field name "chamber".
|
||||
chamber: Optional[str] = Field(None, alias="daire", description="Chamber")
|
||||
esasNo: Optional[str] = Field(None)
|
||||
kararNo: Optional[str] = Field(None)
|
||||
kararTarihi: Optional[str] = Field(None)
|
||||
arananKelime: Optional[str] = Field(None, description="Keyword")
|
||||
chamber: str = Field("", alias="daire", description="Chamber")
|
||||
esasNo: str = Field("", description="Case number")
|
||||
kararNo: str = Field("", description="Decision number")
|
||||
kararTarihi: str = Field("", description="Decision date")
|
||||
arananKelime: str = Field("", description="Keyword")
|
||||
# index: Optional[int] = None # Present in response, can be added if needed by MCP tool
|
||||
# siraNo: Optional[int] = None # Present in detailed response, can be added
|
||||
|
||||
@@ -93,7 +91,7 @@ class DanistayApiResponseInnerData(BaseModel):
|
||||
data: List[DanistayApiDecisionEntry]
|
||||
recordsTotal: int
|
||||
recordsFiltered: int
|
||||
draw: Optional[int] = Field(None, description="Draw counter")
|
||||
draw: int = Field(0, description="Draw counter")
|
||||
|
||||
class DanistayApiResponse(BaseModel):
|
||||
"""Model for the complete search response from the Danistay API."""
|
||||
@@ -103,7 +101,7 @@ class DanistayApiResponse(BaseModel):
|
||||
class DanistayDocumentMarkdown(BaseModel):
|
||||
"""Model for a Danistay decision document, containing only Markdown content."""
|
||||
id: str
|
||||
markdown_content: Optional[str] = Field(None, description="The decision content (Karar İçeriği) converted to Markdown.")
|
||||
markdown_content: str = Field("", description="The decision content (Karar İçeriği) converted to Markdown.")
|
||||
source_url: HttpUrl
|
||||
|
||||
class CompactDanistaySearchResult(BaseModel):
|
||||
|
||||
+22
-22
@@ -12,8 +12,8 @@ class EmsalDetailedSearchRequestData(BaseModel):
|
||||
"""
|
||||
arananKelime: Optional[str] = ""
|
||||
|
||||
Bam_Hukuk_Mahkemeleri: Optional[str] = Field(None, alias="Bam Hukuk Mahkemeleri")
|
||||
Hukuk_Mahkemeleri: Optional[str] = Field(None, alias="Hukuk Mahkemeleri")
|
||||
Bam_Hukuk_Mahkemeleri: str = Field("", alias="Bam Hukuk Mahkemeleri")
|
||||
Hukuk_Mahkemeleri: str = Field("", alias="Hukuk Mahkemeleri")
|
||||
# Add other specific court type fields from the form if they are separate keys in payload
|
||||
# E.g., "Ceza Mahkemeleri", "İdari Mahkemeler" etc.
|
||||
|
||||
@@ -36,22 +36,22 @@ class EmsalDetailedSearchRequestData(BaseModel):
|
||||
|
||||
class EmsalSearchRequest(BaseModel): # This is the model the MCP tool will accept
|
||||
"""Model for Emsal detailed search request, with user-friendly field names."""
|
||||
keyword: Optional[str] = Field(None, description="Keyword")
|
||||
keyword: str = Field("", description="Keyword")
|
||||
|
||||
selected_bam_civil_court: Optional[str] = Field(None, description="BAM Civil Court")
|
||||
selected_civil_court: Optional[str] = Field(None, description="Civil Court")
|
||||
selected_regional_civil_chambers: Optional[List[str]] = Field(default_factory=list, description="Regional chambers")
|
||||
selected_bam_civil_court: str = Field("", description="BAM Civil Court")
|
||||
selected_civil_court: str = Field("", description="Civil Court")
|
||||
selected_regional_civil_chambers: List[str] = Field(default_factory=list, description="Regional chambers")
|
||||
|
||||
case_year_esas: Optional[str] = Field(None, description="Case year")
|
||||
case_start_seq_esas: Optional[str] = Field(None, description="Start case no")
|
||||
case_end_seq_esas: Optional[str] = Field(None, description="End case no")
|
||||
case_year_esas: str = Field("", description="Case year")
|
||||
case_start_seq_esas: str = Field("", description="Start case no")
|
||||
case_end_seq_esas: str = Field("", description="End case no")
|
||||
|
||||
decision_year_karar: Optional[str] = Field(None, description="Decision year")
|
||||
decision_start_seq_karar: Optional[str] = Field(None, description="Start decision no")
|
||||
decision_end_seq_karar: Optional[str] = Field(None, description="End decision no")
|
||||
decision_year_karar: str = Field("", description="Decision year")
|
||||
decision_start_seq_karar: str = Field("", description="Start decision no")
|
||||
decision_end_seq_karar: str = Field("", description="End decision no")
|
||||
|
||||
start_date: Optional[str] = Field(None, description="Start date (DD.MM.YYYY)")
|
||||
end_date: Optional[str] = Field(None, description="End date (DD.MM.YYYY)")
|
||||
start_date: str = Field("", description="Start date (DD.MM.YYYY)")
|
||||
end_date: str = Field("", description="End date (DD.MM.YYYY)")
|
||||
|
||||
sort_criteria: str = Field("1", description="Sort by")
|
||||
sort_direction: str = Field("desc", description="Direction")
|
||||
@@ -63,12 +63,12 @@ class EmsalSearchRequest(BaseModel): # This is the model the MCP tool will accep
|
||||
class EmsalApiDecisionEntry(BaseModel):
|
||||
"""Model for an individual decision entry from the Emsal API search response."""
|
||||
id: str
|
||||
daire: Optional[str] = Field(None, description="Chamber")
|
||||
esasNo: Optional[str] = Field(None)
|
||||
kararNo: Optional[str] = Field(None)
|
||||
kararTarihi: Optional[str] = Field(None)
|
||||
arananKelime: Optional[str] = Field(None, description="Keyword")
|
||||
durum: Optional[str] = Field(None, description="Status")
|
||||
daire: str = Field("", description="Chamber")
|
||||
esasNo: str = Field("", description="Case number")
|
||||
kararNo: str = Field("", description="Decision number")
|
||||
kararTarihi: str = Field("", description="Decision date")
|
||||
arananKelime: str = Field("", description="Keyword")
|
||||
durum: str = Field("", description="Status")
|
||||
# index: Optional[int] = None # Present in Emsal response, can be added if tool needs it
|
||||
|
||||
document_url: Optional[HttpUrl] = Field(None, description="Document URL")
|
||||
@@ -80,7 +80,7 @@ class EmsalApiResponseInnerData(BaseModel):
|
||||
data: List[EmsalApiDecisionEntry]
|
||||
recordsTotal: int
|
||||
recordsFiltered: int
|
||||
draw: Optional[int] = Field(None, description="Draw counter (Çizim Sayıcısı) from API, usually for DataTables.")
|
||||
draw: int = Field(0, description="Draw counter (Çizim Sayıcısı) from API, usually for DataTables.")
|
||||
|
||||
class EmsalApiResponse(BaseModel):
|
||||
"""Model for the complete search response from the Emsal API."""
|
||||
@@ -90,7 +90,7 @@ class EmsalApiResponse(BaseModel):
|
||||
class EmsalDocumentMarkdown(BaseModel):
|
||||
"""Model for an Emsal decision document, containing only Markdown content."""
|
||||
id: str
|
||||
markdown_content: Optional[str] = Field(None, description="The decision content (Karar İçeriği) converted to Markdown.")
|
||||
markdown_content: str = Field("", description="The decision content (Karar İçeriği) converted to Markdown.")
|
||||
source_url: HttpUrl
|
||||
|
||||
class CompactEmsalSearchResult(BaseModel):
|
||||
|
||||
+13
-13
@@ -13,16 +13,16 @@ class KikKararTipi(str, Enum):
|
||||
class KikSearchRequest(BaseModel):
|
||||
"""Model for KIK Decision search criteria."""
|
||||
karar_tipi: KikKararTipi = Field(KikKararTipi.UYUSMAZLIK, description="Type")
|
||||
karar_no: Optional[str] = Field(None, description="No")
|
||||
karar_tarihi_baslangic: Optional[str] = Field(None, description="Start", pattern=r"^\d{2}\.\d{2}\.\d{4}$")
|
||||
karar_tarihi_bitis: Optional[str] = Field(None, description="End", pattern=r"^\d{2}\.\d{2}\.\d{4}$")
|
||||
resmi_gazete_sayisi: Optional[str] = Field(None, description="Gazette")
|
||||
resmi_gazete_tarihi: Optional[str] = Field(None, description="Date", pattern=r"^\d{2}\.\d{2}\.\d{4}$")
|
||||
basvuru_konusu_ihale: Optional[str] = Field(None, description="Subject")
|
||||
basvuru_sahibi: Optional[str] = Field(None, description="Applicant")
|
||||
ihaleyi_yapan_idare: Optional[str] = Field(None, description="Entity")
|
||||
yil: Optional[str] = Field(None, description="Year")
|
||||
karar_metni: Optional[str] = Field(None, description="Text")
|
||||
karar_no: str = Field("", description="No")
|
||||
karar_tarihi_baslangic: str = Field("", description="Start", pattern=r"^\d{2}\.\d{2}\.\d{4}$|^$")
|
||||
karar_tarihi_bitis: str = Field("", description="End", pattern=r"^\d{2}\.\d{2}\.\d{4}$|^$")
|
||||
resmi_gazete_sayisi: str = Field("", description="Gazette")
|
||||
resmi_gazete_tarihi: str = Field("", description="Date", pattern=r"^\d{2}\.\d{2}\.\d{4}$|^$")
|
||||
basvuru_konusu_ihale: str = Field("", description="Subject")
|
||||
basvuru_sahibi: str = Field("", description="Applicant")
|
||||
ihaleyi_yapan_idare: str = Field("", description="Entity")
|
||||
yil: str = Field("", description="Year")
|
||||
karar_metni: str = Field("", description="Text")
|
||||
page: int = Field(1, ge=1, description="Page")
|
||||
|
||||
class KikDecisionEntry(BaseModel):
|
||||
@@ -32,9 +32,9 @@ class KikDecisionEntry(BaseModel):
|
||||
karar_tipi: KikKararTipi = Field(..., description="Decision type")
|
||||
|
||||
karar_tarihi_str: str = Field(..., alias="kararTarihi", description="Date")
|
||||
idare_str: Optional[str] = Field(None, alias="idare", description="Entity")
|
||||
basvuru_sahibi_str: Optional[str] = Field(None, alias="basvuruSahibi", description="Applicant")
|
||||
ihale_konusu_str: Optional[str] = Field(None, alias="ihaleKonusu", description="Subject")
|
||||
idare_str: str = Field("", alias="idare", description="Entity")
|
||||
basvuru_sahibi_str: str = Field("", alias="basvuruSahibi", description="Applicant")
|
||||
ihale_konusu_str: str = Field("", alias="ihaleKonusu", description="Subject")
|
||||
|
||||
@computed_field
|
||||
@property
|
||||
|
||||
+326
-129
@@ -4,9 +4,14 @@ import atexit
|
||||
import logging
|
||||
import os
|
||||
import httpx
|
||||
import json
|
||||
import time
|
||||
from collections import defaultdict
|
||||
from pydantic import HttpUrl, Field
|
||||
from typing import Optional, Dict, List, Literal, Any, Union
|
||||
import urllib.parse
|
||||
import tiktoken
|
||||
from fastmcp.server.middleware import Middleware, MiddlewareContext
|
||||
|
||||
# --- Logging Configuration Start ---
|
||||
LOG_DIRECTORY = os.path.join(os.path.dirname(os.path.abspath(__file__)), "logs")
|
||||
@@ -32,6 +37,197 @@ root_logger.addHandler(console_handler)
|
||||
logger = logging.getLogger(__name__)
|
||||
# --- Logging Configuration End ---
|
||||
|
||||
# --- Token Counting Middleware ---
|
||||
class TokenCountingMiddleware(Middleware):
|
||||
"""Middleware for counting input/output tokens using tiktoken."""
|
||||
|
||||
def __init__(self, model: str = "cl100k_base"):
|
||||
"""Initialize token counting middleware.
|
||||
|
||||
Args:
|
||||
model: Tiktoken model name (cl100k_base for GPT-4/Claude compatibility)
|
||||
"""
|
||||
self.encoder = tiktoken.get_encoding(model)
|
||||
self.model = model
|
||||
self.token_stats = defaultdict(lambda: {"input": 0, "output": 0, "calls": 0})
|
||||
self.logger = logging.getLogger("token_counter")
|
||||
|
||||
# Create separate log file for token metrics
|
||||
token_log_path = os.path.join(LOG_DIRECTORY, "token_metrics.log")
|
||||
token_handler = logging.FileHandler(token_log_path, mode='a', encoding='utf-8')
|
||||
token_formatter = logging.Formatter('%(asctime)s - %(message)s')
|
||||
token_handler.setFormatter(token_formatter)
|
||||
token_handler.setLevel(logging.INFO)
|
||||
self.logger.addHandler(token_handler)
|
||||
self.logger.setLevel(logging.INFO)
|
||||
|
||||
def count_tokens(self, text: str) -> int:
|
||||
"""Count tokens in text using tiktoken."""
|
||||
if not text:
|
||||
return 0
|
||||
try:
|
||||
return len(self.encoder.encode(str(text)))
|
||||
except Exception as e:
|
||||
logger.warning(f"Token counting failed: {e}")
|
||||
return 0
|
||||
|
||||
def extract_text_content(self, data: Any) -> str:
|
||||
"""Extract text content from various data types."""
|
||||
if isinstance(data, str):
|
||||
return data
|
||||
elif isinstance(data, dict):
|
||||
# Extract text from common response fields
|
||||
text_parts = []
|
||||
for key, value in data.items():
|
||||
if isinstance(value, str):
|
||||
text_parts.append(value)
|
||||
elif isinstance(value, list):
|
||||
for item in value:
|
||||
if isinstance(item, str):
|
||||
text_parts.append(item)
|
||||
elif isinstance(item, dict) and 'text' in item:
|
||||
text_parts.append(str(item['text']))
|
||||
return ' '.join(text_parts)
|
||||
elif isinstance(data, list):
|
||||
text_parts = []
|
||||
for item in data:
|
||||
text_parts.append(self.extract_text_content(item))
|
||||
return ' '.join(text_parts)
|
||||
else:
|
||||
return str(data)
|
||||
|
||||
def log_token_usage(self, operation: str, input_tokens: int, output_tokens: int,
|
||||
tool_name: str = None, duration_ms: float = None):
|
||||
"""Log token usage with structured format."""
|
||||
log_data = {
|
||||
"operation": operation,
|
||||
"tool_name": tool_name,
|
||||
"input_tokens": input_tokens,
|
||||
"output_tokens": output_tokens,
|
||||
"total_tokens": input_tokens + output_tokens,
|
||||
"duration_ms": duration_ms,
|
||||
"timestamp": time.time()
|
||||
}
|
||||
|
||||
# Update statistics
|
||||
key = tool_name if tool_name else operation
|
||||
self.token_stats[key]["input"] += input_tokens
|
||||
self.token_stats[key]["output"] += output_tokens
|
||||
self.token_stats[key]["calls"] += 1
|
||||
|
||||
# Log as JSON for easy parsing
|
||||
self.logger.info(json.dumps(log_data))
|
||||
|
||||
# Also log human-readable format to main logger
|
||||
logger.info(f"Token Usage - {operation}" +
|
||||
(f" ({tool_name})" if tool_name else "") +
|
||||
f": {input_tokens} in + {output_tokens} out = {input_tokens + output_tokens} total")
|
||||
|
||||
async def on_call_tool(self, context: MiddlewareContext, call_next):
|
||||
"""Count tokens for tool calls."""
|
||||
start_time = time.perf_counter()
|
||||
|
||||
# Extract tool name and arguments
|
||||
tool_name = getattr(context.message, 'name', 'unknown_tool')
|
||||
tool_args = getattr(context.message, 'arguments', {})
|
||||
|
||||
# Count input tokens (tool arguments)
|
||||
input_text = self.extract_text_content(tool_args)
|
||||
input_tokens = self.count_tokens(input_text)
|
||||
|
||||
try:
|
||||
# Execute the tool
|
||||
result = await call_next(context)
|
||||
|
||||
# Count output tokens (tool result)
|
||||
output_text = self.extract_text_content(result)
|
||||
output_tokens = self.count_tokens(output_text)
|
||||
|
||||
# Calculate duration
|
||||
duration_ms = (time.perf_counter() - start_time) * 1000
|
||||
|
||||
# Log token usage
|
||||
self.log_token_usage("tool_call", input_tokens, output_tokens,
|
||||
tool_name, duration_ms)
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
duration_ms = (time.perf_counter() - start_time) * 1000
|
||||
self.log_token_usage("tool_call_error", input_tokens, 0,
|
||||
tool_name, duration_ms)
|
||||
raise
|
||||
|
||||
async def on_read_resource(self, context: MiddlewareContext, call_next):
|
||||
"""Count tokens for resource reads."""
|
||||
start_time = time.perf_counter()
|
||||
|
||||
# Extract resource URI
|
||||
resource_uri = getattr(context.message, 'uri', 'unknown_resource')
|
||||
|
||||
try:
|
||||
# Execute the resource read
|
||||
result = await call_next(context)
|
||||
|
||||
# Count output tokens (resource content)
|
||||
output_text = self.extract_text_content(result)
|
||||
output_tokens = self.count_tokens(output_text)
|
||||
|
||||
# Calculate duration
|
||||
duration_ms = (time.perf_counter() - start_time) * 1000
|
||||
|
||||
# Log token usage (no input tokens for resource reads)
|
||||
self.log_token_usage("resource_read", 0, output_tokens,
|
||||
resource_uri, duration_ms)
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
duration_ms = (time.perf_counter() - start_time) * 1000
|
||||
self.log_token_usage("resource_read_error", 0, 0,
|
||||
resource_uri, duration_ms)
|
||||
raise
|
||||
|
||||
async def on_get_prompt(self, context: MiddlewareContext, call_next):
|
||||
"""Count tokens for prompt retrievals."""
|
||||
start_time = time.perf_counter()
|
||||
|
||||
# Extract prompt name
|
||||
prompt_name = getattr(context.message, 'name', 'unknown_prompt')
|
||||
|
||||
try:
|
||||
# Execute the prompt retrieval
|
||||
result = await call_next(context)
|
||||
|
||||
# Count output tokens (prompt content)
|
||||
output_text = self.extract_text_content(result)
|
||||
output_tokens = self.count_tokens(output_text)
|
||||
|
||||
# Calculate duration
|
||||
duration_ms = (time.perf_counter() - start_time) * 1000
|
||||
|
||||
# Log token usage
|
||||
self.log_token_usage("prompt_get", 0, output_tokens,
|
||||
prompt_name, duration_ms)
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
duration_ms = (time.perf_counter() - start_time) * 1000
|
||||
self.log_token_usage("prompt_get_error", 0, 0,
|
||||
prompt_name, duration_ms)
|
||||
raise
|
||||
|
||||
def get_token_stats(self) -> Dict[str, Any]:
|
||||
"""Get current token usage statistics."""
|
||||
return dict(self.token_stats)
|
||||
|
||||
def reset_token_stats(self):
|
||||
"""Reset token usage statistics."""
|
||||
self.token_stats.clear()
|
||||
|
||||
# --- End Token Counting Middleware ---
|
||||
|
||||
# Create FastMCP app directly without authentication wrapper
|
||||
from fastmcp import FastMCP
|
||||
|
||||
@@ -113,6 +309,11 @@ from kvkk_mcp_module.models import (
|
||||
|
||||
app = create_app()
|
||||
|
||||
# --- Add Token Counting Middleware ---
|
||||
token_counter = TokenCountingMiddleware()
|
||||
app.add_middleware(token_counter)
|
||||
logger.info("Token counting middleware added to MCP server")
|
||||
|
||||
# --- Tool Documentation Resources ---
|
||||
@app.resource("docs://tools/yargitay")
|
||||
async def get_yargitay_tools_documentation() -> str:
|
||||
@@ -863,7 +1064,7 @@ KARAR_TURU_ADI_TO_GUID_ENUM_MAP = {
|
||||
|
||||
# --- MCP Tools for Yargitay ---
|
||||
@app.tool(
|
||||
description="Search Yargıtay decisions using primary API with 52 chamber filtering and advanced operators. Before using, read docs://tools/yargitay",
|
||||
description="Search Yargıtay decisions with 52 chamber filtering and advanced operators",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -871,10 +1072,8 @@ KARAR_TURU_ADI_TO_GUID_ENUM_MAP = {
|
||||
}
|
||||
)
|
||||
async def search_yargitay_detailed(
|
||||
arananKelime: str = Field("", description="Search keyword with OR/AND/wildcard operators"),
|
||||
arananKelime: str = Field("", description="Turkish search keyword. Supports +required -excluded \"exact phrase\" operators"),
|
||||
birimYrgKurulDaire: str = Field("ALL", description="Chamber selection (52 options: Civil/Criminal chambers, General Assemblies)"),
|
||||
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'."),
|
||||
esasIlkSiraNo: str = Field("", description="Starting sequence number for 'Esas No'."),
|
||||
esasSonSiraNo: str = Field("", description="Ending sequence number for 'Esas No'."),
|
||||
@@ -883,8 +1082,6 @@ async def search_yargitay_detailed(
|
||||
kararSonSiraNo: str = Field("", description="Ending sequence number for 'Karar No'."),
|
||||
baslangicTarihi: str = Field("", description="Start date for decision search (DD.MM.YYYY)."),
|
||||
bitisTarihi: str = Field("", description="End date for decision search (DD.MM.YYYY)."),
|
||||
siralama: str = Field("3", description="Sorting criteria (1: Esas No, 2: Karar No, 3: Karar Tarihi)."),
|
||||
siralamaDirection: str = Field("desc", description="Sorting direction ('asc' or 'desc')."),
|
||||
pageSize: int = Field(10, ge=1, le=10, description="Number of results per page."),
|
||||
pageNumber: int = Field(1, ge=1, description="Page number to retrieve.")
|
||||
) -> CompactYargitaySearchResult:
|
||||
@@ -897,8 +1094,6 @@ async def search_yargitay_detailed(
|
||||
search_query = YargitayDetailedSearchRequest(
|
||||
arananKelime=arananKelime,
|
||||
birimYrgKurulDaire=birimYrgKurulDaire,
|
||||
birimYrgHukukDaire=birimYrgHukukDaire,
|
||||
birimYrgCezaDaire=birimYrgCezaDaire,
|
||||
esasYil=esasYil,
|
||||
esasIlkSiraNo=esasIlkSiraNo,
|
||||
esasSonSiraNo=esasSonSiraNo,
|
||||
@@ -907,8 +1102,8 @@ async def search_yargitay_detailed(
|
||||
kararSonSiraNo=kararSonSiraNo,
|
||||
baslangicTarihi=baslangicTarihi,
|
||||
bitisTarihi=bitisTarihi,
|
||||
siralama=siralama,
|
||||
siralamaDirection=siralamaDirection,
|
||||
siralama="3",
|
||||
siralamaDirection="desc",
|
||||
pageSize=pageSize,
|
||||
pageNumber=pageNumber
|
||||
)
|
||||
@@ -941,7 +1136,7 @@ async def search_yargitay_detailed(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve full text of a Yargıtay decision in Markdown format. Before using, read docs://tools/yargitay",
|
||||
description="Get Yargıtay decision text in Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"idempotentHint": True
|
||||
@@ -959,7 +1154,7 @@ async def get_yargitay_document_markdown(id: str) -> YargitayDocumentMarkdown:
|
||||
|
||||
# --- MCP Tools for Danistay ---
|
||||
@app.tool(
|
||||
description="Search Danıştay decisions using keyword logic with AND/OR/NOT operators. Before using, read docs://tools/danistay",
|
||||
description="Search Danıştay decisions with keyword logic (AND/OR/NOT operators)",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1001,7 +1196,7 @@ async def search_danistay_by_keyword(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Search Danıştay decisions with detailed criteria including chamber selection and case numbers. Before using, read docs://tools/danistay",
|
||||
description="Search Danıştay decisions with detailed criteria (chamber selection, case numbers)",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1009,20 +1204,18 @@ async def search_danistay_by_keyword(
|
||||
}
|
||||
)
|
||||
async def search_danistay_detailed(
|
||||
daire: Optional[str] = Field(None, description="Chamber/Department name (e.g., '1. Daire')."),
|
||||
esasYil: Optional[str] = Field(None, description="Case year for 'Esas No'."),
|
||||
esasIlkSiraNo: Optional[str] = Field(None, description="Starting sequence for 'Esas No'."),
|
||||
esasSonSiraNo: Optional[str] = Field(None, description="Ending sequence for 'Esas No'."),
|
||||
kararYil: Optional[str] = Field(None, description="Decision year for 'Karar No'."),
|
||||
kararIlkSiraNo: Optional[str] = Field(None, description="Starting sequence for 'Karar No'."),
|
||||
kararSonSiraNo: Optional[str] = Field(None, description="Ending sequence for 'Karar No'."),
|
||||
baslangicTarihi: Optional[str] = Field(None, description="Start date for decision (DD.MM.YYYY)."),
|
||||
bitisTarihi: Optional[str] = Field(None, description="End date for decision (DD.MM.YYYY)."),
|
||||
mevzuatNumarasi: Optional[str] = Field(None, description="Legislation number."),
|
||||
mevzuatAdi: Optional[str] = Field(None, description="Legislation name."),
|
||||
madde: Optional[str] = Field(None, description="Article number."),
|
||||
siralama: str = Field("1", description="Sorting criteria (e.g., 1: Esas No, 3: Karar Tarihi)."),
|
||||
siralamaDirection: str = Field("desc", description="Sorting direction ('asc' or 'desc')."),
|
||||
daire: str = Field("", description="Chamber/Department name (e.g., '1. Daire')."),
|
||||
esasYil: str = Field("", description="Case year for 'Esas No'."),
|
||||
esasIlkSiraNo: str = Field("", description="Starting sequence for 'Esas No'."),
|
||||
esasSonSiraNo: str = Field("", description="Ending sequence for 'Esas No'."),
|
||||
kararYil: str = Field("", description="Decision year for 'Karar No'."),
|
||||
kararIlkSiraNo: str = Field("", description="Starting sequence for 'Karar No'."),
|
||||
kararSonSiraNo: str = Field("", description="Ending sequence for 'Karar No'."),
|
||||
baslangicTarihi: str = Field("", description="Start date for decision (DD.MM.YYYY)."),
|
||||
bitisTarihi: str = Field("", description="End date for decision (DD.MM.YYYY)."),
|
||||
mevzuatNumarasi: str = Field("", description="Legislation number."),
|
||||
mevzuatAdi: str = Field("", description="Legislation name."),
|
||||
madde: str = Field("", description="Article number."),
|
||||
pageNumber: int = Field(1, ge=1, description="Page number."),
|
||||
pageSize: int = Field(10, ge=1, le=10, description="Results per page.")
|
||||
) -> CompactDanistaySearchResult:
|
||||
@@ -1041,8 +1234,8 @@ async def search_danistay_detailed(
|
||||
mevzuatNumarasi=mevzuatNumarasi,
|
||||
mevzuatAdi=mevzuatAdi,
|
||||
madde=madde,
|
||||
siralama=siralama,
|
||||
siralamaDirection=siralamaDirection,
|
||||
siralama="3",
|
||||
siralamaDirection="desc",
|
||||
pageNumber=pageNumber,
|
||||
pageSize=pageSize
|
||||
)
|
||||
@@ -1063,7 +1256,7 @@ async def search_danistay_detailed(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve full text of a Danıştay decision in Markdown format. Before using, read docs://tools/danistay",
|
||||
description="Get Danıştay decision text in Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"idempotentHint": True
|
||||
@@ -1081,7 +1274,7 @@ async def get_danistay_document_markdown(id: str) -> DanistayDocumentMarkdown:
|
||||
|
||||
# --- MCP Tools for Emsal ---
|
||||
@app.tool(
|
||||
description="Search Emsal precedent decisions with detailed criteria across Turkish courts. Before using, read docs://tools/emsal",
|
||||
description="Search Emsal precedent decisions with detailed criteria",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1089,18 +1282,18 @@ async def get_danistay_document_markdown(id: str) -> DanistayDocumentMarkdown:
|
||||
}
|
||||
)
|
||||
async def search_emsal_detailed_decisions(
|
||||
keyword: Optional[str] = Field(None, description="Keyword to search."),
|
||||
selected_bam_civil_court: Optional[str] = Field(None, description="Selected BAM Civil Court."),
|
||||
selected_civil_court: Optional[str] = Field(None, description="Selected Civil Court."),
|
||||
keyword: str = Field("", description="Keyword to search."),
|
||||
selected_bam_civil_court: str = Field("", description="Selected BAM Civil Court."),
|
||||
selected_civil_court: str = Field("", description="Selected Civil Court."),
|
||||
selected_regional_civil_chambers: List[str] = Field(default_factory=list, description="Selected Regional Civil Chambers."),
|
||||
case_year_esas: Optional[str] = Field(None, description="Case year for 'Esas No'."),
|
||||
case_start_seq_esas: Optional[str] = Field(None, description="Starting sequence for 'Esas No'."),
|
||||
case_end_seq_esas: Optional[str] = Field(None, description="Ending sequence for 'Esas No'."),
|
||||
decision_year_karar: Optional[str] = Field(None, description="Decision year for 'Karar No'."),
|
||||
decision_start_seq_karar: Optional[str] = Field(None, description="Starting sequence for 'Karar No'."),
|
||||
decision_end_seq_karar: Optional[str] = Field(None, description="Ending sequence for 'Karar No'."),
|
||||
start_date: Optional[str] = Field(None, description="Start date for decision (DD.MM.YYYY)."),
|
||||
end_date: Optional[str] = Field(None, description="End date for decision (DD.MM.YYYY)."),
|
||||
case_year_esas: str = Field("", description="Case year for 'Esas No'."),
|
||||
case_start_seq_esas: str = Field("", description="Starting sequence for 'Esas No'."),
|
||||
case_end_seq_esas: str = Field("", description="Ending sequence for 'Esas No'."),
|
||||
decision_year_karar: str = Field("", description="Decision year for 'Karar No'."),
|
||||
decision_start_seq_karar: str = Field("", description="Starting sequence for 'Karar No'."),
|
||||
decision_end_seq_karar: str = Field("", description="Ending sequence for 'Karar No'."),
|
||||
start_date: str = Field("", description="Start date for decision (DD.MM.YYYY)."),
|
||||
end_date: str = Field("", description="End date for decision (DD.MM.YYYY)."),
|
||||
sort_criteria: str = Field("1", description="Sorting criteria (e.g., 1: Esas No)."),
|
||||
sort_direction: str = Field("desc", description="Sorting direction ('asc' or 'desc')."),
|
||||
page_number: int = Field(1, ge=1, description="Page number (accepts int)."),
|
||||
@@ -1144,7 +1337,7 @@ async def search_emsal_detailed_decisions(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve full text of an Emsal precedent decision in Markdown format. Before using, read docs://tools/emsal",
|
||||
description="Get Emsal precedent decision text in Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"idempotentHint": True
|
||||
@@ -1162,7 +1355,7 @@ async def get_emsal_document_markdown(id: str) -> EmsalDocumentMarkdown:
|
||||
|
||||
# --- MCP Tools for Uyusmazlik ---
|
||||
@app.tool(
|
||||
description="Search Uyuşmazlık Mahkemesi decisions for jurisdictional disputes between court systems. Before using, read docs://tools/uyusmazlik",
|
||||
description="Search Uyuşmazlık Mahkemesi decisions for jurisdictional disputes",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1233,7 +1426,7 @@ async def search_uyusmazlik_decisions(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve full text of an Uyuşmazlık Mahkemesi decision from URL in Markdown format. Before using, read docs://tools/uyusmazlik",
|
||||
description="Get Uyuşmazlık Mahkemesi decision text from URL in Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"idempotentHint": True
|
||||
@@ -1254,7 +1447,7 @@ async def get_uyusmazlik_document_markdown_from_url(
|
||||
|
||||
# --- MCP Tools for Anayasa Mahkemesi (Norm Denetimi) ---
|
||||
@app.tool(
|
||||
description="Search Constitutional Court norm control decisions with comprehensive filtering and legal criteria. Before using, read docs://tools/constitutional_court",
|
||||
description="Search Constitutional Court norm control decisions with comprehensive filtering",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1262,34 +1455,34 @@ async def get_uyusmazlik_document_markdown_from_url(
|
||||
}
|
||||
)
|
||||
async def search_anayasa_norm_denetimi_decisions(
|
||||
keywords_all: List[str] = Field(default_factory=list, description="AND keywords"),
|
||||
keywords_any: List[str] = Field(default_factory=list, description="OR keywords"),
|
||||
keywords_exclude: List[str] = Field(default_factory=list, description="Exclude keywords"),
|
||||
keywords_all: List[str] = Field(default_factory=list, description="AND"),
|
||||
keywords_any: List[str] = Field(default_factory=list, description="OR"),
|
||||
keywords_exclude: List[str] = Field(default_factory=list, description="NOT"),
|
||||
period: Literal["ALL", "1", "2"] = Field("ALL", description="Period"),
|
||||
case_number_esas: Optional[str] = Field(None, description="Case number"),
|
||||
decision_number_karar: Optional[str] = Field(None, description="Decision number"),
|
||||
first_review_date_start: Optional[str] = Field(None, description="Review start date"),
|
||||
first_review_date_end: Optional[str] = Field(None, description="Review end date"),
|
||||
decision_date_start: Optional[str] = Field(None, description="Decision start"),
|
||||
decision_date_end: Optional[str] = Field(None, description="Decision end"),
|
||||
case_number_esas: str = Field("", description="Case number"),
|
||||
decision_number_karar: str = Field("", description="Decision number"),
|
||||
first_review_date_start: str = Field("", description="Start"),
|
||||
first_review_date_end: str = Field("", description="End"),
|
||||
decision_date_start: str = Field("", description="Start"),
|
||||
decision_date_end: str = Field("", description="End"),
|
||||
application_type: Literal["ALL", "1", "2", "3"] = Field("ALL", description="App type"),
|
||||
applicant_general_name: Optional[str] = Field(None, description="Applicant"),
|
||||
applicant_specific_name: Optional[str] = Field(None, description="Specific name"),
|
||||
official_gazette_date_start: Optional[str] = Field(None, description="Gazette start"),
|
||||
official_gazette_date_end: Optional[str] = Field(None, description="Gazette end"),
|
||||
official_gazette_number_start: Optional[str] = Field(None, description="Gazette no start"),
|
||||
official_gazette_number_end: Optional[str] = Field(None, description="Gazette no end"),
|
||||
has_press_release: Literal["ALL", "0", "1"] = Field("ALL", description="Press release"),
|
||||
applicant_general_name: str = Field("", description="Applicant"),
|
||||
applicant_specific_name: str = Field("", description="Name"),
|
||||
official_gazette_date_start: str = Field("", description="Start"),
|
||||
official_gazette_date_end: str = Field("", description="End"),
|
||||
official_gazette_number_start: str = Field("", description="Start"),
|
||||
official_gazette_number_end: str = Field("", description="End"),
|
||||
has_press_release: Literal["ALL", "0", "1"] = Field("ALL", description="Press"),
|
||||
has_dissenting_opinion: Literal["ALL", "0", "1"] = Field("ALL", description="Dissenting"),
|
||||
has_different_reasoning: Literal["ALL", "0", "1"] = Field("ALL", description="Different reason"),
|
||||
has_different_reasoning: Literal["ALL", "0", "1"] = Field("ALL", description="Reason"),
|
||||
attending_members_names: List[str] = Field(default_factory=list, description="Members"),
|
||||
rapporteur_name: Optional[str] = Field(None, description="Rapporteur"),
|
||||
rapporteur_name: str = Field("", description="Rapporteur"),
|
||||
norm_type: Literal["ALL", "1", "2", "14", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "0", "13"] = Field("ALL", description="Norm type"),
|
||||
norm_id_or_name: Optional[str] = Field(None, description="Norm name"),
|
||||
norm_article: Optional[str] = Field(None, description="Article"),
|
||||
norm_id_or_name: str = Field("", description="Norm name"),
|
||||
norm_article: str = Field("", description="Article"),
|
||||
review_outcomes: List[Literal["ALL", "1", "2", "3", "4", "5", "6", "7", "8", "12"]] = Field(default_factory=list, description="Outcomes"),
|
||||
reason_for_final_outcome: Literal["ALL", "29", "1", "2", "30", "3", "4", "27", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26"] = Field("ALL", description="Reason"),
|
||||
basis_constitution_article_numbers: List[str] = Field(default_factory=list, description="Articles"),
|
||||
basis_constitution_article_numbers: List[str] = Field(default_factory=list, description="Arts"),
|
||||
results_per_page: int = Field(10, description="Count"),
|
||||
page_to_fetch: int = Field(1, ge=1, description="Page"),
|
||||
sort_by_criteria: str = Field("KararTarihi", description="Sort")
|
||||
@@ -1348,7 +1541,7 @@ async def search_anayasa_norm_denetimi_decisions(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve full text of a Constitutional Court norm control decision in paginated Markdown format. Before using, read docs://tools/constitutional_court",
|
||||
description="Get Constitutional Court norm control decision text in paginated Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"idempotentHint": True
|
||||
@@ -1371,7 +1564,7 @@ async def get_anayasa_norm_denetimi_document_markdown(
|
||||
|
||||
# --- MCP Tools for Anayasa Mahkemesi (Bireysel Başvuru Karar Raporu & Belgeler) ---
|
||||
@app.tool(
|
||||
description="Search Constitutional Court individual application decisions for human rights violation reports. Before using, read docs://tools/constitutional_court",
|
||||
description="Search Constitutional Court individual application decisions for human rights violations",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1397,7 +1590,7 @@ async def search_anayasa_bireysel_basvuru_report(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Parameter description",
|
||||
description="Get Constitutional Court individual application decision text in paginated Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"idempotentHint": True
|
||||
@@ -1427,7 +1620,7 @@ async def get_anayasa_bireysel_basvuru_document_markdown(
|
||||
|
||||
# --- MCP Tools for KIK (Kamu İhale Kurulu) ---
|
||||
@app.tool(
|
||||
description="Search Public Procurement Authority (KİK) decisions for procurement law and administrative disputes. Before using, read docs://tools/kik",
|
||||
description="Search Public Procurement Authority (KİK) decisions for procurement law disputes",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1436,21 +1629,23 @@ async def get_anayasa_bireysel_basvuru_document_markdown(
|
||||
)
|
||||
async def search_kik_decisions(
|
||||
karar_tipi: Literal["rbUyusmazlik", "rbDuzenleyici", "rbMahkeme"] = Field("rbUyusmazlik", description="Type of KIK Decision."),
|
||||
karar_no: Optional[str] = Field(None, description="Decision Number (e.g., '2024/UH.II-1766')."),
|
||||
karar_tarihi_baslangic: Optional[str] = Field(None, description="Decision Date Start (DD.MM.YYYY)."),
|
||||
karar_tarihi_bitis: Optional[str] = Field(None, description="Decision Date End (DD.MM.YYYY)."),
|
||||
basvuru_sahibi: Optional[str] = Field(None, description="Applicant."),
|
||||
ihaleyi_yapan_idare: Optional[str] = Field(None, description="Procuring Entity."),
|
||||
basvuru_konusu_ihale: Optional[str] = Field(None, description="Tender subject of the application."),
|
||||
karar_metni: Optional[str] = Field(None, description="""
|
||||
karar_no: str = Field("", description="Decision Number (e.g., '2024/UH.II-1766')."),
|
||||
karar_tarihi_baslangic: str = Field("", description="Decision Date Start (DD.MM.YYYY)."),
|
||||
karar_tarihi_bitis: str = Field("", description="Decision Date End (DD.MM.YYYY)."),
|
||||
basvuru_sahibi: str = Field("", description="Applicant."),
|
||||
ihaleyi_yapan_idare: str = Field("", description="Procuring Entity."),
|
||||
basvuru_konusu_ihale: str = Field("", description="Tender subject of the application."),
|
||||
karar_metni: str = Field("", description="""
|
||||
Keyword/phrase in decision text. Advanced search operators supported:
|
||||
- word1+word2 = AND logic (+anayasa +mahkeme -> both words required)
|
||||
- +"required" -"excluded" = Include and exclude (+ihale -"iptal")
|
||||
Examples: anayasa | +anayasa +mahkeme | +ihale -"iptal"
|
||||
- "exact phrase" = Exact match ("kamu yararı" for exact phrase)
|
||||
- OR/AND/wildcard operators supported
|
||||
Examples: anayasa | +anayasa +mahkeme | +ihale -"iptal" | "tam cümle"
|
||||
"""),
|
||||
yil: Optional[str] = Field(None, description="Year of the decision."),
|
||||
resmi_gazete_tarihi: Optional[str] = Field(None, description="Official Gazette Date (DD.MM.YYYY)."),
|
||||
resmi_gazete_sayisi: Optional[str] = Field(None, description="Official Gazette Number."),
|
||||
yil: str = Field("", description="Year of the decision."),
|
||||
resmi_gazete_tarihi: str = Field("", description="Official Gazette Date (DD.MM.YYYY)."),
|
||||
resmi_gazete_sayisi: str = Field("", description="Official Gazette Number."),
|
||||
page: int = Field(1, ge=1, description="Results page number.")
|
||||
) -> KikSearchResult:
|
||||
"""Search Public Procurement Authority (KIK) decisions."""
|
||||
@@ -1486,7 +1681,7 @@ async def search_kik_decisions(
|
||||
return KikSearchResult(decisions=[], total_records=0, current_page=current_page_val)
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve full text of a Public Procurement Authority (KİK) decision in paginated Markdown format. Before using, read docs://tools/kik",
|
||||
description="Get Public Procurement Authority (KİK) decision text in paginated Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"idempotentHint": True
|
||||
@@ -1526,7 +1721,7 @@ async def get_kik_document_markdown(
|
||||
is_paginated=False
|
||||
)
|
||||
@app.tool(
|
||||
description="Search Competition Authority (Rekabet Kurumu) decisions for competition law and antitrust research. Before using, read docs://tools/rekabet",
|
||||
description="Search Competition Authority (Rekabet Kurumu) decisions for competition law and antitrust",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1534,10 +1729,10 @@ async def get_kik_document_markdown(
|
||||
}
|
||||
)
|
||||
async def search_rekabet_kurumu_decisions(
|
||||
sayfaAdi: Optional[str] = Field(None, description="Search in decision title (Başlık)."),
|
||||
YayinlanmaTarihi: Optional[str] = Field(None, description="Publication date (Yayım Tarihi), e.g., DD.MM.YYYY."),
|
||||
PdfText: Optional[str] = Field(
|
||||
None,
|
||||
sayfaAdi: str = Field("", description="Search in decision title (Başlık)."),
|
||||
YayinlanmaTarihi: str = Field("", description="Publication date (Yayım Tarihi), e.g., DD.MM.YYYY."),
|
||||
PdfText: str = Field(
|
||||
"",
|
||||
description='Search in decision text. Use "\\"kesin cümle\\"" for precise matching.'
|
||||
),
|
||||
KararTuru: Literal[
|
||||
@@ -1548,8 +1743,8 @@ async def search_rekabet_kurumu_decisions(
|
||||
"Özelleştirme",
|
||||
"Rekabet İhlali"
|
||||
] = Field("ALL", description="Parameter description"),
|
||||
KararSayisi: Optional[str] = Field(None, description="Decision number (Karar Sayısı)."),
|
||||
KararTarihi: Optional[str] = Field(None, description="Decision date (Karar Tarihi), e.g., DD.MM.YYYY."),
|
||||
KararSayisi: str = Field("", description="Decision number (Karar Sayısı)."),
|
||||
KararTarihi: str = Field("", description="Decision date (Karar Tarihi), e.g., DD.MM.YYYY."),
|
||||
page: int = Field(1, ge=1, description="Page number to fetch for the results list.")
|
||||
) -> RekabetSearchResult:
|
||||
"""Search Competition Authority decisions."""
|
||||
@@ -1582,7 +1777,7 @@ async def search_rekabet_kurumu_decisions(
|
||||
return RekabetSearchResult(decisions=[], retrieved_page_number=page, total_records_found=0, total_pages=0)
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve full text of a Competition Authority decision in paginated Markdown format. Before using, read docs://tools/rekabet",
|
||||
description="Get Competition Authority decision text in paginated Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"idempotentHint": True
|
||||
@@ -1606,7 +1801,7 @@ async def get_rekabet_kurumu_document(
|
||||
|
||||
# --- MCP Tools for Bedesten (Unified Search Across All Courts) ---
|
||||
@app.tool(
|
||||
description="Search Yargıtay, Danıştay, Local Courts, Appeals Courts, and KYB decisions",
|
||||
description="Search multiple Turkish courts (Yargıtay, Danıştay, Local Courts, Appeals Courts, KYB)",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1614,7 +1809,7 @@ async def get_rekabet_kurumu_document(
|
||||
}
|
||||
)
|
||||
async def search_bedesten_unified(
|
||||
phrase: str = Field(..., description="Search phrase. Use \"exact phrase\" for precise matching"),
|
||||
phrase: str = Field(..., description="Turkish search phrase. Supports +required -excluded \"exact phrase\" operators"),
|
||||
court_types: List[BedestenCourtTypeEnum] = Field(
|
||||
default=["YARGITAYKARARI", "DANISTAYKARAR"],
|
||||
description="Court types: YARGITAYKARARI, DANISTAYKARAR, YERELHUKUK, ISTINAFHUKUK, KYB"
|
||||
@@ -1622,8 +1817,8 @@ async def search_bedesten_unified(
|
||||
pageSize: int = Field(10, ge=1, le=10, description="Results per page (1-10)"),
|
||||
pageNumber: int = Field(1, ge=1, description="Page number"),
|
||||
birimAdi: Optional[Union[YargitayBirimEnum, DanistayBirimEnum]] = Field(None, description="Chamber filter (optional)"),
|
||||
kararTarihiStart: Optional[str] = Field(None, description="Start date (ISO 8601 format)"),
|
||||
kararTarihiEnd: Optional[str] = Field(None, description="End date (ISO 8601 format)")
|
||||
kararTarihiStart: str = Field("", description="Start date (ISO 8601 format)"),
|
||||
kararTarihiEnd: str = Field("", description="End date (ISO 8601 format)")
|
||||
) -> dict:
|
||||
"""Search Turkish legal databases via unified Bedesten API."""
|
||||
search_data = BedestenSearchData(
|
||||
@@ -1665,7 +1860,7 @@ async def search_bedesten_unified(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve legal decision document from Bedesten API in Markdown format",
|
||||
description="Get legal decision document from Bedesten API in Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"idempotentHint": True
|
||||
@@ -1689,7 +1884,7 @@ async def get_bedesten_document_markdown(
|
||||
# --- MCP Tools for Sayıştay (Turkish Court of Accounts) ---
|
||||
|
||||
@app.tool(
|
||||
description="Search Sayıştay Genel Kurul decisions for audit and accountability regulations. Before using, read docs://tools/sayistay",
|
||||
description="Search Sayıştay Genel Kurul decisions for audit and accountability regulations",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1697,11 +1892,11 @@ async def get_bedesten_document_markdown(
|
||||
}
|
||||
)
|
||||
async def search_sayistay_genel_kurul(
|
||||
karar_no: Optional[str] = Field(None, description="Decision number to search for (e.g., '5415')"),
|
||||
karar_ek: Optional[str] = Field(None, description="Decision appendix number (max 99, e.g., '1')"),
|
||||
karar_tarih_baslangic: Optional[str] = Field(None, description="See docs for details"),
|
||||
karar_tarih_bitis: Optional[str] = Field(None, description="See docs for details"),
|
||||
karar_tamami: Optional[str] = Field(None, description="See docs for details"),
|
||||
karar_no: str = Field("", description="Decision number to search for (e.g., '5415')"),
|
||||
karar_ek: str = Field("", description="Decision appendix number (max 99, e.g., '1')"),
|
||||
karar_tarih_baslangic: str = Field("", description="Start date (DD.MM.YYYY)"),
|
||||
karar_tarih_bitis: str = Field("", description="End date (DD.MM.YYYY)"),
|
||||
karar_tamami: str = Field("", description="Full text search"),
|
||||
start: int = Field(0, description="Starting record for pagination (0-based)"),
|
||||
length: int = Field(10, description="Number of records per page (1-100)")
|
||||
) -> GenelKurulSearchResponse:
|
||||
@@ -1724,7 +1919,7 @@ async def search_sayistay_genel_kurul(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Search Sayıştay Temyiz Kurulu decisions with chamber filtering and comprehensive search criteria. Before using, read docs://tools/sayistay",
|
||||
description="Search Sayıştay Temyiz Kurulu decisions with chamber filtering and comprehensive criteria",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1732,16 +1927,16 @@ async def search_sayistay_genel_kurul(
|
||||
}
|
||||
)
|
||||
async def search_sayistay_temyiz_kurulu(
|
||||
ilam_dairesi: DaireEnum = Field("ALL", description="See docs for details"),
|
||||
yili: Optional[str] = Field(None, description="See docs for details"),
|
||||
karar_tarih_baslangic: Optional[str] = Field(None, description="See docs for details"),
|
||||
karar_tarih_bitis: Optional[str] = Field(None, description="See docs for details"),
|
||||
kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="See docs for details"),
|
||||
ilam_no: Optional[str] = Field(None, description="Audit report number (İlam No, max 50 chars)"),
|
||||
dosya_no: Optional[str] = Field(None, description="File number for the case"),
|
||||
temyiz_tutanak_no: Optional[str] = Field(None, description="Appeals board meeting minutes number"),
|
||||
temyiz_karar: Optional[str] = Field(None, description="See docs for details"),
|
||||
web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="See docs for details"),
|
||||
ilam_dairesi: DaireEnum = Field("ALL", description="Audit chamber selection"),
|
||||
yili: str = Field("", description="Year (YYYY)"),
|
||||
karar_tarih_baslangic: str = Field("", description="Start date (DD.MM.YYYY)"),
|
||||
karar_tarih_bitis: str = Field("", description="End date (DD.MM.YYYY)"),
|
||||
kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="Public admin type"),
|
||||
ilam_no: str = Field("", description="Audit report number (İlam No, max 50 chars)"),
|
||||
dosya_no: str = Field("", description="File number for the case"),
|
||||
temyiz_tutanak_no: str = Field("", description="Appeals board meeting minutes number"),
|
||||
temyiz_karar: str = Field("", description="Appeals decision text"),
|
||||
web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="Decision subject"),
|
||||
start: int = Field(0, description="Starting record for pagination (0-based)"),
|
||||
length: int = Field(10, description="Number of records per page (1-100)")
|
||||
) -> TemyizKuruluSearchResponse:
|
||||
@@ -1769,7 +1964,7 @@ async def search_sayistay_temyiz_kurulu(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Search Sayıştay Daire decisions with chamber filtering and subject categorization. Before using, read docs://tools/sayistay",
|
||||
description="Search Sayıştay Daire decisions with chamber filtering and subject categorization",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -1777,14 +1972,14 @@ async def search_sayistay_temyiz_kurulu(
|
||||
}
|
||||
)
|
||||
async def search_sayistay_daire(
|
||||
yargilama_dairesi: DaireEnum = Field("ALL", description="See docs for details"),
|
||||
karar_tarih_baslangic: Optional[str] = Field(None, description="See docs for details"),
|
||||
karar_tarih_bitis: Optional[str] = Field(None, description="See docs for details"),
|
||||
ilam_no: Optional[str] = Field(None, description="Audit report number (İlam No, max 50 chars)"),
|
||||
kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="See docs for details"),
|
||||
hesap_yili: Optional[str] = Field(None, description="See docs for details"),
|
||||
web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="See docs for details"),
|
||||
web_karar_metni: Optional[str] = Field(None, description="See docs for details"),
|
||||
yargilama_dairesi: DaireEnum = Field("ALL", description="Chamber selection"),
|
||||
karar_tarih_baslangic: str = Field("", description="Start date (DD.MM.YYYY)"),
|
||||
karar_tarih_bitis: str = Field("", description="End date (DD.MM.YYYY)"),
|
||||
ilam_no: str = Field("", description="Audit report number (İlam No, max 50 chars)"),
|
||||
kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="Public admin type"),
|
||||
hesap_yili: str = Field("", description="Fiscal year"),
|
||||
web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="Decision subject"),
|
||||
web_karar_metni: str = Field("", description="Decision text search"),
|
||||
start: int = Field(0, description="Starting record for pagination (0-based)"),
|
||||
length: int = Field(10, description="Number of records per page (1-100)")
|
||||
) -> DaireSearchResponse:
|
||||
@@ -1810,7 +2005,7 @@ async def search_sayistay_daire(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve Sayıştay Genel Kurul decision document in Markdown format. Before using, read docs://tools/sayistay",
|
||||
description="Get Sayıştay Genel Kurul decision document in Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": False,
|
||||
@@ -1833,7 +2028,7 @@ async def get_sayistay_genel_kurul_document_markdown(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve Sayıştay Temyiz Kurulu decision document in Markdown format. Before using, read docs://tools/sayistay",
|
||||
description="Get Sayıştay Temyiz Kurulu decision document in Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": False,
|
||||
@@ -1856,7 +2051,7 @@ async def get_sayistay_temyiz_kurulu_document_markdown(
|
||||
raise
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve Sayıştay Daire decision document in Markdown format. Before using, read docs://tools/sayistay",
|
||||
description="Get Sayıştay Daire decision document in Markdown format",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": False,
|
||||
@@ -2085,7 +2280,7 @@ async def check_government_servers_health() -> Dict[str, Any]:
|
||||
|
||||
# --- MCP Tools for KVKK ---
|
||||
@app.tool(
|
||||
description="Search KVKK decisions using Brave Search API for data protection authority decisions. Before using, read docs://tools/kvkk",
|
||||
description="Search KVKK data protection authority decisions",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": True,
|
||||
@@ -2093,7 +2288,7 @@ async def check_government_servers_health() -> Dict[str, Any]:
|
||||
}
|
||||
)
|
||||
async def search_kvkk_decisions(
|
||||
keywords: str = Field(..., description="Turkish keywords for KVKK decision search"),
|
||||
keywords: str = Field(..., description="Turkish keywords. Supports +required -excluded \"exact phrase\" operators"),
|
||||
page: int = Field(1, ge=1, le=50, description="Page number for results (1-50)."),
|
||||
pageSize: int = Field(10, ge=1, le=20, description="Number of results per page (1-20).")
|
||||
) -> KvkkSearchResult:
|
||||
@@ -2122,7 +2317,7 @@ async def search_kvkk_decisions(
|
||||
)
|
||||
|
||||
@app.tool(
|
||||
description="Retrieve KVKK decision document in Markdown format with metadata extraction. Before using, read docs://tools/kvkk",
|
||||
description="Get KVKK decision document in Markdown format with metadata extraction",
|
||||
annotations={
|
||||
"readOnlyHint": True,
|
||||
"openWorldHint": False,
|
||||
@@ -2130,7 +2325,7 @@ async def search_kvkk_decisions(
|
||||
}
|
||||
)
|
||||
async def get_kvkk_document_markdown(
|
||||
decision_url: str = Field(..., description="See docs for details"),
|
||||
decision_url: str = Field(..., description="KVKK decision URL from search results"),
|
||||
page_number: Union[int, str] = Field(1, description="Page number for paginated Markdown content (1-indexed, accepts int). Default is 1 (first 5,000 characters).")
|
||||
) -> KvkkDocumentMarkdown:
|
||||
"""Get KVKK decision as paginated Markdown."""
|
||||
@@ -2499,6 +2694,8 @@ async def fetch(
|
||||
logger.exception(f"Error fetching ChatGPT Deep Research document {id}")
|
||||
raise
|
||||
|
||||
# --- Token Metrics Tool Removed for Optimization ---
|
||||
|
||||
def ensure_playwright_browsers():
|
||||
"""Ensure Playwright browsers are installed for KIK tool functionality."""
|
||||
try:
|
||||
|
||||
@@ -30,6 +30,7 @@ dependencies = [
|
||||
"pypdf>=5.5.0",
|
||||
"fastapi>=0.115.14",
|
||||
"PyJWT>=2.8.0",
|
||||
"tiktoken>=0.5.0",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
|
||||
@@ -25,31 +25,31 @@ class RekabetKararTuruAdiEnum(str, Enum):
|
||||
|
||||
class RekabetKurumuSearchRequest(BaseModel):
|
||||
"""Model for Rekabet Kurumu (Turkish Competition Authority) search request."""
|
||||
sayfaAdi: Optional[str] = Field(None, description="Title")
|
||||
YayinlanmaTarihi: Optional[str] = Field(None, description="Date")
|
||||
PdfText: Optional[str] = Field(None, description="Text")
|
||||
KararTuruID: Optional[RekabetKararTuruGuidEnum] = Field(RekabetKararTuruGuidEnum.TUMU, description="Type")
|
||||
KararSayisi: Optional[str] = Field(None, description="No")
|
||||
KararTarihi: Optional[str] = Field(None, description="Date")
|
||||
sayfaAdi: str = Field("", description="Title")
|
||||
YayinlanmaTarihi: str = Field("", description="Date")
|
||||
PdfText: str = Field("", description="Text")
|
||||
KararTuruID: RekabetKararTuruGuidEnum = Field(RekabetKararTuruGuidEnum.TUMU, description="Type")
|
||||
KararSayisi: str = Field("", description="No")
|
||||
KararTarihi: str = Field("", description="Date")
|
||||
page: int = Field(1, ge=1, description="Page")
|
||||
|
||||
class RekabetDecisionSummary(BaseModel):
|
||||
"""Model for a single Rekabet Kurumu decision summary from search results."""
|
||||
publication_date: Optional[str] = Field(None, description="Pub date")
|
||||
decision_number: Optional[str] = Field(None, description="Number")
|
||||
decision_date: Optional[str] = Field(None, description="Date")
|
||||
decision_type_text: Optional[str] = Field(None, description="Type")
|
||||
title: Optional[str] = Field(None, description="Title")
|
||||
decision_url: Optional[HttpUrl] = Field(None, description="URL")
|
||||
karar_id: Optional[str] = Field(None, description="ID")
|
||||
related_cases_url: Optional[HttpUrl] = Field(None, description="Cases URL")
|
||||
publication_date: str = Field("", description="Pub date")
|
||||
decision_number: str = Field("", description="Number")
|
||||
decision_date: str = Field("", description="Date")
|
||||
decision_type_text: str = Field("", description="Type")
|
||||
title: str = Field("", description="Title")
|
||||
decision_url: str = Field("", description="URL")
|
||||
karar_id: str = Field("", description="ID")
|
||||
related_cases_url: str = Field("", description="Cases URL")
|
||||
|
||||
class RekabetSearchResult(BaseModel):
|
||||
"""Model for the overall search result for Rekabet Kurumu decisions."""
|
||||
decisions: List[RekabetDecisionSummary]
|
||||
total_records_found: Optional[int] = Field(None, description="Total")
|
||||
total_records_found: int = Field(0, description="Total")
|
||||
retrieved_page_number: int = Field(description="Page")
|
||||
total_pages: Optional[int] = Field(None, description="Pages")
|
||||
total_pages: int = Field(0, description="Pages")
|
||||
|
||||
class RekabetDocument(BaseModel):
|
||||
"""
|
||||
|
||||
@@ -16,14 +16,14 @@ class GenelKurulSearchRequest(BaseModel):
|
||||
of the Turkish Court of Accounts, typically addressing interpretation of
|
||||
audit and accountability regulations.
|
||||
"""
|
||||
karar_no: Optional[str] = Field(None, description="Decision no")
|
||||
karar_ek: Optional[str] = Field(None, description="Appendix no")
|
||||
karar_no: str = Field("", description="Decision no")
|
||||
karar_ek: str = Field("", description="Appendix no")
|
||||
|
||||
karar_tarih_baslangic: Optional[str] = Field(None, description="Start year (YYYY)")
|
||||
karar_tarih_baslangic: str = Field("", description="Start year (YYYY)")
|
||||
|
||||
karar_tarih_bitis: Optional[str] = Field(None, description="End year")
|
||||
karar_tarih_bitis: str = Field("", description="End year")
|
||||
|
||||
karar_tamami: Optional[str] = Field(None, description="Value")
|
||||
karar_tamami: str = Field("", description="Value")
|
||||
|
||||
# DataTables pagination
|
||||
start: int = Field(0, description="Starting record for pagination (0-based)")
|
||||
@@ -56,19 +56,19 @@ class TemyizKuruluSearchRequest(BaseModel):
|
||||
"""
|
||||
ilam_dairesi: DaireEnum = Field("ALL", description="Value")
|
||||
|
||||
yili: Optional[str] = Field(None, description="Value")
|
||||
yili: str = Field("", description="Value")
|
||||
|
||||
karar_tarih_baslangic: Optional[str] = Field(None, description="Value")
|
||||
karar_tarih_baslangic: str = Field("", description="Value")
|
||||
|
||||
karar_tarih_bitis: Optional[str] = Field(None, description="End year")
|
||||
karar_tarih_bitis: str = Field("", description="End year")
|
||||
|
||||
kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="Value")
|
||||
|
||||
ilam_no: Optional[str] = Field(None, description="Audit report number (İlam No, max 50 chars)")
|
||||
dosya_no: Optional[str] = Field(None, description="File number for the case")
|
||||
temyiz_tutanak_no: Optional[str] = Field(None, description="Appeals board meeting minutes number")
|
||||
ilam_no: str = Field("", description="Audit report number (İlam No, max 50 chars)")
|
||||
dosya_no: str = Field("", description="File number for the case")
|
||||
temyiz_tutanak_no: str = Field("", description="Appeals board meeting minutes number")
|
||||
|
||||
temyiz_karar: Optional[str] = Field(None, description="Value")
|
||||
temyiz_karar: str = Field("", description="Value")
|
||||
|
||||
web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="Value")
|
||||
|
||||
@@ -103,19 +103,19 @@ class DaireSearchRequest(BaseModel):
|
||||
"""
|
||||
yargilama_dairesi: DaireEnum = Field("ALL", description="Value")
|
||||
|
||||
karar_tarih_baslangic: Optional[str] = Field(None, description="Value")
|
||||
karar_tarih_baslangic: str = Field("", description="Value")
|
||||
|
||||
karar_tarih_bitis: Optional[str] = Field(None, description="End year")
|
||||
karar_tarih_bitis: str = Field("", description="End year")
|
||||
|
||||
ilam_no: Optional[str] = Field(None, description="Audit report number (İlam No, max 50 chars)")
|
||||
ilam_no: str = Field("", description="Audit report number (İlam No, max 50 chars)")
|
||||
|
||||
kamu_idaresi_turu: KamuIdaresiTuruEnum = Field("ALL", description="Value")
|
||||
|
||||
hesap_yili: Optional[str] = Field(None, description="Value")
|
||||
hesap_yili: str = Field("", description="Value")
|
||||
|
||||
web_karar_konusu: WebKararKonusuEnum = Field("ALL", description="Value")
|
||||
|
||||
web_karar_metni: Optional[str] = Field(None, description="Value")
|
||||
web_karar_metni: str = Field("", description="Value")
|
||||
|
||||
# DataTables pagination
|
||||
start: int = Field(0, description="Starting record for pagination (0-based)")
|
||||
@@ -127,7 +127,7 @@ class DaireDecision(BaseModel):
|
||||
yargilama_dairesi: int = Field(..., description="Chamber number (1-8)")
|
||||
karar_tarih: str = Field(..., description="Decision date in DD.MM.YYYY format")
|
||||
karar_no: str = Field(..., description="Decision number")
|
||||
ilam_no: Optional[str] = Field(None, description="Audit report number (may be null)")
|
||||
ilam_no: str = Field("", description="Audit report number (may be null)")
|
||||
madde_no: int = Field(..., description="Article/item number within the decision")
|
||||
kamu_idaresi_turu: str = Field(..., description="Public administration type")
|
||||
hesap_yili: int = Field(..., description="Account year being audited")
|
||||
@@ -155,6 +155,6 @@ class SayistayDocumentMarkdown(BaseModel):
|
||||
decision_id: str = Field(..., description="Unique decision identifier")
|
||||
decision_type: str = Field(..., description="Value")
|
||||
source_url: str = Field(..., description="Original URL where the document was retrieved")
|
||||
markdown_content: Optional[str] = Field(None, description="Full decision text converted to Markdown format")
|
||||
retrieval_date: Optional[str] = Field(None, description="Date when document was retrieved (ISO format)")
|
||||
error_message: Optional[str] = Field(None, description="Error message if document retrieval failed")
|
||||
markdown_content: str = Field("", description="Full decision text converted to Markdown format")
|
||||
retrieval_date: str = Field("", description="Date when document was retrieved (ISO format)")
|
||||
error_message: str = Field("", description="Error message if document retrieval failed")
|
||||
@@ -37,8 +37,6 @@ class YargitayDetailedSearchRequest(BaseModel):
|
||||
arananKelime: Optional[str] = Field("", description="Turkish keywords (supports +word -word \"phrase\" operators)")
|
||||
# Department/Board selection - Complete Court of Cassation chamber hierarchy
|
||||
birimYrgKurulDaire: Optional[str] = Field("ALL", description="Chamber (ALL or specific chamber name)")
|
||||
birimYrgHukukDaire: Optional[str] = Field("", description="Legacy field")
|
||||
birimYrgCezaDaire: Optional[str] = Field("", description="Legacy field")
|
||||
|
||||
esasYil: Optional[str] = Field("", description="Case year (YYYY)")
|
||||
esasIlkSiraNo: Optional[str] = Field("", description="Start case no")
|
||||
@@ -51,8 +49,6 @@ class YargitayDetailedSearchRequest(BaseModel):
|
||||
baslangicTarihi: Optional[str] = Field("", description="Start date (DD.MM.YYYY)")
|
||||
bitisTarihi: Optional[str] = Field("", description="End date (DD.MM.YYYY)")
|
||||
|
||||
siralama: Optional[str] = Field("3", description="Sort by (1=case, 2=decision, 3=date)")
|
||||
siralamaDirection: Optional[str] = Field("desc", description="Direction (asc/desc)")
|
||||
|
||||
pageSize: int = Field(10, ge=1, le=10, description="Results per page (1-100)")
|
||||
pageNumber: int = Field(1, ge=1, description="Page number (1-indexed)")
|
||||
|
||||
Reference in New Issue
Block a user