nodebb-plugin-integration 0.4.4 → 0.6.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/README.md +156 -145
- package/README.ru.md +147 -136
- package/docs/MCP.md +718 -0
- package/docs/MCP.ru.md +719 -0
- package/package.json +3 -2
- package/src/mcp/server.js +32 -28
- package/src/mcp/tools.js +294 -76
- package/src/nodebb/posts.js +72 -21
- package/src/nodebb/topics.js +121 -24
- package/src/nodebb/users.js +19 -4
- package/src/routes/api.js +297 -35
- package/src/routes/index.js +24 -31
package/docs/MCP.ru.md
ADDED
|
@@ -0,0 +1,719 @@
|
|
|
1
|
+
# Справочник MCP API
|
|
2
|
+
|
|
3
|
+
Версия: 0.6.0
|
|
4
|
+
|
|
5
|
+
Документ описывает все MCP-инструменты, предоставляемые плагином `nodebb-plugin-integration`.
|
|
6
|
+
|
|
7
|
+
## 1. Обзор
|
|
8
|
+
|
|
9
|
+
Плагин предоставляет сервер Model Context Protocol (MCP) с транспортом Streamable HTTP.
|
|
10
|
+
|
|
11
|
+
Архитектура:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
MCP-клиент
|
|
15
|
+
|
|
|
16
|
+
| Streamable HTTP + Bearer-токен
|
|
17
|
+
v
|
|
18
|
+
Дочерний процесс MCP
|
|
19
|
+
|
|
|
20
|
+
| Внутренний HTTP API + отдельный Bearer-токен
|
|
21
|
+
v
|
|
22
|
+
Плагин интеграции NodeBB
|
|
23
|
+
|
|
|
24
|
+
v
|
|
25
|
+
Нативные API NodeBB и проверки прав
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
MCP работает в отдельном дочернем процессе, которым управляет плагин NodeBB.
|
|
29
|
+
|
|
30
|
+
Все операции записи выполняются от имени NodeBB-аккаунта, заданного параметром `mcpServiceUid`. MCP-клиент не может самостоятельно выбрать или подменить пользователя, от имени которого выполняется операция.
|
|
31
|
+
|
|
32
|
+
## 2. Настройка
|
|
33
|
+
|
|
34
|
+
Настройки находятся в NodeBB ACP → Plugins → NodeBB Integration.
|
|
35
|
+
|
|
36
|
+
| Параметр | Описание |
|
|
37
|
+
|---|---|
|
|
38
|
+
| Enable MCP | Включение и выключение MCP-сервера |
|
|
39
|
+
| Bind address | Сетевой интерфейс, на котором слушает HTTP-сервер MCP |
|
|
40
|
+
| Port | HTTP-порт MCP |
|
|
41
|
+
| NodeBB URL | Адрес NodeBB, используемый процессом MCP |
|
|
42
|
+
| Bearer token | Секрет для аутентификации MCP-клиентов |
|
|
43
|
+
| Service user UID | NodeBB UID пользователя для проверок прав и операций записи | . Обязательный параметр; должен быть положительным целым числом.
|
|
44
|
+
|
|
45
|
+
Значения по умолчанию:
|
|
46
|
+
|
|
47
|
+
- Адрес: `127.0.0.1`
|
|
48
|
+
- Порт: `3100`
|
|
49
|
+
- NodeBB URL: `http://127.0.0.1:4567`
|
|
50
|
+
|
|
51
|
+
Плагин автоматически генерирует и сохраняет отдельный токен внутреннего API.
|
|
52
|
+
|
|
53
|
+
Внешний Bearer-токен MCP и токен внутреннего API — разные секреты.
|
|
54
|
+
|
|
55
|
+
Не передавайте токен внутреннего API MCP-клиентам.
|
|
56
|
+
|
|
57
|
+
## 3. Аутентификация и права доступа
|
|
58
|
+
|
|
59
|
+
MCP-клиент передаёт токен в заголовке:
|
|
60
|
+
|
|
61
|
+
```http
|
|
62
|
+
Authorization: Bearer YOUR_MCP_TOKEN
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Дочерний процесс MCP использует отдельный токен для аутентификации запросов к NodeBB.
|
|
66
|
+
|
|
67
|
+
Внутренний API отклоняет запросы, если MCP выключен или внутренний токен неверен.
|
|
68
|
+
|
|
69
|
+
### Пользователь, от имени которого выполняются операции
|
|
70
|
+
|
|
71
|
+
Настроенный `mcpServiceUid` используется для:
|
|
72
|
+
|
|
73
|
+
- Чтения сообщений и тем с проверкой прав.
|
|
74
|
+
- Фильтрации результатов семантического поиска.
|
|
75
|
+
- Получения списков тем и сообщений.
|
|
76
|
+
- Создания тем и ответов.
|
|
77
|
+
- Редактирования, удаления и восстановления сообщений.
|
|
78
|
+
- Удаления и восстановления тем.
|
|
79
|
+
- Массового удаления ответов пользователя.
|
|
80
|
+
|
|
81
|
+
Аргумент `uid` инструмента `delete_user_posts` указывает целевого автора сообщений. Он не меняет пользователя, от имени которого выполняется удаление.
|
|
82
|
+
|
|
83
|
+
### Проверки NodeBB
|
|
84
|
+
|
|
85
|
+
Для операций записи используются нативные методы NodeBB. Сохраняются штатные проверки прав, ограничения и хуки.
|
|
86
|
+
|
|
87
|
+
В частности:
|
|
88
|
+
|
|
89
|
+
- Проверки прав категории при создании темы.
|
|
90
|
+
- Проверки права ответа и состояния темы.
|
|
91
|
+
- Проверки права редактирования и ограничений редактирования.
|
|
92
|
+
- Проверки прав удаления и восстановления сообщений и тем.
|
|
93
|
+
- Нативные хуки NodeBB, связанные с этими операциями.
|
|
94
|
+
|
|
95
|
+
Операции чтения содержимого сообщений и тем проверяют доступ пользователя сервиса.
|
|
96
|
+
|
|
97
|
+
`get_user` возвращает публичные поля профиля и не раскрывает приватные данные аккаунта.
|
|
98
|
+
|
|
99
|
+
При ошибке проверки доступа доступ запрещается.
|
|
100
|
+
|
|
101
|
+
## 4. Общие правила аргументов
|
|
102
|
+
|
|
103
|
+
- ID должны быть положительными безопасными целыми числами.
|
|
104
|
+
- Смещения пагинации должны быть неотрицательными целыми числами.
|
|
105
|
+
- Неизвестные аргументы отклоняются.
|
|
106
|
+
- Дополнительные свойства объектов запрещены.
|
|
107
|
+
- Текстовые аргументы не могут быть пустыми или состоять только из пробелов.
|
|
108
|
+
- Ограничения длины текста измеряются в символах JavaScript-строки.
|
|
109
|
+
- Аргументы инструмента должны быть JSON-объектами.
|
|
110
|
+
|
|
111
|
+
Результаты инструментов возвращаются в MCP как текст с форматированным JSON. Ошибки возвращаются как результаты инструмента с `isError: true`.
|
|
112
|
+
|
|
113
|
+
## 5. Описание инструментов
|
|
114
|
+
|
|
115
|
+
### 5.1 get_forum_info
|
|
116
|
+
|
|
117
|
+
Получает общедоступную информацию о форуме.
|
|
118
|
+
|
|
119
|
+
Аргументы: отсутствуют.
|
|
120
|
+
|
|
121
|
+
Пример:
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Поля ответа:
|
|
128
|
+
|
|
129
|
+
| Поле | Тип | Описание |
|
|
130
|
+
|---|---|---|
|
|
131
|
+
| title | string | Название форума |
|
|
132
|
+
| url | string | URL форума |
|
|
133
|
+
| version | string | Версия NodeBB |
|
|
134
|
+
| language | string или null | Язык форума |
|
|
135
|
+
|
|
136
|
+
Пример:
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"title": "Example Forum",
|
|
141
|
+
"url": "https://forum.example.com",
|
|
142
|
+
"version": "4.16.7",
|
|
143
|
+
"language": "ru"
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 5.2 get_post
|
|
148
|
+
|
|
149
|
+
Получает сообщение по ID после проверки прав настроенного пользователя сервиса на чтение сообщения и его темы.
|
|
150
|
+
|
|
151
|
+
Аргументы:
|
|
152
|
+
|
|
153
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
154
|
+
|---|---|---|---|
|
|
155
|
+
| pid | integer | Да | Минимум 1 |
|
|
156
|
+
|
|
157
|
+
Пример:
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"pid": 123
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Поля ответа:
|
|
166
|
+
|
|
167
|
+
| Поле | Тип | Описание |
|
|
168
|
+
|---|---|---|
|
|
169
|
+
| pid | integer | ID сообщения |
|
|
170
|
+
| tid | integer | ID темы |
|
|
171
|
+
| uid | integer | UID автора |
|
|
172
|
+
| cid | integer | ID категории |
|
|
173
|
+
| content | string | Содержимое сообщения |
|
|
174
|
+
| timestamp | NodeBB timestamp | Время создания сообщения |
|
|
175
|
+
|
|
176
|
+
Удалённые, отсутствующие и недоступные пользователю сервиса сообщения возвращаются как ненайденные.
|
|
177
|
+
|
|
178
|
+
### 5.3 get_topic
|
|
179
|
+
|
|
180
|
+
Получает метаданные темы после проверки права на её чтение.
|
|
181
|
+
|
|
182
|
+
Аргументы:
|
|
183
|
+
|
|
184
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
185
|
+
|---|---|---|---|
|
|
186
|
+
| tid | integer | Да | Минимум 1 |
|
|
187
|
+
|
|
188
|
+
Пример:
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"tid": 42
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Поля ответа:
|
|
197
|
+
|
|
198
|
+
| Поле | Тип | Описание |
|
|
199
|
+
|---|---|---|
|
|
200
|
+
| tid | integer | ID темы |
|
|
201
|
+
| uid | integer | UID автора темы |
|
|
202
|
+
| title | string | Заголовок темы |
|
|
203
|
+
| cid | integer | ID категории |
|
|
204
|
+
| timestamp | NodeBB timestamp | Время создания темы |
|
|
205
|
+
| mainPid | integer | ID первого сообщения |
|
|
206
|
+
|
|
207
|
+
Инструмент возвращает метаданные темы, а не полный список сообщений. Для получения сообщений используйте `list_posts`.
|
|
208
|
+
|
|
209
|
+
### 5.4 get_user
|
|
210
|
+
|
|
211
|
+
Возвращает публичную информацию о профиле пользователя.
|
|
212
|
+
|
|
213
|
+
Аргумент `uid` указывает пользователя, чей профиль требуется получить. Он не меняет пользователя сервиса и не используется для выполнения операций от его имени.
|
|
214
|
+
|
|
215
|
+
Аргументы:
|
|
216
|
+
|
|
217
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
218
|
+
|---|---|---|---|
|
|
219
|
+
| uid | integer | Да | Минимум 1 |
|
|
220
|
+
|
|
221
|
+
Пример:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"uid": 7
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Поля ответа:
|
|
230
|
+
|
|
231
|
+
| Поле | Тип | Описание |
|
|
232
|
+
|---|---|---|
|
|
233
|
+
| uid | integer | ID пользователя |
|
|
234
|
+
| username | string | Имя пользователя |
|
|
235
|
+
| userslug | string | URL-совместимое имя |
|
|
236
|
+
| picture | string | URL или значение аватара, предоставленное NodeBB |
|
|
237
|
+
|
|
238
|
+
Возвращаются только перечисленные выше поля.
|
|
239
|
+
|
|
240
|
+
### 5.5 search_knowledge
|
|
241
|
+
|
|
242
|
+
Выполняет семантический поиск по базе знаний форума.
|
|
243
|
+
|
|
244
|
+
Требует включённого провайдера OpenAI и работающей коллекции Qdrant.
|
|
245
|
+
|
|
246
|
+
Аргументы:
|
|
247
|
+
|
|
248
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
249
|
+
|---|---|---|---|
|
|
250
|
+
| query | string | Да | 1–2000 символов |
|
|
251
|
+
| limit | integer | Нет | 1–20; по умолчанию 5 |
|
|
252
|
+
|
|
253
|
+
Пример:
|
|
254
|
+
|
|
255
|
+
```json
|
|
256
|
+
{
|
|
257
|
+
"query": "Как настроить уведомления форума?",
|
|
258
|
+
"limit": 5
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Ответ:
|
|
263
|
+
|
|
264
|
+
```json
|
|
265
|
+
{
|
|
266
|
+
"results": [
|
|
267
|
+
{
|
|
268
|
+
"pid": 123,
|
|
269
|
+
"tid": 42,
|
|
270
|
+
"uid": 7,
|
|
271
|
+
"cid": 3,
|
|
272
|
+
"score": 0.91,
|
|
273
|
+
"content": "Содержимое сообщения..."
|
|
274
|
+
}
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Поля результата:
|
|
280
|
+
|
|
281
|
+
| Поле | Тип | Описание |
|
|
282
|
+
|---|---|---|
|
|
283
|
+
| pid | integer | ID сообщения |
|
|
284
|
+
| tid | integer | ID темы |
|
|
285
|
+
| uid | integer | UID автора |
|
|
286
|
+
| cid | integer | ID категории |
|
|
287
|
+
| score | number | Оценка семантического сходства из векторного поиска |
|
|
288
|
+
| content | string | Содержимое сообщения, полученное из NodeBB |
|
|
289
|
+
|
|
290
|
+
Алгоритм поиска:
|
|
291
|
+
|
|
292
|
+
1. Создаёт embedding для запроса.
|
|
293
|
+
2. Ищет кандидатов в Qdrant.
|
|
294
|
+
3. Проверяет исключённые категории.
|
|
295
|
+
4. Проверяет права пользователя сервиса на чтение сообщения и темы.
|
|
296
|
+
5. Получает разрешённое содержимое сообщений из NodeBB.
|
|
297
|
+
6. Возвращает не более запрошенного количества подходящих результатов.
|
|
298
|
+
|
|
299
|
+
Реализация может получить больше кандидатов, чем запрошено, чтобы компенсировать отсеивание по правам доступа.
|
|
300
|
+
|
|
301
|
+
В режиме Fake AI инструмент возвращает ошибку о выключенном AI. Семантический поиск не выполняется.
|
|
302
|
+
|
|
303
|
+
### 5.6 create_topic
|
|
304
|
+
|
|
305
|
+
Создаёт тему в категории NodeBB от имени настроенного пользователя сервиса.
|
|
306
|
+
|
|
307
|
+
Аргументы:
|
|
308
|
+
|
|
309
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
310
|
+
|---|---|---|---|
|
|
311
|
+
| cid | integer | Да | Минимум 1 |
|
|
312
|
+
| title | string | Да | 1–255 символов |
|
|
313
|
+
| content | string | Да | 1–20000 символов |
|
|
314
|
+
| tags | массив строк | Нет | Не более 10 тегов; каждый 1–32 символа |
|
|
315
|
+
|
|
316
|
+
Пример:
|
|
317
|
+
|
|
318
|
+
```json
|
|
319
|
+
{
|
|
320
|
+
"cid": 3,
|
|
321
|
+
"title": "Новая дискуссия",
|
|
322
|
+
"content": "Содержимое первого сообщения.",
|
|
323
|
+
"tags": ["discussion", "help"]
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Если `tags` не указан, используется пустой массив.
|
|
328
|
+
|
|
329
|
+
Перед отправкой заголовок очищается от пробелов по краям. Содержимое передаётся NodeBB без обрезки.
|
|
330
|
+
|
|
331
|
+
NodeBB выполняет проверки прав категории, ограничений публикации, тегов и штатные хуки создания темы.
|
|
332
|
+
|
|
333
|
+
Ответ соответствует результату нативного метода NodeBB создания темы.
|
|
334
|
+
|
|
335
|
+
### 5.7 delete_topic
|
|
336
|
+
|
|
337
|
+
Удаляет тему логически (soft delete), используя нативные проверки прав и хуки NodeBB.
|
|
338
|
+
|
|
339
|
+
Аргументы:
|
|
340
|
+
|
|
341
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
342
|
+
|---|---|---|---|
|
|
343
|
+
| tid | integer | Да | Минимум 1 |
|
|
344
|
+
|
|
345
|
+
Пример:
|
|
346
|
+
|
|
347
|
+
```json
|
|
348
|
+
{
|
|
349
|
+
"tid": 42
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Это логическое удаление, а не физическое уничтожение данных.
|
|
354
|
+
|
|
355
|
+
Ответ соответствует результату нативной операции NodeBB.
|
|
356
|
+
|
|
357
|
+
### 5.8 restore_topic
|
|
358
|
+
|
|
359
|
+
Восстанавливает ранее логически удалённую тему.
|
|
360
|
+
|
|
361
|
+
Аргументы:
|
|
362
|
+
|
|
363
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
364
|
+
|---|---|---|---|
|
|
365
|
+
| tid | integer | Да | Минимум 1 |
|
|
366
|
+
|
|
367
|
+
Пример:
|
|
368
|
+
|
|
369
|
+
```json
|
|
370
|
+
{
|
|
371
|
+
"tid": 42
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
NodeBB проверяет права пользователя и выполняет штатные хуки восстановления.
|
|
376
|
+
|
|
377
|
+
Восстановление темы не восстанавливает автоматически сообщения, которые были удалены отдельно.
|
|
378
|
+
|
|
379
|
+
Ответ соответствует результату нативной операции NodeBB.
|
|
380
|
+
|
|
381
|
+
### 5.9 list_topics
|
|
382
|
+
|
|
383
|
+
Получает список тем, доступных настроенному пользователю сервиса.
|
|
384
|
+
|
|
385
|
+
Аргументы:
|
|
386
|
+
|
|
387
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
388
|
+
|---|---|---|---|
|
|
389
|
+
| start | integer | Нет | 0–10000000; по умолчанию 0 |
|
|
390
|
+
| limit | integer | Нет | 1–100; по умолчанию 20 |
|
|
391
|
+
| sort | string | Нет | Одно из допустимых значений; по умолчанию `recent` |
|
|
392
|
+
| cid | integer | Нет | Минимум 1; фильтр по категории |
|
|
393
|
+
|
|
394
|
+
Допустимые значения `sort`:
|
|
395
|
+
|
|
396
|
+
| Значение | Описание |
|
|
397
|
+
|---|---|
|
|
398
|
+
| recent | По последней активности |
|
|
399
|
+
| old | Более старые темы |
|
|
400
|
+
| create | Сортировка по созданию |
|
|
401
|
+
| posts | По количеству сообщений |
|
|
402
|
+
| votes | По голосам |
|
|
403
|
+
| views | По просмотрам |
|
|
404
|
+
|
|
405
|
+
Пример:
|
|
406
|
+
|
|
407
|
+
```json
|
|
408
|
+
{
|
|
409
|
+
"start": 0,
|
|
410
|
+
"limit": 20,
|
|
411
|
+
"sort": "recent",
|
|
412
|
+
"cid": 3
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Ответ содержит результат нативного списка NodeBB и метаданные пагинации:
|
|
417
|
+
|
|
418
|
+
| Поле | Тип | Описание |
|
|
419
|
+
|---|---|---|
|
|
420
|
+
| topics | array | Записи тем, возвращённые NodeBB |
|
|
421
|
+
| topicCount | integer | Общее количество тем по данным NodeBB |
|
|
422
|
+
| nextStart | integer | Рекомендуемое смещение следующего запроса |
|
|
423
|
+
| hasMore | boolean | `hasMore` — подсказка о наличии следующих результатов, рассчитанная по общему количеству записей NodeBB. Она не гарантирует, что следующий запрос вернёт непустую страницу. |
|
|
424
|
+
|
|
425
|
+
Точный набор полей записей тем определяется установленной версией NodeBB.
|
|
426
|
+
|
|
427
|
+
### 5.10 create_post
|
|
428
|
+
|
|
429
|
+
Создаёт ответ в существующей теме.
|
|
430
|
+
|
|
431
|
+
Инструмент создаёт ответ, а не новую тему и не заменяет первое сообщение темы.
|
|
432
|
+
|
|
433
|
+
Аргументы:
|
|
434
|
+
|
|
435
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
436
|
+
|---|---|---|---|
|
|
437
|
+
| tid | integer | Да | Минимум 1 |
|
|
438
|
+
| content | string | Да | 1–20000 символов |
|
|
439
|
+
|
|
440
|
+
Пример:
|
|
441
|
+
|
|
442
|
+
```json
|
|
443
|
+
{
|
|
444
|
+
"tid": 42,
|
|
445
|
+
"content": "Это ответ в теме."
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
Ответ создаётся от имени настроенного пользователя сервиса.
|
|
450
|
+
|
|
451
|
+
NodeBB проверяет право ответа, состояние темы, права категории и штатные ограничения публикации.
|
|
452
|
+
|
|
453
|
+
Ответ соответствует результату нативного метода NodeBB создания ответа.
|
|
454
|
+
|
|
455
|
+
### 5.11 edit_post
|
|
456
|
+
|
|
457
|
+
Редактирует существующее сообщение.
|
|
458
|
+
|
|
459
|
+
Аргументы:
|
|
460
|
+
|
|
461
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
462
|
+
|---|---|---|---|
|
|
463
|
+
| pid | integer | Да | Минимум 1 |
|
|
464
|
+
| content | string | Да | 1–20000 символов |
|
|
465
|
+
|
|
466
|
+
Пример:
|
|
467
|
+
|
|
468
|
+
```json
|
|
469
|
+
{
|
|
470
|
+
"pid": 123,
|
|
471
|
+
"content": "Обновлённый текст сообщения."
|
|
472
|
+
}
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
Операция выполняется от имени настроенного пользователя сервиса.
|
|
476
|
+
|
|
477
|
+
NodeBB применяет штатные проверки прав и ограничения редактирования. Сохраняются нативные хуки и история редактирования.
|
|
478
|
+
|
|
479
|
+
Ответ соответствует результату нативного метода NodeBB редактирования.
|
|
480
|
+
|
|
481
|
+
### 5.12 delete_post
|
|
482
|
+
|
|
483
|
+
Логически удаляет сообщение.
|
|
484
|
+
|
|
485
|
+
Аргументы:
|
|
486
|
+
|
|
487
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
488
|
+
|---|---|---|---|
|
|
489
|
+
| pid | integer | Да | Минимум 1 |
|
|
490
|
+
|
|
491
|
+
Пример:
|
|
492
|
+
|
|
493
|
+
```json
|
|
494
|
+
{
|
|
495
|
+
"pid": 123
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
NodeBB применяет штатные проверки прав и хуки удаления сообщения.
|
|
500
|
+
|
|
501
|
+
Это не физическое удаление. Методы окончательной очистки (purge) не вызываются.
|
|
502
|
+
|
|
503
|
+
Ответ соответствует результату нативной операции NodeBB.
|
|
504
|
+
|
|
505
|
+
### 5.13 restore_post
|
|
506
|
+
|
|
507
|
+
Восстанавливает логически удалённое сообщение.
|
|
508
|
+
|
|
509
|
+
Аргументы:
|
|
510
|
+
|
|
511
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
512
|
+
|---|---|---|---|
|
|
513
|
+
| pid | integer | Да | Минимум 1 |
|
|
514
|
+
|
|
515
|
+
Пример:
|
|
516
|
+
|
|
517
|
+
```json
|
|
518
|
+
{
|
|
519
|
+
"pid": 123
|
|
520
|
+
}
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
NodeBB применяет штатные проверки прав и хуки восстановления.
|
|
524
|
+
|
|
525
|
+
Ответ соответствует результату нативной операции NodeBB.
|
|
526
|
+
|
|
527
|
+
### 5.14 delete_user_posts
|
|
528
|
+
|
|
529
|
+
Логически удаляет ответы, написанные указанным пользователем.
|
|
530
|
+
|
|
531
|
+
Первое сообщение каждой темы всегда пропускается. Инструмент не удаляет первые сообщения тем.
|
|
532
|
+
|
|
533
|
+
Аргументы:
|
|
534
|
+
|
|
535
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
536
|
+
|---|---|---|---|
|
|
537
|
+
| uid | integer | Да | UID целевого пользователя; минимум 1 |
|
|
538
|
+
| start | integer | Нет | 0–10000000; по умолчанию 0 |
|
|
539
|
+
| limit | integer | Нет | 1–100; по умолчанию 100 |
|
|
540
|
+
|
|
541
|
+
Пример:
|
|
542
|
+
|
|
543
|
+
```json
|
|
544
|
+
{
|
|
545
|
+
"uid": 25,
|
|
546
|
+
"start": 0,
|
|
547
|
+
"limit": 100
|
|
548
|
+
}
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
Удаление выполняется настроенным пользователем сервиса. Переданный `uid` указывает только целевого автора сообщений.
|
|
552
|
+
|
|
553
|
+
Операция обрабатывает сообщения последовательно и продолжает работу после отдельных ошибок удаления.
|
|
554
|
+
|
|
555
|
+
Ошибки отдельных операций удаления включаются в массив `failed`. Сами по себе такие ошибки не прерывают обработку остальных сообщений и не означают, что весь вызов инструмента завершился ошибкой.
|
|
556
|
+
|
|
557
|
+
Сообщения пропускаются, если их ID некорректен, сообщение отсутствует, уже удалено, принадлежит другому пользователю или является первым сообщением темы.
|
|
558
|
+
|
|
559
|
+
Ответ:
|
|
560
|
+
|
|
561
|
+
| Поле | Тип | Описание |
|
|
562
|
+
|---|---|---|
|
|
563
|
+
| uid | integer | UID целевого пользователя |
|
|
564
|
+
| scanned | integer | Количество ID, полученных на текущей странице |
|
|
565
|
+
| deleted | integer | Количество успешно удалённых ответов |
|
|
566
|
+
| skipped | integer | Количество пропущенных сообщений |
|
|
567
|
+
| failed | array | Ошибки отдельных операций удаления |
|
|
568
|
+
| hasMore | boolean | Заполнена ли текущая страница ID до запрошенного лимита |
|
|
569
|
+
| nextStart | integer | Рекомендуемое смещение следующей пачки |
|
|
570
|
+
|
|
571
|
+
Каждая запись `failed` содержит:
|
|
572
|
+
|
|
573
|
+
```json
|
|
574
|
+
{
|
|
575
|
+
"pid": 123,
|
|
576
|
+
"error": "Permission denied"
|
|
577
|
+
}
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
Пример ответа:
|
|
581
|
+
|
|
582
|
+
```json
|
|
583
|
+
{
|
|
584
|
+
"uid": 25,
|
|
585
|
+
"scanned": 100,
|
|
586
|
+
"deleted": 85,
|
|
587
|
+
"skipped": 10,
|
|
588
|
+
"failed": [
|
|
589
|
+
{
|
|
590
|
+
"pid": 456,
|
|
591
|
+
"error": "Permission denied"
|
|
592
|
+
}
|
|
593
|
+
],
|
|
594
|
+
"hasMore": true,
|
|
595
|
+
"nextStart": 15
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
Пример иллюстративный: реальные значения зависят от полученных ID и результатов операций.
|
|
600
|
+
|
|
601
|
+
#### Обработка пачками
|
|
602
|
+
|
|
603
|
+
Для следующего запроса используйте `nextStart` из предыдущего ответа в качестве `start`:
|
|
604
|
+
|
|
605
|
+
```json
|
|
606
|
+
{
|
|
607
|
+
"uid": 25,
|
|
608
|
+
"start": 15,
|
|
609
|
+
"limit": 100
|
|
610
|
+
}
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
Успешно удалённые сообщения исчезают из активного списка сообщений пользователя. Реализация вычитает количество успешно удалённых сообщений из `nextStart`, чтобы не пропускать оставшиеся ответы из-за смещения списка.
|
|
614
|
+
|
|
615
|
+
`hasMore` определяется по тому, содержит ли текущая страница ID полное запрошенное количество записей. Это подсказка пагинации: дополнительный запрос может вернуть пустую страницу.
|
|
616
|
+
|
|
617
|
+
Операция не выполняет физическое уничтожение данных. Первые сообщения тем этим инструментом не удаляются.
|
|
618
|
+
### 5.15 list_posts
|
|
619
|
+
|
|
620
|
+
Получает сообщения темы с применением фильтрации доступа NodeBB и пагинации.
|
|
621
|
+
|
|
622
|
+
Аргументы:
|
|
623
|
+
|
|
624
|
+
| Имя | Тип | Обязательный | Ограничения |
|
|
625
|
+
|---|---|---|---|
|
|
626
|
+
| tid | integer | Да | Минимум 1 |
|
|
627
|
+
| start | integer | Нет | 0–10000000; по умолчанию 0 |
|
|
628
|
+
| limit | integer | Нет | 1–100; по умолчанию 20 |
|
|
629
|
+
| reverse | boolean | Нет | По умолчанию false |
|
|
630
|
+
|
|
631
|
+
Пример:
|
|
632
|
+
|
|
633
|
+
```json
|
|
634
|
+
{
|
|
635
|
+
"tid": 42,
|
|
636
|
+
"start": 0,
|
|
637
|
+
"limit": 20,
|
|
638
|
+
"reverse": false
|
|
639
|
+
}
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
Ответ:
|
|
643
|
+
|
|
644
|
+
| Поле | Тип | Описание |
|
|
645
|
+
|---|---|---|
|
|
646
|
+
| tid | integer | ID темы |
|
|
647
|
+
| start | integer | Запрошенное смещение |
|
|
648
|
+
| limit | integer | Запрошенный размер страницы |
|
|
649
|
+
| reverse | boolean | Флаг обратного порядка |
|
|
650
|
+
| posts | array | Записи сообщений темы, возвращённые NodeBB |
|
|
651
|
+
| total | integer | Количество сообщений темы по данным NodeBB |
|
|
652
|
+
| nextStart | integer | Рекомендуемое смещение следующей страницы |
|
|
653
|
+
| hasMore | boolean | `hasMore` — подсказка о наличии следующих результатов, рассчитанная по общему количеству записей NodeBB. Она не гарантирует, что следующий запрос вернёт непустую страницу. |
|
|
654
|
+
|
|
655
|
+
Поля записей сообщений определяются установленной версией NodeBB.
|
|
656
|
+
|
|
657
|
+
Перед получением сообщений проверяется право пользователя сервиса на чтение темы. Удалённые или недоступные темы не возвращаются.
|
|
658
|
+
|
|
659
|
+
## 6. Пагинация
|
|
660
|
+
|
|
661
|
+
Инструменты списков используют смещения, начинающиеся с нуля.
|
|
662
|
+
|
|
663
|
+
| Инструмент | Начальное смещение | Лимит по умолчанию | Максимум |
|
|
664
|
+
|---|---:|---:|---:|
|
|
665
|
+
| list_topics | 0 | 20 | 100 |
|
|
666
|
+
| list_posts | 0 | 20 | 100 |
|
|
667
|
+
| delete_user_posts | 0 | 100 | 100 |
|
|
668
|
+
|
|
669
|
+
Для инструментов списков используйте возвращённый `nextStart` в следующем запросе, если `hasMore` равен `true`.
|
|
670
|
+
|
|
671
|
+
Для массового удаления всегда используйте возвращённый `nextStart`, поскольку успешное удаление изменяет активный список сообщений пользователя.
|
|
672
|
+
|
|
673
|
+
## 7. Ошибки
|
|
674
|
+
|
|
675
|
+
Сервер MCP возвращает ошибки выполнения как текст с `isError: true`.
|
|
676
|
+
|
|
677
|
+
Типичные ситуации:
|
|
678
|
+
|
|
679
|
+
| Ситуация | Поведение |
|
|
680
|
+
|---|---|
|
|
681
|
+
| Некорректные аргументы | Ошибка проверки аргументов |
|
|
682
|
+
| Неизвестный или дополнительный аргумент | Запрос отклоняется |
|
|
683
|
+
| Некорректный ID | Запрос отклоняется |
|
|
684
|
+
| MCP выключен | Внутренний API отклоняет запрос |
|
|
685
|
+
| Неверный внутренний токен | Внутренний API возвращает Unauthorized |
|
|
686
|
+
| Сообщение или тема отсутствуют либо недоступны | Для защищённых операций чтения возвращается Not found |
|
|
687
|
+
| Нет прав NodeBB | Ошибка нативной операции NodeBB |
|
|
688
|
+
| AI-провайдер выключен | Семантический поиск недоступен |
|
|
689
|
+
| Ошибка внутренней операции | Инструмент возвращает ошибку |
|
|
690
|
+
|
|
691
|
+
Для `search_knowledge` выключенный AI возвращается как явная ошибка. Другие ошибки поисковой инфраструктуры также возвращаются как ошибки.
|
|
692
|
+
|
|
693
|
+
Массовое удаление отличается от одиночных операций: отдельные ошибки собираются в `failed`, обработка остальных ID продолжается.
|
|
694
|
+
|
|
695
|
+
## 8. Безопасность и эксплуатация
|
|
696
|
+
|
|
697
|
+
- Используйте отдельную учётную запись NodeBB с минимально необходимыми правами.
|
|
698
|
+
- Не раскрывайте токен внутреннего API MCP.
|
|
699
|
+
- Используйте `127.0.0.1` для bind-адреса, если удалённый доступ не требуется.
|
|
700
|
+
- При удалённом доступе используйте защищённый сетевой канал.
|
|
701
|
+
- Инструменты удаления выполняют логическое удаление, а не окончательную очистку.
|
|
702
|
+
- `delete_user_posts` пропускает первые сообщения тем.
|
|
703
|
+
- Восстановление темы не восстанавливает отдельно удалённые сообщения.
|
|
704
|
+
- Семантический поиск возвращает только сообщения, доступные пользователю сервиса.
|
|
705
|
+
- Плагин не доверяет UID пользователя, переданному клиентом для операций записи.
|
|
706
|
+
|
|
707
|
+
## 9. Совместимость
|
|
708
|
+
|
|
709
|
+
Плагин предназначен для NodeBB 4.x и требует Node.js >= 22.
|
|
710
|
+
|
|
711
|
+
Реализация версии 0.6.0 проверена на NodeBB 4.16.7.
|
|
712
|
+
|
|
713
|
+
Для создания, редактирования, удаления, восстановления и получения списков используются нативные методы NodeBB. Набор полей нативных ответов может отличаться между версиями NodeBB.
|
|
714
|
+
|
|
715
|
+
## 10. Связанная документация
|
|
716
|
+
|
|
717
|
+
- [README проекта](../README.md)
|
|
718
|
+
- [English MCP documentation](MCP.md)
|
|
719
|
+
- [Русский README](../README.ru.md)
|