Skip to main content
Glama

🗞️ newsdesk-mcp

Your own curated news channel: ChatGPT researches, a Raspberry Pi remembers, Discord delivers.

Self-hosted MCP server · AI news digest for Discord · ChatGPT Scheduled Tasks · news deduplication with long-term memory · Raspberry Pi

CI License: MIT Python MCP Raspberry Pi

A ChatGPT Scheduled Task reads the news sources you choose every day and writes short, sourced summaries. Before posting, it asks this self-hosted MCP server "have we covered this already?" — the server matches candidates against a compact long-term memory on your Pi and returns only what is relevant, so ChatGPT posts only genuinely new stories and real updates, never the same story twice. The server then delivers the posts reliably to a Discord channel through a bot.

No LLM on the Pi, no crawler, no Docker, no cloud database: Python + SQLite + systemd, ~100 MB RAM.

In one sentence: a daily, AI-written news briefing in your Discord server that never repeats a story, posts follow-ups only when something materially changed, cites only outlets you allow, and runs unattended on a Raspberry Pi — with ChatGPT doing the research and a small MCP server doing the remembering.

## 🔄 Update: Austrian health insurer confirms data breach
-# 🛡️ Cybersecurity · 04 Oct 2026
📍 **Region:** Austria

**Since the last update:** The insurer has now officially confirmed the breach first claimed by a
hacker group on Thursday.

**Key facts:**
- Confirmation came from the insurer's own statement
- Police and the data protection authority are investigating

**Confirmed / unclear:** The breach is confirmed; whether medical records were taken is still open.

⭐ **Importance:** 7/10 — one of the largest health-data breaches in Austria.

🇦🇹 **Impact Austria:** About 1.2 million insured people should expect phishing mails and calls …

🌍 **Impact global:** Adds to a wave of attacks on European health insurers …

