@crowley/rag-mcp 1.0.3 → 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.
- package/dist/tools/indexing.d.ts +4 -0
- package/dist/tools/indexing.js +116 -18
- package/package.json +3 -2
package/dist/tools/indexing.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Indexing tools module - codebase indexing, status, zero-downtime reindex,
|
|
3
3
|
* and alias management.
|
|
4
|
+
*
|
|
5
|
+
* index_codebase and reindex_zero_downtime read files locally and upload
|
|
6
|
+
* them to the RAG API in batches via POST /api/index/upload. This allows
|
|
7
|
+
* remote MCP clients to index codebases that aren't on the server filesystem.
|
|
4
8
|
*/
|
|
5
9
|
import type { ToolModule } from "../types.js";
|
|
6
10
|
/**
|
package/dist/tools/indexing.js
CHANGED
|
@@ -1,7 +1,105 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Indexing tools module - codebase indexing, status, zero-downtime reindex,
|
|
3
3
|
* and alias management.
|
|
4
|
+
*
|
|
5
|
+
* index_codebase and reindex_zero_downtime read files locally and upload
|
|
6
|
+
* them to the RAG API in batches via POST /api/index/upload. This allows
|
|
7
|
+
* remote MCP clients to index codebases that aren't on the server filesystem.
|
|
4
8
|
*/
|
|
9
|
+
import * as fs from "fs";
|
|
10
|
+
import * as path from "path";
|
|
11
|
+
import { glob } from "glob";
|
|
12
|
+
const DEFAULT_PATTERNS = [
|
|
13
|
+
"**/*.ts",
|
|
14
|
+
"**/*.tsx",
|
|
15
|
+
"**/*.js",
|
|
16
|
+
"**/*.jsx",
|
|
17
|
+
"**/*.vue",
|
|
18
|
+
"**/*.py",
|
|
19
|
+
"**/*.go",
|
|
20
|
+
"**/*.rs",
|
|
21
|
+
"**/*.java",
|
|
22
|
+
"**/*.md",
|
|
23
|
+
"**/*.sql",
|
|
24
|
+
"**/*.yml",
|
|
25
|
+
"**/*.yaml",
|
|
26
|
+
"**/Dockerfile",
|
|
27
|
+
];
|
|
28
|
+
const DEFAULT_EXCLUDE = [
|
|
29
|
+
"**/node_modules/**",
|
|
30
|
+
"**/dist/**",
|
|
31
|
+
"**/build/**",
|
|
32
|
+
"**/.git/**",
|
|
33
|
+
"**/coverage/**",
|
|
34
|
+
"**/.nuxt/**",
|
|
35
|
+
"**/.next/**",
|
|
36
|
+
"**/vendor/**",
|
|
37
|
+
"**/__pycache__/**",
|
|
38
|
+
"**/target/**",
|
|
39
|
+
"**/package-lock.json",
|
|
40
|
+
"**/yarn.lock",
|
|
41
|
+
"**/pnpm-lock.yaml",
|
|
42
|
+
"**/eval/results/**",
|
|
43
|
+
"**/eval/golden-queries.json",
|
|
44
|
+
];
|
|
45
|
+
const BATCH_SIZE = 50;
|
|
46
|
+
/**
|
|
47
|
+
* Discover files locally using glob, read their contents, and upload
|
|
48
|
+
* them to the RAG API in batches.
|
|
49
|
+
*/
|
|
50
|
+
async function uploadFiles(ctx, projectPath, opts) {
|
|
51
|
+
const patterns = opts.patterns || DEFAULT_PATTERNS;
|
|
52
|
+
const excludePatterns = opts.excludePatterns || DEFAULT_EXCLUDE;
|
|
53
|
+
// Discover files locally
|
|
54
|
+
const files = await glob(patterns, {
|
|
55
|
+
cwd: projectPath,
|
|
56
|
+
ignore: excludePatterns,
|
|
57
|
+
nodir: true,
|
|
58
|
+
absolute: false,
|
|
59
|
+
});
|
|
60
|
+
if (files.length === 0) {
|
|
61
|
+
return { totalFiles: 0, indexedFiles: 0, totalChunks: 0, errors: 0, duration: 0 };
|
|
62
|
+
}
|
|
63
|
+
let totalIndexed = 0;
|
|
64
|
+
let totalChunks = 0;
|
|
65
|
+
let totalErrors = 0;
|
|
66
|
+
let totalDuration = 0;
|
|
67
|
+
for (let i = 0; i < files.length; i += BATCH_SIZE) {
|
|
68
|
+
const batch = files.slice(i, i + BATCH_SIZE);
|
|
69
|
+
const filePayloads = [];
|
|
70
|
+
for (const relPath of batch) {
|
|
71
|
+
try {
|
|
72
|
+
const absPath = path.join(projectPath, relPath);
|
|
73
|
+
const content = fs.readFileSync(absPath, "utf-8");
|
|
74
|
+
filePayloads.push({ path: relPath, content });
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
totalErrors++;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (filePayloads.length === 0)
|
|
81
|
+
continue;
|
|
82
|
+
const isFirst = i === 0;
|
|
83
|
+
const isLast = i + BATCH_SIZE >= files.length;
|
|
84
|
+
const response = await ctx.api.post("/api/index/upload", {
|
|
85
|
+
files: filePayloads,
|
|
86
|
+
force: isFirst && (opts.force ?? false),
|
|
87
|
+
done: isLast,
|
|
88
|
+
});
|
|
89
|
+
const data = response.data;
|
|
90
|
+
totalIndexed += data.filesProcessed || 0;
|
|
91
|
+
totalChunks += data.chunksCreated || 0;
|
|
92
|
+
totalErrors += data.errors || 0;
|
|
93
|
+
totalDuration += data.duration || 0;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
totalFiles: files.length,
|
|
97
|
+
indexedFiles: totalIndexed,
|
|
98
|
+
totalChunks,
|
|
99
|
+
errors: totalErrors,
|
|
100
|
+
duration: totalDuration,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
5
103
|
/**
|
|
6
104
|
* Create the indexing tools module with project-specific descriptions.
|
|
7
105
|
*/
|
|
@@ -67,16 +165,15 @@ export function createIndexingTools(projectName) {
|
|
|
67
165
|
];
|
|
68
166
|
const handlers = {
|
|
69
167
|
index_codebase: async (args, ctx) => {
|
|
70
|
-
const { path, force = false } = args;
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
path: path || ctx.projectPath,
|
|
74
|
-
force,
|
|
75
|
-
});
|
|
76
|
-
const data = response.data;
|
|
168
|
+
const { path: indexPath, force = false } = args;
|
|
169
|
+
const projectPath = indexPath || ctx.projectPath;
|
|
170
|
+
const stats = await uploadFiles(ctx, projectPath, { force });
|
|
77
171
|
let result = `## Indexing ${projectName}\n\n`;
|
|
78
|
-
result += `- **
|
|
79
|
-
result += `- **Files
|
|
172
|
+
result += `- **Total files found:** ${stats.totalFiles}\n`;
|
|
173
|
+
result += `- **Files indexed:** ${stats.indexedFiles}\n`;
|
|
174
|
+
result += `- **Chunks created:** ${stats.totalChunks}\n`;
|
|
175
|
+
result += `- **Errors:** ${stats.errors}\n`;
|
|
176
|
+
result += `- **Duration:** ${stats.duration}ms\n`;
|
|
80
177
|
return result;
|
|
81
178
|
},
|
|
82
179
|
get_index_status: async (_args, ctx) => {
|
|
@@ -91,18 +188,19 @@ export function createIndexingTools(projectName) {
|
|
|
91
188
|
return result;
|
|
92
189
|
},
|
|
93
190
|
reindex_zero_downtime: async (args, ctx) => {
|
|
94
|
-
const { path, patterns, excludePatterns } = args;
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
path: path || ctx.projectPath,
|
|
191
|
+
const { path: indexPath, patterns, excludePatterns } = args;
|
|
192
|
+
const projectPath = indexPath || ctx.projectPath;
|
|
193
|
+
const stats = await uploadFiles(ctx, projectPath, {
|
|
98
194
|
patterns,
|
|
99
195
|
excludePatterns,
|
|
196
|
+
force: true,
|
|
100
197
|
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
result += `- **
|
|
104
|
-
result += `- **
|
|
105
|
-
result += `- **
|
|
198
|
+
let result = `## Reindex: ${projectName}\n\n`;
|
|
199
|
+
result += `- **Total files found:** ${stats.totalFiles}\n`;
|
|
200
|
+
result += `- **Files indexed:** ${stats.indexedFiles}\n`;
|
|
201
|
+
result += `- **Chunks created:** ${stats.totalChunks}\n`;
|
|
202
|
+
result += `- **Errors:** ${stats.errors}\n`;
|
|
203
|
+
result += `- **Duration:** ${stats.duration}ms\n`;
|
|
106
204
|
return result;
|
|
107
205
|
},
|
|
108
206
|
list_aliases: async (_args, ctx) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crowley/rag-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Universal RAG MCP Server for any project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
34
|
-
"axios": "^1.6.0"
|
|
34
|
+
"axios": "^1.6.0",
|
|
35
|
+
"glob": "^11.0.0"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@types/node": "^20.10.0",
|