mirror of
https://github.com/modelcontextprotocol/servers.git
synced 2026-04-20 00:53:24 +02:00
[WIP] Refactor everything server to be more modular and use recommended APIs.
Added tools to toggle simulated logging and resource updates on and off rather than have them start immediately upon connection
* Updated architecture.md
* In server/index.ts
- remove import of beginSimulatedResourceUpdates and beginSimulatedLogging
- remove clientConnected from createServer factory result
* In tools/index.ts
- import registerToggleLoggingTool and registerToggleSubscriberUpdatesTool
- in registerTools
- call registerToggleLoggingTool and registerToggleSubscriberUpdatesTool
* In logging.ts
- in beginSimulatedLogging
- refactor extract inline interval callback into function sendSimulatedLoggingMessage
- call sendSimulatedLoggingMessage right away to send the first message
- supply sendSimulatedLoggingMessage as interval callback
* In subscriptions.ts
- remove import of Transport
- remove transports map
- in beginSimulatedResourceUpdates()
- change arguments to server and sessionId
- check for the subsUpdateInterval for the session
- remove all transport storage and interaction
- instead use the server to send the notification
- in stopSimulatedResourceUpdates()
- remove management of transports map
* In stdio.ts, sse.ts, and streamableHttp.ts
- remove destructure and calling of clientConnected
* Added tools/toggle-logging.ts
- registers a tool that
- takes no arguments
- tracks clients that have been enabled by session id in a set
- if client isn't enabled,
- calls beginSimulatedLogging
- adds session id to client set
- else
- calls stopSimulatedLogging
- deletes session id from client set
- returns a message explaining what was done including what to expect when logging is enabled
* Added tools/toggle-subscriber-updates.ts
- registers a tool that
- takes no arguments
- tracks clients that have been enabled by session id in a set
- if client isn't enabled,
- calls beginSimulatedResourceUpdates
- adds session id to client set
- else
- calls stopSimulatedResourceUpdates
- deletes session id from client set
- returns a message explaining what was done including what to expect when logging is enabled
This commit is contained in:
@@ -96,6 +96,38 @@ export const setSubscriptionHandlers = (server: McpServer) => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends simulated resource update notifications to the subscribed client.
|
||||
*
|
||||
* This function iterates through all resource URIs stored in the subscriptions
|
||||
* and checks if the specified session ID is subscribed to them. If so, it sends
|
||||
* a notification through the provided server. If the session ID is no longer valid
|
||||
* (disconnected), it removes the session ID from the list of subscribers.
|
||||
*
|
||||
* @param {McpServer} server - The server instance used to send notifications.
|
||||
* @param {string | undefined} sessionId - The session ID of the client to check for subscriptions.
|
||||
* @returns {Promise<void>} Resolves once all applicable notifications are sent.
|
||||
*/
|
||||
const sendSimulatedResourceUpdates = async (
|
||||
server: McpServer,
|
||||
sessionId: string | undefined
|
||||
): Promise<void> => {
|
||||
// Search all URIs for ones this client is subscribed to
|
||||
for (const uri of subscriptions.keys()) {
|
||||
const subscribers = subscriptions.get(uri) as Set<string | undefined>;
|
||||
|
||||
// If this client is subscribed, send the notification
|
||||
if (subscribers.has(sessionId)) {
|
||||
await server.server.notification({
|
||||
method: "notifications/resources/updated",
|
||||
params: { uri },
|
||||
});
|
||||
} else {
|
||||
subscribers.delete(sessionId); // subscriber has disconnected
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts the process of simulating resource updates and sending server notifications
|
||||
* to the client for the resources they are subscribed to. If the update interval is
|
||||
@@ -109,25 +141,13 @@ export const beginSimulatedResourceUpdates = (
|
||||
sessionId: string | undefined
|
||||
) => {
|
||||
if (!subsUpdateIntervals.has(sessionId)) {
|
||||
// Set the interval to send resource update notifications to this client
|
||||
// Send once immediately
|
||||
sendSimulatedResourceUpdates(server, sessionId);
|
||||
|
||||
// Set the interval to send later resource update notifications to this client
|
||||
subsUpdateIntervals.set(
|
||||
sessionId,
|
||||
setInterval(async () => {
|
||||
// Search all URIs for ones this client is subscribed to
|
||||
for (const uri of subscriptions.keys()) {
|
||||
const subscribers = subscriptions.get(uri) as Set<string | undefined>;
|
||||
|
||||
// If this client is subscribed, send the notification
|
||||
if (subscribers.has(sessionId)) {
|
||||
await server.server.notification({
|
||||
method: "notifications/resources/updated",
|
||||
params: { uri },
|
||||
});
|
||||
} else {
|
||||
subscribers.delete(sessionId); // subscriber has disconnected
|
||||
}
|
||||
}
|
||||
}, 10000)
|
||||
setInterval(() => sendSimulatedResourceUpdates(server, sessionId), 5000)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user