@@ -2,6 +2,9 @@ import { MongoClient, Db } from "mongodb";
2
2
import { config } from "dotenv" ;
3
3
import mongoose from "mongoose" ;
4
4
import { glob } from "glob" ;
5
+ import fs from 'fs' ;
6
+ import path from 'path' ;
7
+ import { tmpdir } from 'os' ;
5
8
6
9
7
10
config ( ) ;
@@ -12,6 +15,7 @@ class MongoDBClient {
12
15
private db : Db | null = null ;
13
16
private models : Record < string , mongoose . Model < any > > = { } ;
14
17
private initialized : boolean = false ;
18
+ private tempSchemaDir : string | null = null ;
15
19
16
20
private constructor ( ) { }
17
21
@@ -22,26 +26,62 @@ class MongoDBClient {
22
26
return MongoDBClient . instance ;
23
27
}
24
28
29
+ private async copySchemaFiles ( sourcePath : string ) : Promise < string > {
30
+ const tempDir = path . join ( tmpdir ( ) , 'mcp-schemas-' + Date . now ( ) ) ;
31
+ await fs . promises . mkdir ( tempDir , { recursive : true } ) ;
32
+
33
+ const files = await glob ( `${ sourcePath } /**/*.{js,ts}` ) ;
34
+
35
+ for ( const file of files ) {
36
+ const relativePath = path . relative ( sourcePath , file ) ;
37
+ const targetPath = path . join ( tempDir , relativePath ) ;
38
+
39
+ await fs . promises . mkdir ( path . dirname ( targetPath ) , { recursive : true } ) ;
40
+ await fs . promises . copyFile ( file , targetPath ) ;
41
+ }
42
+
43
+ return tempDir ;
44
+ }
45
+
46
+ private async cleanupTempDir ( ) : Promise < void > {
47
+ if ( this . tempSchemaDir ) {
48
+ try {
49
+ await fs . promises . rm ( this . tempSchemaDir , { recursive : true , force : true } ) ;
50
+ } catch ( error ) {
51
+ console . error ( 'Error cleaning up temporary schema directory:' , error ) ;
52
+ }
53
+ }
54
+ }
55
+
25
56
public async initialize ( ) : Promise < void > {
26
57
if ( this . initialized ) return ;
27
58
28
59
try {
29
60
const uri = process . env . MONGODB_URI || "mongodb://localhost:27017/mcp-database" ;
30
61
const schemaPath = process . env . SCHEMA_PATH ;
31
62
63
+ console . error ( `Attempting to connect to MongoDB at: ${ uri } ` ) ;
64
+ console . error ( `Schema path: ${ schemaPath } ` ) ;
65
+
32
66
// Connect with MongoDB driver
33
67
this . mongoClient = new MongoClient ( uri ) ;
34
68
await this . mongoClient . connect ( ) ;
35
69
this . db = this . mongoClient . db ( ) ;
36
70
console . error ( `Connected to MongoDB using native driver` ) ;
37
71
38
72
// Connect with Mongoose
39
- await mongoose . connect ( uri ) ;
73
+ await mongoose . connect ( uri , {
74
+ serverSelectionTimeoutMS : 5000 ,
75
+ socketTimeoutMS : 45000 ,
76
+ } ) ;
40
77
console . error ( `Connected to MongoDB using Mongoose` ) ;
41
78
42
79
// Load schemas if path is provided
43
80
if ( schemaPath ) {
44
- await this . loadSchemas ( schemaPath ) ;
81
+ console . error ( `Loading schemas from: ${ schemaPath } ` ) ;
82
+ // Copy schema files to temp directory if running via npx
83
+ this . tempSchemaDir = await this . copySchemaFiles ( schemaPath ) ;
84
+ await this . loadSchemas ( this . tempSchemaDir ) ;
45
85
} else {
46
86
console . error ( "No schema path provided. Running in schemaless mode." ) ;
47
87
}
@@ -55,9 +95,11 @@ class MongoDBClient {
55
95
56
96
private async loadSchemas ( schemaPath : string ) : Promise < void > {
57
97
try {
58
- // Use the absolute path directly
98
+ console . error ( `Starting schema loading from path: ${ schemaPath } ` ) ;
59
99
const schemaFiles = await glob ( `${ schemaPath } /**/*.{js,ts}` ) ;
60
100
101
+ console . error ( `Found schema files:` , schemaFiles ) ;
102
+
61
103
if ( schemaFiles . length === 0 ) {
62
104
console . error ( `No schema files found in ${ schemaPath } . Running in schemaless mode.` ) ;
63
105
return ;
@@ -67,20 +109,23 @@ class MongoDBClient {
67
109
68
110
for ( const file of schemaFiles ) {
69
111
try {
70
- // Use require for npm package compatibility
112
+ console . error ( `Attempting to load schema file: ${ file } ` ) ;
71
113
const moduleImport = require ( file ) ;
72
114
const schema = moduleImport . default ;
73
115
74
116
if ( schema && schema . modelName ) {
75
117
this . models [ schema . modelName . toLowerCase ( ) ] = schema ;
76
- console . error ( `Loaded schema for: ${ schema . modelName } ` ) ;
118
+ console . error ( `Successfully loaded schema for: ${ schema . modelName } ` ) ;
119
+ } else {
120
+ console . error ( `Schema file ${ file } does not export a valid model` ) ;
77
121
}
78
122
} catch ( err ) {
79
123
console . error ( `Error loading schema file ${ file } :` , err ) ;
80
124
}
81
125
}
82
126
83
127
console . error ( `Loaded ${ Object . keys ( this . models ) . length } schemas.` ) ;
128
+ console . error ( `Available models:` , Object . keys ( this . models ) ) ;
84
129
} catch ( error ) {
85
130
console . error ( "Error loading schemas:" , error ) ;
86
131
console . error ( "Running in schemaless mode." ) ;
@@ -133,6 +178,7 @@ class MongoDBClient {
133
178
await mongoose . connection . close ( ) ;
134
179
}
135
180
181
+ await this . cleanupTempDir ( ) ;
136
182
this . initialized = false ;
137
183
}
138
184
}
0 commit comments