iwgt 2.4.4 → 2.4.6
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "2.0",
|
|
3
|
-
"generatedAt": "2025-10-
|
|
3
|
+
"generatedAt": "2025-10-07T13:07:58.669Z",
|
|
4
4
|
"description": "Справочник по библиотеке common.v2.js для InSales - набор готовых скриптов для разработки шаблонов",
|
|
5
5
|
"installation": {
|
|
6
6
|
"method": "liquid_tag",
|
package/dist/server-http.js
CHANGED
|
@@ -7,6 +7,7 @@ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
|
7
7
|
import { createServer } from 'http';
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
9
|
import { dirname } from 'path';
|
|
10
|
+
import crypto from 'crypto';
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
12
|
const __dirname = dirname(__filename);
|
|
12
13
|
// Импортируем класс WidgetServer
|
|
@@ -16,6 +17,8 @@ const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3000;
|
|
|
16
17
|
const HOST = process.env.HOST || '0.0.0.0';
|
|
17
18
|
// API ключ для аутентификации (опционально)
|
|
18
19
|
const API_KEY = process.env.MCP_API_KEY;
|
|
20
|
+
// Хранилище активных SSE сессий и их транспортов
|
|
21
|
+
const activeSessions = new Map();
|
|
19
22
|
/**
|
|
20
23
|
* Проверка API ключа
|
|
21
24
|
*/
|
|
@@ -55,7 +58,7 @@ const httpServer = createServer(async (req, res) => {
|
|
|
55
58
|
res.end(JSON.stringify({
|
|
56
59
|
status: 'ok',
|
|
57
60
|
service: 'InSales Widgets MCP Server',
|
|
58
|
-
version: '2.4.
|
|
61
|
+
version: '2.4.5',
|
|
59
62
|
transport: 'SSE',
|
|
60
63
|
endpoints: {
|
|
61
64
|
sse: '/sse',
|
|
@@ -69,18 +72,23 @@ const httpServer = createServer(async (req, res) => {
|
|
|
69
72
|
if (req.url === '/sse' && req.method === 'GET') {
|
|
70
73
|
console.log('📡 New SSE connection established');
|
|
71
74
|
try {
|
|
75
|
+
// Генерируем уникальный sessionId
|
|
76
|
+
const sessionId = crypto.randomUUID();
|
|
72
77
|
// Создаем новый MCP сервер для этого соединения
|
|
73
78
|
const widgetServer = new WidgetServer();
|
|
74
|
-
const transport = new SSEServerTransport(
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
const transport = new SSEServerTransport(`/message?sessionId=${sessionId}`, res);
|
|
80
|
+
// Сохраняем сессию
|
|
81
|
+
activeSessions.set(sessionId, { server: widgetServer, transport });
|
|
82
|
+
console.log(`📝 Session created: ${sessionId} (active: ${activeSessions.size})`);
|
|
83
|
+
// Подключаем транспорт через публичный метод
|
|
84
|
+
await widgetServer.connect(transport);
|
|
79
85
|
console.log('✅ MCP server connected via SSE');
|
|
80
86
|
// Обработка закрытия соединения
|
|
81
87
|
req.on('close', () => {
|
|
82
|
-
console.log(
|
|
88
|
+
console.log(`📡 SSE connection closed for session ${sessionId}`);
|
|
89
|
+
activeSessions.delete(sessionId);
|
|
83
90
|
transport.close();
|
|
91
|
+
console.log(`📝 Session deleted: ${sessionId} (active: ${activeSessions.size})`);
|
|
84
92
|
});
|
|
85
93
|
}
|
|
86
94
|
catch (error) {
|
|
@@ -91,23 +99,54 @@ const httpServer = createServer(async (req, res) => {
|
|
|
91
99
|
return;
|
|
92
100
|
}
|
|
93
101
|
// Message endpoint для отправки сообщений
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
// Проверяем, что URL начинается с /message (может быть /message?sessionId=xxx)
|
|
103
|
+
if (req.url?.startsWith('/message') && req.method === 'POST') {
|
|
104
|
+
// Извлекаем sessionId из URL
|
|
105
|
+
const urlObj = new URL(req.url, `http://${req.headers.host}`);
|
|
106
|
+
const sessionId = urlObj.searchParams.get('sessionId');
|
|
107
|
+
if (!sessionId) {
|
|
108
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
109
|
+
res.end(JSON.stringify({ error: 'Missing sessionId' }));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const session = activeSessions.get(sessionId);
|
|
113
|
+
if (!session) {
|
|
114
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
115
|
+
res.end(JSON.stringify({ error: 'Session not found' }));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
// Передаём запрос в SSE транспорт для обработки
|
|
120
|
+
// @ts-ignore - метод может существовать в runtime, но не в типах
|
|
121
|
+
if (typeof session.transport.handlePostMessage === 'function') {
|
|
122
|
+
await session.transport.handlePostMessage(req, res);
|
|
105
123
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
124
|
+
else {
|
|
125
|
+
// Fallback: читаем тело и отправляем ответ вручную
|
|
126
|
+
let body = '';
|
|
127
|
+
req.on('data', (chunk) => {
|
|
128
|
+
body += chunk.toString();
|
|
129
|
+
});
|
|
130
|
+
req.on('end', async () => {
|
|
131
|
+
try {
|
|
132
|
+
const message = JSON.parse(body);
|
|
133
|
+
console.log(`📥 Received POST message:`, message.method || 'unknown');
|
|
134
|
+
// Просто подтверждаем получение
|
|
135
|
+
res.writeHead(202, { 'Content-Type': 'application/json' });
|
|
136
|
+
res.end(JSON.stringify({ status: 'accepted' }));
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
140
|
+
res.end(JSON.stringify({ error: 'Invalid JSON' }));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
109
143
|
}
|
|
110
|
-
}
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
console.error('❌ Error handling POST:', error);
|
|
147
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
148
|
+
res.end(JSON.stringify({ error: 'Internal server error' }));
|
|
149
|
+
}
|
|
111
150
|
return;
|
|
112
151
|
}
|
|
113
152
|
// 404 для неизвестных путей
|
package/dist/server.d.ts
CHANGED
|
@@ -3,6 +3,13 @@ export declare class WidgetServer {
|
|
|
3
3
|
constructor();
|
|
4
4
|
private setupHandlers;
|
|
5
5
|
private createWidget;
|
|
6
|
+
/**
|
|
7
|
+
* Подключить внешний транспорт (например, SSE)
|
|
8
|
+
*/
|
|
9
|
+
connect(transport: any): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Запустить сервер с stdio транспортом
|
|
12
|
+
*/
|
|
6
13
|
run(): Promise<void>;
|
|
7
14
|
}
|
|
8
15
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.js
CHANGED
|
@@ -25,7 +25,7 @@ export class WidgetServer {
|
|
|
25
25
|
constructor() {
|
|
26
26
|
this.server = new Server({
|
|
27
27
|
name: 'insales-widgets',
|
|
28
|
-
version: '2.4.
|
|
28
|
+
version: '2.4.5',
|
|
29
29
|
}, {
|
|
30
30
|
capabilities: {
|
|
31
31
|
tools: {},
|
|
@@ -570,6 +570,15 @@ export class WidgetServer {
|
|
|
570
570
|
],
|
|
571
571
|
};
|
|
572
572
|
}
|
|
573
|
+
/**
|
|
574
|
+
* Подключить внешний транспорт (например, SSE)
|
|
575
|
+
*/
|
|
576
|
+
async connect(transport) {
|
|
577
|
+
await this.server.connect(transport);
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Запустить сервер с stdio транспортом
|
|
581
|
+
*/
|
|
573
582
|
async run() {
|
|
574
583
|
const transport = new StdioServerTransport();
|
|
575
584
|
await this.server.connect(transport);
|