mirror of
https://github.com/modelcontextprotocol/servers.git
synced 2026-04-21 21:35:15 +02:00
Fix SSE server crash by starting notification timers only after client connects
- Move setInterval calls from server creation to startNotificationIntervals function - Only start notification timers when a client actually connects to the SSE server - Prevents 'Not connected' error when server tries to send notifications before client connection - Fixes issue where server crashes after 5 seconds when running 'npx @modelcontextprotocol/server-everything sse' 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Ola Hungerford <olaservo@users.noreply.github.com>
This commit is contained in:
@@ -169,16 +169,6 @@ export const createServer = () => {
|
|||||||
let subsUpdateInterval: NodeJS.Timeout | undefined;
|
let subsUpdateInterval: NodeJS.Timeout | undefined;
|
||||||
let stdErrUpdateInterval: NodeJS.Timeout | undefined;
|
let stdErrUpdateInterval: NodeJS.Timeout | undefined;
|
||||||
|
|
||||||
// Set up update interval for subscribed resources
|
|
||||||
subsUpdateInterval = setInterval(() => {
|
|
||||||
for (const uri of subscriptions) {
|
|
||||||
server.notification({
|
|
||||||
method: "notifications/resources/updated",
|
|
||||||
params: { uri },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 10000);
|
|
||||||
|
|
||||||
let logLevel: LoggingLevel = "debug";
|
let logLevel: LoggingLevel = "debug";
|
||||||
let logsUpdateInterval: NodeJS.Timeout | undefined;
|
let logsUpdateInterval: NodeJS.Timeout | undefined;
|
||||||
const messages = [
|
const messages = [
|
||||||
@@ -198,15 +188,30 @@ export const createServer = () => {
|
|||||||
return messageLevel < currentLevel;
|
return messageLevel < currentLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set up update interval for random log messages
|
// Function to start notification intervals when a client connects
|
||||||
logsUpdateInterval = setInterval(() => {
|
const startNotificationIntervals = () => {
|
||||||
let message = {
|
if (!subsUpdateInterval) {
|
||||||
method: "notifications/message",
|
subsUpdateInterval = setInterval(() => {
|
||||||
params: messages[Math.floor(Math.random() * messages.length)],
|
for (const uri of subscriptions) {
|
||||||
};
|
server.notification({
|
||||||
if (!isMessageIgnored(message.params.level as LoggingLevel))
|
method: "notifications/resources/updated",
|
||||||
server.notification(message);
|
params: { uri },
|
||||||
}, 20000);
|
});
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!logsUpdateInterval) {
|
||||||
|
logsUpdateInterval = setInterval(() => {
|
||||||
|
let message = {
|
||||||
|
method: "notifications/message",
|
||||||
|
params: messages[Math.floor(Math.random() * messages.length)],
|
||||||
|
};
|
||||||
|
if (!isMessageIgnored(message.params.level as LoggingLevel))
|
||||||
|
server.notification(message);
|
||||||
|
}, 20000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -874,7 +879,7 @@ export const createServer = () => {
|
|||||||
if (stdErrUpdateInterval) clearInterval(stdErrUpdateInterval);
|
if (stdErrUpdateInterval) clearInterval(stdErrUpdateInterval);
|
||||||
};
|
};
|
||||||
|
|
||||||
return { server, cleanup };
|
return { server, cleanup, startNotificationIntervals };
|
||||||
};
|
};
|
||||||
|
|
||||||
const MCP_TINY_IMAGE =
|
const MCP_TINY_IMAGE =
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const transports: Map<string, SSEServerTransport> = new Map<string, SSEServerTra
|
|||||||
|
|
||||||
app.get("/sse", async (req, res) => {
|
app.get("/sse", async (req, res) => {
|
||||||
let transport: SSEServerTransport;
|
let transport: SSEServerTransport;
|
||||||
const { server, cleanup } = createServer();
|
const { server, cleanup, startNotificationIntervals } = createServer();
|
||||||
|
|
||||||
if (req?.query?.sessionId) {
|
if (req?.query?.sessionId) {
|
||||||
const sessionId = (req?.query?.sessionId as string);
|
const sessionId = (req?.query?.sessionId as string);
|
||||||
@@ -25,6 +25,9 @@ app.get("/sse", async (req, res) => {
|
|||||||
await server.connect(transport);
|
await server.connect(transport);
|
||||||
console.error("Client Connected: ", transport.sessionId);
|
console.error("Client Connected: ", transport.sessionId);
|
||||||
|
|
||||||
|
// Start notification intervals after client connects
|
||||||
|
startNotificationIntervals();
|
||||||
|
|
||||||
// Handle close of connection
|
// Handle close of connection
|
||||||
server.onclose = async () => {
|
server.onclose = async () => {
|
||||||
console.error("Client Disconnected: ", transport.sessionId);
|
console.error("Client Disconnected: ", transport.sessionId);
|
||||||
|
|||||||
Reference in New Issue
Block a user