HH.ru — анализ плана интеграции

artifacts/hh-integration-plan-analysis-2026.html · hr-tech · 2026-05-27

Главная развилка плана — не озвучена явно. План смешивает employer-сценарии («найти резюме», «откликнуться на резюме», «статистика откликов») с фразеологией job-seeker-помощников. Это две принципиально разные интеграции с разной доступностью после 15.12.2025. Сначала надо ответить: чью сторону мы автоматизируем — работодателя или соискателя? От этого зависит ~70% реализуемости плана.
Краткий вердикт. Если интерпретация employer-side (а судя по «поиск резюме» и «корпоративный аккаунт» — именно она имелась в виду) — план реализуем на 80–90%: за 2-3 дня собирается рабочий PoC. Если интерпретация job-seeker — план заблокирован на ~50% закрытием API 15.12.2025; всё, что про отклики на вакансии от имени соискателя, работает только через UI-эмуляцию (серая зона).
Содержание
  1. Развилка: employer vs job-seeker
  2. Секция 1: Тестовый аккаунт HH
  3. Секция 2: MCP-серверы для HH
  4. Секция 3: План Б — собственный MCP
  5. Секция 4: Демо-приложение и сценарии
  6. Roadmap: пошаговый план реализации
  7. Сводная таблица: что реализуемо
  8. Вопросы, на которые нужны ответы перед стартом

1. Развилка: employer vs job-seeker

До детального анализа нужно зафиксировать, какой сценарий имеется в виду. Это меняет всё.

Employer-side (корпоративная автоматизация HR)

Цель: автоматизировать работу рекрутера/компании.

Действия: публикация вакансий, поиск резюме в базе, приглашения кандидатов, ответы на отклики, аналитика воронки найма.

API статус: employer-side остался открытым после 15.12.2025.

Требования: юр.лицо (ИП/ООО), employer-подписка HH с доступом к базе резюме.

Job-seeker-side (помощник кандидата)

Цель: автоматизировать поиск работы за кандидата.

Действия: поиск вакансий, авто-отклики, чтение переписок с работодателями.

API статус: закрыт 15.12.2025; через API невозможно.

Альтернативы: UI-эмуляция (Playwright) — серая зона с тремя слоями риска (ToS / 152-ФЗ / ATS-репутация — см. Quick-Offer case).

Дальнейший анализ исходит из employer-интерпретации (по сигналу «корпоративный аккаунт работодателя» в плане). Где-то отметим, что меняется при job-seeker-чтении.

2. Секция 1: Тестовый аккаунт HH

1.1 Зарегистрировать тестовый корпоративный аккаунт работодателя на hh.ru реализуемо

Время: 1-3 дня (включая верификацию)

Через hh.ru/employer/registration. Требуется ИНН/ОГРН — нужно либо иметь ИП/ООО, либо использовать существующее юр.лицо компании. Без юр.лица employer-аккаунт получить нельзя — это первый блокер плана.

Тестовый режим: у HH нет sandbox в смысле AWS — это боевая платформа. «Тестовость» эмулируется через тестовый OAuth-app и dev-окружение, но действия с реальными вакансиями/откликами видны кандидатам.

1.2 Получить OAuth-приложение / API-ключи в dev.hh.ru реализуемо

Время: 5-30 минут после п. 1.1

После employer-аккаунта: dev.hh.ru/admin → «Создать приложение» → название, описание, redirect_uri → получаешь client_id, client_secret, опционально app_token.

Для PoC: создать отдельное dev-приложение, не использовать его для production. Если credentials утекут — revoke без последствий.

1.3 Зафиксировать лимиты, доступные scope'ы, способ аутентификации с оговорками

Время: 1-2 часа эмпирического тестирования

Что НЕ задокументировано публично:

Что задокументировано: OAuth 2.0 (authorization code grant + client credentials), header Authorization: Bearer ..., обязательный User-Agent: AppName/Version (contact@email), домен только api.hh.ru.

3. Секция 2: MCP-серверы для HH

2.1 Проверить наличие официального MCP-сервера от HH нет такого

Проверено. Официального MCP-сервера от HH не существует. HH предоставляет:

MCP — внешний по отношению к HH протокол; компания им не занимается. Это не временный пробел, а архитектурное решение.

2.2 Поискать opensource MCP-серверы (github, awesome-mcp списки) выполнено

Найден один заметный кандидат:

ПроектТипПокрытиеАктивностьЛицензия
gmen1057/headhunter-mcp-server Python MCP (stdio) 10 tools: поиск, vacancy, employer, similar, areas, dictionaries, resumes*, apply*, negotiations* 8 коммитов, 14 stars, 2 open issues MIT
Apify scrapers (easyapi/hh-ru-job-scraper, scrapestorm) SaaS scraper с MCP-endpoint Read-only поиск через HTML-парсинг Активны SaaS / paid

