News Monitor Mcp

io.github.malkreide由 GitHub 帳號 malkreide 發布v0.4.0更新於 Oct 24, 2026

News monitoring via WorldNewsAPI: search, sentiment, headlines, trends, alerts (Swiss default)

概覽

AI 產生的概覽

本機 MCP 伺服器,透過 WorldNewsAPI 讓助理進行全球新聞搜尋、頭條、情緒分析、簡報、趨勢與提醒。

可以做什麼
搜尋與閱讀新聞:跨國家與語言全文搜尋、頭條、文章取得、來源查詢、依地點搜尋,付費方案還可取得報紙頭版。分析報導:針對實體或主題的德語與英語情緒評分、依國家的類別趨勢偵測,以及多主題每週媒體簡報。管理提醒:建立、列出、檢查並刪除儲存在本機的情緒、數量或關鍵字提醒。檢視並清空伺服器的記憶體回應快取。
適用情境
適合讓助理監測某機構、議題或地區在媒體中的形象,產出給管理層的簡報,或長期追蹤趨勢與頭條,尤其適用於德語與英語報導。
執行需求
需要 Python 3.11+ 及 uv 或 pip,透過 uvx 或 pip 在本機執行。必須在環境變數 WORLD_NEWS_API_KEY 中提供 WorldNewsAPI 金鑰,免費額度為每天 50 點。可選的 HTTP 模式需要 MCP_BEARER_TOKEN,並需能連線至 WorldNewsAPI。
安裝前請注意
WorldNewsAPI 金鑰屬於憑證,必須妥善保密。用量以點數計費,頻繁查詢可能耗盡或超出免費額度。頭版功能需要付費方案。建立與刪除提醒會寫入本機提醒檔案,清空快取會捨棄快取資料。查詢與結果會以第三方資料傳送給 WorldNewsAPI。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 News Monitor Mcp,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

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.

🇩🇪 Deutsche Version


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
#ToolDescription
1news_searchFull-text news search in 150+ countries
2news_top_headlinesTop headlines by country and language
3news_sentiment_monitorSentiment analysis for entity or topic
4news_media_briefingMulti-topic weekly briefing report
5news_retrieve_articleFetch full article by ID
6news_search_sourcesFind available news sources by name/country
7news_front_pagesDigital newspaper front pages — paid plan required, see below
8news_trend_radarCategory-based trend detection per country
9news_geo_searchLocation-specific news search
10news_alert_createCreate a persistent alert (sentiment / volume / keyword)
11news_alert_listList configured alerts with status
12news_alert_checkEvaluate alerts against current data
13news_alert_deletePermanently remove an alert
14news_cache_statsCache hit-rate and entries by type
15news_cache_clearClear cache (entirely or per tool type)

Demo

[Media Briefing Demo]

"Create a media briefing for: AI in education, Volksschule Zürich, school digitalisation"


Data Sources

SourceAPI TypeContent
WorldNewsAPIREST JSON150+ countries, 50+ languages, full text, sentiment

Prerequisites


Installation

bash
# Recommended: uvx (no install step needed)uvx news-monitor-mcp
# Alternative: pippip install news-monitor-mcp

Quickstart

bash
# Start the server (stdio mode for Claude Desktop)WORLD_NEWS_API_KEY=your-key uvx news-monitor-mcp

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

