Skip to main content
Glama
qinshoudawang

Followin MCP

Followin-MCP

Projektübersicht

Dieses Projekt kann als Prototyp für eine ereignisbasierte Empfehlung für Krypto-Nachrichten verstanden werden:

  • Upstream: Abrufen von Originalinhalten über Followin API + adapters.py

  • normalizer.py: Standardisierung der Originalinhalte in strukturierte ContentItem-Objekte

  • service.py: Durchführung von explizitem Multi-Path-Recall in get_personal_feed, gefolgt von semantischer Ergänzung

  • clustering.py: Zusammenfassung mehrerer Inhalte zu einem EventCluster für dasselbe Ereignis

  • ranking.py: Generierung eines personalisierten Feeds mittels Multi-Signal-Heuristik-Ranker und MMR-Reranking

Zusammenfassung in einem Satz:

Ein Followin-MCP-Prototyp für Krypto-Nachrichten: Originalinhalte werden in strukturierte Items standardisiert und durch Multi-Path-Recall, semantische Ergänzung, Ereignis-Clustering und personalisiertes Ranking in einen ereignisbasierten Feed für den Benutzer umgewandelt.

Related MCP server: Daily News MCP Server

Verzeichnisstruktur

  • followin_mcp/ Einstiegspunkt des Python-Pakets

  • followin_mcp/core/ Kern-Geschäftslogik: Adapter, Modell, Normalisierer, Ranking, Service

  • followin_mcp/mcp/ Einstiegspunkt des MCP-Servers

  • followin_mcp/demo/ Test-Agent und Web-Demo

  • scripts/start_dev.sh Lokales Startskript

  • web/ Statische Frontend-Ressourcen

Kernmodule

  • followin_mcp/core/adapters.py Followin API-Adapterschicht

  • followin_mcp/core/models.py Datenmodelle

  • followin_mcp/core/taxonomy_rules.py Taxonomie / Regelkonfiguration

  • followin_mcp/core/normalizer.py Standardisierung von Originalinhalten, Entitätsextraktion, Erkennung von Ereignistypen

  • followin_mcp/core/clustering.py Ereignis-Clustering

  • followin_mcp/core/ranking.py Benutzerempfehlungs-Ranking und Erklärungen

  • followin_mcp/core/semantic_recall.py Embedding-Indexierung, semantischer Recall, Item-Ähnlichkeit

  • followin_mcp/core/service.py Service-Einstiegspunkt für MCP / Anwendungsschicht

Ablauf der Anforderungsverarbeitung

sequenceDiagram
    participant U as MCP client / agent
    participant M as mcp/server.py
    participant S as service.py
    participant A as adapters.py
    participant F as Followin API
    participant N as normalizer.py
    participant SR as semantic_recall.py
    participant C as clustering.py
    participant R as ranking.py

    U->>M: call tool
    M->>S: get_latest / search / get_personal_feed ...

    S->>A: fetch raw content
    A->>F: HTTP request
    F-->>A: raw payload
    A-->>S: raw items

    loop per raw item
        S->>N: normalize(raw)
        N-->>S: ContentItem\nentities / event_type / scores
    end

    S->>SR: enqueue normalized items
    SR-->>S: background indexing

    opt personal feed / semantic supplement
        S->>SR: recall(query, candidate pool)
        SR-->>S: semantic candidates / similarity
    end

    opt personal feed
        S->>C: cluster_same_event(items)
        Note over C: uses item embedding similarity
        C-->>S: EventCluster list
        S->>R: rank_for_user(user, clusters)
        Note over R: uses semantic_match_score
        R-->>S: ranked clusters
    end

    S-->>M: tool payload
    M-->>U: MCP response

Verarbeitungskette

1. MCP-Einstiegspunkt

  • mcp/server.py

    • Stellt 7 MCP-Tools bereit

    • Konvertiert MCP-Eingabeparameter in Aufrufe von service.py

    • Verantwortlich für die Serialisierung von ContentItem / EventCluster in die MCP-Rückgabestruktur

2. Abruf von Originalinhalten

  • service.py -> adapters.py

    • get_latest_headlines / get_project_feed / get_project_opinions / get_trending_topics Leitet die Paging-Funktionen des Upstreams direkt weiter

    • get_trending_feeds / search_content Gibt das aktuelle Snapshot-Ergebnis direkt zurück

    • get_personal_feed Führt zuerst expliziten Multi-Path-Recall und semantische Ergänzung durch, gefolgt von Ereignis-Clustering und personalisiertem Ranking

