schemeog-mcp 2.0.0 → 2.2.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 (3) hide show
  1. package/README.md +189 -52
  2. package/index.js +801 -45
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,10 @@
1
- # SchemeOG MCP Server v2.0
1
+ # SchemeOG MCP Server v2.1
2
2
 
3
3
  MCP сервер для [SchemeOG Cloud](https://scheme.smartlaunchhub.com) — создавай диаграммы и схемы с помощью AI.
4
4
 
5
- ## 5 команд всё что нужно
5
+ ## 14 команд для полного контроля
6
+
7
+ ### Схемы (5 команд)
6
8
 
7
9
  | Команда | Описание |
8
10
  |---------|----------|
@@ -12,12 +14,31 @@ MCP сервер для [SchemeOG Cloud](https://scheme.smartlaunchhub.com) —
12
14
  | `replace_schema` | Заменить содержимое схемы |
13
15
  | `delete_schema` | Удалить схему |
14
16
 
17
+ ### Проекты (5 команд)
18
+
19
+ | Команда | Описание |
20
+ |---------|----------|
21
+ | `list_projects` | Список проектов (папок) |
22
+ | `create_project` | Создать проект |
23
+ | `update_project` | Обновить проект |
24
+ | `delete_project` | Удалить проект |
25
+ | `move_schema_to_project` | Переместить схему в проект |
26
+
27
+ ### Теги (4 команды)
28
+
29
+ | Команда | Описание |
30
+ |---------|----------|
31
+ | `list_tags` | Список тегов схемы |
32
+ | `add_tag` | Добавить тег в схему |
33
+ | `remove_tag` | Удалить тег из схемы |
34
+ | `tag_element` | Присвоить/убрать тег с элемента |
35
+
15
36
  ## Установка
16
37
 
17
38
  ### Через npx (рекомендуется)
18
39
 
19
40
  ```bash
20
- npx schemeog-cloud-mcp
41
+ npx schemeog-mcp
21
42
  ```
22
43
 
23
44
  ## Настройка
@@ -26,8 +47,8 @@ npx schemeog-cloud-mcp
26
47
 
27
48
  1. Открой https://scheme.smartlaunchhub.com
28
49
  2. Войди по email
29
- 3. DevTools (F12) → Application → Local Storage
30
- 4. Скопируй значение `token`
50
+ 3. Перейди в Профиль
51
+ 4. Скопируй токен из секции "Claude Code Integration"
31
52
 
32
53
  ### 2. Добавь в Claude Code / Cline
33
54
 
@@ -38,91 +59,207 @@ npx schemeog-cloud-mcp
38
59
  "mcpServers": {
39
60
  "schemeog": {
40
61
  "command": "npx",
41
- "args": ["-y", "schemeog-cloud-mcp"],
62
+ "args": ["-y", "schemeog-mcp"],
42
63
  "env": {
43
- "SCHEMEOG_TOKEN": "твой-jwt-токен"
64
+ "SCHEMEOG_TOKEN": "schog_xxxxx..."
44
65
  }
45
66
  }
46
67
  }
47
68
  }
48
69
  ```
49
70
 
50
- ## Примеры использования
51
-
52
- ### Создать схему
53
-
54
- ```
55
- Создай схему "User Registration Flow" с блоками:
56
- - Форма регистрации
57
- - Валидация
58
- - Сохранение в БД
59
- - Отправка email
60
- - Успех
61
- ```
71
+ ## Формат данных схемы
62
72
 
63
- AI сгенерирует:
73
+ ### Полный пример схемы
64
74
 
65
75
  ```json
66
76
  {
67
77
  "name": "User Registration Flow",
78
+ "description": "Процесс регистрации пользователя",
68
79
  "elements": [
69
- {"id": "1", "type": "block", "x": 100, "y": 100, "text": "Форма регистрации"},
70
- {"id": "2", "type": "block", "x": 300, "y": 100, "text": "Валидация"},
71
- {"id": "3", "type": "block", "x": 500, "y": 100, "text": "Сохранение в БД"},
72
- {"id": "4", "type": "block", "x": 700, "y": 100, "text": "Отправка email"},
73
- {"id": "5", "type": "block", "x": 900, "y": 100, "text": "Успех"}
80
+ {
81
+ "id": "start",
82
+ "type": "card",
83
+ "title": "Форма регистрации",
84
+ "color": "light_green",
85
+ "borderColor": "green",
86
+ "tags": ["пользователь"],
87
+ "description": "Пользователь заполняет форму с email и паролем"
88
+ },
89
+ {
90
+ "id": "validate",
91
+ "type": "condition",
92
+ "title": "Валидация данных",
93
+ "color": "light_yellow",
94
+ "borderColor": "yellow",
95
+ "tags": ["система", "проверка"],
96
+ "description": "Проверка корректности email и сложности пароля"
97
+ },
98
+ {
99
+ "id": "save",
100
+ "type": "card",
101
+ "title": "Сохранение в БД",
102
+ "color": "light_blue",
103
+ "borderColor": "blue",
104
+ "tags": ["система"],
105
+ "description": "Создание записи пользователя в базе данных"
106
+ },
107
+ {
108
+ "id": "error",
109
+ "type": "card",
110
+ "title": "Ошибка валидации",
111
+ "color": "light_red",
112
+ "borderColor": "red",
113
+ "tags": ["система", "ошибка"],
114
+ "description": "Показать пользователю ошибки валидации"
115
+ },
116
+ {
117
+ "id": "success",
118
+ "type": "card",
119
+ "title": "Успешная регистрация",
120
+ "color": "light_green",
121
+ "borderColor": "green",
122
+ "tags": ["пользователь"],
123
+ "description": "Пользователь успешно зарегистрирован"
124
+ }
74
125
  ],
75
126
  "connections": [
76
- {"from": "1", "to": "2"},
77
- {"from": "2", "to": "3"},
78
- {"from": "3", "to": "4"},
79
- {"from": "4", "to": "5"}
127
+ {"from": "start", "to": "validate", "label": "отправка формы"},
128
+ {"from": "validate", "to": "save", "label": "данные корректны"},
129
+ {"from": "validate", "to": "error", "label": "ошибка"},
130
+ {"from": "save", "to": "success"},
131
+ {"from": "error", "to": "start", "label": "исправить"}
132
+ ],
133
+ "tagsDictionary": [
134
+ {"id": "tag-user", "name": "пользователь", "color": "#4CAF50"},
135
+ {"id": "tag-system", "name": "система", "color": "#2196F3"},
136
+ {"id": "tag-check", "name": "проверка", "color": "#FF9800"},
137
+ {"id": "tag-error", "name": "ошибка", "color": "#F44336"}
80
138
  ]
81
139
  }
82
140
  ```
83
141
 
84
- ### Обновить схему
142
+ ### Элемент (card или condition)
85
143
 
86
- ```
87
- Добавь в схему блок "Обработка ошибок" после валидации
144
+ ```json
145
+ {
146
+ "id": "unique_id",
147
+ "type": "card",
148
+ "title": "Название карточки",
149
+ "color": "light_blue",
150
+ "borderColor": "blue",
151
+ "tags": ["тег1", "тег2"],
152
+ "description": "Подробное описание действия или процесса"
153
+ }
88
154
  ```
89
155
 
90
- AI получит текущую схему, добавит блок и связи, отправит обновление.
156
+ **Типы элементов:**
157
+ - `card` — обычная карточка процесса/действия
158
+ - `condition` — точка принятия решения (ромб)
91
159
 
92
- ### Посмотреть схемы
160
+ **Доступные цвета фона (`color`):**
161
+ | Цвет | Назначение |
162
+ |------|------------|
163
+ | `white` | Базовый белый |
164
+ | `light_blue` | Основные процессы |
165
+ | `light_green` | Старт и успех |
166
+ | `light_yellow` | Проверки и условия |
167
+ | `light_orange` | Предупреждения |
168
+ | `light_red` | Ошибки и критичное |
169
+ | `light_purple` | Решения |
170
+ | `light_gray` | Завершение |
171
+ | `light_pink` | Дополнительные процессы |
172
+ | `light_teal` | Специальные операции |
93
173
 
94
- ```
95
- Покажи мои схемы
96
- ```
174
+ **Цвета обводки (`borderColor`):**
175
+ `default`, `blue`, `green`, `orange`, `purple`, `red`, `teal`, `yellow`, `gray`, `black`
97
176
 
98
- ## Формат данных
177
+ **Важно:** НЕ указывай `width`, `height`, `x`, `y` — они рассчитываются автоматически!
99
178
 
100
- ### Элемент
179
+ ### Связь (connection)
101
180
 
102
181
  ```json
103
182
  {
104
- "id": "unique_id",
105
- "type": "block", // block, note, group
106
- "x": 100, // X координата
107
- "y": 100, // Y координата
108
- "text": "Текст", // содержимое
109
- "width": 200, // ширина (опционально)
110
- "height": 100, // высота (опционально)
111
- "color": "#E3F2FD" // цвет фона (опционально)
183
+ "from": "source_id",
184
+ "to": "target_id",
185
+ "label": "подпись (опционально)",
186
+ "style": "solid"
112
187
  }
113
188
  ```
114
189
 
115
- ### Связь
190
+ **Стили линий (`style`):** `solid`, `dashed`, `dotted`
191
+
192
+ ### Справочник тегов (tagsDictionary)
116
193
 
117
194
  ```json
118
195
  {
119
- "from": "id1", // ID источника
120
- "to": "id2", // ID назначения
121
- "label": "текст", // подпись (опционально)
122
- "style": "solid" // solid, dashed, dotted
196
+ "tagsDictionary": [
197
+ {"id": "tag-1", "name": "система", "color": "#2196F3"},
198
+ {"id": "tag-2", "name": "пользователь", "color": "#4CAF50"},
199
+ {"id": "tag-3", "name": "проверка", "color": "#FF9800"}
200
+ ]
123
201
  }
124
202
  ```
125
203
 
204
+ **Теги = роли/акторы.** Указывают КТО выполняет действие:
205
+ - `система`, `пользователь`, `администратор`
206
+ - `клиент`, `менеджер`, `бот`
207
+ - `муж`, `жена`, `ребёнок` (для личных схем)
208
+
209
+ ## Примеры использования
210
+
211
+ ### Создать схему
212
+
213
+ ```
214
+ Создай схему "Авторизация пользователя" с этапами:
215
+ 1. Ввод логина/пароля (пользователь)
216
+ 2. Проверка в базе (система)
217
+ 3. Успех или ошибка
218
+ ```
219
+
220
+ ### Обновить схему
221
+
222
+ ```
223
+ Добавь в схему блок "Двухфакторная аутентификация" между проверкой и успехом
224
+ ```
225
+
226
+ ### Работа с проектами
227
+
228
+ ```
229
+ Создай проект "Backend API" с иконкой 🚀 и синим цветом
230
+ ```
231
+
232
+ ```
233
+ Перемести схему в проект Backend API
234
+ ```
235
+
236
+ ### Работа с тегами
237
+
238
+ ```
239
+ Добавь тег "Critical" красного цвета в схему
240
+ ```
241
+
242
+ ```
243
+ Пометь элемент "Валидация" тегом Critical
244
+ ```
245
+
246
+ ## Методология создания схем
247
+
248
+ Схема = полное дерево **ДЕЙСТВИЙ** и **ПОСЛЕДСТВИЙ**:
249
+
250
+ 1. Каждое решение → показать ВСЕ возможные варианты
251
+ 2. Каждый вариант → показать ВСЕ последствия
252
+ 3. Использовать `condition` для точек принятия решений
253
+ 4. НЕ абстрактные размышления — КОНКРЕТНЫЕ пути развития
254
+ 5. Теги указывают КТО выполняет действие
255
+
256
+ **Пример:**
257
+ ```
258
+ "Отправка формы" → condition "Валидация" →
259
+ ├── "Данные корректны" → "Сохранение" → "Успех"
260
+ └── "Ошибка" → "Показать ошибки" → "Исправить форму"
261
+ ```
262
+
126
263
  ## Ссылки
127
264
 
128
265
  - [SchemeOG Cloud](https://scheme.smartlaunchhub.com)
package/index.js CHANGED
@@ -1,17 +1,29 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * SchemeOG Cloud MCP Server v2.0
4
+ * SchemeOG MCP Server v2.1
5
5
  *
6
- * Минималистичный MCP сервер для работы со схемами.
7
- * 5 команд — максимум мощи, минимум сложности.
6
+ * MCP сервер для работы со схемами, проектами и тегами в SchemeOG Cloud.
8
7
  *
9
- * Команды:
8
+ * Команды для схем:
10
9
  * - list_schemas: Список всех схем
11
10
  * - get_schema: Получить схему с данными
12
11
  * - create_schema: Создать схему (с элементами и связями)
13
12
  * - replace_schema: Полностью заменить содержимое схемы
14
13
  * - delete_schema: Удалить схему
14
+ *
15
+ * Команды для проектов:
16
+ * - list_projects: Список проектов (папок)
17
+ * - create_project: Создать проект
18
+ * - update_project: Обновить проект
19
+ * - delete_project: Удалить проект
20
+ * - move_schema_to_project: Переместить схему в проект
21
+ *
22
+ * Команды для тегов:
23
+ * - list_tags: Список тегов схемы
24
+ * - add_tag: Добавить тег в схему
25
+ * - remove_tag: Удалить тег из схемы
26
+ * - tag_element: Присвоить/убрать тег с элемента
15
27
  */
16
28
 
17
29
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -24,16 +36,98 @@ import {
24
36
  // Конфигурация
25
37
  const API_BASE_URL = process.env.SCHEMEOG_API_URL || "https://scheme.smartlaunchhub.com";
26
38
  const AUTH_TOKEN = process.env.SCHEMEOG_TOKEN || "";
39
+ const DOCS_URL = "https://scheme.smartlaunchhub.com/docs";
40
+ const PROFILE_URL = "https://scheme.smartlaunchhub.com/profile";
41
+
42
+ /**
43
+ * Коды ошибок MCP
44
+ */
45
+ const ErrorCodes = {
46
+ AUTH_MISSING: "AUTH_MISSING",
47
+ AUTH_INVALID: "AUTH_INVALID",
48
+ AUTH_EXPIRED: "AUTH_EXPIRED",
49
+ NOT_FOUND: "NOT_FOUND",
50
+ VALIDATION_ERROR: "VALIDATION_ERROR",
51
+ RATE_LIMIT: "RATE_LIMIT",
52
+ SERVER_ERROR: "SERVER_ERROR",
53
+ NETWORK_ERROR: "NETWORK_ERROR",
54
+ };
55
+
56
+ /**
57
+ * Создать форматированную ошибку
58
+ */
59
+ function createError(code, message, details = {}) {
60
+ const errorMessages = {
61
+ [ErrorCodes.AUTH_MISSING]: {
62
+ title: "🔑 Токен не указан",
63
+ hint: `Укажите SCHEMEOG_TOKEN в настройках MCP.\n\nПолучить токен: ${PROFILE_URL}\nДокументация: ${DOCS_URL}`,
64
+ },
65
+ [ErrorCodes.AUTH_INVALID]: {
66
+ title: "🔒 Неверный токен",
67
+ hint: `Токен невалидный или отозван.\n\nСоздайте новый токен: ${PROFILE_URL}`,
68
+ },
69
+ [ErrorCodes.AUTH_EXPIRED]: {
70
+ title: "⏰ Токен истёк",
71
+ hint: `Срок действия токена истёк.\n\nСоздайте новый токен: ${PROFILE_URL}`,
72
+ },
73
+ [ErrorCodes.NOT_FOUND]: {
74
+ title: "🔍 Не найдено",
75
+ hint: `Проверьте правильность ID.\n\nСписок схем: list_schemas\nСписок проектов: list_projects`,
76
+ },
77
+ [ErrorCodes.VALIDATION_ERROR]: {
78
+ title: "⚠️ Ошибка валидации",
79
+ hint: `Проверьте формат данных.\n\nДокументация: ${DOCS_URL}`,
80
+ },
81
+ [ErrorCodes.RATE_LIMIT]: {
82
+ title: "🚫 Превышен лимит запросов",
83
+ hint: "Подождите немного и повторите запрос.",
84
+ },
85
+ [ErrorCodes.SERVER_ERROR]: {
86
+ title: "💥 Ошибка сервера",
87
+ hint: `Попробуйте позже или обратитесь в поддержку.\n\nСтатус: ${API_BASE_URL}/status`,
88
+ },
89
+ [ErrorCodes.NETWORK_ERROR]: {
90
+ title: "🌐 Ошибка сети",
91
+ hint: "Проверьте подключение к интернету.",
92
+ },
93
+ };
94
+
95
+ const errorInfo = errorMessages[code] || { title: "Ошибка", hint: "" };
96
+
97
+ return {
98
+ code,
99
+ message: `${errorInfo.title}\n\n${message}${errorInfo.hint ? `\n\n${errorInfo.hint}` : ""}`,
100
+ details,
101
+ };
102
+ }
27
103
 
28
104
  /**
29
105
  * Выполнить запрос к API SchemeOG
30
106
  */
31
107
  async function apiRequest(endpoint, options = {}) {
108
+ // Проверка токена перед запросом
109
+ if (!AUTH_TOKEN) {
110
+ const error = createError(
111
+ ErrorCodes.AUTH_MISSING,
112
+ "Переменная окружения SCHEMEOG_TOKEN не установлена."
113
+ );
114
+ throw new Error(error.message);
115
+ }
116
+
117
+ // Базовая валидация формата токена
118
+ if (!AUTH_TOKEN.startsWith("sk-") || AUTH_TOKEN.length < 20) {
119
+ const error = createError(
120
+ ErrorCodes.AUTH_INVALID,
121
+ `Неверный формат токена. Токен должен начинаться с "sk-" и содержать минимум 20 символов.\n\nПолучен: ${AUTH_TOKEN.substring(0, 10)}...`
122
+ );
123
+ throw new Error(error.message);
124
+ }
125
+
32
126
  const url = `${API_BASE_URL}/api${endpoint}`;
33
127
 
34
128
  const headers = {
35
129
  "Content-Type": "application/json",
36
- ...(AUTH_TOKEN && { "Authorization": `Bearer ${AUTH_TOKEN}` }),
130
+ "Authorization": `Bearer ${AUTH_TOKEN}`,
37
131
  ...options.headers,
38
132
  };
39
133
 
@@ -43,15 +137,67 @@ async function apiRequest(endpoint, options = {}) {
43
137
  headers,
44
138
  });
45
139
 
46
- const data = await response.json();
140
+ // Попробуем распарсить JSON
141
+ let data;
142
+ try {
143
+ data = await response.json();
144
+ } catch {
145
+ data = { error: "Invalid JSON response" };
146
+ }
47
147
 
48
148
  if (!response.ok) {
49
- throw new Error(data.message || data.error || `HTTP ${response.status}`);
149
+ // Определяем тип ошибки по статусу
150
+ let errorCode;
151
+ let errorMessage = data.message || data.error || `HTTP ${response.status}`;
152
+
153
+ switch (response.status) {
154
+ case 401:
155
+ errorCode = ErrorCodes.AUTH_INVALID;
156
+ errorMessage = "Токен отклонён сервером. Возможно, он отозван или недействителен.";
157
+ break;
158
+ case 403:
159
+ errorCode = ErrorCodes.AUTH_EXPIRED;
160
+ errorMessage = "Доступ запрещён. Проверьте права токена.";
161
+ break;
162
+ case 404:
163
+ errorCode = ErrorCodes.NOT_FOUND;
164
+ errorMessage = data.message || "Ресурс не найден. Проверьте ID схемы или проекта.";
165
+ break;
166
+ case 422:
167
+ errorCode = ErrorCodes.VALIDATION_ERROR;
168
+ errorMessage = data.message || "Неверный формат данных.";
169
+ if (data.errors) {
170
+ errorMessage += "\n\nДетали:\n" + JSON.stringify(data.errors, null, 2);
171
+ }
172
+ break;
173
+ case 429:
174
+ errorCode = ErrorCodes.RATE_LIMIT;
175
+ errorMessage = "Слишком много запросов.";
176
+ break;
177
+ default:
178
+ errorCode = response.status >= 500 ? ErrorCodes.SERVER_ERROR : ErrorCodes.VALIDATION_ERROR;
179
+ }
180
+
181
+ const error = createError(errorCode, errorMessage);
182
+ throw new Error(error.message);
50
183
  }
51
184
 
52
185
  return data;
53
186
  } catch (error) {
54
- throw new Error(`API Error: ${error.message}`);
187
+ // Если это уже наша форматированная ошибка — пробрасываем
188
+ if (error.message.includes("🔑") || error.message.includes("🔒") ||
189
+ error.message.includes("🔍") || error.message.includes("⚠️") ||
190
+ error.message.includes("🚫") || error.message.includes("💥") ||
191
+ error.message.includes("🌐") || error.message.includes("⏰")) {
192
+ throw error;
193
+ }
194
+
195
+ // Ошибка сети
196
+ const networkError = createError(
197
+ ErrorCodes.NETWORK_ERROR,
198
+ `Не удалось подключиться к ${API_BASE_URL}\n\nДетали: ${error.message}`
199
+ );
200
+ throw new Error(networkError.message);
55
201
  }
56
202
  }
57
203
 
@@ -89,14 +235,15 @@ function prepareConnections(connections) {
89
235
  }
90
236
 
91
237
  /**
92
- * 5 основных инструментов MCP
238
+ * Инструменты MCP
93
239
  */
94
240
  const TOOLS = [
241
+ // ========== СХЕМЫ ==========
95
242
  {
96
243
  name: "list_schemas",
97
244
  description: `Получить список всех схем пользователя.
98
245
 
99
- Возвращает: ID, название, описание, дату обновления каждой схемы.
246
+ Возвращает: ID, название, описание, проект, дату обновления каждой схемы.
100
247
 
101
248
  Используй эту команду чтобы узнать какие схемы есть у пользователя.`,
102
249
  inputSchema: {
@@ -132,45 +279,63 @@ const TOOLS = [
132
279
  name: "create_schema",
133
280
  description: `Создать новую схему с элементами и связями.
134
281
 
135
- ВАЖНО: Генерируй сразу полную схему с elements и connections!
282
+ ВАЖНО: Генерируй сразу полную схему с elements, connections и tagsDictionary!
136
283
 
137
284
  Параметры:
138
285
  - name: название схемы (обязательно)
139
286
  - description: описание
287
+ - project_id: ID проекта (опционально)
140
288
  - elements: массив элементов
141
289
  - connections: массив связей
290
+ - tagsDictionary: справочник тегов (опционально)
142
291
 
143
292
  Формат элемента:
144
293
  {
145
- "id": "node1", // уникальный ID (можно не указывать - сгенерируется)
146
- "type": "block", // block, note, group
147
- "x": 100, // координата X
148
- "y": 100, // координата Y
149
- "text": "Текст блока", // текст внутри
150
- "width": 200, // ширина (опционально)
151
- "height": 100, // высота (опционально)
152
- "color": "#E3F2FD" // цвет фона (опционально)
294
+ "id": "unique_id", // уникальный ID
295
+ "type": "card", // card (карточка) или condition (ромб решения)
296
+ "title": "Название", // заголовок карточки
297
+ "color": "light_blue", // цвет фона: white, light_blue, light_green, light_yellow, light_orange, light_red, light_purple, light_gray, light_pink, light_teal
298
+ "borderColor": "blue", // цвет обводки: default, blue, green, orange, purple, red, teal, yellow, gray, black
299
+ "tags": ["тег1"], // массив названий тегов (опционально)
300
+ "description": "Описание процесса" // подробное описание (опционально)
153
301
  }
154
302
 
303
+ НЕ указывай x, y, width, height - рассчитываются автоматически!
304
+
155
305
  Формат связи:
156
306
  {
157
- "from": "node1", // ID элемента-источника
158
- "to": "node2", // ID элемента-назначения
307
+ "from": "source_id", // ID элемента-источника
308
+ "to": "target_id", // ID элемента-назначения
159
309
  "label": "подпись", // текст на связи (опционально)
160
310
  "style": "solid" // solid, dashed, dotted (опционально)
161
311
  }
162
312
 
163
- Пример: создать схему с 3 блоками и 2 связями:
313
+ Формат тега (tagsDictionary):
164
314
  {
165
- "name": "User Flow",
315
+ "id": "tag-1", // уникальный ID тега
316
+ "name": "система", // название тега (роль/актор)
317
+ "color": "#2196F3" // цвет в HEX
318
+ }
319
+
320
+ Пример: создать схему регистрации:
321
+ {
322
+ "name": "User Registration",
166
323
  "elements": [
167
- {"id": "1", "type": "block", "x": 100, "y": 100, "text": "Login"},
168
- {"id": "2", "type": "block", "x": 300, "y": 100, "text": "Dashboard"},
169
- {"id": "3", "type": "block", "x": 500, "y": 100, "text": "Settings"}
324
+ {"id": "start", "type": "card", "title": "Форма регистрации", "color": "light_green", "tags": ["пользователь"]},
325
+ {"id": "validate", "type": "condition", "title": "Валидация", "color": "light_yellow", "tags": ["система"]},
326
+ {"id": "save", "type": "card", "title": "Сохранение в БД", "color": "light_blue", "tags": ["система"]},
327
+ {"id": "error", "type": "card", "title": "Ошибка", "color": "light_red", "tags": ["система"]},
328
+ {"id": "success", "type": "card", "title": "Успех", "color": "light_green", "tags": ["пользователь"]}
170
329
  ],
171
330
  "connections": [
172
- {"from": "1", "to": "2", "label": "success"},
173
- {"from": "2", "to": "3"}
331
+ {"from": "start", "to": "validate"},
332
+ {"from": "validate", "to": "save", "label": "OK"},
333
+ {"from": "validate", "to": "error", "label": "ошибка"},
334
+ {"from": "save", "to": "success"}
335
+ ],
336
+ "tagsDictionary": [
337
+ {"id": "tag-user", "name": "пользователь", "color": "#4CAF50"},
338
+ {"id": "tag-system", "name": "система", "color": "#2196F3"}
174
339
  ]
175
340
  }`,
176
341
  inputSchema: {
@@ -184,6 +349,10 @@ const TOOLS = [
184
349
  type: "string",
185
350
  description: "Описание схемы",
186
351
  },
352
+ project_id: {
353
+ type: "string",
354
+ description: "ID проекта для размещения схемы (опционально)",
355
+ },
187
356
  elements: {
188
357
  type: "array",
189
358
  description: "Массив элементов схемы",
@@ -191,13 +360,12 @@ const TOOLS = [
191
360
  type: "object",
192
361
  properties: {
193
362
  id: { type: "string" },
194
- type: { type: "string", enum: ["block", "note", "group"] },
195
- x: { type: "number" },
196
- y: { type: "number" },
197
- text: { type: "string" },
198
- width: { type: "number" },
199
- height: { type: "number" },
200
- color: { type: "string" },
363
+ type: { type: "string", enum: ["card", "condition"] },
364
+ title: { type: "string" },
365
+ color: { type: "string", enum: ["white", "light_blue", "light_green", "light_yellow", "light_orange", "light_red", "light_purple", "light_gray", "light_pink", "light_teal"] },
366
+ borderColor: { type: "string", enum: ["default", "blue", "green", "orange", "purple", "red", "teal", "yellow", "gray", "black"] },
367
+ tags: { type: "array", items: { type: "string" } },
368
+ description: { type: "string" },
201
369
  },
202
370
  },
203
371
  },
@@ -215,6 +383,18 @@ const TOOLS = [
215
383
  required: ["from", "to"],
216
384
  },
217
385
  },
386
+ tagsDictionary: {
387
+ type: "array",
388
+ description: "Справочник тегов схемы",
389
+ items: {
390
+ type: "object",
391
+ properties: {
392
+ id: { type: "string" },
393
+ name: { type: "string" },
394
+ color: { type: "string" },
395
+ },
396
+ },
397
+ },
218
398
  },
219
399
  required: ["name"],
220
400
  },
@@ -285,14 +465,319 @@ const TOOLS = [
285
465
  required: ["schema_id"],
286
466
  },
287
467
  },
468
+
469
+ // ========== ПРОЕКТЫ ==========
470
+ {
471
+ name: "list_projects",
472
+ description: `Получить список всех проектов пользователя.
473
+
474
+ Проекты - это папки для группировки схем.
475
+ Возвращает: ID, название, описание, цвет, иконку и количество схем в каждом проекте.`,
476
+ inputSchema: {
477
+ type: "object",
478
+ properties: {},
479
+ required: [],
480
+ },
481
+ },
482
+ {
483
+ name: "create_project",
484
+ description: `Создать новый проект (папку для схем).
485
+
486
+ Параметры:
487
+ - name: название проекта (обязательно)
488
+ - description: описание проекта
489
+ - color: цвет в формате HEX (например #FF5733)
490
+ - icon: emoji иконка (например 📁, 🚀, 💡)`,
491
+ inputSchema: {
492
+ type: "object",
493
+ properties: {
494
+ name: {
495
+ type: "string",
496
+ description: "Название проекта",
497
+ },
498
+ description: {
499
+ type: "string",
500
+ description: "Описание проекта",
501
+ },
502
+ color: {
503
+ type: "string",
504
+ description: "Цвет проекта в формате HEX",
505
+ },
506
+ icon: {
507
+ type: "string",
508
+ description: "Emoji иконка проекта",
509
+ },
510
+ },
511
+ required: ["name"],
512
+ },
513
+ },
514
+ {
515
+ name: "delete_project",
516
+ description: `Удалить проект.
517
+
518
+ ВАЖНО: Схемы внутри проекта НЕ удаляются - они перемещаются в раздел "Общие".`,
519
+ inputSchema: {
520
+ type: "object",
521
+ properties: {
522
+ project_id: {
523
+ type: "string",
524
+ description: "ID проекта для удаления",
525
+ },
526
+ },
527
+ required: ["project_id"],
528
+ },
529
+ },
530
+ {
531
+ name: "move_schema_to_project",
532
+ description: `Переместить схему в проект или убрать из проекта.
533
+
534
+ Параметры:
535
+ - schema_id: ID схемы (обязательно)
536
+ - project_id: ID проекта. Если не указан или null - схема перемещается в "Общие" (без проекта)`,
537
+ inputSchema: {
538
+ type: "object",
539
+ properties: {
540
+ schema_id: {
541
+ type: "string",
542
+ description: "ID схемы",
543
+ },
544
+ project_id: {
545
+ type: "string",
546
+ description: "ID проекта (или null для перемещения в Общие)",
547
+ },
548
+ },
549
+ required: ["schema_id"],
550
+ },
551
+ },
552
+ {
553
+ name: "update_project",
554
+ description: `Обновить проект - изменить название, описание, цвет или иконку.
555
+
556
+ Параметры:
557
+ - project_id: ID проекта (обязательно)
558
+ - name: новое название
559
+ - description: новое описание
560
+ - color: новый цвет в формате HEX
561
+ - icon: новая emoji иконка`,
562
+ inputSchema: {
563
+ type: "object",
564
+ properties: {
565
+ project_id: {
566
+ type: "string",
567
+ description: "ID проекта",
568
+ },
569
+ name: {
570
+ type: "string",
571
+ description: "Новое название проекта",
572
+ },
573
+ description: {
574
+ type: "string",
575
+ description: "Новое описание проекта",
576
+ },
577
+ color: {
578
+ type: "string",
579
+ description: "Новый цвет проекта в формате HEX",
580
+ },
581
+ icon: {
582
+ type: "string",
583
+ description: "Новая emoji иконка проекта",
584
+ },
585
+ },
586
+ required: ["project_id"],
587
+ },
588
+ },
589
+
590
+ // ========== ТЕГИ ==========
591
+ {
592
+ name: "add_tag",
593
+ description: `Добавить новый тег в схему.
594
+
595
+ Теги используются для категоризации элементов схемы.
596
+
597
+ Параметры:
598
+ - schema_id: ID схемы (обязательно)
599
+ - name: название тега (обязательно)
600
+ - color: цвет тега в формате HEX (например #4CAF50)`,
601
+ inputSchema: {
602
+ type: "object",
603
+ properties: {
604
+ schema_id: {
605
+ type: "string",
606
+ description: "ID схемы",
607
+ },
608
+ name: {
609
+ type: "string",
610
+ description: "Название тега",
611
+ },
612
+ color: {
613
+ type: "string",
614
+ description: "Цвет тега в формате HEX",
615
+ },
616
+ },
617
+ required: ["schema_id", "name"],
618
+ },
619
+ },
620
+ {
621
+ name: "remove_tag",
622
+ description: `Удалить тег из схемы.
623
+
624
+ Тег будет удалён из tagsDictionary и убран со всех элементов.
625
+
626
+ Параметры:
627
+ - schema_id: ID схемы (обязательно)
628
+ - tag_id: ID тега для удаления (обязательно)`,
629
+ inputSchema: {
630
+ type: "object",
631
+ properties: {
632
+ schema_id: {
633
+ type: "string",
634
+ description: "ID схемы",
635
+ },
636
+ tag_id: {
637
+ type: "string",
638
+ description: "ID тега для удаления",
639
+ },
640
+ },
641
+ required: ["schema_id", "tag_id"],
642
+ },
643
+ },
644
+ {
645
+ name: "tag_element",
646
+ description: `Присвоить или убрать тег с элемента.
647
+
648
+ Параметры:
649
+ - schema_id: ID схемы (обязательно)
650
+ - element_id: ID элемента (обязательно)
651
+ - tag_id: ID тега (обязательно)
652
+ - action: "add" или "remove" (по умолчанию "add")`,
653
+ inputSchema: {
654
+ type: "object",
655
+ properties: {
656
+ schema_id: {
657
+ type: "string",
658
+ description: "ID схемы",
659
+ },
660
+ element_id: {
661
+ type: "string",
662
+ description: "ID элемента",
663
+ },
664
+ tag_id: {
665
+ type: "string",
666
+ description: "ID тега",
667
+ },
668
+ action: {
669
+ type: "string",
670
+ enum: ["add", "remove"],
671
+ description: "Действие: add (добавить) или remove (убрать)",
672
+ },
673
+ },
674
+ required: ["schema_id", "element_id", "tag_id"],
675
+ },
676
+ },
677
+ {
678
+ name: "list_tags",
679
+ description: `Получить список всех тегов схемы.
680
+
681
+ Параметры:
682
+ - schema_id: ID схемы (обязательно)`,
683
+ inputSchema: {
684
+ type: "object",
685
+ properties: {
686
+ schema_id: {
687
+ type: "string",
688
+ description: "ID схемы",
689
+ },
690
+ },
691
+ required: ["schema_id"],
692
+ },
693
+ },
288
694
  ];
289
695
 
696
+ /**
697
+ * Валидация UUID формата
698
+ */
699
+ function isValidUUID(str) {
700
+ if (!str || typeof str !== "string") return false;
701
+ // Принимаем разные форматы ID: UUID и cuid
702
+ return /^[a-zA-Z0-9_-]{10,}$/.test(str);
703
+ }
704
+
705
+ /**
706
+ * Валидация параметров команды
707
+ */
708
+ function validateArgs(name, args) {
709
+ const errors = [];
710
+
711
+ // Валидация schema_id
712
+ if (["get_schema", "replace_schema", "delete_schema", "add_tag", "remove_tag", "tag_element", "list_tags"].includes(name)) {
713
+ if (!args.schema_id) {
714
+ errors.push("schema_id — обязательный параметр");
715
+ } else if (!isValidUUID(args.schema_id)) {
716
+ errors.push(`schema_id "${args.schema_id}" — неверный формат. Используйте ID из list_schemas`);
717
+ }
718
+ }
719
+
720
+ // Валидация project_id
721
+ if (["delete_project", "update_project"].includes(name)) {
722
+ if (!args.project_id) {
723
+ errors.push("project_id — обязательный параметр");
724
+ } else if (!isValidUUID(args.project_id)) {
725
+ errors.push(`project_id "${args.project_id}" — неверный формат. Используйте ID из list_projects`);
726
+ }
727
+ }
728
+
729
+ // Валидация name для создания
730
+ if (["create_schema", "create_project"].includes(name)) {
731
+ if (!args.name || typeof args.name !== "string" || args.name.trim().length === 0) {
732
+ errors.push("name — обязательный параметр (название)");
733
+ } else if (args.name.length > 100) {
734
+ errors.push("name — слишком длинное название (макс. 100 символов)");
735
+ }
736
+ }
737
+
738
+ // Валидация тегов
739
+ if (name === "add_tag") {
740
+ if (!args.name || typeof args.name !== "string") {
741
+ errors.push("name — обязательный параметр (название тега)");
742
+ }
743
+ }
744
+
745
+ if (name === "remove_tag" || name === "tag_element") {
746
+ if (!args.tag_id) {
747
+ errors.push("tag_id — обязательный параметр");
748
+ }
749
+ }
750
+
751
+ if (name === "tag_element") {
752
+ if (!args.element_id) {
753
+ errors.push("element_id — обязательный параметр");
754
+ }
755
+ }
756
+
757
+ // Валидация цвета
758
+ if (args.color && !/^#[0-9A-Fa-f]{6}$/.test(args.color)) {
759
+ errors.push(`color "${args.color}" — неверный формат. Используйте HEX: #RRGGBB (например #4CAF50)`);
760
+ }
761
+
762
+ return errors;
763
+ }
764
+
290
765
  /**
291
766
  * Обработчики инструментов
292
767
  */
293
768
  async function handleTool(name, args) {
769
+ // Валидация параметров
770
+ const validationErrors = validateArgs(name, args);
771
+ if (validationErrors.length > 0) {
772
+ const error = createError(
773
+ ErrorCodes.VALIDATION_ERROR,
774
+ `Ошибки в параметрах:\n\n• ${validationErrors.join("\n• ")}`
775
+ );
776
+ throw new Error(error.message);
777
+ }
778
+
294
779
  switch (name) {
295
- // ========== LIST SCHEMAS ==========
780
+ // ========== СХЕМЫ ==========
296
781
  case "list_schemas": {
297
782
  const result = await apiRequest("/schemas");
298
783
 
@@ -309,6 +794,8 @@ async function handleTool(name, args) {
309
794
  id: s.id,
310
795
  name: s.name,
311
796
  description: s.description || "",
797
+ projectId: s.projectId || null,
798
+ projectName: s.project?.name || "Общие",
312
799
  updatedAt: s.updatedAt,
313
800
  elementsCount: s.data?.elements?.length || 0,
314
801
  connectionsCount: s.data?.connections?.length || 0,
@@ -322,7 +809,6 @@ async function handleTool(name, args) {
322
809
  };
323
810
  }
324
811
 
325
- // ========== GET SCHEMA ==========
326
812
  case "get_schema": {
327
813
  const { schema_id } = args;
328
814
  const result = await apiRequest(`/schemas/${schema_id}`);
@@ -336,6 +822,7 @@ async function handleTool(name, args) {
336
822
 
337
823
  ID: ${schema.id}
338
824
  Описание: ${schema.description || "(нет)"}
825
+ Проект: ${schema.project?.name || "Общие"}
339
826
  Элементов: ${schema.data?.elements?.length || 0}
340
827
  Связей: ${schema.data?.connections?.length || 0}
341
828
  URL: ${API_BASE_URL}/canvas?id=${schema.id}
@@ -349,9 +836,8 @@ ${JSON.stringify(schema.data?.connections || [], null, 2)}`,
349
836
  };
350
837
  }
351
838
 
352
- // ========== CREATE SCHEMA ==========
353
839
  case "create_schema": {
354
- const { name, description, elements, connections } = args;
840
+ const { name, description, project_id, elements, connections } = args;
355
841
 
356
842
  const data = {
357
843
  elements: prepareElements(elements),
@@ -361,15 +847,18 @@ ${JSON.stringify(schema.data?.connections || [], null, 2)}`,
361
847
 
362
848
  const result = await apiRequest("/schemas", {
363
849
  method: "POST",
364
- body: JSON.stringify({ name, description, data }),
850
+ body: JSON.stringify({ name, description, data, projectId: project_id }),
365
851
  });
366
852
 
853
+ const projectInfo = project_id ? `Проект: ${project_id}` : 'Проект: Общие';
854
+
367
855
  return {
368
856
  content: [{
369
857
  type: "text",
370
858
  text: `Схема "${result.schema.name}" создана!
371
859
 
372
860
  ID: ${result.schema.id}
861
+ ${projectInfo}
373
862
  Элементов: ${data.elements.length}
374
863
  Связей: ${data.connections.length}
375
864
 
@@ -380,7 +869,6 @@ URL: ${API_BASE_URL}/canvas?id=${result.schema.id}
380
869
  };
381
870
  }
382
871
 
383
- // ========== REPLACE SCHEMA ==========
384
872
  case "replace_schema": {
385
873
  const { schema_id, name, description, elements, connections } = args;
386
874
 
@@ -423,7 +911,6 @@ URL: ${API_BASE_URL}/canvas?id=${schema_id}`,
423
911
  };
424
912
  }
425
913
 
426
- // ========== DELETE SCHEMA ==========
427
914
  case "delete_schema": {
428
915
  const { schema_id } = args;
429
916
 
@@ -439,6 +926,253 @@ URL: ${API_BASE_URL}/canvas?id=${schema_id}`,
439
926
  };
440
927
  }
441
928
 
929
+ // ========== ПРОЕКТЫ ==========
930
+ case "list_projects": {
931
+ const result = await apiRequest("/projects");
932
+
933
+ if (!result.projects || result.projects.length === 0) {
934
+ return {
935
+ content: [{
936
+ type: "text",
937
+ text: `Проектов пока нет. Все схемы находятся в разделе "Общие" (${result.unassignedCount || 0} схем).\n\nСоздай проект с помощью create_project.`,
938
+ }],
939
+ };
940
+ }
941
+
942
+ const projectsList = result.projects.map(p => ({
943
+ id: p.id,
944
+ name: p.name,
945
+ description: p.description || "",
946
+ color: p.color,
947
+ icon: p.icon,
948
+ schemasCount: p.schemasCount || 0,
949
+ }));
950
+
951
+ return {
952
+ content: [{
953
+ type: "text",
954
+ text: `Найдено ${result.projects.length} проектов:\n\n${JSON.stringify(projectsList, null, 2)}\n\nСхем без проекта ("Общие"): ${result.unassignedCount || 0}`,
955
+ }],
956
+ };
957
+ }
958
+
959
+ case "create_project": {
960
+ const { name, description, color, icon } = args;
961
+
962
+ const result = await apiRequest("/projects", {
963
+ method: "POST",
964
+ body: JSON.stringify({ name, description, color, icon }),
965
+ });
966
+
967
+ return {
968
+ content: [{
969
+ type: "text",
970
+ text: `Проект "${result.project.name}" создан!\n\nID: ${result.project.id}`,
971
+ }],
972
+ };
973
+ }
974
+
975
+ case "delete_project": {
976
+ const { project_id } = args;
977
+
978
+ const result = await apiRequest(`/projects/${project_id}`, {
979
+ method: "DELETE",
980
+ });
981
+
982
+ return {
983
+ content: [{
984
+ type: "text",
985
+ text: result.message || "Проект удалён. Схемы перемещены в 'Общие'.",
986
+ }],
987
+ };
988
+ }
989
+
990
+ case "move_schema_to_project": {
991
+ const { schema_id, project_id } = args;
992
+
993
+ if (project_id) {
994
+ // Переместить в проект
995
+ const result = await apiRequest(`/projects/${project_id}/schemas/${schema_id}`, {
996
+ method: "PUT",
997
+ });
998
+ return {
999
+ content: [{
1000
+ type: "text",
1001
+ text: result.message || "Схема перемещена в проект.",
1002
+ }],
1003
+ };
1004
+ } else {
1005
+ // Убрать из проекта (в "Общие")
1006
+ const result = await apiRequest(`/projects/null/schemas/${schema_id}`, {
1007
+ method: "DELETE",
1008
+ });
1009
+ return {
1010
+ content: [{
1011
+ type: "text",
1012
+ text: result.message || "Схема перемещена в 'Общие'.",
1013
+ }],
1014
+ };
1015
+ }
1016
+ }
1017
+
1018
+ case "update_project": {
1019
+ const { project_id, name, description, color, icon } = args;
1020
+
1021
+ const updateBody = {};
1022
+ if (name !== undefined) updateBody.name = name;
1023
+ if (description !== undefined) updateBody.description = description;
1024
+ if (color !== undefined) updateBody.color = color;
1025
+ if (icon !== undefined) updateBody.icon = icon;
1026
+
1027
+ const result = await apiRequest(`/projects/${project_id}`, {
1028
+ method: "PUT",
1029
+ body: JSON.stringify(updateBody),
1030
+ });
1031
+
1032
+ return {
1033
+ content: [{
1034
+ type: "text",
1035
+ text: `Проект "${result.project.name}" обновлён!\n\nID: ${result.project.id}`,
1036
+ }],
1037
+ };
1038
+ }
1039
+
1040
+ // ========== ТЕГИ ==========
1041
+ case "add_tag": {
1042
+ const { schema_id, name, color } = args;
1043
+
1044
+ // Получаем текущую схему
1045
+ const currentResult = await apiRequest(`/schemas/${schema_id}`);
1046
+ const currentData = currentResult.schema.data || { elements: [], connections: [], tagsDictionary: [] };
1047
+
1048
+ // Создаём новый тег
1049
+ const newTag = {
1050
+ id: generateId(),
1051
+ name: name,
1052
+ color: color || "#9E9E9E",
1053
+ };
1054
+
1055
+ // Добавляем тег в tagsDictionary
1056
+ const tagsDictionary = currentData.tagsDictionary || [];
1057
+ tagsDictionary.push(newTag);
1058
+
1059
+ // Обновляем схему
1060
+ await apiRequest(`/schemas/${schema_id}`, {
1061
+ method: "PUT",
1062
+ body: JSON.stringify({
1063
+ data: { ...currentData, tagsDictionary },
1064
+ }),
1065
+ });
1066
+
1067
+ return {
1068
+ content: [{
1069
+ type: "text",
1070
+ text: `Тег "${name}" добавлен!\n\nID: ${newTag.id}\nЦвет: ${newTag.color}`,
1071
+ }],
1072
+ };
1073
+ }
1074
+
1075
+ case "remove_tag": {
1076
+ const { schema_id, tag_id } = args;
1077
+
1078
+ // Получаем текущую схему
1079
+ const currentResult = await apiRequest(`/schemas/${schema_id}`);
1080
+ const currentData = currentResult.schema.data || { elements: [], connections: [], tagsDictionary: [] };
1081
+
1082
+ // Удаляем тег из tagsDictionary
1083
+ const tagsDictionary = (currentData.tagsDictionary || []).filter(t => t.id !== tag_id);
1084
+
1085
+ // Удаляем тег со всех элементов
1086
+ const elements = (currentData.elements || []).map(el => {
1087
+ if (el.tags && Array.isArray(el.tags)) {
1088
+ el.tags = el.tags.filter(t => t !== tag_id);
1089
+ }
1090
+ return el;
1091
+ });
1092
+
1093
+ // Обновляем схему
1094
+ await apiRequest(`/schemas/${schema_id}`, {
1095
+ method: "PUT",
1096
+ body: JSON.stringify({
1097
+ data: { ...currentData, tagsDictionary, elements },
1098
+ }),
1099
+ });
1100
+
1101
+ return {
1102
+ content: [{
1103
+ type: "text",
1104
+ text: `Тег удалён из схемы и со всех элементов.`,
1105
+ }],
1106
+ };
1107
+ }
1108
+
1109
+ case "tag_element": {
1110
+ const { schema_id, element_id, tag_id, action = "add" } = args;
1111
+
1112
+ // Получаем текущую схему
1113
+ const currentResult = await apiRequest(`/schemas/${schema_id}`);
1114
+ const currentData = currentResult.schema.data || { elements: [], connections: [], tagsDictionary: [] };
1115
+
1116
+ // Находим элемент и обновляем его теги
1117
+ const elements = (currentData.elements || []).map(el => {
1118
+ if (el.id === element_id) {
1119
+ const tags = el.tags || [];
1120
+ if (action === "add") {
1121
+ if (!tags.includes(tag_id)) {
1122
+ tags.push(tag_id);
1123
+ }
1124
+ } else if (action === "remove") {
1125
+ const index = tags.indexOf(tag_id);
1126
+ if (index > -1) {
1127
+ tags.splice(index, 1);
1128
+ }
1129
+ }
1130
+ el.tags = tags;
1131
+ }
1132
+ return el;
1133
+ });
1134
+
1135
+ // Обновляем схему
1136
+ await apiRequest(`/schemas/${schema_id}`, {
1137
+ method: "PUT",
1138
+ body: JSON.stringify({
1139
+ data: { ...currentData, elements },
1140
+ }),
1141
+ });
1142
+
1143
+ const actionText = action === "add" ? "добавлен к" : "убран с";
1144
+ return {
1145
+ content: [{
1146
+ type: "text",
1147
+ text: `Тег ${actionText} элемента ${element_id}.`,
1148
+ }],
1149
+ };
1150
+ }
1151
+
1152
+ case "list_tags": {
1153
+ const { schema_id } = args;
1154
+
1155
+ // Получаем схему
1156
+ const result = await apiRequest(`/schemas/${schema_id}`);
1157
+ const tagsDictionary = result.schema.data?.tagsDictionary || [];
1158
+
1159
+ if (tagsDictionary.length === 0) {
1160
+ return {
1161
+ content: [{
1162
+ type: "text",
1163
+ text: "В схеме нет тегов.\n\nДобавь тег с помощью add_tag.",
1164
+ }],
1165
+ };
1166
+ }
1167
+
1168
+ return {
1169
+ content: [{
1170
+ type: "text",
1171
+ text: `Теги схемы (${tagsDictionary.length}):\n\n${JSON.stringify(tagsDictionary, null, 2)}`,
1172
+ }],
1173
+ };
1174
+ }
1175
+
442
1176
  default:
443
1177
  throw new Error(`Неизвестная команда: ${name}`);
444
1178
  }
@@ -449,13 +1183,35 @@ URL: ${API_BASE_URL}/canvas?id=${schema_id}`,
449
1183
  */
450
1184
  async function main() {
451
1185
  if (!AUTH_TOKEN) {
452
- console.error("⚠️ SCHEMEOG_TOKEN не установлен. Укажите токен в переменной окружения.");
1186
+ console.error(`
1187
+ ⚠️ SCHEMEOG_TOKEN не установлен!
1188
+
1189
+ Для работы MCP сервера необходим API токен.
1190
+
1191
+ 1. Получите токен: ${PROFILE_URL}
1192
+ 2. Добавьте в настройки MCP:
1193
+
1194
+ "env": {
1195
+ "SCHEMEOG_TOKEN": "sk-ваш-токен"
1196
+ }
1197
+
1198
+ Документация: ${DOCS_URL}
1199
+ `);
1200
+ } else if (!AUTH_TOKEN.startsWith("sk-")) {
1201
+ console.error(`
1202
+ ⚠️ Неверный формат токена!
1203
+
1204
+ Токен должен начинаться с "sk-".
1205
+ Получен: ${AUTH_TOKEN.substring(0, 10)}...
1206
+
1207
+ Создайте новый токен: ${PROFILE_URL}
1208
+ `);
453
1209
  }
454
1210
 
455
1211
  const server = new Server(
456
1212
  {
457
1213
  name: "schemeog-mcp",
458
- version: "2.0.0",
1214
+ version: "2.1.0",
459
1215
  },
460
1216
  {
461
1217
  capabilities: {
@@ -485,7 +1241,7 @@ async function main() {
485
1241
  const transport = new StdioServerTransport();
486
1242
  await server.connect(transport);
487
1243
 
488
- console.error("SchemeOG MCP Server v2.0 запущен");
1244
+ console.error("SchemeOG MCP Server v2.1 запущен");
489
1245
  }
490
1246
 
491
1247
  main().catch(console.error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "schemeog-mcp",
3
- "version": "2.0.0",
3
+ "version": "2.2.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",