@crowley/rag-mcp 1.0.0
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.
- package/dist/api-client.d.ts +4 -0
- package/dist/api-client.js +19 -0
- package/dist/context-enrichment.d.ts +44 -0
- package/dist/context-enrichment.js +190 -0
- package/dist/formatters.d.ts +33 -0
- package/dist/formatters.js +70 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +109 -0
- package/dist/tool-registry.d.ts +20 -0
- package/dist/tool-registry.js +123 -0
- package/dist/tools/advanced.d.ts +9 -0
- package/dist/tools/advanced.js +315 -0
- package/dist/tools/agents.d.ts +8 -0
- package/dist/tools/agents.js +97 -0
- package/dist/tools/analytics.d.ts +9 -0
- package/dist/tools/analytics.js +261 -0
- package/dist/tools/architecture.d.ts +5 -0
- package/dist/tools/architecture.js +720 -0
- package/dist/tools/ask.d.ts +9 -0
- package/dist/tools/ask.js +256 -0
- package/dist/tools/cache.d.ts +5 -0
- package/dist/tools/cache.js +98 -0
- package/dist/tools/clustering.d.ts +9 -0
- package/dist/tools/clustering.js +251 -0
- package/dist/tools/confluence.d.ts +9 -0
- package/dist/tools/confluence.js +147 -0
- package/dist/tools/database.d.ts +5 -0
- package/dist/tools/database.js +429 -0
- package/dist/tools/feedback.d.ts +9 -0
- package/dist/tools/feedback.js +220 -0
- package/dist/tools/guidelines.d.ts +5 -0
- package/dist/tools/guidelines.js +146 -0
- package/dist/tools/indexing.d.ts +9 -0
- package/dist/tools/indexing.js +129 -0
- package/dist/tools/memory.d.ts +9 -0
- package/dist/tools/memory.js +565 -0
- package/dist/tools/pm.d.ts +9 -0
- package/dist/tools/pm.js +680 -0
- package/dist/tools/review.d.ts +8 -0
- package/dist/tools/review.js +213 -0
- package/dist/tools/search.d.ts +9 -0
- package/dist/tools/search.js +377 -0
- package/dist/tools/session.d.ts +10 -0
- package/dist/tools/session.js +386 -0
- package/dist/tools/suggestions.d.ts +9 -0
- package/dist/tools/suggestions.js +301 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.js +4 -0
- package/package.json +40 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics tools module - tool analytics, knowledge gaps, collection analytics,
|
|
3
|
+
* backups, and quantization.
|
|
4
|
+
*/
|
|
5
|
+
import { pct } from "../formatters.js";
|
|
6
|
+
/**
|
|
7
|
+
* Create the analytics tools module with project-specific descriptions.
|
|
8
|
+
*/
|
|
9
|
+
export function createAnalyticsTools(projectName) {
|
|
10
|
+
const tools = [
|
|
11
|
+
{
|
|
12
|
+
name: "get_tool_analytics",
|
|
13
|
+
description: `Get tool usage analytics for ${projectName}. Shows call counts, success rates, and performance.`,
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: "object",
|
|
16
|
+
properties: {},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "get_knowledge_gaps",
|
|
21
|
+
description: `Get knowledge gaps for ${projectName}. Shows queries that returned few or no results.`,
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "get_analytics",
|
|
29
|
+
description: `Get detailed analytics for a ${projectName} collection. Shows vectors, storage, language breakdown, and more.`,
|
|
30
|
+
inputSchema: {
|
|
31
|
+
type: "object",
|
|
32
|
+
properties: {
|
|
33
|
+
collectionName: {
|
|
34
|
+
type: "string",
|
|
35
|
+
description: "Collection name to get analytics for (e.g., 'codebase', 'docs', 'memory')",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
required: ["collectionName"],
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "backup_collection",
|
|
43
|
+
description: `Create a backup snapshot of a ${projectName} collection.`,
|
|
44
|
+
inputSchema: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
collectionName: {
|
|
48
|
+
type: "string",
|
|
49
|
+
description: "Collection name to backup",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
required: ["collectionName"],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: "list_backups",
|
|
57
|
+
description: `List backup snapshots for a ${projectName} collection.`,
|
|
58
|
+
inputSchema: {
|
|
59
|
+
type: "object",
|
|
60
|
+
properties: {
|
|
61
|
+
collectionName: {
|
|
62
|
+
type: "string",
|
|
63
|
+
description: "Collection name to list backups for",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
required: ["collectionName"],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "enable_quantization",
|
|
71
|
+
description: `Enable scalar quantization on a ${projectName} collection to reduce memory usage.`,
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: "object",
|
|
74
|
+
properties: {
|
|
75
|
+
collectionName: {
|
|
76
|
+
type: "string",
|
|
77
|
+
description: "Collection name to enable quantization on",
|
|
78
|
+
},
|
|
79
|
+
quantile: {
|
|
80
|
+
type: "number",
|
|
81
|
+
description: "Quantile for quantization (0-1, default: 0.99)",
|
|
82
|
+
default: 0.99,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
required: ["collectionName"],
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "get_platform_stats",
|
|
90
|
+
description: `Get cross-project platform statistics. Shows all projects, their collections, and aggregated metrics.`,
|
|
91
|
+
inputSchema: {
|
|
92
|
+
type: "object",
|
|
93
|
+
properties: {},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "get_prediction_stats",
|
|
98
|
+
description: `Get predictive loader stats for ${projectName}. Shows prediction accuracy, hit rates, and strategy breakdown.`,
|
|
99
|
+
inputSchema: {
|
|
100
|
+
type: "object",
|
|
101
|
+
properties: {
|
|
102
|
+
sessionId: {
|
|
103
|
+
type: "string",
|
|
104
|
+
description: "Session ID to get stats for. If omitted, returns aggregate stats.",
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
const handlers = {
|
|
111
|
+
get_tool_analytics: async (_args, ctx) => {
|
|
112
|
+
const response = await ctx.api.get("/api/tool-analytics");
|
|
113
|
+
const data = response.data;
|
|
114
|
+
let result = `## Tool Analytics\n\n`;
|
|
115
|
+
result += `- **Total Calls:** ${data.totalCalls ?? "N/A"}\n`;
|
|
116
|
+
result += `- **Success Rate:** ${data.successRate !== undefined ? pct(data.successRate) : "N/A"}\n`;
|
|
117
|
+
result += `- **Avg Duration:** ${data.avgDurationMs ? data.avgDurationMs + "ms" : "N/A"}\n\n`;
|
|
118
|
+
if (data.topTools && data.topTools.length > 0) {
|
|
119
|
+
result += `### Top Tools\n`;
|
|
120
|
+
for (const t of data.topTools) {
|
|
121
|
+
result += `- **${t.tool || t.name}**: ${t.count ?? t.calls} calls`;
|
|
122
|
+
if (t.avgDurationMs || t.avgDuration)
|
|
123
|
+
result += ` (avg ${t.avgDurationMs || t.avgDuration}ms)`;
|
|
124
|
+
result += "\n";
|
|
125
|
+
}
|
|
126
|
+
result += "\n";
|
|
127
|
+
}
|
|
128
|
+
if (data.errorsByTool && Object.keys(data.errorsByTool).length > 0) {
|
|
129
|
+
result += `### Errors by Tool\n`;
|
|
130
|
+
for (const [tool, count] of Object.entries(data.errorsByTool)) {
|
|
131
|
+
result += `- **${tool}**: ${count} errors\n`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
},
|
|
136
|
+
get_knowledge_gaps: async (_args, ctx) => {
|
|
137
|
+
const response = await ctx.api.get("/api/knowledge-gaps");
|
|
138
|
+
const data = response.data;
|
|
139
|
+
const queries = data.queries || data.gaps || data;
|
|
140
|
+
if (!queries || (Array.isArray(queries) && queries.length === 0)) {
|
|
141
|
+
return "No knowledge gaps identified.";
|
|
142
|
+
}
|
|
143
|
+
let result = `## Knowledge Gaps\n\n`;
|
|
144
|
+
result += `Queries with low or no results:\n\n`;
|
|
145
|
+
for (const q of Array.isArray(queries) ? queries : []) {
|
|
146
|
+
result += `- **"${q.query}"**`;
|
|
147
|
+
if (q.count)
|
|
148
|
+
result += ` (${q.count} times)`;
|
|
149
|
+
if (q.avgResultCount !== undefined)
|
|
150
|
+
result += ` - avg results: ${q.avgResultCount}`;
|
|
151
|
+
if (q.toolName)
|
|
152
|
+
result += ` [${q.toolName}]`;
|
|
153
|
+
result += "\n";
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
},
|
|
157
|
+
get_analytics: async (args, ctx) => {
|
|
158
|
+
const { collectionName } = args;
|
|
159
|
+
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
160
|
+
? collectionName
|
|
161
|
+
: `${ctx.collectionPrefix}${collectionName}`;
|
|
162
|
+
const response = await ctx.api.get(`/api/analytics/${fullName}`);
|
|
163
|
+
const data = response.data;
|
|
164
|
+
let result = `## Collection Analytics: ${collectionName}\n\n`;
|
|
165
|
+
result += `- **Vectors:** ${data.vectorCount ?? data.vectors ?? "N/A"}\n`;
|
|
166
|
+
result += `- **Files:** ${data.totalFiles ?? data.files ?? "N/A"}\n`;
|
|
167
|
+
result += `- **Segments:** ${data.segments ?? "N/A"}\n`;
|
|
168
|
+
result += `- **Optimizer:** ${data.optimizerStatus || data.optimizer || "N/A"}\n`;
|
|
169
|
+
result += `- **Quantization:** ${data.quantization || "none"}\n`;
|
|
170
|
+
result += `- **RAM Usage:** ${data.ramUsage || "N/A"}\n`;
|
|
171
|
+
result += `- **Disk Usage:** ${data.diskUsage || "N/A"}\n`;
|
|
172
|
+
if (data.languages && Object.keys(data.languages).length > 0) {
|
|
173
|
+
result += `\n### Language Breakdown\n`;
|
|
174
|
+
for (const [lang, count] of Object.entries(data.languages)) {
|
|
175
|
+
result += `- ${lang}: ${count} files\n`;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
result += `\n- **Last Indexed:** ${data.lastIndexed ? new Date(data.lastIndexed).toLocaleString() : "Never"}\n`;
|
|
179
|
+
return result;
|
|
180
|
+
},
|
|
181
|
+
backup_collection: async (args, ctx) => {
|
|
182
|
+
const { collectionName } = args;
|
|
183
|
+
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
184
|
+
? collectionName
|
|
185
|
+
: `${ctx.collectionPrefix}${collectionName}`;
|
|
186
|
+
const response = await ctx.api.post(`/api/collections/${fullName}/snapshots`);
|
|
187
|
+
const data = response.data;
|
|
188
|
+
let result = `## Backup Created\n\n`;
|
|
189
|
+
result += `- **Collection:** ${fullName}\n`;
|
|
190
|
+
result += `- **Snapshot:** ${data.name || data.snapshotName || "N/A"}\n`;
|
|
191
|
+
result += `- **Created:** ${data.createdAt ? new Date(data.createdAt).toLocaleString() : new Date().toLocaleString()}\n`;
|
|
192
|
+
return result;
|
|
193
|
+
},
|
|
194
|
+
list_backups: async (args, ctx) => {
|
|
195
|
+
const { collectionName } = args;
|
|
196
|
+
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
197
|
+
? collectionName
|
|
198
|
+
: `${ctx.collectionPrefix}${collectionName}`;
|
|
199
|
+
const response = await ctx.api.get(`/api/collections/${fullName}/snapshots`);
|
|
200
|
+
const snapshots = response.data.snapshots || response.data;
|
|
201
|
+
if (!snapshots || snapshots.length === 0) {
|
|
202
|
+
return `No backups found for ${fullName}.`;
|
|
203
|
+
}
|
|
204
|
+
let result = `## Backups: ${fullName}\n\n`;
|
|
205
|
+
for (const s of snapshots) {
|
|
206
|
+
const sizeMB = s.size ? (s.size / (1024 * 1024)).toFixed(2) : "?";
|
|
207
|
+
result += `- **${s.name}** - ${sizeMB} MB`;
|
|
208
|
+
if (s.createdAt)
|
|
209
|
+
result += ` (${new Date(s.createdAt).toLocaleString()})`;
|
|
210
|
+
result += "\n";
|
|
211
|
+
}
|
|
212
|
+
return result;
|
|
213
|
+
},
|
|
214
|
+
get_platform_stats: async (_args, ctx) => {
|
|
215
|
+
const response = await ctx.api.get("/api/platform/stats");
|
|
216
|
+
const data = response.data;
|
|
217
|
+
let result = `## Platform Statistics\n\n`;
|
|
218
|
+
result += `- **Total Projects:** ${data.totalProjects ?? 0}\n`;
|
|
219
|
+
result += `- **Total Collections:** ${data.totalCollections ?? 0}\n\n`;
|
|
220
|
+
if (data.projects && data.projects.length > 0) {
|
|
221
|
+
result += `### Projects\n`;
|
|
222
|
+
for (const p of data.projects) {
|
|
223
|
+
result += `- **${p.project}**: ${p.collections} collections, ${p.totalVectors} vectors\n`;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
},
|
|
228
|
+
get_prediction_stats: async (args, ctx) => {
|
|
229
|
+
const { sessionId } = args;
|
|
230
|
+
const params = sessionId ? `?sessionId=${sessionId}` : "";
|
|
231
|
+
const response = await ctx.api.get(`/api/predictions/stats${params}`);
|
|
232
|
+
const data = response.data;
|
|
233
|
+
let result = `## Prediction Stats${sessionId ? ` (Session ${sessionId})` : ""}\n\n`;
|
|
234
|
+
result += `- **Total Predictions:** ${data.totalPredictions ?? 0}\n`;
|
|
235
|
+
result += `- **Hits:** ${data.totalHits ?? 0}\n`;
|
|
236
|
+
result += `- **Misses:** ${data.totalMisses ?? 0}\n`;
|
|
237
|
+
result += `- **Hit Rate:** ${data.hitRate !== undefined ? pct(data.hitRate) : "N/A"}\n\n`;
|
|
238
|
+
if (data.byStrategy && Object.keys(data.byStrategy).length > 0) {
|
|
239
|
+
result += `### By Strategy\n`;
|
|
240
|
+
for (const [strategy, stats] of Object.entries(data.byStrategy)) {
|
|
241
|
+
result += `- **${strategy}**: ${stats.predictions} predictions, ${stats.hits} hits (${pct(stats.hitRate)})\n`;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return result;
|
|
245
|
+
},
|
|
246
|
+
enable_quantization: async (args, ctx) => {
|
|
247
|
+
const { collectionName, quantile = 0.99 } = args;
|
|
248
|
+
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
249
|
+
? collectionName
|
|
250
|
+
: `${ctx.collectionPrefix}${collectionName}`;
|
|
251
|
+
const response = await ctx.api.post(`/api/collections/${fullName}/quantization`, { quantile });
|
|
252
|
+
const data = response.data;
|
|
253
|
+
let result = `## Quantization Enabled\n\n`;
|
|
254
|
+
result += `- **Collection:** ${fullName}\n`;
|
|
255
|
+
result += `- **Quantile:** ${quantile}\n`;
|
|
256
|
+
result += `- **Expected Reduction:** ${data.expectedReduction || "~4x memory reduction"}\n`;
|
|
257
|
+
return result;
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
return { tools, handlers };
|
|
261
|
+
}
|