Skip to main content
Glama

news-digest

A small personal news digest: RSS aggregator with optional LLM summarization, exposed as an MCP server for Claude Code / Claude Desktop (plus a FastAPI HTTP layer). Built as a hobby project "delve into Python", focused on asyncio, raw SQL, the Anthropic API and the Model Context Protocol.

README CONTENTS:

What it does

Register the server in Claude Code and ask "fetch the latest articles and give me an overview of today's AI news". The model calls the fetch_latest and get_articles_for_digest tools on its own and writes the digest from the source material.

The app is domain-agnostic: it digests whatever your feeds cover. The bundled defaults are tech feeds, so the examples below are tech - but point feeds.txt at economics, sports or local-news sources and everything downstream (archive, search, digest, topic filter) follows. A sample run with the defaults:

Today's AI news (Aug 11, 2026)

Local and edge inference - today's strongest theme

  • H3-metal (391 pts) - antirez wrote native MiniMax-H3 inference for Apple Silicon in plain C. The biggest AI story of the day on HN.

  • Needle 2 (472 pts) - a 14 MB agentic LLM: tool calls and structured extraction on phones and Raspberry Pi 5 (~500 tok/s).

Business and society

  • As AI eats the web (693 pts, 744 comments) - how AI answers drain the web...

Related MCP server: junk-filter-mcp

Architecture

                    ┌─────────────────────────┐
  RSS/Atom feeds ──▶│  ingest.py              │
  (httpx async,     │  httpx.AsyncClient      │
   N sources        │  + feedparser (sync!)   │
   in parallel)     │  → list[Article]        │
                    └────────────┬────────────┘
                                 │
                                 ▼
                    ┌─────────────────────────┐
                    │  storage.py             │
                    │  SQLite, raw SQL        │
                    │  articles, sources      │
                    │  dedup via UNIQUE(url)  │
                    └────────────┬────────────┘
                                 │
                                 ▼
                    ┌─────────────────────────┐
                    │  llm.py                 │
                    │  Anthropic API:         │
                    │  classify (Haiku)       │
                    │  → rank → summarize     │
                    │  (Opus), structured out │
                    └────────────┬────────────┘
                                 │
                 ┌───────────────┴───────────────┐
                 ▼                                ▼
    ┌─────────────────────────┐     ┌─────────────────────────┐
    │  mcp_server.py          │     │  api.py                 │
    │  MCPServer, stdio       │     │  FastAPI, Pydantic      │
    │  tools: fetch_latest,   │     │  GET /digest/latest     │
    │  search, digest,        │     │  GET /articles          │
    │  source management      │     │                         │
    └─────────────────────────┘     └─────────────────────────┘
         ▲
         │ stdio transport
    Claude Code / Claude Desktop (MCP host)

Design decisions

  • Two phases of intelligence. Phase 1 MCP tools (fetch_latest, search_archive, get_articles_for_digest) return data only - the host model does the synthesis, so the server needs no API key. Phase 2 (make_digest) runs its own pipeline against the Anthropic API: a cheap model (Haiku) classifies every article, a stronger one (Opus) only summarizes the top N. With MCP you have to decide on which side the LLM call runs - both variants live here side by side on purpose.

  • SQLite + raw SQL, no ORM. A local single-user tool: the DB is one file, dedup is UNIQUE(url) + INSERT OR IGNORE, every query is parametrized. On a bigger schema I would reach for SQLAlchemy/SQLModel for the same reasons I use Drizzle in TypeScript.

  • feedparser runs via asyncio.to_thread. No blocking calls inside async code - either the library has an async variant (httpx), or it goes to a worker thread.

  • One dead feed never kills the run. fetch_feed returns None instead of raising; a failing source is skipped and the rest proceed.

Getting started

You will need two tools installed:

  • uv - Python package manager (also installs Python itself if you have none)

  • Claude Code - the MCP host you will talk to

You do not "run" this app directly - you clone it, register it as an MCP server and then talk to it through Claude. In your terminal:

git clone https://github.com/davpu/news-digest
cd news-digest
uv sync
claude mcp add news-digest -- uv run --directory "$(pwd)" python src/mcp_server.py

The registration is scoped to the directory you run claude mcp add from - start your Claude Code sessions there (cd news-digest && claude) to see the server.

Then just ask, in plain language (examples assume the default tech feeds - with your own sources, ask about your own domain):

  • "fetch the latest articles and give me an overview of today's AI news"

  • "did we have anything about Kubernetes lately?"

or use the built-in prompt template as a one-click action: /mcp__news-digest__daily_digest (arguments: topic, days).

Phase 2 (make_digest, module llm.py) needs ANTHROPIC_API_KEY in .env (see .env.example).

Development

Each module doubles as a smoke test when run directly:

uv run python src/ingest.py      # feed fetching
uv run python src/storage.py     # SQLite layer

Configuration

Everything model- or content-facing lives outside the code, which is also what makes the app domain-agnostic:

  • feeds.txt - what to digest from: one feed URL per line, any domain; while empty, the app runs on bundled defaults (DEFAULT_FEEDS in src/ingest.py). You can also just ask Claude - the list_sources, add_source and remove_source tools manage this file conversationally, and each new feed is downloaded and validated before it is added. The setup_sources prompt template bootstraps a whole new domain in one go ("find me quality economics feeds")

  • prompts/interests.md - default relevance profile for the LLM classification step (phase 2)

  • what to digest: the daily_digest prompt template and the get_articles_for_digest tool both take an optional topic, so the same archive can produce an AI digest, a security digest, or anything else

Repo structure

  • src/ - the code (5 modules, see diagram)

  • prompts/ - model-facing text kept out of code

The MCP server also exposes a daily_digest(topic, days) prompt template (MCP prompts primitive), so hosts can offer the whole flow as a one-click action.

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server for generating rough-draft project plans from natural-language prompts.

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

  • MCP server for AI dialogue using various LLM models via AceDataCloud

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/davpu/news-digest'

If you have feedback or need assistance with the MCP directory API, please join our Discord server