camoufox-research
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| CAMOUFOX_VENV | No | Path to the virtual environment for Camoufox | |
| CAMOUFOX_CACHE_DIR | No | Directory for caching pages |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| batch_fetchA | Открывает НЕСКОЛЬКО URL в одном браузере — для глубокого ресёрча на 30-50 источников одним вызовом вместо серии холодных стартов. Кэш: уже посещённые URL возвращаются мгновенно, без браузера. Rate limit между переходами защищает от капчи. Батч ≥8 URL — параллельно (пул потоков, свой браузер на поток); число воркеров автоопределяется по ресурсам машины (слабый ПК — 1-2, мощный — 3-4), max_parallel — явное ограничение. Возвращает тексты с разделителями '--- URL: ...'. article_only=True — извлечь текст статьи (Trafilatura), без меню и баннеров. Пример: batch_fetch(urls=["https://docs.python.org/3/", "https://opencode.ai/docs/"], max_chars=6000, article_only=True) КОГДА: читать 10-50 URL одним вызовом (глубокий ресёрч после research_start / research_report). НЕ КОГДА: 1-2 страницы → fetch_page; URL ещё не собраны → research_start, sitemap, map_site сначала. |
| browser_clickA | Открывает URL и кликает по элементу: CSS-селектор (selector), текст ссылки/кнопки (target_text) или ref из snapshot (ref="3"). Возвращает страницу после клика. Пример: browser_click(url, target_text="Продолжить") |
| browser_navigateC | Текст страницы + первые ссылки. |
| browser_typeA | Открывает URL, вводит text в поле ввода (CSS-селектор), возвращает обновлённую страницу. Для форм поиска. |
| check_linksC | Проверка битых ссылок: собрать ссылки страницы, проверить HTTP-статусы, отчёт «[404] URL». Паттерн broken link checkers. |
| citation_packA | CIT-ПАКЕТ для синтеза отчёта: только verified ✅ источники с выжимками, одним блоком (цитируй по номерам [1]..[N]). Это гейт качества DEER/DeepResearch Bench: отчёт опирается на живые источники, а не на мёртвые ссылки. Если verify/выжимки ещё не прогонялись — достроит автоматически (сеть/браузер). КОГДА: пишешь отчёт с ссылками — брать ТОЛЬКО отсюда (гейт качества: без мёртвых ссылок). НЕ КОГДА: нужен файл на диске → citation_report; нужны выжимки без верификации → research_digest(refresh=False). |
| citation_reportA | Цитированный отчёт НА ДИСК: готовый MD-документ с выжимками verified ✅ источников (нумерация [1..N] + раздел «Ссылки»). Без path — exports/{camp_id}.cit.md. Отдаёт путь и размер — документ можно сразу отправить/приложить. КОГДА: готовый цитированный документ КАК ФАЙЛ (приложить, отправить, сохранить в репозиторий). НЕ КОГДА: текст нужен в ответ для синтеза → citation_pack. |
| crawlA | BFS-обход сайта: стартовая страница + внутренние ссылки (depth <= max_depth, всего <= max_pages). Тексты с разделителями '--- URL:'. Паттерн Firecrawl crawl. Кэш: повторный обход дешёвый. КОГДА: собрать содержимое САЙТА целиком (BFS, своя структура). НЕ КОГДА: нужны только URL без текста → map_site / sitemap (дешевле); нужен один раздел → fetch_page; сайт огромный → sitemap → фильтр pattern, потом crawl. |
| exportA | Сохранить результат (из extract/crawl) в файл: json/csv/md. path — свой или авто ~/.cache/camoufox-research/exports/. Паттерн data export. КОГДА: результат нужен на диске (CSV для таблиц, JSON для автоматизации, MD для отчёта). НЕ КОГДА: результат идёт в разговор/синтез → верни текст как есть; нужен готовый отчёт кампании → citation_report. |
| extractA | Извлечение по схеме (Firecrawl extract): schema — JSON {"поле": "css:.price"} или {"поле": {"selector": ".price", "attr": "text|href|src"}}. Селекторы: CSS ("css:", ".price"), XPath ("//div[@class='x']" или "xpath=..."). Возвращает JSON. llm=True — извлечение ИЗ ТЕКСТА страницы (LLM): schema — {"поле": подсказка} или {"поле": {"hint": "..."}}; работает, где селекторы хрупкие; требует LLM (DeepSeek/Ollama), иначе честный ответ «недоступен». КОГДА: нужны КОНКРЕТНЫЕ поля при СТАБИЛЬНОЙ структуре (CSS/XPath); структура неизвестна/меняется → llm=True. НЕ КОГДА: нужен сплошной текст → fetch_page / batch_fetch; нужны таблицы → table_extract; не знаешь селектор → snapshot сначала (найти элементы с ref). |
| extract_linksC | Собирает ссылки страницы (фильтр по подстроке pattern). |
| fetch_pageA | Текст страницы без HTML-мусора (статьи, доки, README). Кэш на сутки. article_only=True — текст статьи (Trafilatura), fallback — весь body. delta=True — delta-чтение: если контент не изменился с прошлого раза, вернёт маркер '[delta: ...]' вместо текста (не тратим токены на повтор). КОГДА: прочитать 1 страницу (JS/SPA — тоже) чистым текстом. НЕ КОГДА: страниц 10+ → batch_fetch; нужны поля по схеме → extract; повторное чтение → delta=True; нужен клик/ввод → session_start. |
| map_siteA | Карта сайта: все ссылки того же домена со стартовой страницы (без чтения содержимого). Паттерн Firecrawl map. |
| page_diffA | Дифф страницы с прошлым чтением (кэш vs свежее): мониторинг изменений, «что поменялось». Паттерн change detection. КОГДА: следить за страницей (цены, доки, новости) — второй и далее заходы покажут ИЗМЕНЕНИЯ. НЕ КОГДА: страница читается впервые (диффу не с чем сравнить) → fetch_page; нужна полная текстовая версия → fetch_page. |
| paper_searchA | Поиск научных статей: arXiv + Semantic Scholar (бесплатные API, без ключей). Возвращает статьи с годом/авторами/цитатами — первоисточники (tier 0), которых общий поиск почти не видит (паттерн индустрии: vertical index / arxiv-канал рядом с вебом). Кэш на сутки. Пример: paper_search("deep research agents") |
| pingA | Проверка связи: возвращает pong. |
| profile_loadA | Загрузить куки + localStorage профиля в живой браузер. |
| profile_saveA | Сохранить куки + localStorage живого браузера в профиль (логины не терять между сессиями). Путь: ~/.cache/camoufox-research/ profiles/.json |
| read_documentA | Текст из PDF/DOCX/XLSX: source — URL или локальный путь. Библиотеки pypdf/python-docx/openpyxl (pip install, если нет). КОГДА: документ (отчёт, прайс, спецификация) — часто ссылки с сайтов/в рассылках. НЕ КОГДА: HTML-страница → fetch_page; старые .doc/.xls → конвертируй libreoffice --convert-to docx/xlsx (не читаются). |
| researchA | Deep-поиск ОДНИМ вызовом — норматив «10 источников» за один ход. queries — несколько формулировок запроса (агент сам планирует подзапросы, паттерн gpt-researcher); сервер ищет по каждой, дедуплицирует URL и возвращает список со сниппетами. ⚠️ ЭТОТ ВЫЗОВ НЕ СЧИТАЕТСЯ В БЮДЖЕТЕ КАМПАНИИ (search_calls): research() — «в воздух» (нет camp_id); для бюджета используй research_start (кампания) — там волны считаются кросстаблично в campaigns.search_calls (budget_review.py / research_status). fetch_top>0 — сразу читает топ-N источников (тексты статей). Режим «20+ источников, не топы» (реальный ресёрч):
|
| research_criticA | КРИТИК-РЕВЬЮЕР (канон groundwork/DCM 2026): отчёт кампании → выделяет 3-5 НЕСУЩИХ утверждений и проверяет каждое против текстов источников (supported/unsupported/unverifiable). 11-57% ошибок цитирования у коммерческих агентов — мы меряем СВОИ. Требует DEEPSEEK_API_KEY или OLLAMA_HOST (иначе честный ответ «недоступен»), отчёт НЕ правит — только флагает. |
| research_digestA | Выжимки + верификация кампании: короткие пакеты (заголовок + первый абзац, ~700 символов) для синтеза и статус «жив/битый» каждого источника (гейт качества, паттерн DEER / DeepResearch Bench: verified citations). refresh=True — собрать выжимки и проверить живость заново (до 30 URL, параллельно); у фоновой кампании всё уже заполнено — refresh не нужен. max_age — свежесть verified в секундах (0 = проверить ВСЁ заново, напр. сомнение в кэше; 86400 = сутки TTL-кэш). КОГДА: кампания done — короткие выжимки + статус «жив/битый». НЕ КОГДА: нужен полный MD на диск → citation_report; кампания ещё running → сначала research_status/ждать маркер. |
| research_indexA | Сводка ВСЕХ кампаний: id · тема · статус · домены/цель · когда обновлена. md-таблица или json. Сырьё для «что мы уже охотили». |
| research_reportA | Отчёт кампании: список источников (титул/URL/домен/класс) в md-таблице или json. Сырьё для синтеза с цитатами. КОГДА: кампания done — собрать полный список для отчёта/синтеза. НЕ КОГДА: нужны только verified-цитаты с текстами → citation_pack; нужна сводка ВСЕХ кампаний → research_index; кампания running → research_status. |
| research_resumeA | ДОБОРКА кампании с места (паттерн LangGraph resume): берёт partial/failed и добирает недостающие РАЗНЫЕ сайты свежими углами (tutorial/comparison/case study). done — откажет («нечего добирать»), running — откажет (двойной запуск = гонка). Нулевая волна (те же домены по кругу) = честный стоп. Синхронно по умолчанию; большую доборку — background=True (ждать маркер .json). |
| research_startA | КАМПАНИЯ ресёрча: цель «N РАЗНЫХ сайтов» с счётчиком прогресса. Фон=True — охота уходит в отдельный процесс: лог + маркер done (~/.cache/camoufox-research/exports/.json) — ждать маркер, не поллить. Состояние в sqlite: сколько уникальных доменов реально собрано; угловые волны (лучшие практики/грабли/ альтернативы) добирают сами. Уникальных сайтов меньше цели → честный статус partial. Синтез: research_report(id) → список источников → batch_fetch по тем, что нужны текстом. feeds — RSS/sitemap URL: первая нога охоты БЕЗ поисковика (работает даже при мёртвом DDG); queries можно опустить. Перед стартом проверяет пульс крона сторожа — мёртвый крон предупредит, а не промолчит. Финальный отчёт автоархивируется (CAMOUFOX_REPORT_DIR, по умолчанию exports). llm_planner=True — Layer B, LLM (DeepSeek/Ollama) для 20+ вопросов [1]. КОГДА: большая тема «на N сайтов» в фон, счётчик в sqlite, маркер done; кормит research_report → batch_fetch → citation_pack. НЕ КОГДА: результат нужен прямо сейчас → research (синхронно); кампания уже running → research_resume (двойной запуск = гонка). |
| research_statusA | Прогресс кампании: статус, счётчик разных сайтов vs цель, топ источников по качеству (доки/код первыми). КОГДА: «как охота?» — глянуть статус/счётчик/топ за секунду. НЕ КОГДА: нужен полный список источников → research_report; нужны тексты/выжимки → research_digest. |
| rssC | Посты из RSS/Atom-фида: title, link, дата. Новости, блоги, changelog одним вызовом. Паттерн RSS scrapers. |
| screenshotA | Скриншот в PNG: активная вкладка сессии (без url) или страница по url. selector — только элемент. som=True — Set-of-Mark: красные рамки с номерами на интерактивных элементах (ref совпадают со snapshot). Возвращает путь к файлу. КОГДА: визуальная проверка (вёрстка, canvas, капча, картинки). НЕ КОГДА: нужны только тексты/ссылки → snapshot / fetch_page (сильно дешевле по токенам). |
| service_routeA | СЕРВИС-РОУТЕР (авто-подбор, паттерн MegaAgent orchestration): НЕ подсказывает, а САМ вызывает нужный тул по цели. goal — цель («поиск», «статьи», «мониторинг», «выжимки», «таблицы», «цитаты», «сессия», «страница», «сниппет», «скриншот»); query — параметр (тема/URL/camp_id). dry=True — только показать план (какой тул + аргументы), БЕЗ вызова. Возвращает РЕЗУЛЬТАТ тула (не совет). |
| session_backB | Назад по истории вкладки сессии. Требует session_start. |
| session_blockA | Заблокировать запросы, URL которых содержит pattern (напр. 'analytics', '**.gif'). Паттерн request blocking. Действует на активную вкладку. |
| session_clickA | Клик на живой странице сессии: CSS-селектор (selector), текст ссылки (target_text) или ref из snapshot (ref="3"). Возвращает текст ПОСЛЕ клика. Требует session_start. КОГДА: клик по элементу уже открытой страницы (сессия жива). НЕ КОГДА: сессии нет → session_start сначала; нужен разовый «открыл-кликнул-прочитал» → browser_click; нужен только список элементов → snapshot (получишь ref). |
| session_consoleB | Консоль активной вкладки: сообщения JS (error/warning/log). Требует session_start. |
| session_downloadA | Скачать файл. url — прямая ссылка; selector — кликнуть и поймать download (кнопки «Скачать»). Сохраняет в ~/.cache/camoufox-research/downloads/. Возвращает путь. |
| session_endA | Закрывает вкладку сессии, сбрасывает состояние. |
| session_evalA | Выполнить JS в активной вкладке сессии (MAIN world), вернуть JSON. Паттерн browser_eval. Требует session_start. |
| session_form_fillA | Заполнить форму РАЗОМ: fields — JSON {"селектор": "значение"}. submit — селектор кнопки отправки (кликнет, если задан). Паттерн form filling. Требует session_start. |
| session_key_pressA | Нажать клавишу на активной вкладке сессии: 'Enter', 'Escape', 'Tab', 'ArrowDown', 'F5' (имена Playwright keyboard). Требует session_start. |
| session_linksC | Ссылки текущей страницы сессии. Требует session_start. |
| session_navigateB | Переход на URL в ТЕКУЩЕЙ вкладке сессии (без новой страницы). Требует session_start. |
| session_networkB | Сеть активной вкладки: последние запросы (status, method, type, url). Видно AJAX и ошибки. Паттерн network inspection. Требует session_start. |
| session_resizeA | Изменить размер viewport активной вкладки (адаптивные сайты). Требует session_start. |
| session_scrollA | Скролл на живой странице сессии: bottom/top/down/up. Ждёт догрузку lazy-контента. Требует session_start. |
| session_select_optionB | Выбрать вариант в по значению/метке/индексу. Требует session_start. |
| session_startA | Начинает ЖИВУЮ сессию: открывает URL в постоянной вкладке serve-воркера. Состояние (скролл, ввод, клики) живёт между командами — «как человек в одной вкладке». Дальше: session_navigate, session_click, session_type, session_scroll, session_links, session_text, session_back. Закрыть: session_end. session_status — состояние вкладки. КОГДА: интерактив (клики, формы, скролл, ввод) — «как человек в одной вкладке», состояние живёт между командами. НЕ КОГДА: нужен только текст → fetch_page (быстрее, кэш); нужен разовый клик по URL → browser_click. |
| session_statusA | Состояние сессии: URL, заголовок, жива ли вкладка. |
| session_tabsA | Вкладки сессии: op=list (все с id/url/title), op=new (url или пустая), op=switch (tab_id — активной), op=close (tab_id). Несколько вкладок — как у человека. Требует session_start. |
| session_textB | Текст текущей страницы сессии (без навигации). Требует session_start. |
| session_typeB | Ввод в поле на живой странице сессии (CSS-селектор). Требует session_start. |
| session_unblockA | Снять блокировку запросов: по pattern или все (пустая строка). |
| session_uploadA | Загрузить файл в форму: selector — input[type=file], path — локальный путь. Паттерн form file upload. Требует session_start. |
| session_wait_forA | Ждать на живой странице сессии появления текста (text) или элемента (selector). Вернёт «дождался»/«не дождался». Требует session_start. |
| set_proxyA | Прокси на лету (runtime): 'host:port', 'user:pass@host:port', 'socks5://host:port'. Пустая строка — выключить. В serve-режиме браузер перезапускается с новым прокси. |
| sitemapB | URL'ы из sitemap.xml (+ .xml.gz, вложенные sitemapindex). Готовая карта ВСЕХ страниц сайта — фид для crawl. Паттерн sitemap crawlers. |
| snapshotA | Дерево интерактивных элементов с ref (aria-подобный YAML, ~2-5KB вместо HTML 100KB+). Клик по ref: session_click(ref="N"). Без url — текущая вкладка сессии; с url — открыть и снять. КОГДА: понять структуру страницы и получить ref для кликов (дёшево по токенам, в отличие от HTML). НЕ КОГДА: нужен текст → session_text / fetch_page; нужен вид глазами → screenshot(som=True) — там номера совпадают с ref. |
| statsA | Наблюдаемость: сколько раз вызывали каждый тул, среднее время, ошибки + последние вызовы (audit; секреты замаскированы). |
| table_extractA | HTML-таблицы страницы → CSV-текст (характеристики, прайсы, сравнения). Паттерн table export. КОГДА: на странице есть — прайсы/спеки/сравнения. НЕ КОГДА: данных нет в таблице → extract (произвольные поля); таблиц нет вовсе → fetch_page. |
| tool_hintA | РОУТЕР (паттерн MegaAgent-MCP): «для чего использовать какой тул». what — действие/вопрос, например «анализ страницы», «мониторинг», «статьи». Отвечает каким тулом и почему — вместо перебора 57 тулов вслепую. Сокращает выбор (индустрия: >40 тулов = −260% selection quality, роутинг решает). |
| tool_usageA | МЕТРИКА использования (28.08): какие тулы РЕАЛЬНО зовутся (persistent, из tool_usage.json). days>0 — показать только тулы с последним вызовом в пределах N дней; days=0 — топ всех. Внизу — «кандидаты на резку»: вызовы были >30 дней назад (метрика работает, а тул не используют). |
| web_searchA | Поиск в DuckDuckGo через анти-детект браузер: номер, заголовок, URL. pages>1 — пагинация (больше уникальных URL). include_snippets — сниппет под URL. Кэш на сутки. КОГДА: быстрый ответ по факту (новости, точный URL, один запрос). НЕ КОГДА: нужна охота на ≥10 разных сайтов → research / research_start; нужны научные статьи → paper_search. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| research_plan | Глубокий ресёрч темы: план «20+ источников, не топы». |
| extract_schema | Извлечение полей со страницы: поля → JSON-схема → extract. |
| monitor_page | Мониторинг изменений страницы (delta + page_diff). |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| _res_stats | Статистика вызовов тулов (audit, секреты замаскированы). |
| _res_cache | Инфо о кэше: размер БД, записи (pages/searches/deltas), TTL. |
| _res_session | Состояние живой сессии: URL, заголовок, жива ли вкладка. |
| _res_info | Инфо о сервере: имя, число тулов, список. |
| _res_health | Healthcheck для production (MCP Best Practices 9,11): uptime, версия, rate-limit, auth. |
TDQS
Scored across 61 tools
Many tools are clearly isolated by prefix and detailed when/not-when guidance, but there are multiple easy-to-confuse pairs: browser_click vs session_click, fetch_page vs session_text, research vs research_start, citation_pack vs citation_report, and even service_route vs tool_hint. The descriptions reduce ambiguity, but with 61 tools an agent still faces non-trivial selection risk.
Names are consistently lowercase snake_case and mostly follow a verb_noun or prefixed action pattern like session_navigate, research_start, extract_links, and map_site. A few bare nouns like rss, sitemap, snapshot, ping, and stats break the pattern, but they are readable and predictable enough.
61 tools is far too many for a single MCP server, even for a broad browser-research assistant. The 23 session_* tools, duplicated browser_* one-shot equivalents, and meta-tools like service_route, tool_hint, stats, and tool_usage could be consolidated or split into separate servers.
The tool surface covers the full research workflow: search, deep research campaigns, resuming, status, reporting, digesting, citation packs, document reading, extraction, table extraction, browsing, live sessions, screenshots, proxies, profiles, and export. There are no obvious dead ends; lifecycle tools exist for both research campaigns and browser sessions.