@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
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Tool Registry
3
+ * Central registry for MCP tools
4
+ */
5
+
6
+ import { logger } from '../utils/logger';
7
+ import type { ToolDefinition } from '../types/tools';
8
+ import type { MCPToolDefinition } from '../types/mcp';
9
+
10
+ class ToolRegistry {
11
+ private tools: Map<string, ToolDefinition> = new Map();
12
+
13
+ /**
14
+ * Register a tool
15
+ */
16
+ registerTool(tool: ToolDefinition): void {
17
+ if (this.tools.has(tool.name)) {
18
+ throw new Error(`Tool '${tool.name}' is already registered`);
19
+ }
20
+
21
+ this.tools.set(tool.name, tool);
22
+ logger.info({ toolName: tool.name }, `Tool registered: ${tool.name}`);
23
+ }
24
+
25
+ /**
26
+ * Get a tool by name
27
+ */
28
+ getTool(name: string): ToolDefinition | undefined {
29
+ return this.tools.get(name);
30
+ }
31
+
32
+ /**
33
+ * List all registered tools
34
+ */
35
+ listTools(): ToolDefinition[] {
36
+ return Array.from(this.tools.values());
37
+ }
38
+
39
+ /**
40
+ * Get MCP tool definitions (for tools/list response)
41
+ */
42
+ getMCPToolDefinitions(): MCPToolDefinition[] {
43
+ return this.listTools().map((tool) => ({
44
+ name: tool.name,
45
+ description: tool.description,
46
+ inputSchema: tool.inputSchema,
47
+ }));
48
+ }
49
+
50
+ /**
51
+ * Check if a tool exists
52
+ */
53
+ hasTool(name: string): boolean {
54
+ return this.tools.has(name);
55
+ }
56
+
57
+ /**
58
+ * Get tool count
59
+ */
60
+ getToolCount(): number {
61
+ return this.tools.size;
62
+ }
63
+
64
+ /**
65
+ * Call a tool by name with arguments
66
+ */
67
+ async callTool(name: string, args: Record<string, unknown>): Promise<unknown> {
68
+ const tool = this.getTool(name);
69
+ if (!tool) {
70
+ throw new Error(`Tool '${name}' not found`);
71
+ }
72
+
73
+ logger.debug({ toolName: name, args }, 'Calling tool');
74
+
75
+ try {
76
+ const result = await tool.handler(args);
77
+
78
+ // Debug: Log the result structure
79
+ logger.debug({
80
+ toolName: name,
81
+ resultType: typeof result,
82
+ resultKeys: result && typeof result === 'object' ? Object.keys(result) : undefined,
83
+ hasSuccess: result && typeof result === 'object' && 'success' in result,
84
+ hasData: result && typeof result === 'object' && 'data' in result,
85
+ hasError: result && typeof result === 'object' && 'error' in result
86
+ }, 'Tool execution result structure');
87
+
88
+ return result;
89
+ } catch (error) {
90
+ logger.error({ toolName: name, error, errorType: typeof error, errorMessage: error instanceof Error ? error.message : String(error) }, 'Tool execution threw error');
91
+ throw error;
92
+ }
93
+ }
94
+ }
95
+
96
+ // Global singleton
97
+ export const toolRegistry = new ToolRegistry();
@@ -0,0 +1,177 @@
1
+ /**
2
+ * search_resources Tool
3
+ * Search for available resources
4
+ */
5
+
6
+ import { logger, logToolCall } from '../utils/logger';
7
+ import { apiClient } from '../api/client';
8
+ import { filesystemManager } from '../filesystem/manager';
9
+ import { getCursorResourcePath } from '../utils/cursor-paths.js';
10
+ import { MCPServerError } from '../types/errors';
11
+ import type { SearchResourcesParams, SearchResourcesResult, ToolResult } from '../types/tools';
12
+
13
+ // Simple in-memory cache
14
+ const searchCache = new Map<string, { results: SearchResourcesResult; timestamp: number }>();
15
+ const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
16
+
17
+ /**
18
+ * Generate cache key from search parameters
19
+ */
20
+ function getCacheKey(params: SearchResourcesParams): string {
21
+ return JSON.stringify({
22
+ team: params.team || '',
23
+ type: params.type || '',
24
+ keyword: params.keyword || '',
25
+ });
26
+ }
27
+
28
+ /**
29
+ * Get cached search results if available and not expired
30
+ */
31
+ function getCachedResults(cacheKey: string): SearchResourcesResult | null {
32
+ const cached = searchCache.get(cacheKey);
33
+ if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
34
+ logger.debug({ cacheKey }, 'Search cache hit');
35
+ return cached.results;
36
+ }
37
+
38
+ if (cached) {
39
+ // Remove expired cache entry
40
+ searchCache.delete(cacheKey);
41
+ logger.debug({ cacheKey }, 'Search cache expired, removed');
42
+ }
43
+
44
+ return null;
45
+ }
46
+
47
+ /**
48
+ * Cache search results
49
+ */
50
+ function cacheResults(cacheKey: string, results: SearchResourcesResult): void {
51
+ searchCache.set(cacheKey, {
52
+ results,
53
+ timestamp: Date.now(),
54
+ });
55
+ logger.debug({ cacheKey, total: results.total }, 'Search results cached');
56
+ }
57
+
58
+ export async function searchResources(params: unknown): Promise<ToolResult<SearchResourcesResult>> {
59
+ const startTime = Date.now();
60
+
61
+ // Type assertion for params
62
+ const typedParams = params as SearchResourcesParams;
63
+
64
+ logger.info({ tool: 'search_resources', params }, 'search_resources called');
65
+
66
+ try {
67
+ // Generate cache key
68
+ const cacheKey = getCacheKey(typedParams);
69
+
70
+ // Check cache first
71
+ const cachedResult = getCachedResults(cacheKey);
72
+ if (cachedResult) {
73
+ const duration = Date.now() - startTime;
74
+ logToolCall('search_resources', 'user-id', params as Record<string, unknown>, duration);
75
+
76
+ logger.info({ total: cachedResult.total, duration, cached: true }, 'search_resources completed (cache hit)');
77
+
78
+ return {
79
+ success: true,
80
+ data: cachedResult,
81
+ };
82
+ }
83
+
84
+ // Search via API
85
+ logger.debug({ team: typedParams.team, type: typedParams.type, keyword: typedParams.keyword }, 'Searching resources...');
86
+
87
+ const searchResults = await apiClient.searchResources({
88
+ team: typedParams.team,
89
+ type: typedParams.type,
90
+ keyword: typedParams.keyword,
91
+ });
92
+
93
+ // Check subscription and installation status for each result
94
+ const enhancedResults = await Promise.all(
95
+ searchResults.results.map(async (resource) => {
96
+ // Check if installed locally in the Cursor directory for this resource type
97
+ let isInstalled = false;
98
+ try {
99
+ const resourcePath = getCursorResourcePath(resource.type, resource.name);
100
+ isInstalled = await filesystemManager.fileExists(resourcePath);
101
+ } catch {
102
+ // Unknown type or path check failed — treat as not installed
103
+ isInstalled = false;
104
+ }
105
+
106
+ return {
107
+ ...resource,
108
+ is_installed: isInstalled,
109
+ };
110
+ })
111
+ );
112
+
113
+ // Build final result
114
+ const result: SearchResourcesResult = {
115
+ total: searchResults.total,
116
+ results: enhancedResults,
117
+ };
118
+
119
+ // Cache the results
120
+ cacheResults(cacheKey, result);
121
+
122
+ const duration = Date.now() - startTime;
123
+ logToolCall('search_resources', 'user-id', params as Record<string, unknown>, duration);
124
+
125
+ logger.info(
126
+ {
127
+ team: typedParams.team,
128
+ type: typedParams.type,
129
+ keyword: typedParams.keyword,
130
+ total: result.total,
131
+ duration,
132
+ cached: false,
133
+ },
134
+ 'search_resources completed successfully'
135
+ );
136
+
137
+ return {
138
+ success: true,
139
+ data: result,
140
+ };
141
+ } catch (error) {
142
+ logger.error({ error, tool: 'search_resources', errorStack: error instanceof Error ? error.stack : undefined }, 'search_resources failed');
143
+ return {
144
+ success: false,
145
+ error: {
146
+ code: error instanceof MCPServerError ? error.code : 'UNKNOWN_ERROR',
147
+ message: error instanceof Error ? error.message : String(error),
148
+ },
149
+ };
150
+ }
151
+ }
152
+
153
+ // Tool definition for registry
154
+ export const searchResourcesTool = {
155
+ name: 'search_resources',
156
+ description: 'Search for available resources by team, type, or keyword',
157
+ inputSchema: {
158
+ type: 'object' as const,
159
+ properties: {
160
+ team: {
161
+ type: 'string',
162
+ description: 'Filter by team (empty = all teams)',
163
+ },
164
+ type: {
165
+ type: 'string',
166
+ description: 'Filter by resource type',
167
+ enum: ['command', 'skill', 'rule', 'mcp', ''],
168
+ },
169
+ keyword: {
170
+ type: 'string',
171
+ description: 'Search keyword (searches in name, description, tags)',
172
+ },
173
+ },
174
+ required: ['keyword'],
175
+ },
176
+ handler: searchResources,
177
+ };