Skip to content

Commit 9d9ef2a

Browse files
committed
fix(transports): Conform SSE/HTTP streams to MCP spec and improve logging
- Removes non-standard initial messages (': stream opened', initial ': keep-alive') from SSE and HTTP stream transports. - Corrects periodic keep-alive mechanism to send standard JSON-RPC 'ping' requests instead of ': keep-alive' comments, aligning with MCP specification. - Updates server startup log message in MCPServer to include the framework's own version alongside the SDK version for better diagnostics.
1 parent df733f9 commit 9d9ef2a

File tree

4 files changed

+11
-7
lines changed

4 files changed

+11
-7
lines changed

src/core/MCPServer.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,10 @@ export class MCPServer {
432432
}
433433
this.isRunning = true;
434434

435+
const frameworkPackageJson = require('../../package.json');
436+
const frameworkVersion = frameworkPackageJson.version || 'unknown';
435437
const sdkVersion = this.getSdkVersion();
436-
logger.info(`Starting MCP server with SDK ${sdkVersion}...`);
438+
logger.info(`Starting MCP server (Framework: ${frameworkVersion}, SDK: ${sdkVersion})...`);
437439

438440
const tools = await this.toolLoader.loadTools();
439441
this.toolsMap = new Map(

src/transports/http/server.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,6 @@ export class HttpStreamTransport extends AbstractTransport {
481481
if (res.socket) { res.socket.setNoDelay(true); res.socket.setKeepAlive(true); res.socket.setTimeout(0); logger.debug(`Optimized socket for SSE stream ${streamId}`); }
482482
else { logger.warn(`Could not access socket for SSE stream ${streamId} to optimize.`); }
483483
this._activeSseConnections.add(connection);
484-
res.write(': stream opened\n\n');
485484
connection.pingInterval = setInterval(() => this.sendPing(connection), 15000);
486485
if (lastEventId && this._config.resumability.enabled) {
487486
this.handleResumption(connection, lastEventId, sessionId).catch(err => { logger.error(`Error during stream resumption for ${streamId}: ${err.message}`); this.cleanupConnection(connection, `Resumption error: ${err.message}`); });
@@ -646,7 +645,8 @@ export class HttpStreamTransport extends AbstractTransport {
646645
private sendPing(connection: ActiveSseConnection): void {
647646
if (!connection || !connection.res || connection.res.writableEnded) return;
648647
try {
649-
connection.res.write(': keep-alive\n\n');
648+
const pingMessage = { jsonrpc: "2.0", method: "ping", params: { timestamp: Date.now() } };
649+
connection.res.write(`data: ${JSON.stringify(pingMessage)}\n\n`);
650650
logger.debug(`Sent keep-alive ping to stream ${connection.streamId}`);
651651
} catch (error: any) {
652652
logger.error(`Error sending ping to stream ${connection.streamId}: ${error.message}`);

src/transports/sse/server.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,14 @@ export class SSEServerTransport extends AbstractTransport {
225225
res.write(`event: endpoint\ndata: ${endpointUrl}\n\n`)
226226

227227
logger.debug('Sending initial keep-alive')
228-
res.write(": keep-alive\n\n")
228+
// Removed initial keep-alive: res.write(": keep-alive\n\n")
229229

230230
this._keepAliveInterval = setInterval(() => {
231231
if (this._sseResponse && !this._sseResponse.writableEnded) {
232232
try {
233-
logger.debug('Sending keep-alive ping')
234-
this._sseResponse.write(": keep-alive\n\n")
233+
// Sending proper JSON-RPC ping instead of ': keep-alive' comment
234+
// logger.debug('Sending keep-alive ping')
235+
// this._sseResponse.write(": keep-alive\n\n")
235236

236237
const pingMessage = {
237238
jsonrpc: "2.0",

tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"strict": true,
1010
"esModuleInterop": true,
1111
"skipLibCheck": true,
12-
"forceConsistentCasingInFileNames": true
12+
"forceConsistentCasingInFileNames": true,
13+
"resolveJsonModule": true
1314
},
1415
"include": ["src/**/*"],
1516
"exclude": ["node_modules", "**/*.test.ts"]

0 commit comments

Comments
 (0)