Turkish public-tender award intelligence: who won, for how much, at what discount, against how many bidders. Exposes analytics and parsing tools for EKAP tender data.
ihalent provides 7 tools with complete input schemas and descriptions. Naming follows verb_noun convention (tool_overview, tool_firm, tool_discounts, tool_concentration, tool_flags, tool_parse_notice, tool_ingest_bundle). Descriptions are substantive (100-250 chars), explaining WHAT each tool does and WHEN to use it. However, parameter descriptions lack actionable constraints (e.g., 'by' in tool_discounts accepts 'authority', 'province', or 'tender_type' but this is stated in the description, not as an enum). Output schemas are not explicitly documented in the source, we infer structure from .to_dict() calls but cannot verify field names, types, or pagination. Error handling is minimal: tool_parse_notice returns {'error': str(exc)} but does not guide recovery. No tool annotations (readOnlyHint/destructiveHint) despite tool_ingest_bundle being a WRITE operation. Composition is sound, each tool has one responsibility and returns data suitable for chaining (e.g., firm_profile returns structured dicts). Overall: solid definitions with room for schema documentation and error guidance.
Winner concentration (HHI) over the dataset, or a slice of it by authority or province. Where single-bid share measures competition within a tender, this measures it across tenders: are the same few firms winning everything? Returns the HHI (0..1 over win counts), the leading firms, and the coverage.
Discount (kırım) distribution grouped by 'authority', 'province' or 'tender_type'.
Profile one company across the dataset: wins, total value, discount, where it wins. Spelling variants of the same company fold together.
Per-award procurement red flags: a single valid bid, a contract at or above the public estimate, a missing estimate, or a tender many firms took documents for but almost none bid on. None is proof; each is a reason to open the file. Awards raising the most flags (and the most money) come first.
Structure collected ihale-mcp/EKAP output into awards and append them to the dataset file. Returns how many awards with result notices were written.
Output schemas not documented. Tools return .to_dict() but field names, types, and structure are not visible in source. LLMs cannot plan downstream calls or extract specific fields reliably.
Parameter 'by' in tool_discounts accepts only 3 values ('authority', 'province', 'tender_type') but is defined as a free-form string. Should be an enum to prevent hallucinated values.
tool_ingest_bundle is a WRITE operation (appends to dataset file) but lacks destructiveHint annotation and no confirmation/dry-run pattern. Agents cannot distinguish safe reads from state-modifying calls.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 56 | 2026-07-28+ | v2 |
Summary of a dataset: awarded value, discount, competition, and data gaps.
Parse a single result-notice (Sonuç İlanı) markdown into a structured award.
Error handling is minimal. tool_parse_notice returns {'error': str(exc)} but does not guide recovery. Other tools do not document failure modes or recovery steps.
Parameter 'awards_path' is optional across all tools and defaults to IHALENT_AWARDS env var. If env var is missing, tools raise ValueError. Error message is clear but tools do not offer alternatives (e.g., 'Call tool_overview without awards_path to introspect available datasets').