
News Monitor Mcp
io.github.malkreidePublished by GitHub account malkreidev0.4.0Updated Oct 24, 2026
News monitoring via WorldNewsAPI: search, sentiment, headlines, trends, alerts (Swiss default)
Overview
A local MCP server that gives an assistant global news search, headlines, sentiment analysis, briefings, trends and alerts through WorldNewsAPI.
- What you can do
- Search and read news: full-text search across countries and languages, top headlines, article retrieval, source lookup and location-based search, plus newspaper front pages on paid plans. Analyze coverage: German and English sentiment scoring for an entity or topic, category trend detection per country, and multi-topic weekly media briefings. Manage alerts: create, list, check and delete persistent sentiment, volume or keyword alerts stored locally. Inspect and clear the server's in-memory response cache.
- When to use it
- Useful when you want an assistant to monitor how an organization, topic or region is portrayed in the press, produce leadership briefings, or track trends and headlines over time, especially for German- and English-language coverage.
- Requirements
- Python 3.11+ with uv or pip, run locally via uvx or pip install. A WorldNewsAPI key is required in the WORLD_NEWS_API_KEY environment variable; the free tier allows 50 points per day. Optional HTTP mode needs MCP_BEARER_TOKEN and network access to WorldNewsAPI.
Installation
In SourceWeft
- Open News Monitor Mcp in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
🇨🇭 Part of the Swiss Public Data MCP Portfolio
📰 news-monitor-mcp
[Version] [License: MIT] [Python 3.11+] [MCP] [Data Source] [CI]
MCP server for global news monitoring, media analysis and sentiment tracking via WorldNewsAPI — full-text search across 150+ countries, German/English sentiment analysis, top headlines, GL briefings, newspaper front pages and geo-search. API key required.
Overview
news-monitor-mcp transforms any AI assistant into a proactive media intelligence agent. The server connects LLMs like Claude with global news data: from Swiss institutional reputation monitoring to weekly leadership briefings and trend detection across categories.
Source: WorldNewsAPI (worldnewsapi.com) — the only freely available news API with German-language sentiment analysis.
API key required. Get a free key at worldnewsapi.com/console — free plan: 50 points/day, no credit card, backlink to worldnewsapi.com required (checked 2026-08-14).
Anchor demo query: "How has the Schulamt Zürich been portrayed in the media over the last 30 days, and what is the overall sentiment?"
Features
- 🔍 Full-text search – 150+ countries, 50+ languages, Boolean queries and exact phrase matching
- 📊 Sentiment analysis – German and English only (WorldNewsAPI unique feature); scores from −1 (negative) to +1 (positive)
- 📰 Top headlines – clustered by country and language, ranked by number of sources reporting
- 📋 Media briefing – multi-topic weekly report with sentiment overview for GL / leadership updates
- 🗞️ Newspaper front pages – digital covers from 6,000+ publications in 125 countries
- 📡 Trend radar – category-based trend detection (politics, technology, education, …) per country
- 📍 Geo-search – location-specific news (Zürich, Bern, Basel, Kanton Zürich, …)
- ☁️ Dual transport – stdio for Claude Desktop, Streamable HTTP for cloud deployment
Demo
"Create a media briefing for: AI in education, Volksschule Zürich, school digitalisation"
Data Sources
Prerequisites
- Python 3.11+
uvorpip- API key from worldnewsapi.com/console (free tier available)
Installation
Quickstart
Try it immediately in Claude Desktop:
"Show me the top news from Switzerland today" "How is the Schulamt Zürich covered in German-language media this month?" "Create a media briefing on: Volksschule Zürich, AI in education, school digitalisation"
Configuration
Environment Variables
Claude Desktop Configuration
Config file locations:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
After restarting Claude Desktop, all tools are available. Example queries:
- "Show me the top Swiss news today"
- "What is the media sentiment on AI in education this month?"
- "Create a weekly briefing for: Schulamt Zürich, Volksschule, KI Bildung"
- "Find all German-language articles about school digitalisation in the last 14 days"
- "Show me the front pages of Swiss newspapers today"
Cloud Deployment (Streamable HTTP)
For use via claude.ai in the browser (e.g. on managed workstations without local software):
Authentication is mandatory. The HTTP transport refuses any request without a valid Authorization: Bearer <token> header. Generate a token once and keep it secret:
Render.com (recommended):
- Push/fork the repository to GitHub
- On render.com: New Web Service → connect GitHub repo
- Set the following environment variables in the Render dashboard:
WORLD_NEWS_API_KEY— your WorldNewsAPI keyMCP_BEARER_TOKEN— the token generated aboveMCP_HOST=0.0.0.0— bind on all interfaces inside the containerMCP_ALLOWED_ORIGINS=https://claude.ai(optional, recommended)
- In claude.ai under Settings → MCP Servers, add the URL
https://your-app.onrender.com/mcpand configure the Bearer token as the auth header.
Scaling notes
This server is currently single-process / single-replica:
- The TTL cache lives in process memory (
NewsCache). If you run multiple Render or Kubernetes replicas, each replica has its own cache — hit-rates drop linearly with the replica count. - Alerts persist to a local
alerts.json(defaults to/datainside the container). Multiple replicas mounting the same persistent volume serialize viafcntl.flock, but for true cluster operation a shared store (Redis / Postgres) is needed — see the open findingSCALE-STATEFUL. - A pending confirmation (
input_required, see MCP Protocol Version) carries arequestStatethat the SDK seals with a key held only by this process, valid for 10 minutes. A retry that reaches another replica, arrives after a restart, or comes later than that is rejected with-32602 Invalid or expired requestState— nothing is deleted, the client calls again and the person is asked again. Running several replicas would need a shared key (request_state_security=onMCPServer), which this server does not configure. - On Render Free Tier, the container sleeps after ~15 minutes of inactivity and loses non-persistent state. Attach a Persistent Disk for
/dataif you need alerts to survive restarts. For Render Free + alerts you must accept that the cache is lost on every wake-up.
The MCP_CACHE_MAX_PER_TYPE cap (default 1000 entries / type) and the background sweep (MCP_CACHE_SWEEP_SECONDS, default 5 min) prevent the in-process cache from growing without bound.
Container image
A non-root multi-stage Dockerfile is included and built on every CI run. Inside the container the server defaults to --http, binds 0.0.0.0:8000, persists alerts under /data, and refuses to start if MCP_BEARER_TOKEN is missing.
Architecture
Project Structure
MCP Protocol Version
This server speaks two protocol eras over the same endpoint. The client's first request on a connection decides which one applies; a later claim from the other era is refused.
Both revisions are pinned in
tests/test_protocol_version.py and asserted
against the installed SDK, so a Dependabot bump of mcp cannot move either one
silently. The handshake ceiling is measured against a live initialize through
the assembled ASGI stack, not read off a constant name.
Note that the SDK's LATEST_PROTOCOL_VERSION is an alias for the modern
era, not for the handshake era — pinning against it alone would leave the era
that current clients actually negotiate free to drift.
Update policy. When the gate fails, do not edit the constant blindly: read
the spec changelog between the two revisions, verify the server still behaves,
then move the constant, this section, README.de.md and
CHANGELOG.md together.
What the server contributes in 2026-07-28
The SDK carries the envelope, server/discover and the error codes. Three
things it does not get right on its own, measured through the assembled ASGI
stack in tests/test_spec_2026_07_28.py:
- Identity. Without a handshake,
serverInfotravels inserver/discoverand in the_metaof every result. It used to carry"version": ""; it now names version (from the package metadata), title, description and website. - No sessions, in either era. The spec removed
Mcp-Session-Id(SEP-2567). The HTTP transport now runs stateless for handshake clients too: this server keeps no per-connection state — alerts are addressed by server-minted IDs passed as tool arguments, the cache is process-wide. A session no longer pins a client to one process; what still does is listed under Scaling notes. - Human confirmation via
input_required(SEP-2322) for the two destructive tools,news_alert_deleteandnews_cache_clear. When a2026-07-28client declares form elicitation, the server asks the person and only acts on their answer — aconfirm=trueset by the model no longer skips the question. Clients without form elicitation, and every handshake client, keep theconfirmflow unchanged.
Not changed on purpose: server/discover still lists prompts and
resources capabilities, because MCPServer registers both handlers
unconditionally; both lists are empty.
Testing
256 tests — 249 offline, 7 live (2 of which need no API key).
The live tests run daily at 06:17 UTC via
.github/workflows/live-tests.yml, not on
push: they measure the source, which changes independently of this repo.
Three live tests never ran
Until 2026-08-08 the repo's three live tests carried @pytest.mark.live but no
@pytest.mark.asyncio. Under pytest-asyncio's strict default that does not mean
"skipped" — it means async def functions are not natively supported. They
never executed, and anyone running -m live got three errors that said nothing
about the source. CI excludes -m live, so nothing reported it.
asyncio_mode = "auto" now makes a forgotten marker unable to cause this.
And running would not have shown much either:
The second branch matches the tool's own results heading, so the disjunction
could not fail. assert "Top-Schlagzeilen" in result and assert "Sentiment" in result likewise matched only the template. All three now assert something that
can fail, and they skip rather than fail when no key is set — "red" should
mean something is wrong, not that you have no key.
What is verified without a key, and what is not
tests/fixtures/api_routen.json records, for each of the five paths the tools
build, the status code and content type measured without a key. The gateway
routes before authenticating:
So a 401 means "this route exists". Without the control it would only mean "I
got a 401" — and that is not a given: epl.bag.admin.ch elsewhere in this
portfolio answers 401 for invented paths too. The recorder therefore re-measures
the control on every run and aborts if it stops discriminating.
Still open, and marked as such in PROVENANCE.md: whether the query
parameter names the server sends are correct. The API answers 401 regardless of
parameters, so no key means no verification. In global-education-mcp in this
same portfolio exactly that went wrong — two filters were silently inert
because unknown parameters were answered with HTTP 200 and dropped. That check
is outstanding, not done.
Empty result vs. changed response shape
data.get("news", []) answers two entirely different cases the same way: "the
source found nothing" and "the source answers differently than we assume". The
second becomes "0 results" — complete, plausible, formatted and wrong. That is
not hypothetical: in global-education-mcp the envelope had been renamed, so
every answer came back empty while 128 tests stayed green.
articles_of() now reads the envelope. An empty news stays an empty list — a
statement by the source. A missing news is not a statement about the news
but about the response, and is reported as such.
Example Use Cases
Schulamt / Institutional Communication
KI-Fachgruppe / AI Working Group
City Administration / Location Research
→ More use cases by audience →
Sentiment Analysis
WorldNewsAPI offers German-language sentiment analysis — rare among news APIs:
⚠️ Sentiment is only available for German (de) and English (en).
Safety, Limits & Responsible Use
Read-Only Operation
12 of the 15 tools carry readOnlyHint: true. All 9 monitoring tools (search,
headlines, sentiment, briefing, article, sources, front_pages, trend, geo) are
fully read-only and issue GET requests to WorldNewsAPI only. The 3 exceptions
are local-only operations: news_alert_create and news_alert_delete (write/
delete ~/.news-monitor-mcp/alerts.json) and news_cache_clear (clears
in-memory cache). None of the 15 tools modify any external data source.
API Rate Limits
Quotas checked against worldnewsapi.com/pricing on 2026-08-14. Undated, a quota is indistinguishable from a guess after a year. Two caveats worth knowing before you plan around this table:
- The API bills in points, not calls. What a request costs depends on the endpoint and its options, so there is no fixed "calls per day" figure — the earlier claim of 1,000 calls/month was both the wrong unit and the wrong magnitude.
news_front_pagesdoes not work on the free plan. Measured 2026-08-14:/retrieve-front-pageanswersHTTP 403 — This endpoint is not available on the free plan.The other 14 tools were reachable on the free key.- Articles per call is not plan-dependent. Measured 2026-08-14 on the free
plan:
number=50returned 50 articles,number=100returned 100, both HTTP 200 (available: 13037in each case). Earlier versions of this README claimed a cap of 10 for the free plan — that was this server's own default (DEFAULT_RESULTS), mistaken for a limit of the source.
The TTL cache (v0.2+) reduces redundant calls by up to 80%.
Data Privacy
- No personal data stored: The server holds no persistent user data. Cache entries are in-memory and reset on server restart.
- No profiling: The server retrieves publicly published journalism only. It is not designed for surveillance or personal profiling.
- Alert data: Alert configurations are stored locally in
~/.news-monitor-mcp/alerts.json— on your machine only, never transmitted.
Responsible Use
- Query public news only — do not use as a profiling tool for individuals.
- Sentiment scores reflect algorithmic analysis of journalistic tone, not verified editorial judgements.
- Results depend on WorldNewsAPI's indexing; Swiss regional media may be less well-covered than national outlets.
Terms of Service
Users must comply with:
This MCP server is an independent open-source project and is not affiliated with WorldNewsAPI.
Synergies with Other MCP Servers
news-monitor-mcp can be combined with other servers in the portfolio:
Changelog
See CHANGELOG.md
Contributing
See CONTRIBUTING.md (Deutsch).
Security & Compliance
- Report vulnerabilities privately: see SECURITY.md
- Swiss public-sector deployment: see
docs/isds-klassifikation.mdfor the ISDS / Schutzbedarfsfeststellung - Swiss data protection (revDSG) — duties, profiling, retention, drittlandtransfer:
docs/privacy-dsg.md - Audit history:
audits/
License
MIT License — see LICENSE
Author
Hayal Oezkan · malkreide
Credits & Related Projects
- Data: WorldNewsAPI – global news data with sentiment analysis
- Protocol: Model Context Protocol – Anthropic / Linux Foundation
- Related: swiss-culture-mcp – MCP server for Swiss cultural heritage data
- Related: srgssr-mcp – MCP server for SRG SSR Swiss public media
- Portfolio: Swiss Public Data MCP Portfolio
Installation
Run via uv's uvx — no clone or manual install needed. Add to your MCP client config (mcpServers for Claude Desktop, Cursor and Windsurf; use a top-level servers key for VS Code in .vscode/mcp.json):
Source: README.md at commit 13d36d0
Tools
0Version history
2- v0.4.0LatestSep 27, 2026
- v0.3.6Sep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts