{
  "markdown": "# rotv-mcp\n\nRead-only [Model Context Protocol](https://modelcontextprotocol.io/) server for\n[tv.madeinro.eu](https://tv.madeinro.eu) — Romanian TV guide, streaming catalog and an\nentertainment concierge, exposed as 14 tools to any MCP-compatible client\n(Claude, ChatGPT, or your own agent) — including an\n[MCP Apps](https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/)\nvisual tonight-card.\n\n**Live endpoint:** `https://tv.madeinro.eu/mcp` · no auth · streamable HTTP\n**Registry:** [`eu.madeinro/rotv-mcp`](https://registry.modelcontextprotocol.io/?q=rotv) (official MCP registry)\n**Human-readable overview:** [tv.madeinro.eu/mcp/help](https://tv.madeinro.eu/mcp/help)\n\n## Quick start\n\nNo installation, no key — talk to the live server directly:\n\n```bash\n# What's important on Romanian TV today? (World Cup, finals, Romania playing…)\ncurl -X POST https://tv.madeinro.eu/mcp \\\n  -H 'Content-Type: application/json' \\\n  -H 'Accept: application/json, text/event-stream' \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\n        \"name\":\"tv_important_today\",\"arguments\":{}}}'\n\n# Decide for me: I have 2 free hours tonight\ncurl -X POST https://tv.madeinro.eu/mcp \\\n  -H 'Content-Type: application/json' \\\n  -H 'Accept: application/json, text/event-stream' \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\n        \"name\":\"tv_concierge\",\"arguments\":{\"duration_hours\":2,\"mood\":\"captivant\"}}}'\n```\n\nAs an MCP client (e.g. Claude Code):\n\n```bash\nclaude mcp add --transport http rotv https://tv.madeinro.eu/mcp\n```\n\n## Tools\n\nAll tools are **read-only** and declare the standard MCP annotations\n(`readOnlyHint: true`), so well-behaved clients can run them without\nper-call confirmation. Time references accepted throughout: `now`, `tonight`,\n`tomorrow`, `weekend`, `primetime`, or ISO 8601 instant/range.\n\n### Core EPG (v1)\n\n| Tool | What it does |\n|---|---|\n| `tv_now_on_tv` | What's on right now — the 14 main Romanian channels or all ~258 |\n| `tv_search_program` | Search the schedule by keywords and timeframe |\n| `tv_get_prime_time` | Tonight's 20:00–23:00 (Europe/Bucharest) lineup, grouped by channel |\n| `tv_recommend_today` | Ranked picks for today (channel quality, timing, preferences) |\n| `tv_get_title_details` | One title across TV airings + streaming providers |\n\n### Decision layer (v2)\n\n| Tool | What it does |\n|---|---|\n| `tv_recommend_by_mood` | Ranked list matched to a mood (obosit / vesel / concentrat / romantic / familie / captivant) |\n| `tv_plan_evening` | A full evening plan across TV + streaming |\n| `tv_compare_options` | Side-by-side trade-offs between candidate picks |\n| `tv_find_for_couple` | Picks that satisfy two different moods at once |\n| `tv_explain_recommendation` | Transparent scoring breakdown for any candidate |\n| `tv_check_freshness` | How fresh the underlying EPG/streaming data is |\n\n### Concierge (v3)\n\n| Tool | What it does |\n|---|---|\n| `tv_concierge` | **One decision, not a list.** A single primary pick for your free-time window with a confidence % and full reasoning, plus up to 3 diverse alternatives with explicit trade-offs. Built-in anti-noise filter (news/politics/reality), title dedup, opportunity-cost lookahead — and event awareness (below). |\n| `tv_important_today` | **What actually matters today**: World Cup / Euro / Champions League matches, finals, knockout games, Romania's team and clubs. Every event ships with quoted evidence from the EPG text. |\n\n### MCP Apps (v3.2+)\n\n| Tool | What it does |\n|---|---|\n| `tv_concierge` *(card since v3.3)* | The concierge decision above **also renders as a visual card** (`ui://rotv/concierge-card`): the single primary pick with channel/platform, local time, disclosed confidence and reasoning, the important-event banner, and the alternatives with their explicit trade-offs. |\n| `tv_tonight_card` | **Tonight's picks as a visual card.** The daily decision (importance-scored major event, or a deterministic prime-time film fallback) plus one pick per vertical — TV, streaming (official Netflix RO top 10), theater (online + stage), cinema (box office ∩ today's screenings) — and measured stats. Declares `_meta.ui.resourceUri → ui://rotv/tonight-card`; hosts supporting the [MCP Apps extension](https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/) (Claude, ChatGPT, VS Code, Goose) render it as an interactive card in a sandboxed iframe, everyone else gets the same structured JSON. |\n\n## The importance layer\n\nRomanian EPG data is *diffuse*: every program's genre is literally `\"General\"`,\ndescriptions are often empty, and a World Cup knockout match can appear as just\n`\"Fotbal World Cup\"`. There is no structured field that says \"this matters\".\n\nSo importance is detected from **real text, with quoted evidence** (`src/lib/importance.mjs`):\n\n- **Tier 1 — major**: World Cup / Euro / Champions League / Olympics / Grand Slams / finals in the title\n- **Tier 2 — notable**: country-vs-country fixtures (\"Spania - Belgia\"), competition mentions in descriptions\n- **Boosts**: Romania playing (national team or clubs in European cups), knockout stages, mainstream national channel\n- **Demotions**: recaps, studio/practice shows, broadcasts too short to be the live event\n\nEvery result carries `reasons[]` quoting the text that matched — the detector\nnever claims more than the data supports. The same signal feeds\n`tv_concierge` as an `event_importance` confidence axis, so a description-less\nWorld Cup match no longer loses to a well-tagged filler movie, and every\nconcierge answer lists tier-1 events in an `important_today` field even when\nthe mood-based pick is something else.\n\n## Architecture\n\n```\nMCP client ── POST /mcp (streamable HTTP, stateless: fresh server per request)\n                 │\n        express (loopback :3010)\n        access log → rate limit (60 rpm) → optional bearer auth\n                 │\n        14 tools over in-memory EPG/streaming caches\n        + 2 MCP Apps UI resources (tonight-card · concierge-card)\n                 │\n        JSON artifacts produced by the rotv-guide pipeline\n        (epg-normalized.json · epg-homepage.json · streaming-full.json\n         · tonight-picks.json)\n        hot-reloaded via fs.watch (debounced 750 ms)\n```\n\n- **Stateless streamable HTTP** (`enableJsonResponse`) — one `McpServer` +\n  transport per POST; safe behind any proxy/tunnel.\n- **Data** (read-only, produced by the [rotv-guide](https://github.com/marian5070/rotv-guide)\n  pipeline, never modified by this service):\n  - `epg-normalized.json` — ~258 TV channels, −6h to +72h, ISO 8601 UTC\n  - `epg-homepage.json` — 15 main channels, −2h to +36h\n  - `streaming-full.json` — Netflix / HBO Max / Prime / Disney+ / Apple TV+ catalogs\n  - Paths configurable via `ROTV_DATA_DIR`.\n- **Telemetry**: every tool call logs one JSON line\n  (`{evt:\"tool\", tool, ms, ok, q:{…}}`) to stdout for log analysis.\n\n## Running it yourself\n\nRequires Node ≥ 24 and the rotv-guide data artifacts.\n\n```bash\ncp .env.example .env        # PORT, RATE_LIMIT_RPM, optional MCP_AUTH_TOKEN\nnpm install\nROTV_DATA_DIR=/path/to/rotv-guide/public/data npm start\n```\n\nProduction runs under pm2 behind a Cloudflare tunnel — the path-based ingress\nrule routes `tv.madeinro.eu/mcp/*` to `localhost:3010`, above the catch-all of\nthe main site:\n\n```bash\npm2 start ecosystem.config.cjs && pm2 save\ncurl https://tv.madeinro.eu/mcp/health\n```\n\n## Tests\n\n```bash\nnode --test test/importance.test.mjs        # importance detector, 12 cases\nnpm run smoke                               # 26 end-to-end JSON-RPC checks\nBASE=https://tv.madeinro.eu npm run smoke   # same suite against production\n```\n\n## License\n\n[MIT](LICENSE) © 2026 Marian Matinca. The live server surfaces data from\npublic EPG sources, refreshed automatically by the rotv-guide pipeline.\n",
  "bytes": 7781,
  "sha": "dc8d82b64441244f95b0cd3defa62d5ee7192ef5d92c60e405ea4ce27af7d76b",
  "repo_slug": "marian5070/rotv.mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_eu_madeinro_rotv_mcp_74d26039/readme"
}