Skip to main content
Glama

get_tender_details

Retrieve comprehensive tender details from Turkish public procurement data, including basic information, characteristics, OKAS codes, authority details, process rules, announcements summary, and cancellation status when applicable.

Instructions

Get comprehensive tender details with HTML-to-Markdown conversion.

Returns: basic info, characteristics, OKAS codes, authority details, process rules, announcements summary, cancellation info if applicable.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
tender_idYesThe tender ID to get comprehensive details for

Implementation Reference

  • MCP tool handler function for 'get_tender_details'. This is the main entrypoint for the tool, decorated with @mcp.tool for registration, with input schema via Annotated type hint, and delegates to EKAPClient for core logic.
    @mcp.tool async def get_tender_details( tender_id: Annotated[int, "The tender ID to get comprehensive details for"] ) -> Dict[str, Any]: """ Get comprehensive tender details with HTML-to-Markdown conversion. Returns: basic info, characteristics, OKAS codes, authority details, process rules, announcements summary, cancellation info if applicable. """ # Use the client to get tender details result = await ekap_client.get_tender_details(tender_id) if result.get("error"): return result return { "tender_details": result, "summary": { "tender_name": result.get("name"), "ikn": result.get("ikn"), "status": result.get("status", {}).get("description"), "authority": result.get("authority", {}).get("name"), "location": result.get("basic_info", {}).get("location"), "is_electronic": result.get("basic_info", {}).get("is_electronic"), "characteristics_count": len(result.get("characteristics", [])), "okas_codes_count": len(result.get("okas_codes", [])), "announcements_count": result.get("announcements_summary", {}).get("total_count", 0) } }
  • Core helper implementation in EKAPClient class that fetches tender details from EKAP API endpoint '/b_ihalearama/api/IhaleDetay/GetByIhaleIdIhaleDetay', parses response, converts HTML to Markdown, formats data including characteristics, OKAS codes, authority info, process rules, and announcements summary.
    async def get_tender_details( self, tender_id: int ) -> Dict[str, Any]: """Get comprehensive details for a specific tender""" # Build API request payload for tender details details_params = { "ihaleId": str(tender_id) } try: # Make API request to tender details endpoint response_data = await self._make_request(self.tender_details_endpoint, details_params) # Parse and format the response item = response_data.get("item", {}) if not item: return { "error": "Tender details not found", "tender_id": tender_id } # Format tender characteristics characteristics = [] for char in item.get("ihaleOzellikList", []): char_text = char.get("ihaleOzellik", "") # Clean up the characteristic text if "TENDER_DETAIL." in char_text: char_text = char_text.replace("TENDER_DETAIL.", "").replace("_", " ").title() characteristics.append(char_text) # Format basic tender info basic_info = item.get("ihaleBilgi", {}) # Format OKAS codes okas_codes = [] for okas in item.get("ihtiyacKalemiOkasList", []): okas_codes.append({ "code": okas.get("kodu"), "name": okas.get("adi"), "full_description": okas.get("koduAdi") }) # Format authority info authority = item.get("idare", {}) authority_info = { "id": authority.get("id"), "name": authority.get("adi"), "code1": authority.get("kod1"), "code2": authority.get("kod2"), "phone": authority.get("telefon"), "fax": authority.get("fax"), "parent_authority": authority.get("ustIdare"), "top_authority_code": authority.get("enUstIdareKod"), "top_authority_name": authority.get("enUstIdareAdi"), "province": authority.get("il", {}).get("adi"), "district": authority.get("ilce", {}).get("ilceAdi") } # Format process rules rules = item.get("islemlerKuralSeti", {}) process_rules = { "can_download_documents": rules.get("dokumanIndirmisMi", False), "has_submitted_bid": rules.get("teklifteBulunmusMu", False), "can_submit_bid": rules.get("teklifVerilebilirMi", False), "has_non_price_factors": rules.get("fiyatDisiUnsurVarMi", False), "contract_signed": rules.get("sozlesmeImzaliMi", False), "is_electronic": rules.get("eIhaleMi", False), "is_own_tender": rules.get("idareKendiIhaleMi", False), "electronic_auction": rules.get("eEksiltmeYapilacakMi", False) } # Initialize markdown converter for tender details HTML content markitdown = MarkItDown() # Format announcements list (basic info) with markdown conversion announcements = [] for announcement in item.get("ilanList", []): # Map announcement types announcement_type_map = { "1": "Ön İlan", "2": "İhale İlanı", "3": "İptal İlanı", "4": "Sonuç İlanı", "5": "Ön Yeterlik İlanı", "6": "Düzeltme İlanı" } announcement_type = announcement.get("ilanTip", "") announcement_type_desc = announcement_type_map.get(announcement_type, f"Type {announcement_type}") # Convert HTML content to markdown if available html_content = announcement.get("veriHtml", "") markdown_content = None if html_content: try: # Create BytesIO from HTML content html_bytes = BytesIO(html_content.encode('utf-8')) result = markitdown.convert_stream(html_bytes, file_extension=".html") markdown_content = result.text_content if result else None except Exception as e: print(f"Warning: Failed to convert HTML to markdown in tender details: {e}") markdown_content = None announcements.append({ "id": announcement.get("id"), "type": { "code": announcement_type, "description": announcement_type_desc }, "title": announcement.get("baslik"), "date": announcement.get("ilanTarihi"), "status": announcement.get("status"), "markdown_content": markdown_content, "content_preview": self._extract_text_preview(html_content) }) # Build comprehensive response result = { "tender_id": item.get("id"), "ikn": item.get("ikn"), "name": item.get("ihaleAdi"), "status": { "code": item.get("ihaleDurum"), "description": basic_info.get("ihaleDurumAciklama") }, "basic_info": { "is_electronic": item.get("eIhale", False), "method_code": item.get("ihaleUsul"), "method_description": basic_info.get("ihaleUsulAciklama"), "type_description": basic_info.get("ihaleTipiAciklama"), "scope_description": item.get("ihaleKapsamAciklama"), "tender_datetime": basic_info.get("ihaleTarihSaat"), "location": basic_info.get("isinYapilacagiYer"), "venue": basic_info.get("ihaleYeri"), "complaint_fee": basic_info.get("itirazenSikayetBasvuruBedeli"), "is_partial": item.get("kismiIhale", False) }, "characteristics": characteristics, "okas_codes": okas_codes, "authority": authority_info, "process_rules": process_rules, "announcements_summary": { "total_count": len(announcements), "announcements": announcements, "types_available": list(set(ann["type"]["description"] for ann in announcements)) }, "flags": { "is_authority_tender": item.get("ihaleniIdaresiMi", False), "is_without_announcement": item.get("ihaleIlansizMi", False), "is_invitation_only": item.get("ihaleyeDavetEdilenMi", False), "show_detail_documents": item.get("ihaleDetayDokumaniGorsunMu", False), "show_document_downloaders": item.get("dokumanIndirenlerGosterilsinMi", False) }, "document_count": item.get("dokumanSayisi", 0) } # Add cancellation info if tender is cancelled if basic_info.get("iptalTarihi"): result["cancellation_info"] = { "cancelled_date": basic_info.get("iptalTarihi"), "cancellation_reason": basic_info.get("iptalNedeni"), "cancellation_article": basic_info.get("iptalMadde") } return result except httpx.HTTPStatusError as e: return { "error": f"API request failed with status {e.response.status_code}", "message": str(e) } except Exception as e: return { "error": "Request failed - tender details", "message": str(e) }
  • ihale_mcp.py:21-29 (registration)
    MCP server initialization. Tool functions decorated with @mcp.tool are automatically registered here.
    mcp = FastMCP( name="ihale-mcp", instructions=""" This server provides access to Turkish government tender (ihale) data from EKAP v2 portal. Use the search_tenders tool to find tenders based on various criteria. The server supports filtering by text, tender type, region, dates, and other parameters. All tender information is in Turkish as it comes directly from the government portal. """ )
  • Global EKAPClient instance used by all EKAP-related tools including get_tender_details.
    ekap_client = EKAPClient()
  • Import of EKAPClient class containing the core API logic.
    from ihale_client import EKAPClient

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/saidsurucu/ihale-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server