@x0333/bitrix24-mcp-server 2.1.1 → 2.2.1
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/README.md +53 -24
- package/index.js +44 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,34 +1,45 @@
|
|
|
1
|
-
# Bitrix24 MCP Server
|
|
1
|
+
# 🔌 Bitrix24 Stdio MCP Server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
MCP-сервер для работы с Bitrix24 через входящий вебхук.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Он позволяет подключить Bitrix24 к Stdio MCP-совместимым AI-клиентам, например Manus, Claude Desktop и другим инструментам, которые умеют работать с Model Context Protocol.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **get_task**: Retrieve detailed information about a specific task by ID.
|
|
9
|
-
- **search_tasks**: Search for tasks by title with sorting and pagination.
|
|
10
|
-
- **get_group**: Get detailed information about a workgroup or project.
|
|
11
|
-
- **search_groups**: Search for workgroups or projects by name.
|
|
7
|
+
Сервер ходит в REST API Bitrix24 через webhook URL и отдаёт данные в формате, удобном для AI-агента.
|
|
12
8
|
|
|
13
|
-
##
|
|
9
|
+
## ⚙️ Что умеет
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
Сейчас сервер предоставляет такие инструменты:
|
|
12
|
+
|
|
13
|
+
- **get_profile** — профиль пользователя, от имени которого создан вебхук (`profile`).
|
|
14
|
+
- **get_task** — карточка задачи по ID (`tasks.task.get`), опционально список полей `select`.
|
|
15
|
+
- **search_tasks** — список задач (`tasks.task.list`). Нужен **хотя бы один** критерий:
|
|
16
|
+
- **`title`** — подстрока в названии (`%TITLE` в фильтре);
|
|
17
|
+
- **`stage_id`** — ID колонки канбана задач (`STAGE_ID` в фильтре).
|
|
18
|
+
Можно передать оба параметра одновременно (условия объединяются). Дополнительно: **`order`**, **`dir`** (сортировка), **`start`** (смещение для пагинации).
|
|
19
|
+
- **search_groups** — рабочие группы и проекты по подстроке имени (`sonet_group.get.json`, фильтр `%NAME`).
|
|
20
|
+
- **get_group** — данные группы или проекта по ID (`sonet_group.get.json`, фильтр `ID`).
|
|
21
|
+
- **get_kanban_stages_by_group** — стадии канбана задач для группы по её ID (`task.stages.get`, в теле запроса `entityId` = ID группы).
|
|
22
|
+
|
|
23
|
+
Все вызовы к Bitrix24 идут как `POST` на `{B24_BASE}/{метод}` с JSON-телом, как в документации REST.
|
|
24
|
+
|
|
25
|
+
## 🚀 Установка и запуск
|
|
26
|
+
|
|
27
|
+
Пакет можно запускать напрямую через `npx`:
|
|
16
28
|
|
|
17
29
|
```bash
|
|
18
|
-
# To start the MCP server (default)
|
|
19
30
|
npx -y @x0333/bitrix24-mcp-server
|
|
20
|
-
|
|
21
|
-
# To call a specific tool via CLI (example)
|
|
22
|
-
npx -y @x0333/bitrix24-mcp-server get_profile
|
|
23
31
|
```
|
|
24
32
|
|
|
25
|
-
|
|
33
|
+
Для работы нужно передать переменную окружения `B24_BASE`.
|
|
34
|
+
Пример запуска:
|
|
26
35
|
|
|
27
|
-
|
|
36
|
+
```bash
|
|
37
|
+
B24_BASE="https://your-domain.bitrix24.ru/rest/USER_ID/WEBHOOK_CODE/" npx -y @x0333/bitrix24-mcp-server
|
|
38
|
+
```
|
|
28
39
|
|
|
29
|
-
|
|
40
|
+
## 🧩 Конфигурация для Manus / Claude Desktop
|
|
30
41
|
|
|
31
|
-
|
|
42
|
+
Пример MCP-конфига:
|
|
32
43
|
|
|
33
44
|
```json
|
|
34
45
|
{
|
|
@@ -44,13 +55,31 @@ Add this to your configuration:
|
|
|
44
55
|
}
|
|
45
56
|
```
|
|
46
57
|
|
|
47
|
-
|
|
58
|
+
После этого AI-клиент сможет вызывать инструменты сервера и получать данные из Bitrix24.
|
|
59
|
+
|
|
60
|
+
## 🔑 Как получить Webhook URL в Bitrix24
|
|
61
|
+
|
|
62
|
+
1. Откройте свой портал Bitrix24.
|
|
63
|
+
2. Перейдите в раздел **Разработчикам**.
|
|
64
|
+
3. Создайте **Входящий вебхук**.
|
|
65
|
+
4. Выдайте вебхуку нужные права (минимум для текущих инструментов):
|
|
66
|
+
- задачи (в т.ч. стадии канбана групповых задач);
|
|
67
|
+
- рабочие группы / проекты;
|
|
68
|
+
- пользователи (для профиля).
|
|
69
|
+
5. Скопируйте **URL для вызова REST API**.
|
|
70
|
+
|
|
71
|
+
Обычно он выглядит примерно так:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
https://domain.bitrix24.ru/rest/1/abcdef12345/
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Именно этот URL нужно передать в переменную `B24_BASE`.
|
|
78
|
+
|
|
79
|
+
## 🛠️ Разработка
|
|
48
80
|
|
|
49
|
-
|
|
50
|
-
2. Navigate to **Developer Resources** -> **Other** -> **Inbound Webhook**.
|
|
51
|
-
3. Select the required permissions (Tasks, Social Network, User).
|
|
52
|
-
4. Copy the **URL for REST API call** (it should look like `https://domain.bitrix24.ru/rest/1/abcdef12345/`).
|
|
81
|
+
В проекте используется `pnpm`, `pnpm install` для установки зависимостей.
|
|
53
82
|
|
|
54
|
-
## License
|
|
83
|
+
## 📄 License
|
|
55
84
|
|
|
56
85
|
MIT
|
package/index.js
CHANGED
|
@@ -27,7 +27,7 @@ if (!B24_BASE) {
|
|
|
27
27
|
const server = new Server(
|
|
28
28
|
{
|
|
29
29
|
name: "bitrix24-mcp-server",
|
|
30
|
-
version: "2.
|
|
30
|
+
version: "2.2.0",
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
capabilities: {
|
|
@@ -86,16 +86,20 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
name: "search_tasks",
|
|
89
|
-
description:
|
|
89
|
+
description:
|
|
90
|
+
"Search tasks in Bitrix24: by title substring (%TITLE), by Kanban stage id (filter STAGE_ID), or both.",
|
|
90
91
|
inputSchema: {
|
|
91
92
|
type: "object",
|
|
92
93
|
properties: {
|
|
93
94
|
title: { type: "string", description: "Substring of the task title to search for" },
|
|
95
|
+
stage_id: {
|
|
96
|
+
type: "number",
|
|
97
|
+
description: "Kanban stage ID (tasks.task.list filter STAGE_ID)",
|
|
98
|
+
},
|
|
94
99
|
order: { type: "string", description: "Field to sort by (default: 'ID')" },
|
|
95
100
|
dir: { type: "string", enum: ["asc", "desc"], description: "Sort direction (default: 'desc')" },
|
|
96
101
|
start: { type: "number", description: "Pagination offset (default: 0)" },
|
|
97
102
|
},
|
|
98
|
-
required: ["title"],
|
|
99
103
|
},
|
|
100
104
|
},
|
|
101
105
|
{
|
|
@@ -105,7 +109,6 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
105
109
|
type: "object",
|
|
106
110
|
properties: {
|
|
107
111
|
name: { type: "string", description: "Substring of the group name to search for" },
|
|
108
|
-
start: { type: "number", description: "Pagination offset (default: 0)" },
|
|
109
112
|
},
|
|
110
113
|
required: ["name"],
|
|
111
114
|
},
|
|
@@ -121,6 +124,18 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
121
124
|
required: ["id"],
|
|
122
125
|
},
|
|
123
126
|
},
|
|
127
|
+
{
|
|
128
|
+
name: "get_kanban_stages_by_group",
|
|
129
|
+
description:
|
|
130
|
+
"Get task Kanban stages for a workgroup or project (task.stages.get). entityId is the group ID.",
|
|
131
|
+
inputSchema: {
|
|
132
|
+
type: "object",
|
|
133
|
+
properties: {
|
|
134
|
+
id: { type: "number", description: "The unique ID of the group (entityId for task kanban)" },
|
|
135
|
+
},
|
|
136
|
+
required: ["id"],
|
|
137
|
+
},
|
|
138
|
+
},
|
|
124
139
|
],
|
|
125
140
|
};
|
|
126
141
|
});
|
|
@@ -145,10 +160,23 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
145
160
|
}
|
|
146
161
|
|
|
147
162
|
case "search_tasks": {
|
|
163
|
+
const hasTitle = args.title != null && String(args.title).trim() !== "";
|
|
164
|
+
const hasStage =
|
|
165
|
+
args.stage_id !== undefined && args.stage_id !== null && !Number.isNaN(Number(args.stage_id));
|
|
166
|
+
if (!hasTitle && !hasStage) {
|
|
167
|
+
throw new Error("search_tasks requires at least one of: title, stage_id");
|
|
168
|
+
}
|
|
169
|
+
const filter = {};
|
|
170
|
+
if (hasTitle) {
|
|
171
|
+
filter["%TITLE"] = args.title;
|
|
172
|
+
}
|
|
173
|
+
if (hasStage) {
|
|
174
|
+
filter.STAGE_ID = Number(args.stage_id);
|
|
175
|
+
}
|
|
148
176
|
const body = {
|
|
149
177
|
order: { [args.order || "ID"]: (args.dir || "desc").toUpperCase() },
|
|
150
|
-
filter
|
|
151
|
-
select: ["ID", "TITLE", "STATUS", "RESPONSIBLE_ID", "GROUP_ID"],
|
|
178
|
+
filter,
|
|
179
|
+
select: ["ID", "TITLE", "STATUS", "RESPONSIBLE_ID", "GROUP_ID", "STAGE_ID"],
|
|
152
180
|
start: args.start || 0,
|
|
153
181
|
};
|
|
154
182
|
const data = await callBitrix("tasks.task.list", body);
|
|
@@ -157,17 +185,21 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
157
185
|
|
|
158
186
|
case "search_groups": {
|
|
159
187
|
const body = {
|
|
160
|
-
|
|
161
|
-
order: { ID: "DESC" },
|
|
162
|
-
start: args.start || 0,
|
|
188
|
+
FILTER: { "%NAME": args.name },
|
|
163
189
|
};
|
|
164
|
-
const data = await callBitrix("
|
|
190
|
+
const data = await callBitrix("sonet_group.get.json", body);
|
|
165
191
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
166
192
|
}
|
|
167
193
|
|
|
168
194
|
case "get_group": {
|
|
169
|
-
const body = {
|
|
170
|
-
const data = await callBitrix("
|
|
195
|
+
const body = { FILTER: { ID: args.id } };
|
|
196
|
+
const data = await callBitrix("sonet_group.get.json", body);
|
|
197
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
case "get_kanban_stages_by_group": {
|
|
201
|
+
const body = { entityId: args.id };
|
|
202
|
+
const data = await callBitrix("task.stages.get", body);
|
|
171
203
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
172
204
|
}
|
|
173
205
|
|