@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.
Files changed (191) hide show
  1. package/dist/api/cached-client.d.ts +48 -0
  2. package/dist/api/cached-client.d.ts.map +1 -0
  3. package/dist/api/cached-client.js +126 -0
  4. package/dist/api/cached-client.js.map +1 -0
  5. package/dist/api/client.d.ts +213 -0
  6. package/dist/api/client.d.ts.map +1 -0
  7. package/dist/api/client.js +326 -0
  8. package/dist/api/client.js.map +1 -0
  9. package/dist/auth/index.d.ts +8 -0
  10. package/dist/auth/index.d.ts.map +1 -0
  11. package/dist/auth/index.js +26 -0
  12. package/dist/auth/index.js.map +1 -0
  13. package/dist/auth/middleware.d.ts +36 -0
  14. package/dist/auth/middleware.d.ts.map +1 -0
  15. package/dist/auth/middleware.js +194 -0
  16. package/dist/auth/middleware.js.map +1 -0
  17. package/dist/auth/permissions.d.ts +60 -0
  18. package/dist/auth/permissions.d.ts.map +1 -0
  19. package/dist/auth/permissions.js +256 -0
  20. package/dist/auth/permissions.js.map +1 -0
  21. package/dist/auth/token-validator.d.ts +52 -0
  22. package/dist/auth/token-validator.d.ts.map +1 -0
  23. package/dist/auth/token-validator.js +217 -0
  24. package/dist/auth/token-validator.js.map +1 -0
  25. package/dist/cache/cache-manager.d.ts +49 -0
  26. package/dist/cache/cache-manager.d.ts.map +1 -0
  27. package/dist/cache/cache-manager.js +191 -0
  28. package/dist/cache/cache-manager.js.map +1 -0
  29. package/dist/cache/index.d.ts +6 -0
  30. package/dist/cache/index.d.ts.map +1 -0
  31. package/dist/cache/index.js +12 -0
  32. package/dist/cache/index.js.map +1 -0
  33. package/dist/cache/redis-client.d.ts +45 -0
  34. package/dist/cache/redis-client.d.ts.map +1 -0
  35. package/dist/cache/redis-client.js +210 -0
  36. package/dist/cache/redis-client.js.map +1 -0
  37. package/dist/config/constants.d.ts +28 -0
  38. package/dist/config/constants.d.ts.map +1 -0
  39. package/dist/config/constants.js +31 -0
  40. package/dist/config/constants.js.map +1 -0
  41. package/dist/config/index.d.ts +54 -0
  42. package/dist/config/index.d.ts.map +1 -0
  43. package/dist/config/index.js +168 -0
  44. package/dist/config/index.js.map +1 -0
  45. package/dist/filesystem/manager.d.ts +45 -0
  46. package/dist/filesystem/manager.d.ts.map +1 -0
  47. package/dist/filesystem/manager.js +246 -0
  48. package/dist/filesystem/manager.js.map +1 -0
  49. package/dist/git/multi-source-manager.d.ts +62 -0
  50. package/dist/git/multi-source-manager.d.ts.map +1 -0
  51. package/dist/git/multi-source-manager.js +293 -0
  52. package/dist/git/multi-source-manager.js.map +1 -0
  53. package/dist/git/operations.d.ts +27 -0
  54. package/dist/git/operations.d.ts.map +1 -0
  55. package/dist/git/operations.js +83 -0
  56. package/dist/git/operations.js.map +1 -0
  57. package/dist/index.d.ts +6 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +109 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/monitoring/health.d.ts +35 -0
  62. package/dist/monitoring/health.d.ts.map +1 -0
  63. package/dist/monitoring/health.js +105 -0
  64. package/dist/monitoring/health.js.map +1 -0
  65. package/dist/resources/index.d.ts +6 -0
  66. package/dist/resources/index.d.ts.map +1 -0
  67. package/dist/resources/index.js +10 -0
  68. package/dist/resources/index.js.map +1 -0
  69. package/dist/resources/loader.d.ts +87 -0
  70. package/dist/resources/loader.d.ts.map +1 -0
  71. package/dist/resources/loader.js +452 -0
  72. package/dist/resources/loader.js.map +1 -0
  73. package/dist/server/http.d.ts +57 -0
  74. package/dist/server/http.d.ts.map +1 -0
  75. package/dist/server/http.js +336 -0
  76. package/dist/server/http.js.map +1 -0
  77. package/dist/server.d.ts +13 -0
  78. package/dist/server.d.ts.map +1 -0
  79. package/dist/server.js +157 -0
  80. package/dist/server.js.map +1 -0
  81. package/dist/session/manager.d.ts +91 -0
  82. package/dist/session/manager.d.ts.map +1 -0
  83. package/dist/session/manager.js +251 -0
  84. package/dist/session/manager.js.map +1 -0
  85. package/dist/tools/index.d.ts +11 -0
  86. package/dist/tools/index.d.ts.map +1 -0
  87. package/dist/tools/index.js +27 -0
  88. package/dist/tools/index.js.map +1 -0
  89. package/dist/tools/manage-subscription.d.ts +43 -0
  90. package/dist/tools/manage-subscription.d.ts.map +1 -0
  91. package/dist/tools/manage-subscription.js +268 -0
  92. package/dist/tools/manage-subscription.js.map +1 -0
  93. package/dist/tools/registry.d.ts +40 -0
  94. package/dist/tools/registry.d.ts.map +1 -0
  95. package/dist/tools/registry.js +85 -0
  96. package/dist/tools/registry.js.map +1 -0
  97. package/dist/tools/search-resources.d.ts +31 -0
  98. package/dist/tools/search-resources.d.ts.map +1 -0
  99. package/dist/tools/search-resources.js +154 -0
  100. package/dist/tools/search-resources.js.map +1 -0
  101. package/dist/tools/sync-resources.d.ts +41 -0
  102. package/dist/tools/sync-resources.d.ts.map +1 -0
  103. package/dist/tools/sync-resources.js +606 -0
  104. package/dist/tools/sync-resources.js.map +1 -0
  105. package/dist/tools/uninstall-resource.d.ts +30 -0
  106. package/dist/tools/uninstall-resource.d.ts.map +1 -0
  107. package/dist/tools/uninstall-resource.js +259 -0
  108. package/dist/tools/uninstall-resource.js.map +1 -0
  109. package/dist/tools/upload-resource.d.ts +77 -0
  110. package/dist/tools/upload-resource.d.ts.map +1 -0
  111. package/dist/tools/upload-resource.js +252 -0
  112. package/dist/tools/upload-resource.js.map +1 -0
  113. package/dist/transport/sse.d.ts +29 -0
  114. package/dist/transport/sse.d.ts.map +1 -0
  115. package/dist/transport/sse.js +271 -0
  116. package/dist/transport/sse.js.map +1 -0
  117. package/dist/types/errors.d.ts +60 -0
  118. package/dist/types/errors.d.ts.map +1 -0
  119. package/dist/types/errors.js +112 -0
  120. package/dist/types/errors.js.map +1 -0
  121. package/dist/types/index.d.ts +7 -0
  122. package/dist/types/index.d.ts.map +1 -0
  123. package/dist/types/index.js +23 -0
  124. package/dist/types/index.js.map +1 -0
  125. package/dist/types/mcp.d.ts +50 -0
  126. package/dist/types/mcp.d.ts.map +1 -0
  127. package/dist/types/mcp.js +6 -0
  128. package/dist/types/mcp.js.map +1 -0
  129. package/dist/types/resources.d.ts +109 -0
  130. package/dist/types/resources.d.ts.map +1 -0
  131. package/dist/types/resources.js +7 -0
  132. package/dist/types/resources.js.map +1 -0
  133. package/dist/types/tools.d.ts +147 -0
  134. package/dist/types/tools.d.ts.map +1 -0
  135. package/dist/types/tools.js +6 -0
  136. package/dist/types/tools.js.map +1 -0
  137. package/dist/utils/cursor-paths.d.ts +49 -0
  138. package/dist/utils/cursor-paths.d.ts.map +1 -0
  139. package/dist/utils/cursor-paths.js +116 -0
  140. package/dist/utils/cursor-paths.js.map +1 -0
  141. package/dist/utils/log-cleaner.d.ts +18 -0
  142. package/dist/utils/log-cleaner.d.ts.map +1 -0
  143. package/dist/utils/log-cleaner.js +112 -0
  144. package/dist/utils/log-cleaner.js.map +1 -0
  145. package/dist/utils/logger.d.ts +59 -0
  146. package/dist/utils/logger.d.ts.map +1 -0
  147. package/dist/utils/logger.js +292 -0
  148. package/dist/utils/logger.js.map +1 -0
  149. package/dist/utils/validation.d.ts +58 -0
  150. package/dist/utils/validation.d.ts.map +1 -0
  151. package/dist/utils/validation.js +214 -0
  152. package/dist/utils/validation.js.map +1 -0
  153. package/package.json +58 -0
  154. package/src/api/cached-client.ts +144 -0
  155. package/src/api/client.ts +578 -0
  156. package/src/auth/index.ts +11 -0
  157. package/src/auth/middleware.ts +244 -0
  158. package/src/auth/permissions.ts +317 -0
  159. package/src/auth/token-validator.ts +294 -0
  160. package/src/cache/cache-manager.ts +243 -0
  161. package/src/cache/index.ts +6 -0
  162. package/src/cache/redis-client.ts +249 -0
  163. package/src/config/constants.ts +33 -0
  164. package/src/config/index.ts +228 -0
  165. package/src/filesystem/manager.ts +235 -0
  166. package/src/git/multi-source-manager.ts +333 -0
  167. package/src/git/operations.ts +93 -0
  168. package/src/index.ts +139 -0
  169. package/src/monitoring/health.ts +132 -0
  170. package/src/resources/index.ts +13 -0
  171. package/src/resources/loader.ts +530 -0
  172. package/src/server/http.ts +427 -0
  173. package/src/server.ts +191 -0
  174. package/src/session/manager.ts +296 -0
  175. package/src/tools/index.ts +11 -0
  176. package/src/tools/manage-subscription.ts +332 -0
  177. package/src/tools/registry.ts +97 -0
  178. package/src/tools/search-resources.ts +177 -0
  179. package/src/tools/sync-resources.ts +662 -0
  180. package/src/tools/uninstall-resource.ts +248 -0
  181. package/src/tools/upload-resource.ts +258 -0
  182. package/src/transport/sse.ts +308 -0
  183. package/src/types/errors.ts +146 -0
  184. package/src/types/index.ts +7 -0
  185. package/src/types/mcp.ts +61 -0
  186. package/src/types/resources.ts +141 -0
  187. package/src/types/tools.ts +175 -0
  188. package/src/utils/cursor-paths.ts +83 -0
  189. package/src/utils/log-cleaner.ts +92 -0
  190. package/src/utils/logger.ts +333 -0
  191. 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';