UNPKG

@modelcontextprotocol/server-everything

Version:

MCP server that exercises all the features of the MCP protocol

48 lines (47 loc) • 2.48 kB
// The per-instance context the server factory hands to the features that // need more than the `McpServer` itself (#4852). // // Before the 2026-07-28 revision, features that kept state across calls // (simulated logging, resource subscriptions, the roots cache, the URL // elicitation error path) held it in module-level maps keyed by the // transport's session id. The 2026-07-28 revision has no sessions, so that // state now lives here, on the server instance the factory built: one per // stdio connection, one per 2025-era Streamable HTTP session, and one per // request on the 2026-07-28 HTTP path, where nothing survives between // requests unless the server mints a handle for it (as the tasks store does). // // The context also carries the protocol era the instance serves, because a // few features differ by era, and the publisher that announces list and // resource changes, because where a change notification goes differs by // transport: on stdio and on a 2025-era session the instance sends it // itself, while on the 2026-07-28 HTTP path the instance lives for one // request and the change goes out on the handler's subscription bus. /** * A publisher that sends each change from `server` itself. On a 2025-era * connection the notification goes to the client unsolicited; on a * 2026-07-28 stdio connection `serveStdio` routes it onto the open * `subscriptions/listen` streams that asked for it. * * `resourceUpdated` is sent only for a URI `isSubscribed` accepts: a 2025-era * client subscribes per resource, and on 2026-07-28 the listen router does * the filtering, so the server passes `() => true` there. */ export function instancePublisher(server, isSubscribed) { const report = (error) => console.error("Change notification failed:", error); // The low-level sends return their promise; McpServer's own helpers start // the same send and drop it, so a failed one would go unhandled. const send = (notify) => { if (server.isConnected()) notify().catch(report); }; return { toolsChanged: () => send(() => server.server.sendToolListChanged()), promptsChanged: () => send(() => server.server.sendPromptListChanged()), resourcesChanged: () => send(() => server.server.sendResourceListChanged()), resourceUpdated: (uri) => { if (isSubscribed(uri)) { server.server.sendResourceUpdated({ uri }).catch(report); } }, }; }