@elliotding/ai-agent-mcp 0.1.2 → 0.1.4

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 (104) hide show
  1. package/.prompt-cache/cmd-cmd-client-sdk-ai-hub-generate-testcase.md +101 -0
  2. package/.prompt-cache/cmd-cmd-client-sdk-ai-hub-submit_zct_job.md +158 -0
  3. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-conf-status.md +311 -0
  4. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-sdk-log.md +64 -0
  5. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-zmb-log-errors.md +84 -0
  6. package/ai-resource-telemetry.json +22 -0
  7. package/dist/api/client.d.ts +76 -8
  8. package/dist/api/client.d.ts.map +1 -1
  9. package/dist/api/client.js +86 -40
  10. package/dist/api/client.js.map +1 -1
  11. package/dist/auth/permissions.d.ts.map +1 -1
  12. package/dist/auth/permissions.js +6 -0
  13. package/dist/auth/permissions.js.map +1 -1
  14. package/dist/config/index.d.ts +6 -1
  15. package/dist/config/index.d.ts.map +1 -1
  16. package/dist/config/index.js +1 -3
  17. package/dist/config/index.js.map +1 -1
  18. package/dist/index.js +12 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/prompts/cache.d.ts +69 -0
  21. package/dist/prompts/cache.d.ts.map +1 -0
  22. package/dist/prompts/cache.js +163 -0
  23. package/dist/prompts/cache.js.map +1 -0
  24. package/dist/prompts/generator.d.ts +49 -0
  25. package/dist/prompts/generator.d.ts.map +1 -0
  26. package/dist/prompts/generator.js +158 -0
  27. package/dist/prompts/generator.js.map +1 -0
  28. package/dist/prompts/index.d.ts +13 -0
  29. package/dist/prompts/index.d.ts.map +1 -0
  30. package/dist/prompts/index.js +24 -0
  31. package/dist/prompts/index.js.map +1 -0
  32. package/dist/prompts/manager.d.ts +106 -0
  33. package/dist/prompts/manager.d.ts.map +1 -0
  34. package/dist/prompts/manager.js +263 -0
  35. package/dist/prompts/manager.js.map +1 -0
  36. package/dist/server/http.d.ts.map +1 -1
  37. package/dist/server/http.js +61 -17
  38. package/dist/server/http.js.map +1 -1
  39. package/dist/server.d.ts.map +1 -1
  40. package/dist/server.js +43 -0
  41. package/dist/server.js.map +1 -1
  42. package/dist/telemetry/index.d.ts +3 -0
  43. package/dist/telemetry/index.d.ts.map +1 -0
  44. package/dist/telemetry/index.js +7 -0
  45. package/dist/telemetry/index.js.map +1 -0
  46. package/dist/telemetry/manager.d.ts +149 -0
  47. package/dist/telemetry/manager.d.ts.map +1 -0
  48. package/dist/telemetry/manager.js +368 -0
  49. package/dist/telemetry/manager.js.map +1 -0
  50. package/dist/tools/index.d.ts +1 -0
  51. package/dist/tools/index.d.ts.map +1 -1
  52. package/dist/tools/index.js +1 -0
  53. package/dist/tools/index.js.map +1 -1
  54. package/dist/tools/manage-subscription.d.ts +4 -0
  55. package/dist/tools/manage-subscription.d.ts.map +1 -1
  56. package/dist/tools/manage-subscription.js +36 -7
  57. package/dist/tools/manage-subscription.js.map +1 -1
  58. package/dist/tools/search-resources.d.ts +4 -0
  59. package/dist/tools/search-resources.d.ts.map +1 -1
  60. package/dist/tools/search-resources.js +6 -1
  61. package/dist/tools/search-resources.js.map +1 -1
  62. package/dist/tools/sync-resources.d.ts +13 -4
  63. package/dist/tools/sync-resources.d.ts.map +1 -1
  64. package/dist/tools/sync-resources.js +127 -6
  65. package/dist/tools/sync-resources.js.map +1 -1
  66. package/dist/tools/track-usage.d.ts +63 -0
  67. package/dist/tools/track-usage.d.ts.map +1 -0
  68. package/dist/tools/track-usage.js +90 -0
  69. package/dist/tools/track-usage.js.map +1 -0
  70. package/dist/tools/uninstall-resource.d.ts.map +1 -1
  71. package/dist/tools/uninstall-resource.js +53 -3
  72. package/dist/tools/uninstall-resource.js.map +1 -1
  73. package/dist/tools/upload-resource.d.ts +4 -0
  74. package/dist/tools/upload-resource.d.ts.map +1 -1
  75. package/dist/tools/upload-resource.js +164 -23
  76. package/dist/tools/upload-resource.js.map +1 -1
  77. package/dist/types/tools.d.ts +17 -2
  78. package/dist/types/tools.d.ts.map +1 -1
  79. package/dist/utils/cursor-paths.d.ts +10 -0
  80. package/dist/utils/cursor-paths.d.ts.map +1 -1
  81. package/dist/utils/cursor-paths.js +13 -0
  82. package/dist/utils/cursor-paths.js.map +1 -1
  83. package/package.json +1 -1
  84. package/src/api/client.ts +191 -71
  85. package/src/auth/permissions.ts +6 -0
  86. package/src/config/index.ts +11 -5
  87. package/src/index.ts +18 -0
  88. package/src/prompts/cache.ts +140 -0
  89. package/src/prompts/generator.ts +142 -0
  90. package/src/prompts/index.ts +20 -0
  91. package/src/prompts/manager.ts +342 -0
  92. package/src/server/http.ts +69 -17
  93. package/src/server.ts +13 -0
  94. package/src/telemetry/index.ts +10 -0
  95. package/src/telemetry/manager.ts +419 -0
  96. package/src/tools/index.ts +1 -0
  97. package/src/tools/manage-subscription.ts +41 -7
  98. package/src/tools/search-resources.ts +14 -6
  99. package/src/tools/sync-resources.ts +141 -9
  100. package/src/tools/track-usage.ts +113 -0
  101. package/src/tools/uninstall-resource.ts +62 -4
  102. package/src/tools/upload-resource.ts +204 -31
  103. package/src/types/tools.ts +17 -2
  104. package/src/utils/cursor-paths.ts +13 -0