3. Inhaltsstandardisierung

  • normalizer.py

    • normalize(raw) konvertiert einen einzelnen Originalinhalt in ein ContentItem

    • Quellen der Entitätsextraktion:

      • Tag

      • Chain-Keyword

      • Projekt-Alias

      • Token-Alias

      • Themen-Alias

      • Dynamischer Alias (leichtgewichtige Entitätserkennung / Bypass-NER)

    • Ausgabe:

      • projects / tokens / chains / topics

      • entity_sources

      • entity_confidence (Stärke der Treffermethode)

      • event_type

      • credibility_score (Glaubwürdigkeit der Quelle)

      • importance_score (Berechnung nach vordefinierten Regeln)

4. Recall

  • "Recall" bezieht sich hier auf:

    • Zuerst eine Menge von ContentItem-Kandidaten aus einem größeren Pool abrufen

    • Zur Verwendung für nachfolgendes Clustering, Ranking und Paging

  • service.py führt im personalisierten Feed zuerst expliziten Multi-Path-Recall durch:

    • latest

    • trending

    • project

    • search

  • Ergebnisse des Multi-Path-Recalls werden zuerst nach item.id dedupliziert

    • Wenn dasselbe Item mehrfach getroffen wird, wird die Version mit dem stärkeren semantischen Match, höherer Wichtigkeit und dem aktuellsten Zeitstempel bevorzugt

5. Ereignis-Clustering

  • clustering.py

    • Eingabe: Liste von ContentItem

    • Ausgabe: Liste von EventCluster

    • Ziel des Clusterings ist das "selbe Ereignis", nicht dasselbe Projekt oder Thema

    • Hauptsignale:

      • Kompatibilität des Ereignistyps

      • Zeitfenster

      • Entitätsüberschneidung mit Konfidenzgewichtung

      • Titelähnlichkeit

      • Optionale semantische Ähnlichkeit

6. Personalisiertes Ranking

  • ranking.py

    • Eingabe: EventCluster

    • Ausgabe: Nach Benutzer sortierter Cluster-Feed

    • Hauptsignale:

      • importance_score

      • freshness_score

      • follow_affinity_score

      • interest_match_score

      • semantic_match_score

      • source_quality_score

      • risk_boost_score

    • mute_penalty

    • Abschließend ein MMR-artiges Diversifizierungs-Reranking

7. Embedding

  • semantic_recall.py

    • Normalisierte Items werden in einen asynchronen Embedding-Worker eingereiht (enqueue)

    • Item-Embeddings werden in der lokalen SQLite-Datenbank semantic_index.db gespeichert

  • Embeddings werden derzeit hauptsächlich für drei Dinge verwendet:

    • service.py führt im personalisierten Feed einen query-aware semantischen Recall / semantische Ergänzung basierend auf der aktuellen Abfrage und dem Kandidatenpool durch

    • clustering.py verwendet die Ähnlichkeit der Item-Embeddings als eines der Clustering-Signale

    • ranking.py bringt semantische Übereinstimmungssignale über den semantic_match_score in das finale Ranking ein

Personal Feed

  • get_personal_feed ist das derzeit einzige Tool mit Sitzungsverwaltung (Sessionized Feed Tool)

  • Hauptablauf:

    • Expliziter Multi-Path-Recall

    • Semantische Ergänzung

    • Ereignis-Clustering

    • Personalisiertes Ranking

  • service.py verwaltet intern den FeedSessionState, der hauptsächlich Folgendes speichert:

    • pending_clusters

    • delivered_event_ids

    • delivered_item_ids

    • source_cursors

  • Das Rückgabeergebnis enthält:

    • ranked_clusters

    • Aufgeklappte unterstützende items

    • next_cursor

    • has_more

  • Paging-Semantik:

    • Die erste Anfrage erstellt eine Feed-Sitzung und versucht, die sortierten Cluster in pending_clusters zu füllen

    • Die aktuelle Seite nimmt die ersten max_items Cluster vom Anfang von pending_clusters

    • Zurückgegebene Cluster / Items werden in der Delivered-Menge vermerkt, um Duplikate zu vermeiden

    • Nachfolgende "Mehr"-Anfragen verbrauchen bevorzugt die verbleibenden pending_clusters

    • Wenn der Puffer unter den Refill-Schwellenwert fällt, wird eine neue Runde von Recall, semantischer Ergänzung, Clustering und Ranking ausgelöst, um den Puffer aufzufüllen

Tool-Semantik und Kontextgrenzen

