@elliotding/ai-agent-mcp 0.1.25 → 0.1.26

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 (237) 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/dist/api/cached-client.d.ts +0 -48
  9. package/dist/api/cached-client.d.ts.map +0 -1
  10. package/dist/api/cached-client.js +0 -126
  11. package/dist/api/cached-client.js.map +0 -1
  12. package/dist/api/client.d.ts +0 -281
  13. package/dist/api/client.d.ts.map +0 -1
  14. package/dist/api/client.js +0 -371
  15. package/dist/api/client.js.map +0 -1
  16. package/dist/auth/index.d.ts +0 -8
  17. package/dist/auth/index.d.ts.map +0 -1
  18. package/dist/auth/index.js +0 -26
  19. package/dist/auth/index.js.map +0 -1
  20. package/dist/auth/middleware.d.ts +0 -36
  21. package/dist/auth/middleware.d.ts.map +0 -1
  22. package/dist/auth/middleware.js +0 -194
  23. package/dist/auth/middleware.js.map +0 -1
  24. package/dist/auth/permissions.d.ts +0 -60
  25. package/dist/auth/permissions.d.ts.map +0 -1
  26. package/dist/auth/permissions.js +0 -262
  27. package/dist/auth/permissions.js.map +0 -1
  28. package/dist/auth/token-validator.d.ts +0 -52
  29. package/dist/auth/token-validator.d.ts.map +0 -1
  30. package/dist/auth/token-validator.js +0 -215
  31. package/dist/auth/token-validator.js.map +0 -1
  32. package/dist/cache/cache-manager.d.ts +0 -49
  33. package/dist/cache/cache-manager.d.ts.map +0 -1
  34. package/dist/cache/cache-manager.js +0 -191
  35. package/dist/cache/cache-manager.js.map +0 -1
  36. package/dist/cache/index.d.ts +0 -6
  37. package/dist/cache/index.d.ts.map +0 -1
  38. package/dist/cache/index.js +0 -12
  39. package/dist/cache/index.js.map +0 -1
  40. package/dist/cache/redis-client.d.ts +0 -45
  41. package/dist/cache/redis-client.d.ts.map +0 -1
  42. package/dist/cache/redis-client.js +0 -210
  43. package/dist/cache/redis-client.js.map +0 -1
  44. package/dist/config/constants.d.ts +0 -28
  45. package/dist/config/constants.d.ts.map +0 -1
  46. package/dist/config/constants.js +0 -31
  47. package/dist/config/constants.js.map +0 -1
  48. package/dist/config/index.d.ts +0 -71
  49. package/dist/config/index.d.ts.map +0 -1
  50. package/dist/config/index.js +0 -190
  51. package/dist/config/index.js.map +0 -1
  52. package/dist/filesystem/manager.d.ts +0 -45
  53. package/dist/filesystem/manager.d.ts.map +0 -1
  54. package/dist/filesystem/manager.js +0 -246
  55. package/dist/filesystem/manager.js.map +0 -1
  56. package/dist/git/multi-source-manager.d.ts +0 -78
  57. package/dist/git/multi-source-manager.d.ts.map +0 -1
  58. package/dist/git/multi-source-manager.js +0 -577
  59. package/dist/git/multi-source-manager.js.map +0 -1
  60. package/dist/git/operations.d.ts +0 -27
  61. package/dist/git/operations.d.ts.map +0 -1
  62. package/dist/git/operations.js +0 -83
  63. package/dist/git/operations.js.map +0 -1
  64. package/dist/index.d.ts +0 -6
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/index.js +0 -122
  67. package/dist/index.js.map +0 -1
  68. package/dist/monitoring/health.d.ts +0 -35
  69. package/dist/monitoring/health.d.ts.map +0 -1
  70. package/dist/monitoring/health.js +0 -105
  71. package/dist/monitoring/health.js.map +0 -1
  72. package/dist/prompts/cache.d.ts +0 -69
  73. package/dist/prompts/cache.d.ts.map +0 -1
  74. package/dist/prompts/cache.js +0 -163
  75. package/dist/prompts/cache.js.map +0 -1
  76. package/dist/prompts/generator.d.ts +0 -49
  77. package/dist/prompts/generator.d.ts.map +0 -1
  78. package/dist/prompts/generator.js +0 -160
  79. package/dist/prompts/generator.js.map +0 -1
  80. package/dist/prompts/index.d.ts +0 -13
  81. package/dist/prompts/index.d.ts.map +0 -1
  82. package/dist/prompts/index.js +0 -24
  83. package/dist/prompts/index.js.map +0 -1
  84. package/dist/prompts/manager.d.ts +0 -207
  85. package/dist/prompts/manager.d.ts.map +0 -1
  86. package/dist/prompts/manager.js +0 -566
  87. package/dist/prompts/manager.js.map +0 -1
  88. package/dist/resources/index.d.ts +0 -6
  89. package/dist/resources/index.d.ts.map +0 -1
  90. package/dist/resources/index.js +0 -10
  91. package/dist/resources/index.js.map +0 -1
  92. package/dist/resources/loader.d.ts +0 -88
  93. package/dist/resources/loader.d.ts.map +0 -1
  94. package/dist/resources/loader.js +0 -492
  95. package/dist/resources/loader.js.map +0 -1
  96. package/dist/server/http.d.ts +0 -57
  97. package/dist/server/http.d.ts.map +0 -1
  98. package/dist/server/http.js +0 -435
  99. package/dist/server/http.js.map +0 -1
  100. package/dist/server.d.ts +0 -13
  101. package/dist/server.d.ts.map +0 -1
  102. package/dist/server.js +0 -201
  103. package/dist/server.js.map +0 -1
  104. package/dist/session/manager.d.ts +0 -91
  105. package/dist/session/manager.d.ts.map +0 -1
  106. package/dist/session/manager.js +0 -251
  107. package/dist/session/manager.js.map +0 -1
  108. package/dist/telemetry/index.d.ts +0 -3
  109. package/dist/telemetry/index.d.ts.map +0 -1
  110. package/dist/telemetry/index.js +0 -7
  111. package/dist/telemetry/index.js.map +0 -1
  112. package/dist/telemetry/manager.d.ts +0 -151
  113. package/dist/telemetry/manager.d.ts.map +0 -1
  114. package/dist/telemetry/manager.js +0 -367
  115. package/dist/telemetry/manager.js.map +0 -1
  116. package/dist/tools/index.d.ts +0 -13
  117. package/dist/tools/index.d.ts.map +0 -1
  118. package/dist/tools/index.js +0 -29
  119. package/dist/tools/index.js.map +0 -1
  120. package/dist/tools/manage-subscription.d.ts +0 -47
  121. package/dist/tools/manage-subscription.d.ts.map +0 -1
  122. package/dist/tools/manage-subscription.js +0 -317
  123. package/dist/tools/manage-subscription.js.map +0 -1
  124. package/dist/tools/registry.d.ts +0 -40
  125. package/dist/tools/registry.d.ts.map +0 -1
  126. package/dist/tools/registry.js +0 -85
  127. package/dist/tools/registry.js.map +0 -1
  128. package/dist/tools/resolve-prompt-content.d.ts +0 -35
  129. package/dist/tools/resolve-prompt-content.d.ts.map +0 -1
  130. package/dist/tools/resolve-prompt-content.js +0 -99
  131. package/dist/tools/resolve-prompt-content.js.map +0 -1
  132. package/dist/tools/search-resources.d.ts +0 -35
  133. package/dist/tools/search-resources.d.ts.map +0 -1
  134. package/dist/tools/search-resources.js +0 -159
  135. package/dist/tools/search-resources.js.map +0 -1
  136. package/dist/tools/sync-resources.d.ts +0 -54
  137. package/dist/tools/sync-resources.d.ts.map +0 -1
  138. package/dist/tools/sync-resources.js +0 -735
  139. package/dist/tools/sync-resources.js.map +0 -1
  140. package/dist/tools/track-usage.d.ts +0 -63
  141. package/dist/tools/track-usage.d.ts.map +0 -1
  142. package/dist/tools/track-usage.js +0 -90
  143. package/dist/tools/track-usage.js.map +0 -1
  144. package/dist/tools/uninstall-resource.d.ts +0 -30
  145. package/dist/tools/uninstall-resource.d.ts.map +0 -1
  146. package/dist/tools/uninstall-resource.js +0 -174
  147. package/dist/tools/uninstall-resource.js.map +0 -1
  148. package/dist/tools/upload-resource.d.ts +0 -81
  149. package/dist/tools/upload-resource.d.ts.map +0 -1
  150. package/dist/tools/upload-resource.js +0 -393
  151. package/dist/tools/upload-resource.js.map +0 -1
  152. package/dist/transport/sse.d.ts +0 -29
  153. package/dist/transport/sse.d.ts.map +0 -1
  154. package/dist/transport/sse.js +0 -271
  155. package/dist/transport/sse.js.map +0 -1
  156. package/dist/types/errors.d.ts +0 -60
  157. package/dist/types/errors.d.ts.map +0 -1
  158. package/dist/types/errors.js +0 -112
  159. package/dist/types/errors.js.map +0 -1
  160. package/dist/types/index.d.ts +0 -7
  161. package/dist/types/index.d.ts.map +0 -1
  162. package/dist/types/index.js +0 -23
  163. package/dist/types/index.js.map +0 -1
  164. package/dist/types/mcp.d.ts +0 -50
  165. package/dist/types/mcp.d.ts.map +0 -1
  166. package/dist/types/mcp.js +0 -6
  167. package/dist/types/mcp.js.map +0 -1
  168. package/dist/types/resources.d.ts +0 -109
  169. package/dist/types/resources.d.ts.map +0 -1
  170. package/dist/types/resources.js +0 -7
  171. package/dist/types/resources.js.map +0 -1
  172. package/dist/types/tools.d.ts +0 -253
  173. package/dist/types/tools.d.ts.map +0 -1
  174. package/dist/types/tools.js +0 -6
  175. package/dist/types/tools.js.map +0 -1
  176. package/dist/utils/cursor-paths.d.ts +0 -84
  177. package/dist/utils/cursor-paths.d.ts.map +0 -1
  178. package/dist/utils/cursor-paths.js +0 -166
  179. package/dist/utils/cursor-paths.js.map +0 -1
  180. package/dist/utils/log-cleaner.d.ts +0 -18
  181. package/dist/utils/log-cleaner.d.ts.map +0 -1
  182. package/dist/utils/log-cleaner.js +0 -112
  183. package/dist/utils/log-cleaner.js.map +0 -1
  184. package/dist/utils/logger.d.ts +0 -59
  185. package/dist/utils/logger.d.ts.map +0 -1
  186. package/dist/utils/logger.js +0 -292
  187. package/dist/utils/logger.js.map +0 -1
  188. package/dist/utils/validation.d.ts +0 -58
  189. package/dist/utils/validation.d.ts.map +0 -1
  190. package/dist/utils/validation.js +0 -214
  191. package/dist/utils/validation.js.map +0 -1
  192. package/src/api/cached-client.ts +0 -144
  193. package/src/api/client.ts +0 -697
  194. package/src/auth/index.ts +0 -11
  195. package/src/auth/middleware.ts +0 -244
  196. package/src/auth/permissions.ts +0 -323
  197. package/src/auth/token-validator.ts +0 -292
  198. package/src/cache/cache-manager.ts +0 -243
  199. package/src/cache/index.ts +0 -6
  200. package/src/cache/redis-client.ts +0 -249
  201. package/src/config/constants.ts +0 -33
  202. package/src/config/index.ts +0 -269
  203. package/src/filesystem/manager.ts +0 -235
  204. package/src/git/multi-source-manager.ts +0 -654
  205. package/src/git/operations.ts +0 -93
  206. package/src/index.ts +0 -157
  207. package/src/monitoring/health.ts +0 -132
  208. package/src/prompts/cache.ts +0 -140
  209. package/src/prompts/generator.ts +0 -143
  210. package/src/prompts/index.ts +0 -20
  211. package/src/prompts/manager.ts +0 -718
  212. package/src/resources/index.ts +0 -13
  213. package/src/resources/loader.ts +0 -563
  214. package/src/server/http.ts +0 -549
  215. package/src/server.ts +0 -206
  216. package/src/session/manager.ts +0 -296
  217. package/src/telemetry/index.ts +0 -10
  218. package/src/telemetry/manager.ts +0 -419
  219. package/src/tools/index.ts +0 -13
  220. package/src/tools/manage-subscription.ts +0 -388
  221. package/src/tools/registry.ts +0 -97
  222. package/src/tools/resolve-prompt-content.ts +0 -113
  223. package/src/tools/search-resources.ts +0 -185
  224. package/src/tools/sync-resources.ts +0 -829
  225. package/src/tools/track-usage.ts +0 -113
  226. package/src/tools/uninstall-resource.ts +0 -199
  227. package/src/tools/upload-resource.ts +0 -431
  228. package/src/transport/sse.ts +0 -308
  229. package/src/types/errors.ts +0 -146
  230. package/src/types/index.ts +0 -7
  231. package/src/types/mcp.ts +0 -61
  232. package/src/types/resources.ts +0 -141
  233. package/src/types/tools.ts +0 -305
  234. package/src/utils/cursor-paths.ts +0 -135
  235. package/src/utils/log-cleaner.ts +0 -92
  236. package/src/utils/logger.ts +0 -333
  237. package/src/utils/validation.ts +0 -262
