From 3bcf2bbf2a29c0df61d0c3e5541432bd62537c91 Mon Sep 17 00:00:00 2001 From: saidsurucu Date: Wed, 28 May 2025 18:42:16 +0300 Subject: [PATCH] flatten parameters --- anayasa_mcp_module/bireysel_client.py | 2 +- anayasa_mcp_module/client.py | 2 +- danistay_mcp_module/client.py | 2 +- emsal_mcp_module/client.py | 2 +- mcp_server_main.py | 341 +++++++++++++++++++++++--- pyproject.toml | 2 +- uyusmazlik_mcp_module/client.py | 2 +- yargitay_mcp_module/client.py | 2 +- 8 files changed, 320 insertions(+), 35 deletions(-) diff --git a/anayasa_mcp_module/bireysel_client.py b/anayasa_mcp_module/bireysel_client.py index 5c048f7..a4848ed 100644 --- a/anayasa_mcp_module/bireysel_client.py +++ b/anayasa_mcp_module/bireysel_client.py @@ -232,7 +232,7 @@ class AnayasaBireyselBasvuruApiClient: markdown_text = None temp_file_path = None try: - md_converter = MarkItDown(enable_plugins=False) + md_converter = MarkItDown() with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".html", encoding="utf-8") as tmp_file: if not html_input_for_markdown.strip().lower().startswith(("{html_input_for_markdown}") diff --git a/anayasa_mcp_module/client.py b/anayasa_mcp_module/client.py index 6a8fe19..7053441 100644 --- a/anayasa_mcp_module/client.py +++ b/anayasa_mcp_module/client.py @@ -224,7 +224,7 @@ class AnayasaMahkemesiApiClient: markdown_text = None temp_file_path = None try: - md_converter = MarkItDown(enable_plugins=False) + md_converter = MarkItDown() with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".html", encoding="utf-8") as tmp_file: # Ensure the content is wrapped in basic HTML structure if it's not already if not html_input_for_markdown.strip().lower().startswith((" CompactYargitaySearchResult: +async def search_yargitay_detailed( + arananKelime: str = Field("", description="Keyword to search for."), + birimYrgKurulDaire: str = Field("", description="Yargitay Board Unit (e.g., 'Hukuk Genel Kurulu')."), + birimYrgHukukDaire: str = Field("", description="Yargitay Civil Chamber (e.g., '1. Hukuk Dairesi')."), + birimYrgCezaDaire: str = Field("", description="Yargitay Criminal Chamber."), + 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'."), + kararYil: str = Field("", description="Decision year for 'Karar No'."), + kararIlkSiraNo: str = Field("", description="Starting sequence number for 'Karar No'."), + 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=100, description="Number of results per page."), + pageNumber: int = Field(1, ge=1, description="Page number to retrieve.") +) -> CompactYargitaySearchResult: """Searches Yargitay (Court of Cassation) decisions using detailed criteria.""" + + search_query = YargitayDetailedSearchRequest( + arananKelime=arananKelime, + birimYrgKurulDaire=birimYrgKurulDaire, + birimYrgHukukDaire=birimYrgHukukDaire, + birimYrgCezaDaire=birimYrgCezaDaire, + esasYil=esasYil, + esasIlkSiraNo=esasIlkSiraNo, + esasSonSiraNo=esasSonSiraNo, + kararYil=kararYil, + kararIlkSiraNo=kararIlkSiraNo, + kararSonSiraNo=kararSonSiraNo, + baslangicTarihi=baslangicTarihi, + bitisTarihi=bitisTarihi, + siralama=siralama, + siralamaDirection=siralamaDirection, + pageSize=pageSize, + pageNumber=pageNumber + ) + logger.info(f"Tool 'search_yargitay_detailed' called: {search_query.model_dump_json(exclude_none=True, indent=2)}") try: api_response = await yargitay_client_instance.search_detailed_decisions(search_query) @@ -103,7 +142,7 @@ async def search_yargitay_detailed(search_query: YargitayDetailedSearchRequest) logger.warning("API response for Yargitay search did not contain expected data structure.") return CompactYargitaySearchResult(decisions=[], total_records=0, requested_page=search_query.pageNumber, page_size=search_query.pageSize) except Exception as e: - logger.exception(f"Error in tool 'search_yargitay_detailed'.") # Query loglaması kaldırıldı, PII içerebilir + logger.exception(f"Error in tool 'search_yargitay_detailed'.") raise @app.tool() @@ -118,11 +157,27 @@ async def get_yargitay_document_markdown(document_id: str) -> YargitayDocumentMa raise # --- MCP Tools for Danistay --- -# ... (Danıştay araçları öncekiyle aynı, docstringler İngilizce) ... @app.tool() -async def search_danistay_by_keyword(search_query: DanistayKeywordSearchRequest) -> CompactDanistaySearchResult: +async def search_danistay_by_keyword( + andKelimeler: List[str] = Field(default_factory=list, description="Keywords for AND logic, e.g., ['word1', 'word2']"), + orKelimeler: List[str] = Field(default_factory=list, description="Keywords for OR logic."), + notAndKelimeler: List[str] = Field(default_factory=list, description="Keywords for NOT AND logic."), + notOrKelimeler: List[str] = Field(default_factory=list, description="Keywords for NOT OR logic."), + pageNumber: int = Field(1, ge=1, description="Page number."), + pageSize: int = Field(10, ge=1, le=100, description="Results per page.") +) -> CompactDanistaySearchResult: """Searches Danıştay (Council of State) decisions using keywords.""" - logger.info(f"Tool 'search_danistay_by_keyword' called.") # Query loglaması kaldırıldı + + search_query = DanistayKeywordSearchRequest( + andKelimeler=andKelimeler, + orKelimeler=orKelimeler, + notAndKelimeler=notAndKelimeler, + notOrKelimeler=notOrKelimeler, + pageNumber=pageNumber, + pageSize=pageSize + ) + + logger.info(f"Tool 'search_danistay_by_keyword' called.") try: api_response = await danistay_client_instance.search_keyword_decisions(search_query) if api_response.data: @@ -138,9 +193,46 @@ async def search_danistay_by_keyword(search_query: DanistayKeywordSearchRequest) raise @app.tool() -async def search_danistay_detailed(search_query: DanistayDetailedSearchRequest) -> CompactDanistaySearchResult: +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')."), + pageNumber: int = Field(1, ge=1, description="Page number."), + pageSize: int = Field(10, ge=1, le=100, description="Results per page.") +) -> CompactDanistaySearchResult: """Performs a detailed search for Danıştay (Council of State) decisions.""" - logger.info(f"Tool 'search_danistay_detailed' called.") # Query loglaması kaldırıldı + + search_query = DanistayDetailedSearchRequest( + daire=daire, + esasYil=esasYil, + esasIlkSiraNo=esasIlkSiraNo, + esasSonSiraNo=esasSonSiraNo, + kararYil=kararYil, + kararIlkSiraNo=kararIlkSiraNo, + kararSonSiraNo=kararSonSiraNo, + baslangicTarihi=baslangicTarihi, + bitisTarihi=bitisTarihi, + mevzuatNumarasi=mevzuatNumarasi, + mevzuatAdi=mevzuatAdi, + madde=madde, + siralama=siralama, + siralamaDirection=siralamaDirection, + pageNumber=pageNumber, + pageSize=pageSize + ) + + logger.info(f"Tool 'search_danistay_detailed' called.") try: api_response = await danistay_client_instance.search_detailed_decisions(search_query) if api_response.data: @@ -167,11 +259,47 @@ async def get_danistay_document_markdown(document_id: str) -> DanistayDocumentMa raise # --- MCP Tools for Emsal --- -# ... (Emsal araçları öncekiyle aynı, docstringler İngilizce) ... @app.tool() -async def search_emsal_detailed_decisions(search_query: EmsalSearchRequest) -> CompactEmsalSearchResult: +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."), + 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)."), + 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."), + page_size: int = Field(10, ge=1, le=100, description="Results per page.") +) -> CompactEmsalSearchResult: """Searches for Emsal (UYAP Precedent) decisions using detailed criteria.""" - logger.info(f"Tool 'search_emsal_detailed_decisions' called.") # Query loglaması kaldırıldı + + search_query = EmsalSearchRequest( + keyword=keyword, + selected_bam_civil_court=selected_bam_civil_court, + selected_civil_court=selected_civil_court, + selected_regional_civil_chambers=selected_regional_civil_chambers, + case_year_esas=case_year_esas, + case_start_seq_esas=case_start_seq_esas, + case_end_seq_esas=case_end_seq_esas, + decision_year_karar=decision_year_karar, + decision_start_seq_karar=decision_start_seq_karar, + decision_end_seq_karar=decision_end_seq_karar, + start_date=start_date, + end_date=end_date, + sort_criteria=sort_criteria, + sort_direction=sort_direction, + page_number=page_number, + page_size=page_size + ) + + logger.info(f"Tool 'search_emsal_detailed_decisions' called.") try: api_response = await emsal_client_instance.search_detailed_decisions(search_query) if api_response.data: @@ -199,13 +327,56 @@ async def get_emsal_document_markdown(document_id: str) -> EmsalDocumentMarkdown raise # --- MCP Tools for Uyusmazlik --- -# ... (Uyuşmazlık araçları öncekiyle aynı, docstringler İngilizce) ... @app.tool() async def search_uyusmazlik_decisions( - search_params: UyusmazlikSearchRequest + icerik: str = Field("", description="Keyword or content for main text search."), + bolum: Literal["", "Ceza Bölümü", "Genel Kurul Kararları", "Hukuk Bölümü"] = Field("", description="Select the department (Bölüm)."), + uyusmazlik_turu: Literal["", "Görev Uyuşmazlığı", "Hüküm Uyuşmazlığı"] = Field("", description="Select the type of dispute."), + karar_sonuclari: List[Literal["Hüküm Uyuşmazlığı Olmadığına Dair", "Hüküm Uyuşmazlığı Olduğuna Dair"]] = Field(default_factory=list, description="List of desired 'Karar Sonucu' types."), + esas_yil: str = Field("", description="Case year ('Esas Yılı')."), + esas_sayisi: str = Field("", description="Case number ('Esas Sayısı')."), + karar_yil: str = Field("", description="Decision year ('Karar Yılı')."), + karar_sayisi: str = Field("", description="Decision number ('Karar Sayısı')."), + kanun_no: str = Field("", description="Relevant Law Number."), + karar_date_begin: str = Field("", description="Decision start date (DD.MM.YYYY)."), + karar_date_end: str = Field("", description="Decision end date (DD.MM.YYYY)."), + resmi_gazete_sayi: str = Field("", description="Official Gazette number."), + resmi_gazete_date: str = Field("", description="Official Gazette date (DD.MM.YYYY)."), + tumce: str = Field("", description="Exact phrase search."), + wild_card: str = Field("", description="Search for phrase and its inflections."), + hepsi: str = Field("", description="Search for texts containing all specified words."), + herhangi_birisi: str = Field("", description="Search for texts containing any of the specified words."), + not_hepsi: str = Field("", description="Exclude texts containing these specified words.") ) -> UyusmazlikSearchResponse: """Searches for Uyuşmazlık Mahkemesi (Court of Jurisdictional Disputes) decisions using various criteria.""" - logger.info(f"Tool 'search_uyusmazlik_decisions' called.") # Query loglaması kaldırıldı + + # Convert string literals to enums + bolum_enum = UyusmazlikBolumEnum(bolum) if bolum else UyusmazlikBolumEnum.TUMU + uyusmazlik_turu_enum = UyusmazlikTuruEnum(uyusmazlik_turu) if uyusmazlik_turu else UyusmazlikTuruEnum.TUMU + karar_sonuclari_enums = [UyusmazlikKararSonucuEnum(ks) for ks in karar_sonuclari] + + search_params = UyusmazlikSearchRequest( + icerik=icerik, + bolum=bolum_enum, + uyusmazlik_turu=uyusmazlik_turu_enum, + karar_sonuclari=karar_sonuclari_enums, + esas_yil=esas_yil, + esas_sayisi=esas_sayisi, + karar_yil=karar_yil, + karar_sayisi=karar_sayisi, + kanun_no=kanun_no, + karar_date_begin=karar_date_begin, + karar_date_end=karar_date_end, + resmi_gazete_sayi=resmi_gazete_sayi, + resmi_gazete_date=resmi_gazete_date, + tumce=tumce, + wild_card=wild_card, + hepsi=hepsi, + herhangi_birisi=herhangi_birisi, + not_hepsi=not_hepsi + ) + + logger.info(f"Tool 'search_uyusmazlik_decisions' called.") try: return await uyusmazlik_client_instance.search_decisions(search_params) except Exception as e: @@ -229,16 +400,90 @@ async def get_uyusmazlik_document_markdown_from_url(document_url: HttpUrl) -> Uy raise # --- MCP Tools for Anayasa Mahkemesi (Norm Denetimi) --- -# ... (Anayasa Norm araçları öncekiyle aynı, docstringler İngilizce) ... @app.tool() async def search_anayasa_norm_denetimi_decisions( - search_query: AnayasaNormDenetimiSearchRequest + keywords_all: List[str] = Field(default_factory=list, description="Keywords for AND logic."), + keywords_any: List[str] = Field(default_factory=list, description="Keywords for OR logic."), + keywords_exclude: List[str] = Field(default_factory=list, description="Keywords to exclude."), + period: Literal["", "1", "2"] = Field("", description="Constitutional period ('': All, '1': 1961, '2': 1982)."), + case_number_esas: Optional[str] = Field(None, description="Case registry number (e.g., '2023/123')."), + decision_number_karar: Optional[str] = Field(None, description="Decision number (e.g., '2023/456')."), + first_review_date_start: Optional[str] = Field(None, description="First review start date (DD/MM/YYYY)."), + first_review_date_end: Optional[str] = Field(None, description="First review end date (DD/MM/YYYY)."), + decision_date_start: Optional[str] = Field(None, description="Decision start date (DD/MM/YYYY)."), + decision_date_end: Optional[str] = Field(None, description="Decision end date (DD/MM/YYYY)."), + application_type: Literal["", "1", "2", "3"] = Field("", description="Application type ('': All, '1': İptal, '2': İtiraz, '3': Diğer)."), + applicant_general_name: Optional[str] = Field(None, description="General applicant name."), + applicant_specific_name: Optional[str] = Field(None, description="Specific applicant name."), + official_gazette_date_start: Optional[str] = Field(None, description="Official Gazette start date (DD/MM/YYYY)."), + official_gazette_date_end: Optional[str] = Field(None, description="Official Gazette end date (DD/MM/YYYY)."), + official_gazette_number_start: Optional[str] = Field(None, description="Official Gazette starting number."), + official_gazette_number_end: Optional[str] = Field(None, description="Official Gazette ending number."), + has_press_release: Literal["", "0", "1"] = Field("", description="Press release ('': All, '0': No, '1': Yes)."), + has_dissenting_opinion: Literal["", "0", "1"] = Field("", description="Dissenting opinion ('': All, '0': No, '1': Yes)."), + has_different_reasoning: Literal["", "0", "1"] = Field("", description="Different reasoning ('': All, '0': No, '1': Yes)."), + attending_members_names: List[str] = Field(default_factory=list, description="List of attending members' exact names."), + rapporteur_name: Optional[str] = Field(None, description="Rapporteur's exact name."), + norm_type: Literal["", "1", "2", "14", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "0", "13"] = Field("", description="Type of reviewed norm."), + norm_id_or_name: Optional[str] = Field(None, description="Number or name of the norm."), + norm_article: Optional[str] = Field(None, description="Article number of the norm."), + review_outcomes: List[Literal["", "1", "2", "3", "4", "5", "6", "7", "8", "12"]] = Field(default_factory=list, description="List of review outcomes."), + reason_for_final_outcome: Literal["", "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("", description="Main reason for decision outcome."), + basis_constitution_article_numbers: List[str] = Field(default_factory=list, description="List of supporting Constitution article numbers."), + results_per_page: int = Field(10, description="Results per page (10, 20, 30, 40, 50)."), + page_to_fetch: int = Field(1, ge=1, description="Page number to fetch."), + sort_by_criteria: str = Field("KararTarihi", description="Sort criteria ('KararTarihi', 'YayinTarihi', 'Toplam').") ) -> AnayasaSearchResult: """ Searches Anayasa Mahkemesi (Constitutional Court) Norm Denetimi (Norm Control) decisions using criteria from https://normkararlarbilgibankasi.anayasa.gov.tr. """ - logger.info(f"Tool 'search_anayasa_norm_denetimi_decisions' called.") # Query loglaması kaldırıldı + + # Convert string literals to enums + period_enum = AnayasaDonemEnum(period) + application_type_enum = AnayasaBasvuruTuruEnum(application_type) + has_press_release_enum = AnayasaVarYokEnum(has_press_release) + has_dissenting_opinion_enum = AnayasaVarYokEnum(has_dissenting_opinion) + has_different_reasoning_enum = AnayasaVarYokEnum(has_different_reasoning) + norm_type_enum = AnayasaNormTuruEnum(norm_type) + review_outcomes_enums = [AnayasaIncelemeSonucuEnum(ro) for ro in review_outcomes] + reason_for_final_outcome_enum = AnayasaSonucGerekcesiEnum(reason_for_final_outcome) + + search_query = AnayasaNormDenetimiSearchRequest( + keywords_all=keywords_all, + keywords_any=keywords_any, + keywords_exclude=keywords_exclude, + period=period_enum, + case_number_esas=case_number_esas, + decision_number_karar=decision_number_karar, + first_review_date_start=first_review_date_start, + first_review_date_end=first_review_date_end, + decision_date_start=decision_date_start, + decision_date_end=decision_date_end, + application_type=application_type_enum, + applicant_general_name=applicant_general_name, + applicant_specific_name=applicant_specific_name, + official_gazette_date_start=official_gazette_date_start, + official_gazette_date_end=official_gazette_date_end, + official_gazette_number_start=official_gazette_number_start, + official_gazette_number_end=official_gazette_number_end, + has_press_release=has_press_release_enum, + has_dissenting_opinion=has_dissenting_opinion_enum, + has_different_reasoning=has_different_reasoning_enum, + attending_members_names=attending_members_names, + rapporteur_name=rapporteur_name, + norm_type=norm_type_enum, + norm_id_or_name=norm_id_or_name, + norm_article=norm_article, + review_outcomes=review_outcomes_enums, + reason_for_final_outcome=reason_for_final_outcome_enum, + basis_constitution_article_numbers=basis_constitution_article_numbers, + results_per_page=results_per_page, + page_to_fetch=page_to_fetch, + sort_by_criteria=sort_by_criteria + ) + + logger.info(f"Tool 'search_anayasa_norm_denetimi_decisions' called.") try: return await anayasa_norm_client_instance.search_norm_denetimi_decisions(search_query) except Exception as e: @@ -266,17 +511,23 @@ async def get_anayasa_norm_denetimi_document_markdown( raise # --- MCP Tools for Anayasa Mahkemesi (Bireysel Başvuru Karar Raporu & Belgeler) --- -# ... (Anayasa Bireysel araçları öncekiyle aynı, docstringler İngilizce) ... @app.tool() async def search_anayasa_bireysel_basvuru_report( - search_query: AnayasaBireyselReportSearchRequest + keywords: List[str] = Field(default_factory=list, description="Keywords for AND logic."), + page_to_fetch: int = Field(1, ge=1, description="Page number to fetch for the report. Default is 1.") ) -> AnayasaBireyselReportSearchResult: """ Searches Anayasa Mahkemesi (Constitutional Court) Bireysel Başvuru (Individual Application) decisions and generates a 'Karar Arama Raporu' (Decision Search Report). This is for https://kararlarbilgibankasi.anayasa.gov.tr (uses KararBulteni=1). """ - logger.info(f"Tool 'search_anayasa_bireysel_basvuru_report' called.") # Query loglaması kaldırıldı + + search_query = AnayasaBireyselReportSearchRequest( + keywords=keywords, + page_to_fetch=page_to_fetch + ) + + logger.info(f"Tool 'search_anayasa_bireysel_basvuru_report' called.") try: return await anayasa_bireysel_client_instance.search_bireysel_basvuru_report(search_query) except Exception as e: @@ -305,16 +556,48 @@ async def get_anayasa_bireysel_basvuru_document_markdown( # --- MCP Tools for KIK (Kamu İhale Kurulu) --- @app.tool() -async def search_kik_decisions(search_query: KikSearchRequest) -> KikSearchResult: +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="Keyword/phrase in decision text."), + 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."), + page: int = Field(1, ge=1, description="Results page number.") +) -> KikSearchResult: """ Searches KIK (Public Procurement Authority) decisions. """ - logger.info(f"Tool 'search_kik_decisions' called.") # Query loglaması kaldırıldı + + # Convert string literal to enum + karar_tipi_enum = KikKararTipi(karar_tipi) + + search_query = KikSearchRequest( + karar_tipi=karar_tipi_enum, + karar_no=karar_no, + karar_tarihi_baslangic=karar_tarihi_baslangic, + karar_tarihi_bitis=karar_tarihi_bitis, + basvuru_sahibi=basvuru_sahibi, + ihaleyi_yapan_idare=ihaleyi_yapan_idare, + basvuru_konusu_ihale=basvuru_konusu_ihale, + karar_metni=karar_metni, + yil=yil, + resmi_gazete_tarihi=resmi_gazete_tarihi, + resmi_gazete_sayisi=resmi_gazete_sayisi, + page=page + ) + + logger.info(f"Tool 'search_kik_decisions' called.") try: api_response = await kik_client_instance.search_decisions(search_query) page_param_for_log = search_query.page if hasattr(search_query, 'page') else 1 if not api_response.decisions and api_response.total_records == 0 and page_param_for_log == 1: - logger.warning(f"KIK search returned no decisions for query.") # Query detayı kaldırıldı + logger.warning(f"KIK search returned no decisions for query.") return api_response except Exception as e: logger.exception(f"Error in KIK search tool 'search_kik_decisions'.") @@ -360,7 +643,6 @@ async def get_kik_document_markdown( ) # --- Application Shutdown Handling --- -# ... (perform_cleanup ve main fonksiyonları öncekiyle aynı, değişiklik yok) ... def perform_cleanup(): logger.info("MCP Server performing cleanup...") try: @@ -404,7 +686,9 @@ def perform_cleanup(): except Exception as e: logger.error(f"Error during atexit cleanup execution: {e}", exc_info=True) logger.info("MCP Server atexit cleanup process finished.") + atexit.register(perform_cleanup) + def main(): logger.info(f"Starting {app.name} server via main() function...") logger.info(f"Logs will be written to: {LOG_FILE_PATH}") @@ -416,5 +700,6 @@ def main(): logger.exception("Server failed to start or crashed.") finally: logger.info(f"{app.name} server has shut down.") + if __name__ == "__main__": main() \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 00876cc..262128a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,12 +6,12 @@ readme = "README.md" requires-python = ">=3.11" dependencies = [ "beautifulsoup4>=4.13.4", - "fastmcp>=2.2.10", "httpx>=0.28.1", "markitdown>=0.1.1", "pydantic>=2.11.4", "aiohttp>=3.11.18", "playwright>=1.52.0", + "fastmcp>=2.5.1", ] [project.scripts] diff --git a/uyusmazlik_mcp_module/client.py b/uyusmazlik_mcp_module/client.py index a69b91a..9bda9fa 100644 --- a/uyusmazlik_mcp_module/client.py +++ b/uyusmazlik_mcp_module/client.py @@ -196,7 +196,7 @@ class UyusmazlikApiClient: markdown_text = None temp_file_path = None try: - md_converter = MarkItDown(enable_plugins=False) + md_converter = MarkItDown() with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".html", encoding="utf-8") as tmp_file: tmp_file.write(html_input_for_markdown) temp_file_path = tmp_file.name diff --git a/yargitay_mcp_module/client.py b/yargitay_mcp_module/client.py index 408ab69..88172f9 100644 --- a/yargitay_mcp_module/client.py +++ b/yargitay_mcp_module/client.py @@ -110,7 +110,7 @@ class YargitayOfficialApiClient: markdown_output = None temp_file_path = None try: - md_converter = MarkItDown(enable_plugins=False) # Plugins disabled as per basic usage + md_converter = MarkItDown() # Plugins disabled as per basic usage # Write the HTML to a temporary file for MarkItDown to process with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".html", encoding="utf-8") as tmp_html_file: