Skip to content

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

comet-research

Claude Code plugin • MIT License

Claude Code плагин, который подключает браузер Perplexity Comet как источник веб-поиска — с минимальным расходом токенов и приватностью истории.

  • 💬 comet_answer возвращает синтезированный ответ Perplexity (Pro) + цитаты [{n, title, url}] — выжимку по нескольким источникам одним вызовом.
  • 🔎 comet_search возвращает сжатый список [{title, url, snippet≤200}] (до 10), а не полный HTML/текст страницы.
  • 📄 comet_read_page отдаёт только основной текст статьи, обрезанный до max_tokens, с пометкой [TRUNCATED]. Полный текст лежит локально в кэше. Страница открывается в анонимной вкладке — ваши cookie на чужой сайт не уходят, а его трекеры не оседают в вашем профиле.
  • ➕ comet_get_more дозагружает следующий фрагмент из кэша (не тратя браузер).
  • 🧠 comet_task_start отдаёт Perplexity задачу, а не запрос: внутри одного треда проходит несколько промптов (план → проработка подвопросов → синтез), а наружу возвращает только итог и однострочные выжимки шагов.
  • 🕵️ Поиск идёт в основном (залогиненном) профиле с включённым Incognito/Temporary Perplexity: сохраняется Pro, но треды не попадают в постоянную историю и истекают за 24 часа.
  • ⚡ Локальный кэш: повторный URL и повторный поиск отдаются мгновенно (без браузера); кэш с TTL и лимитом (LRU-вытеснение), не растёт бесконечно.
  • 🚫 Никакого Perplexity/Sonar API — только управление реальным Comet через CDP под вашей веб-подпиской.
  • 🪶 Сырой CDP через нативный WebSocket — без puppeteer (одна зависимость, выше отказоустойчивость; совместимо с движком Comet Chrome 150).
  • 🔁 Само восстанавливается: если вкладку закрыли руками или оборвалось CDP-соединение — переподключается, пересоздаёт вкладку и повторяет операцию.

Требования

  • macOS, установленный Comet (/Applications/Comet.app).
  • Подписка Perplexity Pro/Max (для снятия лимитов).
  • Node.js ≥ 22 (нужен встроенный WebSocket; проверено на v22.18).
  • Claude Code с авторизацией через /login (API-ключ не нужен).

📥 Установка с нуля на новой машине

Репозиторий публичный — авторизация в GitHub не нужна.

Вариант A — одна команда (рекомендую)

curl -fsSL https://raw.githubusercontent.com/ArkHak/comet-research/main/bootstrap.sh | bash

Скачает bootstrap.sh, склонирует репозиторий в ~/comet-research и запустит установку. Передать параметры (см. ниже) или другой каталог:

# без вопросов и с авто-перезапуском Comet:
curl -fsSL https://raw.githubusercontent.com/ArkHak/comet-research/main/bootstrap.sh | bash -s -- ~/comet-research -- --yes

Вариант B — клонировать вручную, затем установить

git clone https://github.com/ArkHak/comet-research.git
cd comet-research
./install.sh

🚀 Если файлы плагина уже есть — установка одной командой

Один скрипт делает всё: проверяет окружение, ставит зависимости, подключает плагин к Claude Code навсегда и запускает Comet с нужным флагом.

cd comet-research
./install.sh

Что делает install.sh:

  1. Проверяет Node.js ≥ 22 и наличие Comet (иначе — понятная ошибка с подсказкой).
  2. Ставит зависимости MCP-сервера (npm install).
  3. Регистрирует плагин в Claude Code навсегда (marketplace + install, scope user) — больше не нужно каждый раз запускать --plugin-dir.
  4. Если CDP-порт закрыт — предлагает запустить Comet с флагом отладки (спросит перед закрытием текущих окон Comet), затем проверяет порт.

После этого перезапустите Claude Code — плагин загрузится сам в каждой сессии.

Режимы (меньше вопросов — больше автоматизации):

./install.sh --yes           # не спрашивать, перезапустить Comet автоматически
./install.sh --no-launch     # не трогать Comet (зависимости + постоянная регистрация)
./install.sh --no-register   # не регистрировать в Claude Code (только зависимости)
./install.sh --help

Больше ничего запускать вручную не нужно: если при первом поиске Comet окажется не запущен, MCP-сервер сам стартует его с флагом отладки (COMET_AUTO_LAUNCH=1 в .mcp.json). Исключение — если Comet уже запущен без флага: тогда выполните ./launch-comet.sh (сам не закрывает чужие окна).

Запуск Comet с CDP-флагом (вручную/повторно)

Плагин управляет Comet по Chrome DevTools Protocol, поэтому Comet должен работать с флагом удалённой отладки. Удобнее всего — скриптом (сам закроет старый экземпляр и дождётся порта):

./launch-comet.sh

Эквивалент вручную:

# Полностью закройте Comet, затем:
/Applications/Comet.app/Contents/MacOS/Comet --remote-debugging-port=9222
# Проверка, что порт слушается:
curl -s http://localhost:9222/json/version   # вернётся JSON с версией браузера

Порт можно поменять в .mcp.json (env.COMET_CDP_PORT).

Приватность: как это работает (важно)

Плагин работает в вашем основном (залогиненном) профиле Comet — чтобы сохранить Perplexity Pro, — но включает встроенный Incognito/Temporary-режим Perplexity: треды не сохраняются в постоянную историю и удаляются через 24 часа.

⚠️ Почему НЕ браузерное инкогнито: отдельное окно инкогнито (CDP createBrowserContext или ⌘⇧N) даёт анонимную сессию без логина — то есть без Pro. Проверено эмпирически. Поэтому плагин использует не браузерное инкогнито, а собственный приватный режим Perplexity в залогиненном профиле.

Что делает плагин автоматически перед первым поиском в сессии:

  1. Открывает perplexity.ai в вашем основном профиле.
  2. Проверяет, включён ли приватный режим; если нет — нажимает кнопку-призрак инкогнито (настоящим кликом мыши через CDP) и убеждается, что режим включён.
  3. Если включить приватный режим не удалось — возвращает предупреждение и не выполняет поиск (чтобы не засорять историю).
  4. Если вы не залогинены в Perplexity — сообщит, что Pro недоступен (войдите в аккаунт в Comet).

Требование: вы должны быть залогинены в Perplexity в Comet (для Pro).

Режим перепроверяется, а не подтверждается один раз. Приватный режим может слететь: вы нажали «Выйти из режима инкогнито», Perplexity сбросил состояние, истекли сутки. Раньше плагин верил первому подтверждению до конца сессии — и в таком случае молча писал бы в постоянную историю. Теперь у подтверждения есть срок годности (privateRecheckMs, по умолчанию 10 минут), а внутри срока перед каждым запросом состояние дёшево перепроверяется прямо на текущей странице (один вызов, без навигации). Если режим слетел — плагин включает его заново и сообщает об этом в notices.

Чтение внешних страниц

comet_read_page открывает чужие сайты не в вашем профиле, а в одноразовой анонимной вкладке:

  • сайт не получает ваши cookie, то есть не узнаёт вас;
  • его трекеры и cookie не оседают в основном профиле, а визит не попадает в историю браузера;
  • контекст уничтожается после каждого чтения, поэтому cookie сайта A не доживают до чтения сайта B.

Обратная сторона: страницы, требующие вашего логина (закрытые разделы, часть paywall), в анонимной вкладке не прочитаются. Для таких случаев — COMET_READER_ANONYMOUS=0, тогда чтение идёт в основном профиле, как раньше.

URL проверяется перед открытием. Разрешены только http/https и только публичные адреса. Локальные и внутренние ресурсы (localhost, 127.0.0.1, 192.168.*, 10.*, 172.16–31.*, 169.254.169.254, *.local) отклоняются — иначе плагин можно было бы навести на ваши локальные сервисы или на метаданные облака. Имя хоста при этом резолвится: домен, указывающий на внутренний адрес, тоже отклоняется.

♾️ Постоянное подключение к Claude Code

Плагин подключается навсегда (загружается в каждой сессии, без --plugin-dir) через механизм маркетплейсов Claude Code. install.sh делает это сам, но можно и вручную:

# из каталога плагина (после клона + npm install в mcp-server/):
claude plugin marketplace add "$(pwd)"        # добавить маркетплейс (scope user)
claude plugin install comet-research@mys_ya   # установить плагин навсегда

Плагин копируется в кэш Claude Code (~/.claude/plugins/cache/…) вместе с зависимостями, поэтому работает независимо от исходного каталога — его можно потом переместить или удалить.

Перезапустите Claude Code, затем проверьте:

  • /mcp — сервер comet-research в списке, инструменты comet_search, comet_read_page, comet_get_more доступны.
  • /context — навык comet-research (SKILL.md) подхватился.
  • claude plugin list — строка comet-research@mys_ya … ✔ enabled.

Управление:

claude plugin update comet-research@mys_ya     # обновить после git pull (требует restart)
claude plugin disable comet-research@mys_ya    # временно отключить
claude plugin uninstall comet-research@mys_ya  # удалить плагин
claude plugin marketplace remove mys_ya        # удалить маркетплейс

При обновлении кода поднимите version в .claude-plugin/plugin.json и marketplace.json, затем claude plugin marketplace update mys_ya + claude plugin install comet-research@mys_ya — иначе кэш той же версии не перечитается.

На одну сессию (без постоянной установки)

claude --plugin-dir .

Инструменты

Инструмент Что возвращает
comet_answer(query, max_tokens=800) Синтезированный ответ Perplexity + citations: [{n, title, url}]
comet_search(query) Сжатый список источников [{title, url, snippet≤200}] (до 10)
comet_read_page(url, max_tokens=600) Основной текст статьи, [TRUNCATED] + cache_id
comet_get_more(cache_id, offset) Следующий фрагмент из кэша (работает и с cache_id из comet_answer)
comet_healthcheck() Самодиагностика: CDP, логин, приватный режим, парсинг ответа/источников, статус DOM-якорей
comet_task_start({task, context?, steps?, max_steps=4}) Запускает многошаговую проработку задачи в фоне, возвращает task_id
comet_task_status(task_id) Прогресс и выжимки шагов; по готовности — итог, цитаты, cache_id стенограммы
comet_task_cancel(task_id) Остановить проработку после текущего шага
comet_list_models() Модели ИИ, доступные сейчас в Perplexity: {current, models: [{name, badges, locked, checked}]}
comet_set_model(model) Переключить модель по подстроке названия (глобально, персистентно — см. ниже)

Пример использования

В диалоге с Claude:

Чем StateFlow отличается от SharedFlow в Kotlin?

Claude вызовет comet_answer(...) и получит готовую выжимку с цитатами — часто это закрывает вопрос одним вызовом. Если нужен список ссылок — comet_search(...); если нужно углубиться в конкретную страницу — comet_read_page(url).

Проработка задачи вместо одного запроса

Когда вопрос не закрывается одним ответом:

Разберись, какой подход к офлайн-синхронизации выбрать для нашего KMP-приложения.

Claude вызовет comet_task_start(...), и внутри одного треда Perplexity пройдёт несколько промптов:

план  →  шаг 1  →  шаг 2  →  шаг 3  →  синтез
        (каждый шаг видит контекст предыдущих — тред общий)

Работа идёт в фоне (обычно 1–6 минут), Claude опрашивает comet_task_status. В контекст возвращается только итог + по одной строке на шаг; полная стенограмма всех ответов остаётся в локальном кэше и доступна по cache_id через comet_get_more. На реальном прогоне: 4 запроса к Perplexity за 59 секунд, стенограмма 5992 символа, в контекст ушло 1651.

Задача не блокирует остальные инструменты: вкладка захватывается пошагово, и между шагами в неё пролезают обычные comet_search/comet_answer. Если такой вызов увёл вкладку, задача перед следующим шагом возвращается в свой тред по URL — контекст диалога при этом сохраняется.

Ограничения:

  • одновременно выполняется одна задача — вкладка у плагина одна;
  • каждый шаг тратит запрос Pro, поэтому max_steps ограничен (по умолчанию 4, максимум 6);
  • состояние задач живёт в памяти MCP-сервера: после перезапуска Claude Code старые task_id недоступны (стенограмма при этом остаётся в кэше).

Выбор модели ИИ

По умолчанию comet_search/comet_answer/comet_task_start отвечают той моделью, что выбрана в вашем профиле Perplexity. Управлять этим можно двумя инструментами:

  • comet_list_models() — список моделей, доступных прямо сейчас, и какая из них активна: {current, models: [{name, badges, locked, checked}]}.
  • comet_set_model({model}) — переключить модель. Сопоставление — по регистронезависимой подстроке названия ("sonar", "claude", "gemini" сработают), точное совпадение приоритетнее частичного.

Важно — это настройка ПРОФИЛЯ, а не одного вызова. Переключив модель, вы меняете её ровно так же, как ручным кликом в интерфейсе Perplexity: она остаётся активной для всех последующих запросов (comet_search, comet_answer, comet_task_start) любых сессий, пока её не сменят снова. Автоматического отката нет.

Список моделей нигде не захардкожен — comet_list_models/comet_set_model читают его из живого меню «Модель» в интерфейсе при каждом вызове, поэтому инструмент остаётся рабочим и после того, как Perplexity переименует или добавит модели. Модели уровня Max (в списке — locked: true) требуют отдельной подписки Perplexity Max: comet_set_model откажет с понятной ошибкой и ничего не переключит, если попросить такую модель. Среди нескольких совпадений по подстроке доступная модель приоритетнее запертой (Max).

