@crowley/rag-mcp 1.0.4 → 1.0.6

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 (50) hide show
  1. package/dist/annotations.d.ts +16 -0
  2. package/dist/annotations.js +158 -0
  3. package/dist/context-enrichment.d.ts +2 -2
  4. package/dist/context-enrichment.js +37 -14
  5. package/dist/formatters.d.ts +2 -0
  6. package/dist/formatters.js +12 -0
  7. package/dist/index.js +64 -47
  8. package/dist/schemas.d.ts +97 -0
  9. package/dist/schemas.js +128 -0
  10. package/dist/tool-middleware.d.ts +40 -0
  11. package/dist/tool-middleware.js +216 -0
  12. package/dist/tool-registry.js +2 -1
  13. package/dist/tools/advanced.d.ts +2 -2
  14. package/dist/tools/advanced.js +200 -275
  15. package/dist/tools/agents.d.ts +2 -2
  16. package/dist/tools/agents.js +59 -78
  17. package/dist/tools/analytics.d.ts +2 -2
  18. package/dist/tools/analytics.js +170 -210
  19. package/dist/tools/architecture.d.ts +2 -2
  20. package/dist/tools/architecture.js +506 -661
  21. package/dist/tools/ask.d.ts +2 -2
  22. package/dist/tools/ask.js +164 -219
  23. package/dist/tools/cache.d.ts +2 -2
  24. package/dist/tools/cache.js +63 -82
  25. package/dist/tools/clustering.d.ts +2 -2
  26. package/dist/tools/clustering.js +154 -215
  27. package/dist/tools/confluence.d.ts +2 -2
  28. package/dist/tools/confluence.js +80 -116
  29. package/dist/tools/database.d.ts +2 -2
  30. package/dist/tools/database.js +303 -380
  31. package/dist/tools/feedback.d.ts +2 -2
  32. package/dist/tools/feedback.js +143 -184
  33. package/dist/tools/guidelines.d.ts +2 -2
  34. package/dist/tools/guidelines.js +123 -135
  35. package/dist/tools/indexing.d.ts +2 -2
  36. package/dist/tools/indexing.js +104 -100
  37. package/dist/tools/memory.d.ts +2 -2
  38. package/dist/tools/memory.js +299 -485
  39. package/dist/tools/pm.d.ts +2 -2
  40. package/dist/tools/pm.js +367 -615
  41. package/dist/tools/review.d.ts +2 -2
  42. package/dist/tools/review.js +142 -189
  43. package/dist/tools/search.d.ts +2 -2
  44. package/dist/tools/search.js +230 -305
  45. package/dist/tools/session.d.ts +2 -2
  46. package/dist/tools/session.js +288 -345
  47. package/dist/tools/suggestions.d.ts +2 -2
  48. package/dist/tools/suggestions.js +444 -255
  49. package/dist/types.d.ts +19 -2
  50. package/package.json +4 -2
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Tool annotations map for all MCP tools.
3
+ *
4
+ * Annotations help clients understand tool behaviour:
5
+ * readOnlyHint – tool does NOT modify its environment
6
+ * destructiveHint – tool may delete or irreversibly change data
7
+ * idempotentHint – repeated calls with same args have no extra effect
8
+ * openWorldHint – tool interacts with external entities (RAG API)
9
+ */
10
+ export interface ToolAnnotations {
11
+ readOnlyHint?: boolean;
12
+ destructiveHint?: boolean;
13
+ idempotentHint?: boolean;
14
+ openWorldHint?: boolean;
15
+ }
16
+ export declare const TOOL_ANNOTATIONS: Record<string, ToolAnnotations>;
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Tool annotations map for all MCP tools.
3
+ *
4
+ * Annotations help clients understand tool behaviour:
5
+ * readOnlyHint – tool does NOT modify its environment
6
+ * destructiveHint – tool may delete or irreversibly change data
7
+ * idempotentHint – repeated calls with same args have no extra effect
8
+ * openWorldHint – tool interacts with external entities (RAG API)
9
+ */
10
+ // ── Shorthand presets ───────────────────────────────────────
11
+ /** Read-only, idempotent – the vast majority of tools */
12
+ const RO = {
13
+ readOnlyHint: true,
14
+ destructiveHint: false,
15
+ idempotentHint: true,
16
+ openWorldHint: true,
17
+ };
18
+ /** Mutating but non-destructive (create / append) */
19
+ const MUT = {
20
+ readOnlyHint: false,
21
+ destructiveHint: false,
22
+ idempotentHint: false,
23
+ openWorldHint: true,
24
+ };
25
+ /** Idempotent upsert (record_*, setup_project, validate, promote) */
26
+ const UPSERT = {
27
+ readOnlyHint: false,
28
+ destructiveHint: false,
29
+ idempotentHint: true,
30
+ openWorldHint: true,
31
+ };
32
+ /** Destructive – may delete or irreversibly change data */
33
+ const DESTRUCT = {
34
+ readOnlyHint: false,
35
+ destructiveHint: true,
36
+ idempotentHint: false,
37
+ openWorldHint: true,
38
+ };
39
+ // ── Per-tool annotations ────────────────────────────────────
40
+ export const TOOL_ANNOTATIONS = {
41
+ // ── search (8) ──────────────────────────────────────────
42
+ search_codebase: RO,
43
+ search_similar: RO,
44
+ grouped_search: RO,
45
+ hybrid_search: RO,
46
+ search_docs: RO,
47
+ get_project_stats: RO,
48
+ find_symbol: RO,
49
+ search_graph: RO,
50
+ // ── ask (5) ─────────────────────────────────────────────
51
+ ask_codebase: RO,
52
+ explain_code: RO,
53
+ find_feature: RO,
54
+ analyze_conversation: RO,
55
+ auto_remember: MUT, // creates memory from conversation
56
+ // ── indexing (4) ────────────────────────────────────────
57
+ index_codebase: MUT,
58
+ get_index_status: RO,
59
+ reindex_zero_downtime: MUT,
60
+ list_aliases: RO,
61
+ // ── memory (11) ────────────────────────────────────────
62
+ remember: MUT,
63
+ recall: RO,
64
+ list_memories: RO,
65
+ forget: DESTRUCT,
66
+ update_todo: MUT,
67
+ batch_remember: MUT,
68
+ validate_memory: UPSERT, // idempotent status update
69
+ review_memories: RO,
70
+ promote_memory: UPSERT, // idempotent promotion
71
+ run_quality_gates: MUT, // may update memory status
72
+ memory_maintenance: DESTRUCT, // prunes old memories
73
+ // ── architecture (9) ───────────────────────────────────
74
+ record_adr: UPSERT,
75
+ get_adrs: RO,
76
+ record_pattern: UPSERT,
77
+ get_patterns: RO,
78
+ check_architecture: RO,
79
+ suggest_architecture: RO,
80
+ record_tech_debt: UPSERT,
81
+ get_tech_debt: RO,
82
+ analyze_project_structure: RO,
83
+ // ── database (8) ───────────────────────────────────────
84
+ record_table: UPSERT,
85
+ get_table_info: RO,
86
+ record_db_rule: UPSERT,
87
+ get_db_rules: RO,
88
+ record_enum: UPSERT,
89
+ get_enums: RO,
90
+ check_db_schema: RO,
91
+ suggest_db_schema: RO,
92
+ // ── confluence (4) ─────────────────────────────────────
93
+ search_confluence: RO,
94
+ index_confluence: MUT,
95
+ get_confluence_status: RO,
96
+ list_confluence_spaces: RO,
97
+ // ── pm (7) ─────────────────────────────────────────────
98
+ search_requirements: RO,
99
+ analyze_requirements: RO,
100
+ estimate_feature: RO,
101
+ get_feature_status: RO,
102
+ list_requirements: RO,
103
+ ask_pm: RO,
104
+ generate_spec: RO,
105
+ // ── review (3) ─────────────────────────────────────────
106
+ review_code: RO, // generates review, no side-effects
107
+ generate_tests: RO, // generates test suggestions
108
+ analyze_tests: RO,
109
+ // ── analytics (8) ──────────────────────────────────────
110
+ get_tool_analytics: RO,
111
+ get_knowledge_gaps: RO,
112
+ get_analytics: RO,
113
+ backup_collection: MUT, // creates a backup snapshot
114
+ list_backups: RO,
115
+ enable_quantization: DESTRUCT, // irreversible vector re-encoding
116
+ get_platform_stats: RO,
117
+ get_prediction_stats: RO,
118
+ // ── clustering (4) ─────────────────────────────────────
119
+ cluster_code: RO, // computes clusters, no persistence
120
+ find_duplicates: RO,
121
+ recommend_similar: RO,
122
+ extract_learnings: RO,
123
+ // ── session (7) ────────────────────────────────────────
124
+ summarize_context: RO,
125
+ summarize_changes: RO,
126
+ analyze_usage_patterns: RO,
127
+ get_developer_profile: RO,
128
+ start_session: MUT,
129
+ get_session_context: RO,
130
+ end_session: MUT,
131
+ // ── feedback (4) ───────────────────────────────────────
132
+ feedback_search: MUT, // stores search feedback
133
+ feedback_memory: MUT, // stores memory feedback
134
+ suggest_better_query: RO,
135
+ get_quality_metrics: RO,
136
+ // ── suggestions (7) ────────────────────────────────────
137
+ context_briefing: RO,
138
+ get_contextual_suggestions: RO,
139
+ suggest_related_code: RO,
140
+ suggest_implementation: RO,
141
+ suggest_tests: RO,
142
+ get_code_context: RO,
143
+ setup_project: UPSERT, // writes config (idempotent)
144
+ // ── cache (2) ──────────────────────────────────────────
145
+ get_cache_stats: RO,
146
+ warm_cache: MUT,
147
+ // ── guidelines (1) ─────────────────────────────────────
148
+ get_rag_guidelines: RO,
149
+ // ── advanced (5) ───────────────────────────────────────
150
+ merge_memories: DESTRUCT, // merges → deletes originals
151
+ get_completion_context: RO,
152
+ get_import_suggestions: RO,
153
+ get_type_context: RO,
154
+ get_behavior_patterns: RO,
155
+ // ── agents (2) ─────────────────────────────────────────
156
+ run_agent: MUT, // side-effects depend on agent type
157
+ get_agent_types: RO,
158
+ };
@@ -26,9 +26,9 @@ export declare class ContextEnricher {
26
26
  */
27
27
  before(name: string, args: Record<string, unknown>, ctx: ToolContext): Promise<string | null>;
28
28
  /**
29
- * After hook: fire-and-forget session activity tracking.
29
+ * After hook: fire-and-forget session activity tracking + implicit feedback.
30
30
  */
31
- after(name: string, _args: Record<string, unknown>, _result: string, ctx: ToolContext): void;
31
+ after(name: string, args: Record<string, unknown>, result: string, ctx: ToolContext): void;
32
32
  /**
33
33
  * Extract a semantic query string from tool arguments.
34
34
  */
@@ -18,6 +18,7 @@ export const DEFAULT_ENRICHABLE_TOOLS = new Set([
18
18
  "suggest_implementation",
19
19
  "suggest_related_code",
20
20
  "check_architecture",
21
+ "context_briefing",
21
22
  "run_agent",
22
23
  ]);
23
24
  export const DEFAULT_SKIP_TOOLS = new Set([
@@ -79,21 +80,43 @@ export class ContextEnricher {
79
80
  }
80
81
  }
81
82
  /**
82
- * After hook: fire-and-forget session activity tracking.
83
+ * After hook: fire-and-forget session activity tracking + implicit feedback.
83
84
  */
84
- after(name, _args, _result, ctx) {
85
- if (!ctx.activeSessionId)
86
- return;
87
- // Fire-and-forget: track tool usage in session
88
- ctx.api
89
- .post(`/api/session/${ctx.activeSessionId}/activity`, {
90
- projectName: ctx.projectName,
91
- type: "tool",
92
- value: name,
93
- })
94
- .catch(() => {
95
- // Silently ignore tracking errors
96
- });
85
+ after(name, args, result, ctx) {
86
+ // Session activity tracking
87
+ if (ctx.activeSessionId) {
88
+ ctx.api
89
+ .post(`/api/session/${ctx.activeSessionId}/activity`, {
90
+ projectName: ctx.projectName,
91
+ type: "tool",
92
+ value: name,
93
+ })
94
+ .catch(() => { });
95
+ }
96
+ // Implicit positive feedback for enrichable search tools
97
+ if (this.config.enrichableTools.has(name)) {
98
+ const query = this.extractQuery(args);
99
+ if (query &&
100
+ result &&
101
+ !result.includes("No results") &&
102
+ !result.includes("not found") &&
103
+ !result.includes("No relevant context found")) {
104
+ // Count approximate results for weighted feedback
105
+ const numbered = result.match(/^\d+\./gm);
106
+ const bullets = result.match(/^[-*] /gm);
107
+ const resultCount = numbered?.length ?? bullets?.length ?? 1;
108
+ ctx.api
109
+ .post("/api/feedback/search", {
110
+ projectName: ctx.projectName,
111
+ query,
112
+ feedbackType: "helpful",
113
+ toolName: name,
114
+ resultCount,
115
+ sessionId: ctx.activeSessionId,
116
+ })
117
+ .catch(() => { });
118
+ }
119
+ }
97
120
  }
98
121
  /**
99
122
  * Extract a semantic query string from tool arguments.
@@ -39,6 +39,8 @@ export declare function formatNavigationResults(results: Array<{
39
39
  score: number;
40
40
  graphExpanded?: boolean;
41
41
  }>): string;
42
+ /** Format pagination footer for list tools */
43
+ export declare function paginationFooter(count: number, limit: number, offset: number): string;
42
44
  /** Format a simple list of files with scores */
43
45
  export declare function formatFileList(files: Array<{
44
46
  file: string;
@@ -80,6 +80,18 @@ export function formatNavigationResults(results) {
80
80
  return out;
81
81
  }).join('\n\n');
82
82
  }
83
+ /** Format pagination footer for list tools */
84
+ export function paginationFooter(count, limit, offset) {
85
+ const hasMore = count >= limit;
86
+ if (!hasMore && offset === 0)
87
+ return "";
88
+ let footer = `\n---\n_Showing ${offset + 1}–${offset + count}`;
89
+ if (hasMore) {
90
+ footer += ` | More results available (offset: ${offset + limit})`;
91
+ }
92
+ footer += "_\n";
93
+ return footer;
94
+ }
83
95
  /** Format a simple list of files with scores */
84
96
  export function formatFileList(files, emptyMessage = "No files found.") {
85
97
  if (!files || files.length === 0)
package/dist/index.js CHANGED
@@ -10,12 +10,11 @@
10
10
  * - PROJECT_PATH: Path to project codebase for indexing
11
11
  * - RAG_API_URL: URL of the shared RAG API (default: http://localhost:3100)
12
12
  */
13
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
13
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
14
14
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
15
- import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
16
15
  import { createApiClient } from "./api-client.js";
17
- import { ToolRegistry } from "./tool-registry.js";
18
16
  import { ContextEnricher } from "./context-enrichment.js";
17
+ import { wrapHandler } from "./tool-middleware.js";
19
18
  // Tool modules
20
19
  import { createSearchTools } from "./tools/search.js";
21
20
  import { createAskTools } from "./tools/ask.js";
@@ -51,59 +50,77 @@ const ctx = {
51
50
  collectionPrefix: COLLECTION_PREFIX,
52
51
  enrichmentEnabled: true,
53
52
  };
54
- // Build tool registry from modules
55
- const registry = new ToolRegistry();
56
- registry.register(createSearchTools(PROJECT_NAME));
57
- registry.register(createAskTools(PROJECT_NAME));
58
- registry.register(createIndexingTools(PROJECT_NAME));
59
- registry.register(createMemoryTools(PROJECT_NAME));
60
- registry.register(createArchitectureTools(PROJECT_NAME));
61
- registry.register(createDatabaseTools(PROJECT_NAME));
62
- registry.register(createConfluenceTools(PROJECT_NAME));
63
- registry.register(createPmTools(PROJECT_NAME));
64
- registry.register(createReviewTools(PROJECT_NAME));
65
- registry.register(createAnalyticsTools(PROJECT_NAME));
66
- registry.register(createClusteringTools(PROJECT_NAME));
67
- registry.register(createSessionTools(PROJECT_NAME, ctx));
68
- registry.register(createFeedbackTools(PROJECT_NAME));
69
- registry.register(createSuggestionTools(PROJECT_NAME));
70
- registry.register(createCacheTools(PROJECT_NAME));
71
- registry.register(createGuidelinesTools(PROJECT_NAME));
72
- registry.register(createAdvancedTools(PROJECT_NAME));
73
- registry.register(createAgentTools(PROJECT_NAME));
74
- // Initialize context enrichment middleware
53
+ // Context enrichment middleware
75
54
  const enricher = new ContextEnricher({
76
55
  maxAutoRecall: 3,
77
56
  minRelevance: 0.6,
78
57
  timeoutMs: 2000,
79
58
  });
80
- registry.setEnricher(enricher);
81
- // MCP Server
82
- const server = new Server({
83
- name: `${PROJECT_NAME}-rag`,
84
- version: "1.0.0",
85
- }, {
86
- capabilities: {
87
- tools: {},
88
- },
89
- });
90
- // List tools handler
91
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
92
- tools: registry.getTools(),
93
- }));
94
- // Call tool handler
95
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
96
- const { name, arguments: args } = request.params;
97
- const result = await registry.handle(name, args || {}, ctx);
98
- return {
99
- content: [{ type: "text", text: result }],
100
- };
101
- });
59
+ // Collect all tool specs from modules
60
+ const allSpecs = [
61
+ ...createSearchTools(PROJECT_NAME),
62
+ ...createAskTools(PROJECT_NAME),
63
+ ...createIndexingTools(PROJECT_NAME),
64
+ ...createMemoryTools(PROJECT_NAME),
65
+ ...createArchitectureTools(PROJECT_NAME),
66
+ ...createDatabaseTools(PROJECT_NAME),
67
+ ...createConfluenceTools(PROJECT_NAME),
68
+ ...createPmTools(PROJECT_NAME),
69
+ ...createReviewTools(PROJECT_NAME),
70
+ ...createAnalyticsTools(PROJECT_NAME),
71
+ ...createClusteringTools(PROJECT_NAME),
72
+ ...createSessionTools(PROJECT_NAME, ctx),
73
+ ...createFeedbackTools(PROJECT_NAME),
74
+ ...createSuggestionTools(PROJECT_NAME),
75
+ ...createCacheTools(PROJECT_NAME),
76
+ ...createGuidelinesTools(PROJECT_NAME),
77
+ ...createAdvancedTools(PROJECT_NAME),
78
+ ...createAgentTools(PROJECT_NAME),
79
+ ];
80
+ // MCP Server (modern McpServer API with native Zod validation)
81
+ const server = new McpServer({ name: `${PROJECT_NAME}-rag`, version: "1.0.5" }, { capabilities: { tools: {} } });
82
+ // Register all tools with McpServer using wrapHandler middleware
83
+ for (const spec of allSpecs) {
84
+ const wrapped = wrapHandler(spec.name, spec.handler, { enricher, ctx });
85
+ server.registerTool(spec.name, {
86
+ description: spec.description,
87
+ inputSchema: spec.schema,
88
+ ...(spec.outputSchema ? { outputSchema: spec.outputSchema } : {}),
89
+ annotations: spec.annotations,
90
+ }, async (args) => {
91
+ const result = await wrapped(args, ctx);
92
+ if (typeof result === "string") {
93
+ return { content: [{ type: "text", text: result }] };
94
+ }
95
+ return {
96
+ content: [{ type: "text", text: result.text }],
97
+ structuredContent: result.structured,
98
+ };
99
+ });
100
+ }
101
+ // Graceful shutdown: close active session on exit
102
+ async function cleanup() {
103
+ if (ctx.activeSessionId) {
104
+ try {
105
+ await api.post(`/api/session/${ctx.activeSessionId}/end`, {
106
+ projectName: PROJECT_NAME,
107
+ summary: "Session ended by MCP server shutdown",
108
+ autoSaveLearnings: true,
109
+ });
110
+ }
111
+ catch {
112
+ // Best-effort, don't block shutdown
113
+ }
114
+ }
115
+ process.exit(0);
116
+ }
117
+ process.on("SIGINT", cleanup);
118
+ process.on("SIGTERM", cleanup);
102
119
  // Start server
