@code-rag/mcp-server 0.1.6 → 0.1.8

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/server.d.ts CHANGED
@@ -9,6 +9,7 @@ export interface CodeRAGServerOptions {
9
9
  export declare class CodeRAGServer {
10
10
  private readonly server;
11
11
  private readonly rootDir;
12
+ private runtime;
12
13
  private config;
13
14
  private store;
14
15
  private hybridSearch;
package/dist/server.js CHANGED
@@ -2,9 +2,8 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
3
  import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
4
4
  import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
- import { loadConfig, checkIndexExists, OllamaEmbeddingProvider, LanceDBStore, BM25Index, HybridSearch, DependencyGraph, ContextExpander, CrossEncoderReRanker, } from '@code-rag/core';
6
- import { readFile } from 'node:fs/promises';
7
- import { join, resolve } from 'node:path';
5
+ import { loadConfig, checkIndexExists, createRuntime, } from '@code-rag/core';
6
+ import { resolve } from 'node:path';
8
7
  import { createServer } from 'node:http';
9
8
  import { URL } from 'node:url';
10
9
  import { handleSearch } from './tools/search.js';
@@ -27,6 +26,7 @@ The MCP server will start automatically once indexing is complete.`;
27
26
  export class CodeRAGServer {
28
27
  server;
29
28
  rootDir;
29
+ runtime = null;
30
30
  config = null;
31
31
  store = null;
32
32
  hybridSearch = null;
@@ -68,66 +68,26 @@ export class CodeRAGServer {
68
68
  */
69
69
  async initialize() {
70
70
  try {
71
+ // Check index existence before full init
71
72
  const configResult = await loadConfig(this.rootDir);
72
- if (configResult.isErr()) {
73
- // eslint-disable-next-line no-console
74
- console.error(`[coderag] Config load failed: ${configResult.error.message}`);
75
- return;
73
+ if (configResult.isOk()) {
74
+ const storagePath = resolve(this.rootDir, configResult.value.storage.path);
75
+ if (storagePath.startsWith(resolve(this.rootDir))) {
76
+ this.indexCheck = await checkIndexExists(storagePath);
77
+ }
76
78
  }
77
- this.config = configResult.value;
78
- // Create embedding provider
79
- const embeddingProvider = new OllamaEmbeddingProvider({
80
- model: this.config.embedding.model,
81
- dimensions: this.config.embedding.dimensions,
82
- });
83
- // Create LanceDB store (validate path stays within rootDir)
84
- const storagePath = resolve(this.rootDir, this.config.storage.path);
85
- if (!storagePath.startsWith(resolve(this.rootDir))) {
79
+ const runtimeResult = await createRuntime({ rootDir: this.rootDir });
80
+ if (runtimeResult.isErr()) {
86
81
  // eslint-disable-next-line no-console
87
- console.error('[coderag] Storage path escapes project root');
82
+ console.error(`[coderag] ${runtimeResult.error.message}`);
88
83
  return;
89
84
  }
90
- // Check index existence before connecting
91
- this.indexCheck = await checkIndexExists(storagePath);
92
- this.store = new LanceDBStore(storagePath, this.config.embedding.dimensions);
93
- await this.store.connect();
94
- // Create BM25 index -- try to load from stored data
95
- let bm25Index = new BM25Index();
96
- const bm25Path = join(storagePath, 'bm25-index.json');
97
- try {
98
- const bm25Data = await readFile(bm25Path, 'utf-8');
99
- bm25Index = BM25Index.deserialize(bm25Data);
100
- }
101
- catch {
102
- // No saved BM25 index, start empty
103
- }
104
- // Create HybridSearch
105
- this.hybridSearch = new HybridSearch(this.store, bm25Index, embeddingProvider, this.config.search);
106
- // Create re-ranker if enabled
107
- if (this.config.reranker?.enabled) {
108
- this.reranker = new CrossEncoderReRanker({
109
- model: this.config.reranker.model,
110
- topN: this.config.reranker.topN,
111
- });
112
- }
113
- // Load dependency graph if available
114
- let graph = new DependencyGraph();
115
- const graphPath = join(storagePath, 'graph.json');
116
- try {
117
- const graphData = await readFile(graphPath, 'utf-8');
118
- const parsed = JSON.parse(graphData);
119
- graph = DependencyGraph.fromJSON(parsed);
120
- }
121
- catch {
122
- // No saved graph, start empty
123
- }
124
- // Create retrieval services
125
- const chunkLookup = (_chunkId) => {
126
- // In a full implementation this would look up chunks by ID.
127
- // For now, the context expander will only work with chunks found via search.
128
- return undefined;
129
- };
130
- this.contextExpander = new ContextExpander(graph, chunkLookup);
85
+ this.runtime = runtimeResult.value;
86
+ this.config = this.runtime.config;
87
+ this.store = this.runtime.store;
88
+ this.hybridSearch = this.runtime.hybridSearch;
89
+ this.contextExpander = this.runtime.contextExpander;
90
+ this.reranker = this.runtime.reranker;
131
91
  }
132
92
  catch (error) {
133
93
  const message = error instanceof Error ? error.message : 'Unknown error';
@@ -412,6 +372,11 @@ export class CodeRAGServer {
412
372
  });
413
373
  this.httpServer = null;
414
374
  }
375
+ // Close the runtime (LanceDB, etc.)
376
+ if (this.runtime) {
377
+ this.runtime.close();
378
+ this.runtime = null;
379
+ }
415
380
  }
416
381
  /** Expose for testing. */
417
382
  getServer() {
@@ -77,7 +77,7 @@ export async function handleContext(args, hybridSearch, contextExpander) {
77
77
  };
78
78
  }
79
79
  // Step 2: Expand context via dependency graph
80
- const expanded = contextExpander.expand(results);
80
+ const expanded = await contextExpander.expand(results);
81
81
  // Step 3: Assemble within token budget (use caller's max_tokens)
82
82
  const optimizer = new TokenBudgetOptimizer({ maxTokens: max_tokens });
83
83
  const assembled = optimizer.assemble(expanded);
@@ -112,7 +112,7 @@ export async function handleExplain(args, hybridSearch, contextExpander) {
112
112
  };
113
113
  // Add related symbols from context expander when in detailed mode
114
114
  if (detail_level === 'detailed' && contextExpander) {
115
- const expanded = contextExpander.expand(results);
115
+ const expanded = await contextExpander.expand(results);
116
116
  const relatedSymbols = expanded.relatedChunks.map((related) => {
117
117
  return related.chunk.metadata.name ?? related.chunk.chunk?.filePath ?? 'unknown';
118
118
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-rag/mcp-server",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "MCP server for CodeRAG — exposes codebase search, context, and status tools via Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -41,7 +41,7 @@
41
41
  "dependencies": {
42
42
  "@modelcontextprotocol/sdk": "^1.5.0",
43
43
  "zod": "^4.3.6",
44
- "@code-rag/core": "0.1.6"
44
+ "@code-rag/core": "0.1.8"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/node": "^22.13.4",