Skip to main content
Glama
shi-kirill

hermes-docs-mcp

by shi-kirill
README.md
# hermes-docs-mcp

Локальный MCP-сервер, который даёт агенту полнотекстовый поиск и чтение
документации **Hermes Agent** (`hermes-agent.nousresearch.com/docs`) — офлайн,
из локального кэша, без скрейпинга сайта.

## Откуда берутся данные

Сайт документации сам публикует машиночитаемые выгрузки — ровно для того, чтобы
их скармливали языковым моделям:

| Файл | Что это | Размер |
|---|---|---|
| `/llms-full.txt` | вся документация одним markdown-файлом, страницы размечены маркерами `<!-- source: website/docs/….md -->` | ~4.9 МБ, 228 страниц |
| `/docs/llms.txt` | индекс всех страниц по разделам: заголовок, канонический URL, однострочное описание | ~43 КБ |

Сервер скачивает эти два файла (условными запросами по `ETag`/`Last-Modified`),
кладёт в кэш, разбирает на страницы и фрагменты по заголовкам и строит BM25-индекс
в памяти. Никакого парсинга HTML, приватных эндпоинтов и обхода защит: только
официальный экспорт, документация под MIT.

Текст, который возвращают инструменты, — это сторонняя документация. Для агента
это **данные для чтения, а не инструкции к исполнению**.

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

Два инструмента — контракт, который ждут удалённые коннекторы (в том числе
ChatGPT/Deep Research): `search` находит адресуемые фрагменты, `fetch` отдаёт
страницу за любым из них.

| Инструмент | Назначение |
|---|---|
| `search(query)` | поиск по документации; возвращает до 8 фрагментов с `id`, `title`, `url`, `text` и `heading_path`, плюс отдельным блоком инструкцию отвечать только по ним и ссылаться на `url` |
| `fetch(id)` | страница целиком в markdown: `id`, `title`, `url`, `text`, `metadata` (раздел, описание, список заголовков, признак усечения) |

`id` фрагмента — это `путь/страницы#N`, например `user-guide/features/mcp#3`.
`fetch` принимает и его, и путь страницы, и полный URL документации, и точный
заголовок.

**Про язык запроса.** Документация Hermes Agent англоязычная, а поиск здесь
лексический (BM25), не семантический: русский запрос не найдёт ничего. Поэтому
инструмент просит модель формулировать запрос по-английски, а на пустую выдачу
с кириллицей отвечает подсказкой перевести запрос и повторить. Отвечает
пользователю ассистент всё равно по-русски.

## Установка

Для разработки:

```bash
cd hermes-docs-mcp
uv sync
uv run hermes-docs-mcp   # stdio
```

Для использования из Claude — см. «Подключение» ниже: рантайм ставится отдельно,
**вне** `~/Desktop`, `~/Documents` и `~/Downloads`.

> **macOS:** Claude запускает MCP-серверы без доступа к этим трём папкам. venv,
> лежащий там, умирает ещё до старта Python:
> `PermissionError: Operation not permitted: .../.venv/pyvenv.cfg`,
> затем `Fatal Python error: init_import_site`. Репозиторий может лежать где
> угодно — важно только, где стоит рантайм.

Первый вызов любого инструмента, которому нужна документация, скачает выгрузки
(~5 МБ). Дальше всё работает из кэша; сеть нужна только при обновлении.

## Подключение

### Claude Code

Проектный `.mcp.json` рядом с репозиторием:

```json
{
  "mcpServers": {
    "hermes-docs": {
      "command": "/Users/вы/hermes-docs-mcp/.venv/bin/hermes-docs-mcp",
      "args": []
    }
  }
}
```

Чтобы Claude Code не спрашивал подтверждение, добавьте `"enabledMcpjsonServers": ["hermes-docs"]`
в `.claude/settings.local.json` проекта.

### Claude Desktop

```bash
./scripts/install-desktop-config.sh
```

Скрипт собирает wheel, ставит его в `~/hermes-docs-mcp/.venv` (путь меняется
через `HERMES_DOCS_MCP_PREFIX`) и прописывает этот бинарь в конфиг. Идемпотентен,
делает бэкап конфига, отказывается ставить рантайм в папку, закрытую от Claude.

> Запускайте **при полностью закрытом Claude** (Cmd+Q). Приложение держит
> `claude_desktop_config.json` в памяти и перезаписывает файл, пока работает,
> стирая записи, добавленные в обход него, — проверено, в пределах десяти секунд.

### Hermes Agent

В `~/.hermes/config.yaml`:

```yaml
mcp_servers:
  hermes-docs:
    command: uv
    args: ["--directory", "/opt/hermes-docs-mcp", "run", "hermes-docs-mcp"]
```

Агент, который умеет искать по собственной документации, сам находит нужные флаги,
ключи конфигурации и форматы `SOUL.md` вместо того, чтобы угадывать их.

## Деплой как удалённый коннектор

