@alsania-io/mcpnyx 0.0.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 (98) hide show
  1. package/README.md +251 -0
  2. package/dist/gateways/configToSse.d.ts +16 -0
  3. package/dist/gateways/configToSse.d.ts.map +1 -0
  4. package/dist/gateways/configToSse.js +144 -0
  5. package/dist/gateways/configToSse.js.map +1 -0
  6. package/dist/gateways/configToStreamableHttp.d.ts +16 -0
  7. package/dist/gateways/configToStreamableHttp.d.ts.map +1 -0
  8. package/dist/gateways/configToStreamableHttp.js +287 -0
  9. package/dist/gateways/configToStreamableHttp.js.map +1 -0
  10. package/dist/gateways/configToWs.d.ts +14 -0
  11. package/dist/gateways/configToWs.d.ts.map +1 -0
  12. package/dist/gateways/configToWs.js +145 -0
  13. package/dist/gateways/configToWs.js.map +1 -0
  14. package/dist/gateways/sseToSse.d.ts +16 -0
  15. package/dist/gateways/sseToSse.d.ts.map +1 -0
  16. package/dist/gateways/sseToSse.js +224 -0
  17. package/dist/gateways/sseToSse.js.map +1 -0
  18. package/dist/gateways/sseToStdio.d.ts +8 -0
  19. package/dist/gateways/sseToStdio.d.ts.map +1 -0
  20. package/dist/gateways/sseToStdio.js +130 -0
  21. package/dist/gateways/sseToStdio.js.map +1 -0
  22. package/dist/gateways/sseToWs.d.ts +14 -0
  23. package/dist/gateways/sseToWs.d.ts.map +1 -0
  24. package/dist/gateways/sseToWs.js +212 -0
  25. package/dist/gateways/sseToWs.js.map +1 -0
  26. package/dist/gateways/stdioToSse.d.ts +16 -0
  27. package/dist/gateways/stdioToSse.d.ts.map +1 -0
  28. package/dist/gateways/stdioToSse.js +134 -0
  29. package/dist/gateways/stdioToSse.js.map +1 -0
  30. package/dist/gateways/stdioToStatefulStreamableHttp.d.ts +15 -0
  31. package/dist/gateways/stdioToStatefulStreamableHttp.d.ts.map +1 -0
  32. package/dist/gateways/stdioToStatefulStreamableHttp.js +189 -0
  33. package/dist/gateways/stdioToStatefulStreamableHttp.js.map +1 -0
  34. package/dist/gateways/stdioToStatelessStreamableHttp.d.ts +14 -0
  35. package/dist/gateways/stdioToStatelessStreamableHttp.d.ts.map +1 -0
  36. package/dist/gateways/stdioToStatelessStreamableHttp.js +132 -0
  37. package/dist/gateways/stdioToStatelessStreamableHttp.js.map +1 -0
  38. package/dist/gateways/stdioToWs.d.ts +13 -0
  39. package/dist/gateways/stdioToWs.d.ts.map +1 -0
  40. package/dist/gateways/stdioToWs.js +115 -0
  41. package/dist/gateways/stdioToWs.js.map +1 -0
  42. package/dist/gateways/streamableHttpToSse.d.ts +16 -0
  43. package/dist/gateways/streamableHttpToSse.d.ts.map +1 -0
  44. package/dist/gateways/streamableHttpToSse.js +219 -0
  45. package/dist/gateways/streamableHttpToSse.js.map +1 -0
  46. package/dist/gateways/streamableHttpToStdio.d.ts +8 -0
  47. package/dist/gateways/streamableHttpToStdio.d.ts.map +1 -0
  48. package/dist/gateways/streamableHttpToStdio.js +124 -0
  49. package/dist/gateways/streamableHttpToStdio.js.map +1 -0
  50. package/dist/index.d.ts +46 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +424 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/lib/config.d.ts +78 -0
  55. package/dist/lib/config.d.ts.map +1 -0
  56. package/dist/lib/config.js +59 -0
  57. package/dist/lib/config.js.map +1 -0
  58. package/dist/lib/corsOrigin.d.ts +6 -0
  59. package/dist/lib/corsOrigin.d.ts.map +1 -0
  60. package/dist/lib/corsOrigin.js +24 -0
  61. package/dist/lib/corsOrigin.js.map +1 -0
  62. package/dist/lib/getLogger.d.ts +6 -0
  63. package/dist/lib/getLogger.d.ts.map +1 -0
  64. package/dist/lib/getLogger.js +55 -0
  65. package/dist/lib/getLogger.js.map +1 -0
  66. package/dist/lib/getVersion.d.ts +2 -0
  67. package/dist/lib/getVersion.d.ts.map +1 -0
  68. package/dist/lib/getVersion.js +17 -0
  69. package/dist/lib/getVersion.js.map +1 -0
  70. package/dist/lib/headers.d.ts +9 -0
  71. package/dist/lib/headers.d.ts.map +1 -0
  72. package/dist/lib/headers.js +32 -0
  73. package/dist/lib/headers.js.map +1 -0
  74. package/dist/lib/mcpServerManager.d.ts +24 -0
  75. package/dist/lib/mcpServerManager.d.ts.map +1 -0
  76. package/dist/lib/mcpServerManager.js +347 -0
  77. package/dist/lib/mcpServerManager.js.map +1 -0
  78. package/dist/lib/onSignals.d.ts +14 -0
  79. package/dist/lib/onSignals.d.ts.map +1 -0
  80. package/dist/lib/onSignals.js +28 -0
  81. package/dist/lib/onSignals.js.map +1 -0
  82. package/dist/lib/serializeCorsOrigin.d.ts +5 -0
  83. package/dist/lib/serializeCorsOrigin.d.ts.map +1 -0
  84. package/dist/lib/serializeCorsOrigin.js +7 -0
  85. package/dist/lib/serializeCorsOrigin.js.map +1 -0
  86. package/dist/lib/sessionAccessCounter.d.ts +12 -0
  87. package/dist/lib/sessionAccessCounter.d.ts.map +1 -0
  88. package/dist/lib/sessionAccessCounter.js +78 -0
  89. package/dist/lib/sessionAccessCounter.js.map +1 -0
  90. package/dist/server/websocket.d.ts +22 -0
  91. package/dist/server/websocket.d.ts.map +1 -0
  92. package/dist/server/websocket.js +103 -0
  93. package/dist/server/websocket.js.map +1 -0
  94. package/dist/types.d.ts +7 -0
  95. package/dist/types.d.ts.map +1 -0
  96. package/dist/types.js +2 -0
  97. package/dist/types.js.map +1 -0
  98. package/package.json +95 -0
