@cyanheads/pubmed-mcp-server 1.3.5 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -21
- package/dist/config/index.d.ts +11 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +75 -11
- package/dist/config/index.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/server.d.ts +13 -0
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +31 -13
- package/dist/mcp-server/server.js.map +1 -1
- package/dist/mcp-server/tools/pubmedArticleConnections/index.d.ts +7 -0
- package/dist/mcp-server/tools/pubmedArticleConnections/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/pubmedArticleConnections/index.js +7 -0
- package/dist/mcp-server/tools/pubmedArticleConnections/index.js.map +1 -0
- package/dist/mcp-server/tools/pubmedArticleConnections/logic/citationFormatter.d.ts +10 -0
- package/dist/mcp-server/tools/pubmedArticleConnections/logic/citationFormatter.d.ts.map +1 -0
- package/dist/mcp-server/tools/{getPubMedArticleConnections → pubmedArticleConnections}/logic/citationFormatter.js +9 -7
- package/dist/mcp-server/tools/pubmedArticleConnections/logic/citationFormatter.js.map +1 -0
- package/dist/mcp-server/tools/pubmedArticleConnections/logic/elinkHandler.d.ts +10 -0
- package/dist/mcp-server/tools/pubmedArticleConnections/logic/elinkHandler.d.ts.map +1 -0
- package/dist/mcp-server/tools/{getPubMedArticleConnections → pubmedArticleConnections}/logic/elinkHandler.js +9 -9
- package/dist/mcp-server/tools/pubmedArticleConnections/logic/elinkHandler.js.map +1 -0
- package/dist/mcp-server/tools/{getPubMedArticleConnections → pubmedArticleConnections}/logic/index.d.ts +9 -9
- package/dist/mcp-server/tools/pubmedArticleConnections/logic/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/{getPubMedArticleConnections → pubmedArticleConnections}/logic/index.js +14 -14
- package/dist/mcp-server/tools/pubmedArticleConnections/logic/index.js.map +1 -0
- package/dist/mcp-server/tools/{getPubMedArticleConnections → pubmedArticleConnections}/logic/types.d.ts +4 -4
- package/dist/mcp-server/tools/pubmedArticleConnections/logic/types.d.ts.map +1 -0
- package/dist/mcp-server/tools/pubmedArticleConnections/logic/types.js +6 -0
- package/dist/mcp-server/tools/pubmedArticleConnections/logic/types.js.map +1 -0
- package/dist/mcp-server/tools/pubmedArticleConnections/registration.d.ts +12 -0
- package/dist/mcp-server/tools/pubmedArticleConnections/registration.d.ts.map +1 -0
- package/dist/mcp-server/tools/{getPubMedArticleConnections → pubmedArticleConnections}/registration.js +11 -11
- package/dist/mcp-server/tools/pubmedArticleConnections/registration.js.map +1 -0
- package/dist/mcp-server/tools/pubmedFetchContents/index.d.ts +7 -0
- package/dist/mcp-server/tools/pubmedFetchContents/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/pubmedFetchContents/index.js +7 -0
- package/dist/mcp-server/tools/pubmedFetchContents/index.js.map +1 -0
- package/dist/mcp-server/tools/{fetchPubMedContent → pubmedFetchContents}/logic.d.ts +6 -6
- package/dist/mcp-server/tools/pubmedFetchContents/logic.d.ts.map +1 -0
- package/dist/mcp-server/tools/{fetchPubMedContent → pubmedFetchContents}/logic.js +18 -17
- package/dist/mcp-server/tools/pubmedFetchContents/logic.js.map +1 -0
- package/dist/mcp-server/tools/pubmedFetchContents/registration.d.ts +11 -0
- package/dist/mcp-server/tools/pubmedFetchContents/registration.d.ts.map +1 -0
- package/dist/mcp-server/tools/{fetchPubMedContent → pubmedFetchContents}/registration.js +12 -12
- package/dist/mcp-server/tools/pubmedFetchContents/registration.js.map +1 -0
- package/dist/mcp-server/tools/{generatePubMedChart → pubmedGenerateChart}/index.d.ts +2 -2
- package/dist/mcp-server/tools/pubmedGenerateChart/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/{generatePubMedChart → pubmedGenerateChart}/index.js +2 -2
- package/dist/mcp-server/tools/pubmedGenerateChart/index.js.map +1 -0
- package/dist/mcp-server/tools/{generatePubMedChart → pubmedGenerateChart}/logic.d.ts +4 -4
- package/dist/mcp-server/tools/{generatePubMedChart → pubmedGenerateChart}/logic.d.ts.map +1 -1
- package/dist/mcp-server/tools/{generatePubMedChart → pubmedGenerateChart}/logic.js +24 -20
- package/dist/mcp-server/tools/pubmedGenerateChart/logic.js.map +1 -0
- package/dist/mcp-server/tools/pubmedGenerateChart/registration.d.ts +8 -0
- package/dist/mcp-server/tools/{generatePubMedChart → pubmedGenerateChart}/registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/{generatePubMedChart → pubmedGenerateChart}/registration.js +9 -13
- package/dist/mcp-server/tools/pubmedGenerateChart/registration.js.map +1 -0
- package/dist/mcp-server/tools/pubmedResearchAgent/logic/planOrchestrator.d.ts.map +1 -1
- package/dist/mcp-server/tools/pubmedResearchAgent/logic/planOrchestrator.js +7 -4
- package/dist/mcp-server/tools/pubmedResearchAgent/logic/planOrchestrator.js.map +1 -1
- package/dist/mcp-server/tools/pubmedResearchAgent/registration.js.map +1 -1
- package/dist/mcp-server/tools/pubmedSearchArticles/index.d.ts +7 -0
- package/dist/mcp-server/tools/{searchPubMedArticles → pubmedSearchArticles}/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/pubmedSearchArticles/index.js +7 -0
- package/dist/mcp-server/tools/{searchPubMedArticles → pubmedSearchArticles}/index.js.map +1 -1
- package/dist/mcp-server/tools/{searchPubMedArticles → pubmedSearchArticles}/logic.d.ts +9 -9
- package/dist/mcp-server/tools/{searchPubMedArticles → pubmedSearchArticles}/logic.d.ts.map +1 -1
- package/dist/mcp-server/tools/{searchPubMedArticles → pubmedSearchArticles}/logic.js +16 -14
- package/dist/mcp-server/tools/{searchPubMedArticles → pubmedSearchArticles}/logic.js.map +1 -1
- package/dist/mcp-server/tools/pubmedSearchArticles/registration.d.ts +11 -0
- package/dist/mcp-server/tools/{searchPubMedArticles → pubmedSearchArticles}/registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/{searchPubMedArticles → pubmedSearchArticles}/registration.js +12 -12
- package/dist/mcp-server/tools/{searchPubMedArticles → pubmedSearchArticles}/registration.js.map +1 -1
- package/dist/mcp-server/transports/auth/index.d.ts +1 -1
- package/dist/mcp-server/transports/auth/index.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js +4 -0
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js +5 -0
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js.map +1 -1
- package/dist/mcp-server/transports/core/headerUtils.d.ts +20 -0
- package/dist/mcp-server/transports/core/headerUtils.d.ts.map +1 -0
- package/dist/mcp-server/transports/core/headerUtils.js +38 -0
- package/dist/mcp-server/transports/core/headerUtils.js.map +1 -0
- package/dist/mcp-server/transports/core/honoNodeBridge.d.ts +60 -7
- package/dist/mcp-server/transports/core/honoNodeBridge.d.ts.map +1 -1
- package/dist/mcp-server/transports/core/honoNodeBridge.js +99 -12
- package/dist/mcp-server/transports/core/honoNodeBridge.js.map +1 -1
- package/dist/mcp-server/transports/core/statefulTransportManager.d.ts +53 -8
- package/dist/mcp-server/transports/core/statefulTransportManager.d.ts.map +1 -1
- package/dist/mcp-server/transports/core/statefulTransportManager.js +180 -117
- package/dist/mcp-server/transports/core/statefulTransportManager.js.map +1 -1
- package/dist/mcp-server/transports/core/statelessTransportManager.d.ts +44 -7
- package/dist/mcp-server/transports/core/statelessTransportManager.d.ts.map +1 -1
- package/dist/mcp-server/transports/core/statelessTransportManager.js +84 -24
- package/dist/mcp-server/transports/core/statelessTransportManager.js.map +1 -1
- package/dist/mcp-server/transports/core/transportTypes.d.ts +58 -21
- package/dist/mcp-server/transports/core/transportTypes.d.ts.map +1 -1
- package/dist/mcp-server/transports/core/transportTypes.js +3 -1
- package/dist/mcp-server/transports/core/transportTypes.js.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.d.ts +3 -3
- package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.js +58 -20
- package/dist/mcp-server/transports/http/httpTransport.js.map +1 -1
- package/dist/mcp-server/transports/http/mcpTransportMiddleware.d.ts +4 -3
- package/dist/mcp-server/transports/http/mcpTransportMiddleware.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/mcpTransportMiddleware.js +28 -25
- package/dist/mcp-server/transports/http/mcpTransportMiddleware.js.map +1 -1
- package/dist/services/NCBI/core/ncbiConstants.d.ts +1 -1
- package/dist/services/NCBI/core/ncbiConstants.d.ts.map +1 -1
- package/dist/services/NCBI/core/ncbiCoreApiClient.d.ts.map +1 -1
- package/dist/services/NCBI/core/ncbiCoreApiClient.js +5 -4
- package/dist/services/NCBI/core/ncbiCoreApiClient.js.map +1 -1
- package/dist/services/NCBI/core/ncbiRequestQueueManager.d.ts +4 -4
- package/dist/services/NCBI/core/ncbiRequestQueueManager.d.ts.map +1 -1
- package/dist/services/NCBI/core/ncbiRequestQueueManager.js +6 -5
- package/dist/services/NCBI/core/ncbiRequestQueueManager.js.map +1 -1
- package/dist/services/NCBI/core/ncbiResponseHandler.d.ts +1 -1
- package/dist/services/NCBI/core/ncbiResponseHandler.d.ts.map +1 -1
- package/dist/services/NCBI/core/ncbiResponseHandler.js +1 -1
- package/dist/services/NCBI/core/ncbiResponseHandler.js.map +1 -1
- package/dist/services/NCBI/core/ncbiService.d.ts +3 -3
- package/dist/services/NCBI/core/ncbiService.d.ts.map +1 -1
- package/dist/services/NCBI/parsing/eSummaryResultParser.d.ts.map +1 -1
- package/dist/services/NCBI/parsing/eSummaryResultParser.js +2 -1
- package/dist/services/NCBI/parsing/eSummaryResultParser.js.map +1 -1
- package/dist/services/NCBI/parsing/pubmedArticleStructureParser.js +1 -1
- package/dist/services/NCBI/parsing/pubmedArticleStructureParser.js.map +1 -1
- package/dist/services/NCBI/parsing/xmlGenericHelpers.d.ts +2 -2
- package/dist/services/NCBI/parsing/xmlGenericHelpers.d.ts.map +1 -1
- package/dist/services/NCBI/parsing/xmlGenericHelpers.js +17 -23
- package/dist/services/NCBI/parsing/xmlGenericHelpers.js.map +1 -1
- package/dist/types-global/pubmedXml.d.ts +9 -9
- package/dist/types-global/pubmedXml.d.ts.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/internal/errorHandler.d.ts +0 -7
- package/dist/utils/internal/errorHandler.d.ts.map +1 -1
- package/dist/utils/internal/errorHandler.js +27 -11
- package/dist/utils/internal/errorHandler.js.map +1 -1
- package/dist/utils/internal/index.d.ts +1 -0
- package/dist/utils/internal/index.d.ts.map +1 -1
- package/dist/utils/internal/index.js +1 -0
- package/dist/utils/internal/index.js.map +1 -1
- package/dist/utils/internal/logger.d.ts.map +1 -1
- package/dist/utils/internal/logger.js +2 -0
- package/dist/utils/internal/logger.js.map +1 -1
- package/dist/utils/internal/performance.d.ts +22 -0
- package/dist/utils/internal/performance.d.ts.map +1 -0
- package/dist/utils/internal/performance.js +104 -0
- package/dist/utils/internal/performance.js.map +1 -0
- package/dist/utils/internal/requestContext.d.ts.map +1 -1
- package/dist/utils/internal/requestContext.js +10 -0
- package/dist/utils/internal/requestContext.js.map +1 -1
- package/dist/utils/metrics/tokenCounter.js +4 -4
- package/dist/utils/metrics/tokenCounter.js.map +1 -1
- package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -1
- package/dist/utils/network/fetchWithTimeout.js +18 -0
- package/dist/utils/network/fetchWithTimeout.js.map +1 -1
- package/dist/utils/parsing/dateParser.d.ts +2 -3
- package/dist/utils/parsing/dateParser.d.ts.map +1 -1
- package/dist/utils/parsing/dateParser.js +2 -2
- package/dist/utils/parsing/dateParser.js.map +1 -1
- package/dist/utils/parsing/jsonParser.d.ts +1 -1
- package/dist/utils/parsing/jsonParser.d.ts.map +1 -1
- package/dist/utils/parsing/jsonParser.js +5 -4
- package/dist/utils/parsing/jsonParser.js.map +1 -1
- package/dist/utils/security/idGenerator.d.ts.map +1 -1
- package/dist/utils/security/idGenerator.js +5 -1
- package/dist/utils/security/idGenerator.js.map +1 -1
- package/dist/utils/security/rateLimiter.d.ts.map +1 -1
- package/dist/utils/security/rateLimiter.js +22 -6
- package/dist/utils/security/rateLimiter.js.map +1 -1
- package/dist/utils/telemetry/instrumentation.d.ts +8 -0
- package/dist/utils/telemetry/instrumentation.d.ts.map +1 -0
- package/dist/utils/telemetry/instrumentation.js +179 -0
- package/dist/utils/telemetry/instrumentation.js.map +1 -0
- package/dist/utils/telemetry/semconv.d.ts +16 -0
- package/dist/utils/telemetry/semconv.d.ts.map +1 -0
- package/dist/utils/telemetry/semconv.js +16 -0
- package/dist/utils/telemetry/semconv.js.map +1 -0
- package/package.json +45 -17
- package/dist/mcp-server/tools/fetchPubMedContent/index.d.ts +0 -7
- package/dist/mcp-server/tools/fetchPubMedContent/index.d.ts.map +0 -1
- package/dist/mcp-server/tools/fetchPubMedContent/index.js +0 -7
- package/dist/mcp-server/tools/fetchPubMedContent/index.js.map +0 -1
- package/dist/mcp-server/tools/fetchPubMedContent/logic.d.ts.map +0 -1
- package/dist/mcp-server/tools/fetchPubMedContent/logic.js.map +0 -1
- package/dist/mcp-server/tools/fetchPubMedContent/registration.d.ts +0 -11
- package/dist/mcp-server/tools/fetchPubMedContent/registration.d.ts.map +0 -1
- package/dist/mcp-server/tools/fetchPubMedContent/registration.js.map +0 -1
- package/dist/mcp-server/tools/generatePubMedChart/index.d.ts.map +0 -1
- package/dist/mcp-server/tools/generatePubMedChart/index.js.map +0 -1
- package/dist/mcp-server/tools/generatePubMedChart/logic.js.map +0 -1
- package/dist/mcp-server/tools/generatePubMedChart/registration.d.ts +0 -8
- package/dist/mcp-server/tools/generatePubMedChart/registration.js.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/index.d.ts +0 -7
- package/dist/mcp-server/tools/getPubMedArticleConnections/index.d.ts.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/index.js +0 -7
- package/dist/mcp-server/tools/getPubMedArticleConnections/index.js.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/citationFormatter.d.ts +0 -10
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/citationFormatter.d.ts.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/citationFormatter.js.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/elinkHandler.d.ts +0 -10
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/elinkHandler.d.ts.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/elinkHandler.js.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/index.d.ts.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/index.js.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/types.d.ts.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/types.js +0 -6
- package/dist/mcp-server/tools/getPubMedArticleConnections/logic/types.js.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/registration.d.ts +0 -12
- package/dist/mcp-server/tools/getPubMedArticleConnections/registration.d.ts.map +0 -1
- package/dist/mcp-server/tools/getPubMedArticleConnections/registration.js.map +0 -1
- package/dist/mcp-server/tools/searchPubMedArticles/index.d.ts +0 -7
- package/dist/mcp-server/tools/searchPubMedArticles/index.js +0 -7
- package/dist/mcp-server/tools/searchPubMedArticles/registration.d.ts +0 -11
|
@@ -1,89 +1,138 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* @fileoverview Implements a stateful transport manager for the MCP SDK.
|
|
3
|
+
*
|
|
4
|
+
* This manager handles multiple, persistent MCP sessions. It creates and maintains
|
|
5
|
+
* a dedicated McpServer and StreamableHTTPServerTransport instance for each session,
|
|
6
|
+
* allowing for stateful, multi-turn interactions. It includes robust mechanisms for
|
|
7
|
+
* session lifecycle management, including garbage collection of stale sessions and
|
|
8
|
+
* concurrency controls to prevent race conditions.
|
|
9
|
+
*
|
|
10
|
+
* SCALABILITY NOTE: This manager maintains all session state in local process memory.
|
|
11
|
+
* For horizontal scaling across multiple server instances, a load balancer with
|
|
12
|
+
* sticky sessions (session affinity) is required to ensure that all requests for a
|
|
13
|
+
* given session are routed to the same process instance that holds that session's state.
|
|
14
|
+
*
|
|
7
15
|
* @module src/mcp-server/transports/core/statefulTransportManager
|
|
8
16
|
*/
|
|
9
17
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
10
18
|
import { randomUUID } from "node:crypto";
|
|
11
19
|
import { Readable } from "stream";
|
|
12
|
-
import { config } from "../../../config/index.js";
|
|
13
20
|
import { BaseErrorCode, McpError } from "../../../types-global/errors.js";
|
|
14
21
|
import { ErrorHandler, logger, requestContextService, } from "../../../utils/index.js";
|
|
15
22
|
import { BaseTransportManager } from "./baseTransportManager.js";
|
|
16
23
|
import { HonoStreamResponse } from "./honoNodeBridge.js";
|
|
24
|
+
import { convertNodeHeadersToWebHeaders } from "./headerUtils.js";
|
|
17
25
|
/**
|
|
18
|
-
*
|
|
19
|
-
* for a Hono-based HTTP server.
|
|
26
|
+
* Manages persistent, stateful MCP sessions.
|
|
20
27
|
*/
|
|
21
28
|
export class StatefulTransportManager extends BaseTransportManager {
|
|
22
29
|
transports = new Map();
|
|
23
30
|
servers = new Map();
|
|
24
31
|
sessions = new Map();
|
|
25
32
|
garbageCollector;
|
|
26
|
-
|
|
33
|
+
options;
|
|
34
|
+
/**
|
|
35
|
+
* @param createServerInstanceFn - A factory function to create new McpServer instances.
|
|
36
|
+
* @param options - Configuration options for the manager.
|
|
37
|
+
*/
|
|
38
|
+
constructor(createServerInstanceFn, options) {
|
|
27
39
|
super(createServerInstanceFn);
|
|
40
|
+
this.options = options;
|
|
28
41
|
const context = requestContextService.createRequestContext({
|
|
29
42
|
operation: "StatefulTransportManager.constructor",
|
|
30
43
|
});
|
|
31
44
|
logger.info("Starting session garbage collector.", context);
|
|
32
|
-
this.garbageCollector = setInterval(() => this.cleanupStaleSessions(),
|
|
45
|
+
this.garbageCollector = setInterval(() => this.cleanupStaleSessions(), this.options.staleSessionTimeoutMs);
|
|
33
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Initializes a new stateful session and handles the first request.
|
|
49
|
+
*
|
|
50
|
+
* @param headers - The incoming request headers.
|
|
51
|
+
* @param body - The parsed body of the request.
|
|
52
|
+
* @param context - The request context.
|
|
53
|
+
* @returns A promise resolving to a streaming TransportResponse with a session ID.
|
|
54
|
+
*/
|
|
34
55
|
async initializeAndHandle(headers, body, context) {
|
|
35
|
-
const
|
|
36
|
-
|
|
56
|
+
const opContext = {
|
|
57
|
+
...context,
|
|
58
|
+
operation: "StatefulTransportManager.initializeAndHandle",
|
|
59
|
+
};
|
|
37
60
|
logger.debug("Initializing new stateful session.", opContext);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
let server;
|
|
62
|
+
let transport;
|
|
63
|
+
try {
|
|
64
|
+
server = await this.createServerInstanceFn();
|
|
65
|
+
const mockRes = new HonoStreamResponse();
|
|
66
|
+
const currentServer = server;
|
|
67
|
+
transport = new StreamableHTTPServerTransport({
|
|
68
|
+
sessionIdGenerator: () => randomUUID(),
|
|
69
|
+
onsessioninitialized: (sessionId) => {
|
|
70
|
+
const sessionContext = { ...opContext, sessionId };
|
|
71
|
+
this.transports.set(sessionId, transport);
|
|
72
|
+
this.servers.set(sessionId, currentServer);
|
|
73
|
+
this.sessions.set(sessionId, {
|
|
74
|
+
id: sessionId,
|
|
75
|
+
createdAt: new Date(),
|
|
76
|
+
lastAccessedAt: new Date(),
|
|
77
|
+
activeRequests: 0,
|
|
78
|
+
});
|
|
79
|
+
logger.info(`MCP Session created: ${sessionId}`, sessionContext);
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
transport.onclose = () => {
|
|
83
|
+
const sessionId = transport.sessionId;
|
|
84
|
+
if (sessionId) {
|
|
85
|
+
const closeContext = { ...opContext, sessionId };
|
|
86
|
+
this.closeSession(sessionId, closeContext).catch((err) => logger.error(`Error during transport.onclose cleanup for session ${sessionId}`, err, closeContext));
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
await server.connect(transport);
|
|
90
|
+
logger.debug("Server connected, handling initial request.", opContext);
|
|
91
|
+
const mockReq = {
|
|
92
|
+
headers,
|
|
93
|
+
method: "POST",
|
|
94
|
+
url: this.options.mcpHttpEndpointPath,
|
|
95
|
+
};
|
|
96
|
+
await transport.handleRequest(mockReq, mockRes, body);
|
|
97
|
+
const responseHeaders = convertNodeHeadersToWebHeaders(mockRes.getHeaders());
|
|
98
|
+
if (transport.sessionId) {
|
|
99
|
+
responseHeaders.set("Mcp-Session-Id", transport.sessionId);
|
|
62
100
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
await transport.handleRequest(mockReq, mockRes, body);
|
|
72
|
-
const responseHeaders = new Headers();
|
|
73
|
-
for (const [key, value] of Object.entries(mockRes.getHeaders())) {
|
|
74
|
-
responseHeaders.set(key, Array.isArray(value) ? value.join(", ") : String(value));
|
|
101
|
+
const webStream = Readable.toWeb(mockRes);
|
|
102
|
+
return {
|
|
103
|
+
type: "stream",
|
|
104
|
+
headers: responseHeaders,
|
|
105
|
+
statusCode: mockRes.statusCode,
|
|
106
|
+
stream: webStream,
|
|
107
|
+
sessionId: transport.sessionId,
|
|
108
|
+
};
|
|
75
109
|
}
|
|
76
|
-
|
|
77
|
-
|
|
110
|
+
catch (error) {
|
|
111
|
+
logger.error("Failed to initialize stateful session. Cleaning up orphaned resources.", error instanceof Error ? error : undefined, { ...opContext, error: String(error) });
|
|
112
|
+
const sessionInitialized = transport?.sessionId && this.transports.has(transport.sessionId);
|
|
113
|
+
if (!sessionInitialized) {
|
|
114
|
+
(async () => {
|
|
115
|
+
await ErrorHandler.tryCatch(async () => {
|
|
116
|
+
if (transport)
|
|
117
|
+
await transport.close();
|
|
118
|
+
if (server)
|
|
119
|
+
await server.close();
|
|
120
|
+
}, {
|
|
121
|
+
operation: "initializeAndHandle.cleanupOrphaned",
|
|
122
|
+
context: opContext,
|
|
123
|
+
});
|
|
124
|
+
})();
|
|
125
|
+
}
|
|
126
|
+
throw ErrorHandler.handleError(error, {
|
|
127
|
+
operation: opContext.operation,
|
|
128
|
+
context: opContext,
|
|
129
|
+
rethrow: true,
|
|
130
|
+
});
|
|
78
131
|
}
|
|
79
|
-
const webStream = Readable.toWeb(mockRes);
|
|
80
|
-
return {
|
|
81
|
-
headers: responseHeaders,
|
|
82
|
-
statusCode: mockRes.statusCode,
|
|
83
|
-
stream: webStream,
|
|
84
|
-
sessionId: transport.sessionId,
|
|
85
|
-
};
|
|
86
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Handles a subsequent request for an existing stateful session.
|
|
135
|
+
*/
|
|
87
136
|
async handleRequest(headers, body, context, sessionId) {
|
|
88
137
|
if (!sessionId) {
|
|
89
138
|
throw new McpError(BaseErrorCode.INVALID_INPUT, "Session ID is required for stateful requests.", context);
|
|
@@ -93,14 +142,12 @@ export class StatefulTransportManager extends BaseTransportManager {
|
|
|
93
142
|
sessionId,
|
|
94
143
|
operation: "StatefulTransportManager.handleRequest",
|
|
95
144
|
};
|
|
96
|
-
logger.debug(`Handling request for session: ${sessionId}`, {
|
|
97
|
-
...sessionContext,
|
|
98
|
-
method: headers["x-forwarded-proto"] || "http",
|
|
99
|
-
});
|
|
100
145
|
const transport = this.transports.get(sessionId);
|
|
101
|
-
|
|
146
|
+
const session = this.sessions.get(sessionId);
|
|
147
|
+
if (!transport || !session) {
|
|
102
148
|
logger.warning(`Request for non-existent session: ${sessionId}`, sessionContext);
|
|
103
149
|
return {
|
|
150
|
+
type: "buffered",
|
|
104
151
|
headers: new Headers({ "Content-Type": "application/json" }),
|
|
105
152
|
statusCode: 404,
|
|
106
153
|
body: {
|
|
@@ -109,29 +156,43 @@ export class StatefulTransportManager extends BaseTransportManager {
|
|
|
109
156
|
},
|
|
110
157
|
};
|
|
111
158
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
159
|
+
session.lastAccessedAt = new Date();
|
|
160
|
+
session.activeRequests += 1;
|
|
161
|
+
logger.debug(`Incremented activeRequests for session ${sessionId}. Count: ${session.activeRequests}`, sessionContext);
|
|
162
|
+
try {
|
|
163
|
+
const mockReq = {
|
|
164
|
+
headers,
|
|
165
|
+
method: "POST",
|
|
166
|
+
url: this.options.mcpHttpEndpointPath,
|
|
167
|
+
};
|
|
168
|
+
const mockRes = new HonoStreamResponse();
|
|
169
|
+
await transport.handleRequest(mockReq, mockRes, body);
|
|
170
|
+
const responseHeaders = convertNodeHeadersToWebHeaders(mockRes.getHeaders());
|
|
171
|
+
const webStream = Readable.toWeb(mockRes);
|
|
172
|
+
return {
|
|
173
|
+
type: "stream",
|
|
174
|
+
headers: responseHeaders,
|
|
175
|
+
statusCode: mockRes.statusCode,
|
|
176
|
+
stream: webStream,
|
|
177
|
+
sessionId: transport.sessionId,
|
|
178
|
+
};
|
|
116
179
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
180
|
+
catch (error) {
|
|
181
|
+
throw ErrorHandler.handleError(error, {
|
|
182
|
+
operation: sessionContext.operation,
|
|
183
|
+
context: sessionContext,
|
|
184
|
+
rethrow: true,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
session.activeRequests -= 1;
|
|
189
|
+
session.lastAccessedAt = new Date();
|
|
190
|
+
logger.debug(`Decremented activeRequests for session ${sessionId}. Count: ${session.activeRequests}`, sessionContext);
|
|
126
191
|
}
|
|
127
|
-
const webStream = Readable.toWeb(mockRes);
|
|
128
|
-
return {
|
|
129
|
-
headers: responseHeaders,
|
|
130
|
-
statusCode: mockRes.statusCode,
|
|
131
|
-
stream: webStream,
|
|
132
|
-
sessionId: transport.sessionId,
|
|
133
|
-
};
|
|
134
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Handles a request to explicitly delete a session.
|
|
195
|
+
*/
|
|
135
196
|
async handleDeleteRequest(sessionId, context) {
|
|
136
197
|
const sessionContext = {
|
|
137
198
|
...context,
|
|
@@ -139,28 +200,27 @@ export class StatefulTransportManager extends BaseTransportManager {
|
|
|
139
200
|
operation: "StatefulTransportManager.handleDeleteRequest",
|
|
140
201
|
};
|
|
141
202
|
logger.info(`Attempting to delete session: ${sessionId}`, sessionContext);
|
|
142
|
-
|
|
143
|
-
if (!transport) {
|
|
203
|
+
if (!this.transports.has(sessionId)) {
|
|
144
204
|
logger.warning(`Attempted to delete non-existent session: ${sessionId}`, sessionContext);
|
|
145
205
|
throw new McpError(BaseErrorCode.NOT_FOUND, "Session not found or expired.", sessionContext);
|
|
146
206
|
}
|
|
147
207
|
await this.closeSession(sessionId, sessionContext);
|
|
148
|
-
const headers = new Headers();
|
|
149
|
-
headers.set("Content-Type", "application/json");
|
|
150
208
|
return {
|
|
151
|
-
|
|
209
|
+
type: "buffered",
|
|
210
|
+
headers: new Headers({ "Content-Type": "application/json" }),
|
|
152
211
|
statusCode: 200,
|
|
153
212
|
body: { status: "session_closed", sessionId },
|
|
154
213
|
};
|
|
155
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Retrieves information about a specific session.
|
|
217
|
+
*/
|
|
156
218
|
getSession(sessionId) {
|
|
157
|
-
const context = requestContextService.createRequestContext({
|
|
158
|
-
operation: "StatefulTransportManager.getSession",
|
|
159
|
-
sessionId,
|
|
160
|
-
});
|
|
161
|
-
logger.debug(`Retrieving session: ${sessionId}`, context);
|
|
162
219
|
return this.sessions.get(sessionId);
|
|
163
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* Gracefully shuts down the manager, closing all active sessions.
|
|
223
|
+
*/
|
|
164
224
|
async shutdown() {
|
|
165
225
|
const context = requestContextService.createRequestContext({
|
|
166
226
|
operation: "StatefulTransportManager.shutdown",
|
|
@@ -169,14 +229,19 @@ export class StatefulTransportManager extends BaseTransportManager {
|
|
|
169
229
|
clearInterval(this.garbageCollector);
|
|
170
230
|
logger.debug("Garbage collector stopped.", context);
|
|
171
231
|
const sessionIds = Array.from(this.transports.keys());
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
232
|
+
if (sessionIds.length > 0) {
|
|
233
|
+
logger.info(`Closing ${sessionIds.length} active sessions.`, context);
|
|
234
|
+
const closePromises = sessionIds.map((sessionId) => this.closeSession(sessionId, context));
|
|
235
|
+
await Promise.all(closePromises);
|
|
236
|
+
}
|
|
175
237
|
this.transports.clear();
|
|
176
238
|
this.sessions.clear();
|
|
177
239
|
this.servers.clear();
|
|
178
240
|
logger.info("All active sessions closed and manager shut down.", context);
|
|
179
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* Closes a single session and releases its associated resources.
|
|
244
|
+
*/
|
|
180
245
|
async closeSession(sessionId, context) {
|
|
181
246
|
const sessionContext = {
|
|
182
247
|
...context,
|
|
@@ -187,45 +252,43 @@ export class StatefulTransportManager extends BaseTransportManager {
|
|
|
187
252
|
const transport = this.transports.get(sessionId);
|
|
188
253
|
const server = this.servers.get(sessionId);
|
|
189
254
|
await ErrorHandler.tryCatch(async () => {
|
|
190
|
-
if (transport)
|
|
255
|
+
if (transport)
|
|
191
256
|
await transport.close();
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
if (server) {
|
|
257
|
+
if (server)
|
|
195
258
|
await server.close();
|
|
196
|
-
|
|
197
|
-
}
|
|
198
|
-
}, {
|
|
199
|
-
operation: "closeSession.cleanup",
|
|
200
|
-
context: sessionContext,
|
|
201
|
-
});
|
|
259
|
+
}, { operation: "closeSession.cleanup", context: sessionContext });
|
|
202
260
|
this.transports.delete(sessionId);
|
|
203
261
|
this.servers.delete(sessionId);
|
|
204
262
|
this.sessions.delete(sessionId);
|
|
205
263
|
logger.info(`MCP Session closed and resources released: ${sessionId}`, sessionContext);
|
|
206
264
|
}
|
|
265
|
+
/**
|
|
266
|
+
* Periodically runs to find and clean up stale, inactive sessions.
|
|
267
|
+
*/
|
|
207
268
|
async cleanupStaleSessions() {
|
|
208
269
|
const context = requestContextService.createRequestContext({
|
|
209
270
|
operation: "StatefulTransportManager.cleanupStaleSessions",
|
|
210
271
|
});
|
|
211
272
|
logger.debug("Running stale session cleanup...", context);
|
|
212
273
|
const now = Date.now();
|
|
213
|
-
const STALE_TIMEOUT_MS =
|
|
214
|
-
|
|
274
|
+
const STALE_TIMEOUT_MS = this.options.staleSessionTimeoutMs;
|
|
275
|
+
const staleSessionIds = [];
|
|
215
276
|
for (const [sessionId, session] of this.sessions.entries()) {
|
|
216
277
|
if (now - session.lastAccessedAt.getTime() > STALE_TIMEOUT_MS) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
};
|
|
223
|
-
logger.info(`Found stale session, closing: ${sessionId}`, sessionContext);
|
|
224
|
-
await this.closeSession(sessionId, sessionContext);
|
|
278
|
+
if (session.activeRequests > 0) {
|
|
279
|
+
logger.info(`Session ${sessionId} is stale but has ${session.activeRequests} active requests. Skipping cleanup.`, { ...context, sessionId });
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
staleSessionIds.push(sessionId);
|
|
225
283
|
}
|
|
226
284
|
}
|
|
227
|
-
if (
|
|
228
|
-
logger.info(`
|
|
285
|
+
if (staleSessionIds.length > 0) {
|
|
286
|
+
logger.info(`Found ${staleSessionIds.length} stale sessions. Closing concurrently.`, context);
|
|
287
|
+
const closePromises = staleSessionIds.map((sessionId) => this.closeSession(sessionId, context).catch((err) => {
|
|
288
|
+
logger.error(`Error during concurrent stale session cleanup for ${sessionId}`, err, { ...context, sessionId });
|
|
289
|
+
}));
|
|
290
|
+
await Promise.all(closePromises);
|
|
291
|
+
logger.info(`Stale session cleanup complete. Closed ${staleSessionIds.length} sessions.`, context);
|
|
229
292
|
}
|
|
230
293
|
else {
|
|
231
294
|
logger.debug("No stale sessions found.", context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statefulTransportManager.js","sourceRoot":"","sources":["../../../../src/mcp-server/transports/core/statefulTransportManager.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"statefulTransportManager.js","sourceRoot":"","sources":["../../../../src/mcp-server/transports/core/statefulTransportManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* request
|
|
2
|
+
* @fileoverview Implements a stateless transport manager for the MCP SDK.
|
|
3
|
+
*
|
|
4
|
+
* This manager handles single, ephemeral MCP operations. For each incoming request,
|
|
5
|
+
* it dynamically creates a temporary McpServer and transport instance, processes the
|
|
6
|
+
* request, and then immediately schedules the resources for cleanup. This approach
|
|
7
|
+
* is ideal for simple, one-off tool calls that do not require persistent session state.
|
|
8
|
+
*
|
|
9
|
+
* The key challenge addressed here is bridging the Node.js-centric MCP SDK with
|
|
10
|
+
* modern, Web Standards-based frameworks like Hono. This is achieved by deferring
|
|
11
|
+
* resource cleanup until the response stream has been fully consumed by the web
|
|
12
|
+
* framework, preventing premature closure and truncated responses.
|
|
13
|
+
*
|
|
7
14
|
* @module src/mcp-server/transports/core/statelessTransportManager
|
|
8
15
|
*/
|
|
9
16
|
import type { IncomingHttpHeaders } from "http";
|
|
@@ -11,11 +18,41 @@ import { RequestContext } from "../../../utils/index.js";
|
|
|
11
18
|
import { BaseTransportManager } from "./baseTransportManager.js";
|
|
12
19
|
import { TransportResponse } from "./transportTypes.js";
|
|
13
20
|
/**
|
|
14
|
-
*
|
|
21
|
+
* Manages ephemeral, single-request MCP operations.
|
|
15
22
|
*/
|
|
16
23
|
export declare class StatelessTransportManager extends BaseTransportManager {
|
|
24
|
+
/**
|
|
25
|
+
* Handles a single, stateless MCP request.
|
|
26
|
+
*
|
|
27
|
+
* This method orchestrates the creation of temporary server and transport instances,
|
|
28
|
+
* handles the request, and ensures resources are cleaned up only after the
|
|
29
|
+
* response stream is closed.
|
|
30
|
+
*
|
|
31
|
+
* @param headers - The incoming request headers.
|
|
32
|
+
* @param body - The parsed body of the request.
|
|
33
|
+
* @param context - The request context for logging and tracing.
|
|
34
|
+
* @returns A promise resolving to a streaming TransportResponse.
|
|
35
|
+
*/
|
|
17
36
|
handleRequest(headers: IncomingHttpHeaders, body: unknown, context: RequestContext): Promise<TransportResponse>;
|
|
18
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Attaches listeners to the response stream to trigger resource cleanup
|
|
39
|
+
* only after the stream has been fully consumed or has errored.
|
|
40
|
+
*
|
|
41
|
+
* @param stream - The response stream bridge.
|
|
42
|
+
* @param server - The ephemeral McpServer instance.
|
|
43
|
+
* @param transport - The ephemeral transport instance.
|
|
44
|
+
* @param context - The request context for logging.
|
|
45
|
+
*/
|
|
46
|
+
private setupDeferredCleanup;
|
|
47
|
+
/**
|
|
48
|
+
* Performs the actual cleanup of ephemeral resources.
|
|
49
|
+
* This method is designed to be "fire-and-forget".
|
|
50
|
+
*/
|
|
19
51
|
private cleanup;
|
|
52
|
+
/**
|
|
53
|
+
* Shuts down the manager. For the stateless manager, this is a no-op
|
|
54
|
+
* as there are no persistent resources to manage.
|
|
55
|
+
*/
|
|
56
|
+
shutdown(): Promise<void>;
|
|
20
57
|
}
|
|
21
58
|
//# sourceMappingURL=statelessTransportManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statelessTransportManager.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/transports/core/statelessTransportManager.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"statelessTransportManager.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/transports/core/statelessTransportManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAkB,MAAM,MAAM,CAAC;AAEhE,OAAO,EAGL,cAAc,EAEf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGjE,OAAO,EAAkB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExE;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,oBAAoB;IACjE;;;;;;;;;;;OAWG;IACG,aAAa,CACjB,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,iBAAiB,CAAC;IAoE7B;;;;;;;;OAQG;IACH,OAAO,CAAC,oBAAoB;IA0B5B;;;OAGG;IACH,OAAO,CAAC,OAAO;IA0Bf;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAUhC"}
|