@elliotding/ai-agent-mcp 0.1.8 → 0.1.10

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.
@@ -6,46 +6,10 @@
6
6
  * For MCP resources this also removes the mcpServers entry from ~/.cursor/mcp.json.
7
7
  * For directory-based resources (skill, mcp) the entire install directory is removed.
8
8
  */
9
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- var desc = Object.getOwnPropertyDescriptor(m, k);
12
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
- desc = { enumerable: true, get: function() { return m[k]; } };
14
- }
15
- Object.defineProperty(o, k2, desc);
16
- }) : (function(o, m, k, k2) {
17
- if (k2 === undefined) k2 = k;
18
- o[k2] = m[k];
19
- }));
20
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
- Object.defineProperty(o, "default", { enumerable: true, value: v });
22
- }) : function(o, v) {
23
- o["default"] = v;
24
- });
25
- var __importStar = (this && this.__importStar) || (function () {
26
- var ownKeys = function(o) {
27
- ownKeys = Object.getOwnPropertyNames || function (o) {
28
- var ar = [];
29
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
- return ar;
31
- };
32
- return ownKeys(o);
33
- };
34
- return function (mod) {
35
- if (mod && mod.__esModule) return mod;
36
- var result = {};
37
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
- __setModuleDefault(result, mod);
39
- return result;
40
- };
41
- })();
42
9
  Object.defineProperty(exports, "__esModule", { value: true });
43
10
  exports.uninstallResourceTool = void 0;
44
11
  exports.uninstallResource = uninstallResource;
45
- const fs = __importStar(require("fs/promises"));
46
- const path = __importStar(require("path"));
47
12
  const logger_1 = require("../utils/logger");
48
- const manager_1 = require("../filesystem/manager");
49
13
  const client_1 = require("../api/client");
50
14
  const cursor_paths_js_1 = require("../utils/cursor-paths.js");
51
15
  const errors_1 = require("../types/errors");
