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