@1mcp/agent 0.15.0 → 0.17.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 +115 -14
- package/build/commands/app/backups.d.ts +17 -0
- package/build/commands/app/backups.d.ts.map +1 -0
- package/build/commands/app/backups.js +162 -0
- package/build/commands/app/backups.js.map +1 -0
- package/build/commands/app/consolidate.d.ts +21 -0
- package/build/commands/app/consolidate.d.ts.map +1 -0
- package/build/commands/app/consolidate.js +383 -0
- package/build/commands/app/consolidate.js.map +1 -0
- package/build/commands/app/discover.d.ts +16 -0
- package/build/commands/app/discover.d.ts.map +1 -0
- package/build/commands/app/discover.js +79 -0
- package/build/commands/app/discover.js.map +1 -0
- package/build/commands/app/index.d.ts +12 -0
- package/build/commands/app/index.d.ts.map +1 -0
- package/build/commands/app/index.js +274 -0
- package/build/commands/app/index.js.map +1 -0
- package/build/commands/app/list.d.ts +16 -0
- package/build/commands/app/list.d.ts.map +1 -0
- package/build/commands/app/list.js +95 -0
- package/build/commands/app/list.js.map +1 -0
- package/build/commands/app/restore.d.ts +21 -0
- package/build/commands/app/restore.d.ts.map +1 -0
- package/build/commands/app/restore.js +265 -0
- package/build/commands/app/restore.js.map +1 -0
- package/build/commands/app/status.d.ts +16 -0
- package/build/commands/app/status.d.ts.map +1 -0
- package/build/commands/app/status.js +224 -0
- package/build/commands/app/status.js.map +1 -0
- package/build/commands/mcp/add.d.ts +19 -0
- package/build/commands/mcp/add.d.ts.map +1 -0
- package/build/commands/mcp/add.js +135 -0
- package/build/commands/mcp/add.js.map +1 -0
- package/build/commands/mcp/enable.d.ts +13 -0
- package/build/commands/mcp/enable.d.ts.map +1 -0
- package/build/commands/mcp/enable.js +100 -0
- package/build/commands/mcp/enable.js.map +1 -0
- package/build/commands/mcp/index.d.ts +12 -0
- package/build/commands/mcp/index.d.ts.map +1 -0
- package/build/commands/mcp/index.js +351 -0
- package/build/commands/mcp/index.js.map +1 -0
- package/build/commands/mcp/list.d.ts +11 -0
- package/build/commands/mcp/list.d.ts.map +1 -0
- package/build/commands/mcp/list.js +144 -0
- package/build/commands/mcp/list.js.map +1 -0
- package/build/commands/mcp/remove.d.ts +10 -0
- package/build/commands/mcp/remove.d.ts.map +1 -0
- package/build/commands/mcp/remove.js +89 -0
- package/build/commands/mcp/remove.js.map +1 -0
- package/build/commands/mcp/status.d.ts +10 -0
- package/build/commands/mcp/status.d.ts.map +1 -0
- package/build/commands/mcp/status.js +243 -0
- package/build/commands/mcp/status.js.map +1 -0
- package/build/commands/mcp/update.d.ts +18 -0
- package/build/commands/mcp/update.d.ts.map +1 -0
- package/build/commands/mcp/update.js +157 -0
- package/build/commands/mcp/update.js.map +1 -0
- package/build/commands/mcp/utils/configUtils.d.ts +64 -0
- package/build/commands/mcp/utils/configUtils.d.ts.map +1 -0
- package/build/commands/mcp/utils/configUtils.js +266 -0
- package/build/commands/mcp/utils/configUtils.js.map +1 -0
- package/build/commands/mcp/utils/doubleHyphenParser.d.ts +32 -0
- package/build/commands/mcp/utils/doubleHyphenParser.d.ts.map +1 -0
- package/build/commands/mcp/utils/doubleHyphenParser.js +61 -0
- package/build/commands/mcp/utils/doubleHyphenParser.js.map +1 -0
- package/build/commands/mcp/utils/validation.d.ts +33 -0
- package/build/commands/mcp/utils/validation.d.ts.map +1 -0
- package/build/commands/mcp/utils/validation.js +235 -0
- package/build/commands/mcp/utils/validation.js.map +1 -0
- package/build/constants.d.ts +12 -2
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +16 -2
- package/build/constants.js.map +1 -1
- package/build/core/capabilities/asyncLoadingOrchestrator.d.ts +96 -0
- package/build/core/capabilities/asyncLoadingOrchestrator.d.ts.map +1 -0
- package/build/core/capabilities/asyncLoadingOrchestrator.js +256 -0
- package/build/core/capabilities/asyncLoadingOrchestrator.js.map +1 -0
- package/build/core/capabilities/capabilityAggregator.d.ts +114 -0
- package/build/core/capabilities/capabilityAggregator.d.ts.map +1 -0
- package/build/core/capabilities/capabilityAggregator.js +234 -0
- package/build/core/capabilities/capabilityAggregator.js.map +1 -0
- package/build/core/client/clientManager.d.ts +28 -0
- package/build/core/client/clientManager.d.ts.map +1 -1
- package/build/core/client/clientManager.js +120 -0
- package/build/core/client/clientManager.js.map +1 -1
- package/build/core/loading/loadingStateTracker.d.ts +128 -0
- package/build/core/loading/loadingStateTracker.d.ts.map +1 -0
- package/build/core/loading/loadingStateTracker.js +209 -0
- package/build/core/loading/loadingStateTracker.js.map +1 -0
- package/build/core/loading/mcpLoadingManager.d.ts +139 -0
- package/build/core/loading/mcpLoadingManager.d.ts.map +1 -0
- package/build/core/loading/mcpLoadingManager.js +296 -0
- package/build/core/loading/mcpLoadingManager.js.map +1 -0
- package/build/core/notifications/notificationManager.d.ts +111 -0
- package/build/core/notifications/notificationManager.d.ts.map +1 -0
- package/build/core/notifications/notificationManager.js +232 -0
- package/build/core/notifications/notificationManager.js.map +1 -0
- package/build/core/server/agentConfig.d.ts +59 -0
- package/build/core/server/agentConfig.d.ts.map +1 -1
- package/build/core/server/agentConfig.js +82 -1
- package/build/core/server/agentConfig.js.map +1 -1
- package/build/core/server/serverManager.d.ts +1 -0
- package/build/core/server/serverManager.d.ts.map +1 -1
- package/build/core/server/serverManager.js +3 -0
- package/build/core/server/serverManager.js.map +1 -1
- package/build/index.js +123 -31
- package/build/index.js.map +1 -1
- package/build/server.d.ts +23 -2
- package/build/server.d.ts.map +1 -1
- package/build/server.js +83 -10
- package/build/server.js.map +1 -1
- package/build/services/healthService.d.ts +107 -0
- package/build/services/healthService.d.ts.map +1 -0
- package/build/services/healthService.js +294 -0
- package/build/services/healthService.js.map +1 -0
- package/build/transport/http/middlewares/mcpAvailabilityMiddleware.d.ts +79 -0
- package/build/transport/http/middlewares/mcpAvailabilityMiddleware.d.ts.map +1 -0
- package/build/transport/http/middlewares/mcpAvailabilityMiddleware.js +243 -0
- package/build/transport/http/middlewares/mcpAvailabilityMiddleware.js.map +1 -0
- package/build/transport/http/routes/healthRoutes.d.ts +8 -0
- package/build/transport/http/routes/healthRoutes.d.ts.map +1 -0
- package/build/transport/http/routes/healthRoutes.js +282 -0
- package/build/transport/http/routes/healthRoutes.js.map +1 -0
- package/build/transport/http/routes/sseRoutes.d.ts +2 -1
- package/build/transport/http/routes/sseRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/sseRoutes.js +13 -1
- package/build/transport/http/routes/sseRoutes.js.map +1 -1
- package/build/transport/http/routes/streamableHttpRoutes.d.ts +2 -1
- package/build/transport/http/routes/streamableHttpRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/streamableHttpRoutes.js +13 -1
- package/build/transport/http/routes/streamableHttpRoutes.js.map +1 -1
- package/build/transport/http/server.d.ts +7 -1
- package/build/transport/http/server.d.ts.map +1 -1
- package/build/transport/http/server.js +17 -3
- package/build/transport/http/server.js.map +1 -1
- package/build/transport/transportFactory.d.ts +4 -0
- package/build/transport/transportFactory.d.ts.map +1 -1
- package/build/transport/transportFactory.js +1 -1
- package/build/transport/transportFactory.js.map +1 -1
- package/build/utils/appDiscovery.d.ts +75 -0
- package/build/utils/appDiscovery.d.ts.map +1 -0
- package/build/utils/appDiscovery.js +358 -0
- package/build/utils/appDiscovery.js.map +1 -0
- package/build/utils/appPresets.d.ts +88 -0
- package/build/utils/appPresets.d.ts.map +1 -0
- package/build/utils/appPresets.js +430 -0
- package/build/utils/appPresets.js.map +1 -0
- package/build/utils/backupManager.d.ts +61 -0
- package/build/utils/backupManager.d.ts.map +1 -0
- package/build/utils/backupManager.js +314 -0
- package/build/utils/backupManager.js.map +1 -0
- package/build/utils/urlDetection.d.ts +35 -0
- package/build/utils/urlDetection.d.ts.map +1 -0
- package/build/utils/urlDetection.js +115 -0
- package/build/utils/urlDetection.js.map +1 -0
- package/build/utils/validationHelpers.d.ts +62 -0
- package/build/utils/validationHelpers.d.ts.map +1 -0
- package/build/utils/validationHelpers.js +252 -0
- package/build/utils/validationHelpers.js.map +1 -0
- package/package.json +25 -3
package/build/server.js
CHANGED
|
@@ -4,30 +4,103 @@ import { createTransports } from './transport/transportFactory.js';
|
|
|
4
4
|
import { ClientManager } from './core/client/clientManager.js';
|
|
5
5
|
import { ServerManager } from './core/server/serverManager.js';
|
|
6
6
|
import { McpConfigManager } from './config/mcpConfigManager.js';
|
|
7
|
+
import { AgentConfigManager } from './core/server/agentConfig.js';
|
|
7
8
|
import configReloadService from './services/configReloadService.js';
|
|
9
|
+
import { McpLoadingManager } from './core/loading/mcpLoadingManager.js';
|
|
10
|
+
import { AsyncLoadingOrchestrator } from './core/capabilities/asyncLoadingOrchestrator.js';
|
|
8
11
|
/**
|
|
9
12
|
* Main function to set up the MCP server
|
|
13
|
+
* Conditionally uses async or legacy loading based on configuration
|
|
10
14
|
*/
|
|
11
15
|
async function setupServer() {
|
|
12
16
|
try {
|
|
13
17
|
const mcpConfig = McpConfigManager.getInstance().getTransportConfig();
|
|
18
|
+
const agentConfig = AgentConfigManager.getInstance();
|
|
19
|
+
const asyncLoadingEnabled = agentConfig.isAsyncLoadingEnabled();
|
|
14
20
|
// Create transports from configuration
|
|
15
21
|
const transports = createTransports(mcpConfig);
|
|
16
22
|
logger.info(`Created ${Object.keys(transports).length} transports`);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return serverManager;
|
|
23
|
+
if (asyncLoadingEnabled) {
|
|
24
|
+
logger.info('Using async loading mode - HTTP server will start immediately, MCP servers load in background');
|
|
25
|
+
return setupServerAsync(transports);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
logger.info('Using legacy synchronous loading mode - waiting for all MCP servers before starting HTTP server');
|
|
29
|
+
return setupServerSync(transports);
|
|
30
|
+
}
|
|
26
31
|
}
|
|
27
32
|
catch (error) {
|
|
28
33
|
logger.error(`Failed to set up server: ${error}`);
|
|
29
34
|
throw error;
|
|
30
35
|
}
|
|
31
36
|
}
|
|
32
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Set up server with async loading (new mode)
|
|
39
|
+
* HTTP server starts immediately, MCP servers load in background
|
|
40
|
+
*/
|
|
41
|
+
async function setupServerAsync(transports) {
|
|
42
|
+
// Initialize client manager without connecting (for async loading)
|
|
43
|
+
const clientManager = ClientManager.getOrCreateInstance();
|
|
44
|
+
const clients = clientManager.initializeClientsAsync(transports);
|
|
45
|
+
logger.info(`Initialized storage for ${Object.keys(transports).length} MCP servers`);
|
|
46
|
+
// Create server manager with empty clients initially
|
|
47
|
+
const serverManager = ServerManager.getOrCreateInstance({ name: MCP_SERVER_NAME, version: MCP_SERVER_VERSION }, { capabilities: MCP_SERVER_CAPABILITIES }, clients, transports);
|
|
48
|
+
// Initialize config reload service
|
|
49
|
+
configReloadService.initialize(transports);
|
|
50
|
+
// Create loading manager for async MCP server initialization
|
|
51
|
+
const loadingManager = new McpLoadingManager(clientManager);
|
|
52
|
+
// Create async loading orchestrator for capability tracking and notifications
|
|
53
|
+
const asyncOrchestrator = new AsyncLoadingOrchestrator(clients, serverManager, loadingManager);
|
|
54
|
+
asyncOrchestrator.initialize();
|
|
55
|
+
// Start async loading (non-blocking)
|
|
56
|
+
const loadingPromise = loadingManager
|
|
57
|
+
.startAsyncLoading(transports)
|
|
58
|
+
.then(() => {
|
|
59
|
+
logger.info('All MCP servers finished loading (successfully or failed)');
|
|
60
|
+
})
|
|
61
|
+
.catch((error) => {
|
|
62
|
+
logger.error('MCP loading process encountered an error:', error);
|
|
63
|
+
});
|
|
64
|
+
logger.info('Async server setup completed - HTTP server ready, MCP servers loading in background');
|
|
65
|
+
return {
|
|
66
|
+
serverManager,
|
|
67
|
+
loadingManager,
|
|
68
|
+
loadingPromise,
|
|
69
|
+
asyncOrchestrator,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Set up server with legacy synchronous loading
|
|
74
|
+
* Waits for all MCP servers to load before returning
|
|
75
|
+
*/
|
|
76
|
+
async function setupServerSync(transports) {
|
|
77
|
+
// Use the standard synchronous client creation
|
|
78
|
+
const clientManager = ClientManager.getOrCreateInstance();
|
|
79
|
+
const clients = await clientManager.createClients(transports);
|
|
80
|
+
logger.info(`Connected to ${clients.size} MCP servers synchronously`);
|
|
81
|
+
// Create server manager with connected clients
|
|
82
|
+
const serverManager = ServerManager.getOrCreateInstance({ name: MCP_SERVER_NAME, version: MCP_SERVER_VERSION }, { capabilities: MCP_SERVER_CAPABILITIES }, clients, transports);
|
|
83
|
+
// Initialize config reload service
|
|
84
|
+
configReloadService.initialize(transports);
|
|
85
|
+
// Create a dummy loading manager for compatibility
|
|
86
|
+
const loadingManager = new McpLoadingManager(clientManager);
|
|
87
|
+
const loadingPromise = Promise.resolve(); // Already loaded
|
|
88
|
+
logger.info('Synchronous server setup completed - all MCP servers connected');
|
|
89
|
+
return {
|
|
90
|
+
serverManager,
|
|
91
|
+
loadingManager,
|
|
92
|
+
loadingPromise,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Legacy function for backward compatibility
|
|
97
|
+
* @deprecated Use setupServer() which returns ServerSetupResult
|
|
98
|
+
*/
|
|
99
|
+
async function setupServerLegacy() {
|
|
100
|
+
const result = await setupServer();
|
|
101
|
+
// Wait for loading to complete for legacy behavior
|
|
102
|
+
await result.loadingPromise;
|
|
103
|
+
return result.serverManager;
|
|
104
|
+
}
|
|
105
|
+
export { setupServer, setupServerLegacy };
|
|
33
106
|
//# sourceMappingURL=server.js.map
|
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,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;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { ClientStatus } from '../core/types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Health status levels
|
|
4
|
+
*/
|
|
5
|
+
export declare enum HealthStatus {
|
|
6
|
+
HEALTHY = "healthy",
|
|
7
|
+
DEGRADED = "degraded",
|
|
8
|
+
UNHEALTHY = "unhealthy"
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* MCP server health information
|
|
12
|
+
*/
|
|
13
|
+
export interface McpServerHealth {
|
|
14
|
+
name: string;
|
|
15
|
+
status: ClientStatus;
|
|
16
|
+
healthy: boolean;
|
|
17
|
+
lastConnected?: Date;
|
|
18
|
+
lastError?: string;
|
|
19
|
+
tags?: string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* System health metrics
|
|
23
|
+
*/
|
|
24
|
+
export interface SystemHealth {
|
|
25
|
+
uptime: number;
|
|
26
|
+
memory: {
|
|
27
|
+
used: number;
|
|
28
|
+
total: number;
|
|
29
|
+
percentage: number;
|
|
30
|
+
};
|
|
31
|
+
process: {
|
|
32
|
+
pid: number;
|
|
33
|
+
nodeVersion: string;
|
|
34
|
+
platform: string;
|
|
35
|
+
arch: string;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Complete health check response
|
|
40
|
+
*/
|
|
41
|
+
export interface HealthCheckResponse {
|
|
42
|
+
status: HealthStatus;
|
|
43
|
+
timestamp: string;
|
|
44
|
+
version: string;
|
|
45
|
+
system: SystemHealth;
|
|
46
|
+
servers: {
|
|
47
|
+
total: number;
|
|
48
|
+
healthy: number;
|
|
49
|
+
unhealthy: number;
|
|
50
|
+
details: McpServerHealth[];
|
|
51
|
+
};
|
|
52
|
+
configuration: {
|
|
53
|
+
loaded: boolean;
|
|
54
|
+
serverCount: number;
|
|
55
|
+
enabledCount: number;
|
|
56
|
+
disabledCount: number;
|
|
57
|
+
authEnabled: boolean;
|
|
58
|
+
transport: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Health service for monitoring system and MCP server status
|
|
63
|
+
*/
|
|
64
|
+
export declare class HealthService {
|
|
65
|
+
private static instance;
|
|
66
|
+
private startTime;
|
|
67
|
+
private agentConfig;
|
|
68
|
+
private constructor();
|
|
69
|
+
/**
|
|
70
|
+
* Get singleton instance
|
|
71
|
+
*/
|
|
72
|
+
static getInstance(): HealthService;
|
|
73
|
+
/**
|
|
74
|
+
* Perform complete health check
|
|
75
|
+
*/
|
|
76
|
+
performHealthCheck(): Promise<HealthCheckResponse>;
|
|
77
|
+
/**
|
|
78
|
+
* Sanitize health response based on security configuration
|
|
79
|
+
*/
|
|
80
|
+
private sanitizeHealthResponse;
|
|
81
|
+
/**
|
|
82
|
+
* Sanitize error messages to prevent information leakage
|
|
83
|
+
*/
|
|
84
|
+
private sanitizeErrorMessage;
|
|
85
|
+
/**
|
|
86
|
+
* Get system health metrics
|
|
87
|
+
*/
|
|
88
|
+
private getSystemHealth;
|
|
89
|
+
/**
|
|
90
|
+
* Get MCP server health status
|
|
91
|
+
*/
|
|
92
|
+
private getServerHealth;
|
|
93
|
+
/**
|
|
94
|
+
* Get configuration health status
|
|
95
|
+
*/
|
|
96
|
+
private getConfigurationHealth;
|
|
97
|
+
/**
|
|
98
|
+
* Determine overall health status based on component status
|
|
99
|
+
*/
|
|
100
|
+
private determineOverallHealth;
|
|
101
|
+
/**
|
|
102
|
+
* Get HTTP status code based on health status
|
|
103
|
+
*/
|
|
104
|
+
getHttpStatusCode(healthStatus: HealthStatus): number;
|
|
105
|
+
}
|
|
106
|
+
export default HealthService;
|
|
107
|
+
//# sourceMappingURL=healthService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"healthService.d.ts","sourceRoot":"","sources":["../../src/services/healthService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAOtD;;GAEG;AACH,oBAAY,YAAY;IACtB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,SAAS,cAAc;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,eAAe,EAAE,CAAC;KAC5B,CAAC;IACF,aAAa,EAAE;QACb,MAAM,EAAE,OAAO,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,OAAO,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgB;IACvC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAqB;IAExC,OAAO;IAKP;;OAEG;WACW,WAAW,IAAI,aAAa;IAO1C;;OAEG;IACU,kBAAkB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAyB/D;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA0E9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAc5B;;OAEG;IACH,OAAO,CAAC,eAAe;IAmBvB;;OAEG;YACW,eAAe;IAqD7B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA+B9B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA4B9B;;OAEG;IACI,iBAAiB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM;CAY7D;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { ClientStatus } from '../core/types/index.js';
|
|
2
|
+
import { ServerManager } from '../core/server/serverManager.js';
|
|
3
|
+
import { McpConfigManager } from '../config/mcpConfigManager.js';
|
|
4
|
+
import { AgentConfigManager } from '../core/server/agentConfig.js';
|
|
5
|
+
import { MCP_SERVER_VERSION } from '../constants.js';
|
|
6
|
+
import logger from '../logger/logger.js';
|
|
7
|
+
/**
|
|
8
|
+
* Health status levels
|
|
9
|
+
*/
|
|
10
|
+
export var HealthStatus;
|
|
11
|
+
(function (HealthStatus) {
|
|
12
|
+
HealthStatus["HEALTHY"] = "healthy";
|
|
13
|
+
HealthStatus["DEGRADED"] = "degraded";
|
|
14
|
+
HealthStatus["UNHEALTHY"] = "unhealthy";
|
|
15
|
+
})(HealthStatus || (HealthStatus = {}));
|
|
16
|
+
/**
|
|
17
|
+
* Health service for monitoring system and MCP server status
|
|
18
|
+
*/
|
|
19
|
+
export class HealthService {
|
|
20
|
+
static instance;
|
|
21
|
+
startTime;
|
|
22
|
+
agentConfig;
|
|
23
|
+
constructor() {
|
|
24
|
+
this.startTime = Date.now();
|
|
25
|
+
this.agentConfig = AgentConfigManager.getInstance();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get singleton instance
|
|
29
|
+
*/
|
|
30
|
+
static getInstance() {
|
|
31
|
+
if (!HealthService.instance) {
|
|
32
|
+
HealthService.instance = new HealthService();
|
|
33
|
+
}
|
|
34
|
+
return HealthService.instance;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Perform complete health check
|
|
38
|
+
*/
|
|
39
|
+
async performHealthCheck() {
|
|
40
|
+
try {
|
|
41
|
+
const systemHealth = this.getSystemHealth();
|
|
42
|
+
const serverHealth = await this.getServerHealth();
|
|
43
|
+
const configHealth = this.getConfigurationHealth();
|
|
44
|
+
const overallStatus = this.determineOverallHealth(serverHealth, configHealth);
|
|
45
|
+
const fullResponse = {
|
|
46
|
+
status: overallStatus,
|
|
47
|
+
timestamp: new Date().toISOString(),
|
|
48
|
+
version: MCP_SERVER_VERSION,
|
|
49
|
+
system: systemHealth,
|
|
50
|
+
servers: serverHealth,
|
|
51
|
+
configuration: configHealth,
|
|
52
|
+
};
|
|
53
|
+
// Apply security configuration to sanitize response
|
|
54
|
+
return this.sanitizeHealthResponse(fullResponse);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
logger.error('Health check failed:', error);
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Sanitize health response based on security configuration
|
|
63
|
+
*/
|
|
64
|
+
sanitizeHealthResponse(response) {
|
|
65
|
+
const detailLevel = this.agentConfig.getHealthDetailLevel();
|
|
66
|
+
// Apply detail level restrictions
|
|
67
|
+
switch (detailLevel) {
|
|
68
|
+
case 'minimal':
|
|
69
|
+
// Minimal: Only basic status, no sensitive details
|
|
70
|
+
return {
|
|
71
|
+
status: response.status,
|
|
72
|
+
timestamp: response.timestamp,
|
|
73
|
+
version: response.version,
|
|
74
|
+
system: {
|
|
75
|
+
uptime: response.system.uptime,
|
|
76
|
+
memory: { used: 0, total: 0, percentage: 0 },
|
|
77
|
+
process: { pid: 0, nodeVersion: '', platform: '', arch: '' },
|
|
78
|
+
},
|
|
79
|
+
servers: {
|
|
80
|
+
total: response.servers.total,
|
|
81
|
+
healthy: response.servers.healthy,
|
|
82
|
+
unhealthy: response.servers.unhealthy,
|
|
83
|
+
details: [],
|
|
84
|
+
},
|
|
85
|
+
configuration: {
|
|
86
|
+
loaded: response.configuration.loaded,
|
|
87
|
+
serverCount: 0,
|
|
88
|
+
enabledCount: 0,
|
|
89
|
+
disabledCount: 0,
|
|
90
|
+
authEnabled: false,
|
|
91
|
+
transport: 'http',
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
case 'basic':
|
|
95
|
+
// Basic: Some server info but sanitized errors and no sensitive system details
|
|
96
|
+
return {
|
|
97
|
+
...response,
|
|
98
|
+
system: {
|
|
99
|
+
uptime: response.system.uptime,
|
|
100
|
+
memory: {
|
|
101
|
+
used: Math.round(response.system.memory.used),
|
|
102
|
+
total: Math.round(response.system.memory.total),
|
|
103
|
+
percentage: response.system.memory.percentage,
|
|
104
|
+
},
|
|
105
|
+
process: { pid: 0, nodeVersion: '', platform: '', arch: '' },
|
|
106
|
+
},
|
|
107
|
+
servers: {
|
|
108
|
+
...response.servers,
|
|
109
|
+
details: response.servers.details.map((server) => ({
|
|
110
|
+
name: server.name,
|
|
111
|
+
status: server.status,
|
|
112
|
+
healthy: server.healthy,
|
|
113
|
+
lastConnected: server.lastConnected,
|
|
114
|
+
lastError: this.sanitizeErrorMessage(server.lastError),
|
|
115
|
+
tags: server.tags,
|
|
116
|
+
})),
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
case 'full':
|
|
120
|
+
default:
|
|
121
|
+
// Full: All details but with basic error sanitization
|
|
122
|
+
return {
|
|
123
|
+
...response,
|
|
124
|
+
servers: {
|
|
125
|
+
...response.servers,
|
|
126
|
+
details: response.servers.details.map((server) => ({
|
|
127
|
+
...server,
|
|
128
|
+
lastError: this.sanitizeErrorMessage(server.lastError),
|
|
129
|
+
})),
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Sanitize error messages to prevent information leakage
|
|
136
|
+
*/
|
|
137
|
+
sanitizeErrorMessage(errorMessage) {
|
|
138
|
+
if (!errorMessage)
|
|
139
|
+
return undefined;
|
|
140
|
+
// Remove potentially sensitive information from error messages
|
|
141
|
+
return errorMessage
|
|
142
|
+
.replace(/\b(?:password|token|key|secret|auth)\s*[:=]\s*[^\s]+/gi, '[REDACTED_CREDENTIAL]') // Key-value credentials
|
|
143
|
+
.replace(/\b[\w.-]+:[\w.-]+@/gi, '[REDACTED_CREDENTIAL]') // User:password@ patterns
|
|
144
|
+
.replace(/\bhttps?:\/\/[\w.-]+(?::\d+)?(?:\/[^\s]*)?/gi, '[REDACTED_URL]') // Complete URLs
|
|
145
|
+
.replace(/(?:[A-Za-z]:)?[/\\][\w.-]+(?:[/\\][\w.-]+)*\.(?:json|js|ts|py|yml|yaml|conf|ini)\b/g, '[REDACTED_PATH]') // File paths
|
|
146
|
+
.replace(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g, '[REDACTED_IP]') // IP addresses
|
|
147
|
+
.replace(/\blocalhost(?::\d+)?\b/gi, '[REDACTED_HOST]') // Localhost references
|
|
148
|
+
.substring(0, 100); // Limit error message length
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get system health metrics
|
|
152
|
+
*/
|
|
153
|
+
getSystemHealth() {
|
|
154
|
+
const memUsage = process.memoryUsage();
|
|
155
|
+
return {
|
|
156
|
+
uptime: Math.floor((Date.now() - this.startTime) / 1000),
|
|
157
|
+
memory: {
|
|
158
|
+
used: Math.round((memUsage.heapUsed / 1024 / 1024) * 100) / 100, // MB
|
|
159
|
+
total: Math.round((memUsage.heapTotal / 1024 / 1024) * 100) / 100, // MB
|
|
160
|
+
percentage: Math.round((memUsage.heapUsed / memUsage.heapTotal) * 100 * 100) / 100,
|
|
161
|
+
},
|
|
162
|
+
process: {
|
|
163
|
+
pid: process.pid,
|
|
164
|
+
nodeVersion: process.version,
|
|
165
|
+
platform: process.platform,
|
|
166
|
+
arch: process.arch,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get MCP server health status
|
|
172
|
+
*/
|
|
173
|
+
async getServerHealth() {
|
|
174
|
+
try {
|
|
175
|
+
const serverManager = ServerManager.current;
|
|
176
|
+
if (!serverManager) {
|
|
177
|
+
return {
|
|
178
|
+
total: 0,
|
|
179
|
+
healthy: 0,
|
|
180
|
+
unhealthy: 0,
|
|
181
|
+
details: [],
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
const clients = serverManager.getClients();
|
|
185
|
+
const serverDetails = [];
|
|
186
|
+
let healthyCount = 0;
|
|
187
|
+
let unhealthyCount = 0;
|
|
188
|
+
for (const [name, clientInfo] of clients.entries()) {
|
|
189
|
+
const isHealthy = clientInfo.status === ClientStatus.Connected;
|
|
190
|
+
if (isHealthy) {
|
|
191
|
+
healthyCount++;
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
unhealthyCount++;
|
|
195
|
+
}
|
|
196
|
+
serverDetails.push({
|
|
197
|
+
name,
|
|
198
|
+
status: clientInfo.status,
|
|
199
|
+
healthy: isHealthy,
|
|
200
|
+
lastConnected: clientInfo.lastConnected,
|
|
201
|
+
lastError: clientInfo.lastError?.message,
|
|
202
|
+
tags: clientInfo.transport.tags,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
total: clients.size,
|
|
207
|
+
healthy: healthyCount,
|
|
208
|
+
unhealthy: unhealthyCount,
|
|
209
|
+
details: serverDetails,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
logger.error('Error getting server health:', error);
|
|
214
|
+
return {
|
|
215
|
+
total: 0,
|
|
216
|
+
healthy: 0,
|
|
217
|
+
unhealthy: 0,
|
|
218
|
+
details: [],
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Get configuration health status
|
|
224
|
+
*/
|
|
225
|
+
getConfigurationHealth() {
|
|
226
|
+
try {
|
|
227
|
+
const mcpConfig = McpConfigManager.getInstance();
|
|
228
|
+
const agentConfig = AgentConfigManager.getInstance();
|
|
229
|
+
const config = mcpConfig.getTransportConfig();
|
|
230
|
+
const serverCount = Object.keys(config).length;
|
|
231
|
+
const enabledCount = Object.values(config).filter((server) => !server.disabled).length;
|
|
232
|
+
const disabledCount = serverCount - enabledCount;
|
|
233
|
+
return {
|
|
234
|
+
loaded: true,
|
|
235
|
+
serverCount,
|
|
236
|
+
enabledCount,
|
|
237
|
+
disabledCount,
|
|
238
|
+
authEnabled: agentConfig.isAuthEnabled(),
|
|
239
|
+
transport: 'http', // Since this is the HTTP transport layer
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
logger.error('Error getting configuration health:', error);
|
|
244
|
+
return {
|
|
245
|
+
loaded: false,
|
|
246
|
+
serverCount: 0,
|
|
247
|
+
enabledCount: 0,
|
|
248
|
+
disabledCount: 0,
|
|
249
|
+
authEnabled: false,
|
|
250
|
+
transport: 'unknown',
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Determine overall health status based on component status
|
|
256
|
+
*/
|
|
257
|
+
determineOverallHealth(serverHealth, configHealth) {
|
|
258
|
+
// Configuration must be loaded
|
|
259
|
+
if (!configHealth.loaded) {
|
|
260
|
+
return HealthStatus.UNHEALTHY;
|
|
261
|
+
}
|
|
262
|
+
// If no servers are configured, system is healthy but degraded
|
|
263
|
+
if (serverHealth.total === 0) {
|
|
264
|
+
return HealthStatus.DEGRADED;
|
|
265
|
+
}
|
|
266
|
+
// If all servers are healthy, system is healthy
|
|
267
|
+
if (serverHealth.healthy === serverHealth.total) {
|
|
268
|
+
return HealthStatus.HEALTHY;
|
|
269
|
+
}
|
|
270
|
+
// If more than half servers are healthy, system is degraded
|
|
271
|
+
if (serverHealth.healthy > serverHealth.total / 2) {
|
|
272
|
+
return HealthStatus.DEGRADED;
|
|
273
|
+
}
|
|
274
|
+
// If less than half servers are healthy, system is unhealthy
|
|
275
|
+
return HealthStatus.UNHEALTHY;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Get HTTP status code based on health status
|
|
279
|
+
*/
|
|
280
|
+
getHttpStatusCode(healthStatus) {
|
|
281
|
+
switch (healthStatus) {
|
|
282
|
+
case HealthStatus.HEALTHY:
|
|
283
|
+
return 200;
|
|
284
|
+
case HealthStatus.DEGRADED:
|
|
285
|
+
return 200; // Still operational, but with warnings
|
|
286
|
+
case HealthStatus.UNHEALTHY:
|
|
287
|
+
return 503; // Service unavailable
|
|
288
|
+
default:
|
|
289
|
+
return 500; // Internal server error
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
export default HealthService;
|
|
294
|
+
//# sourceMappingURL=healthService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"healthService.js","sourceRoot":"","sources":["../../src/services/healthService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import { McpLoadingManager } from '../../../core/loading/mcpLoadingManager.js';
|
|
3
|
+
/**
|
|
4
|
+
* Extended request interface to include MCP loading information
|
|
5
|
+
*/
|
|
6
|
+
export interface McpRequest extends Request {
|
|
7
|
+
mcpAvailability?: {
|
|
8
|
+
availableServers: string[];
|
|
9
|
+
unavailableServers: string[];
|
|
10
|
+
loadingServers: string[];
|
|
11
|
+
oauthRequiredServers: string[];
|
|
12
|
+
hasPartialAvailability: boolean;
|
|
13
|
+
allServersReady: boolean;
|
|
14
|
+
requestedTags?: string[];
|
|
15
|
+
totalServersBeforeFiltering?: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Middleware options for MCP availability checking
|
|
20
|
+
*/
|
|
21
|
+
export interface McpAvailabilityOptions {
|
|
22
|
+
/** Whether to allow requests when some servers are still loading */
|
|
23
|
+
allowPartialAvailability?: boolean;
|
|
24
|
+
/** Whether to include OAuth-required servers as available */
|
|
25
|
+
includeOAuthServers?: boolean;
|
|
26
|
+
/** Custom error message for unavailable servers */
|
|
27
|
+
unavailableMessage?: string;
|
|
28
|
+
/** Custom error message for loading servers */
|
|
29
|
+
loadingMessage?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Creates middleware that checks MCP server availability before processing requests
|
|
33
|
+
*
|
|
34
|
+
* This middleware examines the loading state of MCP servers and provides different
|
|
35
|
+
* behaviors based on server availability and configuration options.
|
|
36
|
+
*
|
|
37
|
+
* @param loadingManager - The MCP loading manager instance
|
|
38
|
+
* @param options - Configuration options for availability checking
|
|
39
|
+
* @returns Express middleware function
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const availabilityMiddleware = createMcpAvailabilityMiddleware(loadingManager, {
|
|
44
|
+
* allowPartialAvailability: true,
|
|
45
|
+
* includeOAuthServers: false,
|
|
46
|
+
* });
|
|
47
|
+
*
|
|
48
|
+
* router.post('/mcp', availabilityMiddleware, (req, res) => {
|
|
49
|
+
* // Handle MCP request with availability info in req.mcpAvailability
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function createMcpAvailabilityMiddleware(loadingManager?: McpLoadingManager, options?: McpAvailabilityOptions): (req: McpRequest, res: Response, next: NextFunction) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Utility function to get MCP availability info from request
|
|
56
|
+
*/
|
|
57
|
+
export declare function getMcpAvailability(req: Request): {
|
|
58
|
+
availableServers: string[];
|
|
59
|
+
unavailableServers: string[];
|
|
60
|
+
loadingServers: string[];
|
|
61
|
+
oauthRequiredServers: string[];
|
|
62
|
+
hasPartialAvailability: boolean;
|
|
63
|
+
allServersReady: boolean;
|
|
64
|
+
requestedTags?: string[];
|
|
65
|
+
totalServersBeforeFiltering?: number;
|
|
66
|
+
} | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Utility function to check if all MCP servers are ready
|
|
69
|
+
*/
|
|
70
|
+
export declare function areAllMcpServersReady(req: Request): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Utility function to get list of available MCP servers
|
|
73
|
+
*/
|
|
74
|
+
export declare function getAvailableMcpServers(req: Request): string[];
|
|
75
|
+
/**
|
|
76
|
+
* Utility function to get list of loading MCP servers
|
|
77
|
+
*/
|
|
78
|
+
export declare function getLoadingMcpServers(req: Request): string[];
|
|
79
|
+
//# sourceMappingURL=mcpAvailabilityMiddleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpAvailabilityMiddleware.d.ts","sourceRoot":"","sources":["../../../../src/transport/http/middlewares/mcpAvailabilityMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAK/E;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,OAAO;IACzC,eAAe,CAAC,EAAE;QAChB,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,cAAc,EAAE,MAAM,EAAE,CAAC;QACzB,oBAAoB,EAAE,MAAM,EAAE,CAAC;QAC/B,sBAAsB,EAAE,OAAO,CAAC;QAChC,eAAe,EAAE,OAAO,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,2BAA2B,CAAC,EAAE,MAAM,CAAC;KACtC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,oEAAoE;IACpE,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,mDAAmD;IACnD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAYD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,+BAA+B,CAC7C,cAAc,CAAC,EAAE,iBAAiB,EAClC,OAAO,GAAE,sBAA2B,IAI5B,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UA4M3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO;sBAhRzB,MAAM,EAAE;wBACN,MAAM,EAAE;oBACZ,MAAM,EAAE;0BACF,MAAM,EAAE;4BACN,OAAO;qBACd,OAAO;oBACR,MAAM,EAAE;kCACM,MAAM;cA2QvC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAG3D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAG7D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAG3D"}
|