Metadata-Version: 2.4
Name: st-mcp-4pda
Version: 1.0.0
Summary: MCP для исследования устройств по форуму 4PDA — поиск тем, проблем, аналогов и сводка для покупки
License-File: LICENSE
Requires-Python: >=3.13
Requires-Dist: curl-cffi==0.15.0
Requires-Dist: markdownify==1.2.2
Requires-Dist: mcp[cli]==1.27.2
Requires-Dist: patchright==1.60.1
Requires-Dist: platformdirs==4.10.0
Requires-Dist: python-dotenv==1.2.2
Requires-Dist: selectolax==0.4.10
Provides-Extra: dev
Requires-Dist: ruff==0.15.17; extra == 'dev'
Requires-Dist: ty==0.0.49; extra == 'dev'
Description-Content-Type: text/markdown

# MCP 4PDA

MCP-сервер для чтения и анализа 4PDA. Личный инструмент, который даёт агенту доступ к содержимому форумов: агент не читает тысячи постов, а получает целевые выборки через встроенный поиск 4PDA.

[![FastMCP](https://img.shields.io/badge/FastMCP-1.27.2-000000)](https://github.com/modelcontextprotocol/python-sdk)
[![curl_cffi](https://img.shields.io/badge/curl__cffi-0.15.0-2A6DB2)](https://github.com/lexiforest/curl_cffi)
[![selectolax](https://img.shields.io/badge/selectolax-0.4.10-4B8BBE)](https://github.com/rushter/selectolax)
[![markdownify](https://img.shields.io/badge/markdownify-1.2.2-3776AB)](https://github.com/matthewwithanm/python-markdownify)

## 📑 Содержание

- [Возможности](#-возможности)
- [Быстрый старт](#-быстрый-старт)
- [Стек](#-стек)
- [Инструменты](#-инструменты)
- [Структура](#-структура)
- [Команды](#-команды)
- [Аутентификация](#-аутентификация)
- [Автор](#-автор)
- [Лицензия](#-лицензия)

## 🚀 Возможности

- Два режима исследования: точечный поиск конкретной проблемы и обзорный анализ со сводкой проблем, аналогов и вердиктов
- Поиск тем по устройству, шапка темы в Markdown с картой подтем и devdb-slug
- Карточка характеристик из каталога `devdb` — структурированные спецификации, чище шапки форума
- Агрегаторы на маркерах: болевые точки, аналоги, вердикты; сленг форума агент выводит из выборки и дозапрашивает через `extra_markers`
- Информирование о полноте: поля `returned`/`total`/`has_more`/`next_offset` и `incomplete` — агент видит, что получил не всё, и дозапрашивает
- Экономия контекста: поиск отдаёт id с автором и датой без текста, полные посты — только по запросу

## ⚡ Быстрый старт

Регистрация сервера в Claude Code:

```bash
claude mcp add 4pda -s user -- uvx --from st-mcp-4pda --index https://forgejo.emptyvessel.ru/api/packages/st/pypi/simple st-mcp-4pda
```

Установка навыка `4pda-warmup` — он оркеструет прогрев (см. [Аутентификация](#-аутентификация)):

```bash
/plugin marketplace add ssh://git@forgejo.emptyvessel.ru:49322/st/marketplace.claude.git
/plugin install st-4pda@st-claude
```

## 🛠️ Стек

| Технология  | Версия | Назначение                       |
| ----------- | ------ | -------------------------------- |
| Python      | 3.13+  | Язык разработки                  |
| mcp[cli]    | 1.27.2 | FastMCP, транспорт stdio         |
| curl_cffi   | 0.15.0 | HTTP-клиент с impersonate        |
| selectolax  | 0.4.10 | Разбор HTML форума               |
| markdownify | 1.2.2  | Конвертация HTML в Markdown      |
| patchright  | 1.60.1 | Прогрев сессии (видимый браузер) |

## 🧰 Инструменты

| Инструмент          | Назначение                                                 |
| ------------------- | ---------------------------------------------------------- |
| `warmup_session`    | Прогрев сессии через видимый браузер (проход Turnstile)    |
| `find_topic`        | Глобальный поиск тем по названию устройства                |
| `get_device_info`   | Шапка темы в Markdown, карта подтем, devdb-slug и forum_id |
| `get_devdb`         | Карточка характеристик из каталога devdb                   |
| `search_in_topic`   | Поиск по фразе внутри темы (id, автор, дата — без текста)  |
| `get_post`          | Полный текст поста в Markdown, опционально с контекстом    |
| `find_problems`     | Маркеры проблем → сгруппированные болевые точки            |
| `find_alternatives` | Маркеры аналогов → упоминания альтернативных устройств     |
| `analyze_device`    | Сводка «брать или нет»: инфо, проблемы, аналоги, вердикты  |

## 📁 Структура

```
mcp.4pda/
├── src/st_mcp_4pda/
│   ├── main.py          Точка входа: запуск сервера
│   ├── server.py        FastMCP и регистрация инструментов
│   ├── client.py        ForumClient (curl_cffi), cp1251, URL-шаблоны, обработка ошибок
│   ├── config.py        Чтение настроек из окружения и пути platformdirs
│   ├── parse.py         Разбор HTML: посты, шапка темы, результаты поиска
│   ├── format.py        Очистка тела поста, HTML→Markdown, информирование о полноте
│   ├── presets.py       Каркас маркеров: проблемы, аналоги, вердикты
│   ├── session.py       Запуск прогрева отдельным процессом и проверка сессии
│   ├── warmup.py        Кроссплатформенный прогрев через Patchright
│   ├── tools.py         Поиск тем, информация об устройстве, чтение постов
│   └── analyze.py       Агрегаторы на маркерах
├── scripts/
│   └── check.py         E2E-прогон инструментов через MCP-клиент
├── .env.example
├── Makefile
└── pyproject.toml
```

## 🔧 Команды

```bash
make install      Установка зависимостей
make e2e          Прогон инструментов через MCP-клиент
make lint         Проверка линтером
make fix          Автоисправление и проверка типов
make format       Форматирование кода
make clean        Очистка кэша
make purge        Удаление окружения и кэшей
```

## 🔐 Аутентификация

4PDA закрыт интерактивным Cloudflare Turnstile, прямой `curl_cffi` получает **403**. Схема гибридная:

1. **Прогрев** (`warmup_session`) — видимый браузер (Patchright) проходит Turnstile один раз и сохраняет `cf_clearance` с User-Agent в `session.json`.
2. **Работа** — быстрый `curl_cffi` (`impersonate=chrome131`) с этой cookie, без браузера.

Срок жизни cookie не отслеживается: при 403 любой инструмент возвращает `{"error": "session_expired"}` — сигнал повторного прогрева. Прогрев требует графической среды (`DISPLAY`) и возможен только локально.

Оркестрацию сессии берёт на себя навык `4pda-warmup` (плагин `st-4pda`): агент сам ловит `session_expired`, вызывает прогрев и подсказывает пройти Turnstile — пользователю остаётся один клик по галочке Cloudflare, изредка.

Настройки задаются переменными окружения:

| Переменная        | Назначение                           | По умолчанию   |
| ----------------- | ------------------------------------ | -------------- |
| `PDA_DELAY`       | Пауза между запросами, сек           | `2.0`          |
| `PDA_SESSION_DIR` | Каталог `session.json` и профиля     | `platformdirs` |
| `PDA_USER_AGENT`  | User-Agent (fallback к session.json) | Chrome 131     |
| `PDA_LOG_LEVEL`   | Уровень логирования                  | `INFO`         |

## 👤 Автор

**Станислав Байков** ([@st.rnd](mailto:st.rnd@mail.ru))

## 📄 Лицензия

Распространяется под лицензией MIT. Подробности в [LICENSE](LICENSE).
