cprime-supergateway 3.4.3 → 3.4.5
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.
|
@@ -8,15 +8,19 @@ import { getVersion } from '../lib/getVersion.js';
|
|
|
8
8
|
import { onSignals } from '../lib/onSignals.js';
|
|
9
9
|
import { serializeCorsOrigin } from '../lib/serializeCorsOrigin.js';
|
|
10
10
|
import { EncryptionService } from '../services/encryptionService.js';
|
|
11
|
+
import { initMongoClient } from '../lib/initMongoClient.js';
|
|
12
|
+
import { McpServerLogRepository } from '../lib/mcpServerLogRepository.js';
|
|
11
13
|
const encryptionService = new EncryptionService('env');
|
|
12
|
-
const plaintext = await encryptionService.decryptText(process.env.ENCRYPTED_ENV ?? '', process.env.AAD_JSON ? JSON.parse(process.env.AAD_JSON) : {});
|
|
13
14
|
let decryptedEnvs = {};
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
if (process.env.ENCRYPTED_ENV) {
|
|
16
|
+
const plaintext = await encryptionService.decryptText(process.env.ENCRYPTED_ENV, process.env.AAD_JSON ? JSON.parse(process.env.AAD_JSON) : {});
|
|
17
|
+
try {
|
|
18
|
+
const asObj = JSON.parse(plaintext);
|
|
19
|
+
decryptedEnvs = asObj;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
console.error('Failed to parse decrypted envs', plaintext);
|
|
23
|
+
}
|
|
20
24
|
}
|
|
21
25
|
const setResponseHeaders = ({ res, headers, }) => Object.entries(headers).forEach(([key, value]) => {
|
|
22
26
|
res.setHeader(key, value);
|
|
@@ -34,6 +38,8 @@ export async function stdioToSse(args) {
|
|
|
34
38
|
logger.info(` - CORS: ${corsOrigin ? `enabled (${serializeCorsOrigin({ corsOrigin })})` : 'disabled'}`);
|
|
35
39
|
logger.info(` - Health endpoints: ${healthEndpoints.length ? healthEndpoints.join(', ') : '(none)'}`);
|
|
36
40
|
onSignals({ logger });
|
|
41
|
+
const mongoClient = initMongoClient();
|
|
42
|
+
const mcpServerLogRepository = new McpServerLogRepository(mongoClient, process.env.MONGO_DB ?? 'localhost', process.env.LOGS_COLLECTION ?? 'mcp_server_logs');
|
|
37
43
|
const child = spawn(stdioCmd, {
|
|
38
44
|
shell: true,
|
|
39
45
|
env: { ...process.env, ...decryptedEnvs },
|
|
@@ -72,10 +78,28 @@ export async function stdioToSse(args) {
|
|
|
72
78
|
await server.connect(sseTransport);
|
|
73
79
|
const sessionId = sseTransport.sessionId;
|
|
74
80
|
if (sessionId) {
|
|
75
|
-
sessions[sessionId] = {
|
|
81
|
+
sessions[sessionId] = {
|
|
82
|
+
transport: sseTransport,
|
|
83
|
+
response: res,
|
|
84
|
+
ip: req.ip ?? '',
|
|
85
|
+
userId: req.query.userId ?? '',
|
|
86
|
+
};
|
|
76
87
|
}
|
|
77
88
|
sseTransport.onmessage = (msg) => {
|
|
78
89
|
logger.info(`SSE → Child (session ${sessionId}): ${JSON.stringify(msg)}`);
|
|
90
|
+
mcpServerLogRepository
|
|
91
|
+
.insert({
|
|
92
|
+
ip: req.ip ?? '',
|
|
93
|
+
userId: req.query.userId ?? '',
|
|
94
|
+
sessionId,
|
|
95
|
+
type: 'rpc',
|
|
96
|
+
data: msg,
|
|
97
|
+
createdAt: new Date(),
|
|
98
|
+
updatedAt: new Date(),
|
|
99
|
+
})
|
|
100
|
+
.catch((err) => {
|
|
101
|
+
logger.error(`Failed to insert log:`, JSON.stringify(err));
|
|
102
|
+
});
|
|
79
103
|
child.stdin.write(JSON.stringify(msg) + '\n');
|
|
80
104
|
};
|
|
81
105
|
sseTransport.onclose = () => {
|
|
@@ -129,6 +153,19 @@ export async function stdioToSse(args) {
|
|
|
129
153
|
for (const [sid, session] of Object.entries(sessions)) {
|
|
130
154
|
try {
|
|
131
155
|
session.transport.send(jsonMsg);
|
|
156
|
+
mcpServerLogRepository
|
|
157
|
+
.insert({
|
|
158
|
+
ip: session.ip,
|
|
159
|
+
userId: session.userId,
|
|
160
|
+
sessionId: sid,
|
|
161
|
+
type: 'system',
|
|
162
|
+
data: line,
|
|
163
|
+
createdAt: new Date(),
|
|
164
|
+
updatedAt: new Date(),
|
|
165
|
+
})
|
|
166
|
+
.catch((err) => {
|
|
167
|
+
logger.error(`Failed to insert log:`, JSON.stringify(err));
|
|
168
|
+
});
|
|
132
169
|
}
|
|
133
170
|
catch (err) {
|
|
134
171
|
logger.error(`Failed to send to session ${sid}:`, err);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export class McpServerLogRepository {
|
|
2
|
+
client;
|
|
3
|
+
collection;
|
|
4
|
+
constructor(client, dbName = 'local', collectionName = 'mcp_server_logs') {
|
|
5
|
+
this.client = client;
|
|
6
|
+
this.collection = this.client.db(dbName).collection(collectionName);
|
|
7
|
+
}
|
|
8
|
+
insert(data) {
|
|
9
|
+
return this.collection.insertOne(data);
|
|
10
|
+
}
|
|
11
|
+
update(sessionId, update) {
|
|
12
|
+
return this.collection.updateOne({ sessionId, 'data.id': update.id }, {
|
|
13
|
+
$set: {
|
|
14
|
+
'data.result': update.result,
|
|
15
|
+
'data.error': update.error,
|
|
16
|
+
updatedAt: new Date(),
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cprime-supergateway",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.5",
|
|
4
4
|
"description": "Run MCP stdio servers over SSE, Streamable HTTP or visa versa",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
],
|
|
17
17
|
"type": "module",
|
|
18
18
|
"bin": {
|
|
19
|
-
"supergateway": "dist/index.js"
|
|
19
|
+
"cprime-supergateway": "dist/index.js"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "tsc -p tsconfig.build.json",
|
|
@@ -26,16 +26,18 @@ export interface StdioToSseArgs {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const encryptionService = new EncryptionService('env')
|
|
29
|
-
const plaintext = await encryptionService.decryptText(
|
|
30
|
-
process.env.ENCRYPTED_ENV ?? '',
|
|
31
|
-
process.env.AAD_JSON ? JSON.parse(process.env.AAD_JSON) : {},
|
|
32
|
-
)
|
|
33
29
|
let decryptedEnvs = {}
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
if (process.env.ENCRYPTED_ENV) {
|
|
31
|
+
const plaintext = await encryptionService.decryptText(
|
|
32
|
+
process.env.ENCRYPTED_ENV,
|
|
33
|
+
process.env.AAD_JSON ? JSON.parse(process.env.AAD_JSON) : {},
|
|
34
|
+
)
|
|
35
|
+
try {
|
|
36
|
+
const asObj = JSON.parse(plaintext)
|
|
37
|
+
decryptedEnvs = asObj
|
|
38
|
+
} catch {
|
|
39
|
+
console.error('Failed to parse decrypted envs', plaintext)
|
|
40
|
+
}
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
const setResponseHeaders = ({
|
|
File without changes
|