brms-host 1.0.4 → 1.0.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.
- package/build/index.d.ts +4 -0
- package/build/index.js +71 -39
- package/build/index.js.map +1 -1
- package/package.json +1 -1
package/build/index.d.ts
CHANGED
|
@@ -4,5 +4,9 @@
|
|
|
4
4
|
*
|
|
5
5
|
* - Starts an HTTP server on port 3100 exposing MCP via Streamable HTTP
|
|
6
6
|
* - Starts the native messaging bridge to communicate with the Chrome extension
|
|
7
|
+
*
|
|
8
|
+
* Each Cursor connection gets its own transport + MCP server instance so that
|
|
9
|
+
* reconnects (which send a fresh `initialize`) never hit the "already initialized"
|
|
10
|
+
* error that occurs when a single transport is reused across sessions.
|
|
7
11
|
*/
|
|
8
12
|
export {};
|
package/build/index.js
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* - Starts an HTTP server on port 3100 exposing MCP via Streamable HTTP
|
|
6
6
|
* - Starts the native messaging bridge to communicate with the Chrome extension
|
|
7
|
+
*
|
|
8
|
+
* Each Cursor connection gets its own transport + MCP server instance so that
|
|
9
|
+
* reconnects (which send a fresh `initialize`) never hit the "already initialized"
|
|
10
|
+
* error that occurs when a single transport is reused across sessions.
|
|
7
11
|
*/
|
|
8
12
|
import { createServer as createHttpServer } from 'node:http';
|
|
9
13
|
import { writeFileSync, appendFileSync } from 'node:fs';
|
|
@@ -22,64 +26,98 @@ function debugLog(msg) {
|
|
|
22
26
|
catch { }
|
|
23
27
|
log.info(msg);
|
|
24
28
|
}
|
|
25
|
-
|
|
26
|
-
process.on('
|
|
27
|
-
|
|
28
|
-
});
|
|
29
|
-
process.on('uncaughtException', (err) => {
|
|
30
|
-
debugLog(`UNCAUGHT EXCEPTION: ${err.stack ?? err.message}`);
|
|
31
|
-
});
|
|
32
|
-
process.on('unhandledRejection', (reason) => {
|
|
33
|
-
debugLog(`UNHANDLED REJECTION: ${reason}`);
|
|
34
|
-
});
|
|
29
|
+
process.on('exit', (code) => { debugLog(`Process exiting with code ${code}`); });
|
|
30
|
+
process.on('uncaughtException', (err) => { debugLog(`UNCAUGHT EXCEPTION: ${err.stack ?? err.message}`); });
|
|
31
|
+
process.on('unhandledRejection', (reason) => { debugLog(`UNHANDLED REJECTION: ${reason}`); });
|
|
35
32
|
process.on('SIGTERM', () => debugLog('Received SIGTERM'));
|
|
36
33
|
process.on('SIGINT', () => debugLog('Received SIGINT'));
|
|
37
|
-
// Keep process alive even if stdin closes
|
|
38
|
-
process.stdin.on('end', () => {
|
|
39
|
-
debugLog('stdin ended — keeping process alive');
|
|
40
|
-
});
|
|
34
|
+
// Keep process alive even if stdin closes (native messaging host mode)
|
|
35
|
+
process.stdin.on('end', () => { debugLog('stdin ended — keeping process alive'); });
|
|
41
36
|
process.stdin.resume();
|
|
37
|
+
const CORS_HEADERS = {
|
|
38
|
+
'Access-Control-Allow-Origin': '*',
|
|
39
|
+
'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',
|
|
40
|
+
'Access-Control-Allow-Headers': 'Content-Type, Accept, Mcp-Session-Id',
|
|
41
|
+
};
|
|
42
42
|
async function main() {
|
|
43
43
|
writeFileSync(DEBUG_LOG, `=== BRMS Host starting at ${new Date().toISOString()} ===\n`);
|
|
44
44
|
debugLog(`PID: ${process.pid}, Node: ${process.version}`);
|
|
45
|
-
debugLog(`stdin isTTY: ${process.stdin.isTTY}, stdout isTTY: ${process.stdout.isTTY}`);
|
|
46
45
|
bridge.start();
|
|
47
46
|
debugLog('Bridge started');
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
sessionIdGenerator: () => randomUUID(),
|
|
52
|
-
});
|
|
53
|
-
const CORS_HEADERS = {
|
|
54
|
-
'Access-Control-Allow-Origin': '*',
|
|
55
|
-
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
56
|
-
'Access-Control-Allow-Headers': 'Content-Type, Accept',
|
|
57
|
-
};
|
|
47
|
+
// Session map: sessionId → transport
|
|
48
|
+
// Each Cursor connection gets its own transport so reconnects start fresh.
|
|
49
|
+
const sessions = new Map();
|
|
58
50
|
const httpServer = createHttpServer(async (req, res) => {
|
|
59
51
|
const url = new URL(req.url ?? '/', `http://localhost:${PORT}`);
|
|
60
|
-
//
|
|
52
|
+
// CORS preflight
|
|
61
53
|
if (req.method === 'OPTIONS') {
|
|
62
54
|
res.writeHead(204, CORS_HEADERS);
|
|
63
55
|
res.end();
|
|
64
56
|
return;
|
|
65
57
|
}
|
|
66
|
-
// Attach CORS
|
|
58
|
+
// Attach CORS to every response
|
|
67
59
|
Object.entries(CORS_HEADERS).forEach(([k, v]) => res.setHeader(k, v));
|
|
60
|
+
// ── /health ────────────────────────────────────────────────
|
|
61
|
+
if (url.pathname === '/health') {
|
|
62
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
63
|
+
res.end(JSON.stringify({ status: 'ok', extensionConnected: bridge.isConnected() }));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// ── /mcp ──────────────────────────────────────────────────
|
|
68
67
|
if (url.pathname === '/mcp') {
|
|
69
68
|
try {
|
|
70
|
-
// Parse body for POST requests
|
|
69
|
+
// Parse body once for POST requests
|
|
70
|
+
let parsedBody;
|
|
71
71
|
if (req.method === 'POST') {
|
|
72
|
-
const
|
|
72
|
+
const raw = await new Promise((resolve, reject) => {
|
|
73
73
|
let data = '';
|
|
74
74
|
req.on('data', (chunk) => { data += chunk.toString(); });
|
|
75
75
|
req.on('end', () => resolve(data));
|
|
76
76
|
req.on('error', reject);
|
|
77
77
|
});
|
|
78
|
-
|
|
78
|
+
try {
|
|
79
|
+
parsedBody = JSON.parse(raw);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
83
|
+
res.end(JSON.stringify({ error: 'Invalid JSON' }));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
88
|
+
if (req.method === 'POST' && !sessionId) {
|
|
89
|
+
// ── New session ────────────────────────────────────
|
|
90
|
+
// Cursor is connecting (or reconnecting). Always create a fresh
|
|
91
|
+
// transport so `initialize` succeeds even after a prior connection.
|
|
92
|
+
const newId = randomUUID();
|
|
93
|
+
const transport = new StreamableHTTPServerTransport({
|
|
94
|
+
sessionIdGenerator: () => newId,
|
|
95
|
+
});
|
|
96
|
+
transport.onclose = () => {
|
|
97
|
+
sessions.delete(newId);
|
|
98
|
+
debugLog(`Session closed: ${newId}`);
|
|
99
|
+
};
|
|
100
|
+
// Each session gets its own MCP server instance
|
|
101
|
+
const mcpServer = createServer();
|
|
102
|
+
await mcpServer.connect(transport);
|
|
103
|
+
sessions.set(newId, transport);
|
|
104
|
+
debugLog(`New MCP session: ${newId} (total: ${sessions.size})`);
|
|
79
105
|
await transport.handleRequest(req, res, parsedBody);
|
|
80
106
|
}
|
|
107
|
+
else if (sessionId && sessions.has(sessionId)) {
|
|
108
|
+
// ── Existing session ───────────────────────────────
|
|
109
|
+
await sessions.get(sessionId).handleRequest(req, res, parsedBody);
|
|
110
|
+
}
|
|
111
|
+
else if (sessionId && !sessions.has(sessionId)) {
|
|
112
|
+
// Unknown session — client should reconnect with a fresh initialize
|
|
113
|
+
debugLog(`Unknown session ID: ${sessionId}`);
|
|
114
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
115
|
+
res.end(JSON.stringify({ error: 'Session not found. Send a new initialize request without Mcp-Session-Id.' }));
|
|
116
|
+
}
|
|
81
117
|
else {
|
|
82
|
-
|
|
118
|
+
// GET/DELETE without session ID
|
|
119
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
120
|
+
res.end(JSON.stringify({ error: 'Mcp-Session-Id header required' }));
|
|
83
121
|
}
|
|
84
122
|
}
|
|
85
123
|
catch (err) {
|
|
@@ -91,19 +129,12 @@ async function main() {
|
|
|
91
129
|
}
|
|
92
130
|
return;
|
|
93
131
|
}
|
|
94
|
-
if (url.pathname === '/health') {
|
|
95
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
96
|
-
res.end(JSON.stringify({ status: 'ok', extensionConnected: bridge.isConnected() }));
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
132
|
res.writeHead(404);
|
|
100
133
|
res.end('Not found');
|
|
101
134
|
});
|
|
102
|
-
await mcpServer.connect(transport);
|
|
103
|
-
debugLog('MCP connected to transport');
|
|
104
135
|
httpServer.on('error', (err) => {
|
|
105
136
|
if (err.code === 'EADDRINUSE') {
|
|
106
|
-
debugLog(`Port ${PORT} is already in use
|
|
137
|
+
debugLog(`Port ${PORT} is already in use.`);
|
|
107
138
|
console.error('');
|
|
108
139
|
console.error(` [brms] Error: port ${PORT} is already in use.`);
|
|
109
140
|
console.error(` A previous BRMS server may still be running.`);
|
|
@@ -119,6 +150,7 @@ async function main() {
|
|
|
119
150
|
});
|
|
120
151
|
httpServer.listen(PORT, () => {
|
|
121
152
|
debugLog(`HTTP server listening on :${PORT}`);
|
|
153
|
+
console.log(` [brms] MCP server running at http://localhost:${PORT}/mcp`);
|
|
122
154
|
});
|
|
123
155
|
}
|
|
124
156
|
main().catch((err) => {
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|