Локальный сервер работает только на той машине, где запущен. Чтобы коннектор
появился во всех клиентах сразу — в вебе, на телефоне, на других компьютерах —
его нужно где-то запустить и подключать по URL.

В репозитории есть `render.yaml`: в Render → **New → Blueprint** укажите этот
репозиторий, и сервис поднимется с нужными переменными. URL коннектора —
`https://<имя-сервиса>.onrender.com/mcp/` (слэш в конце желателен), транспорт —
**Streamable HTTP**, авторизации нет.

Что важно понимать про такой инстанс:

- он отдаёт **публичную документацию** и ничего больше: ни файлов, ни секретов,
  ни пользовательских данных;
- аутентификации клиентов у сервера нет, поэтому бинд за пределы loopback
  требует явного `HERMES_DOCS_MCP_ALLOW_PUBLIC_BIND=1` — случайно не выставится;
- обновлять документацию наружу нечем: инстанс сам перечитывает выгрузки по
  истечении `HERMES_DOCS_MCP_TTL`, но не чаще одного раза в
  `HERMES_DOCS_MCP_MIN_REFRESH` секунд (по умолчанию 300) — превратить его в
  кнопку «скачай пять мегабайт» не получится;
- на free-плане Render сервис засыпает без запросов — первый вызов после сна
  будет дольше обычного.

## Настройки (переменные окружения)

| Переменная | По умолчанию | Смысл |
|---|---|---|
| `HERMES_DOCS_MCP_BASE_URL` | `https://hermes-agent.nousresearch.com` | источник выгрузок; только https (http — лишь для loopback) |
| `HERMES_DOCS_MCP_CACHE_DIR` | `~/.cache/hermes-docs-mcp` | где лежит кэш; можно подсунуть заранее заполненный каталог |
| `HERMES_DOCS_MCP_TTL` | `86400` | через сколько секунд кэш считается устаревшим |
| `HERMES_DOCS_MCP_TIMEOUT` | `30` | таймаут HTTP, секунды |
| `HERMES_DOCS_MCP_OFFLINE` | не задана | `1` — никогда не ходить в сеть, работать только из кэша |
| `HERMES_DOCS_MCP_TRANSPORT` | `stdio` | `stdio`, `sse` или `streamable-http` |
| `HERMES_DOCS_MCP_ALLOW_PUBLIC_BIND` | не задана | `1` — разрешить HTTP-бинд вне loopback (осознанная публикация) |
| `HERMES_DOCS_MCP_PUBLIC_URL` | `RENDER_EXTERNAL_URL` | внешний адрес инстанса: с ним иконка отдаётся ссылкой, без него — инлайном. На Render подставляется сам |
| `HERMES_DOCS_MCP_MIN_REFRESH` | `300` | минимальный интервал между обновлениями доки, секунды |
| `HERMES_DOCS_MCP_HOST` / `_PORT` | `127.0.0.1` / `8020` | только для HTTP-транспортов; `PORT` от хостинга тоже читается |

HTTP-транспорты по умолчанию разрешены только на loopback: у сервера нет
аутентификации клиентов. Выставить наружу можно, но только осознанно — см.
«Деплой как удалённый коннектор» выше.

### Полностью офлайн (например, закрытый VPS)

```bash
mkdir -p /opt/hermes-docs-cache
curl -fsSL -o /opt/hermes-docs-cache/llms-full.txt  https://hermes-agent.nousresearch.com/llms-full.txt
curl -fsSL -o /opt/hermes-docs-cache/docs-llms.txt  https://hermes-agent.nousresearch.com/docs/llms.txt
export HERMES_DOCS_MCP_CACHE_DIR=/opt/hermes-docs-cache HERMES_DOCS_MCP_OFFLINE=1
```

## Разработка

```bash
uv run pytest -q
uv run ruff check .
```

Тесты работают на локальных фикстурах и поднятом на loopback HTTP-сервере;
сеть для них не нужна. Отдельная проверка по «живому» сайту включается флагом
`HERMES_DOCS_MCP_LIVE=1`.

## Лицензия

MIT (код сервера). Сама документация Hermes Agent принадлежит Nous Research и
распространяется по условиям их репозитория (MIT). Проект неофициальный.

TDQS

A4.6/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: search returns relevant fragments from the documentation, while fetch retrieves a full page in markdown. Their descriptions explicitly state when to use each, leaving no ambiguity for an agent.

Naming Consistency5/5

Both tool names are single, simple verbs (search, fetch) that directly describe their actions. This consistent minimalist pattern is predictable and easy to remember.

Tool Count3/5

With only 2 tools, the server feels slightly thin for a documentation MCP, though the scope is narrow and focused on search + retrieval. According to the calibration, 1-2 tools is borderline, but each tool clearly earns its place.

Completeness4/5

The pair of search and fetch covers the core documentation lookup workflow well: find relevant fragments, then fetch the full page if needed. A minor gap is the lack of direct browsing or listing of documentation sections, but agents can work around this via search.

Maintenance

ActivityMaintained
ResponsivenessNo issues