103
120
  async function main() {
104
121
  const transport = new StdioServerTransport();
105
122
  await server.connect(transport);
106
123
  console.error(`${PROJECT_NAME} RAG MCP server running (collection prefix: ${COLLECTION_PREFIX})`);
107
- console.error(`Registered ${registry.getTools().length} tools from 18 modules`);
124
+ console.error(`Registered ${allSpecs.length} tools from 18 modules`);
108
125
  }
109
126
  main().catch(console.error);
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Common Zod schemas shared across tool modules.
3
+ *
4
+ * Import individual shapes into each tool module when migrating
5
+ * from raw JSON Schema objects to Zod-based inputSchema definitions.
6
+ */
7
+ import { z } from "zod";
8
+ import type { ToolInputSchema } from "./types.js";
9
+ /**
10
+ * Convert a Zod object schema to the MCP ToolInputSchema format.
11
+ * Used during Phase 2 migration while ToolRegistry still expects raw JSON Schema.
12
+ * Phase 3 passes Zod schemas directly to McpServer.registerTool().
13
+ */
14
+ export declare function zodToInputSchema(schema: z.ZodObject<z.ZodRawShape>): ToolInputSchema;
15
+ export declare const QueryStr: z.ZodString;
16
+ export declare const Limit: z.ZodDefault<z.ZodNumber>;
17
+ export declare const Offset: z.ZodDefault<z.ZodNumber>;
18
+ export declare const FilePath: z.ZodString;
19
+ export declare const FilePaths: z.ZodArray<z.ZodString, "many">;
20
+ export declare const Content: z.ZodString;
21
+ export declare const CollectionSuffix: z.ZodString;
22
+ export declare const MemoryType: z.ZodEnum<["decision", "insight", "pattern", "adr", "tech_debt", "todo", "architecture", "convention", "bug_fix", "optimization"]>;
23
+ export declare const ResponseFormat: z.ZodDefault<z.ZodEnum<["json", "markdown"]>>;
24
+ export declare const Importance: z.ZodDefault<z.ZodEnum<["low", "medium", "high", "critical"]>>;
25
+ export declare const Priority: z.ZodEnum<["low", "medium", "high", "critical"]>;
26
+ export declare const Severity: z.ZodEnum<["low", "medium", "high", "critical"]>;
27
+ export declare const PaginationParams: z.ZodObject<{
28
+ limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
29
+ offset: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
30
+ }, "strip", z.ZodTypeAny, {
31
+ limit?: number | undefined;
32
+ offset?: number | undefined;
33
+ }, {
34
+ limit?: number | undefined;
35
+ offset?: number | undefined;
36
+ }>;
37
+ export declare const SearchFilters: z.ZodOptional<z.ZodObject<{
38
+ file_type: z.ZodOptional<z.ZodString>;
39
+ directory: z.ZodOptional<z.ZodString>;
40
+ }, "strip", z.ZodTypeAny, {
41
+ file_type?: string | undefined;
42
+ directory?: string | undefined;
43
+ }, {
44
+ file_type?: string | undefined;
45
+ directory?: string | undefined;
46
+ }>>;
47
+ export declare const Tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
48
+ export declare const Confidence: z.ZodOptional<z.ZodNumber>;
49
+ /** Base shape for search tools: query + optional limit + optional filters */
50
+ export declare const SearchInput: z.ZodObject<{
51
+ query: z.ZodString;
52
+ limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
53
+ filters: z.ZodOptional<z.ZodObject<{
54
+ file_type: z.ZodOptional<z.ZodString>;
55
+ directory: z.ZodOptional<z.ZodString>;
56
+ }, "strip", z.ZodTypeAny, {
57
+ file_type?: string | undefined;
58
+ directory?: string | undefined;
59
+ }, {
60
+ file_type?: string | undefined;
61
+ directory?: string | undefined;
62
+ }>>;
63
+ }, "strip", z.ZodTypeAny, {
64
+ query: string;
65
+ limit?: number | undefined;
66
+ filters?: {
67
+ file_type?: string | undefined;
68
+ directory?: string | undefined;
69
+ } | undefined;
70
+ }, {
71
+ query: string;
72
+ limit?: number | undefined;
73
+ filters?: {
74
+ file_type?: string | undefined;
75
+ directory?: string | undefined;
76
+ } | undefined;
77
+ }>;
78
+ /** Base shape for memory record tools */
79
+ export declare const MemoryRecordInput: z.ZodObject<{
80
+ content: z.ZodString;
81
+ type: z.ZodEnum<["decision", "insight", "pattern", "adr", "tech_debt", "todo", "architecture", "convention", "bug_fix", "optimization"]>;
82
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
83
+ importance: z.ZodOptional<z.ZodDefault<z.ZodEnum<["low", "medium", "high", "critical"]>>>;
84
+ context: z.ZodOptional<z.ZodString>;
85
+ }, "strip", z.ZodTypeAny, {
86
+ type: "decision" | "insight" | "todo" | "adr" | "pattern" | "tech_debt" | "architecture" | "convention" | "bug_fix" | "optimization";
87
+ content: string;
88
+ context?: string | undefined;
89
+ tags?: string[] | undefined;
90
+ importance?: "low" | "medium" | "high" | "critical" | undefined;
91
+ }, {
92
+ type: "decision" | "insight" | "todo" | "adr" | "pattern" | "tech_debt" | "architecture" | "convention" | "bug_fix" | "optimization";
93
+ content: string;
94
+ context?: string | undefined;
95
+ tags?: string[] | undefined;
96
+ importance?: "low" | "medium" | "high" | "critical" | undefined;
97
+ }>;
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Common Zod schemas shared across tool modules.
3
+ *
4
+ * Import individual shapes into each tool module when migrating
5
+ * from raw JSON Schema objects to Zod-based inputSchema definitions.
6
+ */
7
+ import { z } from "zod";
8
+ import { zodToJsonSchema } from "zod-to-json-schema";
9
+ // ── JSON Schema conversion ──────────────────────────────────
10
+ /**
11
+ * Convert a Zod object schema to the MCP ToolInputSchema format.
12
+ * Used during Phase 2 migration while ToolRegistry still expects raw JSON Schema.
13
+ * Phase 3 passes Zod schemas directly to McpServer.registerTool().
14
+ */
15
+ export function zodToInputSchema(schema) {
16
+ const jsonSchema = zodToJsonSchema(schema, { target: "openApi3" });
17
+ return {
18
+ type: "object",
19
+ properties: (jsonSchema.properties ?? {}),
20
+ ...(Array.isArray(jsonSchema.required) && jsonSchema.required.length > 0
21
+ ? { required: jsonSchema.required }
22
+ : {}),
23
+ };
24
+ }
25
+ // ── Primitives ──────────────────────────────────────────────
26
+ export const QueryStr = z
27
+ .string()
28
+ .min(1)
29
+ .describe("Search query or question");
30
+ export const Limit = z
31
+ .number()
32
+ .int()
33
+ .min(1)
34
+ .max(100)
35
+ .default(20)
36
+ .describe("Maximum results to return");
37
+ export const Offset = z
38
+ .number()
39
+ .int()
40
+ .min(0)
41
+ .default(0)
42
+ .describe("Pagination offset");
43
+ export const FilePath = z
44
+ .string()
45
+ .min(1)
46
+ .describe("File path relative to project root");
47
+ export const FilePaths = z
48
+ .array(FilePath)
49
+ .min(1)
50
+ .describe("List of file paths");
51
+ export const Content = z
52
+ .string()
53
+ .min(1)
54
+ .describe("Text content");
55
+ export const CollectionSuffix = z
56
+ .string()
57
+ .min(1)
58
+ .describe("Collection suffix (e.g. 'codebase', 'docs')");
59
+ // ── Enums ───────────────────────────────────────────────────
60
+ export const MemoryType = z.enum([
61
+ "decision",
62
+ "insight",
63
+ "pattern",
64
+ "adr",
65
+ "tech_debt",
66
+ "todo",
67
+ "architecture",
68
+ "convention",
69
+ "bug_fix",
70
+ "optimization",
71
+ ]);
72
+ export const ResponseFormat = z
73
+ .enum(["json", "markdown"])
74
+ .default("markdown")
75
+ .describe("Output format");
76
+ export const Importance = z
77
+ .enum(["low", "medium", "high", "critical"])
78
+ .default("medium")
79
+ .describe("Importance level");
80
+ export const Priority = z
81
+ .enum(["low", "medium", "high", "critical"])
82
+ .describe("Priority level");
83
+ export const Severity = z
84
+ .enum(["low", "medium", "high", "critical"])
85
+ .describe("Severity level");
86
+ // ── Reusable object shapes ──────────────────────────────────
87
+ export const PaginationParams = z.object({
88
+ limit: Limit.optional(),
89
+ offset: Offset.optional(),
90
+ });
91
+ export const SearchFilters = z
92
+ .object({
93
+ file_type: z
94
+ .string()
95
+ .optional()
96
+ .describe("Filter by file extension (e.g. 'ts', 'py')"),
97
+ directory: z
98
+ .string()
99
+ .optional()
100
+ .describe("Filter by directory prefix"),
101
+ })
102
+ .optional()
103
+ .describe("Search filters");
104
+ export const Tags = z
105
+ .array(z.string())
106
+ .optional()
107
+ .describe("Tags for categorization");
108
+ export const Confidence = z
109
+ .number()
110
+ .min(0)
111
+ .max(1)
112
+ .optional()
113
+ .describe("Confidence score (0-1)");
114
+ // ── Composite input shapes ──────────────────────────────────
115
+ /** Base shape for search tools: query + optional limit + optional filters */
116
+ export const SearchInput = z.object({
117
+ query: QueryStr,
118
+ limit: Limit.optional(),
119
+ filters: SearchFilters,
120
+ });
121
+ /** Base shape for memory record tools */
122
+ export const MemoryRecordInput = z.object({
123
+ content: Content.describe("Content to remember"),
124
+ type: MemoryType,
125
+ tags: Tags,
126
+ importance: Importance.optional(),
127
+ context: z.string().optional().describe("Additional context"),
128
+ });