Пресеты по умолчанию (GPT — для большинства задач, Claude — для кода)

Вместо точного названия модели comet_set_model принимает готовый пресет:

comet_set_model({ preset: "general" })  // по умолчанию GPT
comet_set_model({ preset: "code" })     // по умолчанию Claude

Настраиваются в mcp-server/config.js (modelPresets) или переменными окружения COMET_MODEL_GENERAL/COMET_MODEL_CODE (это подстроки для поиска в живом меню, а не точные имена — так же, как в comet_set_model({model})).

Пресет general применяется автоматически при первом запросе за сессию MCP-сервера — отдельно вызывать его не нужно, если только до этого не переключали на code. Для вопросов по коду переключайтесь на code явно через comet_set_model({preset:"code"}); автоматического отката обратно на general нет — при следующем не-кодовом вопросе переключайте вручную.

Вкладка Comet закрывается при завершении сессии

MCP-сервер держит одну рабочую вкладку на всю сессию (getWorkPage в incognito.js) — так поиски идут быстро, без пересоздания вкладки на каждый вызов. Но при завершении процесса (закрыли Claude Code, SIGINT/SIGTERM, естественное завершение stdio) вкладка теперь закрывается сама (closeSessionPage) — иначе она годами копилась бы в Comet между запусками Claude Code, засоряя окно вкладками-сиротами.

Проверка чистоты истории

После теста:

  1. Откройте Perplexity → Library / История.
  2. Убедитесь, что новых тредов от автоматических запросов там не появилось (в приватном режиме они не сохраняются и истекают за 24 часа).

Настройки (mcp-server/config.js)

Параметр Назначение По умолчанию
cdpPort Порт CDP Comet 9222 (env COMET_CDP_PORT)
autoLaunch Сам запускать Comet, если он не работает true (env COMET_AUTO_LAUNCH, 0 = выкл.)
maxResults Сколько результатов отдавать 10
snippetMaxChars Длина snippet 200
defaultReadMaxTokens Лимит текста в read_page 600
maxSearchesPerSession Лимит поисков за сессию (0 = выкл.) 0 (env COMET_MAX_SEARCHES)
cacheTtlMs TTL кэша страниц/ответов 86400000 (24ч, env COMET_CACHE_TTL_MS)
cacheMaxEntries Лимит записей в кэше (LRU-вытеснение) 300 (env COMET_CACHE_MAX)
searchCacheTtlMs TTL кэша результатов поиска 600000 (10 мин, env COMET_SEARCH_CACHE_TTL_MS)
taskDefaultSteps Шагов в проработке задачи по умолчанию 4 (env COMET_TASK_STEPS)
taskMaxSteps Максимум шагов 6 (env COMET_TASK_MAX_STEPS)
defaultTaskMaxTokens Лимит объёма итога задачи 1200 (env COMET_TASK_MAX_TOKENS)
taskStepTimeout Тайм-аут одного шага 120000 (env COMET_TASK_STEP_TIMEOUT_MS)
tabQueueTimeout Сколько ждать своей очереди на вкладку 180000 (env COMET_TAB_QUEUE_TIMEOUT_MS)
requirePrivate Отказ искать, если не включён приватный режим true
readerAnonymous Читать внешние страницы в анонимной вкладке true (env COMET_READER_ANONYMOUS, 0 = основной профиль)
privateRecheckMs Срок годности подтверждения приватного режима 600000 (10 мин, env COMET_PRIVATE_RECHECK_MS)
modelPresets.general Пресет модели для большинства задач (подстрока для поиска в меню) GPT (env COMET_MODEL_GENERAL)
modelPresets.code Пресет модели для вопросов по коду Claude (env COMET_MODEL_CODE)
autoApplyDefaultModel Применять пресет general автоматически при первом запросе за сессию true (env COMET_MODEL_AUTO_APPLY, 0 = выкл.)

Как включить лимит поисков за сессию

# например, не более 20 поисков
COMET_MAX_SEARCHES=20 claude --plugin-dir .

или измените maxSearchesPerSession в config.js.

Устранение неполадок

Симптом Причина / решение
«CDP недоступен» Comet запущен без флага отладки. Выполните ./launch-comet.sh (авто-запуск не закрывает уже работающий Comet).
«Не удалось включить приватный режим» Включите инкогнито Perplexity вручную (кнопка-призрак в шапке или ⌘⇧N) и повторите.
«Не залогинены в Perplexity» Войдите в свой аккаунт Perplexity в Comet (для Pro).
Пустые результаты Вызовите comet_healthcheck — покажет, что сломалось (CDP/логин/приватность/парсинг). Часто помогает повтор запроса.
Парсинг «поехал» после обновления Perplexity Все DOM-селекторы собраны в mcp-server/selectors.js — правьте там; comet_healthcheck покажет, какие якоря не нашлись.
«Вкладка Comet занята» У плагина одна вкладка, операции идут по очереди. Обычно достаточно повторить; если держит долгая задача — снимите её через comet_task_cancel (кто держит вкладку, видно в comet_healthcheck → tabQueue).
Закрыли вкладку плагина / перезапустили Comet Ничего делать не нужно: следующий вызов сам переподключится и создаст вкладку заново. Шаг comet_task, попавший на обрыв, помечается провальным, а работа продолжается со следующего.

Структура

Репозиторий — сам является плагином (без вложенности): .claude-plugin/ лежит в корне, поэтому claude plugin marketplace add <репозиторий> находит манифест сразу.

comet-research/
├── LICENSE                       # MIT
├── bootstrap.sh                 # скачать плагин с GitHub и установить (с нуля)
├── install.sh                   # авто-установка (если файлы уже есть)
├── launch-comet.sh              # запуск Comet с CDP-флагом (перезапуск при нужде)
├── .claude-plugin/
│   ├── plugin.json              # манифест плагина
│   └── marketplace.json         # манифест маркетплейса (source: "./" — репозиторий сам плагин)
├── .mcp.json                    # регистрация stdio MCP-сервера (+ COMET_AUTO_LAUNCH)
├── skills/comet-research/SKILL.md
├── mcp-server/
│   ├── package.json  # зависимости + метаданные npm-пакета (см. «Публикация»)
│   ├── index.js      # точка входа MCP (10 инструментов), версия — из package.json
│   ├── cdp.js        # сырой CDP-клиент (WebSocket), подключение + переподключение
│   ├── page.js       # обёртка вкладки: navigate / evaluate / waitForFunction
│   ├── incognito.js  # приватный режим Perplexity (профиль + Temporary) + перепроверка
│   ├── anon.js       # одноразовая анонимная вкладка для чтения чужих страниц
│   ├── url-guard.js  # запрет локальных/внутренних адресов (SSRF)
│   ├── selectors.js  # ВСЕ DOM-эвристики в одном месте (устойчивость к вёрстке)
│   ├── search.js     # comet_search + collectSources (вкладка «Ссылки»)
│   ├── answer.js     # comet_answer (ответ Perplexity + цитаты)
│   ├── reader.js     # comet_read_page / comet_get_more
│   ├── healthcheck.js# comet_healthcheck (самодиагностика)
│   ├── composer.js   # ввод в поле Perplexity: диалог в одном треде
│   ├── model.js      # comet_list_models/comet_set_model (выбор модели ИИ)
│   ├── tab-lock.js   # FIFO-очередь на единственную вкладку (withTab)
│   ├── tab-lock.test.mjs # тест очереди (нужен запущенный Comet)
│   ├── reconnect.test.mjs # тест восстановления после обрывов
│   ├── private-recheck.test.mjs # тест перепроверки приватного режима
│   ├── reader-privacy.test.mjs # тест изоляции cookie и URL-guard
│   ├── task/
│   │   ├── runner.js # comet_task_* — план → шаги → синтез, фоновое выполнение
│   │   └── prompts.js# шаблоны промптов и парсеры плана/выжимок
│   ├── cache.js      # файловый кэш + анти-дублирование
│   └── config.js     # настройки и лимиты
└── README.md

Публикация обновлений (для мейнтейнера)

При изменении кода: поднять version в трёх местах — .claude-plugin/plugin.json, .claude-plugin/marketplace.json (поле plugins[0].version) и mcp-server/package.json — затем закоммитить и слить в main. Пользователи с постоянной установкой обновятся через claude plugin marketplace update mys_ya

  • claude plugin update comet-research@mys_ya.

mcp-server/package.json подготовлен к публикации в npm (имя comet-research-mcp, без scope, bin со ссылкой на index.js). Публикация не обязательна — плагин полностью работает через клон + install.sh. Она даёт альтернативный, ещё более короткий способ установки (npx вместо локального node_modules), но требует отдельного npm-аккаунта и выполняется только вручную:

cd mcp-server
npm login              # интерактивно, свои учётные данные npm
npm publish --access public

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages