Skip to content

tejas1364/Tomo-News

Repository files navigation

Tomo News

A self-hosted daily news brief that reads like a newspaper, not a feed.

Every day it gathers headlines from the RSS sources you choose, asks an LLM to pick and summarize the most significant stories into clean sections, and publishes a single, fast, mobile-friendly web page — complete with location-aware weather and a playable Wordle clone that matches the official NYT answer. It then optionally pings a webhook so you know the new edition is up.

License: MIT Python 3.8+ Dependencies: none

Live demo: https://tejas1364.github.io/Tomo-News/ — the rendered brief (the weather reflects your location, not the author's). A static copy is also in examples/sample-brief.html.

Why

Most news apps are built to maximize time-on-app: infinite feeds, notifications, ads. Tomo News is the opposite. It produces a finite edition once a day that you read in a couple of minutes and then you're done. No tracking, no ads, no algorithmic rabbit hole — just the day's signal on a page that's pleasant to read.

Features

  • Curated, sectioned brief. You define the sections — the default set is Tech, Startups & VC, Business, Health, Science, Local news, and Global — and their feeds; an LLM selects the top stories per section, deduplicates overlapping coverage, and writes a one-line "why it matters" for each.
  • Newspaper design. A warm, light, broadsheet layout: serif type, masthead, drop-capped lead, pull-quote, and lettered section heads. Responsive — full width on desktop (two-column front page), edge-to-edge on mobile.
  • Location-aware weather. The page asks the browser for the reader's location and shows local weather, falling back to a configurable city.
  • Daily Word. A playable Wordle clone whose answer matches the official NYT puzzle for the day (with a local fallback word if the source is unreachable).
  • One static page, deployed to Vercel. Loads instantly; nothing to maintain.
  • Optional Hotline. Receive each edition as a text, and/or put an AI assistant in your texts — channel-agnostic (Telegram, iMessage, …). See below.
  • No dependencies. Pure Python standard library, Python 3.8+.

How it works

flowchart LR
    A[RSS / Atom feeds] --> D[gather]
    C[NYT Wordle] --> D
    D --> E[LLM: select + summarize → JSON]
    E --> F[render newspaper HTML]
    F --> G[deploy to Vercel]
    G --> H[optional webhook ping]
Loading

Data is gathered in Python, the LLM only transforms text it is handed (it is given no tools and no web access), the page is rendered from a fixed template, and the result is pushed to Vercel via its REST API. Weather is fetched client-side in the browser so it can reflect the reader's location.

Quickstart

Requirements: Python 3.8+, an Anthropic API key, and a Vercel account + token.

git clone https://github.com/<you>/tomo-news.git
cd tomo-news

cp config.example.json config.json   # edit sections, feeds, location, masthead
cp .env.example .env                  # add ANTHROPIC_API_KEY and VERCEL_TOKEN

python3 tomo_news.py --dry-run        # build site/index.html locally (no deploy)
python3 tomo_news.py                  # build + deploy to Vercel

Open site/index.html from the dry run to preview, then deploy for real.

Configuration

Everything is driven by config.json — masthead, sections, feeds, quotes, the LLM provider/model, the Vercel project, and the weather fallback city. See docs/configuration.md for every field.

Secrets live only in .env (gitignored): ANTHROPIC_API_KEY, VERCEL_TOKEN, and an optional NOTIFY_WEBHOOK.

Deployment & scheduling

The script runs once and exits, so schedule it however you like — cron, launchd, or a GitHub Actions cron (a ready-to-use workflow is in .github/workflows/daily.yml). Details and the Vercel setup are in docs/deployment.md.

Optional: Hotline (get the brief as a text + AI in your texts)

hotline.py is an optional companion with two uses:

  • Receive the brief as a message. Point the daily job at a Telegram chat and it texts you the headline and link whenever a new edition publishes — handy for following along on your phone. No extra process required.
  • Chat with an AI over text. Run the hotline as a small daemon and it answers incoming messages on your channel using an LLM and a persona you set.

It's channel-agnostic: a two-method adapter (fetch_new / send) drives the loop. Telegram (cross-platform, the easy default) and iMessage (macOS) ship in the box; WhatsApp/Slack/SMS are a documented extension point.

python3 hotline.py            # run the assistant on your configured channel
python3 hotline.py --send "hello"   # push one message and exit

Full setup (creating a Telegram bot, getting your chat id, the macOS iMessage path, personas, and adding new channels) is in docs/hotline.md.

Security

  • Untrusted feed text is HTML-escaped before rendering; article links are restricted to http(s) and carry rel="noopener noreferrer".
  • The LLM call runs with all tools disabled so an injected headline can't trigger file or shell access, and it is handed only the gathered text.
  • Secrets are read from the environment (.env), never from tracked config.
  • The published page is public — don't put anything private in it. If you set a specific city instead of geolocation, note the page reveals that location.

Project structure

tomo-news/
├── tomo_news.py              # the brief pipeline (single file, stdlib only)
├── hotline.py                # optional: AI in your texts + brief delivery
├── config.example.json       # copy to config.json and edit
├── .env.example              # copy to .env and fill in secrets
├── examples/sample-brief.html# rendered sample output
├── docs/
│   ├── architecture.md
│   ├── configuration.md
│   ├── deployment.md
│   └── hotline.md
└── .github/workflows/
    ├── daily.yml             # scheduled build + deploy to Vercel
    └── pages.yml             # publish the live demo to GitHub Pages

Limitations

  • Weather is US-only. It uses the U.S. National Weather Service; readers outside the U.S. (or who deny location access) see the fallback city.
  • LLM cost. Each edition is one modest LLM call (a few cents on Sonnet-class models). The claude_cli provider is supported as an alternative.
  • The brief reflects the feeds and model you choose; "most significant" is the model's judgment over your sources, not an objective ranking.

License

MIT — see LICENSE.

About

A self-hosted daily news brief that reads like a newspaper — RSS + an LLM curate sectioned headlines into a fast, mobile-friendly page with location-aware weather, a market ticker, and a daily Wordle. Pure Python, zero dependencies. Optional Telegram/iMessage hotline.

Topics

Resources

License

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages