1- import  {  EJSON  }  from  "bson" ; 
2- import  type  {  JSONRPCMessage  }  from  "@modelcontextprotocol/sdk/types.js" ; 
3- import  {  JSONRPCMessageSchema  }  from  "@modelcontextprotocol/sdk/types.js" ; 
41import  {  StdioServerTransport  }  from  "@modelcontextprotocol/sdk/server/stdio.js" ; 
52import  {  LogId  }  from  "../common/logger.js" ; 
63import  type  {  Server  }  from  "../server.js" ; 
74import  {  TransportRunnerBase ,  type  TransportRunnerConfig  }  from  "./base.js" ; 
85
9- // This is almost a copy of ReadBuffer from @modelcontextprotocol /sdk 
10- // but it uses EJSON.parse instead of JSON.parse to handle BSON types 
11- export  class  EJsonReadBuffer  { 
12-     private  _buffer ?: Buffer ; 
13- 
14-     append ( chunk : Buffer ) : void { 
15-         this . _buffer  =  this . _buffer  ? Buffer . concat ( [ this . _buffer ,  chunk ] )  : chunk ; 
16-     } 
17- 
18-     readMessage ( ) : JSONRPCMessage  |  null  { 
19-         if  ( ! this . _buffer )  { 
20-             return  null ; 
21-         } 
22- 
23-         const  index  =  this . _buffer . indexOf ( "\n" ) ; 
24-         if  ( index  ===  - 1 )  { 
25-             return  null ; 
26-         } 
27- 
28-         const  line  =  this . _buffer . toString ( "utf8" ,  0 ,  index ) . replace ( / \r $ / ,  "" ) ; 
29-         this . _buffer  =  this . _buffer . subarray ( index  +  1 ) ; 
30- 
31-         // This is using EJSON.parse instead of JSON.parse to handle BSON types 
32-         return  JSONRPCMessageSchema . parse ( EJSON . parse ( line ) ) ; 
33-     } 
34- 
35-     clear ( ) : void { 
36-         this . _buffer  =  undefined ; 
37-     } 
38- } 
39- 
40- // This is a hacky workaround for https://github.com/mongodb-js/mongodb-mcp-server/issues/211 
41- // The underlying issue is that StdioServerTransport uses JSON.parse to deserialize 
42- // messages, but that doesn't handle bson types, such as ObjectId when serialized as EJSON. 
43- // 
44- // This function creates a StdioServerTransport and replaces the internal readBuffer with EJsonReadBuffer 
45- // that uses EJson.parse instead. 
46- export  function  createStdioTransport ( ) : StdioServerTransport  { 
47-     const  server  =  new  StdioServerTransport ( ) ; 
48-     server [ "_readBuffer" ]  =  new  EJsonReadBuffer ( ) ; 
49- 
50-     return  server ; 
51- } 
52- 
536export  class  StdioRunner  extends  TransportRunnerBase  { 
547    private  server : Server  |  undefined ; 
558
@@ -60,8 +13,7 @@ export class StdioRunner extends TransportRunnerBase {
6013    async  start ( ) : Promise < void >  { 
6114        try  { 
6215            this . server  =  await  this . setupServer ( ) ; 
63- 
64-             const  transport  =  createStdioTransport ( ) ; 
16+             const  transport  =  new  StdioServerTransport ( ) ; 
6517
6618            await  this . server . connect ( transport ) ; 
6719        }  catch  ( error : unknown )  { 
0 commit comments