@unlimiting/qsc 0.1.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/chunker/ast.d.ts +7 -0
- package/dist/chunker/ast.d.ts.map +1 -0
- package/dist/chunker/ast.js +302 -0
- package/dist/chunker/ast.js.map +1 -0
- package/dist/chunker/index.d.ts +15 -0
- package/dist/chunker/index.d.ts.map +1 -0
- package/dist/chunker/index.js +26 -0
- package/dist/chunker/index.js.map +1 -0
- package/dist/chunker/languages/dart.d.ts +3 -0
- package/dist/chunker/languages/dart.d.ts.map +1 -0
- package/dist/chunker/languages/dart.js +22 -0
- package/dist/chunker/languages/dart.js.map +1 -0
- package/dist/chunker/languages/go.d.ts +3 -0
- package/dist/chunker/languages/go.d.ts.map +1 -0
- package/dist/chunker/languages/go.js +20 -0
- package/dist/chunker/languages/go.js.map +1 -0
- package/dist/chunker/languages/index.d.ts +12 -0
- package/dist/chunker/languages/index.d.ts.map +1 -0
- package/dist/chunker/languages/index.js +35 -0
- package/dist/chunker/languages/index.js.map +1 -0
- package/dist/chunker/languages/kotlin.d.ts +3 -0
- package/dist/chunker/languages/kotlin.d.ts.map +1 -0
- package/dist/chunker/languages/kotlin.js +23 -0
- package/dist/chunker/languages/kotlin.js.map +1 -0
- package/dist/chunker/languages/python.d.ts +3 -0
- package/dist/chunker/languages/python.d.ts.map +1 -0
- package/dist/chunker/languages/python.js +21 -0
- package/dist/chunker/languages/python.js.map +1 -0
- package/dist/chunker/languages/swift.d.ts +3 -0
- package/dist/chunker/languages/swift.d.ts.map +1 -0
- package/dist/chunker/languages/swift.js +24 -0
- package/dist/chunker/languages/swift.js.map +1 -0
- package/dist/chunker/languages/typescript.d.ts +4 -0
- package/dist/chunker/languages/typescript.d.ts.map +1 -0
- package/dist/chunker/languages/typescript.js +34 -0
- package/dist/chunker/languages/typescript.js.map +1 -0
- package/dist/chunker/token.d.ts +6 -0
- package/dist/chunker/token.d.ts.map +1 -0
- package/dist/chunker/token.js +107 -0
- package/dist/chunker/token.js.map +1 -0
- package/dist/collection.d.ts +22 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +154 -0
- package/dist/collection.js.map +1 -0
- package/dist/config/index.d.ts +95 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +103 -0
- package/dist/config/index.js.map +1 -0
- package/dist/embedder/index.d.ts +14 -0
- package/dist/embedder/index.d.ts.map +1 -0
- package/dist/embedder/index.js +18 -0
- package/dist/embedder/index.js.map +1 -0
- package/dist/embedder/local.d.ts +11 -0
- package/dist/embedder/local.d.ts.map +1 -0
- package/dist/embedder/local.js +60 -0
- package/dist/embedder/local.js.map +1 -0
- package/dist/embedder/openai.d.ts +10 -0
- package/dist/embedder/openai.d.ts.map +1 -0
- package/dist/embedder/openai.js +69 -0
- package/dist/embedder/openai.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +824 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/index.d.ts +17 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +18 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/local.d.ts +10 -0
- package/dist/llm/local.d.ts.map +1 -0
- package/dist/llm/local.js +76 -0
- package/dist/llm/local.js.map +1 -0
- package/dist/llm/openai.d.ts +10 -0
- package/dist/llm/openai.d.ts.map +1 -0
- package/dist/llm/openai.js +76 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/mcp.d.ts +3 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +393 -0
- package/dist/mcp.js.map +1 -0
- package/dist/scanner/git.d.ts +26 -0
- package/dist/scanner/git.d.ts.map +1 -0
- package/dist/scanner/git.js +134 -0
- package/dist/scanner/git.js.map +1 -0
- package/dist/scanner/index.d.ts +17 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +174 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/search/bm25.d.ts +17 -0
- package/dist/search/bm25.d.ts.map +1 -0
- package/dist/search/bm25.js +27 -0
- package/dist/search/bm25.js.map +1 -0
- package/dist/search/expander.d.ts +12 -0
- package/dist/search/expander.d.ts.map +1 -0
- package/dist/search/expander.js +60 -0
- package/dist/search/expander.js.map +1 -0
- package/dist/search/fusion.d.ts +32 -0
- package/dist/search/fusion.d.ts.map +1 -0
- package/dist/search/fusion.js +80 -0
- package/dist/search/fusion.js.map +1 -0
- package/dist/search/index.d.ts +61 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +137 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/reranker.d.ts +18 -0
- package/dist/search/reranker.d.ts.map +1 -0
- package/dist/search/reranker.js +56 -0
- package/dist/search/reranker.js.map +1 -0
- package/dist/search/vector.d.ts +23 -0
- package/dist/search/vector.d.ts.map +1 -0
- package/dist/search/vector.js +47 -0
- package/dist/search/vector.js.map +1 -0
- package/dist/store.d.ts +119 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +500 -0
- package/dist/store.js.map +1 -0
- package/package.json +48 -0
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import Database from "better-sqlite3";
|
|
6
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
import { createStore } from "./store.js";
|
|
9
|
+
import { createSearchPipeline } from "./search/index.js";
|
|
10
|
+
import { createEmbedder } from "./embedder/index.js";
|
|
11
|
+
import { createLLMProvider } from "./llm/index.js";
|
|
12
|
+
import { loadConfig } from "./config/index.js";
|
|
13
|
+
import { resolveCollectionDb, resolveCollectionSourcePath } from "./collection.js";
|
|
14
|
+
// --- Helpers ---
|
|
15
|
+
function resolveDbPathFromCollection(collectionName) {
|
|
16
|
+
if (collectionName) {
|
|
17
|
+
return resolveCollectionDb(collectionName);
|
|
18
|
+
}
|
|
19
|
+
// Fallback: environment variable QSC_COLLECTION
|
|
20
|
+
const envCollection = process.env.QSC_COLLECTION;
|
|
21
|
+
if (envCollection) {
|
|
22
|
+
return resolveCollectionDb(envCollection);
|
|
23
|
+
}
|
|
24
|
+
// Legacy fallback: QSC_DB_PATH
|
|
25
|
+
if (process.env.QSC_DB_PATH) {
|
|
26
|
+
return resolve(process.env.QSC_DB_PATH);
|
|
27
|
+
}
|
|
28
|
+
throw new Error("No collection specified. Set QSC_COLLECTION environment variable, use --collection flag, or set QSC_DB_PATH.");
|
|
29
|
+
}
|
|
30
|
+
function resolveConfigPath(collectionName) {
|
|
31
|
+
const name = collectionName ?? process.env.QSC_COLLECTION;
|
|
32
|
+
if (name) {
|
|
33
|
+
try {
|
|
34
|
+
return resolveCollectionSourcePath(name);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
function getVersion() {
|
|
43
|
+
try {
|
|
44
|
+
const pkgPath = new URL("../package.json", import.meta.url);
|
|
45
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
46
|
+
return pkg.version ?? "0.1.0";
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return "0.1.0";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function formatBM25Result(r) {
|
|
53
|
+
const lineInfo = r.start_line != null ? `:${r.start_line}-${r.end_line ?? ""}` : "";
|
|
54
|
+
const nameInfo = r.name ? ` (${r.name})` : "";
|
|
55
|
+
const typeInfo = r.chunk_type ? ` [${r.chunk_type}]` : "";
|
|
56
|
+
return [
|
|
57
|
+
`## ${r.file_path}${lineInfo}${nameInfo}${typeInfo}`,
|
|
58
|
+
`Chunk ID: ${r.chunk_id} | rank: ${r.rank}`,
|
|
59
|
+
"```",
|
|
60
|
+
r.content,
|
|
61
|
+
"```",
|
|
62
|
+
].join("\n");
|
|
63
|
+
}
|
|
64
|
+
function formatSearchResult(r) {
|
|
65
|
+
const lineInfo = r.startLine != null ? `:${r.startLine}-${r.endLine ?? ""}` : "";
|
|
66
|
+
const nameInfo = r.name ? ` (${r.name})` : "";
|
|
67
|
+
const typeInfo = r.chunkType ? ` [${r.chunkType}]` : "";
|
|
68
|
+
const scoreParts = [];
|
|
69
|
+
if (r.scores.bm25 != null)
|
|
70
|
+
scoreParts.push(`bm25=${r.scores.bm25.toFixed(4)}`);
|
|
71
|
+
if (r.scores.vector != null)
|
|
72
|
+
scoreParts.push(`vector=${r.scores.vector.toFixed(4)}`);
|
|
73
|
+
if (r.scores.rrf != null)
|
|
74
|
+
scoreParts.push(`rrf=${r.scores.rrf.toFixed(4)}`);
|
|
75
|
+
if (r.scores.rerank != null)
|
|
76
|
+
scoreParts.push(`rerank=${r.scores.rerank.toFixed(4)}`);
|
|
77
|
+
const scoreDetail = scoreParts.length > 0 ? `\nScores: ${scoreParts.join(", ")}` : "";
|
|
78
|
+
return [
|
|
79
|
+
`## ${r.filePath}${lineInfo}${nameInfo}${typeInfo} | score: ${r.score.toFixed(4)}`,
|
|
80
|
+
`Chunk ID: ${r.chunkId}${scoreDetail}`,
|
|
81
|
+
"```",
|
|
82
|
+
r.content,
|
|
83
|
+
"```",
|
|
84
|
+
].join("\n");
|
|
85
|
+
}
|
|
86
|
+
// --- Parse --collection from process.argv ---
|
|
87
|
+
function parseCollectionArg() {
|
|
88
|
+
const args = process.argv.slice(2);
|
|
89
|
+
for (let i = 0; i < args.length; i++) {
|
|
90
|
+
if (args[i] === "--collection" && i + 1 < args.length) {
|
|
91
|
+
return args[i + 1];
|
|
92
|
+
}
|
|
93
|
+
if (args[i].startsWith("--collection=")) {
|
|
94
|
+
return args[i].split("=")[1];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
// --- Main entry point ---
|
|
100
|
+
export async function startMcpServer() {
|
|
101
|
+
const collectionName = parseCollectionArg();
|
|
102
|
+
const dbPath = resolveDbPathFromCollection(collectionName);
|
|
103
|
+
if (!existsSync(dbPath)) {
|
|
104
|
+
const name = collectionName ?? process.env.QSC_COLLECTION ?? "(unknown)";
|
|
105
|
+
console.error(`Error: Database not found at ${dbPath}\n` +
|
|
106
|
+
`Run 'qsc init ${name} <path>' first to create the collection.`);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
const configPath = resolveConfigPath(collectionName);
|
|
110
|
+
const config = loadConfig(configPath);
|
|
111
|
+
const version = getVersion();
|
|
112
|
+
const displayName = collectionName ?? process.env.QSC_COLLECTION ?? "default";
|
|
113
|
+
// Create main store (read-write, for search operations)
|
|
114
|
+
const store = createStore(dbPath);
|
|
115
|
+
store.initDb(config.embedder.dimensions);
|
|
116
|
+
// Open a read-only connection for get_chunk queries
|
|
117
|
+
const readDb = new Database(dbPath, { readonly: true });
|
|
118
|
+
const getChunkStmt = readDb.prepare(`
|
|
119
|
+
SELECT
|
|
120
|
+
c.id, c.content, c.name, c.chunk_type,
|
|
121
|
+
c.start_line, c.end_line, c.seq,
|
|
122
|
+
f.path AS file_path, f.repo_id
|
|
123
|
+
FROM chunks c
|
|
124
|
+
JOIN files f ON c.file_id = f.id
|
|
125
|
+
WHERE c.id = ?
|
|
126
|
+
`);
|
|
127
|
+
const findRepoStmt = readDb.prepare(`
|
|
128
|
+
SELECT f.repo_id FROM files f WHERE f.path = ? AND f.active = 1 LIMIT 1
|
|
129
|
+
`);
|
|
130
|
+
// Create MCP server
|
|
131
|
+
const server = new McpServer({ name: "qsc", version }, {
|
|
132
|
+
instructions: `QSC (Query Source Code) - Collection: ${displayName}. ` +
|
|
133
|
+
"Search and explore indexed source code repositories. " +
|
|
134
|
+
"Use 'search' for fast BM25 text search, 'query' for full hybrid search (BM25 + vector + LLM reranking), " +
|
|
135
|
+
"'get_file' to retrieve a file's chunks, 'get_chunk' for a specific chunk, and 'status' for index statistics.",
|
|
136
|
+
});
|
|
137
|
+
// Lazily initialized search pipeline components
|
|
138
|
+
let embedder;
|
|
139
|
+
let llmProvider;
|
|
140
|
+
let searchPipeline;
|
|
141
|
+
async function getSearchPipeline() {
|
|
142
|
+
if (searchPipeline)
|
|
143
|
+
return searchPipeline;
|
|
144
|
+
try {
|
|
145
|
+
embedder = await createEmbedder(config.embedder);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// Vector search unavailable
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
llmProvider = await createLLMProvider(config.llm);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// LLM unavailable
|
|
155
|
+
}
|
|
156
|
+
searchPipeline = createSearchPipeline(store, embedder, llmProvider);
|
|
157
|
+
return searchPipeline;
|
|
158
|
+
}
|
|
159
|
+
// --- Tool: search (BM25) ---
|
|
160
|
+
server.registerTool("search", {
|
|
161
|
+
title: "BM25 Search",
|
|
162
|
+
description: "Fast full-text search using BM25 ranking. Best for keyword-based queries. " +
|
|
163
|
+
"Returns matching code chunks with file paths, line numbers, and relevance scores.",
|
|
164
|
+
inputSchema: z.object({
|
|
165
|
+
query: z.string().describe("Search query text"),
|
|
166
|
+
limit: z
|
|
167
|
+
.number()
|
|
168
|
+
.int()
|
|
169
|
+
.min(1)
|
|
170
|
+
.max(100)
|
|
171
|
+
.optional()
|
|
172
|
+
.describe("Maximum number of results (default: 20)"),
|
|
173
|
+
}),
|
|
174
|
+
}, async ({ query, limit }) => {
|
|
175
|
+
if (!query.trim()) {
|
|
176
|
+
return {
|
|
177
|
+
content: [{ type: "text", text: "Error: query must not be empty" }],
|
|
178
|
+
isError: true,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
const results = store.searchBM25(query, limit ?? 20);
|
|
182
|
+
if (results.length === 0) {
|
|
183
|
+
return { content: [{ type: "text", text: "No results found." }] };
|
|
184
|
+
}
|
|
185
|
+
const formatted = results.map(formatBM25Result).join("\n\n---\n\n");
|
|
186
|
+
return {
|
|
187
|
+
content: [
|
|
188
|
+
{ type: "text", text: `Found ${results.length} result(s):\n\n${formatted}` },
|
|
189
|
+
],
|
|
190
|
+
};
|
|
191
|
+
});
|
|
192
|
+
// --- Tool: query (hybrid search) ---
|
|
193
|
+
server.registerTool("query", {
|
|
194
|
+
title: "Hybrid Search",
|
|
195
|
+
description: "Full hybrid search combining BM25, vector similarity, and optional LLM reranking. " +
|
|
196
|
+
"Best for semantic and complex queries. May be slower than 'search' but provides better results.",
|
|
197
|
+
inputSchema: z.object({
|
|
198
|
+
query: z.string().describe("Search query text"),
|
|
199
|
+
limit: z
|
|
200
|
+
.number()
|
|
201
|
+
.int()
|
|
202
|
+
.min(1)
|
|
203
|
+
.max(100)
|
|
204
|
+
.optional()
|
|
205
|
+
.describe("Maximum number of results (default: 20)"),
|
|
206
|
+
expand: z
|
|
207
|
+
.boolean()
|
|
208
|
+
.optional()
|
|
209
|
+
.describe("Enable LLM query expansion (default: true if LLM available)"),
|
|
210
|
+
rerank: z
|
|
211
|
+
.boolean()
|
|
212
|
+
.optional()
|
|
213
|
+
.describe("Enable LLM reranking (default: true if LLM available)"),
|
|
214
|
+
}),
|
|
215
|
+
}, async ({ query, limit, expand, rerank }) => {
|
|
216
|
+
if (!query.trim()) {
|
|
217
|
+
return {
|
|
218
|
+
content: [{ type: "text", text: "Error: query must not be empty" }],
|
|
219
|
+
isError: true,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
const sp = await getSearchPipeline();
|
|
223
|
+
const mode = embedder ? "hybrid" : "bm25";
|
|
224
|
+
const shouldExpand = expand ?? !!llmProvider;
|
|
225
|
+
const shouldRerank = rerank ?? !!llmProvider;
|
|
226
|
+
const response = await sp.search(query, {
|
|
227
|
+
mode,
|
|
228
|
+
limit: limit ?? 20,
|
|
229
|
+
expand: shouldExpand,
|
|
230
|
+
rerank: shouldRerank,
|
|
231
|
+
});
|
|
232
|
+
if (response.results.length === 0) {
|
|
233
|
+
return { content: [{ type: "text", text: "No results found." }] };
|
|
234
|
+
}
|
|
235
|
+
const formatted = response.results.map(formatSearchResult).join("\n\n---\n\n");
|
|
236
|
+
const modeLabel = mode === "hybrid"
|
|
237
|
+
? `hybrid (expand=${shouldExpand}, rerank=${shouldRerank})`
|
|
238
|
+
: "bm25";
|
|
239
|
+
return {
|
|
240
|
+
content: [
|
|
241
|
+
{ type: "text", text: `Found ${response.results.length} result(s) [${modeLabel}]:\n\n${formatted}` },
|
|
242
|
+
],
|
|
243
|
+
};
|
|
244
|
+
});
|
|
245
|
+
// --- Tool: get_file ---
|
|
246
|
+
server.registerTool("get_file", {
|
|
247
|
+
title: "Get File",
|
|
248
|
+
description: "Retrieve a file's metadata and all its indexed chunks by file path. " +
|
|
249
|
+
"Returns file info (hash, language, active status) and chunk contents.",
|
|
250
|
+
inputSchema: z.object({
|
|
251
|
+
path: z.string().describe("Relative file path within the repository"),
|
|
252
|
+
repo_id: z
|
|
253
|
+
.string()
|
|
254
|
+
.optional()
|
|
255
|
+
.describe("Repository ID. If omitted, searches across all repositories."),
|
|
256
|
+
}),
|
|
257
|
+
}, async ({ path, repo_id }) => {
|
|
258
|
+
if (!path.trim()) {
|
|
259
|
+
return {
|
|
260
|
+
content: [{ type: "text", text: "Error: path must not be empty" }],
|
|
261
|
+
isError: true,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
let repoId = repo_id;
|
|
265
|
+
if (!repoId) {
|
|
266
|
+
const row = findRepoStmt.get(path);
|
|
267
|
+
repoId = row?.repo_id;
|
|
268
|
+
}
|
|
269
|
+
if (!repoId) {
|
|
270
|
+
return {
|
|
271
|
+
content: [
|
|
272
|
+
{ type: "text", text: `Error: File not found in index: ${path}. Specify repo_id if needed.` },
|
|
273
|
+
],
|
|
274
|
+
isError: true,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
const file = store.getFileByPath(repoId, path);
|
|
278
|
+
if (!file) {
|
|
279
|
+
return {
|
|
280
|
+
content: [
|
|
281
|
+
{ type: "text", text: `Error: File not found in index: ${path} (repo: ${repoId})` },
|
|
282
|
+
],
|
|
283
|
+
isError: true,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
const chunks = store.getChunksByFileId(file.id);
|
|
287
|
+
const fileMeta = [
|
|
288
|
+
`# ${file.path}`,
|
|
289
|
+
`- **ID**: ${file.id}`,
|
|
290
|
+
`- **Repository**: ${file.repo_id}`,
|
|
291
|
+
`- **Hash**: ${file.hash}`,
|
|
292
|
+
`- **Language**: ${file.language ?? "unknown"}`,
|
|
293
|
+
`- **Active**: ${file.active ? "yes" : "no"}`,
|
|
294
|
+
`- **Indexed at**: ${file.indexed_at ?? "unknown"}`,
|
|
295
|
+
`- **Chunks**: ${chunks.length}`,
|
|
296
|
+
].join("\n");
|
|
297
|
+
const chunkTexts = chunks.map((c) => {
|
|
298
|
+
const lineInfo = c.start_line != null ? `L${c.start_line}-${c.end_line}` : "";
|
|
299
|
+
const nameInfo = c.name ? ` ${c.name}` : "";
|
|
300
|
+
const typeInfo = c.chunk_type ? ` [${c.chunk_type}]` : "";
|
|
301
|
+
return `### Chunk #${c.seq} (ID: ${c.id}) ${lineInfo}${nameInfo}${typeInfo}\n\`\`\`\n${c.content}\n\`\`\``;
|
|
302
|
+
});
|
|
303
|
+
return {
|
|
304
|
+
content: [
|
|
305
|
+
{ type: "text", text: `${fileMeta}\n\n${chunkTexts.join("\n\n")}` },
|
|
306
|
+
],
|
|
307
|
+
};
|
|
308
|
+
});
|
|
309
|
+
// --- Tool: get_chunk ---
|
|
310
|
+
server.registerTool("get_chunk", {
|
|
311
|
+
title: "Get Chunk",
|
|
312
|
+
description: "Retrieve a specific code chunk by its ID. Returns the chunk content, metadata, and location.",
|
|
313
|
+
inputSchema: z.object({
|
|
314
|
+
chunk_id: z.number().int().describe("Chunk ID to retrieve"),
|
|
315
|
+
}),
|
|
316
|
+
}, async ({ chunk_id }) => {
|
|
317
|
+
const row = getChunkStmt.get(chunk_id);
|
|
318
|
+
if (!row) {
|
|
319
|
+
return {
|
|
320
|
+
content: [{ type: "text", text: `Error: Chunk not found: ${chunk_id}` }],
|
|
321
|
+
isError: true,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
const lineInfo = row.start_line != null ? `L${row.start_line}-${row.end_line}` : "";
|
|
325
|
+
const nameInfo = row.name ? ` (${row.name})` : "";
|
|
326
|
+
const typeInfo = row.chunk_type ? ` [${row.chunk_type}]` : "";
|
|
327
|
+
const text = [
|
|
328
|
+
`# Chunk ${row.id}${nameInfo}${typeInfo}`,
|
|
329
|
+
`- **File**: ${row.file_path} ${lineInfo}`,
|
|
330
|
+
`- **Repository**: ${row.repo_id}`,
|
|
331
|
+
`- **Sequence**: ${row.seq}`,
|
|
332
|
+
`- **Type**: ${row.chunk_type ?? "unknown"}`,
|
|
333
|
+
"",
|
|
334
|
+
"```",
|
|
335
|
+
row.content,
|
|
336
|
+
"```",
|
|
337
|
+
].join("\n");
|
|
338
|
+
return { content: [{ type: "text", text }] };
|
|
339
|
+
});
|
|
340
|
+
// --- Tool: status ---
|
|
341
|
+
server.registerTool("status", {
|
|
342
|
+
title: "Index Status",
|
|
343
|
+
description: "Get statistics about the QSC index: repository count, file count, chunk count, and embedding status.",
|
|
344
|
+
inputSchema: z.object({}),
|
|
345
|
+
}, async () => {
|
|
346
|
+
const stats = store.getStats();
|
|
347
|
+
const text = [
|
|
348
|
+
"# QSC Index Status",
|
|
349
|
+
`**Collection**: ${displayName}`,
|
|
350
|
+
"",
|
|
351
|
+
`| Metric | Value |`,
|
|
352
|
+
`|--------|-------|`,
|
|
353
|
+
`| Repositories | ${stats.repositories} |`,
|
|
354
|
+
`| Files (total) | ${stats.files} |`,
|
|
355
|
+
`| Files (active) | ${stats.active_files} |`,
|
|
356
|
+
`| Chunks | ${stats.chunks} |`,
|
|
357
|
+
`| Embedded chunks | ${stats.embedded_chunks} |`,
|
|
358
|
+
`| Pending embed | ${stats.pending_chunks} |`,
|
|
359
|
+
].join("\n");
|
|
360
|
+
return { content: [{ type: "text", text }] };
|
|
361
|
+
});
|
|
362
|
+
// --- Connect transport and start ---
|
|
363
|
+
const transport = new StdioServerTransport();
|
|
364
|
+
await server.connect(transport);
|
|
365
|
+
// Clean up on exit
|
|
366
|
+
const cleanup = () => {
|
|
367
|
+
try {
|
|
368
|
+
readDb.close();
|
|
369
|
+
}
|
|
370
|
+
catch { /* ignore */ }
|
|
371
|
+
try {
|
|
372
|
+
store.close();
|
|
373
|
+
}
|
|
374
|
+
catch { /* ignore */ }
|
|
375
|
+
};
|
|
376
|
+
process.on("SIGINT", () => { cleanup(); process.exit(0); });
|
|
377
|
+
process.on("SIGTERM", () => { cleanup(); process.exit(0); });
|
|
378
|
+
console.error(`QSC MCP server v${version} running on stdio`);
|
|
379
|
+
console.error(`Collection: ${displayName}`);
|
|
380
|
+
console.error(`Database: ${dbPath}`);
|
|
381
|
+
}
|
|
382
|
+
// Direct execution: only run when this file is the entry point
|
|
383
|
+
const isDirectRun = process.argv[1] &&
|
|
384
|
+
(import.meta.url.endsWith(process.argv[1]) ||
|
|
385
|
+
import.meta.url === `file://${process.argv[1]}` ||
|
|
386
|
+
import.meta.url === `file://${resolve(process.argv[1])}`);
|
|
387
|
+
if (isDirectRun) {
|
|
388
|
+
startMcpServer().catch((err) => {
|
|
389
|
+
console.error("Fatal error:", err);
|
|
390
|
+
process.exit(1);
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
//# sourceMappingURL=mcp.js.map
|
package/dist/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface GitChange {
|
|
2
|
+
status: "added" | "modified" | "deleted" | "renamed";
|
|
3
|
+
path: string;
|
|
4
|
+
oldPath?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface GitInfo {
|
|
7
|
+
currentCommit: string;
|
|
8
|
+
changes: GitChange[];
|
|
9
|
+
isFullScan: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get the current HEAD commit hash.
|
|
13
|
+
* Throws if the directory is not a git repository or has no commits.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getCurrentCommit(repoPath: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Check if a path is inside a git repository.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isGitRepository(repoPath: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Detect file changes between lastCommit and HEAD.
|
|
22
|
+
* If lastCommit is not provided, returns isFullScan=true with no change list
|
|
23
|
+
* (caller should do a full repository scan instead).
|
|
24
|
+
*/
|
|
25
|
+
export declare function detectChanges(repoPath: string, lastCommit?: string): GitInfo;
|
|
26
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/scanner/git.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB;AA6CD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQzD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CA2ET"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
// --- Helpers ---
|
|
4
|
+
function execGit(args, cwd) {
|
|
5
|
+
try {
|
|
6
|
+
return execSync(`git ${args}`, {
|
|
7
|
+
cwd,
|
|
8
|
+
encoding: "utf-8",
|
|
9
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
10
|
+
timeout: 30_000,
|
|
11
|
+
}).trim();
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
const err = error;
|
|
15
|
+
if (err.stderr?.includes("not a git repository")) {
|
|
16
|
+
throw new Error(`Not a git repository: ${cwd}`);
|
|
17
|
+
}
|
|
18
|
+
if (err.message?.includes("ENOENT")) {
|
|
19
|
+
throw new Error("git is not installed or not found in PATH");
|
|
20
|
+
}
|
|
21
|
+
throw new Error(`git command failed: git ${args}\n${err.stderr ?? err.message}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function parseStatusCode(code) {
|
|
25
|
+
switch (code[0]) {
|
|
26
|
+
case "A":
|
|
27
|
+
return "added";
|
|
28
|
+
case "M":
|
|
29
|
+
return "modified";
|
|
30
|
+
case "D":
|
|
31
|
+
return "deleted";
|
|
32
|
+
case "R":
|
|
33
|
+
return "renamed";
|
|
34
|
+
default:
|
|
35
|
+
return "modified"; // treat unknown as modified
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function isValidCommitHash(value) {
|
|
39
|
+
return /^[0-9a-f]{4,40}$/i.test(value);
|
|
40
|
+
}
|
|
41
|
+
// --- Public API ---
|
|
42
|
+
/**
|
|
43
|
+
* Get the current HEAD commit hash.
|
|
44
|
+
* Throws if the directory is not a git repository or has no commits.
|
|
45
|
+
*/
|
|
46
|
+
export function getCurrentCommit(repoPath) {
|
|
47
|
+
const cwd = resolve(repoPath);
|
|
48
|
+
return execGit("rev-parse HEAD", cwd);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Check if a path is inside a git repository.
|
|
52
|
+
*/
|
|
53
|
+
export function isGitRepository(repoPath) {
|
|
54
|
+
try {
|
|
55
|
+
const cwd = resolve(repoPath);
|
|
56
|
+
execGit("rev-parse --git-dir", cwd);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Detect file changes between lastCommit and HEAD.
|
|
65
|
+
* If lastCommit is not provided, returns isFullScan=true with no change list
|
|
66
|
+
* (caller should do a full repository scan instead).
|
|
67
|
+
*/
|
|
68
|
+
export function detectChanges(repoPath, lastCommit) {
|
|
69
|
+
const cwd = resolve(repoPath);
|
|
70
|
+
const currentCommit = getCurrentCommit(cwd);
|
|
71
|
+
if (!lastCommit) {
|
|
72
|
+
return {
|
|
73
|
+
currentCommit,
|
|
74
|
+
changes: [],
|
|
75
|
+
isFullScan: true,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// Validate commit hash format to prevent command injection
|
|
79
|
+
if (!isValidCommitHash(lastCommit)) {
|
|
80
|
+
return {
|
|
81
|
+
currentCommit,
|
|
82
|
+
changes: [],
|
|
83
|
+
isFullScan: true,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// Verify lastCommit exists
|
|
87
|
+
try {
|
|
88
|
+
execGit(`cat-file -t ${lastCommit}`, cwd);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// If lastCommit is not valid, fall back to full scan
|
|
92
|
+
return {
|
|
93
|
+
currentCommit,
|
|
94
|
+
changes: [],
|
|
95
|
+
isFullScan: true,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// Get diff between lastCommit and HEAD
|
|
99
|
+
const output = execGit(`diff --name-status ${lastCommit}..${currentCommit}`, cwd);
|
|
100
|
+
if (!output) {
|
|
101
|
+
return {
|
|
102
|
+
currentCommit,
|
|
103
|
+
changes: [],
|
|
104
|
+
isFullScan: false,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const changes = [];
|
|
108
|
+
for (const line of output.split("\n")) {
|
|
109
|
+
if (!line.trim())
|
|
110
|
+
continue;
|
|
111
|
+
const parts = line.split("\t");
|
|
112
|
+
const statusCode = parts[0];
|
|
113
|
+
if (statusCode.startsWith("R")) {
|
|
114
|
+
// Renamed: R100\toldPath\tnewPath
|
|
115
|
+
changes.push({
|
|
116
|
+
status: "renamed",
|
|
117
|
+
path: parts[2],
|
|
118
|
+
oldPath: parts[1],
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
changes.push({
|
|
123
|
+
status: parseStatusCode(statusCode),
|
|
124
|
+
path: parts[1],
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
currentCommit,
|
|
130
|
+
changes,
|
|
131
|
+
isFullScan: false,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/scanner/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ScannerConfig } from "../config/index.js";
|
|
2
|
+
export interface ScannedFile {
|
|
3
|
+
path: string;
|
|
4
|
+
absolutePath: string;
|
|
5
|
+
hash: string;
|
|
6
|
+
size: number;
|
|
7
|
+
language?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ScanResult {
|
|
10
|
+
files: ScannedFile[];
|
|
11
|
+
repoRoot: string;
|
|
12
|
+
totalSize: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function detectLanguage(filePath: string): string | undefined;
|
|
15
|
+
export declare function hashContent(content: Buffer): string;
|
|
16
|
+
export declare function scanRepository(repoPath: string, config: ScannerConfig): Promise<ScanResult>;
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIxD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAiED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUnE;AAiCD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAID,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,UAAU,CAAC,CAqErB"}
|