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.
Files changed (2) hide show
  1. package/index.js +96 -19
  2. 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.2
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
- * Возвращает { elements, warnings }
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
- // НЕ копируем: x, y, width, height они автоматические
398
- if (el.x !== undefined || el.y !== undefined || el.width !== undefined || el.height !== undefined) {
399
- warnings.push(`Элемент ${index + 1}: x/y/width/height удалены (рассчитываются автоматически)`);
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
- return { elements: normalized, warnings };
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
- НЕ указывай x, y, width, height - рассчитываются автоматически!
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: prepareConnections(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, НЕ указывай x/y/width/height`;
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
- newData.connections = prepareConnections(connections);
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, НЕ указывай x/y/width/height`;
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.3 запущен");
1548
+ console.error("SchemeOG MCP Server v2.4 запущен");
1472
1549
  }
1473
1550
 
1474
1551
  main().catch(console.error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "schemeog-mcp",
3
- "version": "2.3.0",
3
+ "version": "2.5.0",
4
4
  "description": "MCP Server for SchemeOG Cloud - Create and manage visual diagrams and flowcharts with AI assistance",
5
5
  "type": "module",
6
6
  "main": "index.js",