MCPcopy
hub / github.com/colbymchenry/codegraph / MCPEngine

Class MCPEngine

src/mcp/engine.ts:53–313  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

51 * connect never double-open the SQLite file.
52 */
53export class MCPEngine {
54 private cg: CodeGraph | null = null;
55 private toolHandler: ToolHandler;
56 // Project root we resolved to. Null until `ensureInitialized` succeeds
57 // (or null forever if no .codegraph/ ever turned up — that's a valid
58 // state for the engine, since cross-project queries still work).
59 private projectPath: string | null = null;
60 // Set on first `ensureInitialized` so subsequent sessions don't redo work.
61 private initPromise: Promise<void> | null = null;
62 private watcherStarted = false;
63 private opts: Required<MCPEngineOptions>;
64 private closed = false;
65 // Off-loop read-tool pool (daemon mode only). Created lazily once the default
66 // project is open — workers each hold their own WAL read connection.
67 private queryPool: QueryPool | null = null;
68
69 constructor(opts: MCPEngineOptions = {}) {
70 this.opts = { watch: opts.watch ?? true, queryPool: opts.queryPool ?? false };
71 this.toolHandler = new ToolHandler(null);
72 }
73
74 /**
75 * Start the worker-thread query pool once a default project is open (daemon
76 * mode only; honors `CODEGRAPH_QUERY_POOL_SIZE`). Idempotent and best-effort:
77 * if workers can't spawn on this platform the ToolHandler keeps serving reads
78 * in-process, so the pool can only help, never break, tool calls.
79 */
80 private maybeStartPool(root: string): void {
81 if (!this.opts.queryPool || this.queryPool || this.closed) return;
82 const size = resolvePoolSize(process.env.CODEGRAPH_QUERY_POOL_SIZE, os.cpus().length);
83 if (size <= 0) {
84 process.stderr.write('[CodeGraph MCP] Query pool disabled (CODEGRAPH_QUERY_POOL_SIZE=0); serving reads in-process.\n');
85 return;
86 }
87 try {
88 this.queryPool = new QueryPool({ root, size });
89 this.toolHandler.setQueryPool(this.queryPool);
90 process.stderr.write(`[CodeGraph MCP] Query pool: up to ${size} worker thread(s) for concurrent reads.\n`);
91 } catch (err) {
92 const msg = err instanceof Error ? err.message : String(err);
93 process.stderr.write(`[CodeGraph MCP] Query pool unavailable (${msg}); serving reads in-process.\n`);
94 this.queryPool = null;
95 }
96 }
97
98 /**
99 * Convenience for {@link MCPServer} compatibility: pre-seed an explicit
100 * project path (from the `--path` CLI flag) without yet opening it. This
101 * keeps the synchronous constructor cheap; the actual open happens on the
102 * first `ensureInitialized` call.
103 */
104 setProjectPathHint(projectPath: string): void {
105 this.projectPath = projectPath;
106 this.toolHandler.setDefaultProjectHint(projectPath);
107 }
108
109 /** Project root that the engine resolved on first init (null if none). */
110 getProjectPath(): string | null {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected