About Ott Platform
Ott Platform is an MCP server in the Documentation category: learning Claude Code via a real-world OTT streaming platform implementation.
Install
git clone https://github.com/stefanros481/ott-platformThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Ott Platform
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
Learning Claude Code — via an OTT Streaming Platform
Disclaimer: This project is a learning playground for exploring AI-native platform design. It is not production-ready and not intended for real-world deployment.
A hands-on learning project for exploring AI-assisted development with Claude Code. The vehicle is a real-world OTT streaming platform: complex enough to encounter genuine engineering challenges, concrete enough to produce something you can actually run and interact with.
What This Is
This repo implements a working OTT platform (VOD catalog, EPG grid, live TV, recommendations, entitlements, and more) while deliberately exploring how Claude Code handles real software engineering tasks — not toy examples.
The goal is to learn by doing: each numbered branch (001-*, 002-*, ...) represents a self-contained feature implementation, built with Claude Code as the primary development tool. Browse the branches to see how individual features were approached and built.
New features are developed using speckit — a Claude Code skill that structures feature work through specs, plans, and tasks before writing any code.
Screenshots
![]() |
![]() |
| Home — personalized hero + content rails | Browse — full catalog with genre & type filters |
![]() |
![]() |
| EPG — 7-day TV guide grid with channel filters | Title detail — play, watchlist, ratings, cast |
![]() |
![]() |
| Profile selector — multi-profile per account | Admin dashboard — catalog, channels, users, embeddings, analytics |
Roadmap
See ROADMAP.md for completed features, what's planned next, and overall coverage.
What You'll Find Here
- A fully runnable backend (FastAPI + PostgreSQL + Redis) and two React frontends
- AI-powered content recommendations using pgvector embeddings
- Multi-profile auth, parental controls, entitlements, TVOD, and stream sessions
- Progressive complexity: from simple CRUD to ML-backed features
- Design docs, PRDs, and user stories in
docs/that informed each feature
Prerequisites
- Docker and Docker Compose installed and running
Quick Start
git clone https://github.com/stefanros481/ott-platform.git
cd ott-platform/docker
docker compose up --build
First build takes ~5 min (Python deps + Node deps + sentence-transformers model download). Subsequent starts use cached layers.
URLs
| Service | URL |
|---|---|
| Client App | http://localhost:5173 |
| Admin Dashboard | http://localhost:5174 |
| Backend API | http://localhost:8000 |
| Swagger Docs | http://localhost:8000/docs |
| CDN (HLS segments) | http://localhost:8081 |
Test Users
| Password | Tier | Admin | Profiles | |
|---|---|---|---|---|
| admin@ott.test | admin123 | Premium | Yes | Admin, Kids |
| basic@ott.test | test123 | Basic | No | Basic User |
| standard@ott.test | test123 | Standard | No | Standard User, Family |
| premium@ott.test | test123 | Premium | No | Premium User, Partner, Kids |
| demo@ott.test | demo123 | Premium | No | Demo User |
Entitlement Tiers
- Basic — 60% of titles, 15 channels
- Standard — 85% of titles, 25 channels
- Premium — 100% of titles, all channels
Seed Data
| Data | Count |
|---|---|
| Titles (movies + series) | 70 |
| Genres | 12 |
| Channels | 25 |
| Schedule entries (7-day) | ~4,800 |
| Content embeddings | 70 |
| Users | 5 |
| Profiles | 10 |
| Analytics events | ~600–1000 |
Data is seeded automatically on first backend startup. To re-seed, delete the postgres_data volume and restart.
EPG schedule stale? The EPG is seeded with ±7 days from the first startup date. If your TV guide looks empty, the schedule has likely expired. To refresh just the EPG without losing other data:
docker exec ott-platform-backend-1 uv run python -c " import asyncio from sqlalchemy import delete from app.database import async_session_factory from app.models.epg import Channel, ScheduleEntry from app.seed.seed_epg import seed_epg async def reseed(): async with async_session_factory() as s: await s.execute(delete(ScheduleEntry)) await s.execute(delete(Channel)) await s.commit() async with async_session_factory() as s: counts = await seed_epg(s) print(counts) asyncio.run(reseed()) "
Tech Stack
- Backend: Python / FastAPI, SQLAlchemy 2.0 (async), Alembic
- Database: PostgreSQL 16 + pgvector (HNSW index for similarity search)
- Cache: Redis 7
- AI: sentence-transformers (
all-MiniLM-L6-v2, 384-dim embeddings) - Frontend Client: React 18, TypeScript, Vite, Tailwind CSS, TanStack Query, Shaka Player
- Frontend Admin: React 18, TypeScript, Vite, Tailwind CSS, TanStack Query
- Auth: JWT (HS256)
- Streaming: HLS/fMP4 via FFmpeg (SimLive), nginx CDN for segment delivery, ClearKey DRM
- MCP Server: FastMCP — read-only AI agent access to the content catalog
- Infra: Docker Compose
Architecture
frontend-client (5173) frontend-admin (5174)
\ /
\ /
+--> backend (8000) <-------+
| | |
PostgreSQL Redis CDN/nginx (8081)
+ pgvector |
hls_data volume
(FFmpeg/SimLive)
Single FastAPI monolith with router-based module separation:
| Module | Endpoints |
|---|---|
| Auth | /auth/login, /register, /refresh, /profiles |
| Catalog | /catalog/titles, /search, /genres, /featured |
| EPG | /epg/channels, /schedule/{channel_id}, /favorites |
| Viewing | /viewing/continue-watching, /bookmarks, /ratings, /watchlist |
| Recommendations | /recommendations/home, /similar/{id} |
| Admin | /admin/titles, /channels, /schedule, /embeddings/generate |
| Analytics | /analytics/events (event ingestion) |
| Content Analytics | /content-analytics/query, /content-analytics/jobs/{id} (NL query agent) |
| TSTV | /tstv/startover, /tstv/catchup, /tstv/sessions (Start Over & Catch-up TV) |
| DRM | /drm/clearkey (ClearKey license server) |
CDN / SimLive: An nginx container (port 8081) serves fMP4 HLS segments from a shared hls_data Docker volume. FFmpeg processes (managed by SimLiveManager) write one simulated live stream per TSTV-enabled channel into that volume. The backend's CDN_BASE_URL points manifests at this CDN.
AI Recommendations
Embeddings are generated from title metadata (title, synopsis, genres, cast, mood/theme tags) using all-MiniLM-L6-v2. Similarity search uses pgvector cosine distance with HNSW index.
Surfaces:
- "More Like This" — cosine similarity from a source title's embedding
- "For You" — centroid of user's watched/rated titles → similarity search
- Home rails — Continue Watching, For You, New Releases, Trending, genre rails
Regenerate embeddings (e.g. after changing seed data):
# Via admin dashboard: click "Generate Embeddings" button
# Via API (as admin user):
curl -X POST "http://localhost:8000/api/v1/admin/embeddings/generate?regenerate=true" \
-H "Authorization: Bearer <admin-jwt>"
Project Structure
├── backend/ # FastAPI app (Python/uv)
│ ├── app/
│ │ ├── models/ # SQLAlchemy ORM models
│ │ ├── schemas/ # Pydantic request/response schemas
│ │ ├── routers/ # FastAPI route handlers
│ │ ├── services/ # Business logic (incl. SimLiveManager)
│ │ └── seed/ # Data seeding scripts
│ └── hls_sources/ # Source video files for SimLive (per channel)
├── frontend-client/ # Viewer-facing React app
│ └── src/
│ ├── api/ # Typed API client
│ ├── pages/ # Route pages
│ ├── components/ # Reusable UI components
│ └── context/ # Auth context
├── frontend-admin/ # Admin dashboard React app
├── mcp-server/ # FastMCP read-only content metadata server
│ └── src/ott_mcp/
│ └── server.py # Tools: catalog, EPG, analytics, TSTV, packages
├── nginx/ # CDN config (serves HLS segments on port 8081)
│ └── cdn.conf
├── docker/ # Docker Compose + init scripts
├── docs/ # Design docs, PRDs, architecture, user stories
└── specs/ # Per-feature specs and validation quickstarts
License
Copyright 2026 Stefan Rosander
Licensed under the Apache License, Version 2.0.
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.