*tools под риском неработоспособности после 15.12.2025 (apply, negotiations) — это job-seeker API.

2.3 Оценить: покрытие методов, активность поддержки, лицензия gmen1057 — community, не enterprise-grade

gmen1057 detailed assessment:

4. Секция 3: План Б — собственный тонкий MCP

3.1 Прикинуть собственный тонкий MCP-обвес поверх HH REST API реализуемо за 1-2 дня

Стек выбора:

Рекомендация: Python. Аргументы: gmen1057 как референс (MIT, можно форкать), официальный hhru SDK тоже на Python (hh-applicant-tool), быстрый старт для PoC.

3.2 Минимальный набор tool'ов зависит от стороны

Если employer-side (рекомендуемая интерпретация):
ToolEndpointAuthСтатус
search_vacanciesGET /vacanciesanonymousработает
search_resumesGET /resumesemployer OAuth + подпискаработает
get_resumeGET /resumes/{id}employer OAuth + подпискаработает
invite_candidatePOST /negotiations (employer-side)employer OAuthработает
list_my_vacanciesGET /vacancies/{employer_id}employer OAuthработает
get_negotiationsGET /negotiations (на свои вакансии)employer OAuthработает
send_messagePOST /messagesemployer OAuthработает
Если job-seeker-side:
ToolEndpointAuthСтатус
search_vacanciesGET /vacanciesanonymousработает
get_vacancyGET /vacancies/{id}anonymousработает
apply_to_vacancyPOST /negotiationsjob-seeker OAuthзакрыт 15.12.2025
list_my_responsesGET /negotiationsjob-seeker OAuthзакрыт 15.12.2025
list_my_resumesGET /resumes/minejob-seeker OAuthстатус неясен

Если интерпретация job-seeker — половина базового tool-set не реализуема через API. Альтернатива — UI-эмуляция через Playwright (см. предыдущий артефакт).

Скелет минимального MCP (Python)

from mcp.server import Server
from mcp.types import Tool, TextContent
import mcp.server.stdio
import httpx, os, asyncio

server = Server("hh-employer-mcp")

BASE = "https://api.hh.ru"
TOKEN = os.getenv("HH_ACCESS_TOKEN")
UA = "MyApp/0.1 (contact@example.com)"

async def hh(path: str, params: dict | None = None):
    headers = {"User-Agent": UA}
    if TOKEN:
        headers["Authorization"] = f"Bearer {TOKEN}"
    async with httpx.AsyncClient() as client:
        r = await client.get(f"{BASE}{path}", params=params, headers=headers)
        r.raise_for_status()
        return r.json()

@server.list_tools()
async def list_tools():
    return [
        Tool(name="search_vacancies", description="Поиск вакансий по тексту/региону",
             inputSchema={"type": "object", "properties": {
                 "text": {"type": "string"},
                 "area": {"type": "integer", "description": "1=Москва, 2=СПб"},
                 "per_page": {"type": "integer", "default": 20}
             }, "required": ["text"]}),
        # ... + остальные tools
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "search_vacancies":
        data = await hh("/vacancies", params=arguments)
        return [TextContent(type="text", text=str(data))]
    # ...

async def main():
    async with mcp.server.stdio.stdio_server() as (read, write):
        await server.run(read, write, server.create_initialization_options())

if __name__ == "__main__":
    asyncio.run(main())

5. Секция 4: Демо-приложение и сценарии

4.1 Простой UI/чат с агентом реализуемо

Время: 0.5-1 день

Простейший путь — использовать сам Claude Code как UI: подключаешь MCP-сервер через ~/.claude.json и общаешься с агентом в терминале. Для PoC хватает.

Для красивой демо — Claude Desktop (нативный chat-интерфейс, поддерживает MCP), либо собственный минимальный web-UI на FastAPI/Streamlit, который дёргает Claude API напрямую с function-calling над теми же tool-функциями.

4.2 Агент через MCP/tools дёргает HH API по естественному запросу реализуемо

Это базовый паттерн MCP — Claude получает tool-определения, видит естественный запрос, решает какие tools вызвать. Работает «из коробки» при правильно описанных inputSchema.

Демо-сценарии — разбор по реализуемости

Сценарий A: «найди резюме senior python в Москве» реализуемо (employer)

Tool: search_resumesGET /resumes?text=senior+python&area=1

Требования: employer OAuth + активная подписка HH с пакетом контактов (без подписки — поиск ограничен или недоступен).

Caveat: в anonymous-режиме базы резюме нет вообще; нужен именно employer.

Сценарий B: «откликнись на N резюме шаблоном» семантическая неоднозначность

Семантика #1 (employer): «отправь приглашение N кандидатам».

Семантика #2 (job-seeker): «откликнись на N вакансий».

Нужно явно определить семантику. Если демо для рекрутеров — Сценарий B = invite_candidate. Если демо для кандидатов — заменить на advisor-сценарий «проанализируй эту вакансию и дай рекомендацию подавать/нет», т.к. сам отклик через API сделать нельзя.

Сценарий C: «покажи статистику откликов» реализуемо (employer)

Tool: get_negotiationsGET /negotiations + клиентская агрегация по statuses

Возможные срезы: total / новые / прочитанные / приглашены / отказы; разбивка по вакансиям; средний time-to-response.

Side benefit: отличный сценарий для агента — он может не только показать цифры, но и предложить инсайты («у вакансии X в 3 раза меньше откликов чем у Y — стоит проверить SEO/требования»).

6. Roadmap: пошаговый план реализации

Шаг 1. Развилка 1 час

Ответить на вопросы из §8. Зафиксировать: employer или job-seeker; нужна ли подписка; нужно ли действие «отклик» или только read+advisor.

Шаг 2. Тестовый аккаунт 1-3 дня

Регистрация employer-аккаунта (если ещё нет юр.лица — это блокер; альтернатива на старте — job-seeker аккаунт для anonymous-only сценариев). Активация (минимальной) подписки если нужны резюме. Создание dev-приложения на dev.hh.ru/admin.

Шаг 3. Smoke-тест API 1 час

curl-проверки: /vacancies (anonymous), /me (с токеном), /resumes (если подписка). Зафиксировать актуальные лимиты эмпирически.

Шаг 4. MCP-обвес 1-2 дня

Вариант A (быстрый): форкнуть gmen1057/headhunter-mcp-server, удалить сломанные/неактуальные tools, добавить нужные employer-tools, починить баг #5.

Вариант B (чистый): написать с нуля по скелету из §3.3, ~200-300 строк Python для 7 tool'ов.

Шаг 5. Подключение к Claude Code 30 минут

Конфиг в ~/.claude.json, проверка что Claude видит tools.

Шаг 6. Демо-сценарии 0.5 дня

Прогнать три сценария руками в Claude Code. Записать скринкаст для демо. Если красивый UI нужен — обернуть в Streamlit/Gradio за 2-3 часа.

Шаг 7. Документация и handover 0.5 дня

README с инструкцией установки. Документировать: какие tools работают, какие ограничения, что нужно для production.

Общая оценка: 4-7 рабочих дней от старта до working demo (если уже есть юр.лицо для employer). Без юр.лица — добавь время на регистрацию ИП (~1 неделя), либо ограничься anonymous-tools.

7. Сводная таблица: что реализуемо

Пункт плана Employer-интерпретация Job-seeker-интерпретация Блокер
1.1 Регистрация employer-аккаунта да нужно юр.лицо
1.2 OAuth-приложение dev.hh.ru да да
1.3 Лимиты / scopes / auth эмпирически эмпирически не публикуется
2.1 Официальный MCP от HH не существует не существует
2.2 Open-source MCP gmen1057 gmen1057, частично сломан
2.3 Оценка качества community, MIT, safe community, MIT, safe
3. Собственный MCP 1-2 дня 1-2 дня (но половина tools — закрыта)
4. UI/чат с агентом Claude Code as-is Claude Code as-is
Сценарий A: поиск резюме senior python в Москве да нет (нет доступа к базе) employer-подписка
Сценарий B: отклик/приглашение на N резюме шаблоном да, но риск ATS-репутации API закрыт 15.12.2025
Сценарий C: статистика откликов да API закрыт 15.12.2025

8. Вопросы, на которые нужны ответы перед стартом

1. Сторона: employer или job-seeker? Если employer — есть ли юр.лицо для регистрации?
2. Подписка HH: готова ли компания оплатить минимальную employer-подписку для PoC? (нужна для доступа к базе резюме)
3. Семантика «отклик»: приглашение кандидата от компании (employer) или отклик кандидата на вакансию (job-seeker)?
4. Action vs read-only: демо должно реально выполнять действия (отправлять приглашения, менять статусы) или достаточно read-only анализа?
5. Production scope: это PoC для внутренней демонстрации или прототип для дальнейшего production-внедрения? От этого зависит выбор: fork gmen1057 (быстро) vs собственный с нуля (чище).
6. Stack команды: Python или Node? (если команда TS-первая — собственный MCP на TS из OpenAPI; иначе Python через fork/скелет).