search_anayasa_unified
Search and retrieve Constitutional Court decisions, including norm control and individual applications, through a unified interface. Specify decision type, keywords, and date ranges to filter results efficiently.
Instructions
Unified search for Constitutional Court decisions: both norm control (normkararlarbilgibankasi) and individual applications (kararlarbilgibankasi) in one tool
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| application_date_end | No | Application end date (norm_denetimi only) | |
| application_date_start | No | Application start date (norm_denetimi only) | |
| decision_end_date | No | Decision end date (bireysel_basvuru only) | |
| decision_start_date | No | Decision start date (bireysel_basvuru only) | |
| decision_type | Yes | Decision type: norm_denetimi (norm control) or bireysel_basvuru (individual applications) | |
| decision_type_norm | No | Decision type for norm denetimi | ALL |
| keywords | No | Keywords to search for (common parameter) | |
| keywords_all | No | All keywords must be present (norm_denetimi only) | |
| keywords_any | No | Any of these keywords (norm_denetimi only) | |
| norm_type | No | Norm type (bireysel_basvuru only) | ALL |
| page_to_fetch | No | Page number to fetch (1-100) | |
| subject_category | No | Subject category (bireysel_basvuru only) |
Implementation Reference
- mcp_server_main.py:814-868 (handler)Handler function for the 'search_anayasa_unified' MCP tool. It validates input using AnayasaUnifiedSearchRequest, calls AnayasaUnifiedClient.search_unified, and returns JSON-serialized results.@app.tool( description="Unified search for Constitutional Court decisions: both norm control (normkararlarbilgibankasi) and individual applications (kararlarbilgibankasi) in one tool", annotations={ "readOnlyHint": True, "openWorldHint": True, "idempotentHint": True } ) async def search_anayasa_unified( decision_type: Literal["norm_denetimi", "bireysel_basvuru"] = Field(..., description="Decision type: norm_denetimi (norm control) or bireysel_basvuru (individual applications)"), keywords: List[str] = Field(default_factory=list, description="Keywords to search for (common parameter)"), page_to_fetch: int = Field(1, ge=1, le=100, description="Page number to fetch (1-100)"), # results_per_page: int = Field(10, ge=1, le=100, description="Results per page (1-100)"), # Norm Denetimi specific parameters (ignored for bireysel_basvuru) keywords_all: List[str] = Field(default_factory=list, description="All keywords must be present (norm_denetimi only)"), keywords_any: List[str] = Field(default_factory=list, description="Any of these keywords (norm_denetimi only)"), decision_type_norm: Literal["ALL", "1", "2", "3"] = Field("ALL", description="Decision type for norm denetimi"), application_date_start: str = Field("", description="Application start date (norm_denetimi only)"), application_date_end: str = Field("", description="Application end date (norm_denetimi only)"), # Bireysel Başvuru specific parameters (ignored for norm_denetimi) decision_start_date: str = Field("", description="Decision start date (bireysel_basvuru only)"), decision_end_date: str = Field("", description="Decision end date (bireysel_basvuru only)"), norm_type: Literal["ALL", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "0"] = Field("ALL", description="Norm type (bireysel_basvuru only)"), subject_category: str = Field("", description="Subject category (bireysel_basvuru only)") ) -> str: logger.info(f"Tool 'search_anayasa_unified' called for decision_type: {decision_type}") results_per_page = 10 # Default value try: request = AnayasaUnifiedSearchRequest( decision_type=decision_type, keywords=keywords, page_to_fetch=page_to_fetch, results_per_page=results_per_page, keywords_all=keywords_all, keywords_any=keywords_any, decision_type_norm=decision_type_norm, application_date_start=application_date_start, application_date_end=application_date_end, decision_start_date=decision_start_date, decision_end_date=decision_end_date, norm_type=norm_type, subject_category=subject_category ) result = await anayasa_unified_client_instance.search_unified(request) return json.dumps(result.model_dump(), ensure_ascii=False, indent=2) except Exception as e: logger.exception(f"Error in tool 'search_anayasa_unified'.") raise
- anayasa_mcp_module/models.py:193-214 (schema)Pydantic schema (input model) for the unified Anayasa search tool, defining parameters for both norm_denetimi and bireysel_basvuru decision types.class AnayasaUnifiedSearchRequest(BaseModel): """Unified search request for both Norm Denetimi and Bireysel Başvuru.""" decision_type: Literal["norm_denetimi", "bireysel_basvuru"] = Field(..., description="Decision type: norm_denetimi or bireysel_basvuru") # Common parameters keywords: List[str] = Field(default_factory=list, description="Keywords to search for") page_to_fetch: int = Field(1, ge=1, le=100, description="Page number to fetch (1-100)") results_per_page: int = Field(10, ge=1, le=100, description="Results per page (1-100)") # Norm Denetimi specific parameters (ignored for bireysel_basvuru) keywords_all: List[str] = Field(default_factory=list, description="All keywords must be present (norm_denetimi only)") keywords_any: List[str] = Field(default_factory=list, description="Any of these keywords (norm_denetimi only)") decision_type_norm: Literal["ALL", "1", "2", "3"] = Field("ALL", description="Decision type for norm denetimi") application_date_start: str = Field("", description="Application start date (norm_denetimi only)") application_date_end: str = Field("", description="Application end date (norm_denetimi only)") # Bireysel Başvuru specific parameters (ignored for norm_denetimi) decision_start_date: str = Field("", description="Decision start date (bireysel_basvuru only)") decision_end_date: str = Field("", description="Decision end date (bireysel_basvuru only)") norm_type: Literal["ALL", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "0"] = Field("ALL", description="Norm type (bireysel_basvuru only)") subject_category: str = Field("", description="Subject category (bireysel_basvuru only)")
- Core helper method in AnayasaUnifiedClient that implements the unified search logic, routing to norm or bireysel clients based on decision_type and converting results to unified format.async def search_unified(self, params: AnayasaUnifiedSearchRequest) -> AnayasaUnifiedSearchResult: """Unified search that routes to appropriate client based on decision_type.""" if params.decision_type == "norm_denetimi": # Convert to norm denetimi request norm_params = AnayasaNormDenetimiSearchRequest( keywords_all=params.keywords_all or params.keywords, keywords_any=params.keywords_any, application_type=params.decision_type_norm, page_to_fetch=params.page_to_fetch, results_per_page=params.results_per_page ) result = await self.norm_client.search_norm_denetimi_decisions(norm_params) # Convert to unified format decisions_list = [decision.model_dump() for decision in result.decisions] return AnayasaUnifiedSearchResult( decision_type="norm_denetimi", decisions=decisions_list, total_records_found=result.total_records_found, retrieved_page_number=result.retrieved_page_number ) elif params.decision_type == "bireysel_basvuru": # Convert to bireysel başvuru request bireysel_params = AnayasaBireyselReportSearchRequest( keywords=params.keywords, decision_start_date=params.decision_start_date, decision_end_date=params.decision_end_date, norm_type=params.norm_type, subject_category=params.subject_category, page_to_fetch=params.page_to_fetch, results_per_page=params.results_per_page ) result = await self.bireysel_client.search_bireysel_basvuru_report(bireysel_params) # Convert to unified format decisions_list = [decision.model_dump() for decision in result.decisions] return AnayasaUnifiedSearchResult( decision_type="bireysel_basvuru", decisions=decisions_list, total_records_found=result.total_records_found, retrieved_page_number=result.retrieved_page_number ) else: raise ValueError(f"Unsupported decision type: {params.decision_type}")
- mcp_server_main.py:814-868 (registration)MCP tool registration via @app.tool decorator in the main server file, which defines the tool name 'search_anayasa_unified', description, annotations, and binds the handler function.@app.tool( description="Unified search for Constitutional Court decisions: both norm control (normkararlarbilgibankasi) and individual applications (kararlarbilgibankasi) in one tool", annotations={ "readOnlyHint": True, "openWorldHint": True, "idempotentHint": True } ) async def search_anayasa_unified( decision_type: Literal["norm_denetimi", "bireysel_basvuru"] = Field(..., description="Decision type: norm_denetimi (norm control) or bireysel_basvuru (individual applications)"), keywords: List[str] = Field(default_factory=list, description="Keywords to search for (common parameter)"), page_to_fetch: int = Field(1, ge=1, le=100, description="Page number to fetch (1-100)"), # results_per_page: int = Field(10, ge=1, le=100, description="Results per page (1-100)"), # Norm Denetimi specific parameters (ignored for bireysel_basvuru) keywords_all: List[str] = Field(default_factory=list, description="All keywords must be present (norm_denetimi only)"), keywords_any: List[str] = Field(default_factory=list, description="Any of these keywords (norm_denetimi only)"), decision_type_norm: Literal["ALL", "1", "2", "3"] = Field("ALL", description="Decision type for norm denetimi"), application_date_start: str = Field("", description="Application start date (norm_denetimi only)"), application_date_end: str = Field("", description="Application end date (norm_denetimi only)"), # Bireysel Başvuru specific parameters (ignored for norm_denetimi) decision_start_date: str = Field("", description="Decision start date (bireysel_basvuru only)"), decision_end_date: str = Field("", description="Decision end date (bireysel_basvuru only)"), norm_type: Literal["ALL", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "0"] = Field("ALL", description="Norm type (bireysel_basvuru only)"), subject_category: str = Field("", description="Subject category (bireysel_basvuru only)") ) -> str: logger.info(f"Tool 'search_anayasa_unified' called for decision_type: {decision_type}") results_per_page = 10 # Default value try: request = AnayasaUnifiedSearchRequest( decision_type=decision_type, keywords=keywords, page_to_fetch=page_to_fetch, results_per_page=results_per_page, keywords_all=keywords_all, keywords_any=keywords_any, decision_type_norm=decision_type_norm, application_date_start=application_date_start, application_date_end=application_date_end, decision_start_date=decision_start_date, decision_end_date=decision_end_date, norm_type=norm_type, subject_category=subject_category ) result = await anayasa_unified_client_instance.search_unified(request) return json.dumps(result.model_dump(), ensure_ascii=False, indent=2) except Exception as e: logger.exception(f"Error in tool 'search_anayasa_unified'.") raise
- AnayasaUnifiedClient class providing unified API clients for norm_denetimi and bireysel_basvuru, instantiated as anayasa_unified_client_instance in main server.class AnayasaUnifiedClient: """Unified client that handles both Norm Denetimi and Bireysel Başvuru searches.""" def __init__(self, request_timeout: float = 60.0): self.norm_client = AnayasaMahkemesiApiClient(request_timeout) self.bireysel_client = AnayasaBireyselBasvuruApiClient(request_timeout) async def search_unified(self, params: AnayasaUnifiedSearchRequest) -> AnayasaUnifiedSearchResult: """Unified search that routes to appropriate client based on decision_type.""" if params.decision_type == "norm_denetimi": # Convert to norm denetimi request norm_params = AnayasaNormDenetimiSearchRequest( keywords_all=params.keywords_all or params.keywords, keywords_any=params.keywords_any, application_type=params.decision_type_norm, page_to_fetch=params.page_to_fetch, results_per_page=params.results_per_page ) result = await self.norm_client.search_norm_denetimi_decisions(norm_params) # Convert to unified format decisions_list = [decision.model_dump() for decision in result.decisions] return AnayasaUnifiedSearchResult( decision_type="norm_denetimi", decisions=decisions_list, total_records_found=result.total_records_found, retrieved_page_number=result.retrieved_page_number ) elif params.decision_type == "bireysel_basvuru": # Convert to bireysel başvuru request bireysel_params = AnayasaBireyselReportSearchRequest( keywords=params.keywords, decision_start_date=params.decision_start_date, decision_end_date=params.decision_end_date, norm_type=params.norm_type, subject_category=params.subject_category, page_to_fetch=params.page_to_fetch, results_per_page=params.results_per_page ) result = await self.bireysel_client.search_bireysel_basvuru_report(bireysel_params) # Convert to unified format decisions_list = [decision.model_dump() for decision in result.decisions] return AnayasaUnifiedSearchResult( decision_type="bireysel_basvuru", decisions=decisions_list, total_records_found=result.total_records_found, retrieved_page_number=result.retrieved_page_number ) else: raise ValueError(f"Unsupported decision type: {params.decision_type}") async def get_document_unified(self, document_url: str, page_number: int = 1) -> AnayasaUnifiedDocumentMarkdown: """Unified document retrieval that auto-detects the appropriate client.""" # Auto-detect decision type based on URL parsed_url = urlparse(document_url) if "normkararlarbilgibankasi" in parsed_url.netloc or "/ND/" in document_url: # Norm Denetimi document result = await self.norm_client.get_decision_document_as_markdown(document_url, page_number) return AnayasaUnifiedDocumentMarkdown( decision_type="norm_denetimi", source_url=result.source_url, document_data=result.model_dump(), markdown_chunk=result.markdown_chunk, current_page=result.current_page, total_pages=result.total_pages, is_paginated=result.is_paginated ) elif "kararlarbilgibankasi" in parsed_url.netloc or "/BB/" in document_url: # Bireysel Başvuru document result = await self.bireysel_client.get_decision_document_as_markdown(document_url, page_number) return AnayasaUnifiedDocumentMarkdown( decision_type="bireysel_basvuru", source_url=result.source_url, document_data=result.model_dump(), markdown_chunk=result.markdown_chunk, current_page=result.current_page, total_pages=result.total_pages, is_paginated=result.is_paginated ) else: raise ValueError(f"Cannot determine document type from URL: {document_url}") async def close_client_session(self): """Close both client sessions.""" if hasattr(self.norm_client, 'close_client_session'):