VariableDefaultDescription
WORLD_NEWS_API_KEY–Required. API key from worldnewsapi.com
MCP_TRANSPORTstdioTransport: stdio or streamable_http
MCP_HOST127.0.0.1HTTP bind host. Use 0.0.0.0 only inside a container.
MCP_PORT8000Port for HTTP transport
MCP_BEARER_TOKEN–Required in --http mode. Bearer token clients must present in Authorization: Bearer <token>. Generate via python -c "import secrets; print(secrets.token_urlsafe(32))".
MCP_ALLOWED_ORIGINS–Optional CSV allowlist for the Origin header (DNS-rebinding protection). Example: https://claude.ai.
LOG_LEVELINFOLog level: DEBUG / INFO / WARNING / ERROR. Logs are emitted as JSON to stderr with automatic redaction of api-key= query params and Authorization: Bearer headers.
NEWS_MONITOR_ALERTS_DIR~/.news-monitor-mcpDirectory that holds alerts.json. The parent dir must not be a symlink (refused at startup as a defense against path-injection). File is created with mode 0o600, directory with 0o700.
NEWS_MONITOR_ALERTS_FILE–(Back-compat) explicit path to the alerts file. Same symlink check applies. Prefer NEWS_MONITOR_ALERTS_DIR.
MCP_ALERT_RETENTION_DAYS90Alerts older than this many days are deleted on server start (Privacy default per docs/privacy-dsg.md). Set to 0 to disable retention.
MCP_CACHE_MAX_PER_TYPE1000Maximum cache entries per tool type. When exceeded, the least-recently-used entry of that type is evicted. Set to 0 to disable the cap (unbounded growth — only safe for short-lived processes).
MCP_CACHE_SWEEP_SECONDS300Interval for the background task that removes TTL-expired entries from the cache. Set to 0 to disable the sweep (expired entries are still pruned lazily on news_cache_stats).

Claude Desktop Configuration

json
{  "mcpServers": {    "news-monitor": {      "command": "uvx",      "args": ["news-monitor-mcp"],      "env": {        "WORLD_NEWS_API_KEY": "your-api-key-here"      }    }  }}

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:

bash
python -c "import secrets; print(secrets.token_urlsafe(32))"

Render.com (recommended):

  1. Push/fork the repository to GitHub
  2. On render.com: New Web Service → connect GitHub repo
  3. Set the following environment variables in the Render dashboard:
    • WORLD_NEWS_API_KEY — your WorldNewsAPI key
    • MCP_BEARER_TOKEN — the token generated above
    • MCP_HOST=0.0.0.0 — bind on all interfaces inside the container
    • MCP_ALLOWED_ORIGINS=https://claude.ai (optional, recommended)
  4. In claude.ai under Settings → MCP Servers, add the URL https://your-app.onrender.com/mcp and configure the Bearer token as the auth header.
bash
# Local HTTP mode (binds 127.0.0.1 by default)WORLD_NEWS_API_KEY=your-key \  MCP_BEARER_TOKEN=$(python -c "import secrets; print(secrets.token_urlsafe(32))") \  news-monitor-mcp --http --port 8000
# Verify auth is enforcedcurl -i http://127.0.0.1:8000/mcp                                  # → 401curl -i -H "Authorization: Bearer $MCP_BEARER_TOKEN" http://127.0.0.1:8000/mcp

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 /data inside the container). Multiple replicas mounting the same persistent volume serialize via fcntl.flock, but for true cluster operation a shared store (Redis / Postgres) is needed — see the open finding SCALE-STATEFUL.
  • A pending confirmation (input_required, see MCP Protocol Version) carries a requestState that 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= on MCPServer), 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 /data if 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.

bash
docker build -t news-monitor-mcp .
docker run --rm -p 8000:8000 \  -e WORLD_NEWS_API_KEY=your-key \  -e MCP_BEARER_TOKEN=$(python -c "import secrets; print(secrets.token_urlsafe(32))") \  -e MCP_ALLOWED_ORIGINS=https://claude.ai \  -v news-monitor-data:/data \  news-monitor-mcp

Architecture

┌─────────────────┐    ┌──────────────────────────┐    ┌──────────────────────────┐│  Claude / AI    │────▶│   News Monitor MCP        │────▶│   WorldNewsAPI           ││  (MCP Host)     │◀────│   (MCP Server)            │◀────│   REST JSON API          │└─────────────────┘    │                            │    │   150+ countries         │                       │  9 Tools                   │    │   50+ languages          │                       │  Stdio | Streamable HTTP   │    │   Sentiment DE/EN        │                       └──────────────────────────┘    └──────────────────────────┘

Project Structure

news-monitor-mcp/├── src/│   └── news_monitor_mcp/│       ├── __init__.py│       └── server.py          # All 9 tools├── tests/│   ├── __init__.py│   └── test_server.py         # 20 tests (unit + live)├── pyproject.toml├── CHANGELOG.md├── CONTRIBUTING.md├── LICENSE├── README.md                  # This file (English)└── README.de.md               # German version

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.

