remove custom post handler
This commit is contained in:
@@ -671,6 +671,9 @@ app.use(cors());
|
|||||||
// Enable compression
|
// Enable compression
|
||||||
app.use(compression());
|
app.use(compression());
|
||||||
|
|
||||||
|
// ⭐ FIX: Apply JSON body parsing globally for the SDK to read POST bodies
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
// Rate limiting
|
// Rate limiting
|
||||||
const limiter = rateLimit({
|
const limiter = rateLimit({
|
||||||
windowMs: RATE_LIMIT_WINDOW_MS,
|
windowMs: RATE_LIMIT_WINDOW_MS,
|
||||||
@@ -701,11 +704,10 @@ app.get('/health', (req, res) => {
|
|||||||
// SSE endpoint for MCP
|
// SSE endpoint for MCP
|
||||||
app.get('/sse', async (req, res) => {
|
app.get('/sse', async (req, res) => {
|
||||||
let pingInterval = null;
|
let pingInterval = null;
|
||||||
// NEW FLAG: Tracks if the 200 SSE headers have been flushed
|
|
||||||
let headersSent = false;
|
let headersSent = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Check system health (MUST be done before sending headers)
|
// Check system health
|
||||||
checkMemory();
|
checkMemory();
|
||||||
checkConcurrency();
|
checkConcurrency();
|
||||||
|
|
||||||
@@ -724,18 +726,18 @@ app.get('/sse', async (req, res) => {
|
|||||||
// Send an initial comment (ping) to complete the HTTP handshake and flush headers
|
// Send an initial comment (ping) to complete the HTTP handshake and flush headers
|
||||||
res.write(':\n');
|
res.write(':\n');
|
||||||
res.flushHeaders();
|
res.flushHeaders();
|
||||||
headersSent = true; // Flag is set after successful header flush
|
headersSent = true;
|
||||||
|
|
||||||
// 2. Start the heartbeat/ping interval
|
// 2. Start the heartbeat/ping interval
|
||||||
pingInterval = setInterval(() => {
|
pingInterval = setInterval(() => {
|
||||||
// Send a comment line (ignored by clients) every 20s to keep the proxy alive
|
// Send a comment line every 20s to keep the proxy alive
|
||||||
res.write(':\n');
|
res.write(':\n');
|
||||||
}, SSE_HEARTBEAT_INTERVAL_MS);
|
}, SSE_HEARTBEAT_INTERVAL_MS);
|
||||||
|
|
||||||
// Create a new MCP server instance for this connection
|
// Create a new MCP server instance for this connection
|
||||||
const server = createMCPServer();
|
const server = createMCPServer();
|
||||||
|
|
||||||
// Create SSE transport
|
// Create SSE transport, specifying the POST message path
|
||||||
const transport = new SSEServerTransport('/message', res);
|
const transport = new SSEServerTransport('/message', res);
|
||||||
|
|
||||||
// Connect server with timeout and circuit breaker
|
// Connect server with timeout and circuit breaker
|
||||||
@@ -748,7 +750,7 @@ app.get('/sse', async (req, res) => {
|
|||||||
req.on('close', () => {
|
req.on('close', () => {
|
||||||
activeRequests--;
|
activeRequests--;
|
||||||
if (pingInterval) {
|
if (pingInterval) {
|
||||||
clearInterval(pingInterval); // STOP THE PING ON CLOSE
|
clearInterval(pingInterval);
|
||||||
}
|
}
|
||||||
console.error(`SSE connection closed. Active requests: ${activeRequests}`);
|
console.error(`SSE connection closed. Active requests: ${activeRequests}`);
|
||||||
});
|
});
|
||||||
@@ -756,42 +758,34 @@ app.get('/sse', async (req, res) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
activeRequests--;
|
activeRequests--;
|
||||||
if (pingInterval) {
|
if (pingInterval) {
|
||||||
clearInterval(pingInterval); // Stop ping on connection failure
|
clearInterval(pingInterval);
|
||||||
}
|
}
|
||||||
console.error('SSE connection error:', error.message);
|
console.error('SSE connection error:', error.message);
|
||||||
|
|
||||||
// --- START CORRECTED ERROR HANDLING ---
|
|
||||||
if (!headersSent) {
|
if (!headersSent) {
|
||||||
// Case 1: Error before SSE headers were flushed (e.g., checkMemory failed)
|
// Case 1: Error before SSE headers were flushed (e.g., checkMemory failed)
|
||||||
// Send a standard HTTP error response.
|
|
||||||
res.status(503).json({
|
res.status(503).json({
|
||||||
error: error.message,
|
error: error.message,
|
||||||
circuitBreaker: circuitBreaker.state,
|
circuitBreaker: circuitBreaker.state,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Case 2: Error after SSE headers were flushed (stream is open)
|
// Case 2: Error after SSE headers were flushed (stream is open)
|
||||||
// Cannot change status. Send an SSE 'error' event and end the connection.
|
// Send an SSE 'error' event and end the connection.
|
||||||
const errorData = JSON.stringify({
|
const errorData = JSON.stringify({
|
||||||
message: error.message,
|
message: error.message,
|
||||||
circuitBreaker: circuitBreaker.state
|
circuitBreaker: circuitBreaker.state
|
||||||
});
|
});
|
||||||
res.write(`event: error\ndata: ${errorData}\n\n`);
|
res.write(`event: error\ndata: ${errorData}\n\n`);
|
||||||
res.end(); // Forcefully close the connection
|
res.end();
|
||||||
}
|
}
|
||||||
// --- END CORRECTED ERROR HANDLING ---
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// POST endpoint for MCP messages
|
|
||||||
app.post('/message', express.json(), async (req, res) => {
|
// ⭐ CRITICAL FIX: Removed the custom app.post('/message') handler.
|
||||||
try {
|
// The SSEServerTransport (created in app.get('/sse')) now automatically handles
|
||||||
// SSE transport handles this internally
|
// the POST requests to '/message' and sends the 200 OK response, fixing the 502 issue.
|
||||||
res.status(200).send();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Message error:', error.message);
|
|
||||||
res.status(500).json({ error: error.message });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Error handling middleware
|
// Error handling middleware
|
||||||
app.use((err, req, res, next) => {
|
app.use((err, req, res, next) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user