Die aktuellen MCP-Tools lassen sich in zwei Kategorien unterteilen:

  • Inhaltsabfragetools

    • get_latest_headlines

    • get_trending_feeds

    • get_project_feed

    • get_project_opinions

    • get_trending_topics

    • search_content

  • Empfehlungstools

    • get_personal_feed

Inhaltsabfragetools sind standardmäßig zustandslos:

  • get_latest_headlines / get_project_feed / get_project_opinions / get_trending_topics

    • Leiten die Paging-Funktionen des Upstreams weiter

    • Geben eine Seite der Ergebnisse für die aktuelle Anfrage zurück

  • get_trending_feeds / search_content

    • Geben das aktuelle Snapshot-Ergebnis zurück

    • Verwalten keinen zusätzlichen Paging-Zustand auf Service-Ebene

get_personal_feed ist das derzeit einzige zustandsbehaftete Tool:

  • service.py verwaltet einen kurzlebigen FeedSessionState

  • Nach außen wird nur der feed session cursor offengelegt

  • Intern speichert der Server:

    • pending_clusters

    • delivered_event_ids

    • delivered_item_ids

    • source_cursors

  • Nachfolgende "Mehr"-Anfragen verbrauchen bevorzugt die pending_clusters in der Sitzung

Die Aufgabentrennung ist grob:

  • Tool / Service-Ebene

    • Bereitstellung von Inhaltsabruf, Kandidaten-Recall, Clustering, Ranking und Feed-Sitzungsverwaltung

  • Agent-Ebene

    • Verantwortlich für die Tool-Auswahl und Kontextübernahme in Multi-Turn-Dialogen

    • Zum Beispiel: Fortsetzen der letzten Charge, Aufklappen des letzten Elements, Nachfragen basierend auf dem Ergebnis der letzten Runde

Aktuelle Paging-Semantik:

  • get_latest_headlines / get_project_feed / get_project_opinions / get_trending_topics

    • Rückgabe der nativen Cursor-Metadaten des Upstreams

  • get_personal_feed

    • Rückgabe von next_cursor und has_more

    • Die Semantik von cursor ist die Fortsetzung der Feed-Sitzung, nicht das einfache Umblättern einer Liste

Aktuell verwendete Technologien / Algorithmen

  • Python + MCP (FastMCP)

  • Followin API-Adapter

  • Regelbasierte Entitätsextraktion

    • Alias-Matching

    • Source-Tag-Matching

    • Keyword-Regeln

  • Ereignisklassifizierung

    • Regelbasiertes Multi-Signal-Scoring

  • Entitätskonfidenz

    • strong / medium / weak

  • Semantischer Recall

    • OpenAI Embedding

    • Kosinus-Ähnlichkeit

    • SQLite-Vektor-Persistenz

  • Clustering

    • Greedy Incremental Clustering

    • Konfidenzgewichtete Jaccard-Überschneidung

    • Jaccard-Ähnlichkeit der Titel

    • Item-Embedding-Ähnlichkeit

  • Ranking

    • Heuristischer linearer Ranker

    • MMR-artiges Diversifizierungs-Reranking

Was dem Prototyp im Vergleich zu industriellen Implementierungen noch fehlt

Recall / Empfehlungssystem-Fähigkeiten

  • Die Empfehlungsschicht hat noch keine echte langfristige / sitzungsbasierte Benutzerrepräsentation

  • Es gibt noch keine asynchrone Aktualisierungskette für Benutzerprofile, die durch Verhaltensprotokolle gesteuert wird

Inhaltsverständnis

  • Es gibt bereits eine leichtgewichtige Entitätserkennung / schwache NER (Tag, Alias, Regel, LLM-gestützte Extraktion), aber noch keine allgemeine Online-NER / Entity-Linking-Hauptkette mit Span-Offsets

  • Die Ereignistaxonomie ist noch ein regelbasiertes Kaltstartsystem, dem eine durch annotierte Daten gesteuerte Kalibrierung fehlt

  • Der credibility_score hängt derzeit hauptsächlich vom Quelltyp / Metadaten des Upstreams ab; aufgrund von Datenbeschränkungen gibt es noch keine feinere Zuverlässigkeit auf Quellenebene und keine Multi-Source-Verifizierung

