@elliotding/ai-agent-mcp 0.1.25 → 0.1.27

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 (53) hide show
  1. package/package.json +4 -1
  2. package/.prompt-cache/cmd-cmd-client-sdk-ai-hub-generate-testcase.md +0 -101
  3. package/.prompt-cache/cmd-cmd-client-sdk-ai-hub-submit_zct_job.md +0 -158
  4. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-conf-status.md +0 -311
  5. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-sdk-log.md +0 -64
  6. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-zmb-log-errors.md +0 -84
  7. package/ai-resource-telemetry.json +0 -40
  8. package/src/api/cached-client.ts +0 -144
  9. package/src/api/client.ts +0 -697
  10. package/src/auth/index.ts +0 -11
  11. package/src/auth/middleware.ts +0 -244
  12. package/src/auth/permissions.ts +0 -323
  13. package/src/auth/token-validator.ts +0 -292
  14. package/src/cache/cache-manager.ts +0 -243
  15. package/src/cache/index.ts +0 -6
  16. package/src/cache/redis-client.ts +0 -249
  17. package/src/config/constants.ts +0 -33
  18. package/src/config/index.ts +0 -269
  19. package/src/filesystem/manager.ts +0 -235
  20. package/src/git/multi-source-manager.ts +0 -654
  21. package/src/git/operations.ts +0 -93
  22. package/src/index.ts +0 -157
  23. package/src/monitoring/health.ts +0 -132
  24. package/src/prompts/cache.ts +0 -140
  25. package/src/prompts/generator.ts +0 -143
  26. package/src/prompts/index.ts +0 -20
  27. package/src/prompts/manager.ts +0 -718
  28. package/src/resources/index.ts +0 -13
  29. package/src/resources/loader.ts +0 -563
  30. package/src/server/http.ts +0 -549
  31. package/src/server.ts +0 -206
  32. package/src/session/manager.ts +0 -296
  33. package/src/telemetry/index.ts +0 -10
  34. package/src/telemetry/manager.ts +0 -419
  35. package/src/tools/index.ts +0 -13
  36. package/src/tools/manage-subscription.ts +0 -388
  37. package/src/tools/registry.ts +0 -97
  38. package/src/tools/resolve-prompt-content.ts +0 -113
  39. package/src/tools/search-resources.ts +0 -185
  40. package/src/tools/sync-resources.ts +0 -829
  41. package/src/tools/track-usage.ts +0 -113
  42. package/src/tools/uninstall-resource.ts +0 -199
  43. package/src/tools/upload-resource.ts +0 -431
  44. package/src/transport/sse.ts +0 -308
  45. package/src/types/errors.ts +0 -146
  46. package/src/types/index.ts +0 -7
  47. package/src/types/mcp.ts +0 -61
  48. package/src/types/resources.ts +0 -141
  49. package/src/types/tools.ts +0 -305
  50. package/src/utils/cursor-paths.ts +0 -135
  51. package/src/utils/log-cleaner.ts +0 -92
  52. package/src/utils/logger.ts +0 -333
  53. package/src/utils/validation.ts +0 -262
