schemeog-mcp 2.8.2 → 2.9.1

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 (3) hide show
  1. package/README.md +94 -3
  2. package/index.js +425 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
- # SchemeOG MCP Server v2.8
1
+ # SchemeOG MCP Server v2.9
2
2
 
3
3
  MCP server for [SchemeOG Cloud](https://scheme.smartlaunchhub.com) — create diagrams and flowcharts with AI.
4
4
 
5
5
  ## Features
6
6
 
7
- - **15 commands** for schemas, projects, and tags
7
+ - **17 commands** for schemas, projects, tags, and import/export
8
8
  - **Auto-refresh**: Browser automatically reloads when MCP updates schema
9
9
  - **Smart positioning**: Existing elements keep their positions, new elements get auto-layout
10
10
  - **No coordinate conflicts**: MCP ignores x/y to prevent overlapping cards
11
11
 
12
- ## 15 Commands
12
+ ## 17 Commands
13
13
 
14
14
  ### Schemas (6 commands)
15
15
 
@@ -22,6 +22,13 @@ MCP server for [SchemeOG Cloud](https://scheme.smartlaunchhub.com) — create di
22
22
  | `replace_schema` | Replace schema content |
23
23
  | `delete_schema` | Delete schema |
24
24
 
25
+ ### Import/Export (2 commands)
26
+
27
+ | Command | Description |
28
+ |---------|-------------|
29
+ | `import_schema_from_json` | Import schema from JSON (multiple formats supported) |
30
+ | `export_schema_to_json` | Export schema to JSON file |
31
+
25
32
  ### Projects (5 commands)
26
33
 
27
34
  | Command | Description |
@@ -267,6 +274,90 @@ Schema = complete tree of **ACTIONS** and **CONSEQUENCES**:
267
274
  └── "Error" → "Show Errors" → "Fix Form"
268
275
  ```
269
276
 
277
+ ## Import/Export Formats
278
+
279
+ ### Export formats
280
+
281
+ Use `export_schema_to_json` with the `format` parameter:
282
+
283
+ | Format | Description |
284
+ |--------|-------------|
285
+ | `full` | Complete export with metadata, viewport, and all data |
286
+ | `compact` | Schema name + elements + tagsDictionary only |
287
+ | `elements_only` | Just the elements array |
288
+
289
+ ### Import formats
290
+
291
+ `import_schema_from_json` automatically detects and supports:
292
+
293
+ **1. Full SchemeOG export:**
294
+ ```json
295
+ {
296
+ "exportVersion": "1.0",
297
+ "schema": {
298
+ "name": "...",
299
+ "elements": [...],
300
+ "tagsDictionary": [...]
301
+ }
302
+ }
303
+ ```
304
+
305
+ **2. Simple format:**
306
+ ```json
307
+ {
308
+ "name": "...",
309
+ "elements": [...],
310
+ "connections": [...],
311
+ "tagsDictionary": [...]
312
+ }
313
+ ```
314
+
315
+ **3. Local format (connections inside elements):**
316
+ ```json
317
+ {
318
+ "name": "...",
319
+ "elements": [
320
+ {
321
+ "id": "1",
322
+ "title": "...",
323
+ "connections": [{"to": "2"}]
324
+ }
325
+ ]
326
+ }
327
+ ```
328
+
329
+ **4. Elements array only:**
330
+ ```json
331
+ [
332
+ {"id": "1", "title": "...", "connections": [{"to": "2"}]}
333
+ ]
334
+ ```
335
+
336
+ ### Import examples
337
+
338
+ **Create new schema:**
339
+ ```
340
+ import_schema_from_json(
341
+ json_content: {...},
342
+ name: "My Schema"
343
+ )
344
+ ```
345
+
346
+ **Update existing schema:**
347
+ ```
348
+ import_schema_from_json(
349
+ json_content: {...},
350
+ schema_id: "existing-id"
351
+ )
352
+ ```
353
+
354
+ ## Version History
355
+
356
+ MCP now automatically creates versions when updating schemas:
357
+ - Before each update via MCP, a snapshot is saved
358
+ - View version history in the web interface (History tab)
359
+ - Restore any previous version with one click
360
+
270
361
  ## Links
271
362
 
272
363
  - [SchemeOG Cloud](https://scheme.smartlaunchhub.com)
package/index.js CHANGED
@@ -1,17 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * SchemeOG MCP Server v2.8
4
+ * SchemeOG MCP Server v2.9.1
5
5
  *
6
6
  * MCP сервер для работы со схемами, проектами и тегами в SchemeOG Cloud.
7
7
  *
8
8
  * Команды для схем:
9
9
  * - list_schemas: Список всех схем
10
10
  * - get_schema: Получить схему с данными
11
+ * - get_schema_by_url: Получить схему по URL
11
12
  * - create_schema: Создать схему (с элементами и связями)
12
13
  * - replace_schema: Полностью заменить содержимое схемы
13
14
  * - delete_schema: Удалить схему
14
15
  *
16
+ * Команды для импорта/экспорта:
17
+ * - import_schema_from_json: Импортировать схему из JSON (создать новую или обновить существующую)
18
+ * - export_schema_to_json: Экспортировать схему в JSON формат
19
+ *
15
20
  * Команды для проектов:
16
21
  * - list_projects: Список проектов (папок)
17
22
  * - create_project: Создать проект
@@ -32,6 +37,7 @@ import {
32
37
  CallToolRequestSchema,
33
38
  ListToolsRequestSchema,
34
39
  } from "@modelcontextprotocol/sdk/types.js";
40
+ import { readFileSync } from "fs";
35
41
 
36
42
  // Конфигурация
37
43
  const API_BASE_URL = process.env.SCHEMEOG_API_URL || "https://scheme.smartlaunchhub.com";
@@ -974,6 +980,154 @@ const TOOLS = [
974
980
  required: ["schema_id"],
975
981
  },
976
982
  },
983
+
984
+ // ========== ИМПОРТ/ЭКСПОРТ ==========
985
+ {
986
+ name: "import_schema_from_json",
987
+ description: `Импортировать схему из JSON файла или JSON строки.
988
+
989
+ Это универсальный метод для загрузки схем — поддерживает:
990
+ 1. Полный JSON экспорт SchemeOG (с метаданными)
991
+ 2. Простой JSON с elements и connections
992
+ 3. Локальный формат (connections внутри элементов)
993
+
994
+ Использование:
995
+ 1. Создание НОВОЙ схемы из JSON:
996
+ - Указать json_content ИЛИ file_path с данными
997
+ - Указать name (название новой схемы)
998
+ - НЕ указывать schema_id
999
+
1000
+ 2. Обновление СУЩЕСТВУЮЩЕЙ схемы:
1001
+ - Указать json_content ИЛИ file_path с данными
1002
+ - Указать schema_id существующей схемы
1003
+ - name не обязателен (возьмётся из JSON или оставится текущее)
1004
+
1005
+ ВАЖНО: Для больших файлов (>50KB) используй file_path вместо json_content!
1006
+ Claude урезает большие параметры, но file_path читает файл напрямую без ограничений.
1007
+
1008
+ Параметры:
1009
+ - json_content: JSON данные схемы (строка или объект) — для небольших схем
1010
+ - file_path: Путь к JSON файлу на диске — для больших файлов (рекомендуется!)
1011
+ - schema_id: ID существующей схемы для обновления (опционально)
1012
+ - name: Название новой схемы (опционально, обязательно если нет schema_id и нет name в JSON)
1013
+ - project_id: ID проекта для размещения (опционально)
1014
+
1015
+ Примеры json_content:
1016
+
1017
+ 1. Полный экспорт SchemeOG:
1018
+ {
1019
+ "exportVersion": "1.0",
1020
+ "exportedAt": "2025-01-11T12:00:00Z",
1021
+ "schema": {
1022
+ "name": "Моя схема",
1023
+ "description": "Описание",
1024
+ "elements": [...],
1025
+ "connections": [...],
1026
+ "tagsDictionary": [...]
1027
+ }
1028
+ }
1029
+
1030
+ 2. Простой формат:
1031
+ {
1032
+ "name": "Схема",
1033
+ "elements": [
1034
+ {"id": "1", "type": "card", "title": "Шаг 1"}
1035
+ ],
1036
+ "connections": [
1037
+ {"from": "1", "to": "2"}
1038
+ ]
1039
+ }
1040
+
1041
+ 3. Локальный формат (connections внутри элементов):
1042
+ {
1043
+ "elements": [
1044
+ {"id": "1", "type": "card", "title": "Шаг 1", "connections": [{"to": "2"}]}
1045
+ ]
1046
+ }`,
1047
+ inputSchema: {
1048
+ type: "object",
1049
+ properties: {
1050
+ json_content: {
1051
+ oneOf: [
1052
+ { type: "string", description: "JSON строка с данными схемы" },
1053
+ { type: "object", description: "JSON объект с данными схемы" }
1054
+ ],
1055
+ description: "JSON данные схемы (строка или объект) — для небольших схем",
1056
+ },
1057
+ file_path: {
1058
+ type: "string",
1059
+ description: "Путь к JSON файлу на диске (для больших файлов >50KB — рекомендуется!)",
1060
+ },
1061
+ schema_id: {
1062
+ type: "string",
1063
+ description: "ID существующей схемы для обновления (если не указан — создаётся новая)",
1064
+ },
1065
+ name: {
1066
+ type: "string",
1067
+ description: "Название схемы (обязательно для новой схемы, если нет name в JSON)",
1068
+ },
1069
+ project_id: {
1070
+ type: "string",
1071
+ description: "ID проекта для размещения схемы",
1072
+ },
1073
+ },
1074
+ required: [],
1075
+ },
1076
+ },
1077
+ {
1078
+ name: "export_schema_to_json",
1079
+ description: `Экспортировать схему в JSON формат.
1080
+
1081
+ Возвращает полные данные схемы в JSON формате, готовые для:
1082
+ - Сохранения в файл
1083
+ - Передачи в другую систему
1084
+ - Импорта через import_schema_from_json
1085
+ - Резервного копирования
1086
+
1087
+ Формат экспорта включает:
1088
+ - Метаданные (версия экспорта, дата, ID схемы)
1089
+ - Название и описание схемы
1090
+ - Все элементы с их свойствами
1091
+ - Все связи между элементами
1092
+ - Справочник тегов
1093
+
1094
+ Параметры:
1095
+ - schema_id: ID схемы для экспорта (обязательно)
1096
+ - format: Формат вывода (опционально)
1097
+ - "full" (по умолчанию) — полный экспорт с метаданными
1098
+ - "compact" — только elements, connections, tagsDictionary
1099
+ - "elements_only" — только массив elements (с connections внутри)
1100
+
1101
+ Пример ответа (format: "full"):
1102
+ {
1103
+ "exportVersion": "1.0",
1104
+ "exportedAt": "2025-01-11T12:00:00Z",
1105
+ "source": "schemeog-mcp",
1106
+ "schema": {
1107
+ "id": "xxx",
1108
+ "name": "Моя схема",
1109
+ "description": "Описание",
1110
+ "elements": [...],
1111
+ "connections": [...],
1112
+ "tagsDictionary": [...]
1113
+ }
1114
+ }`,
1115
+ inputSchema: {
1116
+ type: "object",
1117
+ properties: {
1118
+ schema_id: {
1119
+ type: "string",
1120
+ description: "ID схемы для экспорта",
1121
+ },
1122
+ format: {
1123
+ type: "string",
1124
+ enum: ["full", "compact", "elements_only"],
1125
+ description: "Формат экспорта: full (с метаданными), compact (только данные), elements_only (только элементы)",
1126
+ },
1127
+ },
1128
+ required: ["schema_id"],
1129
+ },
1130
+ },
977
1131
  ];
978
1132
 
979
1133
  /**
@@ -1610,6 +1764,275 @@ URL: ${API_BASE_URL}/canvas?schema=${schema_id}${warningsText}`,
1610
1764
  };
1611
1765
  }
1612
1766
 
1767
+ // ========== ИМПОРТ/ЭКСПОРТ ==========
1768
+ case "import_schema_from_json": {
1769
+ const { json_content, file_path, schema_id, name, project_id } = args;
1770
+
1771
+ // Проверяем что указан хотя бы один источник данных
1772
+ if (!json_content && !file_path) {
1773
+ const error = createError(
1774
+ ErrorCodes.VALIDATION_ERROR,
1775
+ `Укажите json_content ИЛИ file_path.\n\nДля больших файлов (>50KB) рекомендуется использовать file_path.`
1776
+ );
1777
+ throw new Error(error.message);
1778
+ }
1779
+
1780
+ // Получаем содержимое JSON
1781
+ let rawContent;
1782
+ let sourceInfo = "";
1783
+
1784
+ if (file_path) {
1785
+ // Читаем файл с диска (для больших файлов)
1786
+ try {
1787
+ rawContent = readFileSync(file_path, "utf-8");
1788
+ const fileSizeKB = Math.round(rawContent.length / 1024);
1789
+ sourceInfo = ` (из файла ${file_path}, ${fileSizeKB}KB)`;
1790
+ } catch (fileError) {
1791
+ const error = createError(
1792
+ ErrorCodes.VALIDATION_ERROR,
1793
+ `Не удалось прочитать файл: ${file_path}\n\nОшибка: ${fileError.message}`
1794
+ );
1795
+ throw new Error(error.message);
1796
+ }
1797
+ } else {
1798
+ rawContent = json_content;
1799
+ }
1800
+
1801
+ // Парсим JSON если это строка
1802
+ let parsedContent;
1803
+ try {
1804
+ if (typeof rawContent === "string") {
1805
+ parsedContent = JSON.parse(rawContent);
1806
+ } else {
1807
+ parsedContent = rawContent;
1808
+ }
1809
+ } catch (parseError) {
1810
+ const error = createError(
1811
+ ErrorCodes.VALIDATION_ERROR,
1812
+ `Невалидный JSON: ${parseError.message}\n\nПроверьте формат данных.`
1813
+ );
1814
+ throw new Error(error.message);
1815
+ }
1816
+
1817
+ // Извлекаем данные схемы из разных форматов
1818
+ let schemaData;
1819
+ let schemaName;
1820
+ let schemaDescription;
1821
+
1822
+ // Формат 1: Полный экспорт SchemeOG { exportVersion, schema: {...} }
1823
+ if (parsedContent.exportVersion && parsedContent.schema) {
1824
+ schemaData = parsedContent.schema;
1825
+ schemaName = schemaData.name;
1826
+ schemaDescription = schemaData.description;
1827
+ }
1828
+ // Формат 2: Простой { name, elements, connections }
1829
+ else if (parsedContent.elements || parsedContent.name) {
1830
+ schemaData = parsedContent;
1831
+ schemaName = parsedContent.name;
1832
+ schemaDescription = parsedContent.description;
1833
+ }
1834
+ // Формат 3: Только { elements: [...] }
1835
+ else if (Array.isArray(parsedContent)) {
1836
+ schemaData = { elements: parsedContent };
1837
+ }
1838
+ else {
1839
+ const error = createError(
1840
+ ErrorCodes.VALIDATION_ERROR,
1841
+ `Неизвестный формат JSON.\n\nПоддерживаемые форматы:\n• {exportVersion, schema: {...}} — экспорт SchemeOG\n• {name, elements, connections} — простой формат\n• {elements: [...]} — только элементы`
1842
+ );
1843
+ throw new Error(error.message);
1844
+ }
1845
+
1846
+ // Определяем название
1847
+ const finalName = name || schemaName;
1848
+
1849
+ // Нормализуем элементы
1850
+ const elements = schemaData.elements || [];
1851
+ const { elements: normalizedElements, extractedConnections, warnings, error: normalizeError } = prepareElements(elements);
1852
+
1853
+ if (normalizeError) {
1854
+ return {
1855
+ content: [{
1856
+ type: "text",
1857
+ text: `❌ ${normalizeError}`,
1858
+ }],
1859
+ isError: true,
1860
+ };
1861
+ }
1862
+
1863
+ // Объединяем connections (из элементов + отдельные)
1864
+ const existingConnections = prepareConnections(schemaData.connections || []);
1865
+ const allConnections = [...extractedConnections, ...existingConnections];
1866
+
1867
+ // Удаляем дубликаты connections (по from+to)
1868
+ const uniqueConnections = [];
1869
+ const seenConnections = new Set();
1870
+ for (const conn of allConnections) {
1871
+ const key = `${conn.from}->${conn.to}`;
1872
+ if (!seenConnections.has(key)) {
1873
+ seenConnections.add(key);
1874
+ uniqueConnections.push(conn);
1875
+ }
1876
+ }
1877
+
1878
+ const data = {
1879
+ elements: normalizedElements,
1880
+ connections: uniqueConnections,
1881
+ tagsDictionary: schemaData.tagsDictionary || [],
1882
+ };
1883
+
1884
+ let result;
1885
+ let actionText;
1886
+
1887
+ if (schema_id) {
1888
+ // ОБНОВЛЕНИЕ существующей схемы
1889
+ const updateBody = {
1890
+ data,
1891
+ updatedBy: 'mcp',
1892
+ };
1893
+ if (finalName) updateBody.name = finalName;
1894
+ if (schemaDescription) updateBody.description = schemaDescription;
1895
+
1896
+ result = await apiRequest(`/schemas/${schema_id}`, {
1897
+ method: "PUT",
1898
+ body: JSON.stringify(updateBody),
1899
+ });
1900
+ actionText = "обновлена";
1901
+ } else {
1902
+ // СОЗДАНИЕ новой схемы
1903
+ if (!finalName) {
1904
+ const error = createError(
1905
+ ErrorCodes.VALIDATION_ERROR,
1906
+ `Для создания новой схемы необходимо указать name.\n\nЛибо:\n• Добавьте параметр name\n• Либо укажите name в JSON данных`
1907
+ );
1908
+ throw new Error(error.message);
1909
+ }
1910
+
1911
+ result = await apiRequest("/schemas", {
1912
+ method: "POST",
1913
+ body: JSON.stringify({
1914
+ name: finalName,
1915
+ description: schemaDescription,
1916
+ data,
1917
+ projectId: project_id,
1918
+ }),
1919
+ });
1920
+ actionText = "создана";
1921
+ }
1922
+
1923
+ // Формируем сообщение о предупреждениях
1924
+ let warningsText = "";
1925
+ if (warnings.length > 0) {
1926
+ warningsText = `\n\n⚠️ Автоисправления (${warnings.length}):\n• ${warnings.slice(0, 5).join("\n• ")}`;
1927
+ if (warnings.length > 5) {
1928
+ warningsText += `\n• ...и ещё ${warnings.length - 5}`;
1929
+ }
1930
+ }
1931
+
1932
+ return {
1933
+ content: [{
1934
+ type: "text",
1935
+ text: `✅ Схема "${result.schema.name}" ${actionText}${sourceInfo}!
1936
+
1937
+ ID: ${result.schema.id}
1938
+ Элементов: ${data.elements.length}
1939
+ Связей: ${data.connections.length}
1940
+ Тегов: ${data.tagsDictionary.length}
1941
+
1942
+ URL: ${API_BASE_URL}/canvas?schema=${result.schema.id}${warningsText}`,
1943
+ }],
1944
+ };
1945
+ }
1946
+
1947
+ case "export_schema_to_json": {
1948
+ const { schema_id, format = "full" } = args;
1949
+
1950
+ // Получаем схему
1951
+ const result = await apiRequest(`/schemas/${schema_id}`);
1952
+ const schema = result.schema;
1953
+
1954
+ const elements = schema.data?.elements || [];
1955
+ const connections = schema.data?.connections || [];
1956
+ const tagsDictionary = schema.data?.tagsDictionary || [];
1957
+
1958
+ let exportData;
1959
+ let exportText;
1960
+
1961
+ switch (format) {
1962
+ case "compact":
1963
+ // Только данные без метаданных
1964
+ exportData = {
1965
+ name: schema.name,
1966
+ description: schema.description,
1967
+ elements,
1968
+ connections,
1969
+ tagsDictionary,
1970
+ };
1971
+ exportText = `Компактный экспорт схемы "${schema.name}":\n\n\`\`\`json\n${JSON.stringify(exportData, null, 2)}\n\`\`\``;
1972
+ break;
1973
+
1974
+ case "elements_only":
1975
+ // Только элементы с connections внутри (локальный формат)
1976
+ const elementsWithConnections = elements.map(el => {
1977
+ const elConnections = connections
1978
+ .filter(c => c.from === el.id)
1979
+ .map(c => ({ to: c.to, label: c.label }))
1980
+ .filter(c => c.to); // убираем пустые
1981
+
1982
+ const elementCopy = { ...el };
1983
+ if (elConnections.length > 0) {
1984
+ elementCopy.connections = elConnections;
1985
+ }
1986
+ return elementCopy;
1987
+ });
1988
+
1989
+ exportData = { elements: elementsWithConnections };
1990
+ if (tagsDictionary.length > 0) {
1991
+ exportData.tagsDictionary = tagsDictionary;
1992
+ }
1993
+ exportText = `Элементы схемы "${schema.name}" (локальный формат):\n\n\`\`\`json\n${JSON.stringify(exportData, null, 2)}\n\`\`\``;
1994
+ break;
1995
+
1996
+ case "full":
1997
+ default:
1998
+ // Полный экспорт с метаданными
1999
+ exportData = {
2000
+ exportVersion: "1.0",
2001
+ exportedAt: new Date().toISOString(),
2002
+ source: "schemeog-mcp",
2003
+ schema: {
2004
+ id: schema.id,
2005
+ name: schema.name,
2006
+ description: schema.description,
2007
+ projectId: schema.projectId,
2008
+ elements,
2009
+ connections,
2010
+ tagsDictionary,
2011
+ },
2012
+ };
2013
+ exportText = `Полный экспорт схемы "${schema.name}":\n\n\`\`\`json\n${JSON.stringify(exportData, null, 2)}\n\`\`\``;
2014
+ break;
2015
+ }
2016
+
2017
+ return {
2018
+ content: [{
2019
+ type: "text",
2020
+ text: `${exportText}
2021
+
2022
+ ---
2023
+ Статистика:
2024
+ • Элементов: ${elements.length}
2025
+ • Связей: ${connections.length}
2026
+ • Тегов: ${tagsDictionary.length}
2027
+
2028
+ Этот JSON можно:
2029
+ • Сохранить в файл
2030
+ • Импортировать через import_schema_from_json
2031
+ • Передать в другую систему`,
2032
+ }],
2033
+ };
2034
+ }
2035
+
1613
2036
  default:
1614
2037
  throw new Error(`Неизвестная команда: ${name}`);
1615
2038
  }
@@ -1648,7 +2071,7 @@ async function main() {
1648
2071
  const server = new Server(
1649
2072
  {
1650
2073
  name: "schemeog-mcp",
1651
- version: "2.8.1",
2074
+ version: "2.9.1",
1652
2075
  },
1653
2076
  {
1654
2077
  capabilities: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "schemeog-mcp",
3
- "version": "2.8.2",
3
+ "version": "2.9.1",
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",