@theyahia/hh-mcp 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 theYahia
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 theYahia
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,23 +1,23 @@
1
1
  # @theyahia/hh-mcp
2
2
 
3
- MCP-сервер для hh.ru: поиск вакансий, резюме, зарплаты, работодатели, справочники. **8 инструментов.**
3
+ MCP server for the [hh.ru](https://hh.ru) API Russia and CIS job market. **16 tools** covering vacancies, resumes, employers, salary statistics, dictionaries, and autocomplete.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@theyahia/hh-mcp)](https://www.npmjs.com/package/@theyahia/hh-mcp)
6
6
  [![CI](https://github.com/theYahia/hh-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/theYahia/hh-mcp/actions)
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
8
 
9
- Часть серии [Russian API MCP](https://github.com/theYahia/russian-mcp) (50 серверов) by [@theYahia](https://github.com/theYahia).
9
+ Part of the [Russian API MCP](https://github.com/theYahia/russian-mcp) series by [@theYahia](https://github.com/theYahia).
10
10
 
11
- ## Два режима работы
11
+ ## Two Modes
12
12
 
13
- | Режим | Что доступно | Нужен токен? |
14
- |-------|-------------|--------------|
15
- | **Без токена** | Поиск вакансий, вакансия по ID, работодатели, зарплаты, регионы, профроли | Нет |
16
- | **С токеном** | Всё выше + поиск резюме, резюме по ID | Да (`HH_ACCESS_TOKEN`) |
13
+ | Mode | What's available | Token needed? |
14
+ |------|-----------------|:-------------:|
15
+ | **No token** | Vacancy search, vacancy by ID, similar vacancies, employers, salary stats, areas, roles, dictionaries, suggests | No |
16
+ | **With token** | Everything above + resume search, resume by ID | Yes (`HH_ACCESS_TOKEN`) |
17
17
 
18
- Получить токен: [dev.hh.ru/admin](https://dev.hh.ru/admin)
18
+ Get a token at [dev.hh.ru/admin](https://dev.hh.ru/admin).
19
19
 
20
- ## Установка
20
+ ## Installation
21
21
 
22
22
  ### Claude Desktop
23
23
 
@@ -28,7 +28,7 @@ MCP-сервер для hh.ru: поиск вакансий, резюме, зар
28
28
  "command": "npx",
29
29
  "args": ["-y", "@theyahia/hh-mcp"],
30
30
  "env": {
31
- "HH_ACCESS_TOKEN": "your-token-here (опционально)"
31
+ "HH_ACCESS_TOKEN": "optional-oauth-token"
32
32
  }
33
33
  }
34
34
  }
@@ -39,63 +39,115 @@ MCP-сервер для hh.ru: поиск вакансий, резюме, зар
39
39
 
40
40
  ```bash
41
41
  claude mcp add hh -- npx -y @theyahia/hh-mcp
42
- # С токеном:
42
+ # With token:
43
43
  claude mcp add hh -e HH_ACCESS_TOKEN=your-token -- npx -y @theyahia/hh-mcp
44
44
  ```
45
45
 
46
46
  ### VS Code / Cursor
47
47
 
48
48
  ```json
49
- { "servers": { "hh": { "command": "npx", "args": ["-y", "@theyahia/hh-mcp"] } } }
49
+ {
50
+ "servers": {
51
+ "hh": {
52
+ "command": "npx",
53
+ "args": ["-y", "@theyahia/hh-mcp"]
54
+ }
55
+ }
56
+ }
50
57
  ```
51
58
 
52
59
  ### Windsurf
53
60
 
54
61
  ```json
55
- { "mcpServers": { "hh": { "command": "npx", "args": ["-y", "@theyahia/hh-mcp"] } } }
62
+ {
63
+ "mcpServers": {
64
+ "hh": {
65
+ "command": "npx",
66
+ "args": ["-y", "@theyahia/hh-mcp"]
67
+ }
68
+ }
69
+ }
56
70
  ```
57
71
 
58
- ### HTTP режим (Streamable HTTP)
72
+ ### HTTP Mode (Streamable HTTP)
59
73
 
60
74
  ```bash
61
75
  npx @theyahia/hh-mcp --http
62
- # или
76
+ # or
63
77
  HTTP_PORT=8080 npx @theyahia/hh-mcp --http
64
78
  ```
65
79
 
66
- Эндпоинт: `http://localhost:3000/mcp`
80
+ Endpoint: `http://localhost:3000/mcp`
67
81
  Health check: `http://localhost:3000/health`
68
82
 
69
- ## Инструменты (8)
83
+ ## Environment Variables
84
+
85
+ | Variable | Required | Description |
86
+ |----------|----------|-------------|
87
+ | `HH_ACCESS_TOKEN` | No | OAuth 2.0 Bearer token. Required for resume endpoints. |
88
+ | `HTTP_PORT` | No | Port for HTTP mode (default: 3000). |
89
+
90
+ ## Tools (16)
91
+
92
+ ### Vacancies
70
93
 
71
- | Инструмент | Описание | Нужен токен? |
72
- |------------|----------|:------------:|
73
- | `search_vacancies` | Поиск вакансий по словам, региону, зарплате, опыту | Нет |
74
- | `get_vacancy` | Полная информация о вакансии с описанием и контактами | Нет |
75
- | `search_resumes` | Поиск резюме по ключевым словам и параметрам | **Да** |
76
- | `get_resume` | Полная информация о резюме | **Да** |
77
- | `get_employers` | Поиск работодателей по названию | Нет |
78
- | `get_salary_stats` | Статистика зарплат по специальности и региону | Нет |
79
- | `get_areas` | Справочник регионов РФ и СНГ с кодами | Нет |
80
- | `get_professional_roles` | Справочник профессиональных ролей | Нет |
94
+ | Tool | Description | Token? |
95
+ |------|-------------|:------:|
96
+ | `search_vacancies` | Search vacancies by keywords, region, salary, experience, employment type, schedule, with sorting and pagination | No |
97
+ | `get_vacancy` | Full vacancy details: description, requirements, key skills, contacts | No |
98
+ | `get_similar_vacancies` | Find vacancies similar to a given one | No |
81
99
 
82
- ## Примеры
100
+ ### Resumes
101
+
102
+ | Tool | Description | Token? |
103
+ |------|-------------|:------:|
104
+ | `search_resumes` | Search candidate resumes by keywords, region, role, salary, experience | **Yes** |
105
+ | `get_resume` | Full resume: experience, education, skills, contacts | **Yes** |
106
+
107
+ ### Employers
108
+
109
+ | Tool | Description | Token? |
110
+ |------|-------------|:------:|
111
+ | `search_employers` | Search companies by name and region | No |
112
+ | `get_employer` | Employer profile: description, industries, website, vacancy count | No |
113
+ | `get_employer_vacancies` | List active vacancies for a specific employer | No |
114
+
115
+ ### Dictionaries & Suggests
116
+
117
+ | Tool | Description | Token? |
118
+ |------|-------------|:------:|
119
+ | `get_areas` | Full tree of regions and cities with codes | No |
120
+ | `get_professional_roles` | Full tree of professional roles with IDs | No |
121
+ | `get_dictionaries` | All reference data: currencies, employment types, schedules, experience levels | No |
122
+ | `suggest_positions` | Autocomplete job titles | No |
123
+ | `suggest_companies` | Autocomplete company names | No |
124
+ | `suggest_areas` | Autocomplete region/city names | No |
125
+
126
+ ### Salary
127
+
128
+ | Tool | Description | Token? |
129
+ |------|-------------|:------:|
130
+ | `get_salary_statistics` | Salary distribution for a professional role in a region | No |
131
+
132
+ ## Rate Limiting
133
+
134
+ Built-in rate limiter respects the hh.ru API limit of 5 requests per second. Automatic retry with exponential backoff on 429 and 5xx errors (up to 3 attempts).
135
+
136
+ ## Demo Prompts
83
137
 
84
138
  ```
85
- Найди вакансии Python в Москве от 200К
86
- Покажи вакансии в Яндексе
87
- Средняя зарплата Senior Backend?
88
- Какие регионы есть в hh.ru?
89
- Найди резюме Java-разработчиков в Петербурге
139
+ Find remote Python developer jobs in Moscow paying over 300,000 RUB
90
140
  ```
91
141
 
92
- ## API
93
-
94
- Все публичные эндпоинты используют `https://api.hh.ru` без авторизации. Эндпоинты резюме требуют OAuth 2.0 токен через переменную окружения `HH_ACCESS_TOKEN`.
142
+ ```
143
+ Show me all open vacancies at Yandex and give me salary statistics for their top roles
144
+ ```
95
145
 
96
- User-Agent: `theYahia-hh-mcp/1.0`
146
+ ```
147
+ Compare Senior Backend salaries in Moscow vs Saint Petersburg, and suggest similar vacancies to the best-paying one
148
+ ```
97
149
 
98
- ## Разработка
150
+ ## Development
99
151
 
100
152
  ```bash
101
153
  git clone https://github.com/theYahia/hh-mcp.git
@@ -105,10 +157,11 @@ npm run build
105
157
  npm test
106
158
  ```
107
159
 
108
- ## Часть серии Russian API MCP
160
+ ## API Reference
109
161
 
110
- **50 серверов:** [github.com/theYahia/russian-mcp](https://github.com/theYahia/russian-mcp)
162
+ - [hh.ru API docs](https://api.hh.ru/)
163
+ - [hh.ru API GitHub](https://github.com/hhru/api)
111
164
 
112
- ## Лицензия
165
+ ## License
113
166
 
114
167
  MIT
package/dist/client.d.ts CHANGED
@@ -1 +1,7 @@
1
+ export declare class HhApiError extends Error {
2
+ status: number;
3
+ statusText: string;
4
+ body?: string | undefined;
5
+ constructor(status: number, statusText: string, body?: string | undefined);
6
+ }
1
7
  export declare function hhGet(path: string): Promise<unknown>;
package/dist/client.js CHANGED
@@ -1,14 +1,46 @@
1
1
  const BASE_URL = "https://api.hh.ru";
2
2
  const TIMEOUT = 10_000;
3
3
  const MAX_RETRIES = 3;
4
- const USER_AGENT = "theYahia-hh-mcp/1.0 (https://github.com/theYahia/hh-mcp)";
4
+ const USER_AGENT = "theYahia-hh-mcp/2.0 (https://github.com/theYahia/hh-mcp)";
5
+ // Rate limiter: 5 requests per second
6
+ const RATE_LIMIT = 5;
7
+ const RATE_WINDOW = 1000;
8
+ const timestamps = [];
9
+ async function waitForRateLimit() {
10
+ const now = Date.now();
11
+ // Remove timestamps outside the window
12
+ while (timestamps.length > 0 && timestamps[0] <= now - RATE_WINDOW) {
13
+ timestamps.shift();
14
+ }
15
+ if (timestamps.length >= RATE_LIMIT) {
16
+ const oldest = timestamps[0];
17
+ const waitMs = oldest + RATE_WINDOW - now;
18
+ if (waitMs > 0) {
19
+ await new Promise((r) => setTimeout(r, waitMs));
20
+ }
21
+ }
22
+ timestamps.push(Date.now());
23
+ }
24
+ export class HhApiError extends Error {
25
+ status;
26
+ statusText;
27
+ body;
28
+ constructor(status, statusText, body) {
29
+ super(`hh.ru HTTP ${status}: ${statusText}`);
30
+ this.status = status;
31
+ this.statusText = statusText;
32
+ this.body = body;
33
+ this.name = "HhApiError";
34
+ }
35
+ }
5
36
  export async function hhGet(path) {
37
+ await waitForRateLimit();
6
38
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
7
39
  const controller = new AbortController();
8
40
  const timer = setTimeout(() => controller.abort(), TIMEOUT);
9
41
  const headers = {
10
42
  "User-Agent": USER_AGENT,
11
- "Accept": "application/json",
43
+ Accept: "application/json",
12
44
  };
13
45
  const token = process.env.HH_ACCESS_TOKEN;
14
46
  if (token) {
@@ -22,23 +54,46 @@ export async function hhGet(path) {
22
54
  clearTimeout(timer);
23
55
  if (response.ok)
24
56
  return response.json();
25
- if ((response.status === 429 || response.status >= 500) && attempt < MAX_RETRIES) {
57
+ const body = await response.text().catch(() => "");
58
+ // Auth errors — fail immediately
59
+ if (response.status === 401 || response.status === 403) {
60
+ throw new HhApiError(response.status, response.status === 401
61
+ ? "Unauthorized — set HH_ACCESS_TOKEN env var with a valid OAuth2 bearer token"
62
+ : "Forbidden — token lacks required scope for this endpoint", body);
63
+ }
64
+ // Rate limit — use Retry-After header if available
65
+ if (response.status === 429) {
66
+ const retryAfter = response.headers.get("Retry-After");
67
+ const delay = retryAfter
68
+ ? parseInt(retryAfter, 10) * 1000
69
+ : Math.min(1000 * 2 ** (attempt - 1), 8000);
70
+ if (attempt < MAX_RETRIES) {
71
+ console.error(`[hh-mcp] 429 rate limited, retry in ${delay}ms (${attempt}/${MAX_RETRIES})`);
72
+ await new Promise((r) => setTimeout(r, delay));
73
+ continue;
74
+ }
75
+ throw new HhApiError(429, "Rate limited — all retries exhausted", body);
76
+ }
77
+ // Server errors — retry
78
+ if (response.status >= 500 && attempt < MAX_RETRIES) {
26
79
  const delay = Math.min(1000 * 2 ** (attempt - 1), 8000);
27
- console.error(`[hh-mcp] ${response.status}, повтор через ${delay}мс (${attempt}/${MAX_RETRIES})`);
28
- await new Promise(r => setTimeout(r, delay));
80
+ console.error(`[hh-mcp] ${response.status}, retry in ${delay}ms (${attempt}/${MAX_RETRIES})`);
81
+ await new Promise((r) => setTimeout(r, delay));
29
82
  continue;
30
83
  }
31
- throw new Error(`hh.ru HTTP ${response.status}: ${response.statusText}`);
84
+ throw new HhApiError(response.status, response.statusText, body);
32
85
  }
33
86
  catch (error) {
34
87
  clearTimeout(timer);
35
- if (error instanceof DOMException && error.name === "AbortError" && attempt < MAX_RETRIES) {
36
- console.error(`[hh-mcp] Таймаут, повтор (${attempt}/${MAX_RETRIES})`);
88
+ if (error instanceof DOMException &&
89
+ error.name === "AbortError" &&
90
+ attempt < MAX_RETRIES) {
91
+ console.error(`[hh-mcp] Timeout, retry (${attempt}/${MAX_RETRIES})`);
37
92
  continue;
38
93
  }
39
94
  throw error;
40
95
  }
41
96
  }
42
- throw new Error("hh.ru: все попытки исчерпаны");
97
+ throw new Error("hh.ru: all retries exhausted");
43
98
  }
44
99
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,mBAAmB,CAAC;AACrC,MAAM,OAAO,GAAG,MAAM,CAAC;AACvB,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,UAAU,GAAG,0DAA0D,CAAC;AAE9E,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,IAAY;IACtC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACxD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAE5D,MAAM,OAAO,GAA2B;YACtC,YAAY,EAAE,UAAU;YACxB,QAAQ,EAAE,kBAAkB;SAC7B,CAAC;QAEF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QAC1C,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;QAC/C,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,GAAG,IAAI,EAAE,EAAE;gBACjD,OAAO;gBACP,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YACH,YAAY,CAAC,KAAK,CAAC,CAAC;YAEpB,IAAI,QAAQ,CAAC,EAAE;gBAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;YAExC,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,OAAO,GAAG,WAAW,EAAE,CAAC;gBACjF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;gBACxD,OAAO,CAAC,KAAK,CAAC,YAAY,QAAQ,CAAC,MAAM,kBAAkB,KAAK,OAAO,OAAO,IAAI,WAAW,GAAG,CAAC,CAAC;gBAClG,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;gBAC7C,SAAS;YACX,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,cAAc,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QAC3E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,KAAK,YAAY,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,OAAO,GAAG,WAAW,EAAE,CAAC;gBAC1F,OAAO,CAAC,KAAK,CAAC,6BAA6B,OAAO,IAAI,WAAW,GAAG,CAAC,CAAC;gBACtE,SAAS;YACX,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
- declare function createServer(): McpServer;
4
- export { createServer };
3
+ export declare function createServer(): McpServer;
package/dist/index.js CHANGED
@@ -2,39 +2,73 @@
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
5
- import { searchVacanciesSchema, handleSearchVacancies, getVacancySchema, handleGetVacancy } from "./tools/vacancies.js";
6
- import { getEmployersSchema, handleGetEmployers } from "./tools/employers.js";
7
- import { handleGetAreas, handleGetProfessionalRoles, getSalaryStatsSchema, handleGetSalaryStats } from "./tools/references.js";
8
- import { searchResumesSchema, handleSearchResumes, getResumeSchema, handleGetResume } from "./tools/resumes.js";
5
+ import { searchVacanciesSchema, handleSearchVacancies, getVacancySchema, handleGetVacancy, getSimilarVacanciesSchema, handleGetSimilarVacancies, } from "./tools/vacancies.js";
6
+ import { searchEmployersSchema, handleSearchEmployers, getEmployerSchema, handleGetEmployer, getEmployerVacanciesSchema, handleGetEmployerVacancies, } from "./tools/employers.js";
7
+ import { searchResumesSchema, handleSearchResumes, getResumeSchema, handleGetResume, } from "./tools/resumes.js";
8
+ import { handleGetAreas, handleGetProfessionalRoles, handleGetDictionaries, suggestPositionsSchema, handleSuggestPositions, suggestCompaniesSchema, handleSuggestCompanies, suggestAreasSchema, handleSuggestAreas, } from "./tools/references.js";
9
+ import { getSalaryStatisticsSchema, handleGetSalaryStatistics, } from "./tools/salary.js";
10
+ import { HhApiError } from "./client.js";
9
11
  import http from "node:http";
10
- function createServer() {
12
+ const TOOL_COUNT = 16;
13
+ function wrapHandler(fn) {
14
+ return async (params) => {
15
+ try {
16
+ const text = await fn(params);
17
+ return { content: [{ type: "text", text }] };
18
+ }
19
+ catch (error) {
20
+ const message = error instanceof HhApiError
21
+ ? `Error ${error.status}: ${error.message}${error.body ? `\n${error.body}` : ""}`
22
+ : error instanceof Error
23
+ ? error.message
24
+ : String(error);
25
+ return { content: [{ type: "text", text: `ERROR: ${message}` }] };
26
+ }
27
+ };
28
+ }
29
+ export function createServer() {
11
30
  const server = new McpServer({
12
31
  name: "hh-mcp",
13
- version: "1.1.0",
32
+ version: "2.0.0",
14
33
  });
15
- server.tool("search_vacancies", "Поиск вакансий на hh.ru по ключевым словам, региону, зарплате, опыту.", searchVacanciesSchema.shape, async (params) => ({ content: [{ type: "text", text: await handleSearchVacancies(params) }] }));
16
- server.tool("get_vacancy", "Полная информация о вакансии: описание, требования, навыки, контакты.", getVacancySchema.shape, async (params) => ({ content: [{ type: "text", text: await handleGetVacancy(params) }] }));
17
- server.tool("search_resumes", "Поиск резюме на hh.ru (требуется HH_ACCESS_TOKEN).", searchResumesSchema.shape, async (params) => ({ content: [{ type: "text", text: await handleSearchResumes(params) }] }));
18
- server.tool("get_resume", "Полная информация о резюме (требуется HH_ACCESS_TOKEN).", getResumeSchema.shape, async (params) => ({ content: [{ type: "text", text: await handleGetResume(params) }] }));
19
- server.tool("get_employers", "Поиск работодателей по названию.", getEmployersSchema.shape, async (params) => ({ content: [{ type: "text", text: await handleGetEmployers(params) }] }));
20
- server.tool("get_salary_stats", "Статистика зарплат по специальности и региону.", getSalaryStatsSchema.shape, async (params) => ({ content: [{ type: "text", text: await handleGetSalaryStats(params) }] }));
21
- server.tool("get_areas", "Справочник регионов РФ и СНГ с кодами для поиска.", {}, async () => ({ content: [{ type: "text", text: await handleGetAreas() }] }));
22
- server.tool("get_professional_roles", "Справочник профессиональных ролей для поиска вакансий.", {}, async () => ({ content: [{ type: "text", text: await handleGetProfessionalRoles() }] }));
34
+ // --- Vacancies (3) ---
35
+ server.tool("search_vacancies", "Search job vacancies on hh.ru by keywords, region, salary, experience, employment type, schedule. Returns paginated list with title, salary, employer, snippet.", searchVacanciesSchema.shape, wrapHandler(handleSearchVacancies));
36
+ server.tool("get_vacancy", "Get full vacancy details: description, requirements, key skills, contacts, employer info.", getVacancySchema.shape, wrapHandler(handleGetVacancy));
37
+ server.tool("get_similar_vacancies", "Find vacancies similar to a given one. Useful for expanding a candidate's job search.", getSimilarVacanciesSchema.shape, wrapHandler(handleGetSimilarVacancies));
38
+ // --- Resumes (2) require employer token ---
39
+ server.tool("search_resumes", "Search candidate resumes by keywords, region, professional role, salary, experience. Requires employer OAuth token (HH_ACCESS_TOKEN).", searchResumesSchema.shape, wrapHandler(handleSearchResumes));
40
+ server.tool("get_resume", "Get full resume details: experience, education, skills, contacts. Requires employer OAuth token (HH_ACCESS_TOKEN).", getResumeSchema.shape, wrapHandler(handleGetResume));
41
+ // --- Employers (3) ---
42
+ server.tool("search_employers", "Search companies/employers on hh.ru by name. Returns company info and open vacancy count.", searchEmployersSchema.shape, wrapHandler(handleSearchEmployers));
43
+ server.tool("get_employer", "Get detailed employer profile: description, industries, website, vacancy count.", getEmployerSchema.shape, wrapHandler(handleGetEmployer));
44
+ server.tool("get_employer_vacancies", "List active vacancies for a specific employer.", getEmployerVacanciesSchema.shape, wrapHandler(handleGetEmployerVacancies));
45
+ // --- Dictionaries & Suggests (6) ---
46
+ server.tool("get_areas", "Get the full tree of regions and cities with their codes. Use to find area IDs for search filters.", {}, wrapHandler(handleGetAreas));
47
+ server.tool("get_professional_roles", "Get the full tree of professional roles with IDs. Use to find role IDs for resume search and salary stats.", {}, wrapHandler(handleGetProfessionalRoles));
48
+ server.tool("get_dictionaries", "Get all reference dictionaries: currencies, employment types, schedules, experience levels, vacancy types, and more.", {}, wrapHandler(handleGetDictionaries));
49
+ server.tool("suggest_positions", "Autocomplete job titles / professional roles. Returns matching role suggestions for partial input.", suggestPositionsSchema.shape, wrapHandler(handleSuggestPositions));
50
+ server.tool("suggest_companies", "Autocomplete company names. Returns matching employer suggestions for partial input.", suggestCompaniesSchema.shape, wrapHandler(handleSuggestCompanies));
51
+ server.tool("suggest_areas", "Autocomplete region/city names. Returns matching area suggestions for partial input.", suggestAreasSchema.shape, wrapHandler(handleSuggestAreas));
52
+ // --- Salary (1) ---
53
+ server.tool("get_salary_statistics", "Get salary statistics for a professional role in a region. Returns vacancy count and salary distribution data.", getSalaryStatisticsSchema.shape, wrapHandler(handleGetSalaryStatistics));
23
54
  return server;
24
55
  }
56
+ // --- Start ---
25
57
  async function main() {
26
58
  const args = process.argv.slice(2);
27
59
  const httpMode = args.includes("--http") || !!process.env.HTTP_PORT;
28
60
  const port = Number(process.env.HTTP_PORT || process.env.PORT || 3000);
29
61
  if (httpMode) {
30
62
  const server = createServer();
31
- const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => crypto.randomUUID() });
63
+ const transport = new StreamableHTTPServerTransport({
64
+ sessionIdGenerator: () => crypto.randomUUID(),
65
+ });
32
66
  await server.connect(transport);
33
67
  const httpServer = http.createServer(async (req, res) => {
34
68
  const url = new URL(req.url || "/", `http://localhost:${port}`);
35
69
  if (url.pathname === "/health") {
36
70
  res.writeHead(200, { "Content-Type": "application/json" });
37
- res.end(JSON.stringify({ status: "ok", tools: 8 }));
71
+ res.end(JSON.stringify({ status: "ok", tools: TOOL_COUNT }));
38
72
  return;
39
73
  }
40
74
  if (url.pathname === "/mcp") {
@@ -52,12 +86,11 @@ async function main() {
52
86
  const server = createServer();
53
87
  const transport = new StdioServerTransport();
54
88
  await server.connect(transport);
55
- console.error("[hh-mcp] Сервер запущен (stdio). 8 инструментов.");
89
+ console.error(`[hh-mcp] Server started (stdio). ${TOOL_COUNT} tools. Auth: ${process.env.HH_ACCESS_TOKEN ? "token set" : "no token (public endpoints only)"}`);
56
90
  }
57
91
  }
58
- export { createServer };
59
92
  main().catch((error) => {
60
- console.error("[hh-mcp] Ошибка:", error);
93
+ console.error("[hh-mcp] Fatal error:", error);
61
94
  process.exit(1);
62
95
  });
63
96
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB,SAAS,WAAW,CAClB,EAAoC;IAEpC,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE;QACtB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;YAC9B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GACX,KAAK,YAAY,UAAU;gBACzB,CAAC,CAAC,SAAS,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;gBACjF,CAAC,CAAC,KAAK,YAAY,KAAK;oBACtB,CAAC,CAAC,KAAK,CAAC,OAAO;oBACf,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;QAC7E,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,wBAAwB;IAExB,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,iKAAiK,EACjK,qBAAqB,CAAC,KAAK,EAC3B,WAAW,CAAC,qBAAqB,CAAC,CACnC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,aAAa,EACb,2FAA2F,EAC3F,gBAAgB,CAAC,KAAK,EACtB,WAAW,CAAC,gBAAgB,CAAC,CAC9B,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,uFAAuF,EACvF,yBAAyB,CAAC,KAAK,EAC/B,WAAW,CAAC,yBAAyB,CAAC,CACvC,CAAC;IAEF,+CAA+C;IAE/C,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,uIAAuI,EACvI,mBAAmB,CAAC,KAAK,EACzB,WAAW,CAAC,mBAAmB,CAAC,CACjC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,oHAAoH,EACpH,eAAe,CAAC,KAAK,EACrB,WAAW,CAAC,eAAe,CAAC,CAC7B,CAAC;IAEF,wBAAwB;IAExB,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,2FAA2F,EAC3F,qBAAqB,CAAC,KAAK,EAC3B,WAAW,CAAC,qBAAqB,CAAC,CACnC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,cAAc,EACd,iFAAiF,EACjF,iBAAiB,CAAC,KAAK,EACvB,WAAW,CAAC,iBAAiB,CAAC,CAC/B,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,gDAAgD,EAChD,0BAA0B,CAAC,KAAK,EAChC,WAAW,CAAC,0BAA0B,CAAC,CACxC,CAAC;IAEF,sCAAsC;IAEtC,MAAM,CAAC,IAAI,CACT,WAAW,EACX,oGAAoG,EACpG,EAAE,EACF,WAAW,CAAC,cAAc,CAAC,CAC5B,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,4GAA4G,EAC5G,EAAE,EACF,WAAW,CAAC,0BAA0B,CAAC,CACxC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,sHAAsH,EACtH,EAAE,EACF,WAAW,CAAC,qBAAqB,CAAC,CACnC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,oGAAoG,EACpG,sBAAsB,CAAC,KAAK,EAC5B,WAAW,CAAC,sBAAsB,CAAC,CACpC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,sFAAsF,EACtF,sBAAsB,CAAC,KAAK,EAC5B,WAAW,CAAC,sBAAsB,CAAC,CACpC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,eAAe,EACf,sFAAsF,EACtF,kBAAkB,CAAC,KAAK,EACxB,WAAW,CAAC,kBAAkB,CAAC,CAChC,CAAC;IAEF,qBAAqB;IAErB,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,gHAAgH,EAChH,yBAAyB,CAAC,KAAK,EAC/B,WAAW,CAAC,yBAAyB,CAAC,CACvC,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gBAAgB;AAEhB,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;IACpE,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;IAEvE,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;YAClD,kBAAkB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE;SAC9C,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEhC,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YACtD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC;YAEhE,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC/B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;gBAC7D,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;gBAC5B,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBACxC,OAAO;YACT,CAAC;YAED,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,CACL,mEAAmE,CACpE,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YAC3B,OAAO,CAAC,KAAK,CAAC,8BAA8B,IAAI,kBAAkB,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,KAAK,CACX,oCAAoC,UAAU,iBAAiB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,kCAAkC,EAAE,CAChJ,CAAC;IACJ,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};