@@ -22,6 +22,12 @@ export interface SyncResourcesParams {
22
22
  mode?: 'check' | 'incremental' | 'full';
23
23
  scope?: 'global' | 'workspace' | 'all';
24
24
  types?: string[];
25
+ /**
26
+ * CSP API token from the user's mcp.json env configuration.
27
+ * Overrides the server-level fallback token so that each user
28
+ * makes API calls with their own identity.
29
+ */
30
+ user_token?: string;
25
31
  }
26
32
  export interface McpSetupItem {
27
33
  /** MCP server name as it appears in mcp.json */
@@ -66,6 +72,8 @@ export interface ManageSubscriptionParams {
66
72
  auto_sync?: boolean;
67
73
  scope?: 'global' | 'workspace';
68
74
  notify?: boolean;
75
+ /** CSP API token from the user's mcp.json env configuration. */
76
+ user_token?: string;
69
77
  }
70
78
  export interface ManageSubscriptionResult {
71
79
  action: string;
@@ -90,6 +98,8 @@ export interface SearchResourcesParams {
90
98
  team?: string;
91
99
  type?: string;
92
100
  keyword: string;
101
+ /** CSP API token from the user's mcp.json env configuration. */
102
+ user_token?: string;
93
103
  }
94
104
  export interface SearchResourcesResult {
95
105
  total: number;
@@ -111,9 +121,10 @@ export interface FileEntry {
111
121
  }
112
122
  export interface UploadResourceParams {
113
123
  resource_id: string;
114
- type: 'command' | 'skill' | 'rule' | 'mcp';
124
+ /** Resource category. Optional auto-detected from file structure when omitted. */
125
+ type?: 'command' | 'skill' | 'rule' | 'mcp';
115
126
  message: string;
116
- /** Human-readable resource name sent to the CSP API. Defaults to resource_id. */
127
+ /** Human-readable resource name sent to the CSP API. Defaults to the primary file name (without extension). */
117
128
  name?: string;
118
129
  /** Target source repo from ai-resources-config.json (e.g. "csp", "client-sdk-ai-hub"). Defaults to default_source. */
119
130
  target_source?: string;
@@ -122,6 +133,8 @@ export interface UploadResourceParams {
122
133
  files: FileEntry[];
123
134
  title?: string;
124
135
  metadata?: Record<string, unknown>;
136
+ /** CSP API token from the user's mcp.json env configuration. */
137
+ user_token?: string;
125
138
  }
126
139
  export interface UploadResourceResult {
127
140
  resource_id: string;
@@ -133,6 +146,8 @@ export interface UploadResourceResult {
133
146
  export interface UninstallResourceParams {
134
147
  resource_id_or_name: string;
135
148
  remove_from_account?: boolean;
149
+ /** CSP API token from the user's mcp.json env configuration. */
150
+ user_token?: string;
136
151
  }
137
152
  export interface UninstallResourceResult {
138
153
  success: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":"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"}
@@ -46,4 +46,14 @@ export declare function getCursorTypeDir(resourceType: string): string;
46
46
  * @param resourceName - Resource name (with or without extension)
47
47
  */
48
48
  export declare function getCursorResourcePath(resourceType: string, resourceName: string): string;
49
+ /**
50
+ * Returns the path to the local AI resource telemetry file.
51
+ *
52
+ * Stored at the Cursor root level (not inside a resource-type subdirectory)
53
+ * so it persists independently of individual resource installs/uninstalls.
54
+ *
55
+ * macOS / Linux : ~/.cursor/ai-resource-telemetry.json
56
+ * Windows : %APPDATA%\Cursor\User\ai-resource-telemetry.json
57
+ */
58
+ export declare function getTelemetryFilePath(): string;
49
59
  //# sourceMappingURL=cursor-paths.d.ts.map
@@ -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"}
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"}
@@ -47,6 +47,7 @@ exports.CURSOR_TYPE_DIRS = void 0;
47
47
  exports.getCursorRootDir = getCursorRootDir;
48
48
  exports.getCursorTypeDir = getCursorTypeDir;
49
49
  exports.getCursorResourcePath = getCursorResourcePath;
50
+ exports.getTelemetryFilePath = getTelemetryFilePath;
50
51
  const os = __importStar(require("os"));
51
52
  const path = __importStar(require("path"));
52
53
  /** Supported Cursor resource types and their directory names. */
@@ -113,4 +114,16 @@ function getCursorTypeDir(resourceType) {
113
114
  function getCursorResourcePath(resourceType, resourceName) {
114
115
  return path.join(getCursorTypeDir(resourceType), resourceName);
115
116
  }
117
+ /**
118
+ * Returns the path to the local AI resource telemetry file.
119
+ *
120
+ * Stored at the Cursor root level (not inside a resource-type subdirectory)
121
+ * so it persists independently of individual resource installs/uninstalls.
122
+ *
123
+ * macOS / Linux : ~/.cursor/ai-resource-telemetry.json
124
+ * Windows : %APPDATA%\Cursor\User\ai-resource-telemetry.json
125
+ */
126
+ function getTelemetryFilePath() {
127
+ return path.join(getCursorRootDir(), 'ai-resource-telemetry.json');
128
+ }
116
129
  //# sourceMappingURL=cursor-paths.js.map
@@ -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;AAvED,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"}
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliotding/ai-agent-mcp",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
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",
package/src/api/client.ts CHANGED
@@ -23,11 +23,21 @@ class APIClient {
23
23
  },
24
24
  });
25
25
 
26
- // Request interceptor for authentication and logging
26
+ // Request interceptor for authentication and logging.
27
+ // Every request MUST carry a per-request Authorization header supplied by
28
+ // the caller via authConfig(userToken). If none is present the request is
29
+ // rejected immediately with a clear error so the caller knows they must
30
+ // configure their token in mcp.json under env.CSP_API_TOKEN.
27
31
  this.client.interceptors.request.use(
28
32
  (requestConfig) => {
29
- if (config.csp.apiToken) {
30
- requestConfig.headers.Authorization = `Bearer ${config.csp.apiToken}`;
33
+ if (!requestConfig.headers.Authorization) {
34
+ return Promise.reject(
35
+ new Error(
36
+ 'Authorization token is missing. ' +
37
+ 'Ensure the MCP server is connected via SSE with a valid Bearer token in the Authorization header. ' +
38
+ 'Check that your mcp.json has the correct "headers": {"Authorization": "Bearer <token>"} configured.'
39
+ )
40
+ );
31
41
  }
32
42
 
33
43
  // Enhanced request logging
@@ -115,6 +125,27 @@ class APIClient {
115
125
  );
116
126
  }
117
127
 
128
+ /**
129
+ * Build an AxiosRequestConfig that carries a per-request user token.
130
+ * Pass the result as the `config` argument to get/post/put/delete or merge it
131
+ * into any existing request config so that the caller's token overrides the
132
+ * server-level fallback set in the interceptor.
133
+ *
134
+ * Usage:
135
+ * await apiClient.get('/some/path', apiClient.authConfig(userToken));
136
+ * await apiClient.post('/some/path', body, apiClient.authConfig(userToken));
137
+ */
138
+ authConfig(token: string | undefined, extra?: AxiosRequestConfig): AxiosRequestConfig {
139
+ if (!token) return extra ?? {};
140
+ return {
141
+ ...extra,
142
+ headers: {
143
+ ...(extra?.headers ?? {}),
144
+ Authorization: `Bearer ${token}`,
145
+ },
146
+ };
147
+ }
148
+
118
149
  /**
119
150
  * Sanitize headers to hide sensitive information
120
151
  */
@@ -241,12 +272,19 @@ class APIClient {
241
272
 
242
273
  /**
243
274
  * Get subscription list
275
+ *
276
+ * @param params Query parameters for filtering subscriptions.
277
+ * @param userToken Per-request token from the caller's mcp.json configuration.
278
+ * When provided it overrides the server-level fallback token.
244
279
  */
245
- async getSubscriptions(params?: {
246
- scope?: 'general' | 'team' | 'user' | 'all';
247
- types?: string[];
248
- detail?: boolean; // Added: include detailed metadata
249
- }): Promise<{
280
+ async getSubscriptions(
281
+ params?: {
282
+ scope?: 'general' | 'team' | 'user' | 'all';
283
+ types?: string[];
284
+ detail?: boolean;
285
+ },
286
+ userToken?: string
287
+ ): Promise<{
250
288
  total: number;
251
289
  subscriptions: Array<{
252
290
  id: string;
@@ -281,27 +319,29 @@ class APIClient {
281
319
  };
282
320
  }>;
283
321
  };
284
- }>('/csp/api/resources/subscriptions', { params });
285
-
286
- // Extract data from CSP API response format
322
+ }>('/csp/api/resources/subscriptions', this.authConfig(userToken, { params }));
323
+
287
324
  if (!response.data) {
288
325
  throw new Error('Invalid API response: missing data field');
289
326
  }
290
-
327
+
291
328
  return response.data;
292
329
  }
293
330
 
294
331
  /**
295
332
  * Subscribe to resource
333
+ *
334
+ * @param userToken Per-request token from the caller's mcp.json configuration.
296
335
  */
297
336
  async subscribe(
298
- resourceIds: string[],
337
+ resourceIds: string[],
299
338
  autoSync = true,
300
- scope?: 'general' | 'team' | 'user' // Added: subscription scope
339
+ scope?: 'general' | 'team' | 'user',
340
+ userToken?: string
301
341
  ): Promise<{
302
342
  success: boolean;
303
- subscriptions: Array<{
304
- id: string;
343
+ subscriptions: Array<{
344
+ id: string;
305
345
  name: string;
306
346
  type: string;
307
347
  subscribed_at: string;
@@ -312,44 +352,39 @@ class APIClient {
312
352
  result: string;
313
353
  data: {
314
354
  success?: boolean;
315
- subscriptions: Array<{
316
- id: string;
355
+ subscriptions: Array<{
356
+ id: string;
317
357
  name: string;
318
358
  type: string;
319
359
  subscribed_at: string;
320
360
  }>;
321
361
  };
322
- }>('/csp/api/resources/subscriptions/add', {
323
- resource_ids: resourceIds,
324
- auto_sync: autoSync,
325
- scope,
326
- });
327
-
362
+ }>(
363
+ '/csp/api/resources/subscriptions/add',
364
+ { resource_ids: resourceIds, auto_sync: autoSync, scope },
365
+ this.authConfig(userToken)
366
+ );
367
+
328
368
  if (!response.data) {
329
369
  throw new Error('Invalid API response: missing data field');
330
370
  }
331
-
332
- return {
333
- success: true,
334
- subscriptions: response.data.subscriptions
335
- };
371
+
372
+ return { success: true, subscriptions: response.data.subscriptions };
336
373
  }
337
374
 
338
375
  /**
339
376
  * Unsubscribe from resource
377
+ *
378
+ * @param userToken Per-request token from the caller's mcp.json configuration.
340
379
  */
341
- async unsubscribe(resourceIds: string | string[]): Promise<void> {
342
- // Support batch unsubscribe
380
+ async unsubscribe(resourceIds: string | string[], userToken?: string): Promise<void> {
343
381
  const ids = Array.isArray(resourceIds) ? resourceIds : [resourceIds];
344
382
  const response = await this.delete<{
345
383
  code: number;
346
384
  result: string;
347
385
  data: { removed_count: number };
348
- }>('/csp/api/resources/subscriptions/remove', {
349
- data: { resource_ids: ids }
350
- });
351
-
352
- // Just validate response, no need to return anything
386
+ }>('/csp/api/resources/subscriptions/remove', this.authConfig(userToken, { data: { resource_ids: ids } }));
387
+
353
388
  if (!response.data) {
354
389
  throw new Error('Invalid API response: missing data field');
355
390
  }
@@ -357,15 +392,20 @@ class APIClient {
357
392
 
358
393
  /**
359
394
  * Search resources
395
+ *
396
+ * @param userToken Per-request token from the caller's mcp.json configuration.
360
397
  */
361
- async searchResources(params: {
362
- keyword: string;
363
- team?: string;
364
- type?: string;
365
- detail?: boolean; // Added: include detailed metadata
366
- page?: number; // Added: pagination
367
- page_size?: number; // Added: page size
368
- }): Promise<{
398
+ async searchResources(
399
+ params: {
400
+ keyword: string;
401
+ team?: string;
402
+ type?: string;
403
+ detail?: boolean;
404
+ page?: number;
405
+ page_size?: number;
406
+ },
407
+ userToken?: string
408
+ ): Promise<{
369
409
  total: number;
370
410
  page?: number;
371
411
  page_size?: number;
@@ -415,22 +455,21 @@ class APIClient {
415
455
  };
416
456
  }>;
417
457
  };
418
- }>('/csp/api/resources/search', { params });
419
-
420
- // Extract data from CSP API response format
458
+ }>('/csp/api/resources/search', this.authConfig(userToken, { params }));
459
+
421
460
  if (!response.data) {
422
461
  throw new Error('Invalid API response: missing data field');
423
462
  }
424
-
463
+
425
464
  return {
426
465
  total: response.data.total,
427
466
  page: response.data.page,
428
467
  page_size: response.data.page_size,
429
- results: response.data.results.map(r => ({
468
+ results: response.data.results.map((r) => ({
430
469
  ...r,
431
470
  score: r.score || 0,
432
- is_subscribed: r.is_subscribed || false
433
- }))
471
+ is_subscribed: r.is_subscribed || false,
472
+ })),
434
473
  };
435
474
  }
436
475
 
@@ -443,8 +482,13 @@ class APIClient {
443
482
  * files[].path is the relative path within the resource directory.
444
483
  * Single-file resources (command, rule) have exactly one element.
445
484
  * Multi-file resources (skill, mcp) have all their files included.
485
+ *
486
+ * @param userToken Per-request token from the caller's mcp.json configuration.
446
487
  */
447
- async downloadResource(resourceId: string): Promise<{
488
+ async downloadResource(
489
+ resourceId: string,
490
+ userToken?: string
491
+ ): Promise<{
448
492
  resource_id: string;
449
493
  name: string;
450
494
  type: string;
@@ -463,14 +507,19 @@ class APIClient {
463
507
  hash: string;
464
508
  files: Array<{ path: string; content: string }>;
465
509
  };
466
- }>(`/csp/api/resources/download/${resourceId}`);
510
+ }>(`/csp/api/resources/download/${resourceId}`, this.authConfig(userToken));
467
511
  return response.data;
468
512
  }
469
513
 
470
514
  /**
471
515
  * Get resource detail
516
+ *
517
+ * @param userToken Per-request token from the caller's mcp.json configuration.
472
518
  */
473
- async getResourceDetail(resourceId: string): Promise<{
519
+ async getResourceDetail(
520
+ resourceId: string,
521
+ userToken?: string
522
+ ): Promise<{
474
523
  id: string;
475
524
  name: string;
476
525
  type: string;
@@ -489,7 +538,7 @@ class APIClient {
489
538
  };
490
539
  download_url: string;
491
540
  }> {
492
- return this.get(`/csp/api/resources/${resourceId}`);
541
+ return this.get(`/csp/api/resources/${resourceId}`, this.authConfig(userToken));
493
542
  }
494
543
 
495
544
  /**
@@ -501,22 +550,29 @@ class APIClient {
501
550
  *
502
551
  * The server validates path traversal, total size (< 10 MB), and name conflicts.
503
552
  * All file types are supported — mcp packages may include .py, .js, package.json, etc.
553
+ *
554
+ * @param userToken Per-request token from the caller's mcp.json configuration.
504
555
  */
505
- async uploadResourceFiles(params: {
506
- type: string;
507
- name: string;
508
- files: Array<{ path: string; content: string }>;
509
- target_source?: string;
510
- force?: boolean;
511
- }): Promise<{
556
+ async uploadResourceFiles(
557
+ params: {
558
+ type: string;
559
+ name: string;
560
+ files: Array<{ path: string; content: string }>;
561
+ target_source?: string;
562
+ force?: boolean;
563
+ },
564
+ userToken?: string
565
+ ): Promise<{
512
566
  upload_id: string;
513
567
  status: string;
514
568
  expires_at: string;
515
569
  preview_url?: string;
516
570
  }> {
517
- const resp = await this.post<{ code: number; result: string; data: { upload_id: string; status: string; expires_at: string; preview_url?: string } }>(
518
- '/csp/api/resources/upload', params
519
- );
571
+ const resp = await this.post<{
572
+ code: number;
573
+ result: string;
574
+ data: { upload_id: string; status: string; expires_at: string; preview_url?: string };
575
+ }>('/csp/api/resources/upload', params, this.authConfig(userToken));
520
576
  return resp.data;
521
577
  }
522
578
 
@@ -526,23 +582,87 @@ class APIClient {
526
582
  * POST /csp/api/resources/finalize
527
583
  * Body: { upload_id, commit_message }
528
584
  * Response: { resource_id, version, url, commit_hash, download_url }
585
+ *
586
+ * @param userToken Per-request token from the caller's mcp.json configuration.
529
587
  */
530
- async finalizeResourceUpload(uploadId: string, commitMessage: string): Promise<{
588
+ async finalizeResourceUpload(
589
+ uploadId: string,
590
+ commitMessage: string,
591
+ userToken?: string
592
+ ): Promise<{
531
593
  resource_id: string;
532
594
  version?: string;
533
595
  url?: string;
534
596
  commit_hash?: string;
535
597
  download_url?: string;
536
598
  }> {
537
- const resp = await this.post<{ code: number; result: string; data: { resource_id: string; version?: string; url?: string; commit_hash?: string; download_url?: string } }>(
538
- '/csp/api/resources/finalize', {
539
- upload_id: uploadId,
540
- commit_message: commitMessage,
541
- }
599
+ const resp = await this.post<{
600
+ code: number;
601
+ result: string;
602
+ data: {
603
+ resource_id: string;
604
+ version?: string;
605
+ url?: string;
606
+ commit_hash?: string;
607
+ download_url?: string;
608
+ };
609
+ }>(
610
+ '/csp/api/resources/finalize',
611
+ { upload_id: uploadId, commit_message: commitMessage },
612
+ this.authConfig(userToken)
542
613
  );
543
614
  return resp.data;
544
615
  }
545
616
 
617
+ /**
618
+ * Report AI resource usage telemetry to the server.
619
+ *
620
+ * POST /csp/api/resources/telemetry
621
+ * Body: { client_version, reported_at, events[], subscribed_rules[], configured_mcps[] }
622
+ *
623
+ * Called by TelemetryManager.flush() every ~10 seconds and on reconnect.
624
+ * Throws on non-2xx so the caller can apply retry logic.
625
+ *
626
+ * jira_id in each event entry is optional — it is only present when the user
627
+ * explicitly passed a Jira ID during the Prompt invocation.
628
+ *
629
+ * @param payload Telemetry report payload built by TelemetryManager
630
+ * @param userToken Per-request Bearer token from the caller's mcp.json configuration
631
+ */
632
+ async reportTelemetry(
633
+ payload: {
634
+ client_version: string;
635
+ reported_at: string;
636
+ events: Array<{
637
+ resource_id: string;
638
+ resource_type: string;
639
+ resource_name: string;
640
+ invocation_count: number;
641
+ first_invoked_at: string;
642
+ last_invoked_at: string;
643
+ /** Optional Jira Issue ID (e.g. "PROJ-12345"). Absent when not provided. */
644
+ jira_id?: string;
645
+ }>;
646
+ subscribed_rules: Array<{
647
+ resource_id: string;
648
+ resource_name: string;
649
+ subscribed_at: string;
650
+ }>;
651
+ configured_mcps: Array<{
652
+ resource_id: string;
653
+ resource_name: string;
654
+ configured_at: string;
655
+ }>;
656
+ },
657
+ userToken: string
658
+ ): Promise<void> {
659
+ await this.post<{ code: number; result: string; data: unknown }>(
660
+ '/csp/api/resources/telemetry',
661
+ payload,
662
+ this.authConfig(userToken)
663
+ );
664
+ }
665
+
546
666
  /**
547
667
  * @deprecated Use uploadResourceFiles() + finalizeResourceUpload() instead.
548
668
  */
@@ -69,6 +69,12 @@ const defaultPermissions: ToolPermission[] = [
69
69
  allowedGroups: ['*'],
70
70
  requiredPermission: PermissionLevel.WRITE,
71
71
  },
72
+ // track_usage - internal telemetry tool, always allowed for all authenticated users
73
+ {
74
+ tool: 'track_usage',
75
+ allowedGroups: ['*'],
76
+ requiredPermission: PermissionLevel.WRITE,
77
+ },
72
78
  ];
73
79
 
74
80
  /**
@@ -46,6 +46,12 @@ export interface Config {
46
46
  http?: {
47
47
  host: string;
48
48
  port: number;
49
+ /** URL path prefix when the server runs behind a reverse proxy sub-path.
50
+ * e.g. HTTP_BASE_PATH=/csp-agent → SSE at /csp-agent/sse
51
+ * → messages POST to /csp-agent/message
52
+ * Leave empty (default) for direct / root-path deployments.
53
+ */
54
+ basePath: string;
49
55
  };
50
56
 
51
57
  // Session (for SSE transport)
@@ -56,7 +62,10 @@ export interface Config {
56
62
  // CSP API
57
63
  csp: {
58
64
  apiBaseUrl: string;
59
- apiToken: string;
65
+ // NOTE: No apiToken here. The user token comes from mcp.json env.CSP_API_TOKEN,
66
+ // which Cursor injects into the process environment at startup. Each tool call
67
+ // receives it via the user_token argument; telemetry reads process.env.CSP_API_TOKEN
68
+ // directly. Storing it in config would encourage incorrect singleton-token patterns.
60
69
  timeout: number;
61
70
  };
62
71
 
@@ -140,9 +149,6 @@ export function loadConfig(): Config {
140
149
  const logLevel = (process.env.LOG_LEVEL || 'info') as Config['logLevel'];
141
150
  const transportMode = (process.env.TRANSPORT_MODE || 'stdio') as 'stdio' | 'sse';
142
151
 
143
- // Debug: Log CSP_API_TOKEN to verify it was loaded
144
- console.log(`🔑 CSP_API_TOKEN from env: ${process.env.CSP_API_TOKEN ? process.env.CSP_API_TOKEN.substring(0, 20) + '...' : 'NOT SET'}`);
145
-
146
152
  return {
147
153
  nodeEnv,
148
154
  port: getEnvNumber('PORT', 5090),
@@ -155,6 +161,7 @@ export function loadConfig(): Config {
155
161
  http: transportMode === 'sse' ? {
156
162
  host: getEnv('HTTP_HOST', '0.0.0.0'),
157
163
  port: getEnvNumber('HTTP_PORT', 3000),
164
+ basePath: getEnv('HTTP_BASE_PATH', ''),
158
165
  } : undefined,
159
166
 
160
167
  session: transportMode === 'sse' ? {
@@ -163,7 +170,6 @@ export function loadConfig(): Config {
163
170
 
164
171
  csp: {
165
172
  apiBaseUrl: getEnv('CSP_API_BASE_URL', 'https://csp.example.com'),
166
- apiToken: getEnv('CSP_API_TOKEN', 'test-token-12345'),
167
173
  timeout: getEnvNumber('CSP_API_TIMEOUT', 30000),
168
174
  },
169
175
 
package/src/index.ts CHANGED
@@ -10,6 +10,8 @@ import { startLogCleanupSchedule, stopLogCleanupSchedule } from './utils/log-cle
10
10
  import { startServer, stopServer } from './server';
11
11
  import { stopCacheCleanup } from './auth/token-validator';
12
12
  import { sessionManager } from './session/manager';
13
+ import { telemetry } from './telemetry/index.js';
14
+ import { apiClient } from './api/client.js';
13
15
 
14
16
  // Global error handlers
15
17
  process.on('uncaughtException', (error: Error) => {
@@ -52,11 +54,21 @@ async function main() {
52
54
  // Start log cleanup scheduler
53
55
  const cleanupTimer = startLogCleanupSchedule();
54
56
 
57
+ // Wire up telemetry reporting (inject API client to avoid circular import)
58
+ telemetry.configure(
59
+ (payload, token) => apiClient.reportTelemetry(payload, token),
60
+ () => process.env.CSP_API_TOKEN
61
+ );
62
+
55
63
  try {
56
64
  // Start MCP Server
57
65
  await startServer();
58
66
 
59
67
  logger.info({ port: config.port }, `✅ CSP AI Agent MCP Server started successfully`);
68
+
69
+ // Start periodic telemetry flush (every 10 seconds)
70
+ telemetry.startPeriodicFlush(10_000);
71
+ logger.info('Telemetry flush scheduler started (interval: 10s)');
60
72
  } catch (error) {
61
73
  logger.error({ error }, 'Failed to start server');
62
74
  stopLogCleanupSchedule(cleanupTimer);
@@ -110,6 +122,12 @@ async function main() {
110
122
  stopCacheCleanup();
111
123
  logger.info('Token cache cleanup stopped');
112
124
 
125
+ // Stop telemetry scheduler and perform final flush
126
+ telemetry.stopPeriodicFlush();
127
+ logger.info('Telemetry scheduler stopped, performing final flush...');
128
+ await telemetry.flush();
129
+ logger.info('Final telemetry flush completed');
130
+
113
131
  // Phase 4: Flush logs
114
132
  logger.info('Phase 4: Flushing logs...');
115
133