schemeog-mcp 2.3.0 → 2.5.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/index.js +96 -19
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* SchemeOG MCP Server v2.
|
|
4
|
+
* SchemeOG MCP Server v2.4
|
|
5
5
|
*
|
|
6
6
|
* MCP сервер для работы со схемами, проектами и тегами в SchemeOG Cloud.
|
|
7
7
|
*
|
|
@@ -331,13 +331,18 @@ function hexToNamedColor(hex) {
|
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
/**
|
|
334
|
-
* Нормализовать элементы — исправить типы, цвета,
|
|
335
|
-
*
|
|
334
|
+
* Нормализовать элементы — исправить типы, цвета, извлечь connections
|
|
335
|
+
* ВАЖНО: Поддерживает ОБА формата:
|
|
336
|
+
* 1. Локальный формат (connections внутри элементов)
|
|
337
|
+
* 2. Cloud формат (connections отдельным массивом)
|
|
338
|
+
*
|
|
339
|
+
* Возвращает { elements, extractedConnections, warnings }
|
|
336
340
|
*/
|
|
337
341
|
function normalizeElements(elements) {
|
|
338
|
-
if (!elements || !Array.isArray(elements)) return { elements: [], warnings: [] };
|
|
342
|
+
if (!elements || !Array.isArray(elements)) return { elements: [], extractedConnections: [], warnings: [] };
|
|
339
343
|
|
|
340
344
|
const warnings = [];
|
|
345
|
+
const extractedConnections = [];
|
|
341
346
|
|
|
342
347
|
const normalized = elements.map((el, index) => {
|
|
343
348
|
const fixed = {
|
|
@@ -394,20 +399,48 @@ function normalizeElements(elements) {
|
|
|
394
399
|
fixed.tags = el.tags;
|
|
395
400
|
}
|
|
396
401
|
|
|
397
|
-
//
|
|
398
|
-
if (el.x
|
|
399
|
-
|
|
402
|
+
// Координаты x, y — СОХРАНЯЕМ! (нужны для правильного отображения)
|
|
403
|
+
if (typeof el.x === "number") {
|
|
404
|
+
fixed.x = el.x;
|
|
405
|
+
}
|
|
406
|
+
if (typeof el.y === "number") {
|
|
407
|
+
fixed.y = el.y;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// КРИТИЧНО: Извлекаем connections из элемента (локальный формат)
|
|
411
|
+
// и конвертируем в формат сервера {from, to, label}
|
|
412
|
+
if (el.connections && Array.isArray(el.connections)) {
|
|
413
|
+
el.connections.forEach(conn => {
|
|
414
|
+
// Поддерживаем разные форматы connection:
|
|
415
|
+
// { to: "id" } или { to: "id", label: "text" } или полный { from, to, label }
|
|
416
|
+
const normalizedConn = {
|
|
417
|
+
id: conn.id || generateId(),
|
|
418
|
+
from: conn.from || el.id || fixed.id,
|
|
419
|
+
to: conn.to,
|
|
420
|
+
};
|
|
421
|
+
if (conn.label) {
|
|
422
|
+
normalizedConn.label = conn.label;
|
|
423
|
+
}
|
|
424
|
+
if (conn.style) {
|
|
425
|
+
normalizedConn.style = conn.style;
|
|
426
|
+
}
|
|
427
|
+
extractedConnections.push(normalizedConn);
|
|
428
|
+
});
|
|
400
429
|
}
|
|
401
430
|
|
|
402
431
|
return fixed;
|
|
403
432
|
});
|
|
404
433
|
|
|
405
|
-
|
|
434
|
+
if (extractedConnections.length > 0) {
|
|
435
|
+
warnings.push(`Извлечено ${extractedConnections.length} связей из элементов (локальный формат → cloud формат)`);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
return { elements: normalized, extractedConnections, warnings };
|
|
406
439
|
}
|
|
407
440
|
|
|
408
441
|
/**
|
|
409
442
|
* Подготовить элементы — нормализовать и добавить ID
|
|
410
|
-
* Возвращает { elements, warnings }
|
|
443
|
+
* Возвращает { elements, extractedConnections, warnings }
|
|
411
444
|
*/
|
|
412
445
|
function prepareElements(elements) {
|
|
413
446
|
return normalizeElements(elements);
|
|
@@ -498,12 +531,32 @@ const TOOLS = [
|
|
|
498
531
|
"color": "light_blue", // цвет фона: white, light_blue, light_green, light_yellow, light_orange, light_red, light_purple, light_gray, light_pink, light_teal
|
|
499
532
|
"borderColor": "blue", // цвет обводки: default, blue, green, orange, purple, red, teal, yellow, gray, black
|
|
500
533
|
"tags": ["тег1"], // массив названий тегов (опционально)
|
|
501
|
-
"description": "Описание процесса" // подробное описание (опционально)
|
|
534
|
+
"description": "Описание процесса", // подробное описание (опционально)
|
|
535
|
+
"x": 100, // координата X (опционально, сохраняется если указана)
|
|
536
|
+
"y": 200, // координата Y (опционально, сохраняется если указана)
|
|
537
|
+
"connections": [{"to": "id2"}] // АЛЬТЕРНАТИВА: связи внутри элемента (локальный формат)
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
КООРДИНАТЫ x/y: Можно указывать для сохранения позиции. Если не указаны — рассчитываются автоматически.
|
|
541
|
+
|
|
542
|
+
ДВА ФОРМАТА СВЯЗЕЙ (оба поддерживаются):
|
|
543
|
+
|
|
544
|
+
1. Облачный формат — connections отдельным массивом:
|
|
545
|
+
{
|
|
546
|
+
"elements": [...],
|
|
547
|
+
"connections": [{"from": "id1", "to": "id2"}]
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
2. Локальный формат — connections внутри каждого элемента:
|
|
551
|
+
{
|
|
552
|
+
"elements": [
|
|
553
|
+
{"id": "id1", "title": "Card", "connections": [{"to": "id2"}]}
|
|
554
|
+
]
|
|
502
555
|
}
|
|
503
556
|
|
|
504
|
-
|
|
557
|
+
MCP автоматически извлекает связи из элементов и объединяет с массивом connections!
|
|
505
558
|
|
|
506
|
-
Формат
|
|
559
|
+
Формат связи (облачный):
|
|
507
560
|
{
|
|
508
561
|
"from": "source_id", // ID элемента-источника
|
|
509
562
|
"to": "target_id", // ID элемента-назначения
|
|
@@ -511,6 +564,12 @@ const TOOLS = [
|
|
|
511
564
|
"style": "solid" // solid, dashed, dotted (опционально)
|
|
512
565
|
}
|
|
513
566
|
|
|
567
|
+
Формат связи (внутри элемента):
|
|
568
|
+
{
|
|
569
|
+
"to": "target_id", // ID элемента-назначения (from берётся из родительского элемента)
|
|
570
|
+
"label": "подпись" // текст на связи (опционально)
|
|
571
|
+
}
|
|
572
|
+
|
|
514
573
|
Формат тега (tagsDictionary):
|
|
515
574
|
{
|
|
516
575
|
"id": "tag-1", // уникальный ID тега
|
|
@@ -1040,12 +1099,18 @@ ${JSON.stringify(schema.data?.connections || [], null, 2)}`,
|
|
|
1040
1099
|
case "create_schema": {
|
|
1041
1100
|
const { name, description, project_id, elements, connections, tagsDictionary } = args;
|
|
1042
1101
|
|
|
1043
|
-
// Нормализуем элементы и
|
|
1044
|
-
const { elements: normalizedElements, warnings } = prepareElements(elements);
|
|
1102
|
+
// Нормализуем элементы и извлекаем connections (поддержка локального формата)
|
|
1103
|
+
const { elements: normalizedElements, extractedConnections, warnings } = prepareElements(elements);
|
|
1104
|
+
|
|
1105
|
+
// Объединяем: connections из параметров + извлечённые из элементов
|
|
1106
|
+
const allConnections = [
|
|
1107
|
+
...prepareConnections(connections),
|
|
1108
|
+
...extractedConnections,
|
|
1109
|
+
];
|
|
1045
1110
|
|
|
1046
1111
|
const data = {
|
|
1047
1112
|
elements: normalizedElements,
|
|
1048
|
-
connections:
|
|
1113
|
+
connections: allConnections,
|
|
1049
1114
|
tagsDictionary: tagsDictionary || [],
|
|
1050
1115
|
};
|
|
1051
1116
|
|
|
@@ -1063,7 +1128,7 @@ ${JSON.stringify(schema.data?.connections || [], null, 2)}`,
|
|
|
1063
1128
|
if (warnings.length > 10) {
|
|
1064
1129
|
warningsText += `\n• ...и ещё ${warnings.length - 10}`;
|
|
1065
1130
|
}
|
|
1066
|
-
warningsText += `\n\n💡 Подсказка: используй type "card"/"condition", цвета light_blue/light_green/etc
|
|
1131
|
+
warningsText += `\n\n💡 Подсказка: используй type "card"/"condition", цвета light_blue/light_green/etc`;
|
|
1067
1132
|
}
|
|
1068
1133
|
|
|
1069
1134
|
return {
|
|
@@ -1100,13 +1165,25 @@ URL: ${API_BASE_URL}/canvas?id=${result.schema.id}
|
|
|
1100
1165
|
|
|
1101
1166
|
// Обновляем данные только если переданы
|
|
1102
1167
|
const newData = { ...currentData };
|
|
1168
|
+
let extractedConnections = [];
|
|
1103
1169
|
if (elements !== undefined) {
|
|
1104
1170
|
const normalized = prepareElements(elements);
|
|
1105
1171
|
newData.elements = normalized.elements;
|
|
1172
|
+
extractedConnections = normalized.extractedConnections;
|
|
1106
1173
|
warnings = normalized.warnings;
|
|
1107
1174
|
}
|
|
1108
1175
|
if (connections !== undefined) {
|
|
1109
|
-
|
|
1176
|
+
// Объединяем переданные connections + извлечённые из элементов
|
|
1177
|
+
newData.connections = [
|
|
1178
|
+
...prepareConnections(connections),
|
|
1179
|
+
...extractedConnections,
|
|
1180
|
+
];
|
|
1181
|
+
} else if (extractedConnections.length > 0) {
|
|
1182
|
+
// Если connections не переданы, но есть извлечённые — добавляем их к существующим
|
|
1183
|
+
newData.connections = [
|
|
1184
|
+
...(currentData.connections || []),
|
|
1185
|
+
...extractedConnections,
|
|
1186
|
+
];
|
|
1110
1187
|
}
|
|
1111
1188
|
updateBody.data = newData;
|
|
1112
1189
|
|
|
@@ -1122,7 +1199,7 @@ URL: ${API_BASE_URL}/canvas?id=${result.schema.id}
|
|
|
1122
1199
|
if (warnings.length > 10) {
|
|
1123
1200
|
warningsText += `\n• ...и ещё ${warnings.length - 10}`;
|
|
1124
1201
|
}
|
|
1125
|
-
warningsText += `\n\n💡 Подсказка: используй type "card"/"condition", цвета light_blue/light_green/etc
|
|
1202
|
+
warningsText += `\n\n💡 Подсказка: используй type "card"/"condition", цвета light_blue/light_green/etc`;
|
|
1126
1203
|
}
|
|
1127
1204
|
|
|
1128
1205
|
return {
|
|
@@ -1468,7 +1545,7 @@ async function main() {
|
|
|
1468
1545
|
const transport = new StdioServerTransport();
|
|
1469
1546
|
await server.connect(transport);
|
|
1470
1547
|
|
|
1471
|
-
console.error("SchemeOG MCP Server v2.
|
|
1548
|
+
console.error("SchemeOG MCP Server v2.4 запущен");
|
|
1472
1549
|
}
|
|
1473
1550
|
|
|
1474
1551
|
main().catch(console.error);
|