Metadata-Version: 2.4
Name: kap-mcp
Version: 0.1.0
Summary: MCP server for KAP (Turkey's Public Disclosure Platform) - IFRS / BDDK / Insurance financials, disclosures, and company data for all BIST-listed companies
Author: Ata Bora Yalcin
License-Expression: MIT
Project-URL: Homepage, https://github.com/atayalcinb/KAP-MCP-TR
Project-URL: Repository, https://github.com/atayalcinb/KAP-MCP-TR
Project-URL: Issues, https://github.com/atayalcinb/KAP-MCP-TR/issues
Keywords: kap,bist,turkey,mcp,model-context-protocol,finance,ifrs,bddk,financial-statements,disclosures
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Natural Language :: Turkish
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastmcp>=3.2.3
Requires-Dist: httpx>=0.28.1
Requires-Dist: certifi
Requires-Dist: lxml>=6.0.4
Requires-Dist: openpyxl>=3.1.5
Requires-Dist: pandas>=3.0.2
Provides-Extra: dev
Requires-Dist: pytest>=8.3.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.24.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
Requires-Dist: respx>=0.21.1; extra == "dev"
Dynamic: license-file

# kap-mcp

[![MCP](https://img.shields.io/badge/MCP-Server-blue)](https://modelcontextprotocol.io)
[![Python](https://img.shields.io/badge/python-3.12%2B-blue)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

An MCP server for [KAP](https://kap.org.tr) — **Kamuyu Aydınlatma Platformu**, Turkey's Public Disclosure Platform. Gives AI agents structured access to financial statements, corporate disclosures, and company metadata for **all 605 BIST-listed companies**. No API key, no authentication.

> 🇹🇷 [Türkçe README aşağıda](#türkçe) · [Jump to Turkish section](#türkçe)

---

## What it does

- **Parses IFRS / BDDK / Insurance financial statements** directly from KAP's Excel filings into flat `{line_item: value_in_TL}` dicts.
- **100% parser coverage** of BIST-listed companies: 572 IFRS + 27 BDDK (banks, factoring, leasing, asset management) + 6 Insurance (SPK format).
- **Disclosures API**: search filings by company + date range, subject-filter (dividends, capital increases, M&A, etc.), fetch full disclosure bodies and attachment metadata.
- **Expected disclosures**: forward-looking filing calendar — know when Q1/Q2/Q3/FY reports are due.
- **Auto-routing**: parser is selected per company from an internal master (built from KAP's sector taxonomy).

## Coverage

| Parser family | Companies | Applies to |
|--|--|--|
| `ifrs_standard` | 572 | Industry, trade, holding, REITs (GYO), brokerage, retail — standard IFRS |
| `bddk` | 27 | Banks, factoring, leasing, consumer finance, asset management — BDDK TFRS9 format |
| `insurance` | 6 | Insurance companies — SPK insurance format |
| **Total** | **605** | All BIST pay piyasası companies |

Historical depth: **~2016 onwards** (earlier XBRL-era formats not yet supported).

## Installation

### Prerequisites

- **Python 3.12+** (3.13 / 3.14 also supported)
- **[uv](https://docs.astral.sh/uv/)** recommended (handles everything in an isolated env)
- Or plain `pip` if you prefer

Quick sanity check — without adding to any client:

```bash
uvx kap-mcp --help
```

---

### 1. Claude Desktop

Edit `claude_desktop_config.json`:
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "kap": {
      "command": "uvx",
      "args": ["kap-mcp"]
    }
  }
}
```

Restart Claude Desktop. The KAP tools appear under the tools icon.

---

### 2. Claude Code (CLI)

```bash
claude mcp add kap -- uvx kap-mcp
```

Or add to `~/.claude/settings.json` manually:

```json
{
  "mcpServers": {
    "kap": { "command": "uvx", "args": ["kap-mcp"] }
  }
}
```

---

### 3. Cursor

`Settings → MCP → Add new MCP server`, or edit `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "kap": {
      "command": "uvx",
      "args": ["kap-mcp"]
    }
  }
}
```

---

### 4. Windsurf

Edit `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "kap": {
      "command": "uvx",
      "args": ["kap-mcp"]
    }
  }
}
```

---

### 5. Zed

Edit `~/.config/zed/settings.json`:

```json
{
  "context_servers": {
    "kap": {
      "command": { "path": "uvx", "args": ["kap-mcp"] }
    }
  }
}
```

---

### 6. VS Code (with MCP-compatible extensions: Continue, Cline, etc.)

Most VS Code MCP extensions accept the same config format. Add to the extension's MCP settings:

```json
{
  "mcpServers": {
    "kap": { "command": "uvx", "args": ["kap-mcp"] }
  }
}
```

Check your extension's docs for the exact config path.

---

### 7. Any other MCP client

The server speaks standard MCP over stdio. Any compliant client works — just point it at the command:

```
command: uvx
args:    ["kap-mcp"]
```

If your client needs the full module path instead of the entry point:

```
command: python
args:    ["-m", "kap"]
```

---

### Running standalone / from source

```bash
# via uv (no install)
uvx kap-mcp

# clone + editable install
git clone https://github.com/atayalcinb/KAP-MCP-TR
cd KAP-MCP-TR
uv pip install -e .
python -m kap
```

---

### As a Python library (no MCP)

If you only want the parsers — no server, no MCP — just use them as Python functions:

```bash
pip install kap-mcp
```

```python
from kap.parser import parse_financial_bytes           # IFRS
from kap.parser_bddk import parse_bddk_bytes           # Banks / BDDK
from kap.parser_insurance import parse_insurance_bytes # Insurance

with open("downloaded_from_kap.xlsx", "rb") as f:
    parsed = parse_financial_bytes(f.read())
print(parsed["balance_sheet"])
```

## Tools

### 🔍 Search & lookup

| Tool | Description |
|--|--|
| `search_company(search_term)` | Find a company by ticker or name. Returns `mkkMemberOid` + title + sector. Fuzzy match on 605-entry master; falls back to KAP API for funds/non-BIST entities. |
| `smart_search(keyword)` | Broader KAP search across companies + funds. |

### 📊 Financial statements

| Tool | Description |
|--|--|
| `check_financial_availability(oid, year, period)` | Check if a filing exists — empty list = not filed yet. |
| `get_financials(oid, year, period)` | Download + parse. Auto-selects IFRS / BDDK / Insurance parser by `parser_family`. |
| `get_company_financials(ticker, year, period, years, periods, mode)` | **Primary convenience tool** — ticker → parsed statements in one call. Single or multi-period (paired `years`+`periods` lists). `mode="summary"` returns a curated ~80-line IFRS view with a `computed` section (EBIT, EBITDA, Net Finansal Borç, FCF). |
| `get_audit_report_info(ticker, year, period)` | Denetçi raporu metadata (TR + ENG availability, filenames, sizes). |
| `get_financial_ratios(ticker, year, period, years, periods)` | Financial ratios — ratio set auto-selected by `parser_family`: IFRS (21 ratios: liquidity / efficiency / leverage / profitability), BDDK (11 bank ratios: profitability / asset_quality / balance_structure — ROE, ROA, NIM, Cost-to-Income, Cost of Risk, Loan-to-Deposit, Leverage, etc.), insurance (13 ratios: technical_nonlife / technical_life / portfolio / investment_profitability — Loss / Expense / Combined Ratio, Technical Margin, Retention, Claims, Reserve, Investment Yield). Single or multi-period (paired lists). Ratios that require data not in KAP filings (NPL, CASA, CAR/SYR for banks; Premium Growth, Solvency for insurance) surface as `None` with reasons in `meta.not_available_in_kap_filing`. |

### 📰 Disclosures (bildirimler)

| Tool | Description |
|--|--|
| `search_disclosures(oid, from_date, to_date, disclosure_class, subject_oids)` | Company-scoped disclosures in a date window. Supports topic filtering. |
| `get_latest_disclosures()` | Latest ~10 disclosures across all BIST companies. |
| `get_disclosure_detail(disclosure_index)` | Full disclosure body + attachment list. |
| `get_disclosure_pdf_info(disclosure_index)` | PDF availability + size (metadata only). |
| `get_disclosure_subjects(disclosure_class)` | List of `subjectOid` values for topic filtering (e.g. dividends only). |
| `get_expected_disclosures(oid, from_date, to_date)` | Forward-looking filing calendar — when Q1/Q2/Q3/FY are due. |

### 🏭 Sector & taxonomy

Offline lookups over the 605-company master — no network calls.

| Tool | Description |
|--|--|
| `list_sector_groups()` | 15 KAP main sectors with company counts + parser_family breakdown. |
| `list_alt_sectors(sector_group?)` | 48 sub-sectors, optionally filtered by a main sector. |
| `list_companies_by_sector(sector_group, alt_sektor?)` | All BIST companies in a sector → ticker, OID, title, parser_family. |
| `list_parser_families()` | The 3 parser regimes (IFRS / BDDK / insurance) + which sectors feed each. |

## Quick examples

**Parse a full-year filing:**
```
get_company_financials("MGROS", 2024, 4)
```
```json
{
  "ticker": "MGROS",
  "company": "MİGROS TİCARET A.Ş.",
  "balance_sheet": {"Toplam Varlıklar": 94783000000, ...},
  "income_statement": {"Hasılat": 218401000000, ...},
  "cash_flow": {...},
  "sheets_found": ["balance_sheet", "income_statement", "cash_flow"],
  "parser_family": "ifrs_standard"
}
```

**Find all dividend announcements for a company in 2025:**
```
search_company("AKBNK")
  → oid

get_disclosure_subjects("ODA")
  → find subjectOid for "Kar Payı Dağıtım İşlemlerine İlişkin Bildirim"

search_disclosures(oid, "2025-01-01", "2025-12-31",
                   disclosure_class="ODA",
                   subject_oids=[<dividend subject oid>])
```

**Check when BIMAS will file its Q1 2026:**
```
search_company("BIMAS") → oid
get_expected_disclosures(oid, "2026-01-01", "2026-12-31")
```

**Fetch every bank's 2024 FY filing:**
```
list_companies_by_sector("MALİ KURULUŞLAR", "BANKALAR")
  → 13 tickers (all bddk parser_family)

for ticker in tickers:
    get_company_financials(ticker, 2024, 4)
```

**Get BIMAS's financial ratios (2024 FY):**
```
get_financial_ratios("BIMAS", 2024, 4)
```
```json
{
  "liquidity":     {"current_ratio": 0.99, "quick_ratio": 0.49, ...},
  "efficiency":    {"inventory_days": 41.1, "cash_conversion_cycle_days": -20.3, ...},
  "leverage":      {"debt_to_assets": 0.50, "net_financial_debt_to_ebitda": 1.52, ...},
  "profitability": {"gross_margin_pct": 17.48, "ebitda_margin_pct": 4.33,
                    "roe_pct": 15.7, "roic_pct": 2.45, ...},
  "meta": {"period_days": 365, "effective_tax_rate": 0.28,
           "line_items_missing": [], ...}
}
```

### Multi-period & summary view

Instead of calling `get_company_financials` once per period and stitching the JSONs, pass paired `years` + `periods` lists. Output pivots every line item into a period time-series.

**Last 5 FY in one call (full parser output):**
```
get_company_financials("MGROS", years=[2024,2023,2022,2021,2020], periods=[4,4,4,4,4])
```
```json
{
  "ticker": "MGROS",
  "periods_requested": [
    {"year":2024,"period":4,"key":"2024-FY"}, ...
  ],
  "balance_sheet": {
    "TOPLAM VARLIKLAR": {"2024-FY": 150058883000, "2023-FY": 92129481000, ...},
    "Nakit ve Nakit Benzerleri": {...}, ...
  },
  "income_statement": {"Hasılat": {"2024-FY": 293779664000, ...}, ...},
  "cash_flow": {...},
  "meta": {
    "mode": "full", "successful_periods": 5, "failed_periods": [],
    "parser_family": "ifrs_standard",
    "konsolide_by_period": {"2024-FY": true, ...},
    "cash_flow_method_by_period": {"2024-FY": "dolayli", ...}
  }
}
```

**Mixed periods (e.g. compare 2024-9M to 2023-H1 to 2021-FY):**
```
get_company_financials("MGROS", years=[2024,2023,2021], periods=[3,2,4])
```
Period keys become `2024-9M`, `2023-H1`, `2021-FY`. Duplicate `(year, period)` pairs return an error.

**Curated ~80-line summary with computed metrics (IFRS-only):**
```
get_company_financials("THYAO", years=[2024,2023,2022,2021], periods=[4,4,4,4], mode="summary")
```
Returns only the 80-item curated view plus a `computed` section:
```json
{
  "balance_sheet":    { ... 48 curated items ... },
  "income_statement": { ... 24 curated items ... },
  "cash_flow":        { ... 6 items: OCF, ICF, Financing NA, CapEx, D&A, Ending Cash ... },
  "computed": {
    "EBIT":                        {"2024-FY": 80393000000, ...},
    "EBITDA":                      {"2024-FY": 152699000000, ...},
    "Net Finansal Borç":           {"2024-FY": 393947000000, ...},
    "Serbest Nakit Akışı (FCF)":   {"2024-FY": 91617000000, ...}
  }
}
```
For banks (BDDK) and insurance, `mode="summary"` returns a structured error — use `mode="full"` (default). Single-period calls (`year`+`period`) keep their original behavior.

**Ratio trend across 4 years (IFRS):**
```
get_financial_ratios("MGROS", years=[2024,2023,2022,2021], periods=[4,4,4,4])
```
Each ratio becomes a time-series. Group names depend on `parser_family`:
```json
{
  "profitability": {
    "roe_pct":          {"2024-FY": 11.4,  "2023-FY": 24.56, "2022-FY": 63.08, "2021-FY": 66.95},
    "ebitda_margin_pct":{"2024-FY": 0.17, ...}
  },
  "leverage":     {"net_financial_debt_to_equity": {...}},
  "meta": {
    "mode": "multi",
    "parser_family": "ifrs_standard",
    "period_days_by_period": {"2024-FY": 365, "2023-FY": 365, ...},
    "effective_tax_rate_by_period": {...}
  }
}
```
Turnover-days automatically adjust per period (90/180/270/365) — mixing 9M and FY in one call is safe.

**Bank ratios (BDDK — different ratio set auto-selected):**
```
get_financial_ratios("GARAN", years=[2024,2023,2022], periods=[4,4,4])
```
```json
{
  "profitability": {
    "roe_pct":             {"2024-FY": 27.81, "2023-FY": 35.38, "2022-FY": 38.21},
    "roa_pct":             {"2024-FY": 3.07, ...},
    "nim_pct":             {"2024-FY": 4.47, "2023-FY": 4.17, "2022-FY": 7.13},
    "cost_to_income_pct":  {"2024-FY": 37.14, ...},
    "fee_income_to_gross_pct": {...},
    "net_interest_to_gross_pct": {...}
  },
  "asset_quality": {
    "cost_of_risk_pct":    {"2024-FY": 3.27, ...},
    "provisions_burden_pct": {...},
    "npl_ratio_pct":       {"2024-FY": null, ...}   // see meta.not_available_in_kap_filing
  },
  "balance_structure": {
    "loan_to_deposit_pct": {"2024-FY": 82.45, ...},
    "loan_to_assets_pct":  {...},
    "leverage_multiple":   {"2024-FY": 9.06, ...},
    "casa_ratio_pct":      {"2024-FY": null, ...},
    "capital_adequacy_ratio_pct": {"2024-FY": null, ...}
  },
  "meta": {
    "parser_family": "bddk",
    "interest_earning_assets_tl_by_period": {"2024-FY": 2822557620000, ...},
    "not_available_in_kap_filing": {
      "npl_ratio_pct":              "Stage-3 (brüt takipteki krediler) satırı KAP ana tablosunda yok...",
      "casa_ratio_pct":             "Mevduat tek toplam satır; vadesiz/vadeli ayrımı KAP'ta yok...",
      "capital_adequacy_ratio_pct": "Risk Ağırlıklı Varlıklar KAP'ta yok; SYR BDDK raporlarında..."
    }
  }
}
```

**Insurance ratios (segment-aware — non-life specific ratios gate on non-life activity):**
```
get_financial_ratios("ANSGR", year=2024, period=4)   # non-life insurer
```
```json
{
  "technical_nonlife": {
    "loss_ratio_pct":        49.76,
    "expense_ratio_pct":     51.71,
    "combined_ratio_pct":    101.47,   // > 100 = underwriting loss
    "technical_margin_pct":  25.50
  },
  "technical_life":           {"technical_margin_pct": null},   // not active
  "portfolio": {
    "retention_ratio_pct": 75.11,
    "claims_ratio_pct":    49.76,
    "reserve_ratio_pct":   122.20
  },
  "investment_profitability": {
    "investment_margin_tl": 692343959,
    "investment_yield_pct": 1.85,
    "net_profit_margin_pct": 28.05,
    "roa_pct": 12.93,
    "roe_pct": 48.63,
    "premium_growth_pct":   null,   // needs prior period — caller derives from multi-period pivot
    "solvency_ratio_pct":   null    // required capital is a regulator output
  },
  "meta": {
    "parser_family": "insurance",
    "active_segments": ["nonlife"],
    ...
  }
}
```
Dual-segment insurers (e.g. AGESA) populate both `technical_nonlife` and `technical_life` groups. Pure-life insurers return `None` in the non-life group.

## Tests

Offline test suite covers all three parser families and both user-facing
tools (`get_company_financials`, `get_financial_ratios`).

```bash
uv sync --extra dev          # install pytest, pytest-cov, respx
uv run pytest                # 120 tests, ~1 minute
uv run pytest --cov          # with coverage (current: 70% overall,
                             # 87–96% on the ratio modules)
```

Fixtures live in `tests/fixtures/` as raw KAP `.xlsx` files (~12 MB
total) for **MGROS, THYAO, TUPRS, EREGL, EKGYO, ISMEN** (IFRS), **GARAN,
TSKB, GARFA** (BDDK) and **AGESA, AKGRT** (insurance) — chosen for
sector and edge-case coverage (development bank with no deposit base,
factoring filing without deposits or loans, mixed-segment vs nonlife-only
insurer). Tests run fully offline.

To refresh or regenerate fixtures from KAP:
```bash
uv run python scripts/snapshot_fixtures.py
```

CI runs on Python 3.12 and 3.13 via `.github/workflows/test.yml` on
every push and pull request.

## Configuration

| Env var | Default | Description |
|--|--|--|
| `KAP_SSL_VERIFY` | `1` | Set to `0` to disable SSL verification (dev / corporate proxy only) |

## Data notes

- **Periods**: `1=Q1` (3M), `2=H1` (6M), `3=9M` (9M), `4=FY` (annual). KAP's own encoding.
- **Values**: Normalized to **full Turkish Lira** from the native `bin TL` / `milyon TL` units in the source.
- **Language**: Turkish line item names preserved (`Hasılat`, `Toplam Varlıklar`, `Dönem Net Kârı`…). Do not translate in code — AI can reason over them directly.
- **Consolidated vs. solo**: If a filing ships both, the consolidated statement is picked; otherwise whatever is available.
- **Cash flow method**: For IFRS, auto-detects `dolaylı` (indirect) / `doğrudan` (direct) / `bilinmiyor`.
- **Source**: All data comes from [kap.org.tr](https://kap.org.tr) — public and free. No auth, no rate-limit keys. Please be courteous.

## Known limitations

- ~1–2% of KAP Excel filings are malformed; parser will raise — retry usually works.
- BDDK `equity_changes` and insurance `equity_changes` tables are skipped (2D structure doesn't fit a flat dict).
- For 10 banks using BDDK format, `Dönem Net Kârı` reflects parent-only share (minority interest is on a separate line, not yet split in parser output).
- Pre-2016 filings (pre-XBRL era) untested.

## License

[MIT](LICENSE). Data is public and belongs to KAP / BIST / the companies themselves — this tool only structures it.

## Attribution

This project is not affiliated with KAP, BIST, SPK, or BDDK. It consumes publicly available endpoints from kap.org.tr.

---

## Türkçe

Türkiye'nin [Kamuyu Aydınlatma Platformu](https://kap.org.tr) (KAP) için bir **MCP sunucusu**. AI ajanlarının **BIST'e kote 605 şirketin tamamına** ait finansal tablolara, özel durum açıklamalarına ve şirket bilgilerine yapılandırılmış şekilde erişmesini sağlar. API anahtarı veya kimlik doğrulama gerektirmez.

### Ne yapar

- KAP'tan gelen Excel finansal tablolarını **IFRS / BDDK / Sigorta** formatlarına göre parse eder; sonuç düz `{kalem: TL_değeri}` sözlüğüdür.
- **%100 parser kapsaması**: 572 IFRS + 27 BDDK (banka, faktoring, leasing, varlık yönetimi) + 6 Sigorta şirketi.
- **Bildirimler**: şirket + tarih aralığı bazında arama, konuya göre filtreleme (temettü, sermaye artırımı, birleşme vb.), tam bildirim metni ve ek dosyaların metadata'sı.
- **Beklenen bildirimler**: Q1/Q2/Q3/FY raporlarının KAP'a ne zaman yükleneceği.
- **Otomatik yönlendirme**: her şirketin parser ailesi master dosyadan belirlenir (KAP'ın resmi sektör taksonomisine dayalı).

### Kapsam

| Parser ailesi | Şirket | Kim kullanıyor |
|--|--|--|
| `ifrs_standard` | 572 | Sanayi, ticaret, holding, GYO, aracı kurum — standart IFRS |
| `bddk` | 27 | Banka, faktoring, leasing, finansman, varlık yönetimi — BDDK TFRS9 |
| `insurance` | 6 | Sigorta — SPK sigorta formatı |
| **Toplam** | **605** | Tüm BIST pay piyasası şirketleri |

Tarihsel derinlik: **~2016 ve sonrası** (öncesi XBRL dönemi henüz desteklenmiyor).

### Kurulum

**Gereksinimler**
- Python 3.12+ (3.13 / 3.14 de destekli)
- [uv](https://docs.astral.sh/uv/) tavsiye edilir (otomatik izole env)
- veya `pip`

Hızlı test (hiçbir client'e eklemeden):
```bash
uvx kap-mcp --help
```

**Tüm MCP client'ları için ortak config** (aynı JSON, farklı dosya yolu):
```json
{
  "mcpServers": {
    "kap": {
      "command": "uvx",
      "args": ["kap-mcp"]
    }
  }
}
```

Yapıştırılacak dosya:

| Client | Dosya yolu |
|--|--|
| **Claude Desktop** (macOS) | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| **Claude Desktop** (Windows) | `%APPDATA%\Claude\claude_desktop_config.json` |
| **Claude Desktop** (Linux) | `~/.config/Claude/claude_desktop_config.json` |
| **Claude Code (CLI)** | `claude mcp add kap -- uvx kap-mcp` ya da `~/.claude/settings.json` |
| **Cursor** | `~/.cursor/mcp.json` veya Settings → MCP |
| **Windsurf** | `~/.codeium/windsurf/mcp_config.json` |
| **Zed** | `~/.config/zed/settings.json` (anahtar: `context_servers`) |
| **VS Code** (Continue/Cline) | İlgili eklentinin MCP ayar dosyası |
| **Diğer** | stdio üzerinden standart MCP — `command: uvx`, `args: ["kap-mcp"]` |

**Kaynak koddan çalıştırmak:**
```bash
git clone https://github.com/atayalcinb/KAP-MCP-TR
cd KAP-MCP-TR
uv pip install -e .
python -m kap
```

**Sadece parser (MCP olmadan) — Python kütüphanesi olarak:**
```bash
pip install kap-mcp
```
```python
from kap.parser import parse_financial_bytes           # IFRS
from kap.parser_bddk import parse_bddk_bytes           # Banka / BDDK
from kap.parser_insurance import parse_insurance_bytes # Sigorta
```

### Araçlar (tools)

**Arama:** `search_company`, `smart_search`

**Finansallar:** `check_financial_availability`, `get_financials`, `get_company_financials` (tek dönem veya çoklu dönem — `years`+`periods` eşlemeli listeler; `mode="summary"` IFRS için ~80 kalemlik derlenmiş görünüm + `computed` alanı), `get_audit_report_info`, `get_financial_ratios` (üç aile: **IFRS** 21 oran [likidite/faaliyet/borçluluk/karlılık], **BDDK banka** 11 oran [ROE, ROA, NIM, Cost-to-Income, Cost of Risk, Loan-to-Deposit, Kaldıraç, vb.], **sigorta** 13 oran [Loss/Expense/Combined Ratio, Teknik Marj, Retention, Claims, Reserve, Investment Yield, segment-farkındalıklı]; parser_family otomatik route eder; tek veya çoklu dönem; KAP'ta veri olmayan oranlar (NPL/CASA/CAR, Premium Growth, Solvency) `None` döner `meta.not_available_in_kap_filing`'de sebep açıklamasıyla)

**Bildirimler:** `search_disclosures`, `get_latest_disclosures`, `get_disclosure_detail`, `get_disclosure_pdf_info`, `get_disclosure_subjects`, `get_expected_disclosures`

**Sektör & taksonomi (offline — network yok):** `list_sector_groups`, `list_alt_sectors`, `list_companies_by_sector`, `list_parser_families`

Yukarıdaki İngilizce tabloda her aracın detaylı açıklaması var.

### Hızlı örnekler

**2024 FY Migros bilançosu:**
```
get_company_financials("MGROS", 2024, 4)
```

**AKBANK'ın 2025 temettü açıklamaları:**
```
search_company("AKBNK") → oid
get_disclosure_subjects("ODA") → "Kar Payı Dağıtım" subject oid
search_disclosures(oid, "2025-01-01", "2025-12-31",
                   disclosure_class="ODA",
                   subject_oids=[<temettü oid>])
```

**Migros'un son 5 yılı tek çağrıda (tam parser çıktısı):**
```
get_company_financials("MGROS", years=[2024,2023,2022,2021,2020], periods=[4,4,4,4,4])
```
Çıktıda her kalem dönem anahtarına göre pivotlanır:
```json
{
  "balance_sheet": {
    "TOPLAM VARLIKLAR": {"2024-FY": 150058883000, "2023-FY": 92129481000, ...}
  },
  "income_statement": {"Hasılat": {"2024-FY": 293779664000, ...}},
  "meta": {"mode":"full","successful_periods": 5, "failed_periods": []}
}
```

**Karışık dönem karşılaştırma (örn. 2024-9M vs 2023-H1 vs 2021-FY):**
```
get_company_financials("MGROS", years=[2024,2023,2021], periods=[3,2,4])
```
Dönem anahtarları: `2024-9M`, `2023-H1`, `2021-FY`. Duplicate (year, period) çifti error döndürür.

**Derlenmiş özet görünüm + computed alanlar (IFRS şirketleri için):**
```
get_company_financials("THYAO", years=[2024,2023,2022,2021], periods=[4,4,4,4], mode="summary")
```
~80 kalem + `computed`:
```json
{
  "balance_sheet":    { ... 48 derlenmiş kalem ... },
  "income_statement": { ... 24 derlenmiş kalem ... },
  "cash_flow":        { ... 6 kalem: OCF / ICF / Finansman / CapEx / Amortisman / Dönem Sonu Nakit ... },
  "computed": {
    "EBIT":                      {"2024-FY": 80393000000, ...},
    "EBITDA":                    {"2024-FY": 152699000000, ...},
    "Net Finansal Borç":         {"2024-FY": 393947000000, ...},
    "Serbest Nakit Akışı (FCF)": {"2024-FY": 91617000000, ...}
  }
}
```
- **IFRS-only:** BDDK (banka) ve sigorta şirketlerinde `mode="summary"` structured error döner — `mode="full"` (default) kullanın.
- **Net Finansal Borç** = KV Borçlanmalar + UV'nin KV Kısımları + UV Borçlanmalar − Nakit.
- **Serbest Nakit Akışı (FCF)** = OCF + CapEx (tablo işareti korunur).
- Tek dönem çağrı (`year`+`period`) eski davranışını aynen korur.

**4 yıllık oran trendi (IFRS):**
```
get_financial_ratios("MGROS", years=[2024,2023,2022,2021], periods=[4,4,4,4])
```
Her oran zaman serisine dönüşür; turnover-days dönem başına otomatik ayarlanır (90/180/270/365):
```json
{
  "profitability": {"roe_pct": {"2024-FY": 11.4, "2023-FY": 24.56, "2022-FY": 63.08, "2021-FY": 66.95}},
  "leverage": {"net_financial_debt_to_equity": {...}}
}
```

**Banka oranları (BDDK — farklı oran seti otomatik seçilir):**
```
get_financial_ratios("GARAN", years=[2024,2023,2022], periods=[4,4,4])
```
```json
{
  "profitability": {
    "roe_pct":  {"2024-FY": 27.81, "2023-FY": 35.38, "2022-FY": 38.21},
    "nim_pct":  {"2024-FY": 4.47,  "2023-FY": 4.17,  "2022-FY": 7.13}
  },
  "asset_quality": {
    "cost_of_risk_pct": {"2024-FY": 3.27, ...},
    "npl_ratio_pct":    {"2024-FY": null}   // bkz. meta.not_available_in_kap_filing
  },
  "balance_structure": {
    "loan_to_deposit_pct": {"2024-FY": 82.45, ...},
    "leverage_multiple":   {"2024-FY": 9.06, ...},
    "casa_ratio_pct":             {"2024-FY": null},
    "capital_adequacy_ratio_pct": {"2024-FY": null}
  },
  "meta": {
    "parser_family": "bddk",
    "not_available_in_kap_filing": {
      "npl_ratio_pct":              "Stage-3 takipteki krediler KAP ana tablosunda yok — banka notları.",
      "casa_ratio_pct":             "Vadesiz/vadeli mevduat kırılımı KAP'ta yok.",
      "capital_adequacy_ratio_pct": "Risk Ağırlıklı Varlıklar KAP'ta yok — SYR BDDK raporlarında."
    }
  }
}
```

**Sigorta oranları (segment-farkındalıklı):**
```
get_financial_ratios("ANSGR", year=2024, period=4)    # hayat dışı şirket
```
```json
{
  "technical_nonlife": {
    "loss_ratio_pct":       49.76,
    "expense_ratio_pct":    51.71,
    "combined_ratio_pct":   101.47,
    "technical_margin_pct": 25.50
  },
  "technical_life":        {"technical_margin_pct": null},
  "portfolio":             {"retention_ratio_pct": 75.11, "claims_ratio_pct": 49.76, "reserve_ratio_pct": 122.20},
  "investment_profitability": {
    "roe_pct": 48.63, "roa_pct": 12.93, "net_profit_margin_pct": 28.05,
    "investment_yield_pct": 1.85,
    "premium_growth_pct": null,  // önceki dönem gerekir — multi-period'da caller türetir
    "solvency_ratio_pct": null   // gerekli sermaye regülatör hesabı
  },
  "meta": {"parser_family": "insurance", "active_segments": ["nonlife"]}
}
```
Hem hayat hem hayat-dışı aktif olan şirketlerde (AGESA gibi) iki teknik grup da dolu döner. Sadece hayat şirketleri için `technical_nonlife` alanlarının hepsi `None`.

### Veri notları

- **Dönemler**: `1=Q1` (3 ay), `2=H1` (6 ay), `3=9M` (9 ay), `4=FY` (yıllık) — KAP'ın kendi kodlaması.
- **Değerler**: Kaynak dosyadaki `bin TL` / `milyon TL` birimlerinden **tam TL**'ye normalize edilir.
- **Dil**: Türkçe kalem isimleri korunur (`Hasılat`, `Toplam Varlıklar`, `Dönem Net Kârı`…). Kodda çevirmeyin; AI zaten anlıyor.
- **Konsolide vs. solo**: Bir filing'de ikisi de varsa konsolide tercih edilir.
- **Nakit akım**: IFRS için `dolaylı` / `doğrudan` / `bilinmiyor` otomatik tespit edilir.
- **Kaynak**: Tüm veriler [kap.org.tr](https://kap.org.tr) — kamuya açık ve ücretsiz.

### Bilinen sınırlamalar

- KAP'ta ~%1-2 oranında bozuk Excel dosyası var — parser hata atar, retry ile çözülür.
- `equity_changes` (özkaynak değişim) tabloları şimdilik skip ediliyor (2D yapı flat dict'e uymuyor).
- 2016 öncesi dosyalar test edilmedi.

### Lisans

[MIT](LICENSE). Veriler KAP / BIST / şirketlerin kendisine aittir — bu araç sadece yapılandırır.

### Atıf

Bu proje KAP, BIST, SPK veya BDDK ile bağlı değildir. kap.org.tr'nin kamuya açık endpoint'lerini kullanır.
