@dcyfr/ai 1.0.2 → 1.0.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 (91) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +27 -1
  3. package/README.md +359 -23
  4. package/bin/cli.js +12 -0
  5. package/bin/tui/config-wizard.js +107 -0
  6. package/bin/tui/validation-dashboard.js +123 -0
  7. package/bin/tui.js +259 -0
  8. package/dist/ai/agents/agent-loader.d.ts.map +1 -1
  9. package/dist/ai/agents/agent-loader.js +4 -2
  10. package/dist/ai/agents/agent-loader.js.map +1 -1
  11. package/dist/ai/index.d.ts +2 -0
  12. package/dist/ai/index.d.ts.map +1 -1
  13. package/dist/ai/index.js +2 -0
  14. package/dist/ai/index.js.map +1 -1
  15. package/dist/ai/mcp/index.d.ts +14 -2
  16. package/dist/ai/mcp/index.d.ts.map +1 -1
  17. package/dist/ai/mcp/index.js +11 -1
  18. package/dist/ai/mcp/index.js.map +1 -1
  19. package/dist/ai/mcp/servers/analytics/index.d.ts +19 -0
  20. package/dist/ai/mcp/servers/analytics/index.d.ts.map +1 -0
  21. package/dist/ai/mcp/servers/analytics/index.js +556 -0
  22. package/dist/ai/mcp/servers/analytics/index.js.map +1 -0
  23. package/dist/ai/mcp/servers/content-manager/content-provider.d.ts +61 -0
  24. package/dist/ai/mcp/servers/content-manager/content-provider.d.ts.map +1 -0
  25. package/dist/ai/mcp/servers/content-manager/content-provider.js +8 -0
  26. package/dist/ai/mcp/servers/content-manager/content-provider.js.map +1 -0
  27. package/dist/ai/mcp/servers/content-manager/index.d.ts +19 -0
  28. package/dist/ai/mcp/servers/content-manager/index.d.ts.map +1 -0
  29. package/dist/ai/mcp/servers/content-manager/index.js +236 -0
  30. package/dist/ai/mcp/servers/content-manager/index.js.map +1 -0
  31. package/dist/ai/mcp/servers/design-tokens/index.d.ts +19 -0
  32. package/dist/ai/mcp/servers/design-tokens/index.d.ts.map +1 -0
  33. package/dist/ai/mcp/servers/design-tokens/index.js +422 -0
  34. package/dist/ai/mcp/servers/design-tokens/index.js.map +1 -0
  35. package/dist/ai/mcp/servers/design-tokens/token-provider.d.ts +59 -0
  36. package/dist/ai/mcp/servers/design-tokens/token-provider.d.ts.map +1 -0
  37. package/dist/ai/mcp/servers/design-tokens/token-provider.js +8 -0
  38. package/dist/ai/mcp/servers/design-tokens/token-provider.js.map +1 -0
  39. package/dist/ai/mcp/servers/promptintel/index.d.ts +19 -0
  40. package/dist/ai/mcp/servers/promptintel/index.d.ts.map +1 -0
  41. package/dist/ai/mcp/servers/promptintel/index.js +323 -0
  42. package/dist/ai/mcp/servers/promptintel/index.js.map +1 -0
  43. package/dist/ai/mcp/servers/shared/cache.d.ts +62 -0
  44. package/dist/ai/mcp/servers/shared/cache.d.ts.map +1 -0
  45. package/dist/ai/mcp/servers/shared/cache.js +117 -0
  46. package/dist/ai/mcp/servers/shared/cache.js.map +1 -0
  47. package/dist/ai/mcp/servers/shared/promptintel-client.d.ts +53 -0
  48. package/dist/ai/mcp/servers/shared/promptintel-client.d.ts.map +1 -0
  49. package/dist/ai/mcp/servers/shared/promptintel-client.js +185 -0
  50. package/dist/ai/mcp/servers/shared/promptintel-client.js.map +1 -0
  51. package/dist/ai/mcp/servers/shared/promptintel-types.d.ts +85 -0
  52. package/dist/ai/mcp/servers/shared/promptintel-types.d.ts.map +1 -0
  53. package/dist/ai/mcp/servers/shared/promptintel-types.js +7 -0
  54. package/dist/ai/mcp/servers/shared/promptintel-types.js.map +1 -0
  55. package/dist/ai/mcp/servers/shared/rate-limiter.d.ts +54 -0
  56. package/dist/ai/mcp/servers/shared/rate-limiter.d.ts.map +1 -0
  57. package/dist/ai/mcp/servers/shared/rate-limiter.js +122 -0
  58. package/dist/ai/mcp/servers/shared/rate-limiter.js.map +1 -0
  59. package/dist/ai/mcp/servers/shared/redis-client.d.ts +54 -0
  60. package/dist/ai/mcp/servers/shared/redis-client.d.ts.map +1 -0
  61. package/dist/ai/mcp/servers/shared/redis-client.js +225 -0
  62. package/dist/ai/mcp/servers/shared/redis-client.js.map +1 -0
  63. package/dist/ai/mcp/servers/shared/types.d.ts +292 -0
  64. package/dist/ai/mcp/servers/shared/types.d.ts.map +1 -0
  65. package/dist/ai/mcp/servers/shared/types.js +6 -0
  66. package/dist/ai/mcp/servers/shared/types.js.map +1 -0
  67. package/dist/ai/mcp/servers/shared/utils.d.ts +41 -0
  68. package/dist/ai/mcp/servers/shared/utils.d.ts.map +1 -0
  69. package/dist/ai/mcp/servers/shared/utils.js +183 -0
  70. package/dist/ai/mcp/servers/shared/utils.js.map +1 -0
  71. package/dist/ai/memory/config.d.ts +87 -0
  72. package/dist/ai/memory/config.d.ts.map +1 -0
  73. package/dist/ai/memory/config.js +154 -0
  74. package/dist/ai/memory/config.js.map +1 -0
  75. package/dist/ai/memory/dcyfr-memory.d.ts +63 -0
  76. package/dist/ai/memory/dcyfr-memory.d.ts.map +1 -0
  77. package/dist/ai/memory/dcyfr-memory.js +270 -0
  78. package/dist/ai/memory/dcyfr-memory.js.map +1 -0
  79. package/dist/ai/memory/index.d.ts +15 -0
  80. package/dist/ai/memory/index.d.ts.map +1 -0
  81. package/dist/ai/memory/index.js +15 -0
  82. package/dist/ai/memory/index.js.map +1 -0
  83. package/dist/ai/memory/mem0-client.d.ts +108 -0
  84. package/dist/ai/memory/mem0-client.d.ts.map +1 -0
  85. package/dist/ai/memory/mem0-client.js +166 -0
  86. package/dist/ai/memory/mem0-client.js.map +1 -0
  87. package/dist/ai/memory/types.d.ts +175 -0
  88. package/dist/ai/memory/types.d.ts.map +1 -0
  89. package/dist/ai/memory/types.js +10 -0
  90. package/dist/ai/memory/types.js.map +1 -0
  91. package/package.json +46 -8
