nodebb-plugin-integration 0.4.1 → 0.4.4
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 +199 -320
- package/README.ru.md +199 -347
- package/languages/en-GB/integration.json +15 -0
- package/languages/ru/integration.json +15 -0
- package/library.js +93 -115
- package/package.json +60 -53
- package/plugin.json +50 -33
- package/public/js/admin.js +58 -0
- package/public/templates/admin/plugins/integration.tpl +213 -0
- package/src/ai/embeddings.js +46 -253
- package/src/ai/indexer.js +156 -343
- package/src/ai/openai.js +74 -330
- package/src/ai/qdrant.js +114 -517
- package/src/ai/search.js +138 -251
- package/src/config/index.js +176 -133
- package/src/config/validation.js +250 -0
- package/src/events/index.js +174 -324
- package/src/mcp/manager.js +396 -0
- package/src/mcp/server.js +338 -172
- package/src/mcp/tools.js +158 -617
- package/src/nodebb/categories.js +39 -0
- package/src/nodebb/index.js +72 -305
- package/src/nodebb/meta.js +24 -273
- package/src/nodebb/posts.js +93 -348
- package/src/nodebb/privileges.js +68 -0
- package/src/nodebb/topics.js +91 -355
- package/src/nodebb/users.js +62 -345
- package/src/routes/api.js +255 -97
- package/src/routes/index.js +64 -49
package/src/mcp/tools.js
CHANGED
|
@@ -1,654 +1,195 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
/*
|
|
4
|
-
|
|
5
|
-
NodeBB Integration Layer
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
MCP Tools
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const Meta =
|
|
18
|
-
require("../nodebb/meta");
|
|
19
|
-
|
|
20
|
-
const Posts =
|
|
21
|
-
require("../nodebb/posts");
|
|
22
|
-
|
|
23
|
-
const Topics =
|
|
24
|
-
require("../nodebb/topics");
|
|
25
|
-
|
|
26
|
-
const Users =
|
|
27
|
-
require("../nodebb/users");
|
|
28
|
-
|
|
29
|
-
const Search =
|
|
30
|
-
require("../ai/search");
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
3
|
const definitions = [
|
|
45
|
-
|
|
46
|
-
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
name:
|
|
50
|
-
|
|
51
|
-
"get_forum_info",
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
description:
|
|
56
|
-
|
|
57
|
-
"Get NodeBB forum information",
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
inputSchema:
|
|
62
|
-
|
|
63
4
|
{
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"object",
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
name:
|
|
85
|
-
|
|
86
|
-
"get_post",
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
description:
|
|
91
|
-
|
|
92
|
-
"Get NodeBB post by pid",
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
inputSchema:
|
|
97
|
-
|
|
5
|
+
name: "get_forum_info",
|
|
6
|
+
description: "Get public NodeBB forum information",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {},
|
|
10
|
+
additionalProperties: false
|
|
11
|
+
}
|
|
12
|
+
},
|
|
98
13
|
{
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
"object",
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
pid:
|
|
111
|
-
|
|
112
|
-
{
|
|
113
|
-
|
|
114
|
-
type:
|
|
115
|
-
|
|
116
|
-
"number"
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
},
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
required:
|
|
125
|
-
|
|
126
|
-
[
|
|
127
|
-
|
|
128
|
-
"pid"
|
|
129
|
-
|
|
130
|
-
]
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
},
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
{
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
name:
|
|
146
|
-
|
|
147
|
-
"get_topic",
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
description:
|
|
152
|
-
|
|
153
|
-
"Get NodeBB topic by tid",
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
inputSchema:
|
|
158
|
-
|
|
14
|
+
name: "get_post",
|
|
15
|
+
description: "Get a forum post by its post ID. Access permissions are checked by NodeBB.",
|
|
16
|
+
inputSchema: {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
pid: { type: "integer", minimum: 1 }
|
|
20
|
+
},
|
|
21
|
+
required: ["pid"],
|
|
22
|
+
additionalProperties: false
|
|
23
|
+
}
|
|
24
|
+
},
|
|
159
25
|
{
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
"object",
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
tid:
|
|
172
|
-
|
|
173
|
-
{
|
|
174
|
-
|
|
175
|
-
type:
|
|
176
|
-
|
|
177
|
-
"number"
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
required:
|
|
186
|
-
|
|
187
|
-
[
|
|
188
|
-
|
|
189
|
-
"tid"
|
|
190
|
-
|
|
191
|
-
]
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
},
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
{
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
name:
|
|
207
|
-
|
|
208
|
-
"get_user",
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
description:
|
|
213
|
-
|
|
214
|
-
"Get NodeBB user by uid",
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
inputSchema:
|
|
219
|
-
|
|
26
|
+
name: "get_topic",
|
|
27
|
+
description: "Get a forum topic by its topic ID. Access permissions are checked by NodeBB.",
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: "object",
|
|
30
|
+
properties: {
|
|
31
|
+
tid: { type: "integer", minimum: 1 }
|
|
32
|
+
},
|
|
33
|
+
required: ["tid"],
|
|
34
|
+
additionalProperties: false
|
|
35
|
+
}
|
|
36
|
+
},
|
|
220
37
|
{
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
"object",
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
uid:
|
|
233
|
-
|
|
234
|
-
{
|
|
235
|
-
|
|
236
|
-
type:
|
|
237
|
-
|
|
238
|
-
"number"
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
},
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
required:
|
|
247
|
-
|
|
248
|
-
[
|
|
249
|
-
|
|
250
|
-
"uid"
|
|
251
|
-
|
|
252
|
-
]
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
},
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
{
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
name:
|
|
268
|
-
|
|
269
|
-
"search_knowledge",
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
description:
|
|
274
|
-
|
|
275
|
-
"Semantic search in forum knowledge base",
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
inputSchema:
|
|
280
|
-
|
|
38
|
+
name: "get_user",
|
|
39
|
+
description: "Get public profile information for a forum user",
|
|
40
|
+
inputSchema: {
|
|
41
|
+
type: "object",
|
|
42
|
+
properties: {
|
|
43
|
+
uid: { type: "integer", minimum: 1 }
|
|
44
|
+
},
|
|
45
|
+
required: ["uid"],
|
|
46
|
+
additionalProperties: false
|
|
47
|
+
}
|
|
48
|
+
},
|
|
281
49
|
{
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
"object",
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
{
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
query:
|
|
294
|
-
|
|
295
|
-
{
|
|
296
|
-
|
|
297
|
-
type:
|
|
298
|
-
|
|
299
|
-
"string"
|
|
300
|
-
|
|
50
|
+
name: "search_knowledge",
|
|
51
|
+
description: "Search the forum knowledge base using semantic search",
|
|
52
|
+
inputSchema: {
|
|
53
|
+
type: "object",
|
|
54
|
+
properties: {
|
|
55
|
+
query: { type: "string", minLength: 1, maxLength: 2000 },
|
|
56
|
+
limit: { type: "integer", minimum: 1, maximum: 20 }
|
|
301
57
|
},
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
{
|
|
307
|
-
|
|
308
|
-
type:
|
|
309
|
-
|
|
310
|
-
"number"
|
|
311
|
-
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
},
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
required:
|
|
319
|
-
|
|
320
|
-
[
|
|
321
|
-
|
|
322
|
-
"query"
|
|
323
|
-
|
|
324
|
-
]
|
|
325
|
-
|
|
58
|
+
required: ["query"],
|
|
59
|
+
additionalProperties: false
|
|
60
|
+
}
|
|
326
61
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
62
|
];
|
|
336
63
|
|
|
64
|
+
function validateArguments(name, args) {
|
|
65
|
+
if (!args || typeof args !== "object" || Array.isArray(args)) {
|
|
66
|
+
throw new Error("Tool arguments must be an object");
|
|
67
|
+
}
|
|
337
68
|
|
|
69
|
+
const allowed = {
|
|
70
|
+
get_forum_info: [],
|
|
71
|
+
get_post: ["pid"],
|
|
72
|
+
get_topic: ["tid"],
|
|
73
|
+
get_user: ["uid"],
|
|
74
|
+
search_knowledge: ["query", "limit"]
|
|
75
|
+
}[name];
|
|
338
76
|
|
|
77
|
+
if (!allowed) {
|
|
78
|
+
throw new Error(`Unknown MCP tool: ${name}`);
|
|
79
|
+
}
|
|
339
80
|
|
|
81
|
+
if (Object.keys(args).some((key) => !allowed.includes(key))) {
|
|
82
|
+
throw new Error("Unexpected tool argument");
|
|
83
|
+
}
|
|
340
84
|
|
|
85
|
+
if (name === "get_forum_info") {
|
|
86
|
+
return {};
|
|
87
|
+
}
|
|
341
88
|
|
|
89
|
+
if (name === "get_post" || name === "get_topic" || name === "get_user") {
|
|
90
|
+
const key = name === "get_post"
|
|
91
|
+
? "pid"
|
|
92
|
+
: name === "get_topic"
|
|
93
|
+
? "tid"
|
|
94
|
+
: "uid";
|
|
342
95
|
|
|
96
|
+
if (!Number.isSafeInteger(args[key]) || args[key] < 1) {
|
|
97
|
+
throw new Error(`Invalid ${key}`);
|
|
98
|
+
}
|
|
343
99
|
|
|
100
|
+
return { [key]: args[key] };
|
|
101
|
+
}
|
|
344
102
|
|
|
103
|
+
if (
|
|
104
|
+
typeof args.query !== "string" ||
|
|
105
|
+
!args.query.trim() ||
|
|
106
|
+
args.query.length > 2000
|
|
107
|
+
) {
|
|
108
|
+
throw new Error("Search query must contain 1 to 2000 characters");
|
|
109
|
+
}
|
|
345
110
|
|
|
111
|
+
const limit = args.limit === undefined ? 5 : args.limit;
|
|
346
112
|
|
|
113
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 20) {
|
|
114
|
+
throw new Error("Search limit must be an integer from 1 to 20");
|
|
115
|
+
}
|
|
347
116
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
args = {}
|
|
354
|
-
|
|
355
|
-
) {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
switch(name) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
case "get_forum_info":
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
return Meta.getInfo();
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
case "get_post":
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
return Posts.getPost(
|
|
381
|
-
|
|
382
|
-
args.pid
|
|
383
|
-
|
|
384
|
-
);
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
case "get_topic":
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
return Topics.getTopic(
|
|
397
|
-
|
|
398
|
-
args.tid
|
|
399
|
-
|
|
400
|
-
);
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
case "get_user":
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
return Users.getUser(
|
|
413
|
-
|
|
414
|
-
args.uid
|
|
415
|
-
|
|
416
|
-
);
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
case "search_knowledge":
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
return Search.searchText(
|
|
429
|
-
|
|
430
|
-
args.query,
|
|
431
|
-
|
|
432
|
-
args.limit || 5
|
|
433
|
-
|
|
434
|
-
);
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
default:
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
throw new Error(
|
|
447
|
-
|
|
448
|
-
`Unknown MCP tool: ${name}`
|
|
449
|
-
|
|
450
|
-
);
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
function register(server) {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
/*
|
|
479
|
-
* MCP SDK 1.x compatibility
|
|
480
|
-
*/
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
if(
|
|
484
|
-
|
|
485
|
-
typeof server.setRequestHandler !== "function"
|
|
486
|
-
|
|
487
|
-
) {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
throw new Error(
|
|
492
|
-
|
|
493
|
-
"Invalid MCP server instance"
|
|
494
|
-
|
|
495
|
-
);
|
|
496
|
-
|
|
497
|
-
|
|
117
|
+
return {
|
|
118
|
+
query: args.query.trim(),
|
|
119
|
+
limit
|
|
120
|
+
};
|
|
498
121
|
}
|
|
499
122
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
server.setRequestHandler(
|
|
508
|
-
|
|
509
|
-
{
|
|
510
|
-
|
|
511
|
-
method:
|
|
512
|
-
|
|
513
|
-
"tools/list"
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
},
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
async () => ({
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
tools:
|
|
523
|
-
|
|
524
|
-
definitions
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
})
|
|
528
|
-
|
|
529
|
-
);
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
server.setRequestHandler(
|
|
539
|
-
|
|
540
|
-
{
|
|
541
|
-
|
|
542
|
-
method:
|
|
543
|
-
|
|
544
|
-
"tools/call"
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
},
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
async request => {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
const result =
|
|
555
|
-
|
|
556
|
-
await execute(
|
|
557
|
-
|
|
558
|
-
request.params.name,
|
|
559
|
-
|
|
560
|
-
request.params.arguments || {}
|
|
561
|
-
|
|
562
|
-
);
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
return {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
content:
|
|
574
|
-
|
|
575
|
-
[
|
|
576
|
-
|
|
577
|
-
{
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
type:
|
|
581
|
-
|
|
582
|
-
"text",
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
text:
|
|
587
|
-
|
|
588
|
-
JSON.stringify(
|
|
589
|
-
|
|
590
|
-
result,
|
|
591
|
-
|
|
592
|
-
null,
|
|
593
|
-
|
|
594
|
-
2
|
|
595
|
-
|
|
596
|
-
)
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
]
|
|
602
|
-
|
|
603
|
-
};
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
123
|
+
async function execute(name, args = {}, api) {
|
|
124
|
+
if (!api || typeof api.request !== "function") {
|
|
125
|
+
throw new Error("NodeBB API client is not configured");
|
|
607
126
|
}
|
|
608
127
|
|
|
609
|
-
);
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
128
|
+
const validated = validateArguments(name, args);
|
|
613
129
|
|
|
130
|
+
switch (name) {
|
|
131
|
+
case "get_forum_info":
|
|
132
|
+
return api.request("GET", "/api/v3/integration/internal/info");
|
|
614
133
|
|
|
134
|
+
case "get_post":
|
|
135
|
+
return api.request("POST", "/api/v3/integration/internal/post", validated);
|
|
615
136
|
|
|
137
|
+
case "get_topic":
|
|
138
|
+
return api.request("POST", "/api/v3/integration/internal/topic", validated);
|
|
616
139
|
|
|
140
|
+
case "get_user":
|
|
141
|
+
return api.request("POST", "/api/v3/integration/internal/user", validated);
|
|
617
142
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
"[MCP] tools registered"
|
|
621
|
-
|
|
622
|
-
);
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
143
|
+
case "search_knowledge":
|
|
144
|
+
return api.request("POST", "/api/v3/integration/internal/search", validated);
|
|
626
145
|
|
|
146
|
+
default:
|
|
147
|
+
throw new Error(`Unknown MCP tool: ${name}`);
|
|
148
|
+
}
|
|
627
149
|
}
|
|
628
150
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
151
|
+
function register(server, api) {
|
|
152
|
+
const {
|
|
153
|
+
ListToolsRequestSchema,
|
|
154
|
+
CallToolRequestSchema
|
|
155
|
+
} = require("@modelcontextprotocol/sdk/types.js");
|
|
156
|
+
|
|
157
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
158
|
+
tools: definitions
|
|
159
|
+
}));
|
|
160
|
+
|
|
161
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
162
|
+
const name = request.params.name;
|
|
163
|
+
const args = request.params.arguments || {};
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
const result = await execute(name, args, api);
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
content: [
|
|
170
|
+
{
|
|
171
|
+
type: "text",
|
|
172
|
+
text: JSON.stringify(result, null, 2)
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
};
|
|
176
|
+
} catch (error) {
|
|
177
|
+
return {
|
|
178
|
+
isError: true,
|
|
179
|
+
content: [
|
|
180
|
+
{
|
|
181
|
+
type: "text",
|
|
182
|
+
text: error.message || "Tool execution failed"
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
640
189
|
|
|
641
190
|
module.exports = {
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
definitions
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
};
|
|
191
|
+
definitions,
|
|
192
|
+
validateArguments,
|
|
193
|
+
execute,
|
|
194
|
+
register
|
|
195
|
+
};
|