@@ -9,20 +9,9 @@ import { promises as fs } from 'fs';
99
1010import path from 'path' ;
1111import { fileURLToPath } from 'url' ;
12- import { Server } from '@modelcontextprotocol/sdk/server/index.js' ;
13- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' ;
14- import { createServer } from './server/factory.js' ;
15- import { startHttpServer } from './server/http.js' ;
16- import { loadServerConfig } from './server/config.js' ;
12+ import type { Server } from '@modelcontextprotocol/sdk/server/index.js' ;
1713import type { ProjectConfig } from './server/config.js' ;
18- import {
19- CallToolRequestSchema ,
20- ListToolsRequestSchema ,
21- ListResourcesRequestSchema ,
22- ReadResourceRequestSchema ,
23- RootsListChangedNotificationSchema ,
24- Resource
25- } from '@modelcontextprotocol/sdk/types.js' ;
14+ import type { Resource } from '@modelcontextprotocol/sdk/types.js' ;
2615import { CodebaseIndexer } from './core/indexer.js' ;
2716
2817import { analyzerRegistry } from './core/analyzer-registry.js' ;
@@ -69,8 +58,75 @@ analyzerRegistry.register(new NextJsAnalyzer());
6958analyzerRegistry . register ( new ReactAnalyzer ( ) ) ;
7059analyzerRegistry . register ( new GenericAnalyzer ( ) ) ;
7160
61+ let createServer ! : typeof import ( './server/factory.js' ) . createServer ;
62+ let startHttpServer ! : typeof import ( './server/http.js' ) . startHttpServer ;
63+ let loadServerConfig ! : typeof import ( './server/config.js' ) . loadServerConfig ;
64+ let StdioServerTransport ! : typeof import ( '@modelcontextprotocol/sdk/server/stdio.js' ) . StdioServerTransport ;
65+ let CallToolRequestSchema ! : typeof import ( '@modelcontextprotocol/sdk/types.js' ) . CallToolRequestSchema ;
66+ let ListToolsRequestSchema ! : typeof import ( '@modelcontextprotocol/sdk/types.js' ) . ListToolsRequestSchema ;
67+ let ListResourcesRequestSchema ! : typeof import ( '@modelcontextprotocol/sdk/types.js' ) . ListResourcesRequestSchema ;
68+ let ReadResourceRequestSchema ! : typeof import ( '@modelcontextprotocol/sdk/types.js' ) . ReadResourceRequestSchema ;
69+ let RootsListChangedNotificationSchema ! : typeof import ( '@modelcontextprotocol/sdk/types.js' ) . RootsListChangedNotificationSchema ;
70+ let server ! : Server ;
71+ let mcpRuntimeReady = false ;
72+ let mcpRuntimePromise : Promise < void > | undefined ;
73+
7274// Flags that are NOT project paths — skip them when resolving the bootstrap root.
7375const KNOWN_FLAGS = new Set ( [ '--http' , '--port' , '--help' ] ) ;
76+ const CLI_SUBCOMMANDS = [
77+ 'memory' ,
78+ 'search' ,
79+ 'metadata' ,
80+ 'status' ,
81+ 'reindex' ,
82+ 'style-guide' ,
83+ 'patterns' ,
84+ 'refs' ,
85+ 'cycles' ,
86+ 'init' ,
87+ 'map'
88+ ] ;
89+
90+ // Check if this module is the entry point.
91+ const isDirectRun =
92+ process . argv [ 1 ] ?. replace ( / \\ / g, '/' ) . endsWith ( 'index.js' ) ||
93+ process . argv [ 1 ] ?. replace ( / \\ / g, '/' ) . endsWith ( 'index.ts' ) ;
94+ const directSubcommand = process . argv [ 2 ] ;
95+ const isDirectCliSubcommand =
96+ isDirectRun &&
97+ typeof directSubcommand === 'string' &&
98+ ( CLI_SUBCOMMANDS . includes ( directSubcommand ) || directSubcommand === '--help' ) ;
99+
100+ async function ensureMcpRuntimeLoaded ( ) : Promise < void > {
101+ if ( mcpRuntimeReady ) {
102+ return ;
103+ }
104+
105+ mcpRuntimePromise ??= ( async ( ) => {
106+ const [ factoryModule , httpModule , configModule , stdioModule , sdkTypesModule ] =
107+ await Promise . all ( [
108+ import ( './server/factory.js' ) ,
109+ import ( './server/http.js' ) ,
110+ import ( './server/config.js' ) ,
111+ import ( '@modelcontextprotocol/sdk/server/stdio.js' ) ,
112+ import ( '@modelcontextprotocol/sdk/types.js' )
113+ ] ) ;
114+
115+ createServer = factoryModule . createServer ;
116+ startHttpServer = httpModule . startHttpServer ;
117+ loadServerConfig = configModule . loadServerConfig ;
118+ StdioServerTransport = stdioModule . StdioServerTransport ;
119+ CallToolRequestSchema = sdkTypesModule . CallToolRequestSchema ;
120+ ListToolsRequestSchema = sdkTypesModule . ListToolsRequestSchema ;
121+ ListResourcesRequestSchema = sdkTypesModule . ListResourcesRequestSchema ;
122+ ReadResourceRequestSchema = sdkTypesModule . ReadResourceRequestSchema ;
123+ RootsListChangedNotificationSchema = sdkTypesModule . RootsListChangedNotificationSchema ;
124+ server = createServer ( { name : 'codebase-context' , version : PKG_VERSION } , registerHandlers ) ;
125+ mcpRuntimeReady = true ;
126+ } ) ( ) ;
127+
128+ await mcpRuntimePromise ;
129+ }
74130
75131// Resolve optional bootstrap root with validation handled later in main().
76132function resolveRootPath ( ) : string | undefined {
@@ -997,11 +1053,6 @@ export function registerHandlers(target: Server): void {
9971053 } ) ;
9981054}
9991055
1000- const server : Server = createServer (
1001- { name : 'codebase-context' , version : PKG_VERSION } ,
1002- registerHandlers
1003- ) ;
1004-
10051056function buildResources ( ) : Resource [ ] {
10061057 const resources : Resource [ ] = [
10071058 {
@@ -1234,6 +1285,8 @@ async function validateClientRootEntries(
12341285}
12351286
12361287async function refreshKnownRootsFromClient ( ) : Promise < void > {
1288+ await ensureMcpRuntimeLoaded ( ) ;
1289+
12371290 try {
12381291 const { roots } = await server . listRoots ( ) ;
12391292 const fileRoots = await validateClientRootEntries (
@@ -1534,6 +1587,8 @@ async function applyServerConfig(
15341587}
15351588
15361589async function main ( ) {
1590+ await ensureMcpRuntimeLoaded ( ) ;
1591+
15371592 const serverConfig = await loadServerConfig ( ) ;
15381593 await applyServerConfig ( serverConfig ) ;
15391594
@@ -1691,6 +1746,8 @@ export { performIndexing };
16911746 * sharing the same module-level project state.
16921747 */
16931748async function startHttp ( explicitPort ?: number ) : Promise < void > {
1749+ await ensureMcpRuntimeLoaded ( ) ;
1750+
16941751 const serverConfig = await loadServerConfig ( ) ;
16951752 await applyServerConfig ( serverConfig ) ;
16961753
@@ -1764,25 +1821,9 @@ async function startHttp(explicitPort?: number): Promise<void> {
17641821 }
17651822}
17661823
1767- // Only auto-start when run directly as CLI (not when imported as module)
1768- // Check if this module is the entry point
1769- const isDirectRun =
1770- process . argv [ 1 ] ?. replace ( / \\/ g , '/ ') . endsWith ( 'index . js ') ||
1771- process . argv [ 1 ] ?. replace ( / \\/ g , '/ ') . endsWith ( 'index . ts ') ;
1772-
1773- const CLI_SUBCOMMANDS = [
1774- 'memory ',
1775- 'search ',
1776- 'metadata ',
1777- 'status ',
1778- 'reindex ',
1779- 'style - guide ',
1780- 'patterns ',
1781- 'refs ',
1782- 'cycles ',
1783- 'init ',
1784- 'map '
1785- ] ;
1824+ if ( ! isDirectCliSubcommand ) {
1825+ await ensureMcpRuntimeLoaded ( ) ;
1826+ }
17861827
17871828if ( isDirectRun ) {
17881829 const subcommand = process . argv [ 2 ] ;
0 commit comments