@@ -0,0 +1,556 @@
1
+ /**
2
+ * Analytics MCP Server
3
+ * Provides AI assistants with direct access to Redis analytics data
4
+ *
5
+ * Tools:
6
+ * - analytics:getPageViews - Query page view data
7
+ * - analytics:getTrending - Find trending content
8
+ * - analytics:getEngagement - Query interaction metrics
9
+ * - analytics:searchActivity - Search activity logs
10
+ * - analytics:getMilestones - List achievement milestones
11
+ *
12
+ * Resources:
13
+ * - analytics://recent - Last 24h metrics
14
+ * - analytics://top-pages - Most viewed pages
15
+ * - analytics://milestones/production - Production milestones
16
+ * - analytics://engagement/summary - Overall engagement stats
17
+ */
18
+ import { FastMCP } from 'fastmcp';
19
+ import { z } from 'zod';
20
+ import { redis } from '../shared/redis-client.js';
21
+ import { filterProductionData, warnProductionFallback, isWithinTimeRange, sortByProperty, limitResults, handleToolError, logToolExecution, measurePerformance, getTimeRangeMs, } from '../shared/utils.js';
22
+ import { analyticsCache } from '../shared/cache.js';
23
+ // ============================================================================
24
+ // Server Configuration
25
+ // ============================================================================
26
+ const server = new FastMCP({
27
+ name: 'dcyfr-analytics',
28
+ version: '1.0.0',
29
+ instructions: 'Provides access to dcyfr-labs analytics data from Redis. Use these tools to query page views, trending content, engagement metrics, and milestones. All data is environment-aware (filters test data in production).',
30
+ });
31
+ // ============================================================================
32
+ // Tool 1: Get Page Views
33
+ // ============================================================================
34
+ server.addTool({
35
+ name: 'analytics:getPageViews',
36
+ description: 'Get page view analytics for a specific path or all pages. Returns view count and optional trend data.',
37
+ parameters: z.object({
38
+ path: z.string().optional().describe('Page path (e.g., /blog, /work)'),
39
+ timeRange: z
40
+ .enum(['24h', '7d', '30d', 'all'])
41
+ .optional()
42
+ .default('7d')
43
+ .describe('Time range for analytics'),
44
+ }),
45
+ annotations: {
46
+ readOnlyHint: true,
47
+ openWorldHint: false,
48
+ },
49
+ execute: async (args, { log }) => {
50
+ try {
51
+ const { result, durationMs } = await measurePerformance(async () => {
52
+ const cacheKey = `pageviews:${args.path || 'all'}:${args.timeRange}`;
53
+ const cached = analyticsCache.get(cacheKey);
54
+ if (cached) {
55
+ log.info('Returning cached page views');
56
+ return cached;
57
+ }
58
+ // Query Redis for page views using actual key pattern: views:post:*
59
+ const keys = await redis.keys('views:post:*');
60
+ // Filter out daily tracking keys (views:post:{id}:day:{date})
61
+ const baseKeys = keys.filter((key) => !key.includes(':day:'));
62
+ if (!baseKeys || baseKeys.length === 0) {
63
+ warnProductionFallback('views:post:*');
64
+ return {
65
+ path: args.path || 'all',
66
+ views: 0,
67
+ timeRange: args.timeRange,
68
+ message: 'No analytics data available',
69
+ };
70
+ }
71
+ let data;
72
+ if (args.path) {
73
+ // Try to find a matching key for the specific path
74
+ // Path could be post slug or full path
75
+ const matchingKey = baseKeys.find((k) => k.includes(args.path));
76
+ if (matchingKey) {
77
+ const views = parseInt((await redis.get(matchingKey)) || '0', 10);
78
+ data = {
79
+ path: args.path,
80
+ views,
81
+ timeRange: args.timeRange || '7d',
82
+ };
83
+ }
84
+ else {
85
+ data = {
86
+ path: args.path,
87
+ views: 0,
88
+ timeRange: args.timeRange || '7d',
89
+ };
90
+ }
91
+ }
92
+ else {
93
+ // Sum all views across all posts
94
+ let totalViews = 0;
95
+ for (const key of baseKeys) {
96
+ const value = await redis.get(key);
97
+ totalViews += parseInt(value || '0', 10);
98
+ }
99
+ data = {
100
+ path: 'all',
101
+ views: totalViews,
102
+ timeRange: args.timeRange || '7d',
103
+ };
104
+ }
105
+ analyticsCache.set(cacheKey, data, 60000); // 1 minute cache
106
+ return data;
107
+ }, 'getPageViews');
108
+ logToolExecution('analytics:getPageViews', args, true, durationMs);
109
+ return JSON.stringify(result, null, 2);
110
+ }
111
+ catch (error) {
112
+ logToolExecution('analytics:getPageViews', args, false);
113
+ return handleToolError(error);
114
+ }
115
+ },
116
+ });
117
+ // ============================================================================
118
+ // Tool 2: Get Trending Content
119
+ // ============================================================================
120
+ server.addTool({
121
+ name: 'analytics:getTrending',
122
+ description: 'Get trending content based on page views. Returns top pages sorted by views.',
123
+ parameters: z.object({
124
+ limit: z.number().optional().default(10).describe('Maximum number of results to return'),
125
+ timeRange: z
126
+ .enum(['24h', '7d', '30d', 'all'])
127
+ .optional()
128
+ .default('7d')
129
+ .describe('Time range for trending analysis'),
130
+ }),
131
+ annotations: {
132
+ readOnlyHint: true,
133
+ openWorldHint: false,
134
+ },
135
+ execute: async (args, { log }) => {
136
+ try {
137
+ const { result, durationMs } = await measurePerformance(async () => {
138
+ const cacheKey = `trending:${args.timeRange}:${args.limit}`;
139
+ const cached = analyticsCache.get(cacheKey);
140
+ if (cached) {
141
+ log.info('Returning cached trending content');
142
+ return cached;
143
+ }
144
+ // Query Redis for all post views using actual key pattern: views:post:*
145
+ const keys = await redis.keys('views:post:*');
146
+ // Filter out daily tracking keys (views:post:{id}:day:{date})
147
+ const baseKeys = keys.filter((key) => !key.includes(':day:'));
148
+ if (!baseKeys || baseKeys.length === 0) {
149
+ warnProductionFallback('views:post:*');
150
+ return [];
151
+ }
152
+ // Get all view counts and map to post IDs
153
+ const trendingItems = [];
154
+ for (const key of baseKeys) {
155
+ const postId = key.replace('views:post:', '');
156
+ const views = parseInt((await redis.get(key)) || '0', 10);
157
+ if (views > 0) {
158
+ trendingItems.push({
159
+ path: `/blog/${postId}`,
160
+ views,
161
+ rank: 0, // Will be set after sorting
162
+ });
163
+ }
164
+ }
165
+ const sorted = sortByProperty(trendingItems, 'views', 'desc');
166
+ const limited = limitResults(sorted, args.limit);
167
+ // Update ranks after sorting
168
+ limited.forEach((item, index) => {
169
+ item.rank = index + 1;
170
+ });
171
+ analyticsCache.set(cacheKey, limited, 60000); // 1 minute cache
172
+ return limited;
173
+ }, 'getTrending');
174
+ logToolExecution('analytics:getTrending', args, true, durationMs);
175
+ return JSON.stringify(result, null, 2);
176
+ }
177
+ catch (error) {
178
+ logToolExecution('analytics:getTrending', args, false);
179
+ return handleToolError(error);
180
+ }
181
+ },
182
+ });
183
+ // ============================================================================
184
+ // Tool 3: Get Engagement Metrics
185
+ // ============================================================================
186
+ server.addTool({
187
+ name: 'analytics:getEngagement',
188
+ description: 'Get engagement metrics (clicks, shares, interactions) from Redis. Filter by content type and time range.',
189
+ parameters: z.object({
190
+ contentType: z.string().optional().describe('Content type filter (e.g., blog, project, all)'),
191
+ timeRange: z
192
+ .enum(['1h', '24h', '7d', '30d', 'all'])
193
+ .optional()
194
+ .default('7d')
195
+ .describe('Time range for engagement data'),
196
+ }),
197
+ annotations: {
198
+ readOnlyHint: true,
199
+ openWorldHint: false,
200
+ },
201
+ execute: async (args, { log }) => {
202
+ try {
203
+ const { result, durationMs } = await measurePerformance(async () => {
204
+ const cacheKey = `engagement:${args.contentType || 'all'}:${args.timeRange}`;
205
+ const cached = analyticsCache.get(cacheKey);
206
+ if (cached) {
207
+ log.info('Returning cached engagement metrics');
208
+ return cached;
209
+ }
210
+ // Query Redis for likes and bookmarks using all content type patterns
211
+ const [postLikes, projectLikes, activityLikes, postBookmarks, projectBookmarks, activityBookmarks,] = await Promise.all([
212
+ redis.keys('likes:post:*'),
213
+ redis.keys('likes:project:*'),
214
+ redis.keys('likes:activity:*'),
215
+ redis.keys('bookmarks:post:*'),
216
+ redis.keys('bookmarks:project:*'),
217
+ redis.keys('bookmarks:activity:*'),
218
+ ]);
219
+ const likeKeys = [...postLikes, ...projectLikes, ...activityLikes];
220
+ const bookmarkKeys = [...postBookmarks, ...projectBookmarks, ...activityBookmarks];
221
+ if ((!likeKeys || likeKeys.length === 0) && (!bookmarkKeys || bookmarkKeys.length === 0)) {
222
+ warnProductionFallback('likes:* and bookmarks:*');
223
+ return {
224
+ totalLikes: 0,
225
+ totalBookmarks: 0,
226
+ totalInteractions: 0,
227
+ timeRange: args.timeRange,
228
+ contentType: args.contentType || 'all',
229
+ };
230
+ }
231
+ // Sum all likes
232
+ let totalLikes = 0;
233
+ for (const key of likeKeys) {
234
+ const value = await redis.get(key);
235
+ totalLikes += parseInt(value || '0', 10);
236
+ }
237
+ // Sum all bookmarks
238
+ let totalBookmarks = 0;
239
+ for (const key of bookmarkKeys) {
240
+ const value = await redis.get(key);
241
+ totalBookmarks += parseInt(value || '0', 10);
242
+ }
243
+ // Aggregate engagement metrics
244
+ const metrics = {
245
+ totalLikes,
246
+ totalBookmarks,
247
+ totalInteractions: totalLikes + totalBookmarks,
248
+ timeRange: args.timeRange,
249
+ contentType: args.contentType || 'all',
250
+ };
251
+ analyticsCache.set(cacheKey, metrics, 60000); // 1 minute cache
252
+ return metrics;
253
+ }, 'getEngagement');
254
+ logToolExecution('analytics:getEngagement', args, true, durationMs);
255
+ return JSON.stringify(result, null, 2);
256
+ }
257
+ catch (error) {
258
+ logToolExecution('analytics:getEngagement', args, false);
259
+ return handleToolError(error);
260
+ }
261
+ },
262
+ });
263
+ // ============================================================================
264
+ // Tool 4: Search Activity Logs
265
+ // ============================================================================
266
+ server.addTool({
267
+ name: 'analytics:searchActivity',
268
+ description: 'Search activity logs by keyword, type, or date range. Returns matching activity entries.',
269
+ parameters: z.object({
270
+ query: z.string().optional().describe('Search query keyword'),
271
+ activityType: z
272
+ .string()
273
+ .optional()
274
+ .describe('Activity type filter (e.g., pageview, click, share)'),
275
+ timeRange: z
276
+ .enum(['1h', '24h', '7d', '30d', 'all'])
277
+ .optional()
278
+ .default('24h')
279
+ .describe('Time range for activity search'),
280
+ limit: z.number().optional().default(50).describe('Maximum number of results'),
281
+ }),
282
+ annotations: {
283
+ readOnlyHint: true,
284
+ openWorldHint: false,
285
+ },
286
+ execute: async (args, { log }) => {
287
+ try {
288
+ const { result, durationMs } = await measurePerformance(async () => {
289
+ const cacheKey = `activity:${args.query || ''}:${args.activityType || ''}:${args.timeRange}`;
290
+ const cached = analyticsCache.get(cacheKey);
291
+ if (cached) {
292
+ log.info('Returning cached activity search results');
293
+ return cached;
294
+ }
295
+ // Query Redis for view history using actual key pattern: views:history:post:*
296
+ // This returns sorted sets with timestamps of views
297
+ const historyKeys = await redis.keys('views:history:post:*');
298
+ if (!historyKeys || historyKeys.length === 0) {
299
+ warnProductionFallback('views:history:post:*');
300
+ return [];
301
+ }
302
+ // Get recent activity from view history sorted sets
303
+ const activities = [];
304
+ for (const key of historyKeys) {
305
+ const postId = key.replace('views:history:post:', '');
306
+ // Get recent entries from sorted set (within time range)
307
+ const now = Date.now();
308
+ const timeRangeMs = getTimeRangeMs(args.timeRange || '24h');
309
+ const minScore = now - timeRangeMs;
310
+ // zrange with byScore option returns members with scores between min and max (replaces deprecated zrangebyscore)
311
+ const entries = await redis.zrange(key, minScore, now, { byScore: true });
312
+ for (const entry of entries) {
313
+ const timestamp = parseInt(entry, 10);
314
+ activities.push({
315
+ type: 'pageview',
316
+ path: `/blog/${postId}`,
317
+ timestamp,
318
+ data: { postId },
319
+ });
320
+ }
321
+ }
322
+ // Filter by activity type
323
+ if (args.activityType && args.activityType !== 'pageview') {
324
+ // Currently only pageview activity is tracked
325
+ return [];
326
+ }
327
+ // Filter by query keyword
328
+ let filtered = activities;
329
+ if (args.query) {
330
+ const queryLower = args.query.toLowerCase();
331
+ filtered = activities.filter((activity) => activity.path.toLowerCase().includes(queryLower) ||
332
+ activity.data.postId?.toString().toLowerCase().includes(queryLower));
333
+ }
334
+ // Sort by timestamp descending
335
+ filtered.sort((a, b) => b.timestamp - a.timestamp);
336
+ // Limit results
337
+ const limited = limitResults(filtered, args.limit);
338
+ analyticsCache.set(cacheKey, limited, 60000); // 1 minute cache
339
+ return limited;
340
+ }, 'searchActivity');
341
+ logToolExecution('analytics:searchActivity', args, true, durationMs);
342
+ return JSON.stringify(result, null, 2);
343
+ }
344
+ catch (error) {
345
+ logToolExecution('analytics:searchActivity', args, false);
346
+ return handleToolError(error);
347
+ }
348
+ },
349
+ });
350
+ // ============================================================================
351
+ // Tool 5: Get Milestones
352
+ // ============================================================================
353
+ server.addTool({
354
+ name: 'analytics:getMilestones',
355
+ description: 'Get achievement milestones. Filters test data in production environments.',
356
+ parameters: z.object({
357
+ includeTest: z
358
+ .boolean()
359
+ .optional()
360
+ .default(false)
361
+ .describe('Include test milestones (ignored in production)'),
362
+ }),
363
+ annotations: {
364
+ readOnlyHint: true,
365
+ openWorldHint: false,
366
+ },
367
+ execute: async (args, { log }) => {
368
+ try {
369
+ const { result, durationMs } = await measurePerformance(async () => {
370
+ const cacheKey = `milestones:${args.includeTest}`;
371
+ const cached = analyticsCache.get(cacheKey);
372
+ if (cached) {
373
+ log.info('Returning cached milestones');
374
+ return cached;
375
+ }
376
+ const milestonesData = await redis.get('analytics:milestones');
377
+ if (!milestonesData) {
378
+ warnProductionFallback('analytics:milestones');
379
+ return [];
380
+ }
381
+ const allMilestones = JSON.parse(milestonesData);
382
+ // Filter production data (automatically excludes test data in prod)
383
+ const filtered = filterProductionData(allMilestones);
384
+ analyticsCache.set(cacheKey, filtered, 300000); // 5 minute cache
385
+ return filtered;
386
+ }, 'getMilestones');
387
+ logToolExecution('analytics:getMilestones', args, true, durationMs);
388
+ return JSON.stringify(result, null, 2);
389
+ }
390
+ catch (error) {
391
+ logToolExecution('analytics:getMilestones', args, false);
392
+ return handleToolError(error);
393
+ }
394
+ },
395
+ });
396
+ // ============================================================================
397
+ // Resource 1: Recent Metrics (Last 24h)
398
+ // ============================================================================
399
+ server.addResource({
400
+ uri: 'analytics://recent',
401
+ name: 'Recent Analytics (24h)',
402
+ mimeType: 'application/json',
403
+ description: 'Summary of analytics from the last 24 hours',
404
+ async load() {
405
+ try {
406
+ const cacheKey = 'resource:recent';
407
+ const cached = analyticsCache.get(cacheKey);
408
+ if (cached) {
409
+ return { text: JSON.stringify(cached, null, 2) };
410
+ }
411
+ // Query actual Redis keys
412
+ const [allViewKeys, milestonesData] = await Promise.all([
413
+ redis.keys('views:post:*'),
414
+ redis.get('analytics:milestones'),
415
+ ]);
416
+ // Filter out daily tracking keys
417
+ const viewKeys = allViewKeys.filter((key) => !key.includes(':day:'));
418
+ // Sum all views
419
+ let totalViews = 0;
420
+ for (const key of viewKeys) {
421
+ const value = await redis.get(key);
422
+ totalViews += parseInt(value || '0', 10);
423
+ }
424
+ const milestones = milestonesData ? JSON.parse(milestonesData) : [];
425
+ const recent24h = milestones.filter((m) => isWithinTimeRange(m.achievedAt, '24h'));
426
+ const summary = {
427
+ totalViews,
428
+ topPages: [],
429
+ recentActivity: [],
430
+ milestones: filterProductionData(recent24h),
431
+ generatedAt: Date.now(),
432
+ };
433
+ analyticsCache.set(cacheKey, summary, 60000); // 1 minute cache
434
+ return { text: JSON.stringify(summary, null, 2) };
435
+ }
436
+ catch (error) {
437
+ return { text: handleToolError(error) };
438
+ }
439
+ },
440
+ });
441
+ // ============================================================================
442
+ // Resource 2: Top Pages (Most Viewed)
443
+ // ============================================================================
444
+ server.addResource({
445
+ uri: 'analytics://top-pages',
446
+ name: 'Top Pages by Views',
447
+ mimeType: 'application/json',
448
+ description: 'Most viewed pages sorted by traffic',
449
+ async load() {
450
+ try {
451
+ const cacheKey = 'resource:top-pages';
452
+ const cached = analyticsCache.get(cacheKey);
453
+ if (cached) {
454
+ return { text: JSON.stringify(cached, null, 2) };
455
+ }
456
+ // Query actual Redis keys
457
+ const allViewKeys = await redis.keys('views:post:*');
458
+ const viewKeys = allViewKeys.filter((key) => !key.includes(':day:'));
459
+ if (!viewKeys || viewKeys.length === 0) {
460
+ return {
461
+ text: JSON.stringify({ message: 'No page view data available', pages: [] }, null, 2),
462
+ };
463
+ }
464
+ // Get all view counts
465
+ const pages = [];
466
+ for (const key of viewKeys) {
467
+ const postId = key.replace('views:post:', '');
468
+ const views = parseInt((await redis.get(key)) || '0', 10);
469
+ if (views > 0) {
470
+ pages.push({ path: `/blog/${postId}`, views });
471
+ }
472
+ }
473
+ const topPages = pages.sort((a, b) => b.views - a.views).slice(0, 20); // Top 20 pages
474
+ const result = {
475
+ topPages,
476
+ totalPages: pages.length,
477
+ generatedAt: Date.now(),
478
+ };
479
+ analyticsCache.set(cacheKey, result, 300000); // 5 minute cache
480
+ return { text: JSON.stringify(result, null, 2) };
481
+ }
482
+ catch (error) {
483
+ return { text: handleToolError(error) };
484
+ }
485
+ },
486
+ });
487
+ // ============================================================================
488
+ // Resource 3: Engagement Summary
489
+ // ============================================================================
490
+ server.addResource({
491
+ uri: 'analytics://engagement/summary',
492
+ name: 'Engagement Summary',
493
+ mimeType: 'application/json',
494
+ description: 'Overall engagement statistics and trends',
495
+ async load() {
496
+ try {
497
+ const cacheKey = 'resource:engagement-summary';
498
+ const cached = analyticsCache.get(cacheKey);
499
+ if (cached) {
500
+ return { text: JSON.stringify(cached, null, 2) };
501
+ }
502
+ // Query actual Redis keys for likes and bookmarks across all content types
503
+ const [postLikes, projectLikes, activityLikes, postBookmarks, projectBookmarks, activityBookmarks,] = await Promise.all([
504
+ redis.keys('likes:post:*'),
505
+ redis.keys('likes:project:*'),
506
+ redis.keys('likes:activity:*'),
507
+ redis.keys('bookmarks:post:*'),
508
+ redis.keys('bookmarks:project:*'),
509
+ redis.keys('bookmarks:activity:*'),
510
+ ]);
511
+ const likeKeys = [...postLikes, ...projectLikes, ...activityLikes];
512
+ const bookmarkKeys = [...postBookmarks, ...projectBookmarks, ...activityBookmarks];
513
+ if ((!likeKeys || likeKeys.length === 0) && (!bookmarkKeys || bookmarkKeys.length === 0)) {
514
+ return {
515
+ text: JSON.stringify({
516
+ message: 'No engagement data available',
517
+ totalLikes: 0,
518
+ totalBookmarks: 0,
519
+ totalInteractions: 0,
520
+ }, null, 2),
521
+ };
522
+ }
523
+ // Sum all likes
524
+ let totalLikes = 0;
525
+ for (const key of likeKeys) {
526
+ const value = await redis.get(key);
527
+ totalLikes += parseInt(value || '0', 10);
528
+ }
529
+ // Sum all bookmarks
530
+ let totalBookmarks = 0;
531
+ for (const key of bookmarkKeys) {
532
+ const value = await redis.get(key);
533
+ totalBookmarks += parseInt(value || '0', 10);
534
+ }
535
+ const summary = {
536
+ totalLikes,
537
+ totalBookmarks,
538
+ totalInteractions: totalLikes + totalBookmarks,
539
+ generatedAt: Date.now(),
540
+ };
541
+ analyticsCache.set(cacheKey, summary, 300000); // 5 minute cache
542
+ return { text: JSON.stringify(summary, null, 2) };
543
+ }
544
+ catch (error) {
545
+ return { text: handleToolError(error) };
546
+ }
547
+ },
548
+ });
549
+ // ============================================================================
550
+ // Start Server
551
+ // ============================================================================
552
+ server.start({
553
+ transportType: 'stdio',
554
+ });
555
+ console.warn('✅ Analytics MCP Server started (stdio mode)');
556
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/ai/mcp/servers/analytics/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * ContentProvider Interface
3
+ *
4
+ * Abstraction for content sources to decouple Content Manager MCP from dcyfr-labs.
5
+ * Implementations can read from filesystem, database, CMS, or any other source.
6
+ */
7
+ export interface ContentMetadata {
8
+ title: string;
9
+ description?: string;
10
+ date?: string;
11
+ tags?: string[];
12
+ category?: string;
13
+ published?: boolean;
14
+ wordCount?: number;
15
+ readingTime?: number;
16
+ }
17
+ export interface ContentItem {
18
+ filePath: string;
19
+ slug: string;
20
+ type: 'blog' | 'project';
21
+ metadata: ContentMetadata;
22
+ excerpt?: string;
23
+ body?: string;
24
+ }
25
+ export interface ContentSearchOptions {
26
+ query?: string;
27
+ tags?: string[];
28
+ category?: string;
29
+ limit?: number;
30
+ includeUnpublished?: boolean;
31
+ }
32
+ /**
33
+ * ContentProvider interface for abstracting content sources
34
+ */
35
+ export interface ContentProvider {
36
+ /**
37
+ * List all content items of a given type
38
+ */
39
+ listContent(type: 'blog' | 'project', options?: ContentSearchOptions): Promise<ContentItem[]>;
40
+ /**
41
+ * Get a specific content item by slug
42
+ */
43
+ getContent(slug: string, type: 'blog' | 'project'): Promise<ContentItem | null>;
44
+ /**
45
+ * Search content by query string
46
+ */
47
+ searchContent(query: string, type?: 'blog' | 'project'): Promise<ContentItem[]>;
48
+ /**
49
+ * Get all unique tags across content
50
+ */
51
+ getTags(type?: 'blog' | 'project'): Promise<string[]>;
52
+ /**
53
+ * Get content by tag
54
+ */
55
+ getContentByTag(tag: string, type?: 'blog' | 'project'): Promise<ContentItem[]>;
56
+ /**
57
+ * Get content by category
58
+ */
59
+ getContentByCategory(category: string, type?: 'blog' | 'project'): Promise<ContentItem[]>;
60
+ }
61
+ //# sourceMappingURL=content-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-provider.d.ts","sourceRoot":"","sources":["../../../../../packages/ai/mcp/servers/content-manager/content-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAE9F;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAEhF;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAEhF;;OAEG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEtD;;OAEG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAEhF;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;CAC3F"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * ContentProvider Interface
3
+ *
4
+ * Abstraction for content sources to decouple Content Manager MCP from dcyfr-labs.
5
+ * Implementations can read from filesystem, database, CMS, or any other source.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=content-provider.js.map