内容
# niche-finder
[](https://github.com/pandich93/niche-finder/stargazers)
[](https://github.com/pandich93/niche-finder/forks)
[](https://github.com/pandich93/niche-finder/releases/latest)
[](https://github.com/pandich93/niche-finder/actions/workflows/ci.yml)
[](assets/coverage.json)
[](LICENSE)
[](backend/Dockerfile)
[](backend/interfaces/http/api.py)
[](docker-compose.yml)
[](docker-compose.yml)
[](backend/interfaces/mcp/server.py)
[](https://github.com/pandich93/niche-finder/commits/main)
[](https://github.com/pandich93/niche-finder/issues)
[](https://github.com/pandich93/niche-finder/pulls)
A self-hosted alternative to NexLev / vidIQ / ViewStats: find niches, viral
videos from small channels, trending categories and keywords over arbitrary
periods (24h, 48h, 7/30/90 days), plus full channel tracking and analytics.
Runs on the free YouTube Data API v3 and a local PostgreSQL — no
subscription, no paid LLM key: semantic classification like "faceless / on
topic" is done by the model calling these tools, not the server.

The project has three parts that together make up the "product":
- **`backend/`** — Python: an MCP server (29 tools for Claude), an HTTP API
for the dashboard, and a background worker that logs view/subscriber
history on a schedule (without this, "growth rate over 24 hours" doesn't
exist — the YouTube API only ever returns "right now").
- **`frontend/`** — the same functionality, but visual: a dashboard built on
plain ES modules (no npm, no build step) that calls the backend's HTTP API.
- **`extension/`** — a Chrome extension (Manifest V3) that puts the same
metrics on top of YouTube itself, the way vidIQ and NexLev do: outlier
score, view velocity and tags on a watch page, growth and best publishing
times on a channel page, multiplier badges on thumbnails in any list. It
talks only to `127.0.0.1` — nothing leaves the machine.
Both parts and the Postgres store come up together with one command (see
below) — the dashboard and Claude Desktop end up looking at the same
database.
## Features
- Find viral videos and outlier channels by niche over an arbitrary period
(24h / 48h / 7 / 30 / 90 days)
- Trending categories and keywords, best time to publish, title patterns
- Track specific channels: view/subscriber growth rate, snapshot history
- The exact same calculation in Claude Desktop (via MCP) and on the web
dashboard — one shared codebase, not two implementations
- Only the free YouTube Data API v3 and local PostgreSQL — no paid
subscriptions and no LLM key on the server side
## Table of Contents
- [Screens](#screens)
- [How it works](#how-it-works)
- [Quick start](#quick-start)
- [Repository layout](#repository-layout)
- [Contributing](#contributing)
- [Privacy](#privacy)
- [Changelog](#changelog)
- [Read next](#read-next)
## Screens
<table>
<tr>
<td width="50%"><img src="assets/viral.jpg" alt="Viral videos from small channels"><br><sub>Viral videos — small channels that overperformed expectations</sub></td>
<td width="50%"><img src="assets/outliers.jpg" alt="Outlier channels"><br><sub>Outlier channels — best video's multiplier against the channel's median</sub></td>
</tr>
<tr>
<td width="50%"><img src="assets/categories.jpg" alt="Categories"><br><sub>Categories — share and growth across YouTube niches</sub></td>
<td width="50%"><img src="assets/keywords.jpg" alt="Keywords"><br><sub>Keywords — trendScore, lift, momentum</sub></td>
</tr>
<tr>
<td width="50%"><img src="assets/tracker.jpg" alt="Channel tracker"><br><sub>Channel tracker — collect and follow specific channels</sub></td>
<td width="50%"><img src="assets/niches.jpg" alt="Niches"><br><sub>Niches — everything collected under user-defined labels</sub></td>
</tr>
<tr>
<td width="50%"><img src="assets/data.jpg" alt="Data"><br><sub>Data — database state and manual collection/refresh</sub></td>
<td width="50%"></td>
</tr>
</table>
## How it works
```mermaid
flowchart LR
CD["Claude Desktop"] -->|MCP| MCP["MCP server\nbackend/server.py"]
FE["Browser / frontend"] -->|HTTP| API["HTTP API\nbackend/api.py"]
EXT["Chrome extension\non youtube.com"] -->|"HTTP (localhost)"| API
YT["YouTube Data API v3"] <-->|"on schedule"| W["Background worker\nbackend/worker.py"]
MCP --> PG[("PostgreSQL")]
API --> PG
W --> PG
```
The MCP server, HTTP API, and worker are three different entry points into
the same code: all three call the same use cases from `backend/application/`,
so the result in Claude Desktop and on the dashboard is literally the same
calculation — not two separate implementations. A detailed breakdown of the
backend's layers (as of September 5, 2026 — DDD: domain → infrastructure →
application → interfaces) is in
[backend/README.md](backend/README.md#structure).
## Quick start
With Docker (recommended — brings up Postgres, the worker, and the dashboard
together):
```bash
cp .env.example .env # fill in YOUTUBE_API_KEY (not required to build)
docker compose build
make up # or: docker compose up -d web worker
make doctor # check the key, network, and database
open http://localhost:8080 # dashboard
```
Without Docker (needs your own reachable Postgres):
```bash
make local-install # venv + backend dependencies, once
make dev # HTTP dashboard on http://localhost:8080
make local-run # or: MCP server on the host, for Claude Desktop
```
Запуск на хосте (`make dev` / `make local-run`) ходит в ту же базу, но по
другому адресу: контейнер Postgres опубликован на `127.0.0.1:5433`, а дефолт в
коде -- `localhost:5432`, поэтому без подсказки процесс падает с
`psycopg2.OperationalError: Connection refused`. Добавьте в `.env` строку
```bash
NICHE_DATABASE_URL=postgresql://niches:niches@localhost:5433/niches
```
(`NICHE_DATABASE_URL` важнее `POSTGRES_*` и остаётся хостовым: в контейнеры
compose его не передаёт, а `scripts/mcp-docker.sh` и `scripts/diag.sh`
вырезают его явно). **Не** подменяйте это на `POSTGRES_PORT=5433` -- ту же
переменную compose отдаёт контейнерам как внутрисетевой порт и сломает
`web`/`worker`/`mcp`.
`make dev` слушает тот же `:8080`, что и контейнер `web`. Держать оба сразу
нельзя: хостовый uvicorn перехватывает порт, и проброс у контейнера тихо
отваливается (`docker ps` покажет `8080/tcp` без маппинга). Либо
`docker compose stop web` перед `make dev`, либо правьте код прямо в
контейнере -- `./backend` смонтирован внутрь, и `docker compose restart web`
подхватывает изменения без пересборки.
`make help` prints every available command with a one-line description.
## Repository layout
| Path | What's inside |
|---|---|
| [`backend/`](backend/README.md) | MCP server, HTTP API, worker — all the logic and data storage |
| [`frontend/`](frontend/README.md) | dashboard: index.html, styles.css, ui.js, app.js |
| [`extension/`](extension/README.md) | Chrome extension: panels and badges on top of YouTube |
| `docker-compose.yml` | postgres + worker + web + mcp/mcp-http services |
| `Makefile` | commands to run everything, via Docker or straight on the host |
| `.env.example` | YouTube key and worker settings |
| `scripts/mcp-docker.sh` | MCP server launcher in Docker for Claude Desktop |
`docs/` (decision history and market research) — internal notes, not
included in this repository.
## Contributing
Bug reports, bug fixes, and documentation PRs are welcome — for anything
bigger (a new MCP tool, API endpoint, or dashboard screen), please open an
issue first to agree on the shape. See
[CONTRIBUTING.md](CONTRIBUTING.md) for how to set up a dev environment and
run the test suite.
## Privacy
Self-hosted, no telemetry, no account: everything stays in your own Postgres,
and the app contacts exactly two external hosts — `www.googleapis.com` for the
YouTube Data API and `www.youtube.com` for channel RSS feeds. Comments read by
`video_comments` are never stored. See [PRIVACY.md](PRIVACY.md) for the full
picture, including what the first run downloads and how to delete everything.
## Changelog
See [CHANGELOG.md](CHANGELOG.md) for a history of notable changes, in
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format.
## Read next
- [backend/README.md](backend/README.md) — YouTube API quotas, all 24 tools
with descriptions, how to read `period_by`, running with and without
Docker, the DDD layer structure.
- [frontend/README.md](frontend/README.md) — dashboard screens, where the
data comes from, how the palette is built.
- [extension/README.md](extension/README.md) — what the extension shows on
each kind of YouTube page, how to load it unpacked, and what it costs in
API quota.
连接信息
猜你喜欢
暂无推荐服务器