@crowley/rag-mcp 1.5.0 → 1.6.1

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.
@@ -9,12 +9,27 @@ export function createDatabaseTools(projectName) {
9
9
  name: "record_table",
10
10
  description: `Record a database table definition with its purpose, columns, and relationships. Use this to document the database schema for ${projectName}.`,
11
11
  schema: z.object({
12
- tableName: z.string().describe("Name of the table (e.g., 'claims', 'documents')"),
13
- purpose: z.string().describe("What this table is for and when it's used"),
14
- columns: z.string().describe("Key columns and their purposes (format: 'column_name: description')"),
15
- relationships: z.string().optional().describe("Relationships to other tables (FK references)"),
16
- indexes: z.string().optional().describe("Important indexes and their purpose"),
17
- rules: z.string().optional().describe("Business rules and constraints for this table"),
12
+ tableName: z
13
+ .string()
14
+ .describe("Name of the table (e.g., 'claims', 'documents')"),
15
+ purpose: z
16
+ .string()
17
+ .describe("What this table is for and when it's used"),
18
+ columns: z
19
+ .string()
20
+ .describe("Key columns and their purposes (format: 'column_name: description')"),
21
+ relationships: z
22
+ .string()
23
+ .optional()
24
+ .describe("Relationships to other tables (FK references)"),
25
+ indexes: z
26
+ .string()
27
+ .optional()
28
+ .describe("Important indexes and their purpose"),
29
+ rules: z
30
+ .string()
31
+ .optional()
32
+ .describe("Business rules and constraints for this table"),
18
33
  }),
19
34
  annotations: TOOL_ANNOTATIONS["record_table"],
20
35
  handler: async (args, ctx) => {
@@ -47,14 +62,18 @@ ${rules ? `### Business Rules\n${rules}` : ""}`;
47
62
  name: "get_table_info",
48
63
  description: "Get documented information about a database table including its purpose, columns, relationships, and rules.",
49
64
  schema: z.object({
50
- tableName: z.string().describe("Table name to look up (or 'all' to list all tables)"),
65
+ tableName: z
66
+ .string()
67
+ .describe("Table name to look up (or 'all' to list all tables)"),
51
68
  }),
52
69
  annotations: TOOL_ANNOTATIONS["get_table_info"],
53
70
  handler: async (args, ctx) => {
54
71
  const { tableName } = args;
55
72
  const response = await ctx.api.post("/api/memory/recall", {
56
73
  projectName: ctx.projectName,
57
- query: tableName === "all" ? "database table schema" : `table ${tableName}`,
74
+ query: tableName === "all"
75
+ ? "database table schema"
76
+ : `table ${tableName}`,
58
77
  tag: "table",
59
78
  limit: tableName === "all" ? 20 : 5,
60
79
  });
@@ -77,8 +96,25 @@ ${rules ? `### Business Rules\n${rules}` : ""}`;
77
96
  schema: z.object({
78
97
  ruleName: z.string().describe("Short name for the rule"),
79
98
  description: z.string().describe("Detailed description of the rule"),
80
- scope: z.enum(["global", "table", "column", "query", "migration", "naming", "primary-key", "timestamps", "multi-tenancy", "soft-delete", "status"]).describe("Where this rule applies"),
81
- examples: z.string().optional().describe("Good and bad examples of applying this rule"),
99
+ scope: z
100
+ .enum([
101
+ "global",
102
+ "table",
103
+ "column",
104
+ "query",
105
+ "migration",
106
+ "naming",
107
+ "primary-key",
108
+ "timestamps",
109
+ "multi-tenancy",
110
+ "soft-delete",
111
+ "status",
112
+ ])
113
+ .describe("Where this rule applies"),
114
+ examples: z
115
+ .string()
116
+ .optional()
117
+ .describe("Good and bad examples of applying this rule"),
82
118
  }),
83
119
  annotations: TOOL_ANNOTATIONS["record_db_rule"],
84
120
  handler: async (args, ctx) => {
@@ -109,7 +145,10 @@ ${examples ? `### Examples\n${examples}` : ""}`;
109
145
  name: "get_db_rules",
110
146
  description: `Get database rules and constraints for ${projectName}. Filter by scope or get all rules.`,
111
147
  schema: z.object({
112
- scope: z.enum(["global", "table", "column", "query", "migration", "all"]).optional().describe("Filter by scope (default: all)"),
148
+ scope: z
149
+ .enum(["global", "table", "column", "query", "migration", "all"])
150
+ .optional()
151
+ .describe("Filter by scope (default: all)"),
113
152
  }),
114
153
  annotations: TOOL_ANNOTATIONS["get_db_rules"],
115
154
  handler: async (args, ctx) => {
@@ -138,10 +177,20 @@ ${examples ? `### Examples\n${examples}` : ""}`;
138
177
  name: "record_enum",
139
178
  description: "Record a database enum type with its values and usage. Use this to document allowed values for status fields, types, etc.",
140
179
  schema: z.object({
141
- enumName: z.string().describe("Name of the enum (e.g., 'ClaimStatus', 'DocumentType')"),
142
- values: z.string().describe("List of enum values with descriptions (format: 'value: description')"),
143
- usedIn: z.string().optional().describe("Tables and columns where this enum is used"),
144
- transitions: z.string().optional().describe("Allowed state transitions (for status enums)"),
180
+ enumName: z
181
+ .string()
182
+ .describe("Name of the enum (e.g., 'ClaimStatus', 'DocumentType')"),
183
+ values: z
184
+ .string()
185
+ .describe("List of enum values with descriptions (format: 'value: description')"),
186
+ usedIn: z
187
+ .string()
188
+ .optional()
189
+ .describe("Tables and columns where this enum is used"),
190
+ transitions: z
191
+ .string()
192
+ .optional()
193
+ .describe("Allowed state transitions (for status enums)"),
145
194
  }),
146
195
  annotations: TOOL_ANNOTATIONS["record_enum"],
147
196
  handler: async (args, ctx) => {
@@ -171,16 +220,17 @@ ${transitions ? `### State Transitions\n${transitions}` : ""}`;
171
220
  name: "get_enums",
172
221
  description: `Get documented enum types for ${projectName} database.`,
173
222
  schema: z.object({
174
- enumName: z.string().optional().describe("Specific enum to look up (or empty for all)"),
223
+ enumName: z
224
+ .string()
225
+ .optional()
226
+ .describe("Specific enum to look up (or empty for all)"),
175
227
  }),
176
228
  annotations: TOOL_ANNOTATIONS["get_enums"],
177
229
  handler: async (args, ctx) => {
178
230
  const { enumName } = args;
179
231
  const response = await ctx.api.post("/api/memory/recall", {
180
232
  projectName: ctx.projectName,
181
- query: enumName
182
- ? `enum ${enumName}`
183
- : "database enum type values",
233
+ query: enumName ? `enum ${enumName}` : "database enum type values",
184
234
  tag: "enum",
185
235
  limit: 15,
186
236
  });
@@ -199,8 +249,13 @@ ${transitions ? `### State Transitions\n${transitions}` : ""}`;
199
249
  name: "check_db_schema",
200
250
  description: "Check if a proposed database change follows the documented rules and patterns. Use before creating migrations.",
201
251
  schema: z.object({
202
- change: z.string().describe("Description of the proposed change (new table, column, index, etc.)"),
203
- sql: z.string().optional().describe("Optional SQL or Prisma schema for the change"),
252
+ change: z
253
+ .string()
254
+ .describe("Description of the proposed change (new table, column, index, etc.)"),
255
+ sql: z
256
+ .string()
257
+ .optional()
258
+ .describe("Optional SQL or Prisma schema for the change"),
204
259
  }),
205
260
  annotations: TOOL_ANNOTATIONS["check_db_schema"],
206
261
  handler: async (args, ctx) => {
@@ -263,8 +318,13 @@ ${transitions ? `### State Transitions\n${transitions}` : ""}`;
263
318
  name: "suggest_db_schema",
264
319
  description: "Get suggestions for database schema design for a new feature or data requirement.",
265
320
  schema: z.object({
266
- requirement: z.string().describe("What data needs to be stored or what feature needs support"),
267
- relatedTables: z.string().optional().describe("Existing tables that might be related"),
321
+ requirement: z
322
+ .string()
323
+ .describe("What data needs to be stored or what feature needs support"),
324
+ relatedTables: z
325
+ .string()
326
+ .optional()
327
+ .describe("Existing tables that might be related"),
268
328
  }),
269
329
  annotations: TOOL_ANNOTATIONS["suggest_db_schema"],
270
330
  handler: async (args, ctx) => {
@@ -326,7 +386,10 @@ ${transitions ? `### State Transitions\n${transitions}` : ""}`;
326
386
  rules.forEach((r, i) => {
327
387
  const name = r.memory.metadata?.ruleName || r.memory.relatedTo || "Rule";
328
388
  const scope = r.memory.metadata?.scope || "";
329
- const desc = r.memory.content.replace(/^## DB Rule:.*\n*/m, "").replace(/\*\*Scope:\*\*.*\n*/m, "").trim();
389
+ const desc = r.memory.content
390
+ .replace(/^## DB Rule:.*\n*/m, "")
391
+ .replace(/\*\*Scope:\*\*.*\n*/m, "")
392
+ .trim();
330
393
  result += `${i + 1}. **${name}**${scope ? ` (${scope})` : ""}: ${desc.split("\n")[0]}\n`;
331
394
  });
332
395
  result += "\n";
@@ -15,9 +15,17 @@ export function createFeedbackTools(projectName) {
15
15
  description: `Provide feedback on a search result quality for ${projectName}. Helps improve future search results.`,
16
16
  schema: z.object({
17
17
  query: z.string().describe("The original search query"),
18
- feedbackType: z.enum(["helpful", "not_helpful", "partially"]).describe("How helpful the results were"),
19
- file: z.string().optional().describe("The file from results being rated"),
20
- suggestedQuery: z.string().optional().describe("A better query that would have found the right results"),
18
+ feedbackType: z
19
+ .enum(["helpful", "not_helpful", "partially"])
20
+ .describe("How helpful the results were"),
21
+ file: z
22
+ .string()
23
+ .optional()
24
+ .describe("The file from results being rated"),
25
+ suggestedQuery: z
26
+ .string()
27
+ .optional()
28
+ .describe("A better query that would have found the right results"),
21
29
  }),
22
30
  annotations: TOOL_ANNOTATIONS["feedback_search"],
23
31
  handler: async (args, ctx) => {
@@ -50,8 +58,13 @@ export function createFeedbackTools(projectName) {
50
58
  description: `Provide feedback on a memory's accuracy for ${projectName}. Helps keep memory quality high.`,
51
59
  schema: z.object({
52
60
  memoryId: z.string().describe("The memory ID to provide feedback on"),
53
- feedback: z.enum(["accurate", "outdated", "incorrect"]).describe("Feedback on the memory's accuracy"),
54
- correction: z.string().optional().describe("Corrected information if the memory is wrong"),
61
+ feedback: z
62
+ .enum(["accurate", "outdated", "incorrect"])
63
+ .describe("Feedback on the memory's accuracy"),
64
+ correction: z
65
+ .string()
66
+ .optional()
67
+ .describe("Corrected information if the memory is wrong"),
55
68
  }),
56
69
  annotations: TOOL_ANNOTATIONS["feedback_memory"],
57
70
  handler: async (args, ctx) => {
@@ -81,7 +94,10 @@ export function createFeedbackTools(projectName) {
81
94
  description: `Get query improvement suggestions based on feedback patterns for ${projectName}.`,
82
95
  schema: z.object({
83
96
  query: z.string().describe("The query to get suggestions for"),
84
- context: z.string().optional().describe("Additional context about what you are looking for"),
97
+ context: z
98
+ .string()
99
+ .optional()
100
+ .describe("Additional context about what you are looking for"),
85
101
  }),
86
102
  annotations: TOOL_ANNOTATIONS["suggest_better_query"],
87
103
  handler: async (args, ctx) => {
@@ -9,8 +9,21 @@ export function createGuidelinesTools(projectName) {
9
9
  name: "get_rag_guidelines",
10
10
  description: `Get recommended settings and best practices for working with RAG in ${projectName}. Shows optimal tool usage patterns, query strategies, and session management tips.`,
11
11
  schema: z.object({
12
- focus: z.enum(["all", "search", "memory", "session", "feedback", "performance"]).optional().describe("Focus area for guidelines (default: all)"),
13
- context: z.enum(["coding", "debugging", "reviewing", "learning", "documenting"]).optional().describe("Current work context for tailored recommendations"),
12
+ focus: z
13
+ .enum([
14
+ "all",
15
+ "search",
16
+ "memory",
17
+ "session",
18
+ "feedback",
19
+ "performance",
20
+ ])
21
+ .optional()
22
+ .describe("Focus area for guidelines (default: all)"),
23
+ context: z
24
+ .enum(["coding", "debugging", "reviewing", "learning", "documenting"])
25
+ .optional()
26
+ .describe("Current work context for tailored recommendations"),
14
27
  }),
15
28
  annotations: TOOL_ANNOTATIONS["get_rag_guidelines"],
16
29
  handler: async (args, ctx) => {
@@ -60,7 +60,13 @@ async function uploadFiles(ctx, projectPath, opts) {
60
60
  absolute: false,
61
61
  });
62
62
  if (files.length === 0) {
63
- return { totalFiles: 0, indexedFiles: 0, totalChunks: 0, errors: 0, duration: 0 };
63
+ return {
64
+ totalFiles: 0,
65
+ indexedFiles: 0,
66
+ totalChunks: 0,
67
+ errors: 0,
68
+ duration: 0,
69
+ };
64
70
  }
65
71
  let totalIndexed = 0;
66
72
  let totalChunks = 0;
@@ -84,6 +90,7 @@ async function uploadFiles(ctx, projectPath, opts) {
84
90
  const isFirst = i === 0;
85
91
  const isLast = i + BATCH_SIZE >= files.length;
86
92
  const response = await ctx.api.post("/api/index/upload", {
93
+ projectName: ctx.projectName,
87
94
  files: filePayloads,
88
95
  force: isFirst && (opts.force ?? false),
89
96
  done: isLast,
@@ -114,8 +121,14 @@ export function createIndexingTools(projectName) {
114
121
  name: "index_codebase",
115
122
  description: `Index or re-index the ${projectName} codebase for RAG search.`,
116
123
  schema: z.object({
117
- path: z.string().optional().describe("Path to index (default: entire project)"),
118
- force: z.boolean().optional().describe("Force re-index even if already indexed"),
124
+ path: z
125
+ .string()
126
+ .optional()
127
+ .describe("Path to index (default: entire project)"),
128
+ force: z
129
+ .boolean()
130
+ .optional()
131
+ .describe("Force re-index even if already indexed"),
119
132
  }),
120
133
  annotations: TOOL_ANNOTATIONS["index_codebase"],
121
134
  handler: async (args, ctx) => {
@@ -171,7 +184,11 @@ export function createIndexingTools(projectName) {
171
184
  cached: false,
172
185
  };
173
186
  // Cache for 30 minutes
174
- _statusCache = { data: text, expiresAt: Date.now() + STATUS_CACHE_TTL, structured };
187
+ _statusCache = {
188
+ data: text,
189
+ expiresAt: Date.now() + STATUS_CACHE_TTL,
190
+ structured,
191
+ };
175
192
  return { text, structured };
176
193
  },
177
194
  },
@@ -179,13 +196,22 @@ export function createIndexingTools(projectName) {
179
196
  name: "reindex_zero_downtime",
180
197
  description: `Reindex ${projectName} codebase with zero downtime using alias swap.`,
181
198
  schema: z.object({
182
- path: z.string().optional().describe("Path to index (default: entire project)"),
183
- patterns: z.array(z.string()).optional().describe("File patterns to include (e.g., ['**/*.ts', '**/*.py'])"),
184
- excludePatterns: z.array(z.string()).optional().describe("File patterns to exclude (e.g., ['node_modules/**'])"),
199
+ path: z
200
+ .string()
201
+ .optional()
202
+ .describe("Path to index (default: entire project)"),
203
+ patterns: z
204
+ .array(z.string())
205
+ .optional()
206
+ .describe("File patterns to include (e.g., ['**/*.ts', '**/*.py'])"),
207
+ excludePatterns: z
208
+ .array(z.string())
209
+ .optional()
210
+ .describe("File patterns to exclude (e.g., ['node_modules/**'])"),
185
211
  }),
186
212
  annotations: TOOL_ANNOTATIONS["reindex_zero_downtime"],
187
213
  handler: async (args, ctx) => {
188
- const { path: indexPath, patterns, excludePatterns } = args;
214
+ const { path: indexPath, patterns, excludePatterns, } = args;
189
215
  const projectPath = indexPath || ctx.projectPath;
190
216
  const stats = await uploadFiles(ctx, projectPath, {
191
217
  patterns,