Repository navigation
v1.0.0: Stable. Opinion coverage, copied-article detection, simpler install
Status: stable. MuckScraper is out of beta. From here on, upgrades within
1.x never break your stored config or customizations (topics, RSS feeds,
prompts, scheduled fetches, ingestion blocks); anything that would is saved
for 2.0 and called out there. Since 0.8 this release adds opinion
coverage (an Op/Ed section with columns linked to the stories they argue
about, each with its stance, and a roundup of what each side says),
copied-article detection so one wire report under three mastheads counts
once, deep analysis for every edition article, past editions, and
Google News search feeds for the big outlets whose own feeds died. It
also makes a fresh install simpler (both secret keys generated on the first
run) and safer (a placeholder SECRET_KEY is refused), and moves to current
urllib3 and requests.
Added
OLLAMA_THINK(optional, blank by default). Set it tofalseto turn
off a thinking model's hidden reasoning (gemma4, qwen3, deepseek-r1), which
is most of the time those models spend per call. Blank keeps Ollama's
default, so existing installs are unchanged.- Read-only MCP server (
mcp_server/, docs indocs/MCP.md), off by
default behind themcpCompose profile. Gives an AI assistant health and
troubleshooting checks: run status and history, last run, filtered scheduler
logs, Ollama state (without waking the box), outage signs, edition lineups,
quality report, story/article lookup and search, scrape and bias coverage,
containers, search index, whether running code is current, and a runbook
lookup over the docs. The database connection refuses writes, the checkout
is mounted read-only, and HTTP access needs a bearer token (MCP_TOKEN). docker-restart-proxylists each container's start time and restart count,
and has a bounded, read-only log route (GET /containers/<name>/logs).- Op/Ed. Opinion pieces are still kept out of the news, but they are now
saved to their own table instead of being dropped, and listed on a new Op/Ed
page (sidebar, below the topics) with a time window, a Left / Center / Right
filter and search. A newop_edRSS bucket stores every entry of an
opinion feed straight to Op/Ed; ten default feeds, balanced across the
spectrum. On full runs, each new column is linked to the news story it
argues about (embedding match plus a yes/no check by the fast model), and a
story with two or more linked columns gets a short opinion roundup saying
what each side argues. Letters to the editor are never linked. - Copied articles are marked. An article that shares at least half its
text with another outlet's article in the same story (a syndicated wire
story, or one outlet running another's piece) is labelled "Same report as
..." on the story page, and is not counted as a separate source in story
selection, headlines, summaries or reports. - Deep analysis for every edition article with at least 500 characters of
text, shown in a Deep Analysis box on the article page. Sports reports first
decide whether the story is about a game, and stop assuming one. - Quality check for invented titles: the quality report flags summaries
and reports that call someone "former President ..." (or another former
office) when no source does. - Past editions. A Past editions page lists every edition, grouped by
month, and opens each one as it was published, read live from the
database, so opinion columns added to its stories since are there too. - A page for each Op/Ed piece: what it argues, the story it's linked
to, its text (signed-in readers only) and a link to the publisher. The
Op/Ed list and the story page's columns link there. - Opinion page per edition: the stories that got new opinion columns in
that edition, each column with a one-line stance. Every linked column now
gets a stance, not only the ones a roundup described. - Outlets without a working RSS feed (CNN, AP, Reuters, WSJ) come in
through Google News search feeds. Each link is resolved to the publisher's
own URL before anything is stored; an entry that can't be resolved is
dropped and retried next run. - Feed fallback URL: any RSS feed can have a second URL, fetched instead
when the feed answers an HTTP error or can't be parsed (set it on the RSS
Feeds page). - Signed-out article pages say in plain words how much of the article
could be read ("Fully read", "Publisher blocked full-text access", ...), and
why there is no summary when the text couldn't be read.
Changed
- Ingestion refuses more junk: fantasy-sports advice, "odds, predictions"
betting picks, Seeking Alpha contributor pieces, editorial cartoons (as
news and as Op/Ed), show and interview transcripts, and "News of the day"
digests. News about cartoons or transcripts is kept. HTML tags embedded in
feed titles are stripped. - Editions prefer stories covered by two or more outlets, not two
articles: one outlet's pair (a transcript plus its write-up) no longer
jumps ahead of single-source stories. - "former President" is fixed in code. Summaries, reports, headlines and
opinion roundups no longer call the current President or Vice President
"former" unless a source does. Prompt rules alone never stopped the model
doing it. - Back to Feed returns to where you were. Going back from a story or
article lands on the same card in the list, or the same row in Search,
instead of the top of the page. - On article pages, scrape details sit above the summary for signed-in readers.
- The dark top bar spans the full page width on All Stories, Grouped Stories
and Search. - Layout and navigation pass: every page has its back link in the same
place ("Back to Feed" returns to the list you came from, config pages go
"Back to Admin Tools"); the accent colour is the sidebar's indigo (blue is
left for Left); every page has the Light/Dark button and follows the saved
theme; the Headlines and Fetch top bars are sticky; and no page is wider
than a phone screen, upright or sideways. - The browser tab icon is the raccoon mascot.
- The quality checker accepts either label set when a prompt offers two
formats. seed_defaults()seeds prompts as the migrations leave them, so a fresh
install starts with the current prompt text.- Article summaries are shown as one paragraph, without the section labels.
- Phones: the top bar keeps the title, theme button and account control on
one line. - Default feeds: Google News searches replace the dead CNN, AP, Reuters,
WSJ and The Economist feeds; more right-leaning news feeds; and ten Op/Ed
feeds balanced left and right (theop_edbucket had none by default).
Existing installs get the new rows added and nothing else changed: the dead
feeds stay as they are, so disable them on the RSS Feeds page. - Install:
.env.sampleleaves the optional news API keys blank (no more
"still unedited" prompt for them) and suggests a starting model;
install.shcreates.envreadable by its owner only; the optional
Langfuse, n8n and Wake-on-LAN settings no longer print Compose warnings
when unset; a first start no longer prints a database traceback while
Postgres is starting. The first run ofinstall.shnow generates
SECRET_KEYandMEILI_MASTER_KEYwhen it creates.env, so you only
fill in the Ollama settings and the admin password. On an upgrade it
rebuilds the scheduler image too (before, the scheduler kept running the
old code until it was rebuilt by hand). - The restart proxy finds its own Compose project, so the Admin Tools
restart buttons work in a clone with any folder name (it assumed
muckscraper).COMPOSE_PROJECT_NAMEin its environment overrides it. - Outlet names: Politico, Reason, Newsmax and The Daily Wire now match
their AllSides entries.
Fixed
- A wedged Ollama no longer looks asleep. When the port accepts a
connection but nothing answers, the health probe now treats the box as
broken and the run fails fast, instead of waiting out hundreds of timeouts. - Edition dedupe: two stories sharing only country and leader names
("Russia", "Trump", "Ukraine") are no longer treated as the same event; one
shared word has to be something else. A six-outlet Ukraine story had been
dropped from two editions. - Headlines ending in a quotation keep their closing quote mark.
Removed
restart.sh(use./install.sh, the Admin Tools restart buttons, or
docker compose up -d <service>),create_admin.py(install.shcreates
the admin; add more on the Users page) andcatcode.sh(an old code-dump
helper).
Security
- The app refuses to start with the
.env.sampleplaceholder as its
SECRET_KEY. It used to accept it, and since that value is public, anyone
could forge a login session on an install that kept it (only possible by
editing.envby hand;install.shalways replaced it)..env.samplenow
shows the command to generate a key. - urllib3 1.26.20 -> 2.8.0 (decompression-bomb and redirect advisories,
relevant because the pipeline fetches pages from sites it doesn't control)
and requests 2.31.0 -> 2.34.2. The oldurllib3<2.0.0pin is gone.
Database
- Seven migrations:
f2a6c9e4b7d1(deep-analysis prompts),a7d3e9f1c2b4
(Op/Ed table),b3f7c1d9e5a2(Op/Ed links and roundups),c5d1e8a3f7b9
(copied-article columns),d8e2a4f6b1c3(opinion stance prompt),
e4b7c2a9d6f1(feed fallback URL),f7a1d3c5e8b2(new default feeds,
added only where missing). All are additive.
Upgrade Notes
-
Wait for a run to finish, then pull and run the installer:
git pull ./install.sh
It rebuilds the images (the scheduler and the restart proxy included),
applies the seven migrations and recreates the containers. By hand:
docker compose up -d --build, then
docker compose exec app flask db upgrade. -
If
.envstill has the sampleSECRET_KEY, the app now refuses to
start. Generate a key with
python3 -c "import secrets; print(secrets.token_hex(32))", put it in
.env, and rundocker compose up -d app scheduler. Everyone has to sign
in again afterwards. -
New default feeds are added; your own feeds are left alone. So the
old defaults the new ones replace stay enabled: on the RSS Feeds page,
disable the CNN, AP, Reuters and WSJ feeds (dead), The Economist's "world
this week" feed (weekly round-ups only) and National Review ingeneral
andright_enrichment(its columns were landing in the news; it now comes
in through Op/Ed). Their replacements are already in. -
New optional settings:
OLLAMA_THINK(blank keeps Ollama's default;
falseturns off a thinking model's hidden reasoning) andMCP_TOKENfor
the optional MCP server
(docker compose --profile mcp up -d --build mcp docker-restart-proxy).