{% extends "base.html" %} {% block title %}How news48 Works — Docs | news48{% endblock %} {% block body_class %}page-docs{% endblock %} {% block content %} ← back to live feed

How news48 works

The system

The pipeline runs four stages in sequence, each automated and self-healing:

Find & Fetch

news48 monitors RSS feeds continuously, verifies source quality, and retrieves full articles from each URL. It handles paywalls, redirects, and anti-bot measures automatically.

Parse & Rewrite

Raw HTML is extracted and parsed. Summaries are generated, claims are identified, and content is rewritten for clarity without changing the meaning. Redundancy is removed.

Fact-Check & Verify

Important claims are extracted and checked against live evidence. Each claim gets a verdict (verified, disputed, mixed, unverifiable) based on available sources. Sources are linked and visible.

Publish & Expire

Stories are published with grouped topics, source links, and fact-check badges. They remain live for 48 hours, then are automatically deleted. No archive, by design.

Autonomous Operation Score

This score measures how independently news48 operates without human intervention. Each dimension reflects a key capability: self-starting (begins without prompting), self-monitoring (detects problems), self-healing (fixes issues), self-scaling (handles load), self-optimizing (improves over time), and error containment (prevents cascade failures). A score of 5.0 means fully autonomous in that dimension.

{% if assessment %}

{{ "%.1f"|format(assessment.overall) }} / 5.0

{{ assessment.level }}

Tier {{ assessment.tier.replace('T', '') }} · Assessment {{ assessment.architecture }} · Assessed {{ assessment.date }}

{% set dim_keys = [ ("self_starting", "Self-starting"), ("self_monitoring", "Self-monitoring"), ("self_healing", "Self-healing"), ("self_scaling", "Self-scaling"), ("self_optimizing", "Self-optimizing"), ("error_containment", "Error containment"), ] %} {% for key, label in dim_keys %} {% set dim = assessment.dimensions[key] %}
{{ label }}
{{ "%.1f"|format(dim.score) }}
{% endfor %}
{% else %}

Not yet assessed.

{% endif %}

MCP, without the mystery

news48 exposes its news data via the Model Context Protocol, so AI assistants like Claude, Cursor, and others can browse, search, and inspect stories in real time.

Remote Setup — Step by Step

1. Generate an API Key

From your project directory where docker-compose.yml lives:

Docker
docker compose exec dramatiq-worker news48 mcp create-key --label "my-assistant"

This prints a key like n48-abc123.... Save it — you cannot recover it later. You can create multiple keys for different tools or revoke them at any time. Keys are stored in Redis and prefixed n48- for secret scanner detection.

2. Configure Your MCP Client

Replace your-server-ip with your server's IP or hostname, and 8000 with the port where news48 is running (default: 8000, dev: 8765).

Claude Desktop / Cursor — mcp_config.json
{
  "mcpServers": {
    "news48": {
      "url": "http://your-server-ip:8000/mcp",
      "headers": {
        "Authorization": "Bearer n48-your-api-key-here"
      }
    }
  }
}

Both /mcp and /mcp/ work — the endpoint handles both paths without redirects. This is critical for browser-based MCP clients that break on 307 redirects during CORS preflight.

3. Manage Keys

From your project directory:

Docker
# List active keys (masked)
docker compose exec dramatiq-worker news48 mcp list-keys

# Revoke a key
docker compose exec dramatiq-worker news48 mcp revoke-key n48-...

Available Tools

Both local and remote endpoints expose the same 6 tools. The remote endpoint returns only fully parsed articles.

get_briefing Top stories, trending topics, breaking news
search_news Full-text search with sentiment & category filters
get_article Full article with fact-check claims & related coverage
browse_category Browse articles by category or tag
list_categories All active categories with article counts
list_countries Countries mentioned in recent articles

Troubleshooting

Common issues when connecting to the MCP endpoint and how to resolve them:

Symptoms & Fixes
❌ "Failed to fetch (check CORS?)"
    → The web container is not running, or a reverse proxy is stripping
      CORS headers. Check: docker compose ps web

❌ "401 Unauthorized"
    → Missing or invalid API key. Create one:
      docker compose exec dramatiq-worker news48 mcp create-key --label "my-client"

❌ "307 Temporary Redirect"
    → Old server version. Update to latest — both /mcp and /mcp/ now work.

❌ Connection refused
    → Wrong port or host. Verify the port mapping in docker-compose.override.yml
      (dev: 8765, prod: 8000).

Full documentation: docs/mcp-tools.md

Behind a Reverse Proxy (nginx)?

If you're deploying behind nginx, the proxy must preserve streaming responses and pass through CORS headers. Add this location block to your nginx config:

nginx Configuration
location /mcp/ {
    proxy_pass http://backend:8000/mcp/;
    
    # Streaming support (critical)
    proxy_buffering off;           # Disable buffering for streaming
    proxy_http_version 1.1;        # HTTP/1.1 required
    proxy_set_header Connection "";  # Keep-alive
    
    # Headers
    proxy_set_header Authorization $http_authorization;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    
    # CORS
    add_header Access-Control-Allow-Origin * always;
    add_header Access-Control-Allow-Methods "GET, POST, DELETE, OPTIONS" always;
    add_header Access-Control-Allow-Headers "*" always;
}

Critical: proxy_buffering off must be set, otherwise nginx will buffer the entire response and break streaming. The add_header ... always ensures CORS headers are returned even on error responses.

Self-host on your hardware

Deploy news48 in your own environment with Docker. Self-hosted means no data sent anywhere, complete control over your feeds and content, and your own LLM integration. The system runs autonomously—set your feeds, start the workers, and let it run.

Installation Script
curl -fsSL https://raw.githubusercontent.com/malvavisc0/news48/master/scripts/install.sh | bash

The full stack runs independently: fetcher, parser, fact-checker, and scheduler all coordinated via Redis message queues. Includes MySQL database, Redis cache, and local LLM integration via llama.cpp. Everything older than 48 hours is deleted automatically—by design.

CLI Access

The installer adds a news48 command to your PATH that runs CLI commands inside the worker container. After installation:

Terminal
news48 stats              # System statistics
news48 feeds list         # List all feeds
news48 briefing           # News briefing
news48 mcp create-key     # Create MCP API key
{% endblock %}