Skip to main content
Glama
AndreyTepaykin

hh-mcp

README.md
# MCP-сервер для hh.ru API — 52 инструмента для ИИ-агента: вакансии, резюме, ATS/отклики, зарплаты

Если вы искали, как подключить hh.ru к Claude или другому ИИ-агенту, — этот сервер даёт агенту поиск по вакансиям и резюме, inbox откликов (ATS), карточки работодателей, статистику зарплат и справочники hh.ru по России и СНГ. Спрашиваете «найди Python-вакансии в Москве от 250 000 ₽ на удалёнке» — агент возвращает готовый список с зарплатами и опытом, а не ссылку на выдачу. Поиск вакансий работает без токена; токен нужен для базы резюме и ATS.

[![npm](https://img.shields.io/npm/v/@andrey-tepaykin/hh-mcp)](https://www.npmjs.com/package/@andrey-tepaykin/hh-mcp)
[![CI](https://github.com/AndreyTepaykin/hh-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/AndreyTepaykin/hh-mcp/actions)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

![Демонстрация: вопрос «найди Python-вакансии в Москве от 250 000 ₽ на удалёнке» — агент вызывает search_vacancies и отвечает списком вакансий](https://raw.githubusercontent.com/theYahia/WWmcp/main/servers/hh/assets/demo.svg)

По умолчанию ответы приходят компактными сводками, удобными для LLM — передайте `raw: true` любому инструменту поиска или карточки, чтобы получить полный JSON hh.ru.

Основано на [@theyahia/hh-mcp](https://github.com/theYahia/hh-mcp) от [@theYahia](https://github.com/theYahia).

## Два режима

| Режим | Что доступно | Нужен токен? |
|------|-----------------|:-------------:|
| **Без токена** | Поиск вакансий, вакансия по ID, похожие/связанные вакансии, работодатели, статистика зарплат, регионы, роли, отрасли, метро, страны/языки/навыки/районы, справочники, подсказки, проверка токена | нет |
| **С токеном** | Всё перечисленное + поиск резюме, ATS/отклики, менеджеры, лимиты, архив/скрытые вакансии, статистика вакансий, сохранённые поиски | да (`HH_ACCESS_TOKEN`) |

Токен выдаётся на [dev.hh.ru/admin](https://dev.hh.ru/admin). Важно: поиск резюме дополнительно требует аккаунт **работодателя** с **оплаченной подпиской на базу резюме** — токены соискателя и анонимные получают 403. ATS/negotiations требуют employer-токен. Проверить возможности своего токена можно инструментом `validate_token`.

## Установка

### Claude Desktop

```json
{
  "mcpServers": {
    "hh": {
      "command": "npx",
      "args": ["-y", "@andrey-tepaykin/hh-mcp"],
      "env": {
        "HH_ACCESS_TOKEN": "optional-oauth-token"
      }
    }
  }
}
```

### Claude Code

```bash
claude mcp add hh -- npx -y @andrey-tepaykin/hh-mcp
# С токеном:
claude mcp add hh -e HH_ACCESS_TOKEN=your-token -- npx -y @andrey-tepaykin/hh-mcp
```

### VS Code / Cursor

```json
{
  "servers": {
    "hh": {
      "command": "npx",
      "args": ["-y", "@andrey-tepaykin/hh-mcp"]
    }
  }
}
```

### Windsurf

```json
{
  "mcpServers": {
    "hh": {
      "command": "npx",
      "args": ["-y", "@andrey-tepaykin/hh-mcp"]
    }
  }
}
```

### Режим HTTP (Streamable HTTP)

```bash
npx @andrey-tepaykin/hh-mcp --http
# или
HTTP_PORT=8080 npx @andrey-tepaykin/hh-mcp --http
```

Эндпоинт: `http://localhost:3000/mcp` (POST) · Проверка состояния: `http://localhost:3000/health` (GET)

HTTP-режим stateless, по умолчанию слушает `127.0.0.1` с включённой защитой от DNS-rebinding. Чтобы открыть его наружу, задайте `HOST=0.0.0.0`, добавьте свой host/origin в `HH_ALLOWED_HOSTS` / `HH_ALLOWED_ORIGINS` и поставьте перед ним собственную аутентификацию.

## Переменные окружения

| Переменная | Обяз. | Описание |
|----------|----------|-------------|
| `HH_ACCESS_TOKEN` | нет | Bearer-токен OAuth 2.0. Нужен для резюме, ATS/откликов и employer-scoped endpoint'ов. |
| `HH_USER_AGENT` | нет | Свой `HH-User-Agent` (hh.ru его требует). Рекомендуемый формат: `your-app/1.0 (you@example.com)`. |
| `HTTP_PORT` / `PORT` | нет | Порт HTTP-режима (по умолчанию 3000). HTTP включается только флагом `--http`. |
| `HOST` | нет | Интерфейс привязки в HTTP-режиме (по умолчанию `127.0.0.1`). |
| `HH_ALLOWED_HOSTS` | нет | Список разрешённых Host через запятую для HTTP-режима (по умолчанию loopback). |
| `HH_ALLOWED_ORIGINS` | нет | Список разрешённых Origin через запятую для HTTP-режима. |

См. [`.env.example`](.env.example).

## Инструменты (52)

Любой инструмент поиска или карточки принимает `raw: true` — тогда вернётся полный JSON hh.ru вместо компактной сводки.

### Вакансии

| Инструмент | Описание | Токен? |
|------|-------------|:------:|
| `search_vacancies` | Поиск по ключевым словам, региону, профессиональной роли, отрасли, метро, работодателю, зарплате, опыту, формату работы и типу занятости, периоду (`period` или `date_from`/`date_to`), меткам и полю поиска, с сортировкой и пагинацией | нет |
| `get_vacancy` | Полная карточка вакансии: описание, требования, ключевые навыки, контакты | нет |
| `get_similar_vacancies` | Найти вакансии, похожие на заданную | нет |
| `get_related_vacancies` | Связанные вакансии (`/related_vacancies`) | нет |
| `get_vacancy_stats` | Статистика просмотров/откликов по вакансии | **да** |
| `get_vacancy_visitors` | Посетители вакансии | **да** |
| `get_vacancy_conditions` | Условия публикации вакансий | **да** |

### Резюме (токен работодателя + оплаченная база резюме)

| Инструмент | Описание | Токен? |
|------|-------------|:------:|
| `search_resumes` | Поиск резюме кандидатов по ключевым словам, региону, роли, зарплате, опыту | **да** |
| `get_resume` | Полное резюме: опыт, образование, навыки, контакты | **да** |
| `get_resume_negotiations_history` | История откликов по резюме | **да** |
| `list_saved_resume_searches` | Список сохранённых поисков резюме | **да** |
| `get_saved_resume_search` | Сохранённый поиск резюме по ID | **да** |

### ATS / отклики (токен работодателя)

| Инструмент | Описание | Токен? |
|------|-------------|:------:|
| `list_application_collections` | Коллекции (папки) откликов и состояния по вакансии — начните с этого | **да** |
| `list_applications` | Список откликов в коллекции (`page` / `per_page` / `order_by`) | **да** |
| `get_application` | Карточка отклика по topic id | **да** |
| `get_application_messages` | Сообщения в переписке по отклику | **да** |
| `get_negotiations_statistics` | Статистика откликов по работодателю (`employer_id`) | **да** |
| `get_preferred_negotiations_order` | Предпочтительная сортировка откликов по вакансии | **да** |

Типичный flow: `list_application_collections` → `list_applications` → `get_application` → `get_application_messages` / `get_resume`.

### Работодатели

| Инструмент | Описание | Токен? |
|------|-------------|:------:|
| `search_employers` | Поиск компаний по названию и региону | нет |
| `get_employer` | Профиль работодателя: описание, отрасли, сайт, число вакансий | нет |
| `get_employer_vacancies` | Активные вакансии работодателя (публичный поиск с `employer_id`) | нет |
| `list_employer_managers` | Менеджеры аккаунта (`employer_id`) | **да** |
| `get_employer_manager` | Менеджер по ID | **да** |
| `get_manager_resume_limits` | Лимиты просмотра резюме менеджера | **да** |
| `get_manager_negotiations_statistics` | Статистика откликов менеджера | **да** |
| `list_active_vacancies` | Опубликованные вакансии своего аккаунта (`/employers/{id}/vacancies/active`) | **да** |
| `list_archived_vacancies` | Архивные вакансии | **да** |
| `list_hidden_vacancies` | Скрытые вакансии | **да** |
| `get_message_template` | Шаблон сообщения по отклику | **да** |
| `list_mail_templates` | Почтовые шаблоны работодателя | **да** |
| `get_employer_vacancy_areas` | Активные регионы вакансий | **да** |
| `get_employer_departments` | Подразделения | **да** |
| `list_employer_addresses` | Адреса | **да** |

### Справочники и подсказки

| Инструмент | Описание | Токен? |
|------|-------------|:------:|
| `get_areas` | Дерево регионов и городов (`id — название`) | нет |
| `get_areas_subtree` | Регионы и города внутри одного региона — легче, чем всё дерево | нет |
| `get_countries` | Список стран | нет |
| `get_professional_roles` | Дерево профессиональных ролей с ID | нет |
| `get_industries` | Дерево отраслей компаний с ID | нет |
| `get_metro` | Станции и линии метро с ID по городу | нет |
| `get_languages` | Справочник языков | нет |
| `get_skills` | Названия навыков по id (`/skills`, 1–50 id; для поиска по имени — `suggest_skill_set`) | нет |
| `get_districts` | Районы (опционально по `area_id`) | нет |
| `get_dictionaries` | Все справочные данные: валюты, типы занятости, графики, опыт, метки | нет |
| `suggest_positions` | Автодополнение названий должностей (`/suggests/positions`) | нет |
| `suggest_professional_roles` | Автодополнение проф. ролей с ID (для фильтров поиска) | нет |
| `suggest_companies` | Автодополнение названий компаний | нет |
| `suggest_areas` | Автодополнение названий регионов и городов | нет |
| `suggest_vacancy_search_keyword` | Подсказки ключевых слов поиска вакансий | нет |
| `suggest_resume_search_keyword` | Подсказки ключевых слов поиска резюме | нет |
| `suggest_skill_set` | Автодополнение навыков | нет |

### Зарплаты и аккаунт

| Инструмент | Описание | Токен? |
|------|-------------|:------:|
| `get_salary_statistics` | При `HH_ACCESS_TOKEN` + `area_id` сначала пробует платный Банк данных (`/salary_statistics/paid/...`); при 401/403/404 или без токена/региона — оценка по зарплатам в вакансиях (смещённая выборка). | для банка — да |
| `validate_token` | Проверить, действителен ли `HH_ACCESS_TOKEN` (через `/me`), и показать роль аккаунта | нет |

## Ограничение частоты запросов

Встроенный лимитер соблюдает ограничение API hh.ru — 5 запросов в секунду. Автоматический повтор с экспоненциальной задержкой на ошибках 429 и 5xx (до 3 попыток). Учтите: лимитер общий на процесс, поэтому в общем HTTP-режиме все клиенты делят один бюджет 5 запросов/сек.

## Демо-промпты

```
Найди удалённые вакансии Python-разработчика в Москве от 300 000 рублей
```

```
Покажи все открытые вакансии Яндекса и дай статистику зарплат по основным ролям
```

```
Сравни зарплаты Senior Backend в Москве и Санкт-Петербурге и предложи вакансии, похожие на самую высокооплачиваемую
```

```
Покажи коллекции откликов по вакансии 123456 и список неразобранных откликов
```

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

```bash
git clone https://github.com/AndreyTepaykin/hh-mcp.git
cd hh-mcp
npm install
npm run build
npm test
```

## Справочник API

- [Документация API hh.ru](https://api.hh.ru/)
- [API hh.ru на GitHub](https://github.com/hhru/api)

## Лицензия

MIT

---

Репозиторий: [AndreyTepaykin/hh-mcp](https://github.com/AndreyTepaykin/hh-mcp) · npm: [@andrey-tepaykin/hh-mcp](https://www.npmjs.com/package/@andrey-tepaykin/hh-mcp)

TDQS

B3.1/5.0

Scored across 52 tools

Disambiguation4/5

Most tools target a distinct resource+action, and descriptions clarify boundary cases like get_employer_vacancies vs list_active_vacancies. A few similar-sounding statistics and list tools (e.g., get_negotiations_statistics vs get_manager_negotiations_statistics vs get_vacancy_stats) require close reading but are ultimately distinguishable.

Naming Consistency3/5

The overall verb_noun pattern holds (get_, list_, search_, suggest_), but the use of get_ vs list_ is inconsistent: list operations like get_areas, get_languages, get_employer_vacancy_areas, and get_employer_departments use get_, while others like list_employer_addresses and list_active_vacancies use list_. Names are readable but the convention is not uniform.

Tool Count2/5

At 52 tools, this is a very large surface, far exceeding the 25+ threshold. The breadth of the hh.ru domain justifies more tools than a typical server, but 52 still feels heavy and likely overwhelms agents, especially with many near-duplicate reference-data getters.

Completeness3/5

The read/search/monitoring surface is remarkably comprehensive: vacancies, resumes, employers, negotiations, templates, suggestions, statistics, and reference data. However, the set lacks any write or mutation tools (no create_vacancy, update_negotiation, send_message, or create_saved_search), leaving common ATS workflow dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues