codesearch-mcp 0.0.14-alpha → 0.0.16-alpha
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/CHANGELOG.md +30 -0
- package/README.md +2 -0
- package/dist/src/db/index.d.ts +2 -3
- package/dist/src/db/index.js +5 -7
- package/dist/src/db/schema.d.ts +417 -0
- package/dist/src/db/schema.js +36 -0
- package/dist/src/interfaces/IAstParser.d.ts +6 -0
- package/dist/src/services/AstParserService.d.ts +3 -0
- package/dist/src/services/AstParserService.js +92 -20
- package/dist/src/services/DatabaseService.d.ts +11 -4
- package/dist/src/services/DatabaseService.js +89 -48
- package/dist/src/services/IndexerService.d.ts +2 -0
- package/dist/src/services/IndexerService.js +88 -44
- package/dist/src/services/McpServer.js +55 -16
- package/package.json +4 -4
|
@@ -48,29 +48,67 @@ const PKG_VERSION = (() => {
|
|
|
48
48
|
return '0.0.0';
|
|
49
49
|
}
|
|
50
50
|
})();
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
function buildInstructions(t) {
|
|
52
|
+
return `
|
|
53
|
+
You have access to a local code intelligence server. Use these tools to search codebases by meaning, navigate import graphs, look up symbol definitions, and read source files.
|
|
54
|
+
|
|
55
|
+
## Step 0 — Classify your query before starting
|
|
56
|
+
|
|
57
|
+
Pick one workflow based on what you need:
|
|
58
|
+
|
|
59
|
+
| Type | Signals | Workflow |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| **Lookup** | "where is X defined", "find Y" | find_symbol (if name known) → search_codebase (if not found) |
|
|
62
|
+
| **Conceptual** | "how does X work", "what is Y" | search_codebase → read_file_range |
|
|
63
|
+
| **Flow audit** | "how does X connect to Y", "audit this flow", "trace the path" | search_codebase → **get_dependencies + get_dependents** → Grep |
|
|
64
|
+
| **Impact** | "what would break if I change X", "what uses Z" | get_dependents → search_codebase for context |
|
|
65
|
+
|
|
66
|
+
> **No results?** Never conclude the code doesn't exist after a single attempt. Retry with \`threshold\` raised by 0.05–0.10 (e.g. 0.45 → 0.50 → 0.55) before giving up. The code may exist under a different name or domain term.
|
|
53
67
|
|
|
54
68
|
## Tools
|
|
55
69
|
|
|
56
70
|
- **list_projects** — call this first to see what projects are indexed and their exact names.
|
|
57
71
|
- **search_codebase** — semantic search across indexed source files. Returns file path, line number, and a code chunk.
|
|
58
|
-
- **read_file_range** — read a specific line range from any indexed file.
|
|
72
|
+
- **read_file_range** — read a specific line range from any indexed file. Expects a **relative path** as returned by search_codebase.
|
|
59
73
|
- **get_dependencies** — show what files a given file imports (direct or transitive). Use to understand what a file depends on.
|
|
60
74
|
- **get_dependents** — show which files import a given file (reverse graph). Use before refactoring to find all callers.
|
|
61
75
|
- **find_symbol** — find where a symbol (function, class, type, interface, variable, method) is defined by exact name. Faster than semantic search when you know the name.
|
|
62
76
|
- **list_files** — browse the directory tree of a project path. Use to understand project structure before reading files.
|
|
63
|
-
- **read_file** — read a complete file by absolute path with line numbers. Truncates at max_lines with a hint to continue.
|
|
77
|
+
- **read_file** — read a complete file by **absolute path** with line numbers. Truncates at max_lines with a hint to continue.
|
|
64
78
|
|
|
65
79
|
## Recommended workflow
|
|
66
80
|
|
|
81
|
+
### Lookup / Conceptual
|
|
67
82
|
1. Use \`list_projects\` to discover available projects before filtering by \`project\`.
|
|
68
|
-
2.
|
|
69
|
-
3.
|
|
70
|
-
4.
|
|
71
|
-
5. Use \`find_symbol\` when you know the exact name
|
|
72
|
-
6. Use \`list_files\` to explore project structure
|
|
73
|
-
|
|
83
|
+
2. Use \`search_codebase\` to find relevant code by meaning. If your query uses an ambiguous term (e.g. "subscription" could mean pub/sub or billing), pass a lower \`threshold\` (e.g. \`0.40–0.45\`) to filter out weak matches.
|
|
84
|
+
3. If a result looks **truncated or incomplete**, call \`read_file_range\` with the returned \`file_path\` and \`start_line\`.
|
|
85
|
+
4. For exploratory searches where results span chunk boundaries, pass \`include_neighbors: true\`.
|
|
86
|
+
5. Use \`find_symbol\` when you know the exact name — faster than semantic search. Use \`kind: "method"\` for class methods — grep matches lines where \`public\`, \`async\`, \`static\`, or \`override\` appears before the name.
|
|
87
|
+
6. Use \`list_files\` to explore project structure before diving into files. Use \`read_file\` to read a complete file by absolute path.
|
|
88
|
+
|
|
89
|
+
### Flow audit (mandatory steps — do not skip 3 and 4)
|
|
90
|
+
1. Use \`list_projects\` to confirm project names.
|
|
91
|
+
2. Use \`search_codebase\` to find the **central file** (entry point of the flow).
|
|
92
|
+
3. **\`get_dependencies(central_file)\`** — what does this file import? Catches configs, loaders, Redis clients, types.
|
|
93
|
+
4. **\`get_dependents(central_file)\`** — who calls this file? Catches resolvers, routes, socket handlers.
|
|
94
|
+
5. For each peripheral file found in steps 3–4: use \`read_file_range\` or \`find_symbol\` to inspect it.
|
|
95
|
+
6. Only after steps 3–4 draw architectural conclusions — \`search_codebase\` alone misses peripheral files because they are semantically thin (configs, types, loaders contain no domain vocabulary).
|
|
96
|
+
|
|
97
|
+
> **Note:** If \`get_dependencies\` / \`get_dependents\` return empty, the file likely uses path aliases (e.g. \`@core/\`, \`@/\`, \`@db/\`). Fall back to \`Grep\` on the symbol name across the project.
|
|
98
|
+
|
|
99
|
+
### Impact analysis
|
|
100
|
+
1. \`get_dependents(target_file)\` — direct callers.
|
|
101
|
+
2. \`get_dependents(target_file, transitive: true)\` — full reverse graph.
|
|
102
|
+
3. \`search_codebase\` for context on unfamiliar dependents.
|
|
103
|
+
|
|
104
|
+
## When to use read_file_range vs include_neighbors
|
|
105
|
+
|
|
106
|
+
- **include_neighbors: true** — good when context is fragmented across chunks (e.g. a class definition split across chunks).
|
|
107
|
+
- **read_file_range** — better for a precise section, or when one result is cut off.
|
|
108
|
+
|
|
109
|
+
## Handling Code Structure
|
|
110
|
+
- **Class/Function limits**: Chunks often end abruptly. Use \`read_file_range\` to find the closing brace or method start.
|
|
111
|
+
- **Cross-file references**: If you see \`this.validator.validate(data)\`, use \`search_codebase\` to find \`validator\`.
|
|
74
112
|
|
|
75
113
|
## Dependency graph
|
|
76
114
|
|
|
@@ -80,8 +118,9 @@ If \`get_dependents\` returns 0 results, add \`symbol\` (the exported name you c
|
|
|
80
118
|
|
|
81
119
|
## Relevance scores
|
|
82
120
|
|
|
83
|
-
Lower score = better match (cosine distance). Results above the configured threshold are filtered out automatically. Pass \`threshold\` to \`search_codebase\` to override per-query
|
|
121
|
+
Lower score = better match (cosine distance). Results above the configured threshold are filtered out automatically. Treat scores above 0.50 as weak hints — verify with \`read_file_range\` or \`Grep\`. Pass \`threshold\` to \`search_codebase\` to override per-query: \`0.40–0.45\` for precise technical queries (known term, exact concept); \`${t}\` default (broad but reliable). Avoid \`0.35\` — too strict for DSL files (GraphQL, Prisma) and infrastructure code.
|
|
84
122
|
`.trim();
|
|
123
|
+
}
|
|
85
124
|
class McpServer {
|
|
86
125
|
searcher;
|
|
87
126
|
config;
|
|
@@ -92,7 +131,7 @@ class McpServer {
|
|
|
92
131
|
this.logger = logger;
|
|
93
132
|
}
|
|
94
133
|
async start(startupError) {
|
|
95
|
-
const server = new index_js_1.Server({ name: 'local-rag', version: PKG_VERSION }, { capabilities: { tools: {} }, instructions:
|
|
134
|
+
const server = new index_js_1.Server({ name: 'local-rag', version: PKG_VERSION }, { capabilities: { tools: {} }, instructions: buildInstructions(this.config.search.similarityThreshold) });
|
|
96
135
|
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
97
136
|
tools: [
|
|
98
137
|
{
|
|
@@ -105,14 +144,14 @@ class McpServer {
|
|
|
105
144
|
limit: { type: 'number', description: `Max results (default ${this.config.search.defaultLimit}, max ${this.config.search.maxLimit})` },
|
|
106
145
|
project: { type: 'string', description: 'Filter by project name (optional). Use list_projects to see available names.' },
|
|
107
146
|
include_neighbors: { type: 'boolean', description: 'Also include the chunk before and after each result from the same file (Small-to-Big retrieval). Useful when results look truncated.' },
|
|
108
|
-
threshold: { type: 'number', description: `Max cosine distance (0–1). Lower = stricter. Default: ${this.config.search.similarityThreshold}. Use
|
|
147
|
+
threshold: { type: 'number', description: `Max cosine distance (0–1). Lower = stricter. Default: ${this.config.search.similarityThreshold}. Use 0.40–0.45 for precise technical queries, 0.55–0.60 for broad exploration.` },
|
|
109
148
|
},
|
|
110
149
|
required: ['query'],
|
|
111
150
|
},
|
|
112
151
|
},
|
|
113
152
|
{
|
|
114
153
|
name: 'list_projects',
|
|
115
|
-
description: 'List all indexed projects with their chunk counts',
|
|
154
|
+
description: 'List all indexed projects with their chunk counts and metadata (description, stack, notes, relations from .ragmeta.json).',
|
|
116
155
|
inputSchema: { type: 'object', properties: {} },
|
|
117
156
|
},
|
|
118
157
|
{
|
|
@@ -185,11 +224,11 @@ class McpServer {
|
|
|
185
224
|
},
|
|
186
225
|
{
|
|
187
226
|
name: 'read_file',
|
|
188
|
-
description: 'Read a file
|
|
227
|
+
description: 'Read a file by absolute path. Returns contents with line numbers. Truncates at max_lines with a hint to continue with read_file_range.',
|
|
189
228
|
inputSchema: {
|
|
190
229
|
type: 'object',
|
|
191
230
|
properties: {
|
|
192
|
-
file_path: { type: 'string', description: 'Absolute path to the file
|
|
231
|
+
file_path: { type: 'string', description: 'Absolute path to the file. Note: search_codebase returns relative paths — construct the absolute path from your workspace root.' },
|
|
193
232
|
max_lines: { type: 'number', description: 'Maximum lines to return (default 300, max 1000)' },
|
|
194
233
|
},
|
|
195
234
|
required: ['file_path'],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codesearch-mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16-alpha",
|
|
4
4
|
"description": "Local semantic codebase search via MCP — indexes projects into pgvector, exposes search to Claude",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/app.js",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"files": [
|
|
13
13
|
"dist/",
|
|
14
14
|
"docker/",
|
|
15
|
-
"README.md"
|
|
15
|
+
"README.md",
|
|
16
|
+
"CHANGELOG.md"
|
|
16
17
|
],
|
|
17
18
|
"scripts": {
|
|
18
19
|
"build": "tsc",
|
|
@@ -33,14 +34,13 @@
|
|
|
33
34
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
34
35
|
"cli-progress": "^3.12.0",
|
|
35
36
|
"dotenv": "^17.4.2",
|
|
37
|
+
"drizzle-orm": "^0.45.2",
|
|
36
38
|
"ignore": "^7.0.5",
|
|
37
39
|
"ollama": "^0.5.0",
|
|
38
40
|
"pg": "^8.13.0",
|
|
39
41
|
"pino": "^10.3.1",
|
|
40
42
|
"pino-roll": "^4.0.0",
|
|
41
|
-
"reflect-metadata": "^0.2.2",
|
|
42
43
|
"ts-morph": "^28.0.0",
|
|
43
|
-
"typeorm": "^0.3.20",
|
|
44
44
|
"zod": "^4.3.6"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|