EraRevisionWho reaches it
initialize handshake2024-11-05 … 2025-11-25What today's clients speak. The server answers with the revision asked for, or with the 2025-11-25 ceiling when the request asks for something newer.
Per-request envelope2026-07-28A request carrying the 2026-07-28 _meta envelope opens a modern connection.

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, serverInfo travels in server/discover and in the _meta of 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_delete and news_cache_clear. When a 2026-07-28 client declares form elicitation, the server asks the person and only acts on their answer — a confirm=true set by the model no longer skips the question. Clients without form elicitation, and every handshake client, keep the confirm flow unchanged.

Not changed on purpose: server/discover still lists prompts and resources capabilities, because MCPServer registers both handlers unconditionally; both lists are empty.


Testing

bash
# Unit + contract tests (no network) — this is what CI runsPYTHONPATH=src pytest tests/ -m "not live"
# Live tests. The route check needs no key; the data tests skip without one.PYTHONPATH=src pytest tests/ -m "live"
# Re-record the route inventory (writes tests/fixtures/ + PROVENANCE.md)PYTHONPATH=src python scripts/record_fixtures.py

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:

python
assert "Volksschule" in result or "Ergebnisse" in result

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:

PathResponse
the five paths the server builds401, application/json
a freely invented path (control)404, text/html

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

"How has the Schulamt Zürich been portrayed in media over the last 30 days?"→ news_sentiment_monitor(entity="Schulamt Zürich", language="de", days_back=30)
"Create a weekly media briefing for leadership"→ news_media_briefing(topics=["Volksschule Zürich", "KI Bildung", "Schuldigitalisierung"])
"What are Swiss media reporting on school digitalisation?"→ news_search(query="Schuldigitalisierung", language="de", source_country="ch")

KI-Fachgruppe / AI Working Group

"What are the current tech trends in Swiss press this week?"→ news_trend_radar(category="technology", source_country="ch", language="de")
"How are AI developments in education covered internationally?"→ news_search(query="AI education classroom", language="en", number=20)
"Compare Swiss and German media coverage of AI regulation"→ news_search(query="KI Regulierung", source_country="ch", language="de")→ news_search(query="KI Regulierung", source_country="de", language="de")

City Administration / Location Research

"What is being reported about Zürich school infrastructure?"→ news_geo_search(location="Zürich", query="Schule")
"Show today's front pages of Swiss newspapers"→ news_front_pages(source_country="ch")

→ More use cases by audience →


Sentiment Analysis

WorldNewsAPI offers German-language sentiment analysis — rare among news APIs:

ScoreLabelMeaning
> 0.3positiv 😊Positive coverage
−0.3 to 0.3neutral 😐Neutral / factual coverage
< −0.3negativ 😟Critical / negative coverage

⚠️ 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

ConstraintWorldNewsAPI Free TierPaid Plans
Quota50 points/day500 – 50,000 points/day
Articles/callUp to 100Up to 100
Historical depth30 daysExtended
Timeout per call30 seconds30 seconds

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_pages does not work on the free plan. Measured 2026-08-14: /retrieve-front-page answers HTTP 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=50 returned 50 articles, number=100 returned 100, both HTTP 200 (available: 13037 in 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:

CombinationUse Case
+ fedlex-mcpLaw meets discourse: legal framework + media coverage
+ global-education-mcpOECD stats + current media context
+ srgssr-mcpSwiss public media + international news comparison
+ swiss-environment-mcpEnvironmental data + media reporting
+ swiss-statistics-mcpBFS statistics + current media narrative
+ zurich-opendata-mcpCity data + local media coverage

Changelog

See CHANGELOG.md


Contributing

See CONTRIBUTING.md (Deutsch).


Security & Compliance


License

MIT License — see LICENSE


Author

Hayal Oezkan · malkreide


Credits & Related Projects

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):

json
{  "mcpServers": {    "news-monitor-mcp": {      "command": "uvx",      "args": [        "news-monitor-mcp"      ]    }  }}

來源:README.md,提交 13d36d0

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

2
  1. v0.4.0最新Sep 27, 2026
  2. v0.3.6Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分