@elliotding/ai-agent-mcp 0.1.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/dist/api/cached-client.d.ts +48 -0
- package/dist/api/cached-client.d.ts.map +1 -0
- package/dist/api/cached-client.js +126 -0
- package/dist/api/cached-client.js.map +1 -0
- package/dist/api/client.d.ts +213 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +326 -0
- package/dist/api/client.js.map +1 -0
- package/dist/auth/index.d.ts +8 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +26 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/middleware.d.ts +36 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +194 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/permissions.d.ts +60 -0
- package/dist/auth/permissions.d.ts.map +1 -0
- package/dist/auth/permissions.js +256 -0
- package/dist/auth/permissions.js.map +1 -0
- package/dist/auth/token-validator.d.ts +52 -0
- package/dist/auth/token-validator.d.ts.map +1 -0
- package/dist/auth/token-validator.js +217 -0
- package/dist/auth/token-validator.js.map +1 -0
- package/dist/cache/cache-manager.d.ts +49 -0
- package/dist/cache/cache-manager.d.ts.map +1 -0
- package/dist/cache/cache-manager.js +191 -0
- package/dist/cache/cache-manager.js.map +1 -0
- package/dist/cache/index.d.ts +6 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +12 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/redis-client.d.ts +45 -0
- package/dist/cache/redis-client.d.ts.map +1 -0
- package/dist/cache/redis-client.js +210 -0
- package/dist/cache/redis-client.js.map +1 -0
- package/dist/config/constants.d.ts +28 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +31 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/index.d.ts +54 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +168 -0
- package/dist/config/index.js.map +1 -0
- package/dist/filesystem/manager.d.ts +45 -0
- package/dist/filesystem/manager.d.ts.map +1 -0
- package/dist/filesystem/manager.js +246 -0
- package/dist/filesystem/manager.js.map +1 -0
- package/dist/git/multi-source-manager.d.ts +62 -0
- package/dist/git/multi-source-manager.d.ts.map +1 -0
- package/dist/git/multi-source-manager.js +293 -0
- package/dist/git/multi-source-manager.js.map +1 -0
- package/dist/git/operations.d.ts +27 -0
- package/dist/git/operations.d.ts.map +1 -0
- package/dist/git/operations.js +83 -0
- package/dist/git/operations.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +109 -0
- package/dist/index.js.map +1 -0
- package/dist/monitoring/health.d.ts +35 -0
- package/dist/monitoring/health.d.ts.map +1 -0
- package/dist/monitoring/health.js +105 -0
- package/dist/monitoring/health.js.map +1 -0
- package/dist/resources/index.d.ts +6 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +10 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/loader.d.ts +87 -0
- package/dist/resources/loader.d.ts.map +1 -0
- package/dist/resources/loader.js +452 -0
- package/dist/resources/loader.js.map +1 -0
- package/dist/server/http.d.ts +57 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +336 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +157 -0
- package/dist/server.js.map +1 -0
- package/dist/session/manager.d.ts +91 -0
- package/dist/session/manager.d.ts.map +1 -0
- package/dist/session/manager.js +251 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +27 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/manage-subscription.d.ts +43 -0
- package/dist/tools/manage-subscription.d.ts.map +1 -0
- package/dist/tools/manage-subscription.js +268 -0
- package/dist/tools/manage-subscription.js.map +1 -0
- package/dist/tools/registry.d.ts +40 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +85 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/search-resources.d.ts +31 -0
- package/dist/tools/search-resources.d.ts.map +1 -0
- package/dist/tools/search-resources.js +154 -0
- package/dist/tools/search-resources.js.map +1 -0
- package/dist/tools/sync-resources.d.ts +41 -0
- package/dist/tools/sync-resources.d.ts.map +1 -0
- package/dist/tools/sync-resources.js +606 -0
- package/dist/tools/sync-resources.js.map +1 -0
- package/dist/tools/uninstall-resource.d.ts +30 -0
- package/dist/tools/uninstall-resource.d.ts.map +1 -0
- package/dist/tools/uninstall-resource.js +259 -0
- package/dist/tools/uninstall-resource.js.map +1 -0
- package/dist/tools/upload-resource.d.ts +77 -0
- package/dist/tools/upload-resource.d.ts.map +1 -0
- package/dist/tools/upload-resource.js +252 -0
- package/dist/tools/upload-resource.js.map +1 -0
- package/dist/transport/sse.d.ts +29 -0
- package/dist/transport/sse.d.ts.map +1 -0
- package/dist/transport/sse.js +271 -0
- package/dist/transport/sse.js.map +1 -0
- package/dist/types/errors.d.ts +60 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +112 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/mcp.d.ts +50 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +6 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/types/resources.d.ts +109 -0
- package/dist/types/resources.d.ts.map +1 -0
- package/dist/types/resources.js +7 -0
- package/dist/types/resources.js.map +1 -0
- package/dist/types/tools.d.ts +147 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +6 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/utils/cursor-paths.d.ts +49 -0
- package/dist/utils/cursor-paths.d.ts.map +1 -0
- package/dist/utils/cursor-paths.js +116 -0
- package/dist/utils/cursor-paths.js.map +1 -0
- package/dist/utils/log-cleaner.d.ts +18 -0
- package/dist/utils/log-cleaner.d.ts.map +1 -0
- package/dist/utils/log-cleaner.js +112 -0
- package/dist/utils/log-cleaner.js.map +1 -0
- package/dist/utils/logger.d.ts +59 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +292 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validation.d.ts +58 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +214 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +58 -0
- package/src/api/cached-client.ts +144 -0
- package/src/api/client.ts +578 -0
- package/src/auth/index.ts +11 -0
- package/src/auth/middleware.ts +244 -0
- package/src/auth/permissions.ts +317 -0
- package/src/auth/token-validator.ts +294 -0
- package/src/cache/cache-manager.ts +243 -0
- package/src/cache/index.ts +6 -0
- package/src/cache/redis-client.ts +249 -0
- package/src/config/constants.ts +33 -0
- package/src/config/index.ts +228 -0
- package/src/filesystem/manager.ts +235 -0
- package/src/git/multi-source-manager.ts +333 -0
- package/src/git/operations.ts +93 -0
- package/src/index.ts +139 -0
- package/src/monitoring/health.ts +132 -0
- package/src/resources/index.ts +13 -0
- package/src/resources/loader.ts +530 -0
- package/src/server/http.ts +427 -0
- package/src/server.ts +191 -0
- package/src/session/manager.ts +296 -0
- package/src/tools/index.ts +11 -0
- package/src/tools/manage-subscription.ts +332 -0
- package/src/tools/registry.ts +97 -0
- package/src/tools/search-resources.ts +177 -0
- package/src/tools/sync-resources.ts +662 -0
- package/src/tools/uninstall-resource.ts +248 -0
- package/src/tools/upload-resource.ts +258 -0
- package/src/transport/sse.ts +308 -0
- package/src/types/errors.ts +146 -0
- package/src/types/index.ts +7 -0
- package/src/types/mcp.ts +61 -0
- package/src/types/resources.ts +141 -0
- package/src/types/tools.ts +175 -0
- package/src/utils/cursor-paths.ts +83 -0
- package/src/utils/log-cleaner.ts +92 -0
- package/src/utils/logger.ts +333 -0
- package/src/utils/validation.ts +262 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CSP AI Agent MCP Server - Main Entry Point
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { config } from './config';
|
|
8
|
+
import { logger } from './utils/logger';
|
|
9
|
+
import { startLogCleanupSchedule, stopLogCleanupSchedule } from './utils/log-cleaner';
|
|
10
|
+
import { startServer, stopServer } from './server';
|
|
11
|
+
import { stopCacheCleanup } from './auth/token-validator';
|
|
12
|
+
import { sessionManager } from './session/manager';
|
|
13
|
+
|
|
14
|
+
// Global error handlers
|
|
15
|
+
process.on('uncaughtException', (error: Error) => {
|
|
16
|
+
// Handle EPIPE and ECONNRESET gracefully (client disconnected)
|
|
17
|
+
if (error.message.includes('EPIPE') || error.message.includes('ECONNRESET')) {
|
|
18
|
+
logger.debug({
|
|
19
|
+
error: error.message,
|
|
20
|
+
type: 'uncaught_exception_network'
|
|
21
|
+
}, 'Client disconnected (EPIPE/ECONNRESET)');
|
|
22
|
+
return; // Don't exit for network errors
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// For other uncaught exceptions, log and exit
|
|
26
|
+
logger.error({ error, type: 'uncaught_exception' }, `Uncaught Exception: ${error.message}`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
process.on('unhandledRejection', (reason: unknown, _promise: Promise<unknown>) => {
|
|
31
|
+
logger.error(
|
|
32
|
+
{
|
|
33
|
+
type: 'unhandled_rejection',
|
|
34
|
+
reason: reason instanceof Error ? reason.message : String(reason),
|
|
35
|
+
stack: reason instanceof Error ? reason.stack : undefined,
|
|
36
|
+
},
|
|
37
|
+
'Unhandled Promise Rejection'
|
|
38
|
+
);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
async function main() {
|
|
43
|
+
logger.info(
|
|
44
|
+
{
|
|
45
|
+
nodeEnv: config.nodeEnv,
|
|
46
|
+
port: config.port,
|
|
47
|
+
logLevel: config.logLevel,
|
|
48
|
+
},
|
|
49
|
+
'Starting CSP AI Agent MCP Server...'
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// Start log cleanup scheduler
|
|
53
|
+
const cleanupTimer = startLogCleanupSchedule();
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
// Start MCP Server
|
|
57
|
+
await startServer();
|
|
58
|
+
|
|
59
|
+
logger.info({ port: config.port }, `✅ CSP AI Agent MCP Server started successfully`);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
logger.error({ error }, 'Failed to start server');
|
|
62
|
+
stopLogCleanupSchedule(cleanupTimer);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Graceful shutdown handlers
|
|
67
|
+
let isShuttingDown = false;
|
|
68
|
+
const SHUTDOWN_TIMEOUT = Number(process.env.SHUTDOWN_TIMEOUT) || 30000; // 30 seconds default
|
|
69
|
+
|
|
70
|
+
const shutdown = async (signal: string) => {
|
|
71
|
+
// Prevent multiple shutdown attempts
|
|
72
|
+
if (isShuttingDown) {
|
|
73
|
+
logger.warn({ signal }, 'Shutdown already in progress, ignoring signal');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
isShuttingDown = true;
|
|
77
|
+
|
|
78
|
+
logger.info({ signal, timeout: SHUTDOWN_TIMEOUT }, `Received ${signal}, starting graceful shutdown...`);
|
|
79
|
+
|
|
80
|
+
// Set timeout for forced shutdown
|
|
81
|
+
const shutdownTimer = setTimeout(() => {
|
|
82
|
+
logger.error(
|
|
83
|
+
{ timeout: SHUTDOWN_TIMEOUT },
|
|
84
|
+
`Graceful shutdown timeout (${SHUTDOWN_TIMEOUT}ms), forcing exit`
|
|
85
|
+
);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}, SHUTDOWN_TIMEOUT);
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
// Phase 1: Stop accepting new requests
|
|
91
|
+
logger.info('Phase 1: Stopping new requests...');
|
|
92
|
+
|
|
93
|
+
// Phase 2: Wait for ongoing requests to complete
|
|
94
|
+
logger.info('Phase 2: Waiting for ongoing requests to complete...');
|
|
95
|
+
|
|
96
|
+
// Stop MCP Server (this will close all active sessions and connections)
|
|
97
|
+
await stopServer();
|
|
98
|
+
|
|
99
|
+
// Phase 3: Stop background tasks
|
|
100
|
+
logger.info('Phase 3: Stopping background tasks...');
|
|
101
|
+
|
|
102
|
+
// Stop log cleanup
|
|
103
|
+
stopLogCleanupSchedule(cleanupTimer);
|
|
104
|
+
|
|
105
|
+
// Stop session cleanup
|
|
106
|
+
sessionManager.stopCleanup();
|
|
107
|
+
logger.info('Session cleanup stopped');
|
|
108
|
+
|
|
109
|
+
// Stop token cache cleanup
|
|
110
|
+
stopCacheCleanup();
|
|
111
|
+
logger.info('Token cache cleanup stopped');
|
|
112
|
+
|
|
113
|
+
// Phase 4: Flush logs
|
|
114
|
+
logger.info('Phase 4: Flushing logs...');
|
|
115
|
+
|
|
116
|
+
// Give logger time to flush
|
|
117
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
118
|
+
|
|
119
|
+
// Clear shutdown timeout
|
|
120
|
+
clearTimeout(shutdownTimer);
|
|
121
|
+
|
|
122
|
+
logger.info('✅ Graceful shutdown completed successfully');
|
|
123
|
+
process.exit(0);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
logger.error({ error }, 'Error during graceful shutdown');
|
|
126
|
+
clearTimeout(shutdownTimer);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
process.on('SIGINT', () => void shutdown('SIGINT'));
|
|
132
|
+
process.on('SIGTERM', () => void shutdown('SIGTERM'));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Start the application
|
|
136
|
+
void main().catch((error: unknown) => {
|
|
137
|
+
logger.error({ error }, 'Fatal error during startup');
|
|
138
|
+
process.exit(1);
|
|
139
|
+
});
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { CacheManager } from '../cache/cache-manager.js';
|
|
2
|
+
|
|
3
|
+
export interface HealthStatus {
|
|
4
|
+
status: 'healthy' | 'unhealthy';
|
|
5
|
+
timestamp: string;
|
|
6
|
+
services: {
|
|
7
|
+
http: 'up' | 'down';
|
|
8
|
+
redis: 'up' | 'down' | 'not_configured';
|
|
9
|
+
cache: 'healthy' | 'degraded' | 'down';
|
|
10
|
+
};
|
|
11
|
+
details?: {
|
|
12
|
+
redisError?: string;
|
|
13
|
+
cacheError?: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class HealthChecker {
|
|
18
|
+
private cacheManager: CacheManager | null = null;
|
|
19
|
+
|
|
20
|
+
constructor(cacheManager?: CacheManager) {
|
|
21
|
+
this.cacheManager = cacheManager || null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Check HTTP Server health
|
|
26
|
+
*/
|
|
27
|
+
private checkHttpServer(): 'up' | 'down' {
|
|
28
|
+
// HTTP server is up if this code is running
|
|
29
|
+
return 'up';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Check Redis connection health
|
|
34
|
+
*/
|
|
35
|
+
private async checkRedis(): Promise<{ status: 'up' | 'down' | 'not_configured'; error?: string }> {
|
|
36
|
+
if (!this.cacheManager) {
|
|
37
|
+
return { status: 'not_configured' };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
// Try to check Redis connection via cache manager
|
|
42
|
+
const redisCache = (this.cacheManager as any).l2Cache;
|
|
43
|
+
|
|
44
|
+
if (!redisCache) {
|
|
45
|
+
return { status: 'not_configured' };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Try a simple Redis operation (check client status)
|
|
49
|
+
const client = (redisCache as any).client;
|
|
50
|
+
|
|
51
|
+
if (!client || !client.isReady) {
|
|
52
|
+
return { status: 'down', error: 'Redis client not ready' };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Try a ping operation
|
|
56
|
+
await client.ping();
|
|
57
|
+
return { status: 'up' };
|
|
58
|
+
} catch (error) {
|
|
59
|
+
return {
|
|
60
|
+
status: 'down',
|
|
61
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Check Cache health
|
|
68
|
+
*/
|
|
69
|
+
private checkCache(): { status: 'healthy' | 'degraded' | 'down'; error?: string } {
|
|
70
|
+
if (!this.cacheManager) {
|
|
71
|
+
return { status: 'down', error: 'Cache manager not initialized' };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
// Check if cache manager is functional
|
|
76
|
+
const stats = this.cacheManager.getStats();
|
|
77
|
+
|
|
78
|
+
// Cache is healthy if stats are available
|
|
79
|
+
if (stats && typeof stats.hitRate === 'number') {
|
|
80
|
+
// Check if hit rate is reasonable (> 0 means cache is working)
|
|
81
|
+
if (stats.hitRate >= 0) {
|
|
82
|
+
return { status: 'healthy' };
|
|
83
|
+
}
|
|
84
|
+
return { status: 'degraded', error: 'Low cache hit rate' };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { status: 'degraded', error: 'Cache stats unavailable' };
|
|
88
|
+
} catch (error) {
|
|
89
|
+
return {
|
|
90
|
+
status: 'down',
|
|
91
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Perform comprehensive health check
|
|
98
|
+
*/
|
|
99
|
+
async check(): Promise<HealthStatus> {
|
|
100
|
+
const httpStatus = this.checkHttpServer();
|
|
101
|
+
const redisResult = await this.checkRedis();
|
|
102
|
+
const cacheResult = this.checkCache();
|
|
103
|
+
|
|
104
|
+
const allHealthy =
|
|
105
|
+
httpStatus === 'up' &&
|
|
106
|
+
(redisResult.status === 'up' || redisResult.status === 'not_configured') &&
|
|
107
|
+
cacheResult.status === 'healthy';
|
|
108
|
+
|
|
109
|
+
const health: HealthStatus = {
|
|
110
|
+
status: allHealthy ? 'healthy' : 'unhealthy',
|
|
111
|
+
timestamp: new Date().toISOString(),
|
|
112
|
+
services: {
|
|
113
|
+
http: httpStatus,
|
|
114
|
+
redis: redisResult.status,
|
|
115
|
+
cache: cacheResult.status
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// Add error details if any
|
|
120
|
+
if (redisResult.error || cacheResult.error) {
|
|
121
|
+
health.details = {};
|
|
122
|
+
if (redisResult.error) {
|
|
123
|
+
health.details.redisError = redisResult.error;
|
|
124
|
+
}
|
|
125
|
+
if (cacheResult.error) {
|
|
126
|
+
health.details.cacheError = cacheResult.error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return health;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resources Module Exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { ResourceLoader, resourceLoader } from './loader';
|
|
6
|
+
export type {
|
|
7
|
+
AIResourcesConfig,
|
|
8
|
+
ResourceMetadata,
|
|
9
|
+
ResourceType,
|
|
10
|
+
ResourceSource,
|
|
11
|
+
ResourceConflict,
|
|
12
|
+
LoaderStats,
|
|
13
|
+
} from '../types/resources';
|