@1mcp/agent 0.11.0 → 0.13.0
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 +45 -50
- package/build/auth/clientSessionManager.d.ts +94 -0
- package/build/auth/clientSessionManager.d.ts.map +1 -0
- package/build/auth/clientSessionManager.js +220 -0
- package/build/auth/clientSessionManager.js.map +1 -0
- package/build/auth/sdkOAuthClientProvider.d.ts +93 -0
- package/build/auth/sdkOAuthClientProvider.d.ts.map +1 -0
- package/build/auth/sdkOAuthClientProvider.js +199 -0
- package/build/auth/sdkOAuthClientProvider.js.map +1 -0
- package/build/auth/sdkOAuthServerProvider.d.ts +63 -0
- package/build/auth/sdkOAuthServerProvider.d.ts.map +1 -0
- package/build/auth/sdkOAuthServerProvider.js +428 -0
- package/build/auth/sdkOAuthServerProvider.js.map +1 -0
- package/build/{server/auth/sessionManager.d.ts → auth/serverSessionManager.d.ts} +26 -37
- package/build/auth/serverSessionManager.d.ts.map +1 -0
- package/build/{server/auth/sessionManager.js → auth/serverSessionManager.js} +104 -19
- package/build/auth/serverSessionManager.js.map +1 -0
- package/build/auth/sessionTypes.d.ts +24 -0
- package/build/auth/sessionTypes.d.ts.map +1 -0
- package/build/auth/sessionTypes.js +3 -0
- package/build/auth/sessionTypes.js.map +1 -0
- package/build/capabilities/capabilityManager.d.ts +2 -2
- package/build/capabilities/capabilityManager.d.ts.map +1 -1
- package/build/capabilities/capabilityManager.js +40 -7
- package/build/capabilities/capabilityManager.js.map +1 -1
- package/build/config/{configManager.d.ts → mcpConfigManager.d.ts} +18 -7
- package/build/config/mcpConfigManager.d.ts.map +1 -0
- package/build/config/{configManager.js → mcpConfigManager.js} +50 -10
- package/build/config/mcpConfigManager.js.map +1 -0
- package/build/constants.d.ts +36 -14
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +40 -17
- package/build/constants.js.map +1 -1
- package/build/{client.d.ts → core/client/clientFactory.d.ts} +1 -1
- package/build/core/client/clientFactory.d.ts.map +1 -0
- package/build/{client.js → core/client/clientFactory.js} +2 -2
- package/build/core/client/clientFactory.js.map +1 -0
- package/build/{clients → core/client}/clientManager.d.ts +14 -6
- package/build/core/client/clientManager.d.ts.map +1 -0
- package/build/core/client/clientManager.js +209 -0
- package/build/core/client/clientManager.js.map +1 -0
- package/build/{server/config/serverConfig.d.ts → core/server/agentConfig.d.ts} +50 -15
- package/build/core/server/agentConfig.d.ts.map +1 -0
- package/build/core/server/agentConfig.js +166 -0
- package/build/core/server/agentConfig.js.map +1 -0
- package/build/core/server/serverManager.d.ts +39 -0
- package/build/core/server/serverManager.d.ts.map +1 -0
- package/build/core/server/serverManager.js +169 -0
- package/build/core/server/serverManager.js.map +1 -0
- package/build/core/types/client.d.ts +51 -0
- package/build/core/types/client.d.ts.map +1 -0
- package/build/core/types/client.js +15 -0
- package/build/core/types/client.js.map +1 -0
- package/build/core/types/index.d.ts +4 -0
- package/build/core/types/index.d.ts.map +1 -0
- package/build/core/types/index.js +5 -0
- package/build/core/types/index.js.map +1 -0
- package/build/core/types/server.d.ts +14 -0
- package/build/core/types/server.d.ts.map +1 -0
- package/build/core/types/server.js +2 -0
- package/build/core/types/server.js.map +1 -0
- package/build/{types.d.ts → core/types/transport.d.ts} +59 -49
- package/build/core/types/transport.d.ts.map +1 -0
- package/build/{types.js → core/types/transport.js} +11 -13
- package/build/core/types/transport.js.map +1 -0
- package/build/handlers/notificationHandlers.d.ts +3 -3
- package/build/handlers/notificationHandlers.d.ts.map +1 -1
- package/build/handlers/notificationHandlers.js +13 -9
- package/build/handlers/notificationHandlers.js.map +1 -1
- package/build/handlers/requestHandlers.d.ts +2 -2
- package/build/handlers/requestHandlers.d.ts.map +1 -1
- package/build/handlers/requestHandlers.js +25 -3
- package/build/handlers/requestHandlers.js.map +1 -1
- package/build/index.js +48 -8
- package/build/index.js.map +1 -1
- package/build/logger/logger.js +1 -1
- package/build/logger/logger.js.map +1 -1
- package/build/{middleware/loggingMiddleware.d.ts → logger/mcpLoggingEnhancer.d.ts} +1 -1
- package/build/logger/mcpLoggingEnhancer.d.ts.map +1 -0
- package/build/{middleware/loggingMiddleware.js → logger/mcpLoggingEnhancer.js} +2 -2
- package/build/logger/mcpLoggingEnhancer.js.map +1 -0
- package/build/server.d.ts +1 -1
- package/build/server.d.ts.map +1 -1
- package/build/server.js +9 -6
- package/build/server.js.map +1 -1
- package/build/services/configReloadService.d.ts +15 -5
- package/build/services/configReloadService.d.ts.map +1 -1
- package/build/services/configReloadService.js +31 -14
- package/build/services/configReloadService.js.map +1 -1
- package/build/transport/http/middlewares/errorHandler.d.ts.map +1 -0
- package/build/{server → transport/http/middlewares}/errorHandler.js +1 -1
- package/build/transport/http/middlewares/errorHandler.js.map +1 -0
- package/build/transport/http/middlewares/scopeAuthMiddleware.d.ts +42 -0
- package/build/transport/http/middlewares/scopeAuthMiddleware.d.ts.map +1 -0
- package/build/transport/http/middlewares/scopeAuthMiddleware.js +136 -0
- package/build/transport/http/middlewares/scopeAuthMiddleware.js.map +1 -0
- package/build/transport/http/middlewares/securityMiddleware.d.ts +30 -0
- package/build/transport/http/middlewares/securityMiddleware.d.ts.map +1 -0
- package/build/transport/http/middlewares/securityMiddleware.js +201 -0
- package/build/transport/http/middlewares/securityMiddleware.js.map +1 -0
- package/build/transport/http/middlewares/tagsExtractor.d.ts.map +1 -0
- package/build/transport/http/middlewares/tagsExtractor.js.map +1 -0
- package/build/transport/http/routes/oauthRoutes.d.ts +4 -0
- package/build/transport/http/routes/oauthRoutes.d.ts.map +1 -0
- package/build/transport/http/routes/oauthRoutes.js +474 -0
- package/build/transport/http/routes/oauthRoutes.js.map +1 -0
- package/build/transport/http/routes/sseRoutes.d.ts +4 -0
- package/build/transport/http/routes/sseRoutes.d.ts.map +1 -0
- package/build/{server → transport/http}/routes/sseRoutes.js +12 -10
- package/build/transport/http/routes/sseRoutes.js.map +1 -0
- package/build/transport/http/routes/streamableHttpRoutes.d.ts +4 -0
- package/build/transport/http/routes/streamableHttpRoutes.d.ts.map +1 -0
- package/build/{server → transport/http}/routes/streamableHttpRoutes.js +46 -13
- package/build/transport/http/routes/streamableHttpRoutes.js.map +1 -0
- package/build/{server/expressServer.d.ts → transport/http/server.d.ts} +5 -4
- package/build/transport/http/server.d.ts.map +1 -0
- package/build/{server/expressServer.js → transport/http/server.js} +60 -23
- package/build/transport/http/server.js.map +1 -0
- package/build/transport/transportFactory.d.ts +9 -0
- package/build/transport/transportFactory.d.ts.map +1 -0
- package/build/transport/transportFactory.js +148 -0
- package/build/transport/transportFactory.js.map +1 -0
- package/build/utils/clientFiltering.d.ts +4 -4
- package/build/utils/clientFiltering.d.ts.map +1 -1
- package/build/utils/clientFiltering.js +14 -14
- package/build/utils/clientFiltering.js.map +1 -1
- package/build/utils/errorHandling.d.ts +0 -11
- package/build/utils/errorHandling.d.ts.map +1 -1
- package/build/utils/errorHandling.js +1 -18
- package/build/utils/errorHandling.js.map +1 -1
- package/build/utils/errorTypes.js +4 -4
- package/build/utils/errorTypes.js.map +1 -1
- package/build/utils/pagination.d.ts +2 -2
- package/build/utils/pagination.d.ts.map +1 -1
- package/build/utils/pagination.js +87 -8
- package/build/utils/pagination.js.map +1 -1
- package/build/utils/parsing.d.ts +13 -0
- package/build/utils/parsing.d.ts.map +1 -0
- package/build/utils/parsing.js +32 -0
- package/build/utils/parsing.js.map +1 -0
- package/build/utils/sanitization.d.ts +60 -0
- package/build/utils/sanitization.d.ts.map +1 -0
- package/build/utils/sanitization.js +149 -0
- package/build/utils/sanitization.js.map +1 -0
- package/build/utils/scopeValidation.d.ts +102 -0
- package/build/utils/scopeValidation.d.ts.map +1 -0
- package/build/utils/scopeValidation.js +244 -0
- package/build/utils/scopeValidation.js.map +1 -0
- package/package.json +23 -9
- package/build/client.d.ts.map +0 -1
- package/build/client.js.map +0 -1
- package/build/clients/clientManager.d.ts.map +0 -1
- package/build/clients/clientManager.js +0 -147
- package/build/clients/clientManager.js.map +0 -1
- package/build/config/configManager.d.ts.map +0 -1
- package/build/config/configManager.js.map +0 -1
- package/build/config/transportConfig.d.ts +0 -7
- package/build/config/transportConfig.d.ts.map +0 -1
- package/build/config/transportConfig.js +0 -90
- package/build/config/transportConfig.js.map +0 -1
- package/build/middleware/loggingMiddleware.d.ts.map +0 -1
- package/build/middleware/loggingMiddleware.js.map +0 -1
- package/build/server/auth/authManager.d.ts +0 -109
- package/build/server/auth/authManager.d.ts.map +0 -1
- package/build/server/auth/authManager.js +0 -173
- package/build/server/auth/authManager.js.map +0 -1
- package/build/server/auth/authMiddleware.d.ts +0 -16
- package/build/server/auth/authMiddleware.d.ts.map +0 -1
- package/build/server/auth/authMiddleware.js +0 -45
- package/build/server/auth/authMiddleware.js.map +0 -1
- package/build/server/auth/sessionManager.d.ts.map +0 -1
- package/build/server/auth/sessionManager.js.map +0 -1
- package/build/server/config/serverConfig.d.ts.map +0 -1
- package/build/server/config/serverConfig.js +0 -117
- package/build/server/config/serverConfig.js.map +0 -1
- package/build/server/errorHandler.d.ts.map +0 -1
- package/build/server/errorHandler.js.map +0 -1
- package/build/server/expressServer.d.ts.map +0 -1
- package/build/server/expressServer.js.map +0 -1
- package/build/server/routes/oauthRoutes.d.ts +0 -14
- package/build/server/routes/oauthRoutes.d.ts.map +0 -1
- package/build/server/routes/oauthRoutes.js +0 -132
- package/build/server/routes/oauthRoutes.js.map +0 -1
- package/build/server/routes/sseRoutes.d.ts +0 -4
- package/build/server/routes/sseRoutes.d.ts.map +0 -1
- package/build/server/routes/sseRoutes.js.map +0 -1
- package/build/server/routes/streamableHttpRoutes.d.ts +0 -4
- package/build/server/routes/streamableHttpRoutes.d.ts.map +0 -1
- package/build/server/routes/streamableHttpRoutes.js.map +0 -1
- package/build/server/tagsExtractor.d.ts.map +0 -1
- package/build/server/tagsExtractor.js.map +0 -1
- package/build/serverManager.d.ts +0 -27
- package/build/serverManager.d.ts.map +0 -1
- package/build/serverManager.js +0 -87
- package/build/serverManager.js.map +0 -1
- package/build/types.d.ts.map +0 -1
- package/build/types.js.map +0 -1
- /package/build/{server → transport/http/middlewares}/errorHandler.d.ts +0 -0
- /package/build/{server → transport/http/middlewares}/tagsExtractor.d.ts +0 -0
- /package/build/{server → transport/http/middlewares}/tagsExtractor.js +0 -0
package/build/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAI/D;;GAEG;AACH,iBAAe,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC,CA2BnD;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
package/build/server.js
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { MCP_SERVER_CAPABILITIES, MCP_SERVER_NAME, MCP_SERVER_VERSION } from './constants.js';
|
|
2
2
|
import logger from './logger/logger.js';
|
|
3
|
-
import { createTransports } from './
|
|
4
|
-
import { createClients } from './
|
|
5
|
-
import { ServerManager } from './serverManager.js';
|
|
6
|
-
import {
|
|
3
|
+
import { createTransports } from './transport/transportFactory.js';
|
|
4
|
+
import { createClients } from './core/client/clientManager.js';
|
|
5
|
+
import { ServerManager } from './core/server/serverManager.js';
|
|
6
|
+
import { McpConfigManager } from './config/mcpConfigManager.js';
|
|
7
|
+
import configReloadService from './services/configReloadService.js';
|
|
7
8
|
/**
|
|
8
9
|
* Main function to set up the MCP server
|
|
9
10
|
*/
|
|
10
11
|
async function setupServer() {
|
|
11
12
|
try {
|
|
12
|
-
const mcpConfig =
|
|
13
|
+
const mcpConfig = McpConfigManager.getInstance().getTransportConfig();
|
|
13
14
|
// Create transports from configuration
|
|
14
15
|
const transports = createTransports(mcpConfig);
|
|
15
16
|
logger.info(`Created ${Object.keys(transports).length} transports`);
|
|
16
17
|
// Create clients for each transport
|
|
17
18
|
const clients = await createClients(transports);
|
|
18
|
-
logger.info(`Created ${
|
|
19
|
+
logger.info(`Created ${clients.size} clients`);
|
|
19
20
|
const serverManager = ServerManager.getOrCreateInstance({ name: MCP_SERVER_NAME, version: MCP_SERVER_VERSION }, { capabilities: MCP_SERVER_CAPABILITIES }, clients, transports);
|
|
21
|
+
// Initialize config reload service at server startup
|
|
22
|
+
configReloadService.initialize(transports);
|
|
20
23
|
logger.info('Server setup completed successfully');
|
|
21
24
|
return serverManager;
|
|
22
25
|
}
|
package/build/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC9F,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC9F,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,mBAAmB,MAAM,mCAAmC,CAAC;AAEpE;;GAEG;AACH,KAAK,UAAU,WAAW;IACxB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,gBAAgB,CAAC,WAAW,EAAE,CAAC,kBAAkB,EAAE,CAAC;QACtE,uCAAuC;QACvC,MAAM,UAAU,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,aAAa,CAAC,CAAC;QAEpE,oCAAoC;QACpC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,UAAU,CAAC,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,IAAI,UAAU,CAAC,CAAC;QAE/C,MAAM,aAAa,GAAG,aAAa,CAAC,mBAAmB,CACrD,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,EAAE,EACtD,EAAE,YAAY,EAAE,uBAAuB,EAAE,EACzC,OAAO,EACP,UAAU,CACX,CAAC;QAEF,qDAAqD;QACrD,mBAAmB,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAE3C,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACnD,OAAO,aAAa,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAC;QAClD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { InboundConnection, EnhancedTransport } from '../core/types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Service to handle dynamic configuration reloading
|
|
4
4
|
*/
|
|
5
5
|
export declare class ConfigReloadService {
|
|
6
6
|
private static instance;
|
|
7
|
-
private
|
|
7
|
+
private serverInstances;
|
|
8
8
|
private currentTransports;
|
|
9
9
|
private isReloading;
|
|
10
10
|
/**
|
|
@@ -17,16 +17,26 @@ export declare class ConfigReloadService {
|
|
|
17
17
|
*/
|
|
18
18
|
static getInstance(): ConfigReloadService;
|
|
19
19
|
/**
|
|
20
|
-
* Initialize the service with
|
|
21
|
-
* @param serverInfo The MCP server instance
|
|
20
|
+
* Initialize the service with initial transports
|
|
22
21
|
* @param initialTransports The initial transports
|
|
23
22
|
*/
|
|
24
|
-
initialize(
|
|
23
|
+
initialize(initialTransports: Record<string, EnhancedTransport>): void;
|
|
25
24
|
/**
|
|
26
25
|
* Handle configuration changes
|
|
27
26
|
* @param newConfig The new transport configuration
|
|
28
27
|
*/
|
|
29
28
|
private handleConfigChange;
|
|
29
|
+
/**
|
|
30
|
+
* Update the server info when a client connects
|
|
31
|
+
* @param sessionId The session ID for this server instance
|
|
32
|
+
* @param serverInfo The MCP server instance
|
|
33
|
+
*/
|
|
34
|
+
updateServerInfo(sessionId: string, serverInfo: InboundConnection): void;
|
|
35
|
+
/**
|
|
36
|
+
* Remove server info when a client disconnects
|
|
37
|
+
* @param sessionId The session ID to remove
|
|
38
|
+
*/
|
|
39
|
+
removeServerInfo(sessionId: string): void;
|
|
30
40
|
/**
|
|
31
41
|
* Stop the service and clean up resources
|
|
32
42
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configReloadService.d.ts","sourceRoot":"","sources":["../../src/services/configReloadService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,
|
|
1
|
+
{"version":3,"file":"configReloadService.d.ts","sourceRoot":"","sources":["../../src/services/configReloadService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAM/F;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAsB;IAC7C,OAAO,CAAC,eAAe,CAA6C;IACpE,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,WAAW,CAAS;IAE5B;;OAEG;IACH,OAAO;IAEP;;;OAGG;WACW,WAAW,IAAI,mBAAmB;IAOhD;;;OAGG;IACI,UAAU,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,IAAI;IAoB7E;;;OAGG;YACW,kBAAkB;IAgDhC;;;;OAIG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,GAAG,IAAI;IAK/E;;;OAGG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKhD;;OAEG;IACI,IAAI,IAAI,IAAI;CAMpB;;AAED,wBAAiD"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import logger from '../logger/logger.js';
|
|
2
|
-
import { ConfigChangeEvent,
|
|
3
|
-
import { createClients } from '../
|
|
2
|
+
import { ConfigChangeEvent, McpConfigManager } from '../config/mcpConfigManager.js';
|
|
3
|
+
import { createClients } from '../core/client/clientManager.js';
|
|
4
4
|
import { setupCapabilities } from '../capabilities/capabilityManager.js';
|
|
5
|
-
import { createTransports } from '../
|
|
6
|
-
import { ServerManager } from '../serverManager.js';
|
|
5
|
+
import { createTransports } from '../transport/transportFactory.js';
|
|
6
|
+
import { ServerManager } from '../core/server/serverManager.js';
|
|
7
7
|
/**
|
|
8
8
|
* Service to handle dynamic configuration reloading
|
|
9
9
|
*/
|
|
10
10
|
export class ConfigReloadService {
|
|
11
11
|
static instance;
|
|
12
|
-
|
|
12
|
+
serverInstances = new Map();
|
|
13
13
|
currentTransports = {};
|
|
14
14
|
isReloading = false;
|
|
15
15
|
/**
|
|
@@ -27,14 +27,12 @@ export class ConfigReloadService {
|
|
|
27
27
|
return ConfigReloadService.instance;
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
|
-
* Initialize the service with
|
|
31
|
-
* @param serverInfo The MCP server instance
|
|
30
|
+
* Initialize the service with initial transports
|
|
32
31
|
* @param initialTransports The initial transports
|
|
33
32
|
*/
|
|
34
|
-
initialize(
|
|
35
|
-
this.serverInfo = serverInfo;
|
|
33
|
+
initialize(initialTransports) {
|
|
36
34
|
this.currentTransports = initialTransports;
|
|
37
|
-
const configManager =
|
|
35
|
+
const configManager = McpConfigManager.getInstance();
|
|
38
36
|
// Remove any existing listeners to prevent duplicates
|
|
39
37
|
configManager.removeAllListeners(ConfigChangeEvent.TRANSPORT_CONFIG_CHANGED);
|
|
40
38
|
// Increase max listeners limit to prevent warnings
|
|
@@ -50,7 +48,7 @@ export class ConfigReloadService {
|
|
|
50
48
|
* @param newConfig The new transport configuration
|
|
51
49
|
*/
|
|
52
50
|
async handleConfigChange(newConfig) {
|
|
53
|
-
if (
|
|
51
|
+
if (this.isReloading) {
|
|
54
52
|
return;
|
|
55
53
|
}
|
|
56
54
|
this.isReloading = true;
|
|
@@ -75,8 +73,10 @@ export class ConfigReloadService {
|
|
|
75
73
|
// Update ServerManager with new clients and transports
|
|
76
74
|
const serverManager = ServerManager.current;
|
|
77
75
|
serverManager.updateClientsAndTransports(newClients, newTransports);
|
|
78
|
-
// Register new capabilities with the server
|
|
79
|
-
|
|
76
|
+
// Register new capabilities with the server if serverInfo is available
|
|
77
|
+
for (const serverInfo of this.serverInstances.values()) {
|
|
78
|
+
await setupCapabilities(newClients, serverInfo);
|
|
79
|
+
}
|
|
80
80
|
// Update current transports
|
|
81
81
|
this.currentTransports = newTransports;
|
|
82
82
|
logger.info('Configuration reload completed successfully');
|
|
@@ -88,11 +88,28 @@ export class ConfigReloadService {
|
|
|
88
88
|
this.isReloading = false;
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Update the server info when a client connects
|
|
93
|
+
* @param sessionId The session ID for this server instance
|
|
94
|
+
* @param serverInfo The MCP server instance
|
|
95
|
+
*/
|
|
96
|
+
updateServerInfo(sessionId, serverInfo) {
|
|
97
|
+
this.serverInstances.set(sessionId, serverInfo);
|
|
98
|
+
logger.debug(`Updated server info for session ${sessionId} in config reload service`);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Remove server info when a client disconnects
|
|
102
|
+
* @param sessionId The session ID to remove
|
|
103
|
+
*/
|
|
104
|
+
removeServerInfo(sessionId) {
|
|
105
|
+
this.serverInstances.delete(sessionId);
|
|
106
|
+
logger.debug(`Removed server info for session ${sessionId} from config reload service`);
|
|
107
|
+
}
|
|
91
108
|
/**
|
|
92
109
|
* Stop the service and clean up resources
|
|
93
110
|
*/
|
|
94
111
|
stop() {
|
|
95
|
-
const configManager =
|
|
112
|
+
const configManager = McpConfigManager.getInstance();
|
|
96
113
|
configManager.stopWatching();
|
|
97
114
|
configManager.removeAllListeners(ConfigChangeEvent.TRANSPORT_CONFIG_CHANGED);
|
|
98
115
|
logger.info('Config reload service stopped');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configReloadService.js","sourceRoot":"","sources":["../../src/services/configReloadService.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"configReloadService.js","sourceRoot":"","sources":["../../src/services/configReloadService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../../../src/transport/http/middlewares/errorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAI1D,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,QAQhG"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
-
import logger from '
|
|
2
|
+
import logger from '../../../logger/logger.js';
|
|
3
3
|
export default function errorHandler(err, req, res, _next) {
|
|
4
4
|
logger.error('Express error:', err);
|
|
5
5
|
res.status(500).json({
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../../../src/transport/http/middlewares/errorHandler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAE/C,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,GAAU,EAAE,GAAY,EAAE,GAAa,EAAE,KAAmB;IAC/F,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACpC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,KAAK,EAAE;YACL,IAAI,EAAE,SAAS,CAAC,aAAa;YAC7B,OAAO,EAAE,uBAAuB;SACjC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* Authentication information structure
|
|
4
|
+
*/
|
|
5
|
+
export interface AuthInfo {
|
|
6
|
+
token: string;
|
|
7
|
+
clientId: string;
|
|
8
|
+
grantedScopes: string[];
|
|
9
|
+
grantedTags: string[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Creates a scope validation middleware that uses the SDK's bearer auth middleware
|
|
13
|
+
*
|
|
14
|
+
* This middleware:
|
|
15
|
+
* 1. Uses SDK's requireBearerAuth to verify tokens (when auth enabled)
|
|
16
|
+
* 2. Validates that requested tags are covered by granted scopes
|
|
17
|
+
* 3. Provides authentication context to downstream handlers
|
|
18
|
+
*
|
|
19
|
+
* When scope validation is disabled, all tags are allowed.
|
|
20
|
+
* When scope validation is enabled:
|
|
21
|
+
* - If auth is also enabled, validates tokens and scopes
|
|
22
|
+
* - If auth is disabled, allows all tags (useful for development/testing)
|
|
23
|
+
*/
|
|
24
|
+
export declare function createScopeAuthMiddleware(): (_req: Request, res: Response, next: NextFunction) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Default middleware for backward compatibility
|
|
27
|
+
*
|
|
28
|
+
* @deprecated Use createScopeAuthMiddleware() instead
|
|
29
|
+
*/
|
|
30
|
+
export default function scopeAuthMiddleware(req: Request, res: Response, next: NextFunction): void;
|
|
31
|
+
/**
|
|
32
|
+
* Utility function to get validated tags from response locals
|
|
33
|
+
*
|
|
34
|
+
* This should be used by downstream handlers instead of directly accessing res.locals.tags
|
|
35
|
+
* to ensure they get scope-validated tags.
|
|
36
|
+
*/
|
|
37
|
+
export declare function getValidatedTags(res: Response): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Utility function to get authentication information from response locals
|
|
40
|
+
*/
|
|
41
|
+
export declare function getAuthInfo(res: Response): AuthInfo | undefined;
|
|
42
|
+
//# sourceMappingURL=scopeAuthMiddleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopeAuthMiddleware.d.ts","sourceRoot":"","sources":["../../../../src/transport/http/middlewares/scopeAuthMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAO1D;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,WAKvB,OAAO,OAAO,QAAQ,QAAQ,YAAY,KAAG,IAAI,CAuFlE;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAGjG;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,EAAE,CAWxD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAM/D"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { requireBearerAuth } from '@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js';
|
|
2
|
+
import logger from '../../../logger/logger.js';
|
|
3
|
+
import { AgentConfigManager } from '../../../core/server/agentConfig.js';
|
|
4
|
+
import { SDKOAuthServerProvider } from '../../../auth/sdkOAuthServerProvider.js';
|
|
5
|
+
import { hasRequiredScopes, scopesToTags, auditScopeOperation } from '../../../utils/scopeValidation.js';
|
|
6
|
+
/**
|
|
7
|
+
* Creates a scope validation middleware that uses the SDK's bearer auth middleware
|
|
8
|
+
*
|
|
9
|
+
* This middleware:
|
|
10
|
+
* 1. Uses SDK's requireBearerAuth to verify tokens (when auth enabled)
|
|
11
|
+
* 2. Validates that requested tags are covered by granted scopes
|
|
12
|
+
* 3. Provides authentication context to downstream handlers
|
|
13
|
+
*
|
|
14
|
+
* When scope validation is disabled, all tags are allowed.
|
|
15
|
+
* When scope validation is enabled:
|
|
16
|
+
* - If auth is also enabled, validates tokens and scopes
|
|
17
|
+
* - If auth is disabled, allows all tags (useful for development/testing)
|
|
18
|
+
*/
|
|
19
|
+
export function createScopeAuthMiddleware() {
|
|
20
|
+
const serverConfig = AgentConfigManager.getInstance();
|
|
21
|
+
// If scope validation is disabled, return a pass-through middleware
|
|
22
|
+
if (!serverConfig.isScopeValidationEnabled()) {
|
|
23
|
+
return (_req, res, next) => {
|
|
24
|
+
const requestedTags = res.locals.tags || [];
|
|
25
|
+
res.locals.validatedTags = requestedTags;
|
|
26
|
+
next();
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// If scope validation is enabled but auth is disabled, allow all tags
|
|
30
|
+
if (!serverConfig.isAuthEnabled()) {
|
|
31
|
+
return (_req, res, next) => {
|
|
32
|
+
const requestedTags = res.locals.tags || [];
|
|
33
|
+
res.locals.validatedTags = requestedTags;
|
|
34
|
+
next();
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const oauthProvider = new SDKOAuthServerProvider();
|
|
38
|
+
// Create the SDK's bearer auth middleware
|
|
39
|
+
const bearerAuthMiddleware = requireBearerAuth({
|
|
40
|
+
verifier: oauthProvider,
|
|
41
|
+
});
|
|
42
|
+
// Return a combined middleware that does both auth and scope validation
|
|
43
|
+
return async (req, res, next) => {
|
|
44
|
+
try {
|
|
45
|
+
// First run the SDK's bearer auth middleware
|
|
46
|
+
await new Promise((resolve, reject) => {
|
|
47
|
+
bearerAuthMiddleware(req, res, (err) => {
|
|
48
|
+
if (err)
|
|
49
|
+
reject(err);
|
|
50
|
+
else
|
|
51
|
+
resolve();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
// If we get here, auth succeeded and req.auth is populated
|
|
55
|
+
const authInfo = req.auth;
|
|
56
|
+
const grantedScopes = authInfo.scopes || [];
|
|
57
|
+
const grantedTags = scopesToTags(grantedScopes);
|
|
58
|
+
// Get requested tags from previous middleware (tagsExtractor)
|
|
59
|
+
const requestedTags = res.locals.tags || [];
|
|
60
|
+
// Validate that all requested tags are covered by granted scopes
|
|
61
|
+
if (!hasRequiredScopes(grantedScopes, requestedTags)) {
|
|
62
|
+
auditScopeOperation('insufficient_scopes', {
|
|
63
|
+
clientId: authInfo.clientId,
|
|
64
|
+
requestedScopes: requestedTags.map((tag) => `tag:${tag}`),
|
|
65
|
+
grantedScopes,
|
|
66
|
+
success: false,
|
|
67
|
+
error: 'Insufficient scopes for requested tags',
|
|
68
|
+
});
|
|
69
|
+
res.status(403).json({
|
|
70
|
+
error: 'insufficient_scope',
|
|
71
|
+
error_description: `Insufficient scopes. Required: ${requestedTags.join(', ')}, Granted: ${grantedTags.join(', ')}`,
|
|
72
|
+
});
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Provide authentication context to downstream handlers via res.locals
|
|
76
|
+
res.locals.auth = {
|
|
77
|
+
token: req.headers.authorization?.slice(7) || '', // Remove 'Bearer ' prefix
|
|
78
|
+
clientId: authInfo.clientId,
|
|
79
|
+
grantedScopes,
|
|
80
|
+
grantedTags,
|
|
81
|
+
};
|
|
82
|
+
// Provide validated tags to downstream handlers
|
|
83
|
+
// If no specific tags requested, use all granted tags
|
|
84
|
+
res.locals.validatedTags = requestedTags.length > 0 ? requestedTags : grantedTags;
|
|
85
|
+
auditScopeOperation('scope_validation_success', {
|
|
86
|
+
clientId: authInfo.clientId,
|
|
87
|
+
requestedScopes: requestedTags.map((tag) => `tag:${tag}`),
|
|
88
|
+
grantedScopes,
|
|
89
|
+
success: true,
|
|
90
|
+
});
|
|
91
|
+
next();
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
logger.error('Scope auth middleware error:', error);
|
|
95
|
+
res.status(500).json({
|
|
96
|
+
error: 'server_error',
|
|
97
|
+
error_description: 'Internal server error',
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Default middleware for backward compatibility
|
|
104
|
+
*
|
|
105
|
+
* @deprecated Use createScopeAuthMiddleware() instead
|
|
106
|
+
*/
|
|
107
|
+
export default function scopeAuthMiddleware(req, res, next) {
|
|
108
|
+
const middleware = createScopeAuthMiddleware();
|
|
109
|
+
middleware(req, res, next);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Utility function to get validated tags from response locals
|
|
113
|
+
*
|
|
114
|
+
* This should be used by downstream handlers instead of directly accessing res.locals.tags
|
|
115
|
+
* to ensure they get scope-validated tags.
|
|
116
|
+
*/
|
|
117
|
+
export function getValidatedTags(res) {
|
|
118
|
+
if (!res?.locals?.validatedTags) {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
// Ensure it's an array
|
|
122
|
+
if (!Array.isArray(res.locals.validatedTags)) {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
return res.locals.validatedTags;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Utility function to get authentication information from response locals
|
|
129
|
+
*/
|
|
130
|
+
export function getAuthInfo(res) {
|
|
131
|
+
if (!res?.locals?.auth) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
return res.locals.auth;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=scopeAuthMiddleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopeAuthMiddleware.js","sourceRoot":"","sources":["../../../../src/transport/http/middlewares/scopeAuthMiddleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* Security headers middleware to protect against common attacks
|
|
4
|
+
*/
|
|
5
|
+
export declare function securityHeaders(req: Request, res: Response, next: NextFunction): void;
|
|
6
|
+
/**
|
|
7
|
+
* Rate limiter for sensitive operations (stricter than general OAuth)
|
|
8
|
+
*/
|
|
9
|
+
export declare const sensitiveOperationLimiter: import("express-rate-limit").RateLimitRequestHandler;
|
|
10
|
+
/**
|
|
11
|
+
* Enhanced input validation middleware
|
|
12
|
+
*/
|
|
13
|
+
export declare function inputValidation(req: Request, res: Response, next: NextFunction): void;
|
|
14
|
+
/**
|
|
15
|
+
* Session security middleware
|
|
16
|
+
*/
|
|
17
|
+
export declare function sessionSecurity(req: Request, res: Response, next: NextFunction): void;
|
|
18
|
+
/**
|
|
19
|
+
* Request logging middleware for security audit trail
|
|
20
|
+
*/
|
|
21
|
+
export declare function securityAuditLogger(req: Request, res: Response, next: NextFunction): void;
|
|
22
|
+
/**
|
|
23
|
+
* Prevent common timing attacks
|
|
24
|
+
*/
|
|
25
|
+
export declare function timingAttackPrevention(req: Request, res: Response, next: NextFunction): void;
|
|
26
|
+
/**
|
|
27
|
+
* Comprehensive security middleware stack
|
|
28
|
+
*/
|
|
29
|
+
export declare function setupSecurityMiddleware(): (typeof securityHeaders)[];
|
|
30
|
+
//# sourceMappingURL=securityMiddleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"securityMiddleware.d.ts","sourceRoot":"","sources":["../../../../src/transport/http/middlewares/securityMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI1D;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAyBrF;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,sDA2BpC,CAAC;AAEH;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAiErF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAarF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CA4CzF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAwB5F;AAED;;GAEG;AACH,wBAAgB,uBAAuB,+BAEtC"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import rateLimit from 'express-rate-limit';
|
|
2
|
+
import logger from '../../../logger/logger.js';
|
|
3
|
+
/**
|
|
4
|
+
* Security headers middleware to protect against common attacks
|
|
5
|
+
*/
|
|
6
|
+
export function securityHeaders(req, res, next) {
|
|
7
|
+
// Prevent clickjacking
|
|
8
|
+
res.setHeader('X-Frame-Options', 'DENY');
|
|
9
|
+
// Prevent MIME type sniffing
|
|
10
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
11
|
+
// Enable XSS protection
|
|
12
|
+
res.setHeader('X-XSS-Protection', '1; mode=block');
|
|
13
|
+
// Prevent referrer leakage
|
|
14
|
+
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
15
|
+
// Content Security Policy for HTML responses (disabled for OAuth/auth paths)
|
|
16
|
+
if (req.accepts('html') && !req.path.includes('/oauth/') && !req.path.includes('/auth/')) {
|
|
17
|
+
res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; form-action 'self'; frame-ancestors 'none';");
|
|
18
|
+
}
|
|
19
|
+
// Remove server information
|
|
20
|
+
res.removeHeader('X-Powered-By');
|
|
21
|
+
next();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Rate limiter for sensitive operations (stricter than general OAuth)
|
|
25
|
+
*/
|
|
26
|
+
export const sensitiveOperationLimiter = rateLimit({
|
|
27
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
28
|
+
max: 10, // 10 attempts per window
|
|
29
|
+
standardHeaders: true,
|
|
30
|
+
legacyHeaders: false,
|
|
31
|
+
message: {
|
|
32
|
+
error: 'rate_limit_exceeded',
|
|
33
|
+
error_description: 'Too many sensitive operations. Please try again later.',
|
|
34
|
+
},
|
|
35
|
+
skip: (req) => {
|
|
36
|
+
// Skip rate limiting for health checks or non-sensitive endpoints
|
|
37
|
+
return req.path === '/health' || req.path === '/';
|
|
38
|
+
},
|
|
39
|
+
handler: (req, res) => {
|
|
40
|
+
logger.warn(`Rate limit exceeded for sensitive operation`, {
|
|
41
|
+
ip: req.ip,
|
|
42
|
+
userAgent: req.get('User-Agent'),
|
|
43
|
+
path: req.path,
|
|
44
|
+
method: req.method,
|
|
45
|
+
timestamp: new Date().toISOString(),
|
|
46
|
+
});
|
|
47
|
+
res.status(429).json({
|
|
48
|
+
error: 'rate_limit_exceeded',
|
|
49
|
+
error_description: 'Too many sensitive operations. Please try again later.',
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Enhanced input validation middleware
|
|
55
|
+
*/
|
|
56
|
+
export function inputValidation(req, res, next) {
|
|
57
|
+
// Check for common injection patterns in headers
|
|
58
|
+
const suspiciousPatterns = [
|
|
59
|
+
/\$\(.*\)/, // Command injection
|
|
60
|
+
/<script[\s\S]*?>/i, // XSS - matches across newlines
|
|
61
|
+
/javascript:/i, // JavaScript protocol
|
|
62
|
+
/\.\./, // Path traversal
|
|
63
|
+
/\0/, // Null byte injection
|
|
64
|
+
/union.*select/i, // SQL injection
|
|
65
|
+
/exec\s*\(/i, // Code execution
|
|
66
|
+
];
|
|
67
|
+
const checkForMaliciousContent = (value, location) => {
|
|
68
|
+
return suspiciousPatterns.some((pattern) => {
|
|
69
|
+
if (pattern.test(value)) {
|
|
70
|
+
logger.warn(`Suspicious content detected in ${location}`, {
|
|
71
|
+
value: value.substring(0, 100), // Log only first 100 chars
|
|
72
|
+
pattern: pattern.toString(),
|
|
73
|
+
ip: req.ip,
|
|
74
|
+
userAgent: req.get('User-Agent'),
|
|
75
|
+
path: req.path,
|
|
76
|
+
timestamp: new Date().toISOString(),
|
|
77
|
+
});
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
// Check headers
|
|
84
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
85
|
+
if (typeof value === 'string' && checkForMaliciousContent(value, `header:${key}`)) {
|
|
86
|
+
res.status(400).json({
|
|
87
|
+
error: 'invalid_request',
|
|
88
|
+
error_description: 'Request contains suspicious content',
|
|
89
|
+
});
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Check query parameters
|
|
94
|
+
for (const [key, value] of Object.entries(req.query)) {
|
|
95
|
+
if (typeof value === 'string' && checkForMaliciousContent(value, `query:${key}`)) {
|
|
96
|
+
res.status(400).json({
|
|
97
|
+
error: 'invalid_request',
|
|
98
|
+
error_description: 'Request contains suspicious content',
|
|
99
|
+
});
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Check body for POST requests
|
|
104
|
+
if (req.body && typeof req.body === 'object') {
|
|
105
|
+
for (const [key, value] of Object.entries(req.body)) {
|
|
106
|
+
if (typeof value === 'string' && checkForMaliciousContent(value, `body:${key}`)) {
|
|
107
|
+
res.status(400).json({
|
|
108
|
+
error: 'invalid_request',
|
|
109
|
+
error_description: 'Request contains suspicious content',
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
next();
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Session security middleware
|
|
119
|
+
*/
|
|
120
|
+
export function sessionSecurity(req, res, next) {
|
|
121
|
+
// Add security-related headers for session management
|
|
122
|
+
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
|
|
123
|
+
res.setHeader('Pragma', 'no-cache');
|
|
124
|
+
res.setHeader('Expires', '0');
|
|
125
|
+
res.setHeader('Surrogate-Control', 'no-store');
|
|
126
|
+
// For OAuth endpoints, add additional security
|
|
127
|
+
if (req.path.includes('/oauth/')) {
|
|
128
|
+
res.setHeader('X-Robots-Tag', 'noindex, nofollow, nosnippet, noarchive');
|
|
129
|
+
}
|
|
130
|
+
next();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Request logging middleware for security audit trail
|
|
134
|
+
*/
|
|
135
|
+
export function securityAuditLogger(req, res, next) {
|
|
136
|
+
const startTime = Date.now();
|
|
137
|
+
// Log high-value security events
|
|
138
|
+
const isSecurityRelevant = req.path.includes('/oauth/') ||
|
|
139
|
+
req.path.includes('/auth/') ||
|
|
140
|
+
req.method === 'POST' ||
|
|
141
|
+
req.method === 'PUT' ||
|
|
142
|
+
req.method === 'DELETE';
|
|
143
|
+
if (isSecurityRelevant) {
|
|
144
|
+
logger.info('Security-relevant request', {
|
|
145
|
+
method: req.method,
|
|
146
|
+
path: req.path,
|
|
147
|
+
ip: req.ip,
|
|
148
|
+
userAgent: req.get('User-Agent'),
|
|
149
|
+
contentType: req.get('Content-Type'),
|
|
150
|
+
timestamp: new Date().toISOString(),
|
|
151
|
+
sessionId: req.headers['mcp-session-id'],
|
|
152
|
+
authorization: req.headers.authorization ? 'Bearer [REDACTED]' : undefined,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// Capture response details
|
|
156
|
+
const originalSend = res.send;
|
|
157
|
+
res.send = function (body) {
|
|
158
|
+
const duration = Date.now() - startTime;
|
|
159
|
+
if (isSecurityRelevant) {
|
|
160
|
+
logger.info('Security-relevant response', {
|
|
161
|
+
method: req.method,
|
|
162
|
+
path: req.path,
|
|
163
|
+
statusCode: res.statusCode,
|
|
164
|
+
duration,
|
|
165
|
+
ip: req.ip,
|
|
166
|
+
timestamp: new Date().toISOString(),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return originalSend.call(this, body);
|
|
170
|
+
};
|
|
171
|
+
next();
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Prevent common timing attacks
|
|
175
|
+
*/
|
|
176
|
+
export function timingAttackPrevention(req, res, next) {
|
|
177
|
+
const startTime = Date.now();
|
|
178
|
+
// Add random delay for authentication-related endpoints to prevent timing attacks
|
|
179
|
+
const isAuthEndpoint = req.path.includes('/oauth/') || req.path.includes('/auth/');
|
|
180
|
+
if (isAuthEndpoint) {
|
|
181
|
+
// Add random delay between 10-50ms to make timing attacks harder
|
|
182
|
+
const randomDelay = Math.floor(Math.random() * 40) + 10;
|
|
183
|
+
const originalSend = res.send;
|
|
184
|
+
res.send = function (body) {
|
|
185
|
+
const elapsed = Date.now() - startTime;
|
|
186
|
+
const remainingDelay = Math.max(0, randomDelay - elapsed);
|
|
187
|
+
setTimeout(() => {
|
|
188
|
+
return originalSend.call(this, body);
|
|
189
|
+
}, remainingDelay);
|
|
190
|
+
return this;
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
next();
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Comprehensive security middleware stack
|
|
197
|
+
*/
|
|
198
|
+
export function setupSecurityMiddleware() {
|
|
199
|
+
return [securityHeaders, sessionSecurity, inputValidation, securityAuditLogger, timingAttackPrevention];
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=securityMiddleware.js.map
|