@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,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Suggestions tools module - contextual suggestions, related code,
|
|
3
|
+
* implementation suggestions, test suggestions, and code context.
|
|
4
|
+
*/
|
|
5
|
+
import { truncate, pct, PREVIEW } from "../formatters.js";
|
|
6
|
+
/**
|
|
7
|
+
* Create the suggestions tools module with project-specific descriptions.
|
|
8
|
+
*/
|
|
9
|
+
export function createSuggestionTools(projectName) {
|
|
10
|
+
const tools = [
|
|
11
|
+
{
|
|
12
|
+
name: "get_contextual_suggestions",
|
|
13
|
+
description: `Get contextual suggestions based on current work context for ${projectName}. Returns relevant suggestions, triggers, and related memories.`,
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: "object",
|
|
16
|
+
properties: {
|
|
17
|
+
currentFile: {
|
|
18
|
+
type: "string",
|
|
19
|
+
description: "Currently active file path",
|
|
20
|
+
},
|
|
21
|
+
currentCode: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Currently selected or visible code",
|
|
24
|
+
},
|
|
25
|
+
recentFiles: {
|
|
26
|
+
type: "array",
|
|
27
|
+
items: { type: "string" },
|
|
28
|
+
description: "Recently opened file paths",
|
|
29
|
+
},
|
|
30
|
+
task: {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "Current task description",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "suggest_related_code",
|
|
39
|
+
description: `Find code related to a given file or snippet in ${projectName}. Shows similar implementations and related modules.`,
|
|
40
|
+
inputSchema: {
|
|
41
|
+
type: "object",
|
|
42
|
+
properties: {
|
|
43
|
+
file: {
|
|
44
|
+
type: "string",
|
|
45
|
+
description: "File path to find related code for",
|
|
46
|
+
},
|
|
47
|
+
code: {
|
|
48
|
+
type: "string",
|
|
49
|
+
description: "Code snippet to find related code for",
|
|
50
|
+
},
|
|
51
|
+
limit: {
|
|
52
|
+
type: "number",
|
|
53
|
+
description: "Max results (default: 5)",
|
|
54
|
+
default: 5,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "suggest_implementation",
|
|
61
|
+
description: `Get implementation suggestions for a feature in ${projectName}. Shows similar patterns and adaptation hints.`,
|
|
62
|
+
inputSchema: {
|
|
63
|
+
type: "object",
|
|
64
|
+
properties: {
|
|
65
|
+
description: {
|
|
66
|
+
type: "string",
|
|
67
|
+
description: "Description of what to implement",
|
|
68
|
+
},
|
|
69
|
+
currentFile: {
|
|
70
|
+
type: "string",
|
|
71
|
+
description: "Current file for context",
|
|
72
|
+
},
|
|
73
|
+
language: {
|
|
74
|
+
type: "string",
|
|
75
|
+
description: "Target programming language",
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
required: ["description"],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "suggest_tests",
|
|
83
|
+
description: `Get test suggestions for code in ${projectName}. Shows recommended test types, frameworks, and example patterns.`,
|
|
84
|
+
inputSchema: {
|
|
85
|
+
type: "object",
|
|
86
|
+
properties: {
|
|
87
|
+
file: {
|
|
88
|
+
type: "string",
|
|
89
|
+
description: "File to suggest tests for",
|
|
90
|
+
},
|
|
91
|
+
code: {
|
|
92
|
+
type: "string",
|
|
93
|
+
description: "Code to suggest tests for",
|
|
94
|
+
},
|
|
95
|
+
framework: {
|
|
96
|
+
type: "string",
|
|
97
|
+
description: "Test framework preference (jest, mocha, pytest, etc.)",
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "get_code_context",
|
|
104
|
+
description: `Get full context for a code file in ${projectName}. Shows imports, related code, and test patterns.`,
|
|
105
|
+
inputSchema: {
|
|
106
|
+
type: "object",
|
|
107
|
+
properties: {
|
|
108
|
+
file: {
|
|
109
|
+
type: "string",
|
|
110
|
+
description: "File path to get context for",
|
|
111
|
+
},
|
|
112
|
+
code: {
|
|
113
|
+
type: "string",
|
|
114
|
+
description: "Code snippet for context",
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
const handlers = {
|
|
121
|
+
get_contextual_suggestions: async (args, ctx) => {
|
|
122
|
+
const { currentFile, currentCode, recentFiles, task } = args;
|
|
123
|
+
const response = await ctx.api.post("/api/suggestions", {
|
|
124
|
+
projectName: ctx.projectName,
|
|
125
|
+
currentFile,
|
|
126
|
+
currentCode,
|
|
127
|
+
recentFiles,
|
|
128
|
+
task,
|
|
129
|
+
});
|
|
130
|
+
const data = response.data;
|
|
131
|
+
let result = `## Contextual Suggestions\n\n`;
|
|
132
|
+
if (data.relevanceScore !== undefined) {
|
|
133
|
+
result += `**Relevance Score:** ${pct(data.relevanceScore)}\n\n`;
|
|
134
|
+
}
|
|
135
|
+
if (data.triggers && data.triggers.length > 0) {
|
|
136
|
+
result += `### Triggers\n`;
|
|
137
|
+
for (const t of data.triggers) {
|
|
138
|
+
result += `- **${t.type}:** ${t.value}`;
|
|
139
|
+
if (t.confidence)
|
|
140
|
+
result += ` (${pct(t.confidence)})`;
|
|
141
|
+
result += "\n";
|
|
142
|
+
}
|
|
143
|
+
result += "\n";
|
|
144
|
+
}
|
|
145
|
+
if (data.suggestions && data.suggestions.length > 0) {
|
|
146
|
+
result += `### Suggestions\n`;
|
|
147
|
+
for (const s of data.suggestions) {
|
|
148
|
+
result += `- **${s.title}** [${s.type}]\n`;
|
|
149
|
+
if (s.description)
|
|
150
|
+
result += ` ${s.description}\n`;
|
|
151
|
+
if (s.reason)
|
|
152
|
+
result += ` *Reason: ${s.reason}*\n`;
|
|
153
|
+
if (s.relevance !== undefined)
|
|
154
|
+
result += ` Relevance: ${pct(s.relevance)}\n`;
|
|
155
|
+
}
|
|
156
|
+
result += "\n";
|
|
157
|
+
}
|
|
158
|
+
if (data.relatedMemories && data.relatedMemories.length > 0) {
|
|
159
|
+
result += `### Related Memories\n`;
|
|
160
|
+
for (const m of data.relatedMemories) {
|
|
161
|
+
result += `- ${m.content || m.title || JSON.stringify(m)}\n`;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
},
|
|
166
|
+
suggest_related_code: async (args, ctx) => {
|
|
167
|
+
const { file, code, limit = 5 } = args;
|
|
168
|
+
const response = await ctx.api.post("/api/code/related", {
|
|
169
|
+
projectName: ctx.projectName,
|
|
170
|
+
file,
|
|
171
|
+
code,
|
|
172
|
+
limit,
|
|
173
|
+
});
|
|
174
|
+
const results = response.data.results || response.data;
|
|
175
|
+
if (!results || results.length === 0) {
|
|
176
|
+
return "No related code found.";
|
|
177
|
+
}
|
|
178
|
+
let result = `## Related Code\n\n`;
|
|
179
|
+
for (const r of results) {
|
|
180
|
+
result += `### ${r.file}\n`;
|
|
181
|
+
result += `**Score:** ${pct(r.score)}`;
|
|
182
|
+
if (r.reason)
|
|
183
|
+
result += ` | **Reason:** ${r.reason}`;
|
|
184
|
+
if (r.line)
|
|
185
|
+
result += ` | Line ${r.line}`;
|
|
186
|
+
result += "\n";
|
|
187
|
+
if (r.content || r.code) {
|
|
188
|
+
result += "```\n" + truncate(r.content || r.code, PREVIEW.MEDIUM) + "\n```\n";
|
|
189
|
+
}
|
|
190
|
+
result += "\n";
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
},
|
|
194
|
+
suggest_implementation: async (args, ctx) => {
|
|
195
|
+
const { description, currentFile, language } = args;
|
|
196
|
+
const response = await ctx.api.post("/api/code/suggest-implementation", {
|
|
197
|
+
projectName: ctx.projectName,
|
|
198
|
+
description,
|
|
199
|
+
currentFile,
|
|
200
|
+
language,
|
|
201
|
+
});
|
|
202
|
+
const data = response.data;
|
|
203
|
+
const patterns = data.patterns || data.results || [];
|
|
204
|
+
if (!patterns || patterns.length === 0) {
|
|
205
|
+
return "No implementation suggestions found.";
|
|
206
|
+
}
|
|
207
|
+
const patternIcons = {
|
|
208
|
+
similar_structure: "\ud83d\udcd0",
|
|
209
|
+
same_domain: "\ud83c\udfaf",
|
|
210
|
+
related_import: "\ud83d\udce6",
|
|
211
|
+
test_pattern: "\ud83e\uddea",
|
|
212
|
+
};
|
|
213
|
+
let result = `## Implementation Suggestions\n\n`;
|
|
214
|
+
for (const p of patterns) {
|
|
215
|
+
const icon = patternIcons[p.pattern || p.type] || "\ud83d\udcd0";
|
|
216
|
+
result += `### ${icon} ${p.file || p.name || "Pattern"}\n`;
|
|
217
|
+
if (p.adaptationHints || p.hints) {
|
|
218
|
+
result += `**Adaptation:** ${p.adaptationHints || p.hints}\n`;
|
|
219
|
+
}
|
|
220
|
+
if (p.content || p.code) {
|
|
221
|
+
result += "```\n" + truncate(p.content || p.code, 400) + "\n```\n";
|
|
222
|
+
}
|
|
223
|
+
result += "\n";
|
|
224
|
+
}
|
|
225
|
+
return result;
|
|
226
|
+
},
|
|
227
|
+
suggest_tests: async (args, ctx) => {
|
|
228
|
+
const { file, code, framework } = args;
|
|
229
|
+
const response = await ctx.api.post("/api/code/suggest-tests", {
|
|
230
|
+
projectName: ctx.projectName,
|
|
231
|
+
file,
|
|
232
|
+
code,
|
|
233
|
+
framework,
|
|
234
|
+
});
|
|
235
|
+
const data = response.data;
|
|
236
|
+
const tests = data.tests || data.suggestions || data.results || [];
|
|
237
|
+
if (!tests || tests.length === 0) {
|
|
238
|
+
return "No test suggestions found.";
|
|
239
|
+
}
|
|
240
|
+
const typeIcons = {
|
|
241
|
+
unit: "\ud83d\udd2c",
|
|
242
|
+
integration: "\ud83d\udd17",
|
|
243
|
+
e2e: "\ud83c\udf10",
|
|
244
|
+
};
|
|
245
|
+
let result = `## Test Suggestions\n\n`;
|
|
246
|
+
for (const t of tests) {
|
|
247
|
+
const icon = typeIcons[t.type] || "\ud83d\udd2c";
|
|
248
|
+
result += `### ${icon} ${t.name || t.title || t.type || "Test"}\n`;
|
|
249
|
+
if (t.framework)
|
|
250
|
+
result += `**Framework:** ${t.framework}\n`;
|
|
251
|
+
if (t.coverage)
|
|
252
|
+
result += `**Coverage:** ${t.coverage}\n`;
|
|
253
|
+
if (t.content || t.code) {
|
|
254
|
+
result += "```\n" + truncate(t.content || t.code, PREVIEW.LONG) + "\n```\n";
|
|
255
|
+
}
|
|
256
|
+
result += "\n";
|
|
257
|
+
}
|
|
258
|
+
return result;
|
|
259
|
+
},
|
|
260
|
+
get_code_context: async (args, ctx) => {
|
|
261
|
+
const { file, code } = args;
|
|
262
|
+
const response = await ctx.api.post("/api/code/context", {
|
|
263
|
+
projectName: ctx.projectName,
|
|
264
|
+
file,
|
|
265
|
+
code,
|
|
266
|
+
});
|
|
267
|
+
const data = response.data;
|
|
268
|
+
let result = `## Code Context\n\n`;
|
|
269
|
+
if (data.imports && data.imports.length > 0) {
|
|
270
|
+
result += `### Imports\n`;
|
|
271
|
+
for (const imp of data.imports) {
|
|
272
|
+
result += `- ${imp}\n`;
|
|
273
|
+
}
|
|
274
|
+
result += "\n";
|
|
275
|
+
}
|
|
276
|
+
if (data.relatedCode && data.relatedCode.length > 0) {
|
|
277
|
+
result += `### Related Code\n`;
|
|
278
|
+
for (const r of data.relatedCode) {
|
|
279
|
+
result += `- **${r.file}** (${pct(r.score)})`;
|
|
280
|
+
if (r.reason)
|
|
281
|
+
result += ` - ${r.reason}`;
|
|
282
|
+
result += "\n";
|
|
283
|
+
}
|
|
284
|
+
result += "\n";
|
|
285
|
+
}
|
|
286
|
+
if (data.testPatterns && data.testPatterns.length > 0) {
|
|
287
|
+
result += `### Test Patterns\n`;
|
|
288
|
+
for (const t of data.testPatterns) {
|
|
289
|
+
result += `- **${t.file}**`;
|
|
290
|
+
if (t.type)
|
|
291
|
+
result += ` [${t.type}]`;
|
|
292
|
+
if (t.framework)
|
|
293
|
+
result += ` (${t.framework})`;
|
|
294
|
+
result += "\n";
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return result;
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
return { tools, handlers };
|
|
301
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the MCP server tool modules.
|
|
3
|
+
*/
|
|
4
|
+
import type { AxiosInstance } from "axios";
|
|
5
|
+
/** MCP tool input schema shape */
|
|
6
|
+
export interface ToolInputSchema {
|
|
7
|
+
type: "object";
|
|
8
|
+
properties: Record<string, unknown>;
|
|
9
|
+
required?: string[];
|
|
10
|
+
}
|
|
11
|
+
/** MCP tool definition */
|
|
12
|
+
export interface ToolDefinition {
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
inputSchema: ToolInputSchema;
|
|
16
|
+
}
|
|
17
|
+
/** Context passed to every tool handler */
|
|
18
|
+
export interface ToolContext {
|
|
19
|
+
api: AxiosInstance;
|
|
20
|
+
projectName: string;
|
|
21
|
+
projectPath: string;
|
|
22
|
+
collectionPrefix: string;
|
|
23
|
+
activeSessionId?: string;
|
|
24
|
+
enrichmentEnabled: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** A tool handler function */
|
|
27
|
+
export type ToolHandler = (args: Record<string, unknown>, ctx: ToolContext) => Promise<string>;
|
|
28
|
+
/** A tool module exports definitions and handlers */
|
|
29
|
+
export interface ToolModule {
|
|
30
|
+
tools: ToolDefinition[];
|
|
31
|
+
handlers: Record<string, ToolHandler>;
|
|
32
|
+
}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@crowley/rag-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Universal RAG MCP Server for any project",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"rag-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsc -w",
|
|
16
|
+
"start": "node dist/index.js",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"rag",
|
|
22
|
+
"model-context-protocol",
|
|
23
|
+
"ai",
|
|
24
|
+
"embeddings",
|
|
25
|
+
"vector-search"
|
|
26
|
+
],
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/AKerby/shared-ai-infra.git"
|
|
30
|
+
},
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
34
|
+
"axios": "^1.6.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^20.10.0",
|
|
38
|
+
"typescript": "^5.3.0"
|
|
39
|
+
}
|
|
40
|
+
}
|