@@ -1,113 +0,0 @@
1
- /**
2
- * track_usage Tool
3
- *
4
- * Records an AI Resource invocation for telemetry purposes.
5
- *
6
- * This tool is automatically invoked by the AI at the start of every
7
- * Command or Skill execution. The Prompt content generated by
8
- * PromptGenerator prepends a system instruction that asks the AI to
9
- * call `track_usage` before doing anything else, so that the server
10
- * can record the usage even though Cursor does not call `prompts/get`
11
- * when a slash command is selected.
12
- *
13
- * The tool is intentionally lightweight:
14
- * - No external API calls.
15
- * - Fire-and-forget write to the local telemetry file.
16
- * - Always returns a success response so the AI continues normally.
17
- */
18
-
19
- import { logger } from '../utils/logger';
20
- import { telemetry } from '../telemetry/index.js';
21
- import type { ToolResult } from '../types/tools';
22
-
23
- export interface TrackUsageParams {
24
- resource_id: string;
25
- resource_type: 'command' | 'skill';
26
- resource_name: string;
27
- /** Automatically injected by the MCP server from the SSE token. */
28
- user_token?: string;
29
- /** Optional Jira Issue ID for usage correlation (e.g. "PROJ-12345"). */
30
- jira_id?: string;
31
- }
32
-
33
- export async function trackUsage(params: unknown): Promise<ToolResult<{ recorded: boolean }>> {
34
- const p = params as TrackUsageParams;
35
-
36
- const resourceId = p.resource_id ?? '';
37
- const resourceType = p.resource_type ?? 'command';
38
- const resourceName = p.resource_name ?? '';
39
- const userToken = p.user_token ?? '';
40
- const jiraId = typeof p.jira_id === 'string' && p.jira_id.trim() !== ''
41
- ? p.jira_id.trim()
42
- : undefined;
43
-
44
- if (!resourceId || !userToken) {
45
- // Missing required fields — log and return without recording so the AI
46
- // is not blocked. This should not happen in normal operation.
47
- logger.warn(
48
- { resourceId, userToken: !!userToken },
49
- 'track_usage called with missing resource_id or user_token — skipping',
50
- );
51
- return { success: true, data: { recorded: false } };
52
- }
53
-
54
- // Await the write to ensure the event is persisted before the periodic flush
55
- // timer fires and clears pending_events. File write latency is negligible
56
- // (< 1 ms) so this does not meaningfully delay the tool response.
57
- await telemetry
58
- .recordInvocation(resourceId, resourceType, resourceName, userToken, jiraId)
59
- .catch((err) => {
60
- logger.warn({ resourceId, error: (err as Error).message }, 'track_usage: telemetry write failed (non-critical)');
61
- });
62
-
63
- logger.info(
64
- { resourceId, resourceType, resourceName, jiraId: jiraId ?? '(none)' },
65
- 'track_usage: invocation recorded',
66
- );
67
-
68
- return { success: true, data: { recorded: true } };
69
- }
70
-
71
- export const trackUsageTool = {
72
- name: 'track_usage',
73
- description:
74
- 'Record the invocation of an AI Resource (Command or Skill) for telemetry. ' +
75
- 'MUST be called at the very beginning of every Command or Skill execution, ' +
76
- 'before performing any other action. ' +
77
- 'The resource_id, resource_type, and resource_name are provided in the prompt header — ' +
78
- 'copy them exactly as given. ' +
79
- 'user_token is injected automatically by the server; do NOT ask the user for it. ' +
80
- 'jira_id is optional — only include it if the user explicitly mentions a Jira issue number.',
81
- inputSchema: {
82
- type: 'object' as const,
83
- properties: {
84
- resource_id: {
85
- type: 'string',
86
- description: 'Canonical resource ID as shown in the prompt header (e.g. "cmd-client-sdk-ai-hub-generate-testcase").',
87
- },
88
- resource_type: {
89
- type: 'string',
90
- enum: ['command', 'skill'],
91
- description: 'Resource type: "command" or "skill".',
92
- },
93
- resource_name: {
94
- type: 'string',
95
- description: 'Human-readable resource name as shown in the prompt header (e.g. "generate-testcase").',
96
- },
97
- user_token: {
98
- type: 'string',
99
- description:
100
- 'DO NOT set this field — it is automatically injected by the MCP server from ' +
101
- 'the authenticated SSE connection.',
102
- },
103
- jira_id: {
104
- type: 'string',
105
- description:
106
- 'Optional Jira Issue ID for usage correlation (e.g. "PROJ-12345"). ' +
107
- 'Only include if the user explicitly mentioned a Jira issue in this conversation.',
108
- },
109
- },
110
- required: ['resource_id', 'resource_type', 'resource_name'],
111
- },
112
- handler: trackUsage,
113
- };
@@ -1,199 +0,0 @@
1
- /**
2
- * uninstall_resource Tool
3
- * Uninstall a resource from local filesystem and clean up related configuration.
4
- *
5
- * For MCP resources this also removes the mcpServers entry from ~/.cursor/mcp.json.
6
- * For directory-based resources (skill, mcp) the entire install directory is removed.
7
- */
8
-
9
- import { logger, logToolCall } from '../utils/logger';
10
- import { apiClient } from '../api/client';
11
- import { getCursorTypeDirForClient, getCursorRootDirForClient } from '../utils/cursor-paths.js';
12
- import { MCPServerError, createValidationError } from '../types/errors';
13
- import type { UninstallResourceParams, UninstallResourceResult, LocalAction, ToolResult } from '../types/tools';
14
- import { promptManager } from '../prompts/index.js';
15
-
16
-
17
- export async function uninstallResource(params: unknown): Promise<ToolResult<UninstallResourceResult>> {
18
- const startTime = Date.now();
19
- const typedParams = params as UninstallResourceParams;
20
-
21
- logger.info({ tool: 'uninstall_resource', params }, 'uninstall_resource called');
22
-
23
- try {
24
- const pattern = typedParams.resource_id_or_name;
25
- const removeFromAccount = typedParams.remove_from_account || false;
26
-
27
- const removedResources: Array<{ id: string; name: string; path: string }> = [];
28
- let subscriptionRemoved = false;
29
-
30
- // ── Command / Skill: unregister MCP Prompt + delete cache ─────────────
31
- // Match registered prompt names that contain the pattern.
32
- const matchedPromptNames = promptManager.promptNames(typedParams.user_token ?? '').filter(
33
- (name) => name === pattern || name.includes(pattern),
34
- );
35
-
36
- if (matchedPromptNames.length > 0) {
37
- for (const promptName of matchedPromptNames) {
38
- // Prompt name format: <team>/<type>/<resource_name>
39
- const parts = promptName.split('/');
40
- const team = parts[0] ?? 'general';
41
- const resourceType = parts[1] as 'command' | 'skill' | undefined;
42
- const resourceName = parts.slice(2).join('/') || promptName;
43
-
44
- // Find the resource_id from the registered prompt (best-effort via name).
45
- // For unsubscription, we pass the promptName as id if no better source.
46
- const resourceId = pattern.startsWith('cmd-') || pattern.startsWith('skill-')
47
- ? pattern
48
- : promptName;
49
-
50
- // Unregister from the in-memory prompt registry only.
51
- // The server-side .prompt-cache/ files are intentionally NOT deleted here —
52
- // they are shared across all users and will be regenerated on the next git pull.
53
- promptManager.unregisterPrompt(resourceId, resourceType ?? 'command', resourceName, typedParams.user_token ?? '');
54
-
55
- removedResources.push({ id: resourceId, name: resourceName, path: `[MCP Prompt: ${promptName}]` });
56
- logger.info({ promptName, team, resourceType, resourceName }, 'MCP Prompt unregistered via uninstall');
57
- }
58
-
59
- // Remove from server subscription if requested
60
- if (removeFromAccount) {
61
- for (const r of removedResources) {
62
- try {
63
- await apiClient.unsubscribe(r.id);
64
- subscriptionRemoved = true;
65
- } catch (err) {
66
- logger.warn({ resourceId: r.id, err }, 'Failed to unsubscribe Command/Skill Prompt from account');
67
- }
68
- }
69
- }
70
-
71
- // Return early — Command/Skill resources have no local filesystem footprint.
72
- const result: UninstallResourceResult = {
73
- success: true,
74
- removed_resources: removedResources,
75
- subscription_removed: subscriptionRemoved,
76
- message: [
77
- `Successfully unregistered ${removedResources.length} MCP Prompt${removedResources.length > 1 ? 's' : ''}.`,
78
- subscriptionRemoved ? 'Subscription removed from account.' : null,
79
- ].filter(Boolean).join(' '),
80
- };
81
- const duration = Date.now() - startTime;
82
- logToolCall('uninstall_resource', 'user-id', params as Record<string, unknown>, duration);
83
- return { success: true, data: result };
84
- }
85
-
86
- // ── Rule / MCP: return LocalAction instructions for the AI to execute ────
87
- // The MCP server may be running remotely; we must NOT touch the server's
88
- // own filesystem. Instead we return delete/remove instructions so the AI
89
- // Agent performs them on the user's LOCAL machine.
90
- logger.debug({ pattern, resourceType: typedParams.resource_type }, 'Building local uninstall actions for Rule/MCP resource...');
91
-
92
- const localActions: LocalAction[] = [];
93
- // Use client-side tilde-based paths; the MCP server may be running remotely
94
- // and its os.homedir() would resolve to the server's home, not the user's.
95
- const mcpJsonPath = `${getCursorRootDirForClient()}/mcp.json`;
96
-
97
- // When resource_type is provided, only emit the relevant actions.
98
- // When unknown, emit both (AI skips missing files gracefully).
99
- const knownType = typedParams.resource_type;
100
- const isRule = !knownType || knownType === 'rule';
101
- const isMcp = !knownType || knownType === 'mcp';
102
-
103
- if (isRule) {
104
- // Rule: delete ~/.cursor/rules/<pattern>.mdc and .md variants.
105
- const rulesDir = getCursorTypeDirForClient('rule');
106
- for (const ext of ['.mdc', '.md']) {
107
- const filePath = `${rulesDir}/${pattern}${ext}`;
108
- localActions.push({ action: 'delete_file', path: filePath });
109
- removedResources.push({ id: pattern, name: pattern, path: filePath });
110
- }
111
- }
112
-
113
- if (isMcp) {
114
- // MCP: delete install directory (Format A — may not exist for remote-URL MCPs)
115
- // and remove the mcpServers entry from mcp.json.
116
- const mcpDir = getCursorTypeDirForClient('mcp');
117
- const mcpInstallDir = `${mcpDir}/${pattern}`;
118
- localActions.push({ action: 'delete_file', path: mcpInstallDir, recursive: true });
119
- localActions.push({ action: 'remove_mcp_json_entry', mcp_json_path: mcpJsonPath, server_name: pattern });
120
- removedResources.push({ id: pattern, name: pattern, path: mcpInstallDir });
121
- }
122
-
123
- if (removedResources.length === 0 && localActions.length === 0) {
124
- throw createValidationError(
125
- pattern,
126
- 'resource_id_or_name',
127
- 'No installed Rule or MCP resources found matching pattern. Use search_resources to find available resources'
128
- );
129
- }
130
-
131
- // Remove from server subscription if requested
132
- if (removeFromAccount) {
133
- try {
134
- await apiClient.unsubscribe(pattern);
135
- subscriptionRemoved = true;
136
- } catch (err) {
137
- logger.warn({ pattern, err }, 'Failed to unsubscribe resource from account');
138
- }
139
- }
140
-
141
- const result: UninstallResourceResult = {
142
- success: true,
143
- removed_resources: removedResources,
144
- subscription_removed: subscriptionRemoved,
145
- message: [
146
- `Prepared ${localActions.length} local uninstall action(s) for ${removedResources.length} resource(s).`,
147
- 'Execute every action in local_actions_required on the user\'s local machine.',
148
- subscriptionRemoved ? 'Subscription removed from account.' : null,
149
- ].filter(Boolean).join(' '),
150
- local_actions_required: localActions,
151
- };
152
-
153
- const duration = Date.now() - startTime;
154
- logToolCall('uninstall_resource', 'user-id', params as Record<string, unknown>, duration);
155
- logger.info({ pattern, actionCount: localActions.length, subscriptionRemoved, duration }, 'uninstall_resource completed');
156
-
157
- return { success: true, data: result };
158
-
159
- } catch (error) {
160
- logger.error({ error, pattern: typedParams.resource_id_or_name }, 'uninstall_resource failed');
161
- return {
162
- success: false,
163
- error: {
164
- code: error instanceof MCPServerError ? error.code : 'UNKNOWN_ERROR',
165
- message: error instanceof Error ? error.message : String(error),
166
- },
167
- };
168
- }
169
- }
170
-
171
- // Tool definition for registry
172
- export const uninstallResourceTool = {
173
- name: 'uninstall_resource',
174
- description:
175
- 'Uninstall a Rule or MCP resource from the user\'s local machine. ' +
176
- 'Returns `local_actions_required` — an ordered list of delete_file and ' +
177
- 'remove_mcp_json_entry actions that the AI Agent MUST execute on the USER\'S LOCAL MACHINE. ' +
178
- 'For delete_file actions: delete the file or directory at the given path. ' +
179
- 'For remove_mcp_json_entry actions: read ~/.cursor/mcp.json, delete the matching ' +
180
- 'mcpServers key, then write the file back. ' +
181
- 'Command and Skill resources are handled by unregistering their MCP Prompt (no local files). ' +
182
- 'Set remove_from_account: true to also cancel the server-side subscription.',
183
- inputSchema: {
184
- type: 'object' as const,
185
- properties: {
186
- resource_id_or_name: {
187
- type: 'string',
188
- description: 'Resource ID, name, or pattern (supports fuzzy matching)',
189
- },
190
- remove_from_account: {
191
- type: 'boolean',
192
- description: 'Also remove from subscription list (default: false)',
193
- default: false,
194
- },
195
- },
196
- required: ['resource_id_or_name'],
197
- },
198
- handler: uninstallResource,
199
- };