@@ -113,47 +77,27 @@ async function uninstallResource(params) {
113
77
  // Agent performs them on the user's LOCAL machine.
114
78
  logger_1.logger.debug({ pattern }, 'Building local uninstall actions for Rule/MCP resource...');
115
79
  const localActions = [];
116
- const mcpJsonPath = path.join((0, cursor_paths_js_1.getCursorRootDir)(), 'mcp.json');
117
- // Rule: delete matching .md/.mdc files from ~/.cursor/rules/
118
- try {
119
- const rulesDir = (0, cursor_paths_js_1.getCursorTypeDir)('rule');
120
- const ruleFiles = await manager_1.filesystemManager.listFiles(rulesDir, /\.(md|mdc)$/);
121
- for (const relName of ruleFiles) {
122
- const baseName = path.basename(relName).replace(/\.(md|mdc)$/, '');
123
- if (baseName === pattern || baseName.includes(pattern) || relName.includes(pattern)) {
124
- const absPath = path.join(rulesDir, relName);
125
- localActions.push({ action: 'delete_file', path: absPath });
126
- removedResources.push({ id: baseName, name: baseName, path: absPath });
127
- }
128
- }
129
- }
130
- catch { /* rules dir may not exist */ }
131
- // MCP: delete install directory + remove mcp.json entry
132
- try {
133
- const mcpDir = (0, cursor_paths_js_1.getCursorTypeDir)('mcp');
134
- const entries = await fs.readdir(mcpDir, { withFileTypes: true });
135
- for (const entry of entries) {
136
- if (!entry.isDirectory())
137
- continue;
138
- if (entry.name === pattern || entry.name.includes(pattern)) {
139
- const dirPath = path.join(mcpDir, entry.name);
140
- localActions.push({ action: 'delete_file', path: dirPath, recursive: true });
141
- localActions.push({ action: 'remove_mcp_json_entry', mcp_json_path: mcpJsonPath, server_name: entry.name });
142
- removedResources.push({ id: entry.name, name: entry.name, path: dirPath });
143
- }
144
- }
145
- }
146
- catch { /* mcp-servers dir may not exist */ }
147
- // Also check Remote-URL MCPs whose entry is only in mcp.json (no local dir).
148
- // The pattern might match a server name in mcp.json directly.
149
- if (localActions.filter(a => a.action === 'remove_mcp_json_entry').length === 0) {
150
- // Add a conditional remove action — the AI will check if the key exists.
151
- localActions.push({
152
- action: 'remove_mcp_json_entry',
153
- mcp_json_path: mcpJsonPath,
154
- server_name: pattern,
155
- });
80
+ // Use client-side tilde-based paths; the MCP server may be running remotely
81
+ // and its os.homedir() would resolve to the server's home, not the user's.
82
+ const mcpJsonPath = `${(0, cursor_paths_js_1.getCursorRootDirForClient)()}/mcp.json`;
83
+ // Rule: queue delete for ~/.cursor/rules/<pattern>.mdc and .md variants.
84
+ // We cannot scan the server's filesystem for the user's rules, so we emit
85
+ // delete actions for the two common extensions and let the AI skip missing files.
86
+ const rulesDir = (0, cursor_paths_js_1.getCursorTypeDirForClient)('rule');
87
+ for (const ext of ['.mdc', '.md']) {
88
+ const filePath = `${rulesDir}/${pattern}${ext}`;
89
+ localActions.push({ action: 'delete_file', path: filePath });
90
+ removedResources.push({ id: pattern, name: pattern, path: filePath });
156
91
  }
92
+ // MCP: queue delete of install directory (Format A) + remove mcp.json entry.
93
+ // For Format B (remote URL only) there is no local directory, but we still
94
+ // need to remove the mcp.json entry — the AI will skip the delete if the
95
+ // directory does not exist.
96
+ const mcpDir = (0, cursor_paths_js_1.getCursorTypeDirForClient)('mcp');
97
+ const mcpInstallDir = `${mcpDir}/${pattern}`;
98
+ localActions.push({ action: 'delete_file', path: mcpInstallDir, recursive: true });
99
+ localActions.push({ action: 'remove_mcp_json_entry', mcp_json_path: mcpJsonPath, server_name: pattern });
100
+ removedResources.push({ id: pattern, name: pattern, path: mcpInstallDir });
157
101
  if (removedResources.length === 0 && localActions.length === 0) {
158
102
  throw (0, errors_1.createValidationError)(pattern, 'resource_id_or_name', 'No installed Rule or MCP resources found matching pattern. Use search_resources to find available resources');
159
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"uninstall-resource.js","sourceRoot":"","sources":["../../src/tools/uninstall-resource.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"uninstall-resource.js","sourceRoot":"","sources":["../../src/tools/uninstall-resource.ts"],"names":[],"mappings":"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"}
@@ -15,8 +15,33 @@ export declare const CURSOR_TYPE_DIRS: Record<string, string>;
15
15
  *
16
16
  * macOS / Linux : ~/.cursor
17
17
  * Windows : %APPDATA%\Cursor\User
18
+ *
19
+ * NOTE: Only use this when running code on the USER's local machine.
20
+ * When generating paths for LocalAction instructions (which are executed by the
21
+ * AI on the user's machine, not on this server), use getCursorRootDirForClient()
22
+ * instead to avoid returning the server's home directory.
18
23
  */
19
24
  export declare function getCursorRootDir(): string;
25
+ /**
26
+ * Returns a platform-neutral Cursor root path for use in LocalAction instructions.
27
+ *
28
+ * LocalAction paths are sent to the AI Agent running on the USER's local machine,
29
+ * not executed on this (possibly remote) server. Using os.homedir() here would
30
+ * produce the server's home directory (e.g. /root/.cursor on a Linux server),
31
+ * which is wrong when the user is on macOS or Windows.
32
+ *
33
+ * We return a tilde-prefixed path ("~/.cursor") which the AI / shell on the
34
+ * user's machine will expand to the correct home directory automatically.
35
+ * For Windows we still return the APPDATA-relative form as a hint, but note
36
+ * that the AI is expected to expand %APPDATA% on the client side.
37
+ */
38
+ export declare function getCursorRootDirForClient(): string;
39
+ /**
40
+ * Returns the Cursor subdirectory for a given resource type, using a
41
+ * client-side portable path (tilde-based). Use this when building paths
42
+ * that will be included in LocalAction instructions.
43
+ */
44
+ export declare function getCursorTypeDirForClient(resourceType: string): string;
20
45
  /**
21
46
  * Returns the Cursor subdirectory for a given resource type.
22
47
  *
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-paths.d.ts","sourceRoot":"","sources":["../../src/utils/cursor-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,iEAAiE;AACjE,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CASnD,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAQzC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAS7D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAExF;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C"}
1
+ {"version":3,"file":"cursor-paths.d.ts","sourceRoot":"","sources":["../../src/utils/cursor-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,iEAAiE;AACjE,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CASnD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAQzC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAGlD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAStE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAS7D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAExF;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C"}
@@ -45,6 +45,8 @@ var __importStar = (this && this.__importStar) || (function () {
45
45
  Object.defineProperty(exports, "__esModule", { value: true });
46
46
  exports.CURSOR_TYPE_DIRS = void 0;
47
47
  exports.getCursorRootDir = getCursorRootDir;
48
+ exports.getCursorRootDirForClient = getCursorRootDirForClient;
49
+ exports.getCursorTypeDirForClient = getCursorTypeDirForClient;
48
50
  exports.getCursorTypeDir = getCursorTypeDir;
49
51
  exports.getCursorResourcePath = getCursorResourcePath;
50
52
  exports.getTelemetryFilePath = getTelemetryFilePath;
@@ -66,6 +68,11 @@ exports.CURSOR_TYPE_DIRS = {
66
68
  *
67
69
  * macOS / Linux : ~/.cursor
68
70
  * Windows : %APPDATA%\Cursor\User
71
+ *
72
+ * NOTE: Only use this when running code on the USER's local machine.
73
+ * When generating paths for LocalAction instructions (which are executed by the
74
+ * AI on the user's machine, not on this server), use getCursorRootDirForClient()
75
+ * instead to avoid returning the server's home directory.
69
76
  */
70
77
  function getCursorRootDir() {
71
78
  if (process.platform === 'win32') {
@@ -76,6 +83,36 @@ function getCursorRootDir() {
76
83
  // macOS and Linux both use ~/.cursor
77
84
  return path.join(os.homedir(), '.cursor');
78
85
  }
86
+ /**
87
+ * Returns a platform-neutral Cursor root path for use in LocalAction instructions.
88
+ *
89
+ * LocalAction paths are sent to the AI Agent running on the USER's local machine,
90
+ * not executed on this (possibly remote) server. Using os.homedir() here would
91
+ * produce the server's home directory (e.g. /root/.cursor on a Linux server),
92
+ * which is wrong when the user is on macOS or Windows.
93
+ *
94
+ * We return a tilde-prefixed path ("~/.cursor") which the AI / shell on the
95
+ * user's machine will expand to the correct home directory automatically.
96
+ * For Windows we still return the APPDATA-relative form as a hint, but note
97
+ * that the AI is expected to expand %APPDATA% on the client side.
98
+ */
99
+ function getCursorRootDirForClient() {
100
+ // Return a portable ~-based path; the AI on the user's machine expands it.
101
+ return '~/.cursor';
102
+ }
103
+ /**
104
+ * Returns the Cursor subdirectory for a given resource type, using a
105
+ * client-side portable path (tilde-based). Use this when building paths
106
+ * that will be included in LocalAction instructions.
107
+ */
108
+ function getCursorTypeDirForClient(resourceType) {
109
+ const subdir = exports.CURSOR_TYPE_DIRS[resourceType.toLowerCase()];
110
+ if (!subdir) {
111
+ throw new Error(`Unknown resource type "${resourceType}". ` +
112
+ `Supported types: ${Object.keys(exports.CURSOR_TYPE_DIRS).join(', ')}`);
113
+ }
114
+ return `${getCursorRootDirForClient()}/${subdir}`;
115
+ }
79
116
  /**
80
117
  * Returns the Cursor subdirectory for a given resource type.
81
118
  *
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-paths.js","sourceRoot":"","sources":["../../src/utils/cursor-paths.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBH,4CAQC;AAeD,4CASC;AAgBD,sDAEC;AAWD,oDAEC;AApFD,uCAAyB;AACzB,2CAA6B;AAE7B,iEAAiE;AACpD,QAAA,gBAAgB,GAA2B;IACtD,KAAK,EAAI,QAAQ;IACjB,MAAM,EAAG,QAAQ;IACjB,OAAO,EAAE,UAAU;IACnB,QAAQ,EAAC,UAAU;IACnB,IAAI,EAAK,OAAO;IAChB,KAAK,EAAI,OAAO;IAChB,GAAG,EAAM,aAAa;IACtB,aAAa,EAAE,aAAa;CAC7B,CAAC;AAEF;;;;;GAKG;AACH,SAAgB,gBAAgB;IAC9B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,6EAA6E;QAC7E,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACrF,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IACD,qCAAqC;IACrC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,gBAAgB,CAAC,YAAoB;IACnD,MAAM,MAAM,GAAG,wBAAgB,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,0BAA0B,YAAY,KAAK;YAC3C,oBAAoB,MAAM,CAAC,IAAI,CAAC,wBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,qBAAqB,CAAC,YAAoB,EAAE,YAAoB;IAC9E,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,oBAAoB;IAClC,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,4BAA4B,CAAC,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"cursor-paths.js","sourceRoot":"","sources":["../../src/utils/cursor-paths.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BH,4CAQC;AAeD,8DAGC;AAOD,8DASC;AAeD,4CASC;AAgBD,sDAEC;AAWD,oDAEC;AA3HD,uCAAyB;AACzB,2CAA6B;AAE7B,iEAAiE;AACpD,QAAA,gBAAgB,GAA2B;IACtD,KAAK,EAAI,QAAQ;IACjB,MAAM,EAAG,QAAQ;IACjB,OAAO,EAAE,UAAU;IACnB,QAAQ,EAAC,UAAU;IACnB,IAAI,EAAK,OAAO;IAChB,KAAK,EAAI,OAAO;IAChB,GAAG,EAAM,aAAa;IACtB,aAAa,EAAE,aAAa;CAC7B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,SAAgB,gBAAgB;IAC9B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,6EAA6E;QAC7E,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACrF,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IACD,qCAAqC;IACrC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,yBAAyB;IACvC,2EAA2E;IAC3E,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,SAAgB,yBAAyB,CAAC,YAAoB;IAC5D,MAAM,MAAM,GAAG,wBAAgB,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,0BAA0B,YAAY,KAAK;YAC3C,oBAAoB,MAAM,CAAC,IAAI,CAAC,wBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,yBAAyB,EAAE,IAAI,MAAM,EAAE,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,gBAAgB,CAAC,YAAoB;IACnD,MAAM,MAAM,GAAG,wBAAgB,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,0BAA0B,YAAY,KAAK;YAC3C,oBAAoB,MAAM,CAAC,IAAI,CAAC,wBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,qBAAqB,CAAC,YAAoB,EAAE,YAAoB;IAC9E,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,oBAAoB;IAClC,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,4BAA4B,CAAC,CAAC;AACrE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliotding/ai-agent-mcp",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "CSP AI Agent MCP Server - Centralized AI tools distribution and management",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -309,13 +309,34 @@ class MultiSourceGitManager {
309
309
  */
310
310
  async readResourceFiles(
311
311
  resourceName: string,
312
- resourceType: 'command' | 'skill',
312
+ resourceType: 'command' | 'skill' | 'rule' | 'mcp',
313
313
  ): Promise<Array<{ path: string; content: string }>> {
314
314
  const sources = await this.getEnabledSources();
315
315
  // Sort by priority descending so higher-priority sources win.
316
316
  sources.sort((a, b) => b.priority - a.priority);
317
317
 
318
- const typeDir = resourceType === 'command' ? 'commands' : 'skills';
318
+ // Map singular type names to the plural directory keys used in config.
319
+ const typeToDirKey: Record<string, keyof SourceConfig['resources']> = {
320
+ command: 'commands',
321
+ commands: 'commands',
322
+ skill: 'skills',
323
+ skills: 'skills',
324
+ rule: 'rules',
325
+ rules: 'rules',
326
+ mcp: 'mcp',
327
+ };
328
+ const typeDir = typeToDirKey[resourceType] ?? 'skills';
329
+
330
+ logger.info(
331
+ {
332
+ resourceName,
333
+ resourceType,
334
+ resolvedDirKey: typeDir,
335
+ sourceCount: sources.length,
336
+ sourceNames: sources.map((s) => s.name),
337
+ },
338
+ 'readResourceFiles: start — searching git sources for resource',
339
+ );
319
340
 
320
341
  for (const source of sources) {
321
342
  const sourcePath = path.join(this.baseDir, source.path);
@@ -323,7 +344,18 @@ class MultiSourceGitManager {
323
344
  const resourceDir = path.join(sourcePath, resourcesSubDir, resourceName);
324
345
  const resourceFile = path.join(sourcePath, resourcesSubDir, `${resourceName}.md`);
325
346
 
326
- // Try directory-based layout first (e.g. skills/<name>/SKILL.md)
347
+ logger.info(
348
+ {
349
+ source: source.name,
350
+ resourceName,
351
+ resourceType,
352
+ tryDirPath: resourceDir,
353
+ tryFilePath: resourceFile,
354
+ },
355
+ 'readResourceFiles: trying source',
356
+ );
357
+
358
+ // Try directory-based layout first (e.g. rules/<name>/ or mcp/<name>/)
327
359
  try {
328
360
  const stat = await fs.stat(resourceDir);
329
361
  if (stat.isDirectory()) {
@@ -336,28 +368,55 @@ class MultiSourceGitManager {
336
368
  const content = await fs.readFile(filePath, 'utf-8');
337
369
  results.push({ path: f, content });
338
370
  }
339
- logger.debug(
340
- { source: source.name, resourceName, resourceType, fileCount: results.length },
371
+ logger.info(
372
+ {
373
+ source: source.name,
374
+ resourceName,
375
+ resourceType,
376
+ dirPath: resourceDir,
377
+ fileCount: results.length,
378
+ files: results.map((r) => r.path),
379
+ },
341
380
  'readResourceFiles: found files in directory layout',
342
381
  );
343
382
  return results;
344
383
  }
384
+ logger.info(
385
+ { source: source.name, resourceName, resourceType, dirPath: resourceDir },
386
+ 'readResourceFiles: directory exists but contains no .md/.mdc files — trying flat file',
387
+ );
345
388
  }
346
389
  } catch { /* not a directory or doesn't exist — try flat file */ }
347
390
 
348
- // Try flat file layout (e.g. commands/<name>.md)
349
- try {
350
- const content = await fs.readFile(resourceFile, 'utf-8');
351
- logger.debug(
352
- { source: source.name, resourceName, resourceType, filePath: resourceFile },
353
- 'readResourceFiles: found flat file',
354
- );
355
- return [{ path: `${resourceName}.md`, content }];
356
- } catch { /* not found in this source — try next */ }
391
+ // Try flat file layout (e.g. rules/<name>.mdc or rules/<name>.md)
392
+ // Also try .mdc extension for rule resources.
393
+ const mdcFile = path.join(sourcePath, resourcesSubDir, `${resourceName}.mdc`);
394
+ for (const [filePath, ext] of [[resourceFile, '.md'], [mdcFile, '.mdc']] as const) {
395
+ try {
396
+ const content = await fs.readFile(filePath, 'utf-8');
397
+ logger.info(
398
+ {
399
+ source: source.name,
400
+ resourceName,
401
+ resourceType,
402
+ filePath,
403
+ ext,
404
+ contentLength: content.length,
405
+ },
406
+ 'readResourceFiles: found flat file',
407
+ );
408
+ return [{ path: `${resourceName}${ext}`, content }];
409
+ } catch { /* not found — try next extension or source */ }
410
+ }
411
+
412
+ logger.info(
413
+ { source: source.name, resourceName, resourceType },
414
+ 'readResourceFiles: resource not found in this source — trying next',
415
+ );
357
416
  }
358
417
 
359
418
  logger.warn(
360
- { resourceName, resourceType },
419
+ { resourceName, resourceType, resolvedDirKey: typeDir, sourceCount: sources.length },
361
420
  'readResourceFiles: resource not found in any git source',
362
421
  );
363
422
  return [];
@@ -97,8 +97,11 @@ export class PromptManager {
97
97
  this.installedServers.add(server);
98
98
 
99
99
  // List all registered prompts.
100
+ // A fixed setup prompt is always injected at the top of the list so that
101
+ // Cursor's AI Agent picks it up on connection and performs the initial sync,
102
+ // which writes Rule files and MCP entries to the user's local machine.
100
103
  server.setRequestHandler(ListPromptsRequestSchema, () => {
101
- const prompts = Array.from(this.prompts.values()).map(({ name, description }) => ({
104
+ const resourcePrompts = Array.from(this.prompts.values()).map(({ name, description }) => ({
102
105
  name,
103
106
  description,
104
107
  arguments: [
@@ -109,13 +112,80 @@ export class PromptManager {
109
112
  },
110
113
  ],
111
114
  }));
112
- logger.info({ promptNames: prompts.map((p) => p.name), count: prompts.length }, 'ListPrompts called');
115
+
116
+ const setupPrompt = {
117
+ name: 'csp-ai-agent-setup',
118
+ description:
119
+ 'CSP AI Agent initialisation — run sync_resources and apply local actions. ' +
120
+ 'This prompt is automatically injected and should be invoked by the AI on first connect.',
121
+ arguments: [],
122
+ };
123
+
124
+ const prompts = [setupPrompt, ...resourcePrompts];
125
+ logger.info(
126
+ {
127
+ total: prompts.length,
128
+ setupPromptIncluded: true,
129
+ resourcePromptCount: resourcePrompts.length,
130
+ resourcePromptNames: resourcePrompts.map((p) => p.name),
131
+ },
132
+ 'ListPrompts called — csp-ai-agent-setup injected as first entry',
133
+ );
113
134
  return { prompts };
114
135
  });
115
136
 
116
137
  // Serve the content of a specific prompt.
117
138
  server.setRequestHandler(GetPromptRequestSchema, async (request) => {
118
139
  const { name, arguments: args } = request.params;
140
+
141
+ // ── Setup prompt: drives initial sync + local action execution ───────────
142
+ if (name === 'csp-ai-agent-setup') {
143
+ logger.info(
144
+ {
145
+ promptName: name,
146
+ userToken: userToken ? `${userToken.slice(0, 12)}...` : 'none',
147
+ registeredPromptCount: this.prompts.size,
148
+ },
149
+ 'GetPrompt: serving csp-ai-agent-setup — AI will sync resources and apply local actions',
150
+ );
151
+ const setupContent =
152
+ `## CSP AI Agent — Initialisation\n\n` +
153
+ `**[MANDATORY — Execute immediately, do not skip any step]**\n\n` +
154
+ `You MUST perform the following steps in order right now:\n\n` +
155
+ `### Step 1 — Sync AI resources\n` +
156
+ `Call the \`sync_resources\` tool with:\n` +
157
+ `- \`mode\`: \`"incremental"\`\n` +
158
+ `- \`scope\`: \`"global"\`\n\n` +
159
+ `### Step 2 — Apply local actions\n` +
160
+ `If the \`sync_resources\` result contains a \`local_actions_required\` array, ` +
161
+ `you MUST execute every action in it on the user's LOCAL machine:\n\n` +
162
+ `- **\`write_file\`**: Create the file at the given \`path\` with the given \`content\`. ` +
163
+ `Expand \`~\` to the user's home directory. Create parent directories if they do not exist.\n` +
164
+ `- **\`merge_mcp_json\`**: Read \`~/.cursor/mcp.json\` (create if missing), ` +
165
+ `add or update the entry under \`mcpServers[server_name]\` with the provided \`entry\` object, ` +
166
+ `then write the file back. Do not remove existing entries.\n` +
167
+ `- **\`delete_file\`**: Delete the file or directory at \`path\`. ` +
168
+ `If \`recursive\` is true, delete the directory and all its contents. Skip if it does not exist.\n` +
169
+ `- **\`remove_mcp_json_entry\`**: Read \`~/.cursor/mcp.json\`, ` +
170
+ `remove the entry at \`mcpServers[server_name]\` if it exists, then write the file back.\n\n` +
171
+ `### Step 3 — Report\n` +
172
+ `After completing all steps, briefly tell the user:\n` +
173
+ `- How many resources were synced\n` +
174
+ `- Which local files/MCP entries were written (if any)\n` +
175
+ `- Any failures or pending manual actions\n\n` +
176
+ `Do NOT ask the user for confirmation before starting. Begin immediately.\n`;
177
+
178
+ return {
179
+ description: 'CSP AI Agent initialisation — sync resources and apply local actions',
180
+ messages: [
181
+ {
182
+ role: 'user' as const,
183
+ content: { type: 'text' as const, text: setupContent },
184
+ },
185
+ ],
186
+ };
187
+ }
188
+
119
189
  const registered = this.prompts.get(name);
120
190
 
121
191
  logger.info(