tabii-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ id-token: write # required for PyPI trusted publishing (OIDC)
12
+ contents: read
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+ - run: pip install build
19
+ - run: python -m build
20
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,95 @@
1
+ name: Publish to MCP Registry
2
+
3
+ # Official MCP Registry (registry.modelcontextprotocol.io) via GitHub OIDC.
4
+ # No secret, no interactive login: the runner's OIDC token proves ownership
5
+ # of the io.github.mohammad-abbasi-sh/* namespace.
6
+ # Refs: https://github.com/modelcontextprotocol/registry
7
+
8
+ on:
9
+ push:
10
+ tags: ["v*"]
11
+ workflow_dispatch:
12
+
13
+ jobs:
14
+ publish:
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ id-token: write # required for OIDC -> MCP Registry
18
+ contents: read
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - name: Sync server.json version to tag
23
+ # Only sync when running on a version tag (v*). On workflow_dispatch
24
+ # (ref = refs/heads/main) keep the version committed in server.json.
25
+ run: |
26
+ VER=""
27
+ if [[ "$GITHUB_REF" == refs/tags/* ]]; then
28
+ TAG="${GITHUB_REF#refs/tags/}"
29
+ VER="${TAG#v}"
30
+ fi
31
+ if [ -n "$VER" ]; then
32
+ python3 - "$VER" << 'EOF'
33
+ import json, sys
34
+ ver = sys.argv[1]
35
+ d = json.load(open('server.json'))
36
+ d['version'] = ver
37
+ for pkg in d.get('packages', []):
38
+ pkg['version'] = ver
39
+ json.dump(d, open('server.json', 'w'), indent=2, ensure_ascii=False)
40
+ print('server.json version ->', ver)
41
+ EOF
42
+ else
43
+ echo "No version tag ($GITHUB_REF); keeping server.json version as-is"
44
+ fi
45
+
46
+ - name: Wait for PyPI
47
+ # The registry validates that the PyPI package + version exists,
48
+ # but the PyPI publish workflow runs in parallel with this one.
49
+ # Poll until the version appears instead of racing it: a 400 here
50
+ # used to fail silently under continue-on-error and left 40/43
51
+ # servers unlisted in the registry (2026-11-11).
52
+ run: |
53
+ python3 - << 'EOF'
54
+ import json, sys, time, urllib.request, urllib.error
55
+ d = json.load(open('server.json'))
56
+ pkg = d['packages'][0]
57
+ name = pkg.get('identifier') or pkg.get('name')
58
+ ver = pkg['version']
59
+ if not name:
60
+ print('ERROR: no package identifier/name in server.json')
61
+ sys.exit(1)
62
+ url = f'https://pypi.org/pypi/{name}/json'
63
+ for attempt in range(1, 21):
64
+ try:
65
+ with urllib.request.urlopen(url, timeout=30) as r:
66
+ data = json.load(r)
67
+ if ver in data.get('releases', {}):
68
+ print(f'PyPI {name}=={ver} is live (attempt {attempt})')
69
+ sys.exit(0)
70
+ except urllib.error.HTTPError as e:
71
+ print(f'attempt {attempt}: PyPI returned {e.code}')
72
+ except Exception as e:
73
+ print(f'attempt {attempt}: {e}')
74
+ print(f'attempt {attempt}: {name}=={ver} not on PyPI yet, waiting 30s...')
75
+ time.sleep(30)
76
+ print(f'ERROR: {name}=={ver} did not appear on PyPI after 10 minutes')
77
+ sys.exit(1)
78
+ EOF
79
+
80
+ - name: Install mcp-publisher
81
+ run: |
82
+ curl -sL "https://github.com/modelcontextprotocol/registry/releases/download/v1.8.7/mcp-publisher_linux_amd64.tar.gz" -o /tmp/mcp-publisher.tar.gz
83
+ tar -xzf /tmp/mcp-publisher.tar.gz -C /tmp
84
+ sudo mv /tmp/mcp-publisher /usr/local/bin/mcp-publisher
85
+ mcp-publisher --version
86
+
87
+ - name: Validate server.json
88
+ run: mcp-publisher validate server.json
89
+
90
+ - name: Publish to MCP Registry (OIDC)
91
+ # Failures must fail the run visibly: a silent publish failure
92
+ # once left 40/43 servers unlisted in the registry (2026-11-11).
93
+ run: |
94
+ mcp-publisher login github-oidc
95
+ mcp-publisher publish server.json
@@ -0,0 +1,21 @@
1
+ name: Daily live smoke
2
+
3
+ # One fixed probe per day: catches fingerprint rot / bot-wall changes
4
+ # before users hit them. Fails visibly on 403/timeout.
5
+ on:
6
+ schedule:
7
+ - cron: "0 6 * * *"
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ smoke:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+ - name: Install
19
+ run: pip install -e .
20
+ - name: Smoke probe
21
+ run: python tests/smoke_live.py
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mohammad Abbasi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,91 @@
1
+ Metadata-Version: 2.5
2
+ Name: tabii-mcp
3
+ Version: 0.1.0
4
+ Summary: Unofficial read-only MCP server for tabii.com (TRT streaming): catalog search, show details, live channels, people
5
+ Author: Mohammad Abbasi
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: curl-cffi<1.0,>=0.7
10
+ Requires-Dist: mcp<2
11
+ Description-Content-Type: text/markdown
12
+
13
+ # tabii-mcp 🇹🇷
14
+
15
+ mcp-name: io.github.mohammad-abbasi-sh/tabii-mcp
16
+
17
+ Unofficial **read-only** MCP server for tabii.com, TRT's streaming platform (launched 2023, 11M+ subscribers) — Turkish series, movies, documentaries, kids content and 15 live TRT channels. Catalog search by original Turkish title, full show details (seasons, episodes, cast, languages), live-channel HLS stream URLs, and cast/crew filmographies.
18
+
19
+ > Built by Mohammad Abbasi as part of the "Turkey MCP factory" (Sepehr-style pipeline). Not affiliated with tabii.com or TRT.
20
+
21
+ ## For AI agents
22
+
23
+ Add to your MCP client config (stdio):
24
+
25
+ ```json
26
+ {
27
+ "mcpServers": {
28
+ "tabii": {
29
+ "command": "uvx",
30
+ "args": ["tabii-mcp==0.1.0"]
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ Or run locally: `python -m tabii_mcp.server` (needs `mcp<2`, `curl-cffi`).
37
+
38
+ ## Tools
39
+
40
+ | Tool | Description |
41
+ |------|-------------|
42
+ | `tabii_search_content` | Search the catalog by original Turkish title (e.g. "gassal", "mevlana") — `language` ("tr" default, "en", "es", "ar", "ur"), `limit` 1..10; id, slug, localized title, original title, type, year, URL per match |
43
+ | `tabii_get_show` | Full detail of one title — `show_id` or `slug` (e.g. "gassal"); localized title, original title, type, year, genres, age restriction, seasons with episode titles + durations (capped at 60), cast, directors, writers, description, audio/subtitle languages, badges, trailer count, URL |
44
+ | `tabii_homepage` | Current homepage sections (exclusive content, series, movies, documentary, kids) with their titles — `language` |
45
+ | `tabii_live_channels` | The 15 live TRT channels (TRT 1, TRT 2, TRT Belgesel, TRT Haber, TRT Spor, TRT Çocuk, TRT World, ...) with watch URL and public HLS stream URL |
46
+ | `tabii_get_person` | One cast/crew member by numeric person id (e.g. Ahmet Kural is 6774) — name, job title, filmography on tabii |
47
+ | `tabii_health` | Reachability probe (homepage + one public show) — ok / blocked / error |
48
+
49
+ Example output (`tabii_search_content` / "gassal", language "en"):
50
+
51
+ ```json
52
+ {"id": 438813, "slug": "gassal", "title": "The Late Offices",
53
+ "original_title": "Gassal", "content_type": "series", "made_year": 2024,
54
+ "url": "https://www.tabii.com/en/detail/438813/gassal"}
55
+ ```
56
+
57
+ ## How it works
58
+
59
+ tabii.com exposes a public catalog API that needs no login, no API key and no session token: `eu1.tabii.com/apigateway/catalog/v1/public/shows/{id}` and `.../public/persons/{id}` (the authenticated variants — `search/v1`, `catalog/v1/show/{id}` — return HTTP 401 without a Bearer session token and are not used). The homepage is server-rendered Next.js; its `__NEXT_DATA__` JSON carries the featured sections and the 15 live channels with their public HLS URLs. Search scans the site's own sitemaps (EN + TR merged: 1,306 shows, 1,180 people — cached 6h) and resolves the top matches' localized titles through the public shows API. Two things are documented, not worked around: the sitemaps do not cover the whole catalog (some licensed titles, e.g. The Hobbit, and some originals are absent — they are still reachable by id, e.g. via the homepage sections), and genre/category browse pages are client-side shells fed by a login-gated endpoint, so no genre-browse tool is offered. Playback needs a logged-in Tabii Premium session and is out of scope — this server is catalog metadata only. Transport uses Chrome TLS impersonation (`curl-cffi`, rotation); requests are spaced ~0.8s apart; everything is read-only.
60
+
61
+ ## Install
62
+
63
+ ```bash
64
+ uvx tabii-mcp==0.1.0 # run directly (needs uv)
65
+ # or
66
+ pip install tabii-mcp==0.1.0
67
+ tabii-mcp # starts the MCP server on stdio
68
+ ```
69
+
70
+ ## Tests
71
+
72
+ ```bash
73
+ python -m venv .venv && .venv/bin/pip install -e .
74
+ .venv/bin/python -m unittest discover -s tests -v
75
+ ```
76
+
77
+ Offline tests run on recorded fixtures (real pages/API responses fetched 2026-11-11); live tests hit tabii.com and the public API. Tests green at build time (see repo for counts) plus an MCP stdio smoke test.
78
+
79
+ ## Roadmap
80
+
81
+ - Genre browse if tabii ever publishes a session-free endpoint
82
+ - "New this week" / recently-added feed from the homepage sections
83
+ - Episode-level detail (per-episode description, audio/subtitle tracks)
84
+
85
+ ## License
86
+
87
+ MIT — see [LICENSE](LICENSE).
88
+
89
+ ---
90
+
91
+ Built by [Mohammad Abbasi](https://github.com/mohammad-abbasi-sh) — [Almanibama](https://almanibama.ir) · [mabbasi.ir](https://mabbasi.ir)
@@ -0,0 +1,79 @@
1
+ # tabii-mcp 🇹🇷
2
+
3
+ mcp-name: io.github.mohammad-abbasi-sh/tabii-mcp
4
+
5
+ سرور MCP غیررسمی و **فقط‌خواندنی** برای tabii.com، پلتفرم استریم TRT (راه‌اندازی ۲۰۲۳، بیش از ۱۱ میلیون مشترک) — سریال‌ها، فیلم‌ها، مستندها و محتوای کودکانهٔ ترکی، و ۱۵ کانال زندهٔ TRT. جست‌وجوی کاتالوگ با عنوان اصلی ترکی، جزئیات کامل هر عنوان (فصل‌ها، قسمت‌ها، بازیگران، زبان‌ها)، آدرس استریم HLS کانال‌های زنده و فیلم‌شناسی بازیگران و عوامل.
6
+
7
+ > ساختهٔ محمد عباسی در چارچوب «کارخانهٔ MCP ترکیه» (خط تولید به سبک سپهر). وابسته به tabii.com یا TRT نیست.
8
+
9
+ ## برای ایجنت‌های هوش مصنوعی
10
+
11
+ به پیکربندی MCP client خود اضافه کنید (stdio):
12
+
13
+ ```json
14
+ {
15
+ "mcpServers": {
16
+ "tabii": {
17
+ "command": "uvx",
18
+ "args": ["tabii-mcp==0.1.0"]
19
+ }
20
+ }
21
+ }
22
+ ```
23
+
24
+ یا به‌صورت محلی اجرا کنید: `python -m tabii_mcp.server` (نیازمند `mcp<2` و `curl-cffi`).
25
+
26
+ ## ابزارها
27
+
28
+ | ابزار | توضیح |
29
+ |------|-------|
30
+ | `tabii_search_content` | جست‌وجو در کاتالوگ با عنوان اصلی ترکی (مثل «gassal» یا «mevlana») — `language` (پیش‌فرض «tr»، همچنین «en»، «es»، «ar»، «ur»)، `limit` بین ۱ تا ۱۰؛ برای هر نتیجه: id، slug، عنوان محلی‌شده، عنوان اصلی، نوع، سال و URL |
31
+ | `tabii_get_show` | جزئیات کامل یک عنوان — `show_id` یا `slug` (مثل «gassal»)؛ عنوان محلی‌شده، عنوان اصلی، نوع، سال، ژانرها، محدودیت سنی، فصل‌ها با عنوان و مدت قسمت‌ها (حداکثر ۶۰ قسمت)، بازیگران، کارگردانان، نویسندگان، توضیح، زبان‌های صدا/زیرنویس، نشان‌ها، تعداد تریلر و URL |
32
+ | `tabii_homepage` | بخش‌های فعلی صفحهٔ اصلی (محتوای اختصاصی، سریال، فیلم، مستند، کودک) با عنوان‌هایشان — `language` |
33
+ | `tabii_live_channels` | ۱۵ کانال زندهٔ TRT (TRT 1، TRT 2، TRT Belgesel، TRT Haber، TRT Spor، TRT Çocuk، TRT World و…) — آدرس تماشا و آدرس عمومی استریم HLS |
34
+ | `tabii_get_person` | یک بازیگر/عضو عوامل با شناسهٔ عددی (مثلاً احمد کورال 6774) — نام، سمت و فیلم‌شناسی او در tabii |
35
+ | `tabii_health` | بررسی دسترسی (صفحهٔ اصلی + یک محتوای عمومی) — ok / blocked / error |
36
+
37
+ نمونهٔ خروجی (`tabii_search_content` / «gassal»، زبان «en»):
38
+
39
+ ```json
40
+ {"id": 438813, "slug": "gassal", "title": "The Late Offices",
41
+ "original_title": "Gassal", "content_type": "series", "made_year": 2024,
42
+ "url": "https://www.tabii.com/en/detail/438813/gassal"}
43
+ ```
44
+
45
+ ## چطور کار می‌کند؟
46
+
47
+ tabii.com یک API عمومی کاتالوگ دارد که بدون ورود، کلید API و توکن نشست کار می‌کند: `eu1.tabii.com/apigateway/catalog/v1/public/shows/{id}` و `.../public/persons/{id}` (نسخه‌های نیازمند احراز هویت — `search/v1` و `catalog/v1/show/{id}` — بدون توکن Bearer خطای HTTP 401 می‌دهند و استفاده نمی‌شوند). صفحهٔ اصلی با Next.js سمت سرور ساخته می‌شود؛ JSON داخلی `__NEXT_DATA__` بخش‌های ویژه و ۱۵ کانال زنده را با آدرس‌های عمومی HLS در خود دارد. جست‌وجو نقشهٔ سایت را می‌خواند (EN + TR ادغام‌شده: ۱٬۳۰۶ عنوان و ۱٬۱۸۰ نفر — با ۶ ساعت کش) و عنوان‌های محلی‌شدهٔ بهترین تطابق‌ها را از API عمومی می‌گیرد. دو موضوع دور زده نمی‌شود، مستند می‌شود: نقشهٔ سایت کل کاتالوگ را پوشش نمی‌دهد (برخی عنوان‌های دارای مجوز، مثل هابیت، و برخی آثار اصلی غایب‌اند — با شناسه همچنان قابل دسترسی‌اند، مثلاً از بخش‌های صفحهٔ اصلی) و صفحات ژانر/دسته پوسته‌های سمت کاربرند که از یک endpoint نیازمند ورود تغذیه می‌شوند، پس ابزار مرور ژانر ارائه نمی‌شود. پخش به نشست واردشدهٔ Tabii Premium نیاز دارد و خارج از محدوده است — این سرور فقط فرادادهٔ کاتالوگ می‌دهد. انتقال با جعل TLS کروم انجام می‌شود (`curl-cffi`، چرخشی)؛ درخواست‌ها با فاصلهٔ حدود ۰٫۸ ثانیه ارسال می‌شوند؛ همه‌چیز فقط‌خواندنی است.
48
+
49
+ ## نصب
50
+
51
+ ```bash
52
+ uvx tabii-mcp==0.1.0 # اجرای مستقیم (نیازمند uv)
53
+ # یا
54
+ pip install tabii-mcp==0.1.0
55
+ tabii-mcp # سرور MCP را روی stdio راه می‌اندازد
56
+ ```
57
+
58
+ ## تست‌ها
59
+
60
+ ```bash
61
+ python -m venv .venv && .venv/bin/pip install -e .
62
+ .venv/bin/python -m unittest discover -s tests -v
63
+ ```
64
+
65
+ تست‌های آفلاین با فیکسچرهای ضبط‌شده اجرا می‌شوند (صفحات و پاسخ‌های واقعی API، گرفته‌شده در ۱۱ نوامبر ۲۰۲۶)؛ تست‌های زنده به tabii.com و API عمومی وصل می‌شوند. تست‌ها هنگام ساخت سبز بودند (برای شمار به مخزن نگاه کنید)؛ به‌علاوه یک تست دود MCP روی stdio وجود دارد.
66
+
67
+ ## نقشهٔ راه
68
+
69
+ - مرور ژانر، اگر tabii روزی endpoint بدون نشست منتشر کند
70
+ - فید «تازه‌های این هفته» / تازه‌اضافه‌شده‌ها از بخش‌های صفحهٔ اصلی
71
+ - جزئیات در سطح قسمت (توضیح هر قسمت، ترک‌های صدا/زیرنویس)
72
+
73
+ ## پروانه
74
+
75
+ MIT — ببینید [LICENSE](LICENSE).
76
+
77
+ ---
78
+
79
+ Built by [Mohammad Abbasi](https://github.com/mohammad-abbasi-sh) — [Almanibama](https://almanibama.ir) · [mabbasi.ir](https://mabbasi.ir)
@@ -0,0 +1,79 @@
1
+ # tabii-mcp 🇹🇷
2
+
3
+ mcp-name: io.github.mohammad-abbasi-sh/tabii-mcp
4
+
5
+ TRT'nin dijital yayın platformu tabii.com için resmi olmayan, **salt okunur** MCP sunucusu (2023'te yayına girdi, 11 milyondan fazla abone) — Türkçe diziler, filmler, belgeseller, çocuk içerikleri ve 15 canlı TRT kanalı. Orijinal Türkçe başlığa göre katalog araması, dizi/film detayları (sezonlar, bölümler, oyuncular, diller), canlı kanal HLS yayın adresleri ve oyuncu/ekip filmografileri.
6
+
7
+ > Mohammad Abbasi tarafından "Turkey MCP factory" (Sepehr tarzı hat) kapsamında geliştirildi. tabii.com veya TRT ile bağlantısı yoktur.
8
+
9
+ ## Yapay zekâ ajanları için
10
+
11
+ MCP istemci yapılandırmanıza ekleyin (stdio):
12
+
13
+ ```json
14
+ {
15
+ "mcpServers": {
16
+ "tabii": {
17
+ "command": "uvx",
18
+ "args": ["tabii-mcp==0.1.0"]
19
+ }
20
+ }
21
+ }
22
+ ```
23
+
24
+ Veya yerelde çalıştırın: `python -m tabii_mcp.server` (`mcp<2`, `curl-cffi` gerekir).
25
+
26
+ ## Araçlar
27
+
28
+ | Araç | Açıklama |
29
+ |------|----------|
30
+ | `tabii_search_content` | Katalogda orijinal Türkçe başlığa göre arama (örn. "gassal", "mevlana") — `language` ("tr" varsayılan, "en", "es", "ar", "ur"), `limit` 1..10; her sonuçta id, slug, yerelleştirilmiş başlık, orijinal başlık, tür, yıl ve URL |
31
+ | `tabii_get_show` | Bir içeriğin tüm detayı — `show_id` veya `slug` (örn. "gassal"); yerelleştirilmiş başlık, orijinal başlık, tür, yıl, türler (genre), yaş sınırı, bölüm başlıkları + süreleriyle sezonlar (en fazla 60 bölüm), oyuncular, yönetmenler, senaristler, açıklama, ses/altyazı dilleri, rozetler, fragman sayısı, URL |
32
+ | `tabii_homepage` | Ana sayfadaki güncel bölümler (tabii'ye Özel İçerikler, Dizi, Film, Belgesel, Çocuk) ve içerikleri — `language` |
33
+ | `tabii_live_channels` | 15 canlı TRT kanalı (TRT 1, TRT 2, TRT Belgesel, TRT Haber, TRT Spor, TRT Çocuk, TRT World, ...) — izleme URL'si ve herkese açık HLS yayın adresi |
34
+ | `tabii_get_person` | Bir oyuncu/ekip üyesi, sayısal kişi id'siyle (örn. Ahmet Kural 6774) — ad, görev ve tabii'deki filmografisi |
35
+ | `tabii_health` | Erişilebilirlik kontrolü (ana sayfa + bir herkese açık içerik) — ok / blocked / error |
36
+
37
+ Örnek çıktı (`tabii_search_content` / "gassal", dil "en"):
38
+
39
+ ```json
40
+ {"id": 438813, "slug": "gassal", "title": "The Late Offices",
41
+ "original_title": "Gassal", "content_type": "series", "made_year": 2024,
42
+ "url": "https://www.tabii.com/en/detail/438813/gassal"}
43
+ ```
44
+
45
+ ## Nasıl çalışır?
46
+
47
+ tabii.com, giriş, API anahtarı ve oturum jetonu gerektirmeyen herkese açık bir katalog API'si sunar: `eu1.tabii.com/apigateway/catalog/v1/public/shows/{id}` ve `.../public/persons/{id}` (kimlik doğrulamalı sürümler — `search/v1`, `catalog/v1/show/{id}` — Bearer oturum jetonu olmadan HTTP 401 döner ve kullanılmaz). Ana sayfa sunucu taraflı Next.js ile oluşturulur; `__NEXT_DATA__` JSON'i öne çıkan bölümleri ve 15 canlı kanalı herkese açık HLS adresleriyle birlikte taşır. Arama, sitenin site haritalarını tarar (EN + TR birleştirilmiş: 1.306 içerik, 1.180 kişi — 6 saat önbellekli) ve en iyi eşleşmelerin yerelleştirilmiş başlıklarını herkese açık içerik API'siyle çözer. İki konu aşılmaya çalışılmaz, belgelenir: site haritaları kataloğun tamamını kapsamaz (bazı lisanslı içerikler, örn. Hobbit, ve bazı orijinaller eksik — id ile yine de erişilebilir, örn. ana sayfa bölümlerinden) ve tür/kategori sayfaları giriş gerektiren bir uç noktadan beslenen istemci taraflı kabuklardır, bu yüzden tür tarama aracı sunulmaz. Oynatma, giriş yapmış bir Tabii Premium oturumu gerektirir ve kapsam dışıdır — bu sunucu yalnızca katalog verisi sunar. Aktarım, Chrome TLS taklidi kullanır (`curl-cffi`, dönüşümlü); istekler ~0,8 sn aralıklarla yapılır; her şey salt okunurdur.
48
+
49
+ ## Kurulum
50
+
51
+ ```bash
52
+ uvx tabii-mcp==0.1.0 # doğrudan çalıştır (uv gerekir)
53
+ # veya
54
+ pip install tabii-mcp==0.1.0
55
+ tabii-mcp # MCP sunucusunu stdio üzerinde başlatır
56
+ ```
57
+
58
+ ## Testler
59
+
60
+ ```bash
61
+ python -m venv .venv && .venv/bin/pip install -e .
62
+ .venv/bin/python -m unittest discover -s tests -v
63
+ ```
64
+
65
+ Çevrimdışı testler kayıtlı örneklerle çalışır (11.11.2026'da çekilmiş gerçek sayfalar/API yanıtları); canlı testler tabii.com ve herkese açık API'ye bağlanır. Derleme anında testler geçti (sayılar için depoya bakın); ayrıca bir MCP stdio duman testi vardır.
66
+
67
+ ## Yol haritası
68
+
69
+ - tabii oturumsuz bir uç nokta yayınlarsa tür tarama
70
+ - Ana sayfa bölümlerinden "bu hafta yeni" / yeni eklenenler akışı
71
+ - Bölüm düzeyinde detay (bölüm açıklaması, ses/altyazı parçaları)
72
+
73
+ ## Lisans
74
+
75
+ MIT — bkz. [LICENSE](LICENSE).
76
+
77
+ ---
78
+
79
+ Built by [Mohammad Abbasi](https://github.com/mohammad-abbasi-sh) — [Almanibama](https://almanibama.ir) · [mabbasi.ir](https://mabbasi.ir)
@@ -0,0 +1,79 @@
1
+ # tabii-mcp 🇹🇷
2
+
3
+ mcp-name: io.github.mohammad-abbasi-sh/tabii-mcp
4
+
5
+ Unofficial **read-only** MCP server for tabii.com, TRT's streaming platform (launched 2023, 11M+ subscribers) — Turkish series, movies, documentaries, kids content and 15 live TRT channels. Catalog search by original Turkish title, full show details (seasons, episodes, cast, languages), live-channel HLS stream URLs, and cast/crew filmographies.
6
+
7
+ > Built by Mohammad Abbasi as part of the "Turkey MCP factory" (Sepehr-style pipeline). Not affiliated with tabii.com or TRT.
8
+
9
+ ## For AI agents
10
+
11
+ Add to your MCP client config (stdio):
12
+
13
+ ```json
14
+ {
15
+ "mcpServers": {
16
+ "tabii": {
17
+ "command": "uvx",
18
+ "args": ["tabii-mcp==0.1.0"]
19
+ }
20
+ }
21
+ }
22
+ ```
23
+
24
+ Or run locally: `python -m tabii_mcp.server` (needs `mcp<2`, `curl-cffi`).
25
+
26
+ ## Tools
27
+
28
+ | Tool | Description |
29
+ |------|-------------|
30
+ | `tabii_search_content` | Search the catalog by original Turkish title (e.g. "gassal", "mevlana") — `language` ("tr" default, "en", "es", "ar", "ur"), `limit` 1..10; id, slug, localized title, original title, type, year, URL per match |
31
+ | `tabii_get_show` | Full detail of one title — `show_id` or `slug` (e.g. "gassal"); localized title, original title, type, year, genres, age restriction, seasons with episode titles + durations (capped at 60), cast, directors, writers, description, audio/subtitle languages, badges, trailer count, URL |
32
+ | `tabii_homepage` | Current homepage sections (exclusive content, series, movies, documentary, kids) with their titles — `language` |
33
+ | `tabii_live_channels` | The 15 live TRT channels (TRT 1, TRT 2, TRT Belgesel, TRT Haber, TRT Spor, TRT Çocuk, TRT World, ...) with watch URL and public HLS stream URL |
34
+ | `tabii_get_person` | One cast/crew member by numeric person id (e.g. Ahmet Kural is 6774) — name, job title, filmography on tabii |
35
+ | `tabii_health` | Reachability probe (homepage + one public show) — ok / blocked / error |
36
+
37
+ Example output (`tabii_search_content` / "gassal", language "en"):
38
+
39
+ ```json
40
+ {"id": 438813, "slug": "gassal", "title": "The Late Offices",
41
+ "original_title": "Gassal", "content_type": "series", "made_year": 2024,
42
+ "url": "https://www.tabii.com/en/detail/438813/gassal"}
43
+ ```
44
+
45
+ ## How it works
46
+
47
+ tabii.com exposes a public catalog API that needs no login, no API key and no session token: `eu1.tabii.com/apigateway/catalog/v1/public/shows/{id}` and `.../public/persons/{id}` (the authenticated variants — `search/v1`, `catalog/v1/show/{id}` — return HTTP 401 without a Bearer session token and are not used). The homepage is server-rendered Next.js; its `__NEXT_DATA__` JSON carries the featured sections and the 15 live channels with their public HLS URLs. Search scans the site's own sitemaps (EN + TR merged: 1,306 shows, 1,180 people — cached 6h) and resolves the top matches' localized titles through the public shows API. Two things are documented, not worked around: the sitemaps do not cover the whole catalog (some licensed titles, e.g. The Hobbit, and some originals are absent — they are still reachable by id, e.g. via the homepage sections), and genre/category browse pages are client-side shells fed by a login-gated endpoint, so no genre-browse tool is offered. Playback needs a logged-in Tabii Premium session and is out of scope — this server is catalog metadata only. Transport uses Chrome TLS impersonation (`curl-cffi`, rotation); requests are spaced ~0.8s apart; everything is read-only.
48
+
49
+ ## Install
50
+
51
+ ```bash
52
+ uvx tabii-mcp==0.1.0 # run directly (needs uv)
53
+ # or
54
+ pip install tabii-mcp==0.1.0
55
+ tabii-mcp # starts the MCP server on stdio
56
+ ```
57
+
58
+ ## Tests
59
+
60
+ ```bash
61
+ python -m venv .venv && .venv/bin/pip install -e .
62
+ .venv/bin/python -m unittest discover -s tests -v
63
+ ```
64
+
65
+ Offline tests run on recorded fixtures (real pages/API responses fetched 2026-11-11); live tests hit tabii.com and the public API. Tests green at build time (see repo for counts) plus an MCP stdio smoke test.
66
+
67
+ ## Roadmap
68
+
69
+ - Genre browse if tabii ever publishes a session-free endpoint
70
+ - "New this week" / recently-added feed from the homepage sections
71
+ - Episode-level detail (per-episode description, audio/subtitle tracks)
72
+
73
+ ## License
74
+
75
+ MIT — see [LICENSE](LICENSE).
76
+
77
+ ---
78
+
79
+ Built by [Mohammad Abbasi](https://github.com/mohammad-abbasi-sh) — [Almanibama](https://almanibama.ir) · [mabbasi.ir](https://mabbasi.ir)
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "tabii-mcp"
7
+ version = "0.1.0"
8
+ description = "Unofficial read-only MCP server for tabii.com (TRT streaming): catalog search, show details, live channels, people"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.10"
12
+ dependencies = [
13
+ "mcp<2",
14
+ "curl-cffi>=0.7,<1.0",
15
+ ]
16
+ authors = [{ name = "Mohammad Abbasi" }]
17
+
18
+ [project.scripts]
19
+ tabii-mcp = "tabii_mcp.server:main"
20
+
21
+ [tool.hatch.build.targets.wheel]
22
+ packages = ["src/tabii_mcp"]
@@ -0,0 +1 @@
1
+ {"$schema":"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json","description":"Unofficial read-only MCP server for tabii.com — TRT streaming catalog, live channels, people.","name":"io.github.mohammad-abbasi-sh/tabii-mcp","packages":[{"identifier":"tabii-mcp","registryBaseUrl":"https://pypi.org","registryType":"pypi","transport":{"type":"stdio"},"version":"0.1.0"}],"repository":{"source":"github","url":"https://github.com/mohammad-abbasi-sh/tabii-mcp"},"title":"tabii (TRT Streaming)","version":"0.1.0","websiteUrl":"https://github.com/mohammad-abbasi-sh/tabii-mcp"}
@@ -0,0 +1,3 @@
1
+ """tabii_mcp — unofficial read-only MCP server for tabii.com."""
2
+
3
+ __version__ = "0.1.0"