🔮 **Outlook:**
- Medical records turn out to be affected → **open (about even)** (insurer's statement)

📰 Sources: [ORF](…) · [Der Standard](…)

Illustrative example.

🆚 How is this different from an RSS-to-Discord AI bot?

Most "AI news bots" fetch RSS headlines, let an LLM rewrite them and post them. That works, but they forget what they posted after a few days, repeat stories that ten outlets cover, and cannot tell a rehash from a real development. newsdesk-mcp is built around exactly that problem:

Typical RSS + LLM bot

newsdesk-mcp

Who finds the news

RSS feeds

ChatGPT researches the web across your chosen outlets, can verify with primary sources

Duplicate detection

same URL/title, last few days

long-term memory: URL, fact fingerprints, full-text search, fuzzy matching — for years

Same story from 10 outlets

10 posts (or 1 by luck)

1 post

Follow-ups

reposted as "new" or dropped

posted as Update only when facts materially changed; Corrections supported

Sources

whatever the feed contains

enforced allowlist of outlets (lookalike domains rejected)

Missed days / outages

gap or flood

gap-free catch-up in bounded windows

Delivery

fire-and-forget

durable outbox, retries, no double posts, never pings @everyone

Token use

full articles to the LLM

compact candidates; history is matched locally, never sent

Costs

API tokens per run

covered by your ChatGPT plan (no API key needed)

When a simple RSS bot is enough for you, use one — it is easier to set up. Use this when you want a curated, non-repetitive, sourced briefing that keeps track of ongoing stories.

Related MCP server: Hearth

✨ Features

  • Long-term news memory — layered local duplicate detection (canonical URLs, fact fingerprints, FTS5, fuzzy matching) that tells duplicates from material updates and corrections; old topics stay findable for years without ever sending history to ChatGPT.

  • Token-efficient — ChatGPT sends compact candidates and gets back only the few relevant matches.

  • Never misses a day — research checkpoints; after an outage the gap is caught up in bounded windows, nothing is skipped silently.

  • Reliable Discord delivery — durable outbox, rate-limit aware, ordered, nonce-based safe retries; nothing is lost when Discord or the internet is down; never pings anyone. The bot shows as online ("Watching the news") whenever the Pi runs.

  • Secure by default — OAuth 2.1 (PKCE, DCR, RFC 9207), strict input validation, no arbitrary HTTP, secrets as systemd credentials, hardened units (systemd-analyze security ≈ 1.1).

  • Set and forget — watchdogs, health timer, verified backups, integrity checks, retention, safe upgrades with automatic rollback.

  • Only the sources you allow — an enforced allowlist of outlets; language, country and topics of the posts are set with one command.

  • Made for reading — every briefing also arrives as a calm, phone-sized PDF with Bionic Reading. The reader shows each day word by word, embeds its PDF, and creates a full-day MP3 locally on the Pi with Kokoro-82M's CPU voice. Google Translate can open the public page in 100+ languages.

🧭 How it works

flowchart LR
    T["ChatGPT Scheduled Task<br/>(daily, your sources)"] -- "MCP + OAuth 2.1" --> F["Tailscale Funnel<br/>(HTTPS)"]
    F --> A["newsrelay API<br/>on your Raspberry Pi"]
    A <--> D[("SQLite<br/>memory + outbox")]
    D --> W["delivery worker"]
    W -- "Discord bot" --> C["#news channel"]

Each run: begin_run (time window) → research → match_candidates (local dedup) → exactly one publish_digest or complete_noop. Details: ARCHITECTURE.md.

🚀 Quick start

You need: a Raspberry Pi (or any Debian/Ubuntu box) with Python ≥ 3.11 and systemd, a Tailscale account with Funnel enabled, a Discord server, and a ChatGPT plan with developer mode / custom apps (see known limitations).

# 1. on the Pi
git clone https://github.com/Oniichan187/newsdesk-mcp.git && cd newsdesk-mcp
sudo sh scripts/install.sh            # idempotent; creates user, venv, DB, systemd units
sudo sh scripts/expose-funnel.sh      # public HTTPS URL via Tailscale Funnel

# 2. Discord: create an application + bot (Developer Portal), invite it with
#    "View Channel" + "Send Messages", copy the channel id (Developer Mode → right-click channel)
sudo newsrelay set-bot-token          # paste the token (hidden input)
sudoedit /etc/newsrelay/config.toml   # discord_channel_id = "123…"
sudo systemctl restart newsrelay-worker
sudo newsrelay test-discord           # posts a test message and deletes it again

# 3. the passphrase you need when connecting ChatGPT
sudo cat /etc/newsrelay/secrets/owner_passphrase.txt
  1. Connect ChatGPT — Settings → Apps → Advanced settings → Developer mode → Create app, URL https://<your-pi>.<your-tailnet>.ts.net/mcp, authentication OAuth, approve with the passphrase. Step by step: CHATGPT_SETUP.md.

  2. Create the task — paste the default prompt (daily 18:00) or build your own (next section).

🎛️ Make it yours

Sources — the outlets that may be used are an allowlist in src/newsrelay/sources.toml: 30 German-language quality outlets, public broadcasters and independent newsrooms from Germany, Austria and Switzerland (taz, Die Zeit, Süddeutsche, Der Spiegel, Der Standard, ORF, Tagesschau, Deutschlandfunk, Republik, netzpolitik.org, Correctiv, ...). The relay rejects every other source URL, and the prompt builder lists exactly these outlets. Edit the file to use your own.

Group

Outlets

Germany: newspapers & magazines

taz · Frankfurter Rundschau · Die Zeit · Süddeutsche Zeitung · Der Spiegel · Tagesspiegel

Germany: public broadcasting

Tagesschau · Deutschlandfunk · ZDF · ARD · NDR

Germany: independent, investigative, media criticism

netzpolitik.org · Correctiv · FragDenStaat · Volksverpetzer · Übermedien · Belltower.News · Krautreporter

Austria

Der Standard · ORF · Falter · Profil · Dossier · ZackZack

Switzerland

Tages-Anzeiger · Berner Zeitung · Der Bund · Republik · Watson

Other

zufron.com

Prompt — language, country, topics and time in one command:

python3 scripts/build_prompt.py --language German --country Germany --time 07:00 > my-task-prompt.md

Everything else (channel, layout, memory, retention): CUSTOMIZING.md.

🛠️ Operating it

Command

Purpose

sudo newsrelay status

one-screen health: versions, API/worker, checkpoint, delivery backlog, DB size, latest backup

sudo newsrelay test-discord

send + delete a test message

sudo newsrelay outbox list [--all]

undelivered, failed and uncertain posts

sudo newsrelay outbox requeue <id> · requeue-failed --yes

resend after fixing Discord access

sudo newsrelay outbox delivered|resend|cancel <id>

resolve an uncertain delivery

sudo newsrelay backup · restore-test [file]

verified backup / restore rehearsal

sudo newsrelay revoke-tokens

log ChatGPT out (re-authorize afterwards)

sudo sh scripts/update.sh

upgrade from a checkout (migration rehearsal + automatic rollback)

Recovery playbooks: DISASTER_RECOVERY.md.

⚠️ Known limitations

  • ChatGPT approvals. OpenAI treats tools that change data as write actions, which may require confirmation; a Scheduled Task then pauses until you approve. This project needs exactly one write call per run. Whether your plan runs it fully unattended is up to OpenAI — see CHATGPT_SETUP.md.

  • Exactly-once delivery is impossible over HTTP in general; ambiguous sends are retried only with Discord's nonce de-duplication and otherwise parked for a decision, never blindly re-posted.

  • Backups are local (same SD card). Copy /var/lib/newsrelay/backups elsewhere now and then.

❓ FAQ

How do I get a daily AI news summary posted to my Discord server automatically? Run this MCP server on a Raspberry Pi (or any Linux box), connect it to ChatGPT as a custom app, and create a ChatGPT Scheduled Task with the provided prompt. Every day the task researches the news and publishes through the server's Discord bot.

How do I stop ChatGPT (or any AI news bot) from posting the same news again and again? That is the core of this project: before publishing, ChatGPT sends compact candidates to the server, which answers EXACT_DUPLICATE, LIKELY_DUPLICATE, POSSIBLE_EXISTING_TOPIC (with the previous facts) or NO_MATCH, using a local long-term memory. The server also re-checks duplicates when publishing.

Can ChatGPT Scheduled Tasks use a custom MCP server? ChatGPT supports custom MCP servers as apps in developer mode, and Scheduled Tasks can use apps. Write actions may require your approval depending on your plan; this project needs exactly one write call per run. See CHATGPT_SETUP.md for the current details and limitations.

Does the Raspberry Pi run an AI model? No. The Pi only stores memory, matches candidates and delivers to Discord (~100 MB RAM). The research and writing happen in ChatGPT.

Can I use other news sources, another language or country? Yes. Edit the allowlist in src/newsrelay/sources.toml and regenerate the prompt with scripts/build_prompt.py --language … --country … --time … — see CUSTOMIZING.md.

Is it safe to expose a server to the internet for ChatGPT? The endpoint requires OAuth 2.1 (PKCE), accepts only strictly validated news metadata, never fetches URLs, cannot run commands, and holds no secrets it could return. See SECURITY.md.

Does it work with Telegram, Slack or email? Not out of the box — delivery is Discord (bot or webhook). The transport is a small isolated module (publishing/discord.py); other targets are welcome as contributions.

📚 Documentation

ARCHITECTURE

components, run lifecycle, state machines, upgrades

CHATGPT_SETUP

connecting ChatGPT, OAuth details, OpenAI limitations

SCHEDULED_TASK_PROMPT

the ready-to-paste default prompt

CUSTOMIZING

sources, language, Discord, memory, retention

SECURITY

threat model, exposure, secrets, dependencies

DISASTER_RECOVERY

corrupted DB, lost SD card, revoked token, broken update

VERIFICATION

what was tested on real hardware

CHANGELOG

release history

🧪 Development

python3 -m venv .venv
PIP_CONFIG_FILE=/dev/null .venv/bin/pip install --require-hashes -r requirements.lock -r requirements-dev.lock
echo "$PWD/src" > "$(.venv/bin/python -c 'import sysconfig;print(sysconfig.get_paths()["purelib"])')/newsrelay.pth"
.venv/bin/pytest -q && .venv/bin/ruff check . && .venv/bin/mypy

Dependencies are pinned with hashes (scripts/lock.sh, pip-tools, PyPI only). Contributions welcome — see CONTRIBUTING.md.

📄 License

MIT. The bundled IBM Plex Serif fonts are under the SIL Open Font License. News content belongs to the respective publishers; the bot posts short summaries with links to the original articles.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables ChatGPT to safely interact with Windows workspaces through a loopback-only MCP server, with OAuth, bounded PowerShell tools, persistent jobs, and optional Cloudflare Tunnel exposure.
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables ChatGPT to run a durable, sandboxed Windows workspace from a local MCP endpoint: spawning bounded commands, reading, writing, patching and undoing files with receipts, storing large output as artifacts, scheduling and waiting on durable jobs and closed typed scatter flows with per-conversation mailboxes, and driving desktop UI Automation. It also supports recipes, checkpoints, append-only event logs, and continuations, all backed by a single local SQLite database with strict schemas and localhost-only binding.
    3 npm
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI clients to read Discord channels, recent messages, and searchable history, then turn that evidence into freshness-aware team context, briefs, decision baselines, and signed checkpoint diffs through remote MCP and GPT Actions. It keeps Discord access read-only while supporting OAuth/Bearer authentication for multiple clients.
    Apache 2.0