@@ -1,305 +0,0 @@
1
- /**
2
- * MCP Tool Types
3
- */
4
-
5
- import type { MCPToolSchema } from './mcp';
6
-
7
- // ── LocalAction ────────────────────────────────────────────────────────────
8
- //
9
- // When the MCP server is deployed remotely it cannot write to the user's local
10
- // filesystem. Instead it returns a list of LocalAction instructions that the
11
- // AI Agent (running inside the user's local Cursor) must execute.
12
- //
13
- // Action types:
14
- // write_file – create or overwrite a local file
15
- // delete_file – delete a local file or directory
16
- // merge_mcp_json – merge an MCP server entry into ~/.cursor/mcp.json
17
- // remove_mcp_json_entry – remove an MCP server entry from ~/.cursor/mcp.json
18
-
19
- export interface WriteFileAction {
20
- action: 'write_file';
21
- /** Absolute path on the user's local machine (may start with ~). */
22
- path: string;
23
- /** UTF-8 file content to write. */
24
- content: string;
25
- }
26
-
27
- export interface DeleteFileAction {
28
- action: 'delete_file';
29
- /** Absolute path on the user's local machine (may start with ~). */
30
- path: string;
31
- /** When true, recursively delete a directory. */
32
- recursive?: boolean;
33
- }
34
-
35
- export interface MergeMcpJsonAction {
36
- action: 'merge_mcp_json';
37
- /** Absolute path to the user's mcp.json file. */
38
- mcp_json_path: string;
39
- /** Key under mcpServers to add or update. */
40
- server_name: string;
41
- /** The MCP server entry object to merge in. */
42
- entry: Record<string, unknown>;
43
- /** env keys that are currently empty and must be filled by the user. */
44
- missing_env?: string[];
45
- /** Human-readable hint when manual env configuration is required. */
46
- setup_hint?: string;
47
- /** Path to a local setup/readme doc if one exists in the install dir. */
48
- setup_doc?: string;
49
- /**
50
- * When true, the AI MUST skip this action if `mcpServers[server_name]`
51
- * already exists in mcp.json (regardless of content).
52
- * Use this for idempotent installs where re-writing would clobber
53
- * user-customised values (e.g. env vars the user has already filled in).
54
- */
55
- skip_if_exists?: boolean;
56
- }
57
-
58
- export interface RemoveMcpJsonEntryAction {
59
- action: 'remove_mcp_json_entry';
60
- /** Absolute path to the user's mcp.json file. */
61
- mcp_json_path: string;
62
- /** Key under mcpServers to remove. */
63
- server_name: string;
64
- }
65
-
66
- export type LocalAction =
67
- | WriteFileAction
68
- | DeleteFileAction
69
- | MergeMcpJsonAction
70
- | RemoveMcpJsonEntryAction;
71
-
72
- // Tool Handler Function Type (generic, accepts any params and returns any result)
73
- export type ToolHandler = (params: unknown) => Promise<ToolResult>;
74
-
75
- // Tool Definition
76
- export interface ToolDefinition {
77
- name: string;
78
- description: string;
79
- inputSchema: MCPToolSchema;
80
- handler: ToolHandler;
81
- }
82
-
83
- // Tool Result (generic)
84
- export interface ToolResult<T = unknown> {
85
- success: boolean;
86
- data?: T;
87
- error?: {
88
- code: string;
89
- message: string;
90
- details?: unknown;
91
- };
92
- }
93
-
94
- //===============================================
95
- // Tool-specific Parameter and Result Types
96
- //===============================================
97
-
98
- // sync_resources
99
- export interface SyncResourcesParams {
100
- mode?: 'check' | 'incremental' | 'full';
101
- scope?: 'global' | 'workspace' | 'all';
102
- types?: string[];
103
- /**
104
- * CSP API token from the user's mcp.json env configuration.
105
- * Overrides the server-level fallback token so that each user
106
- * makes API calls with their own identity.
107
- */
108
- user_token?: string;
109
- /**
110
- * List of MCP server names that are already configured in the user's
111
- * ~/.cursor/mcp.json. The server will skip downloading and generating
112
- * write_file actions for these MCP resources to reduce overhead.
113
- *
114
- * Set this to the keys from mcpServers in ~/.cursor/mcp.json:
115
- * Object.keys(JSON.parse(fs.readFileSync('~/.cursor/mcp.json')).mcpServers || {})
116
- *
117
- * Only applies in 'incremental' mode; 'full' mode always downloads everything.
118
- */
119
- configured_mcp_servers?: string[];
120
- }
121
-
122
- export interface McpSetupItem {
123
- /** MCP server name as it appears in mcp.json */
124
- server_name: string;
125
- /** Human-readable path to mcp.json on this platform */
126
- mcp_json_path: string;
127
- /** env keys that are currently empty and need user input */
128
- missing_env: string[];
129
- /** true when the registered command might not be correct for this machine */
130
- command_needs_verification: boolean;
131
- /** the command string that was registered */
132
- command: string;
133
- /** freeform guidance shown to the user */
134
- setup_hint: string;
135
- /** absolute path to a local setup/readme doc found in the install directory, if any */
136
- setup_doc?: string;
137
- }
138
-
139
- export interface SyncResourcesResult {
140
- mode: string;
141
- health_score: number;
142
- summary: {
143
- total: number;
144
- synced: number;
145
- cached: number;
146
- failed: number;
147
- };
148
- details: Array<{
149
- id: string;
150
- name: string;
151
- action: string;
152
- version: string;
153
- }>;
154
- /**
155
- * MCP servers that were installed/updated but require manual configuration
156
- * before they can be used. Present only when at least one server needs setup.
157
- * @deprecated use local_actions_required MergeMcpJsonAction.missing_env instead
158
- */
159
- pending_setup?: McpSetupItem[];
160
- /**
161
- * Ordered list of file-system and mcp.json operations the AI Agent must
162
- * execute on the user's LOCAL machine after receiving this response.
163
- * Present only when at least one Rule or MCP resource was synced.
164
- *
165
- * The AI MUST execute every action in order before reporting success to the
166
- * user. See LocalAction type variants for details.
167
- */
168
- local_actions_required?: LocalAction[];
169
- }
170
-
171
- // manage_subscription
172
- export interface ManageSubscriptionParams {
173
- action: 'subscribe' | 'unsubscribe' | 'list' | 'batch_subscribe' | 'batch_unsubscribe';
174
- resource_ids?: string[];
175
- auto_sync?: boolean;
176
- scope?: 'global' | 'workspace';
177
- notify?: boolean;
178
- /** CSP API token from the user's mcp.json env configuration. */
179
- user_token?: string;
180
- }
181
-
182
- export interface ManageSubscriptionResult {
183
- action: string;
184
- success: boolean;
185
- subscriptions?: Array<{
186
- id: string;
187
- name: string;
188
- type: string;
189
- subscribed_at: string;
190
- }>;
191
- message?: string;
192
- /** Sync results for each resource after auto-sync on subscribe */
193
- sync_details?: Array<{ id: string; name: string; action: string }>;
194
- /** MCP servers that need manual configuration after auto-sync */
195
- pending_setup?: unknown[];
196
- }
197
-
198
- // search_resources
199
- export interface SearchResourcesParams {
200
- team?: string;
201
- type?: string;
202
- keyword: string;
203
- /** CSP API token from the user's mcp.json env configuration. */
204
- user_token?: string;
205
- }
206
-
207
- export interface SearchResourcesResult {
208
- total: number;
209
- results: Array<{
210
- id: string;
211
- name: string;
212
- type: string;
213
- team: string;
214
- version: string;
215
- description: string;
216
- score: number;
217
- is_subscribed: boolean;
218
- is_installed: boolean;
219
- }>;
220
- }
221
-
222
- // resolve_prompt_content
223
- export interface ResolvePromptContentParams {
224
- prompt_name?: string;
225
- resource_id?: string;
226
- /** CSP API token from the user's mcp.json env configuration. */
227
- user_token?: string;
228
- /** Optional Jira Issue ID for usage correlation. */
229
- jira_id?: string;
230
- }
231
-
232
- export interface ResolvePromptContentResult {
233
- prompt_name: string;
234
- resource_id: string;
235
- resource_type: 'command' | 'skill';
236
- resource_name: string;
237
- description: string;
238
- content: string;
239
- content_source: 'cache' | 'generated' | 'raw_fallback';
240
- usage_tracked: boolean;
241
- }
242
-
243
- // upload_resource
244
- export interface FileEntry {
245
- path: string; // Relative path under the type subdir (e.g. "my-cmd.md" or "code-review/SKILL.md")
246
- content: string; // File content string
247
- }
248
-
249
- export interface UploadResourceParams {
250
- resource_id: string;
251
- /** Resource category. Optional — auto-detected from file structure when omitted. */
252
- type?: 'command' | 'skill' | 'rule' | 'mcp';
253
- message: string;
254
- /** Human-readable resource name sent to the CSP API. Defaults to the primary file name (without extension). */
255
- name?: string;
256
- /** Target source repo from ai-resources-config.json (e.g. "csp", "client-sdk-ai-hub"). Defaults to default_source. */
257
- target_source?: string;
258
- team?: string;
259
-
260
- // ---- Three input modes (priority: files > directory > content) ----
261
-
262
- /** File list to upload. Paths are relative to the type subdir of the chosen source. Any file extension allowed. */
263
- files: FileEntry[];
264
-
265
- // ---- Optional fields ----
266
- title?: string;
267
- metadata?: Record<string, unknown>;
268
- /** CSP API token from the user's mcp.json env configuration. */
269
- user_token?: string;
270
- }
271
-
272
- export interface UploadResourceResult {
273
- resource_id: string;
274
- version: string;
275
- url: string;
276
- commit_hash: string;
277
- message: string;
278
- }
279
-
280
- // uninstall_resource
281
- export interface UninstallResourceParams {
282
- resource_id_or_name: string;
283
- remove_from_account?: boolean;
284
- /** When known, the resource type — narrows which local_actions are emitted. */
285
- resource_type?: 'command' | 'skill' | 'rule' | 'mcp';
286
- /** CSP API token from the user's mcp.json env configuration. */
287
- user_token?: string;
288
- }
289
-
290
- export interface UninstallResourceResult {
291
- success: boolean;
292
- removed_resources: Array<{
293
- id: string;
294
- name: string;
295
- path: string;
296
- }>;
297
- subscription_removed: boolean;
298
- message: string;
299
- /**
300
- * Ordered list of file-system and mcp.json operations the AI Agent must
301
- * execute on the user's LOCAL machine after receiving this response.
302
- * Present only for Rule and local-executable MCP resources.
303
- */
304
- local_actions_required?: LocalAction[];
305
- }
@@ -1,135 +0,0 @@
1
- /**
2
- * Cursor IDE standard directory path resolver.
3
- *
4
- * Cursor stores user-level assets in platform-specific locations:
5
- * macOS / Linux : ~/.cursor/<type>/
6
- * Windows : %APPDATA%\Cursor\User\<type>\
7
- * (typically C:\Users\<user>\AppData\Roaming\Cursor\User\<type>\)
8
- *
9
- * Resource type → subdirectory mapping mirrors the actual Cursor directory layout.
10
- */
11
-
12
- import * as os from 'os';
13
- import * as path from 'path';
14
-
15
- /** Supported Cursor resource types and their directory names. */
16
- export const CURSOR_TYPE_DIRS: Record<string, string> = {
17
- skill: 'skills',
18
- skills: 'skills',
19
- command: 'commands',
20
- commands:'commands',
21
- rule: 'rules',
22
- rules: 'rules',
23
- mcp: 'mcp-servers',
24
- 'mcp-servers': 'mcp-servers',
25
- };
26
-
27
- /**
28
- * Returns the root of the Cursor user directory on the current platform.
29
- *
30
- * macOS / Linux : ~/.cursor
31
- * Windows : %APPDATA%\Cursor\User
32
- *
33
- * NOTE: Only use this when running code on the USER's local machine.
34
- * When generating paths for LocalAction instructions (which are executed by the
35
- * AI on the user's machine, not on this server), use getCursorRootDirForClient()
36
- * instead to avoid returning the server's home directory.
37
- */
38
- export function getCursorRootDir(): string {
39
- if (process.platform === 'win32') {
40
- // APPDATA is always set on Windows; fall back to USERPROFILE as a safety net
41
- const appData = process.env.APPDATA ?? path.join(os.homedir(), 'AppData', 'Roaming');
42
- return path.join(appData, 'Cursor', 'User');
43
- }
44
- // macOS and Linux both use ~/.cursor
45
- return path.join(os.homedir(), '.cursor');
46
- }
47
-
48
- /**
49
- * Returns a platform-neutral Cursor root path for use in LocalAction instructions.
50
- *
51
- * LocalAction paths are sent to the AI Agent running on the USER's local machine,
52
- * not executed on this (possibly remote) server. Using os.homedir() here would
53
- * produce the server's home directory (e.g. /root/.cursor on a Linux server),
54
- * which is wrong when the user is on macOS or Windows.
55
- *
56
- * We return a tilde-prefixed path ("~/.cursor") which the AI / shell on the
57
- * user's machine will expand to the correct home directory automatically.
58
- * For Windows we still return the APPDATA-relative form as a hint, but note
59
- * that the AI is expected to expand %APPDATA% on the client side.
60
- */
61
- export function getCursorRootDirForClient(): string {
62
- // Return a portable ~-based path; the AI on the user's machine expands it.
63
- return '~/.cursor';
64
- }
65
-
66
- /**
67
- * Returns the Cursor subdirectory for a given resource type, using a
68
- * client-side portable path (tilde-based). Use this when building paths
69
- * that will be included in LocalAction instructions.
70
- */
71
- export function getCursorTypeDirForClient(resourceType: string): string {
72
- const subdir = CURSOR_TYPE_DIRS[resourceType.toLowerCase()];
73
- if (!subdir) {
74
- throw new Error(
75
- `Unknown resource type "${resourceType}". ` +
76
- `Supported types: ${Object.keys(CURSOR_TYPE_DIRS).join(', ')}`
77
- );
78
- }
79
- return `${getCursorRootDirForClient()}/${subdir}`;
80
- }
81
-
82
- /**
83
- * Returns the Cursor subdirectory for a given resource type.
84
- *
85
- * @param resourceType - API resource type string (e.g. 'skill', 'command', 'rule', 'mcp')
86
- * @returns Absolute path to the matching Cursor directory
87
- * @throws Error if the resource type is not recognised
88
- *
89
- * @example
90
- * getCursorTypeDir('skill') // ~/.cursor/skills
91
- * getCursorTypeDir('command') // ~/.cursor/commands
92
- * getCursorTypeDir('rule') // ~/.cursor/rules
93
- * getCursorTypeDir('mcp') // ~/.cursor/mcp-servers
94
- */
95
- export function getCursorTypeDir(resourceType: string): string {
96
- const subdir = CURSOR_TYPE_DIRS[resourceType.toLowerCase()];
97
- if (!subdir) {
98
- throw new Error(
99
- `Unknown resource type "${resourceType}". ` +
100
- `Supported types: ${Object.keys(CURSOR_TYPE_DIRS).join(', ')}`
101
- );
102
- }
103
- return path.join(getCursorRootDir(), subdir);
104
- }
105
-
106
- /**
107
- * Returns the install path for a specific named resource.
108
- *
109
- * For directory-based resources (skill, mcp) the result is a directory:
110
- * ~/.cursor/skills/<name>/
111
- *
112
- * For file-based resources (command, rule) the result is the file path
113
- * preserving the original filename (caller should pass name with extension):
114
- * ~/.cursor/commands/<name> (e.g. generate-testcase.md)
115
- * ~/.cursor/rules/<name> (e.g. elliotTest.mdc)
116
- *
117
- * @param resourceType - Resource type string
118
- * @param resourceName - Resource name (with or without extension)
119
- */
120
- export function getCursorResourcePath(resourceType: string, resourceName: string): string {
121
- return path.join(getCursorTypeDir(resourceType), resourceName);
122
- }
123
-
124
- /**
125
- * Returns the path to the local AI resource telemetry file.
126
- *
127
- * Stored at the Cursor root level (not inside a resource-type subdirectory)
128
- * so it persists independently of individual resource installs/uninstalls.
129
- *
130
- * macOS / Linux : ~/.cursor/ai-resource-telemetry.json
131
- * Windows : %APPDATA%\Cursor\User\ai-resource-telemetry.json
132
- */
133
- export function getTelemetryFilePath(): string {
134
- return path.join(getCursorRootDir(), 'ai-resource-telemetry.json');
135
- }
@@ -1,92 +0,0 @@
1
- /**
2
- * Log Cleanup Module
3
- * Automatically deletes log files older than retention period
4
- */
5
-
6
- import * as fs from 'fs';
7
- import * as path from 'path';
8
- import { logger } from './logger';
9
- import { config } from '../config';
10
-
11
- // Matches both the canonical name (app-YYYY-MM-DD.log) produced after the
12
- // midnight rename, and the active pino-roll name (app.YYYY-MM-DD.1.log).
13
- const LOG_FILE_PATTERN = /^app[.-]\d{4}-\d{2}-\d{2}[\d.]*\.log$/;
14
-
15
- /**
16
- * Delete log files older than retention days
17
- */
18
- // eslint-disable-next-line @typescript-eslint/require-await
19
- export async function cleanupOldLogs(): Promise<void> {
20
- const logsDir = path.resolve(process.cwd(), config.logging.dir);
21
-
22
- if (!fs.existsSync(logsDir)) {
23
- logger.debug('Logs directory does not exist, skipping cleanup');
24
- return;
25
- }
26
-
27
- const retentionMs = config.logging.retentionDays * 24 * 60 * 60 * 1000;
28
- const now = Date.now();
29
-
30
- try {
31
- const files = fs.readdirSync(logsDir);
32
- let deletedCount = 0;
33
-
34
- for (const file of files) {
35
- const match = file.match(LOG_FILE_PATTERN);
36
- if (!match) {
37
- continue; // Skip non-log files
38
- }
39
-
40
- const filePath = path.join(logsDir, file);
41
- const stats = fs.statSync(filePath);
42
- const fileAge = now - stats.mtimeMs;
43
-
44
- if (fileAge > retentionMs) {
45
- fs.unlinkSync(filePath);
46
- deletedCount++;
47
- logger.info(
48
- { file, agedays: Math.floor(fileAge / (24 * 60 * 60 * 1000)) },
49
- `Deleted old log file: ${file}`
50
- );
51
- }
52
- }
53
-
54
- if (deletedCount > 0) {
55
- logger.info(
56
- { deletedCount },
57
- `Log cleanup completed: ${deletedCount} old log files deleted`
58
- );
59
- } else {
60
- logger.debug('Log cleanup completed: no old log files to delete');
61
- }
62
- } catch (error) {
63
- logger.error({ error }, 'Failed to cleanup old log files');
64
- }
65
- }
66
-
67
- /**
68
- * Start log cleanup scheduler
69
- * Runs cleanup once per day at 2 AM
70
- */
71
- export function startLogCleanupSchedule(): NodeJS.Timeout {
72
- // Run cleanup immediately on startup
73
- void cleanupOldLogs();
74
-
75
- // Schedule cleanup every 7 days
76
- const interval = 7 * 24 * 60 * 60 * 1000; // 7 days
77
- const timer = setInterval(() => {
78
- void cleanupOldLogs();
79
- }, interval);
80
-
81
- logger.info({ retentionDays: config.logging.retentionDays }, 'Log cleanup scheduler started');
82
-
83
- return timer;
84
- }
85
-
86
- /**
87
- * Stop log cleanup scheduler
88
- */
89
- export function stopLogCleanupSchedule(timer: NodeJS.Timeout): void {
90
- clearInterval(timer);
91
- logger.info('Log cleanup scheduler stopped');
92
- }