Followin MCP
Followin-MCP
Обзор проекта
Этот проект можно рассматривать как прототип событийной системы рекомендаций для сферы криптоновостей:
Источник: получение исходного контента через
Followin API + adapters.pynormalizer.py: нормализация исходного контента в структурированныеContentItemservice.py: в методеget_personal_feedсначала выполняется явный многоканальный отбор (recall), затем семантическое дополнениеclustering.py: объединение нескольких элементов контента вEventCluster(событийный кластер)ranking.py: генерация персонализированной ленты с помощью эвристического ранжирования по нескольким сигналам + переранжирование MMR
Краткое резюме:
Прототип Followin MCP для криптоновостей: нормализация исходного контента в структурированные элементы, последующий многоканальный отбор, семантическое дополнение, кластеризация событий и персонализированное ранжирование для создания событийной ленты для пользователя.
Related MCP server: Daily News MCP Server
Структура каталогов
followin_mcp/Точка входа пакета Pythonfollowin_mcp/core/Основная бизнес-логика: адаптеры, модели, нормализатор, ранжирование, сервисfollowin_mcp/mcp/Точка входа MCP-сервераfollowin_mcp/demo/Тестовый агент и Web-демоscripts/start_dev.shСкрипт для локального запускаweb/Статические ресурсы фронтенда
Основные модули
followin_mcp/core/adapters.pyСлой адаптации Followin APIfollowin_mcp/core/models.pyМодели данныхfollowin_mcp/core/taxonomy_rules.pyКонфигурация таксономии / правилfollowin_mcp/core/normalizer.pyНормализация исходного контента, извлечение сущностей, распознавание типов событийfollowin_mcp/core/clustering.pyКластеризация событийfollowin_mcp/core/ranking.pyПерсонализированное ранжирование и поясненияfollowin_mcp/core/semantic_recall.pyИндексация эмбеддингов, семантический отбор, сходство элементовfollowin_mcp/core/service.pyСервисная точка входа для MCP / прикладного уровня
Последовательность обработки запросов
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Цепочка обработки
1. Точка входа MCP
mcp/server.pyПредоставляет 7 инструментов MCP
Преобразует входные параметры MCP в вызовы
service.pyОтвечает за сериализацию
ContentItem / EventClusterв структуру ответа MCP
2. Получение исходного контента
service.py -> adapters.pyget_latest_headlines / get_project_feed / get_project_opinions / get_trending_topicsПрямая передача возможностей пагинации вышестоящего APIget_trending_feeds / search_contentВозврат текущего снимка результатовget_personal_feedСначала выполняет явный многоканальный отбор и семантическое дополнение, затем переходит к кластеризации событий и персонализированному ранжированию
3. Нормализация контента
normalizer.pynormalize(raw)преобразует один исходный элемент вContentItemИсточники извлечения сущностей:
теги
ключевые слова блокчейнов
псевдонимы проектов
псевдонимы токенов
псевдонимы тем
динамические псевдонимы (легковесное обнаружение сущностей / побочный NER)
Результат:
projects / tokens / chains / topicsentity_sourcesentity_confidence(сила метода сопоставления)event_typecredibility_score(достоверность источника)importance_score(расчет по заданным правилам)
4. Отбор (Recall)
Под «отбором» здесь понимается:
Извлечение набора кандидатов
ContentItemиз общего пула контентаИспользование для последующей кластеризации, ранжирования и пагинации
service.pyв personal feed сначала выполняет явный многоканальный отбор:latesttrendingprojectsearch
Результаты многоканального отбора сначала дедуплицируются по
item.idЕсли один и тот же элемент найден несколькими путями, приоритет отдается версии с более сильным семантическим соответствием, более высокой важностью и более свежей датой
5. Кластеризация событий
clustering.pyВход: список
ContentItemВыход: список
EventClusterЦель кластеризации — «одно событие», а не один проект или одна тема
Основные сигналы:
совместимость типов событий
временное окно
перекрытие сущностей с весами достоверности
сходство заголовков
опциональное семантическое сходство
6. Персонализированное ранжирование
ranking.pyВход:
EventClusterВыход: отранжированная лента кластеров для пользователя
Основные сигналы:
importance_scorefreshness_scorefollow_affinity_scoreinterest_match_scoresemantic_match_scoresource_quality_scorerisk_boost_score
mute_penaltyВ конце выполняется переранжирование для диверсификации в стиле MMR
7. Эмбеддинги
semantic_recall.pyНормализованный элемент сначала ставится в очередь (
enqueue) асинхронного воркера эмбеддинговЭмбеддинги элементов хранятся в локальной базе SQLite
semantic_index.db
Эмбеддинги в настоящее время участвуют в трех процессах:
service.pyв personal feed выполняет семантический отбор / дополнение с учетом запроса (query-aware)clustering.pyиспользует сходство эмбеддингов как один из сигналов кластеризацииranking.pyвключает сигнал семантического соответствия в итоговое ранжирование черезsemantic_match_score
Personal Feed
get_personal_feed— единственный инструмент ленты с поддержкой сессийОсновной процесс:
явный многоканальный отбор
семантическое дополнение
кластеризация событий
персонализированное ранжирование
service.pyподдерживаетFeedSessionState, где хранятся:pending_clustersdelivered_event_idsdelivered_item_idssource_cursors
Результат содержит:
ranked_clustersразвернутые поддерживающие
itemsnext_cursorhas_more
Семантика пагинации:
Первый запрос создает сессию ленты и заполняет
pending_clustersотранжированными кластерамиТекущая страница берет первые
max_itemsкластеров из началаpending_clustersВозвращенные кластеры / элементы записываются в набор доставленных, чтобы избежать повторов
Последующие запросы «еще» продолжают потреблять оставшиеся
pending_clustersКогда буфер опускается ниже порога пополнения, запускается новый цикл отбора, семантического дополнения, кластеризации и ранжирования
Семантика инструментов и границы контекста
Текущие инструменты MCP можно разделить на две категории:
Инструменты запроса контента
get_latest_headlinesget_trending_feedsget_project_feedget_project_opinionsget_trending_topicssearch_content
Инструменты рекомендаций
get_personal_feed
Инструменты запроса контента по умолчанию не имеют состояния:
get_latest_headlines / get_project_feed / get_project_opinions / get_trending_topicsПередают возможности пагинации вышестоящего API
Возвращают одну страницу результатов для текущего запроса
get_trending_feeds / search_contentВозвращают текущий снимок
Не поддерживают дополнительное состояние пагинации на уровне сервиса
get_personal_feed — единственный инструмент с состоянием:
service.pyподдерживаетFeedSessionStateс коротким жизненным цикломВнешне открыт только
feed session cursorВнутри сервера сохраняются:
pending_clustersdelivered_event_idsdelivered_item_idssource_cursors
Последующие запросы «еще» продолжают потреблять
pending_clustersиз сессии
Разграничение ответственности:
Слой tool / service
Обеспечивает получение контента, отбор кандидатов, кластеризацию, ранжирование и управление сессией ленты
Слой agent
Отвечает за выбор инструментов в многоходовых диалогах и поддержание контекста
Например: продолжить предыдущую выдачу, развернуть предыдущий элемент, уточнить на основе предыдущего результата
Текущая семантика пагинации:
get_latest_headlines / get_project_feed / get_project_opinions / get_trending_topicsВозвращают метаданные курсора вышестоящего API
get_personal_feedВозвращает
next_cursorиhas_moreСемантика
cursor— продолжение сессии ленты, а не обычная пагинация списка
Используемые технологии / алгоритмы
Python + MCP (
FastMCP)Адаптер Followin API
Правиловое извлечение сущностей
сопоставление псевдонимов
сопоставление тегов источников
правила ключевых слов
Классификация событий
эвристический многосигнальный скоринг
Достоверность сущностей
strong / medium / weak
Семантический отбор
OpenAI embedding
косинусное сходство
векторная персистентность в SQLite
Кластеризация
жадная инкрементальная кластеризация
перекрытие Жаккара с весами достоверности
сходство заголовков по Жаккару
сходство эмбеддингов элементов
Ранжирование
эвристический линейный ранжировщик
переранжирование для диверсификации в стиле MMR
Чего не хватает прототипу по сравнению с промышленными решениями
Возможности отбора / рекомендательной системы
В слое рекомендаций еще нет полноценного разделения долгосрочного / сессионного представления пользователя
Нет цепочки асинхронного обновления профиля пользователя на основе логов поведения
Понимание контента
Есть легковесное обнаружение сущностей / слабый NER (теги, псевдонимы, правила, извлечение с помощью LLM), но нет основной цепочки универсального онлайн-NER / связывания сущностей со смещением (span offset)
Таксономия событий все еще опирается на правила «холодного старта», не хватает калибровки на основе размеченных данных
Текущий
credibility_scoreв основном зависит от типа источника / метаданных; из-за ограничений данных нет более детальной надежности на уровне источников и верификации по нескольким источникам
Кластеризация
Сходство эмбеддингов используется как сигнал, но в целом это эвристическая многосигнальная кластеризация, а не обученная модель классификации пар / слияния
Для перехода к онлайн-системе на базе постоянного хранилища кластеров нужны возможности назначения кластеров, а также жизненный цикл кластеров (эволюция, разделение, слияние)
Ранжирование
Используется
semantic_match_scoreна базе эмбеддингов, но в основе лежит эвристический линейный ранжировщик с ручными весами, а не обучение ранжированию (LTR)В слой рекомендаций не подключены поведенческие признаки (клики, время просмотра, шеринги)
Реализована только легкая диверсификация MMR, нет системного контроля квот и бизнес-ограничений
Текущие инструменты MCP
get_latest_headlinesget_trending_feedsget_project_feedget_project_opinionsget_trending_topicssearch_contentget_personal_feed
Web Demo
Если вы хотите протестировать «случайный профиль пользователя + многоходовой диалог», можно запустить Web-демо:
python3 -m followin_mcp.demo.webappИли после установки:
followin-mcp-webЗатем откройте:
http://127.0.0.1:8000Демо поддерживает:
Случайную генерацию профиля пользователя
Создание сессии LangChain-агента для текущего профиля
Сохранение контекста многоходового чата в одной сессии
Сохранение контекста
next_cursorдля инструментов с пагинациейОтображение вызовов инструментов, произошедших в каждом раунде
Отображение карточек с параметрами и результатами инструментов
Перед запуском убедитесь, что в .env настроено:
FOLLOWIN_API_KEY=your_api_key
OPENAI_API_KEY=your_openai_api_keyMCP Server
Следующие возможности уже представлены как инструменты MCP:
get_latest_headlinesget_trending_feedsget_project_feedget_project_opinionsget_trending_topicssearch_contentget_personal_feed
Способ запуска:
python3 -m followin_mcp.mcp.serverИли после установки:
followin-mcp-serverACP Agent
Если вы хотите использовать текущего агента как ACP stdio-агент для клиентов, поддерживающих ACP, запустите:
python3 -m followin_mcp.acp.serverИли после установки:
followin-acp-agentТекущая обертка ACP напрямую использует FollowinChatAgent:
Сессия ACP соответствует сессии
FollowinChatAgentprompt()вызывает существующийchat_stream()Текст ассистента передается клиенту ACP потоковыми чанками
Профиль пользователя по умолчанию считывается из
FOLLOWIN_ACP_PROFILE_JSON, если не настроен — используется встроенный профиль по умолчанию
Для подключения к локальному acpx / OpenClaw, в ~/.acpx/config.json можно использовать минимальную конфигурацию:
{
"agents": {
"followin": {
"command": "/path/to/python",
"args": ["-m", "followin_mcp.acp.server"],
"cwd": "/path/to/followin-mcp"
}
}
}Здесь не нужно дополнительно прописывать env:
followin_mcp.acp.serverпри запуске выполняетload_dotenv()Если
cwdуказывает на корень проекта, будет считан файл.envиз репозитория
This server cannot be deployed
Maintenance
Related MCP Connectors
Real-time curated crypto news for AI agents with sentiment, recaps, and search.
Crypto fundamentals, sentiment, whale tracking and influencer call accuracy for traders and agents.
Evidence-backed crypto due diligence with sources, freshness, and a runtime receipt on every call.
Real-time financial news & regulatory intelligence: cited search, fetch, summaries, collections.
Related MCP Servers
- AlicenseBqualityFmaintenanceReal-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.4MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to fetch news categories and hot news/tweets across various topics like crypto, DeFi, and AI.2352MIT
- FlicenseAqualityDmaintenanceProvides real-time Web3 research digest with macro news, KOL sentiment, market data, and personalized on-chain wallet analysis through four AI tools.4-
- AlicenseAqualityCmaintenanceEnables querying and aggregating Chinese and international news along with multi-platform trending topics, featuring deduplication, event clustering, and article extraction for AI clients.7MIT