@@ -0,0 +1,287 @@
1
+ import express from 'express';
2
+ import cors from 'cors';
3
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
5
+ import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
6
+ import { getVersion } from '../lib/getVersion.js';
7
+ import { onSignals } from '../lib/onSignals.js';
8
+ import { serializeCorsOrigin } from '../lib/serializeCorsOrigin.js';
9
+ import { loadConfig } from '../lib/config.js';
10
+ import { McpServerManager } from '../lib/mcpServerManager.js';
11
+ import { randomUUID } from 'node:crypto';
12
+ import { SessionAccessCounter } from '../lib/sessionAccessCounter.js';
13
+ const setResponseHeaders = ({ res, headers }) => Object.entries(headers).forEach(([key, value]) => {
14
+ res.setHeader(key, value);
15
+ });
16
+ export async function configToStreamableHttp(args) {
17
+ const { configPath, port, host, streamableHttpPath, logger, corsOrigin, healthEndpoints, headers, stateless = false, sessionTimeout, } = args;
18
+ logger.info(` - config: ${configPath}`);
19
+ logger.info(` - Headers: ${Object.keys(headers).length ? JSON.stringify(headers) : '(none)'}`);
20
+ logger.info(` - host: ${host}`);
21
+ logger.info(` - port: ${port}`);
22
+ logger.info(` - streamableHttpPath: ${streamableHttpPath}`);
23
+ logger.info(` - stateless: ${stateless}`);
24
+ logger.info(` - CORS: ${corsOrigin ? `enabled (${serializeCorsOrigin({ corsOrigin })})` : 'disabled'}`);
25
+ logger.info(` - Health endpoints: ${healthEndpoints.length ? healthEndpoints.join(', ') : '(none)'}`);
26
+ if (!stateless && sessionTimeout) {
27
+ logger.info(` - Session timeout: ${sessionTimeout}ms`);
28
+ }
29
+ const serverManager = new McpServerManager(logger);
30
+ const cleanup = async () => {
31
+ await serverManager.cleanup();
32
+ };
33
+ onSignals({ logger, cleanup });
34
+ let config;
35
+ try {
36
+ config = loadConfig(configPath);
37
+ logger.info(`Loaded config with ${Object.keys(config.mcpServers).length} servers`);
38
+ }
39
+ catch (err) {
40
+ logger.error(`Failed to load config: ${err}`);
41
+ process.exit(1);
42
+ }
43
+ for (const [serverName, serverConfig] of Object.entries(config.mcpServers)) {
44
+ try {
45
+ await serverManager.addServer(serverName, serverConfig);
46
+ logger.info(`Successfully initialized server: ${serverName}`);
47
+ }
48
+ catch (err) {
49
+ logger.error(`Failed to initialize server ${serverName}: ${err}`);
50
+ process.exit(1);
51
+ }
52
+ }
53
+ const app = express();
54
+ app.use(express.json());
55
+ if (corsOrigin) {
56
+ app.use(cors({
57
+ origin: corsOrigin,
58
+ exposedHeaders: stateless ? [] : ['Mcp-Session-Id'],
59
+ }));
60
+ }
61
+ for (const ep of healthEndpoints) {
62
+ app.get(ep, (_req, res) => {
63
+ setResponseHeaders({
64
+ res,
65
+ headers,
66
+ });
67
+ res.send('ok');
68
+ });
69
+ }
70
+ if (stateless) {
71
+ // Stateless mode - create new transport for each request
72
+ app.post(streamableHttpPath, async (req, res) => {
73
+ logger.info('Received stateless StreamableHttp request');
74
+ setResponseHeaders({
75
+ res,
76
+ headers,
77
+ });
78
+ try {
79
+ const server = new Server({ name: 'mcp-nyx', version: getVersion() }, { capabilities: {} });
80
+ const transport = new StreamableHTTPServerTransport({
81
+ sessionIdGenerator: undefined,
82
+ });
83
+ await server.connect(transport);
84
+ transport.onmessage = async (msg) => {
85
+ logger.info(`StreamableHttp → Servers: ${JSON.stringify(msg)}`);
86
+ if ('method' in msg && 'id' in msg) {
87
+ try {
88
+ const response = await serverManager.handleRequest(msg);
89
+ logger.info('Servers → StreamableHttp:');
90
+ logger.debug('Servers → StreamableHttp:', response);
91
+ transport.send(response);
92
+ }
93
+ catch (err) {
94
+ logger.error('Error handling request:', err);
95
+ const errorResponse = {
96
+ jsonrpc: '2.0',
97
+ id: msg.id,
98
+ error: {
99
+ code: -32000,
100
+ message: 'Internal error',
101
+ },
102
+ };
103
+ transport.send(errorResponse);
104
+ }
105
+ }
106
+ };
107
+ transport.onclose = () => {
108
+ logger.info('StreamableHttp connection closed');
109
+ };
110
+ transport.onerror = (err) => {
111
+ logger.error('StreamableHttp error:', err);
112
+ };
113
+ await transport.handleRequest(req, res, req.body);
114
+ }
115
+ catch (error) {
116
+ logger.error('Error handling MCP request:', error);
117
+ if (!res.headersSent) {
118
+ res.status(500).json({
119
+ jsonrpc: '2.0',
120
+ error: {
121
+ code: -32603,
122
+ message: 'Internal server error',
123
+ },
124
+ id: null,
125
+ });
126
+ }
127
+ }
128
+ });
129
+ // Stateless mode doesn't support GET/DELETE
130
+ app.get(streamableHttpPath, async (req, res) => {
131
+ setResponseHeaders({ res, headers });
132
+ res.status(405).json({
133
+ jsonrpc: '2.0',
134
+ error: {
135
+ code: -32000,
136
+ message: 'Method not allowed in stateless mode',
137
+ },
138
+ id: null,
139
+ });
140
+ });
141
+ app.delete(streamableHttpPath, async (req, res) => {
142
+ setResponseHeaders({ res, headers });
143
+ res.status(405).json({
144
+ jsonrpc: '2.0',
145
+ error: {
146
+ code: -32000,
147
+ message: 'Method not allowed in stateless mode',
148
+ },
149
+ id: null,
150
+ });
151
+ });
152
+ }
153
+ else {
154
+ // Stateful mode - maintain sessions
155
+ const transports = {};
156
+ const sessionCounter = sessionTimeout
157
+ ? new SessionAccessCounter(sessionTimeout, (sessionId) => {
158
+ logger.info(`Session ${sessionId} timed out, cleaning up`);
159
+ const transport = transports[sessionId];
160
+ if (transport) {
161
+ transport.close();
162
+ }
163
+ delete transports[sessionId];
164
+ }, logger)
165
+ : null;
166
+ app.post(streamableHttpPath, async (req, res) => {
167
+ const sessionId = req.headers['mcp-session-id'];
168
+ let transport;
169
+ setResponseHeaders({
170
+ res,
171
+ headers,
172
+ });
173
+ if (sessionId && transports[sessionId]) {
174
+ // Reuse existing transport
175
+ transport = transports[sessionId];
176
+ sessionCounter?.inc(sessionId, 'POST request for existing session');
177
+ }
178
+ else if (!sessionId && isInitializeRequest(req.body)) {
179
+ // New initialization request
180
+ const server = new Server({ name: 'mcp-nyx', version: getVersion() }, { capabilities: {} });
181
+ transport = new StreamableHTTPServerTransport({
182
+ sessionIdGenerator: () => randomUUID(),
183
+ onsessioninitialized: (sessionId) => {
184
+ transports[sessionId] = transport;
185
+ sessionCounter?.inc(sessionId, 'session initialization');
186
+ },
187
+ });
188
+ await server.connect(transport);
189
+ transport.onmessage = async (msg) => {
190
+ logger.info(`StreamableHttp → Servers (session ${sessionId}): ${JSON.stringify(msg)}`);
191
+ if ('method' in msg && 'id' in msg) {
192
+ try {
193
+ const response = await serverManager.handleRequest(msg);
194
+ logger.info(`Servers → StreamableHttp (session ${sessionId}):`);
195
+ logger.debug(`Servers → StreamableHttp (session ${sessionId}):`, response);
196
+ transport.send(response);
197
+ }
198
+ catch (err) {
199
+ logger.error(`Error handling request in session ${sessionId}:`, err);
200
+ const errorResponse = {
201
+ jsonrpc: '2.0',
202
+ id: msg.id,
203
+ error: {
204
+ code: -32000,
205
+ message: 'Internal error',
206
+ },
207
+ };
208
+ transport.send(errorResponse);
209
+ }
210
+ }
211
+ };
212
+ transport.onclose = () => {
213
+ logger.info(`StreamableHttp connection closed (session ${sessionId})`);
214
+ if (transport.sessionId) {
215
+ sessionCounter?.clear(transport.sessionId, false, 'transport being closed');
216
+ delete transports[transport.sessionId];
217
+ }
218
+ };
219
+ transport.onerror = (err) => {
220
+ logger.error(`StreamableHttp error (session ${sessionId}):`, err);
221
+ if (transport.sessionId) {
222
+ sessionCounter?.clear(transport.sessionId, false, 'transport emitting error');
223
+ delete transports[transport.sessionId];
224
+ }
225
+ };
226
+ }
227
+ else {
228
+ // Invalid request
229
+ res.status(400).json({
230
+ jsonrpc: '2.0',
231
+ error: {
232
+ code: -32000,
233
+ message: 'Bad Request: No valid session ID provided',
234
+ },
235
+ id: null,
236
+ });
237
+ return;
238
+ }
239
+ // Decrement session access count when response ends
240
+ let responseEnded = false;
241
+ const handleResponseEnd = (event) => {
242
+ if (!responseEnded && transport.sessionId) {
243
+ responseEnded = true;
244
+ logger.info(`Response ${event}`, transport.sessionId);
245
+ sessionCounter?.dec(transport.sessionId, `POST response ${event}`);
246
+ }
247
+ };
248
+ res.on('finish', () => handleResponseEnd('finished'));
249
+ res.on('close', () => handleResponseEnd('closed'));
250
+ await transport.handleRequest(req, res, req.body);
251
+ });
252
+ // Reusable handler for GET and DELETE requests in stateful mode
253
+ const handleSessionRequest = async (req, res) => {
254
+ const sessionId = req.headers['mcp-session-id'];
255
+ setResponseHeaders({
256
+ res,
257
+ headers,
258
+ });
259
+ if (!sessionId || !transports[sessionId]) {
260
+ res.status(400).send('Invalid or missing session ID');
261
+ return;
262
+ }
263
+ sessionCounter?.inc(sessionId, `${req.method} request for existing session`);
264
+ let responseEnded = false;
265
+ const handleResponseEnd = (event) => {
266
+ if (!responseEnded) {
267
+ responseEnded = true;
268
+ logger.info(`Response ${event}`, sessionId);
269
+ sessionCounter?.dec(sessionId, `${req.method} response ${event}`);
270
+ }
271
+ };
272
+ res.on('finish', () => handleResponseEnd('finished'));
273
+ res.on('close', () => handleResponseEnd('closed'));
274
+ const transport = transports[sessionId];
275
+ await transport.handleRequest(req, res);
276
+ };
277
+ app.get(streamableHttpPath, handleSessionRequest);
278
+ app.delete(streamableHttpPath, handleSessionRequest);
279
+ }
280
+ app.listen(port, host, () => {
281
+ logger.info(`Listening on ${host}:${port}`);
282
+ logger.info(`StreamableHttp endpoint: http://${host}:${port}${streamableHttpPath}`);
283
+ logger.info(`Mode: ${stateless ? 'stateless' : 'stateful'}`);
284
+ });
285
+ logger.info('Config-to-StreamableHttp gateway ready');
286
+ }
287
+ //# sourceMappingURL=configToStreamableHttp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configToStreamableHttp.js","sourceRoot":"","sources":["../../src/gateways/configToStreamableHttp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type CorsOptions } from 'cors';
2
+ import { Logger } from '../types.js';
3
+ export interface ConfigToWsArgs {
4
+ configPath: string;
5
+ port: number;
6
+ host: string;
7
+ messagePath: string;
8
+ logger: Logger;
9
+ corsOrigin: CorsOptions['origin'];
10
+ healthEndpoints: string[];
11
+ headers: Record<string, string>;
12
+ }
13
+ export declare function configToWs(args: ConfigToWsArgs): Promise<void>;
14
+ //# sourceMappingURL=configToWs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configToWs.d.ts","sourceRoot":"","sources":["../../src/gateways/configToWs.ts"],"names":[],"mappings":"AACA,OAAa,EAAE,KAAK,WAAW,EAAE,MAAM,MAAM,CAAC;AAI9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAClC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAOD,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,iBAmJpD"}
@@ -0,0 +1,145 @@
1
+ import express from 'express';
2
+ import cors from 'cors';
3
+ import { createServer } from 'http';
4
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
5
+ import { getVersion } from '../lib/getVersion.js';
6
+ import { WebSocketServerTransport } from '../server/websocket.js';
7
+ import { onSignals } from '../lib/onSignals.js';
8
+ import { serializeCorsOrigin } from '../lib/serializeCorsOrigin.js';
9
+ import { loadConfig } from '../lib/config.js';
10
+ import { McpServerManager } from '../lib/mcpServerManager.js';
11
+ const setResponseHeaders = ({ res, headers }) => Object.entries(headers).forEach(([key, value]) => {
12
+ res.setHeader(key, value);
13
+ });
14
+ export async function configToWs(args) {
15
+ const { configPath, port, host, messagePath, logger, corsOrigin, healthEndpoints, headers } = args;
16
+ logger.info(` - config: ${configPath}`);
17
+ logger.info(` - Headers: ${Object.keys(headers).length ? JSON.stringify(headers) : '(none)'}`);
18
+ logger.info(` - host: ${host}`);
19
+ logger.info(` - port: ${port}`);
20
+ logger.info(` - messagePath: ${messagePath}`);
21
+ logger.info(` - CORS: ${corsOrigin ? `enabled (${serializeCorsOrigin({ corsOrigin })})` : 'disabled'}`);
22
+ logger.info(` - Health endpoints: ${healthEndpoints.length ? healthEndpoints.join(', ') : '(none)'}`);
23
+ const serverManager = new McpServerManager(logger);
24
+ let wsTransport = null;
25
+ let isReady = false;
26
+ const cleanup = async () => {
27
+ await serverManager.cleanup();
28
+ if (wsTransport) {
29
+ wsTransport.close().catch((err) => {
30
+ logger.error(`Error stopping WebSocket server: ${err.message}`);
31
+ });
32
+ }
33
+ };
34
+ onSignals({ logger, cleanup });
35
+ let config;
36
+ try {
37
+ config = loadConfig(configPath);
38
+ logger.info(`Loaded config with ${Object.keys(config.mcpServers).length} servers`);
39
+ }
40
+ catch (err) {
41
+ logger.error(`Failed to load config: ${err}`);
42
+ process.exit(1);
43
+ }
44
+ for (const [serverName, serverConfig] of Object.entries(config.mcpServers)) {
45
+ try {
46
+ await serverManager.addServer(serverName, serverConfig);
47
+ logger.info(`Successfully initialized server: ${serverName}`);
48
+ }
49
+ catch (err) {
50
+ logger.error(`Failed to initialize server ${serverName}: ${err}`);
51
+ process.exit(1);
52
+ }
53
+ }
54
+ try {
55
+ const server = new Server({ name: 'mcp-nyx', version: getVersion() }, { capabilities: {} });
56
+ const app = express();
57
+ if (corsOrigin) {
58
+ app.use(cors({ origin: corsOrigin }));
59
+ }
60
+ for (const ep of healthEndpoints) {
61
+ app.get(ep, (_req, res) => {
62
+ setResponseHeaders({
63
+ res,
64
+ headers,
65
+ });
66
+ if (!isReady) {
67
+ res.status(500).send('Server is not ready');
68
+ }
69
+ else {
70
+ res.send('ok');
71
+ }
72
+ });
73
+ }
74
+ const httpServer = createServer(app);
75
+ wsTransport = new WebSocketServerTransport({
76
+ path: messagePath,
77
+ server: httpServer,
78
+ });
79
+ await server.connect(wsTransport);
80
+ wsTransport.onmessage = async (message) => {
81
+ // Extract client ID from the modified message ID
82
+ const messageId = message.id;
83
+ let clientId;
84
+ let originalId;
85
+ if (typeof messageId === 'string' && messageId.includes(':')) {
86
+ const parts = messageId.split(':');
87
+ clientId = parts[0];
88
+ originalId = parts.slice(1).join(':');
89
+ // Restore original ID for the request
90
+ message.id = isNaN(Number(originalId)) ? originalId : Number(originalId);
91
+ }
92
+ const isRequest = 'method' in message && 'id' in message;
93
+ if (isRequest) {
94
+ logger.info(`WebSocket → Servers (client ${clientId}):`, message);
95
+ try {
96
+ const response = await serverManager.handleRequest(message);
97
+ logger.info(`Servers → WebSocket (client ${clientId}):`);
98
+ logger.debug(`Servers → WebSocket (client ${clientId}):`, response);
99
+ await wsTransport.send(response, clientId);
100
+ }
101
+ catch (err) {
102
+ logger.error(`Error handling request from client ${clientId}:`, err);
103
+ const errorResponse = {
104
+ jsonrpc: '2.0',
105
+ id: message.id,
106
+ error: {
107
+ code: -32000,
108
+ message: 'Internal error',
109
+ },
110
+ };
111
+ try {
112
+ await wsTransport.send(errorResponse, clientId);
113
+ }
114
+ catch (sendErr) {
115
+ logger.error(`Failed to send error response to client ${clientId}:`, sendErr);
116
+ }
117
+ }
118
+ }
119
+ else {
120
+ logger.info(`Notification from client ${clientId}:`, message);
121
+ }
122
+ };
123
+ wsTransport.onconnection = (clientId) => {
124
+ logger.info(`New WebSocket connection: ${clientId}`);
125
+ };
126
+ wsTransport.ondisconnection = (clientId) => {
127
+ logger.info(`WebSocket connection closed: ${clientId}`);
128
+ };
129
+ wsTransport.onerror = (err) => {
130
+ logger.error(`WebSocket error: ${err.message}`);
131
+ };
132
+ isReady = true;
133
+ httpServer.listen(port, host, () => {
134
+ logger.info(`Listening on ${host}:${port}`);
135
+ logger.info(`WebSocket endpoint: ws://${host}:${port}${messagePath}`);
136
+ });
137
+ logger.info('Config-to-WebSocket gateway ready');
138
+ }
139
+ catch (err) {
140
+ logger.error(`Failed to start: ${err.message}`);
141
+ cleanup();
142
+ process.exit(1);
143
+ }
144
+ }
145
+ //# sourceMappingURL=configToWs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configToWs.js","sourceRoot":"","sources":["../../src/gateways/configToWs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type CorsOptions } from 'cors';
2
+ import { Logger } from '../types.js';
3
+ export interface SseToSseArgs {
4
+ inputSseUrl: string;
5
+ port: number;
6
+ host: string;
7
+ baseUrl: string;
8
+ ssePath: string;
9
+ messagePath: string;
10
+ logger: Logger;
11
+ corsOrigin: CorsOptions['origin'];
12
+ healthEndpoints: string[];
13
+ headers: Record<string, string>;
14
+ }
15
+ export declare function sseToSse(args: SseToSseArgs): Promise<void>;
16
+ //# sourceMappingURL=sseToSse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sseToSse.d.ts","sourceRoot":"","sources":["../../src/gateways/sseToSse.ts"],"names":[],"mappings":"AAEA,OAAa,EAAE,KAAK,WAAW,EAAE,MAAM,MAAM,CAAC;AAa9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAClC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAuCD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,iBAwNhD"}