Clustering

  • Embedding-Ähnlichkeit wird bereits als Clustering-Signal verwendet, aber insgesamt handelt es sich noch um ein heuristisches Multi-Signal-Clustering, noch kein trainiertes Paar-Klassifizierungs- / Merge-Modell

  • Für eine Weiterentwicklung zu einem Online-Clustering-System basierend auf einem persistenten Cluster-Store fehlen noch Cluster-Zuweisung sowie Fähigkeiten für den Cluster-Lebenszyklus wie tägliche Evolution, Aufspaltung und Zusammenführung

Ranking

  • Das Ranking verwendet bereits den Embedding-gesteuerten semantic_match_score, aber der Hauptteil ist immer noch ein heuristischer linearer Ranker mit manuell gewichteten Merkmalen, kein Learned-to-Rank

  • Die Empfehlungsschicht hat noch keine Verhaltensmerkmale wie Klicks, Verweildauer oder Teilen integriert

  • Die Empfehlungsschicht führt derzeit nur eine leichte MMR-Diversifizierung durch, noch keine systematische Quotensteuerung oder geschäftliche Einschränkungen

Aktuell offengelegte MCP-Tools

  • get_latest_headlines

  • get_trending_feeds

  • get_project_feed

  • get_project_opinions

  • get_trending_topics

  • search_content

  • get_personal_feed

Web-Demo

Wenn Sie "zufälliges Benutzerprofil + Multi-Turn-Dialog" intuitiver testen möchten, können Sie eine Web-Demo starten:

python3 -m followin_mcp.demo.webapp

Oder nach der Installation:

followin-mcp-web

Dann öffnen Sie:

http://127.0.0.1:8000

Diese Demo unterstützt:

  • Zufällige Generierung von Benutzerprofilen

  • Erstellung einer LangChain-Agent-Sitzung für das aktuelle Profil

  • Beibehaltung des Chat-Kontexts über mehrere Runden in derselben Sitzung

  • Beibehaltung des zuletzt verfügbaren next_cursor-Kontexts für Tools, die Paging unterstützen

  • Anzeige eines oder mehrerer Tool-Aufrufe, die in jeder Runde tatsächlich stattgefunden haben

  • Anzeige von Tool-Parametern und Ergebniskarten

Bitte stellen Sie vor dem Ausführen sicher, dass in .env konfiguriert ist:

FOLLOWIN_API_KEY=your_api_key
OPENAI_API_KEY=your_openai_api_key

MCP-Server

Die folgenden Funktionen wurden bereits als MCP-Tools offengelegt:

  • get_latest_headlines

  • get_trending_feeds

  • get_project_feed

  • get_project_opinions

  • get_trending_topics

  • search_content

  • get_personal_feed

Startmethode:

python3 -m followin_mcp.mcp.server

Oder nach der Installation verwenden:

followin-mcp-server

ACP-Agent

Wenn Sie den aktuellen Dialog-Agenten als ACP-stdio-Agent für ACP-unterstützende Clients bereitstellen möchten, können Sie Folgendes starten:

python3 -m followin_mcp.acp.server

Oder nach der Installation verwenden:

followin-acp-agent

Der aktuelle ACP-Wrapper verwendet direkt FollowinChatAgent:

  • Die ACP-Sitzung entspricht einer FollowinChatAgent-Sitzung

  • prompt() ruft intern das vorhandene chat_stream() auf

  • Assistant-Texte werden als Streaming-Chunks an den ACP-Client zurückgegeben

  • Das Benutzerprofil wird standardmäßig aus FOLLOWIN_ACP_PROFILE_JSON gelesen; falls nicht konfiguriert, wird ein eingebautes Standardprofil verwendet

Wenn Sie eine Verbindung zu einem lokalen acpx / OpenClaw herstellen möchten, kann ~/.acpx/config.json zunächst mit einer minimalen Konfiguration verwendet werden:

{
  "agents": {
    "followin": {
      "command": "/path/to/python",
      "args": ["-m", "followin_mcp.acp.server"],
      "cwd": "/path/to/followin-mcp"
    }
  }
}

Hier ist kein zusätzliches env erforderlich:

  • followin_mcp.acp.server führt beim Start load_dotenv() aus

  • Solange cwd auf das Projektstammverzeichnis zeigt, wird die .env im Repository gelesen

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    F
    maintenance
    Real-time cryptocurrency news, analysis, and price predictions for AI agents. 5 tools to search 50,000+ articles across 12 categories, filter by 120+ asset tickers, and access content with built-in attribution. Free with attribution. SSE and Streamable HTTP transport.
    4
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables querying and aggregating Chinese and international news along with multi-platform trending topics, featuring deduplication, event clustering, and article extraction for AI clients.
    7
    MIT