schemeog-mcp 2.0.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 +133 -0
  2. package/index.js +491 -0
  3. package/package.json +52 -0
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # SchemeOG MCP Server v2.0
2
+
3
+ MCP сервер для [SchemeOG Cloud](https://scheme.smartlaunchhub.com) — создавай диаграммы и схемы с помощью AI.
4
+
5
+ ## 5 команд — всё что нужно
6
+
7
+ | Команда | Описание |
8
+ |---------|----------|
9
+ | `list_schemas` | Список всех схем |
10
+ | `get_schema` | Получить схему с данными |
11
+ | `create_schema` | Создать новую схему |
12
+ | `replace_schema` | Заменить содержимое схемы |
13
+ | `delete_schema` | Удалить схему |
14
+
15
+ ## Установка
16
+
17
+ ### Через npx (рекомендуется)
18
+
19
+ ```bash
20
+ npx schemeog-cloud-mcp
21
+ ```
22
+
23
+ ## Настройка
24
+
25
+ ### 1. Получи токен
26
+
27
+ 1. Открой https://scheme.smartlaunchhub.com
28
+ 2. Войди по email
29
+ 3. DevTools (F12) → Application → Local Storage
30
+ 4. Скопируй значение `token`
31
+
32
+ ### 2. Добавь в Claude Code / Cline
33
+
34
+ В `~/.claude.json` (или настройки Cline):
35
+
36
+ ```json
37
+ {
38
+ "mcpServers": {
39
+ "schemeog": {
40
+ "command": "npx",
41
+ "args": ["-y", "schemeog-cloud-mcp"],
42
+ "env": {
43
+ "SCHEMEOG_TOKEN": "твой-jwt-токен"
44
+ }
45
+ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ ## Примеры использования
51
+
52
+ ### Создать схему
53
+
54
+ ```
55
+ Создай схему "User Registration Flow" с блоками:
56
+ - Форма регистрации
57
+ - Валидация
58
+ - Сохранение в БД
59
+ - Отправка email
60
+ - Успех
61
+ ```
62
+
63
+ AI сгенерирует:
64
+
65
+ ```json
66
+ {
67
+ "name": "User Registration Flow",
68
+ "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": "Успех"}
74
+ ],
75
+ "connections": [
76
+ {"from": "1", "to": "2"},
77
+ {"from": "2", "to": "3"},
78
+ {"from": "3", "to": "4"},
79
+ {"from": "4", "to": "5"}
80
+ ]
81
+ }
82
+ ```
83
+
84
+ ### Обновить схему
85
+
86
+ ```
87
+ Добавь в схему блок "Обработка ошибок" после валидации
88
+ ```
89
+
90
+ AI получит текущую схему, добавит блок и связи, отправит обновление.
91
+
92
+ ### Посмотреть схемы
93
+
94
+ ```
95
+ Покажи мои схемы
96
+ ```
97
+
98
+ ## Формат данных
99
+
100
+ ### Элемент
101
+
102
+ ```json
103
+ {
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" // цвет фона (опционально)
112
+ }
113
+ ```
114
+
115
+ ### Связь
116
+
117
+ ```json
118
+ {
119
+ "from": "id1", // ID источника
120
+ "to": "id2", // ID назначения
121
+ "label": "текст", // подпись (опционально)
122
+ "style": "solid" // solid, dashed, dotted
123
+ }
124
+ ```
125
+
126
+ ## Ссылки
127
+
128
+ - [SchemeOG Cloud](https://scheme.smartlaunchhub.com)
129
+ - [GitLab](https://gitlab.com/serter2069/schemeog-cloud)
130
+
131
+ ## License
132
+
133
+ MIT
package/index.js ADDED
@@ -0,0 +1,491 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * SchemeOG Cloud MCP Server v2.0
5
+ *
6
+ * Минималистичный MCP сервер для работы со схемами.
7
+ * 5 команд — максимум мощи, минимум сложности.
8
+ *
9
+ * Команды:
10
+ * - list_schemas: Список всех схем
11
+ * - get_schema: Получить схему с данными
12
+ * - create_schema: Создать схему (с элементами и связями)
13
+ * - replace_schema: Полностью заменить содержимое схемы
14
+ * - delete_schema: Удалить схему
15
+ */
16
+
17
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
18
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
19
+ import {
20
+ CallToolRequestSchema,
21
+ ListToolsRequestSchema,
22
+ } from "@modelcontextprotocol/sdk/types.js";
23
+
24
+ // Конфигурация
25
+ const API_BASE_URL = process.env.SCHEMEOG_API_URL || "https://scheme.smartlaunchhub.com";
26
+ const AUTH_TOKEN = process.env.SCHEMEOG_TOKEN || "";
27
+
28
+ /**
29
+ * Выполнить запрос к API SchemeOG
30
+ */
31
+ async function apiRequest(endpoint, options = {}) {
32
+ const url = `${API_BASE_URL}/api${endpoint}`;
33
+
34
+ const headers = {
35
+ "Content-Type": "application/json",
36
+ ...(AUTH_TOKEN && { "Authorization": `Bearer ${AUTH_TOKEN}` }),
37
+ ...options.headers,
38
+ };
39
+
40
+ try {
41
+ const response = await fetch(url, {
42
+ ...options,
43
+ headers,
44
+ });
45
+
46
+ const data = await response.json();
47
+
48
+ if (!response.ok) {
49
+ throw new Error(data.message || data.error || `HTTP ${response.status}`);
50
+ }
51
+
52
+ return data;
53
+ } catch (error) {
54
+ throw new Error(`API Error: ${error.message}`);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Генерация уникального ID для элементов
60
+ */
61
+ function generateId() {
62
+ return `el_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
63
+ }
64
+
65
+ /**
66
+ * Подготовить элементы — добавить ID если нет
67
+ */
68
+ function prepareElements(elements) {
69
+ if (!elements) return [];
70
+ return elements.map(el => ({
71
+ id: el.id || generateId(),
72
+ type: el.type || "block",
73
+ x: el.x || 0,
74
+ y: el.y || 0,
75
+ text: el.text || "",
76
+ ...el
77
+ }));
78
+ }
79
+
80
+ /**
81
+ * Подготовить связи — добавить ID если нет
82
+ */
83
+ function prepareConnections(connections) {
84
+ if (!connections) return [];
85
+ return connections.map(conn => ({
86
+ id: conn.id || generateId(),
87
+ ...conn
88
+ }));
89
+ }
90
+
91
+ /**
92
+ * 5 основных инструментов MCP
93
+ */
94
+ const TOOLS = [
95
+ {
96
+ name: "list_schemas",
97
+ description: `Получить список всех схем пользователя.
98
+
99
+ Возвращает: ID, название, описание, дату обновления каждой схемы.
100
+
101
+ Используй эту команду чтобы узнать какие схемы есть у пользователя.`,
102
+ inputSchema: {
103
+ type: "object",
104
+ properties: {},
105
+ required: [],
106
+ },
107
+ },
108
+ {
109
+ name: "get_schema",
110
+ description: `Получить полные данные схемы по ID.
111
+
112
+ Возвращает:
113
+ - name: название схемы
114
+ - description: описание
115
+ - elements: массив элементов (блоки, заметки, группы)
116
+ - connections: массив связей между элементами
117
+
118
+ Каждый элемент содержит: id, type, x, y, text, width, height, color
119
+ Каждая связь содержит: id, from, to, label, style`,
120
+ inputSchema: {
121
+ type: "object",
122
+ properties: {
123
+ schema_id: {
124
+ type: "string",
125
+ description: "ID схемы (UUID)",
126
+ },
127
+ },
128
+ required: ["schema_id"],
129
+ },
130
+ },
131
+ {
132
+ name: "create_schema",
133
+ description: `Создать новую схему с элементами и связями.
134
+
135
+ ВАЖНО: Генерируй сразу полную схему с elements и connections!
136
+
137
+ Параметры:
138
+ - name: название схемы (обязательно)
139
+ - description: описание
140
+ - elements: массив элементов
141
+ - connections: массив связей
142
+
143
+ Формат элемента:
144
+ {
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" // цвет фона (опционально)
153
+ }
154
+
155
+ Формат связи:
156
+ {
157
+ "from": "node1", // ID элемента-источника
158
+ "to": "node2", // ID элемента-назначения
159
+ "label": "подпись", // текст на связи (опционально)
160
+ "style": "solid" // solid, dashed, dotted (опционально)
161
+ }
162
+
163
+ Пример: создать схему с 3 блоками и 2 связями:
164
+ {
165
+ "name": "User Flow",
166
+ "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"}
170
+ ],
171
+ "connections": [
172
+ {"from": "1", "to": "2", "label": "success"},
173
+ {"from": "2", "to": "3"}
174
+ ]
175
+ }`,
176
+ inputSchema: {
177
+ type: "object",
178
+ properties: {
179
+ name: {
180
+ type: "string",
181
+ description: "Название схемы",
182
+ },
183
+ description: {
184
+ type: "string",
185
+ description: "Описание схемы",
186
+ },
187
+ elements: {
188
+ type: "array",
189
+ description: "Массив элементов схемы",
190
+ items: {
191
+ type: "object",
192
+ properties: {
193
+ 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" },
201
+ },
202
+ },
203
+ },
204
+ connections: {
205
+ type: "array",
206
+ description: "Массив связей между элементами",
207
+ items: {
208
+ type: "object",
209
+ properties: {
210
+ from: { type: "string" },
211
+ to: { type: "string" },
212
+ label: { type: "string" },
213
+ style: { type: "string", enum: ["solid", "dashed", "dotted"] },
214
+ },
215
+ required: ["from", "to"],
216
+ },
217
+ },
218
+ },
219
+ required: ["name"],
220
+ },
221
+ },
222
+ {
223
+ name: "replace_schema",
224
+ description: `Полностью заменить содержимое существующей схемы.
225
+
226
+ Используй когда нужно:
227
+ - Обновить схему новыми данными
228
+ - Добавить/удалить элементы
229
+ - Изменить связи
230
+
231
+ ВАЖНО: Эта команда ЗАМЕНЯЕТ все данные схемы!
232
+ Сначала получи текущую схему через get_schema,
233
+ модифицируй данные, затем отправь через replace_schema.
234
+
235
+ Параметры:
236
+ - schema_id: ID схемы (обязательно)
237
+ - name: новое название (опционально)
238
+ - description: новое описание (опционально)
239
+ - elements: новый массив элементов (опционально)
240
+ - connections: новый массив связей (опционально)
241
+
242
+ Если elements или connections не указаны - они останутся прежними.`,
243
+ inputSchema: {
244
+ type: "object",
245
+ properties: {
246
+ schema_id: {
247
+ type: "string",
248
+ description: "ID схемы для обновления",
249
+ },
250
+ name: {
251
+ type: "string",
252
+ description: "Новое название схемы",
253
+ },
254
+ description: {
255
+ type: "string",
256
+ description: "Новое описание схемы",
257
+ },
258
+ elements: {
259
+ type: "array",
260
+ description: "Новый массив элементов (заменяет все существующие)",
261
+ items: { type: "object" },
262
+ },
263
+ connections: {
264
+ type: "array",
265
+ description: "Новый массив связей (заменяет все существующие)",
266
+ items: { type: "object" },
267
+ },
268
+ },
269
+ required: ["schema_id"],
270
+ },
271
+ },
272
+ {
273
+ name: "delete_schema",
274
+ description: `Удалить схему по ID.
275
+
276
+ ВНИМАНИЕ: Это действие необратимо! Схема будет удалена навсегда.`,
277
+ inputSchema: {
278
+ type: "object",
279
+ properties: {
280
+ schema_id: {
281
+ type: "string",
282
+ description: "ID схемы для удаления",
283
+ },
284
+ },
285
+ required: ["schema_id"],
286
+ },
287
+ },
288
+ ];
289
+
290
+ /**
291
+ * Обработчики инструментов
292
+ */
293
+ async function handleTool(name, args) {
294
+ switch (name) {
295
+ // ========== LIST SCHEMAS ==========
296
+ case "list_schemas": {
297
+ const result = await apiRequest("/schemas");
298
+
299
+ if (!result.schemas || result.schemas.length === 0) {
300
+ return {
301
+ content: [{
302
+ type: "text",
303
+ text: "Схемы не найдены.\n\nСоздай первую схему с помощью create_schema.",
304
+ }],
305
+ };
306
+ }
307
+
308
+ const schemasList = result.schemas.map(s => ({
309
+ id: s.id,
310
+ name: s.name,
311
+ description: s.description || "",
312
+ updatedAt: s.updatedAt,
313
+ elementsCount: s.data?.elements?.length || 0,
314
+ connectionsCount: s.data?.connections?.length || 0,
315
+ }));
316
+
317
+ return {
318
+ content: [{
319
+ type: "text",
320
+ text: `Найдено ${schemasList.length} схем:\n\n${JSON.stringify(schemasList, null, 2)}`,
321
+ }],
322
+ };
323
+ }
324
+
325
+ // ========== GET SCHEMA ==========
326
+ case "get_schema": {
327
+ const { schema_id } = args;
328
+ const result = await apiRequest(`/schemas/${schema_id}`);
329
+
330
+ const schema = result.schema;
331
+
332
+ return {
333
+ content: [{
334
+ type: "text",
335
+ text: `Схема "${schema.name}"
336
+
337
+ ID: ${schema.id}
338
+ Описание: ${schema.description || "(нет)"}
339
+ Элементов: ${schema.data?.elements?.length || 0}
340
+ Связей: ${schema.data?.connections?.length || 0}
341
+ URL: ${API_BASE_URL}/canvas?id=${schema.id}
342
+
343
+ Элементы:
344
+ ${JSON.stringify(schema.data?.elements || [], null, 2)}
345
+
346
+ Связи:
347
+ ${JSON.stringify(schema.data?.connections || [], null, 2)}`,
348
+ }],
349
+ };
350
+ }
351
+
352
+ // ========== CREATE SCHEMA ==========
353
+ case "create_schema": {
354
+ const { name, description, elements, connections } = args;
355
+
356
+ const data = {
357
+ elements: prepareElements(elements),
358
+ connections: prepareConnections(connections),
359
+ tagsDictionary: [],
360
+ };
361
+
362
+ const result = await apiRequest("/schemas", {
363
+ method: "POST",
364
+ body: JSON.stringify({ name, description, data }),
365
+ });
366
+
367
+ return {
368
+ content: [{
369
+ type: "text",
370
+ text: `Схема "${result.schema.name}" создана!
371
+
372
+ ID: ${result.schema.id}
373
+ Элементов: ${data.elements.length}
374
+ Связей: ${data.connections.length}
375
+
376
+ URL: ${API_BASE_URL}/canvas?id=${result.schema.id}
377
+
378
+ Открой ссылку в браузере чтобы увидеть схему.`,
379
+ }],
380
+ };
381
+ }
382
+
383
+ // ========== REPLACE SCHEMA ==========
384
+ case "replace_schema": {
385
+ const { schema_id, name, description, elements, connections } = args;
386
+
387
+ // Получаем текущую схему
388
+ const currentResult = await apiRequest(`/schemas/${schema_id}`);
389
+ const currentSchema = currentResult.schema;
390
+ const currentData = currentSchema.data || { elements: [], connections: [], tagsDictionary: [] };
391
+
392
+ // Формируем обновление
393
+ const updateBody = {};
394
+
395
+ if (name) updateBody.name = name;
396
+ if (description !== undefined) updateBody.description = description;
397
+
398
+ // Обновляем данные только если переданы
399
+ const newData = { ...currentData };
400
+ if (elements !== undefined) {
401
+ newData.elements = prepareElements(elements);
402
+ }
403
+ if (connections !== undefined) {
404
+ newData.connections = prepareConnections(connections);
405
+ }
406
+ updateBody.data = newData;
407
+
408
+ const result = await apiRequest(`/schemas/${schema_id}`, {
409
+ method: "PUT",
410
+ body: JSON.stringify(updateBody),
411
+ });
412
+
413
+ return {
414
+ content: [{
415
+ type: "text",
416
+ text: `Схема "${result.schema.name}" обновлена!
417
+
418
+ Элементов: ${result.schema.data?.elements?.length || 0}
419
+ Связей: ${result.schema.data?.connections?.length || 0}
420
+
421
+ URL: ${API_BASE_URL}/canvas?id=${schema_id}`,
422
+ }],
423
+ };
424
+ }
425
+
426
+ // ========== DELETE SCHEMA ==========
427
+ case "delete_schema": {
428
+ const { schema_id } = args;
429
+
430
+ await apiRequest(`/schemas/${schema_id}`, {
431
+ method: "DELETE",
432
+ });
433
+
434
+ return {
435
+ content: [{
436
+ type: "text",
437
+ text: `Схема удалена.`,
438
+ }],
439
+ };
440
+ }
441
+
442
+ default:
443
+ throw new Error(`Неизвестная команда: ${name}`);
444
+ }
445
+ }
446
+
447
+ /**
448
+ * Запуск MCP сервера
449
+ */
450
+ async function main() {
451
+ if (!AUTH_TOKEN) {
452
+ console.error("⚠️ SCHEMEOG_TOKEN не установлен. Укажите токен в переменной окружения.");
453
+ }
454
+
455
+ const server = new Server(
456
+ {
457
+ name: "schemeog-mcp",
458
+ version: "2.0.0",
459
+ },
460
+ {
461
+ capabilities: {
462
+ tools: {},
463
+ },
464
+ }
465
+ );
466
+
467
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
468
+ return { tools: TOOLS };
469
+ });
470
+
471
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
472
+ try {
473
+ return await handleTool(request.params.name, request.params.arguments || {});
474
+ } catch (error) {
475
+ return {
476
+ content: [{
477
+ type: "text",
478
+ text: `Ошибка: ${error.message}`,
479
+ }],
480
+ isError: true,
481
+ };
482
+ }
483
+ });
484
+
485
+ const transport = new StdioServerTransport();
486
+ await server.connect(transport);
487
+
488
+ console.error("SchemeOG MCP Server v2.0 запущен");
489
+ }
490
+
491
+ main().catch(console.error);
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "schemeog-mcp",
3
+ "version": "2.0.0",
4
+ "description": "MCP Server for SchemeOG Cloud - Create and manage visual diagrams and flowcharts with AI assistance",
5
+ "type": "module",
6
+ "main": "index.js",
7
+ "bin": {
8
+ "schemeog-mcp": "./index.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node index.js",
12
+ "prepublishOnly": "echo 'Ready to publish'"
13
+ },
14
+ "keywords": [
15
+ "mcp",
16
+ "model-context-protocol",
17
+ "claude",
18
+ "anthropic",
19
+ "ai",
20
+ "diagrams",
21
+ "flowcharts",
22
+ "schemas",
23
+ "visualization",
24
+ "schemeog"
25
+ ],
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://gitlab.com/serter2069/schemeog-cloud.git"
29
+ },
30
+ "homepage": "https://scheme.smartlaunchhub.com",
31
+ "bugs": {
32
+ "url": "https://gitlab.com/serter2069/schemeog-cloud/-/issues"
33
+ },
34
+ "dependencies": {
35
+ "@modelcontextprotocol/sdk": "^1.0.0"
36
+ },
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ },
40
+ "files": [
41
+ "index.js",
42
+ "README.md"
43
+ ],
44
+ "author": {
45
+ "name": "Sergei Terekhov",
46
+ "email": "serter2069@gmail.com"
47
+ },
48
+ "license": "MIT",
49
+ "publishConfig": {
50
+ "access": "public"
51
+ }
52
+ }