schemeog-mcp 2.5.1 → 2.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/index.js +145 -99
- 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.6
|
|
5
5
|
*
|
|
6
6
|
* MCP сервер для работы со схемами, проектами и тегами в SchemeOG Cloud.
|
|
7
7
|
*
|
|
@@ -482,8 +482,7 @@ const TOOLS = [
|
|
|
482
482
|
Возвращает:
|
|
483
483
|
- name: название схемы
|
|
484
484
|
- description: описание
|
|
485
|
-
- elements: массив элементов (card или condition)
|
|
486
|
-
- connections: массив связей между элементами
|
|
485
|
+
- elements: массив элементов (card или condition) со связями внутри
|
|
487
486
|
- tagsDictionary: справочник тегов
|
|
488
487
|
|
|
489
488
|
Формат элемента:
|
|
@@ -492,12 +491,15 @@ const TOOLS = [
|
|
|
492
491
|
"type": "card", // card или condition
|
|
493
492
|
"title": "Название", // заголовок
|
|
494
493
|
"color": "light_blue", // ТОЛЬКО: white, light_blue, light_green, light_yellow, light_orange, light_red, light_purple, light_gray, light_pink, light_teal
|
|
494
|
+
"borderColor": "blue", // default, blue, green, orange, purple, red, teal, yellow, gray, black
|
|
495
495
|
"description": "Текст", // описание
|
|
496
|
-
"tags": ["тег1"]
|
|
496
|
+
"tags": ["тег1"], // массив тегов
|
|
497
|
+
"connections": [{"to": "target_id", "label": "подпись"}] // исходящие связи
|
|
497
498
|
}
|
|
498
499
|
|
|
499
500
|
ВАЖНО: НЕ используй x, y, width, height — они рассчитываются автоматически!
|
|
500
|
-
ВАЖНО: Цвета ТОЛЬКО именованные (light_blue), НЕ HEX (#FFFFFF)
|
|
501
|
+
ВАЖНО: Цвета ТОЛЬКО именованные (light_blue), НЕ HEX (#FFFFFF)!
|
|
502
|
+
ВАЖНО: Связи указываются ВНУТРИ элементов в поле "connections"!`,
|
|
501
503
|
inputSchema: {
|
|
502
504
|
type: "object",
|
|
503
505
|
properties: {
|
|
@@ -509,18 +511,42 @@ const TOOLS = [
|
|
|
509
511
|
required: ["schema_id"],
|
|
510
512
|
},
|
|
511
513
|
},
|
|
514
|
+
{
|
|
515
|
+
name: "get_schema_by_url",
|
|
516
|
+
description: `Получить схему по URL ссылке.
|
|
517
|
+
|
|
518
|
+
Поддерживаемые форматы URL:
|
|
519
|
+
- https://scheme.smartlaunchhub.com/canvas?schema=ID
|
|
520
|
+
- https://scheme.smartlaunchhub.com/canvas?id=ID
|
|
521
|
+
- scheme.smartlaunchhub.com/canvas?schema=ID
|
|
522
|
+
|
|
523
|
+
Автоматически извлекает ID схемы из URL и проверяет доступ.
|
|
524
|
+
Если у пользователя есть доступ к схеме — возвращает полные данные.
|
|
525
|
+
Если доступа нет — возвращает ошибку.
|
|
526
|
+
|
|
527
|
+
Используй эту команду когда пользователь скидывает ссылку на схему.`,
|
|
528
|
+
inputSchema: {
|
|
529
|
+
type: "object",
|
|
530
|
+
properties: {
|
|
531
|
+
url: {
|
|
532
|
+
type: "string",
|
|
533
|
+
description: "URL ссылка на схему (например https://scheme.smartlaunchhub.com/canvas?schema=xxx)",
|
|
534
|
+
},
|
|
535
|
+
},
|
|
536
|
+
required: ["url"],
|
|
537
|
+
},
|
|
538
|
+
},
|
|
512
539
|
{
|
|
513
540
|
name: "create_schema",
|
|
514
541
|
description: `Создать новую схему с элементами и связями.
|
|
515
542
|
|
|
516
|
-
ВАЖНО: Генерируй
|
|
543
|
+
ВАЖНО: Генерируй схему с elements и tagsDictionary. Связи указывай ВНУТРИ элементов!
|
|
517
544
|
|
|
518
545
|
Параметры:
|
|
519
546
|
- name: название схемы (обязательно)
|
|
520
547
|
- description: описание
|
|
521
548
|
- project_id: ID проекта (опционально)
|
|
522
|
-
- elements: массив элементов
|
|
523
|
-
- connections: массив связей
|
|
549
|
+
- elements: массив элементов (со связями внутри)
|
|
524
550
|
- tagsDictionary: справочник тегов (опционально)
|
|
525
551
|
|
|
526
552
|
Формат элемента:
|
|
@@ -531,42 +557,13 @@ const TOOLS = [
|
|
|
531
557
|
"color": "light_blue", // цвет фона: white, light_blue, light_green, light_yellow, light_orange, light_red, light_purple, light_gray, light_pink, light_teal
|
|
532
558
|
"borderColor": "blue", // цвет обводки: default, blue, green, orange, purple, red, teal, yellow, gray, black
|
|
533
559
|
"tags": ["тег1"], // массив названий тегов (опционально)
|
|
534
|
-
"description": "Описание
|
|
535
|
-
"
|
|
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"}]
|
|
560
|
+
"description": "Описание", // подробное описание (опционально)
|
|
561
|
+
"connections": [{"to": "target_id", "label": "подпись"}] // ИСХОДЯЩИЕ СВЯЗИ (опционально)
|
|
548
562
|
}
|
|
549
563
|
|
|
550
|
-
|
|
564
|
+
СВЯЗИ (inline формат — внутри элемента):
|
|
551
565
|
{
|
|
552
|
-
"elements": [
|
|
553
|
-
{"id": "id1", "title": "Card", "connections": [{"to": "id2"}]}
|
|
554
|
-
]
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
MCP автоматически извлекает связи из элементов и объединяет с массивом connections!
|
|
558
|
-
|
|
559
|
-
Формат связи (облачный):
|
|
560
|
-
{
|
|
561
|
-
"from": "source_id", // ID элемента-источника
|
|
562
566
|
"to": "target_id", // ID элемента-назначения
|
|
563
|
-
"label": "подпись", // текст на связи (опционально)
|
|
564
|
-
"style": "solid" // solid, dashed, dotted (опционально)
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
Формат связи (внутри элемента):
|
|
568
|
-
{
|
|
569
|
-
"to": "target_id", // ID элемента-назначения (from берётся из родительского элемента)
|
|
570
567
|
"label": "подпись" // текст на связи (опционально)
|
|
571
568
|
}
|
|
572
569
|
|
|
@@ -581,18 +578,12 @@ MCP автоматически извлекает связи из элемент
|
|
|
581
578
|
{
|
|
582
579
|
"name": "User Registration",
|
|
583
580
|
"elements": [
|
|
584
|
-
{"id": "start", "type": "card", "title": "Форма регистрации", "color": "light_green", "tags": ["пользователь"]},
|
|
585
|
-
{"id": "validate", "type": "condition", "title": "Валидация", "color": "light_yellow", "tags": ["система"]},
|
|
586
|
-
{"id": "save", "type": "card", "title": "Сохранение в БД", "color": "light_blue", "tags": ["система"]},
|
|
581
|
+
{"id": "start", "type": "card", "title": "Форма регистрации", "color": "light_green", "tags": ["пользователь"], "connections": [{"to": "validate"}]},
|
|
582
|
+
{"id": "validate", "type": "condition", "title": "Валидация", "color": "light_yellow", "tags": ["система"], "connections": [{"to": "save", "label": "OK"}, {"to": "error", "label": "ошибка"}]},
|
|
583
|
+
{"id": "save", "type": "card", "title": "Сохранение в БД", "color": "light_blue", "tags": ["система"], "connections": [{"to": "success"}]},
|
|
587
584
|
{"id": "error", "type": "card", "title": "Ошибка", "color": "light_red", "tags": ["система"]},
|
|
588
585
|
{"id": "success", "type": "card", "title": "Успех", "color": "light_green", "tags": ["пользователь"]}
|
|
589
586
|
],
|
|
590
|
-
"connections": [
|
|
591
|
-
{"from": "start", "to": "validate"},
|
|
592
|
-
{"from": "validate", "to": "save", "label": "OK"},
|
|
593
|
-
{"from": "validate", "to": "error", "label": "ошибка"},
|
|
594
|
-
{"from": "save", "to": "success"}
|
|
595
|
-
],
|
|
596
587
|
"tagsDictionary": [
|
|
597
588
|
{"id": "tag-user", "name": "пользователь", "color": "#4CAF50"},
|
|
598
589
|
{"id": "tag-system", "name": "система", "color": "#2196F3"}
|
|
@@ -629,20 +620,6 @@ MCP автоматически извлекает связи из элемент
|
|
|
629
620
|
},
|
|
630
621
|
},
|
|
631
622
|
},
|
|
632
|
-
connections: {
|
|
633
|
-
type: "array",
|
|
634
|
-
description: "Массив связей между элементами",
|
|
635
|
-
items: {
|
|
636
|
-
type: "object",
|
|
637
|
-
properties: {
|
|
638
|
-
from: { type: "string" },
|
|
639
|
-
to: { type: "string" },
|
|
640
|
-
label: { type: "string" },
|
|
641
|
-
style: { type: "string", enum: ["solid", "dashed", "dotted"] },
|
|
642
|
-
},
|
|
643
|
-
required: ["from", "to"],
|
|
644
|
-
},
|
|
645
|
-
},
|
|
646
623
|
tagsDictionary: {
|
|
647
624
|
type: "array",
|
|
648
625
|
description: "Справочник тегов схемы",
|
|
@@ -676,10 +653,21 @@ MCP автоматически извлекает связи из элемент
|
|
|
676
653
|
- schema_id: ID схемы (обязательно)
|
|
677
654
|
- name: новое название (опционально)
|
|
678
655
|
- description: новое описание (опционально)
|
|
679
|
-
- elements: новый массив элементов (опционально)
|
|
680
|
-
|
|
656
|
+
- elements: новый массив элементов со связями внутри (опционально)
|
|
657
|
+
|
|
658
|
+
Формат элемента (такой же как в create_schema):
|
|
659
|
+
{
|
|
660
|
+
"id": "unique_id",
|
|
661
|
+
"type": "card", // card или condition
|
|
662
|
+
"title": "Название",
|
|
663
|
+
"color": "light_blue", // white, light_blue, light_green, light_yellow, light_orange, light_red, light_purple, light_gray, light_pink, light_teal
|
|
664
|
+
"borderColor": "blue", // default, blue, green, orange, purple, red, teal, yellow, gray, black
|
|
665
|
+
"tags": ["тег1"],
|
|
666
|
+
"description": "Описание",
|
|
667
|
+
"connections": [{"to": "target_id", "label": "подпись"}] // ИСХОДЯЩИЕ СВЯЗИ внутри элемента
|
|
668
|
+
}
|
|
681
669
|
|
|
682
|
-
Если elements
|
|
670
|
+
Если elements не указаны - они останутся прежними.`,
|
|
683
671
|
inputSchema: {
|
|
684
672
|
type: "object",
|
|
685
673
|
properties: {
|
|
@@ -697,12 +685,7 @@ MCP автоматически извлекает связи из элемент
|
|
|
697
685
|
},
|
|
698
686
|
elements: {
|
|
699
687
|
type: "array",
|
|
700
|
-
description: "Новый массив элементов (заменяет все существующие)",
|
|
701
|
-
items: { type: "object" },
|
|
702
|
-
},
|
|
703
|
-
connections: {
|
|
704
|
-
type: "array",
|
|
705
|
-
description: "Новый массив связей (заменяет все существующие)",
|
|
688
|
+
description: "Новый массив элементов со связями внутри (заменяет все существующие)",
|
|
706
689
|
items: { type: "object" },
|
|
707
690
|
},
|
|
708
691
|
},
|
|
@@ -953,6 +936,42 @@ MCP автоматически извлекает связи из элемент
|
|
|
953
936
|
},
|
|
954
937
|
];
|
|
955
938
|
|
|
939
|
+
/**
|
|
940
|
+
* Извлечь ID схемы из URL
|
|
941
|
+
* Поддерживает форматы:
|
|
942
|
+
* - https://scheme.smartlaunchhub.com/canvas?schema=ID
|
|
943
|
+
* - https://scheme.smartlaunchhub.com/canvas?id=ID
|
|
944
|
+
* - scheme.smartlaunchhub.com/canvas?schema=ID
|
|
945
|
+
*/
|
|
946
|
+
function extractSchemaIdFromUrl(url) {
|
|
947
|
+
if (!url || typeof url !== "string") return null;
|
|
948
|
+
|
|
949
|
+
try {
|
|
950
|
+
// Добавляем https:// если нет протокола
|
|
951
|
+
let normalizedUrl = url.trim();
|
|
952
|
+
if (!normalizedUrl.startsWith("http://") && !normalizedUrl.startsWith("https://")) {
|
|
953
|
+
normalizedUrl = "https://" + normalizedUrl;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
const urlObj = new URL(normalizedUrl);
|
|
957
|
+
|
|
958
|
+
// Проверяем что это наш домен
|
|
959
|
+
if (!urlObj.hostname.includes("scheme.smartlaunchhub.com") &&
|
|
960
|
+
!urlObj.hostname.includes("localhost")) {
|
|
961
|
+
return null;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
// Извлекаем ID из query параметров
|
|
965
|
+
const schemaId = urlObj.searchParams.get("schema") || urlObj.searchParams.get("id");
|
|
966
|
+
|
|
967
|
+
return schemaId || null;
|
|
968
|
+
} catch (e) {
|
|
969
|
+
// Пробуем простой regex для извлечения
|
|
970
|
+
const match = url.match(/[?&](schema|id)=([a-zA-Z0-9_-]+)/);
|
|
971
|
+
return match ? match[2] : null;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
956
975
|
/**
|
|
957
976
|
* Валидация UUID формата
|
|
958
977
|
*/
|
|
@@ -1096,21 +1115,61 @@ ${JSON.stringify(schema.data?.connections || [], null, 2)}`,
|
|
|
1096
1115
|
};
|
|
1097
1116
|
}
|
|
1098
1117
|
|
|
1118
|
+
case "get_schema_by_url": {
|
|
1119
|
+
const { url } = args;
|
|
1120
|
+
|
|
1121
|
+
// Извлекаем ID из URL
|
|
1122
|
+
const schemaId = extractSchemaIdFromUrl(url);
|
|
1123
|
+
|
|
1124
|
+
if (!schemaId) {
|
|
1125
|
+
const error = createError(
|
|
1126
|
+
ErrorCodes.VALIDATION_ERROR,
|
|
1127
|
+
`Не удалось извлечь ID схемы из URL: "${url}"\n\nПоддерживаемые форматы:\n• https://scheme.smartlaunchhub.com/canvas?schema=ID\n• https://scheme.smartlaunchhub.com/canvas?id=ID`
|
|
1128
|
+
);
|
|
1129
|
+
throw new Error(error.message);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// Получаем схему по ID (проверка доступа происходит на сервере)
|
|
1133
|
+
const result = await apiRequest(`/schemas/${schemaId}`);
|
|
1134
|
+
const schema = result.schema;
|
|
1135
|
+
|
|
1136
|
+
return {
|
|
1137
|
+
content: [{
|
|
1138
|
+
type: "text",
|
|
1139
|
+
text: `✅ Доступ к схеме получен!
|
|
1140
|
+
|
|
1141
|
+
Схема "${schema.name}"
|
|
1142
|
+
|
|
1143
|
+
ID: ${schema.id}
|
|
1144
|
+
Описание: ${schema.description || "(нет)"}
|
|
1145
|
+
Проект: ${schema.project?.name || "Общие"}
|
|
1146
|
+
Элементов: ${schema.data?.elements?.length || 0}
|
|
1147
|
+
Связей: ${schema.data?.connections?.length || 0}
|
|
1148
|
+
URL: ${API_BASE_URL}/canvas?schema=${schema.id}
|
|
1149
|
+
|
|
1150
|
+
Элементы:
|
|
1151
|
+
${JSON.stringify(schema.data?.elements || [], null, 2)}
|
|
1152
|
+
|
|
1153
|
+
Связи:
|
|
1154
|
+
${JSON.stringify(schema.data?.connections || [], null, 2)}
|
|
1155
|
+
|
|
1156
|
+
Теперь ты можешь:
|
|
1157
|
+
• Редактировать схему с помощью replace_schema (schema_id: "${schema.id}")
|
|
1158
|
+
• Удалить схему с помощью delete_schema
|
|
1159
|
+
• Работать с тегами через add_tag, remove_tag, tag_element`,
|
|
1160
|
+
}],
|
|
1161
|
+
};
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1099
1164
|
case "create_schema": {
|
|
1100
|
-
const { name, description, project_id, elements,
|
|
1165
|
+
const { name, description, project_id, elements, tagsDictionary } = args;
|
|
1101
1166
|
|
|
1102
|
-
// Нормализуем элементы и извлекаем connections (
|
|
1167
|
+
// Нормализуем элементы и извлекаем connections (inline формат)
|
|
1103
1168
|
const { elements: normalizedElements, extractedConnections, warnings } = prepareElements(elements);
|
|
1104
1169
|
|
|
1105
|
-
// Объединяем: connections из параметров + извлечённые из элементов
|
|
1106
|
-
const allConnections = [
|
|
1107
|
-
...prepareConnections(connections),
|
|
1108
|
-
...extractedConnections,
|
|
1109
|
-
];
|
|
1110
|
-
|
|
1111
1170
|
const data = {
|
|
1112
1171
|
elements: normalizedElements,
|
|
1113
|
-
connections:
|
|
1172
|
+
connections: extractedConnections,
|
|
1114
1173
|
tagsDictionary: tagsDictionary || [],
|
|
1115
1174
|
};
|
|
1116
1175
|
|
|
@@ -1149,7 +1208,7 @@ URL: ${API_BASE_URL}/canvas?id=${result.schema.id}
|
|
|
1149
1208
|
}
|
|
1150
1209
|
|
|
1151
1210
|
case "replace_schema": {
|
|
1152
|
-
const { schema_id, name, description, elements
|
|
1211
|
+
const { schema_id, name, description, elements } = args;
|
|
1153
1212
|
|
|
1154
1213
|
// Получаем текущую схему
|
|
1155
1214
|
const currentResult = await apiRequest(`/schemas/${schema_id}`);
|
|
@@ -1165,26 +1224,13 @@ URL: ${API_BASE_URL}/canvas?id=${result.schema.id}
|
|
|
1165
1224
|
|
|
1166
1225
|
// Обновляем данные только если переданы
|
|
1167
1226
|
const newData = { ...currentData };
|
|
1168
|
-
let extractedConnections = [];
|
|
1169
1227
|
if (elements !== undefined) {
|
|
1170
1228
|
const normalized = prepareElements(elements);
|
|
1171
1229
|
newData.elements = normalized.elements;
|
|
1172
|
-
|
|
1230
|
+
// Связи извлекаются из элементов (inline формат)
|
|
1231
|
+
newData.connections = normalized.extractedConnections;
|
|
1173
1232
|
warnings = normalized.warnings;
|
|
1174
1233
|
}
|
|
1175
|
-
if (connections !== undefined) {
|
|
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
|
-
];
|
|
1187
|
-
}
|
|
1188
1234
|
updateBody.data = newData;
|
|
1189
1235
|
|
|
1190
1236
|
const result = await apiRequest(`/schemas/${schema_id}`, {
|
|
@@ -1515,7 +1561,7 @@ async function main() {
|
|
|
1515
1561
|
const server = new Server(
|
|
1516
1562
|
{
|
|
1517
1563
|
name: "schemeog-mcp",
|
|
1518
|
-
version: "2.
|
|
1564
|
+
version: "2.6.0",
|
|
1519
1565
|
},
|
|
1520
1566
|
{
|
|
1521
1567
|
capabilities: {
|
|
@@ -1545,7 +1591,7 @@ async function main() {
|
|
|
1545
1591
|
const transport = new StdioServerTransport();
|
|
1546
1592
|
await server.connect(transport);
|
|
1547
1593
|
|
|
1548
|
-
console.error("SchemeOG MCP Server v2.
|
|
1594
|
+
console.error("SchemeOG MCP Server v2.6 запущен");
|
|
1549
1595
|
}
|
|
1550
1596
|
|
|
1551
1597
|
main().catch(console.error);
|