1
- import { EJSON } from "bson" ;
2
- import type { JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js" ;
3
- import { JSONRPCMessageSchema } from "@modelcontextprotocol/sdk/types.js" ;
4
1
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" ;
5
2
import { LogId } from "../common/logger.js" ;
6
3
import type { Server } from "../server.js" ;
7
4
import { TransportRunnerBase , type TransportRunnerConfig } from "./base.js" ;
8
5
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
-
53
6
export class StdioRunner extends TransportRunnerBase {
54
7
private server : Server | undefined ;
55
8
@@ -60,8 +13,7 @@ export class StdioRunner extends TransportRunnerBase {
60
13
async start ( ) : Promise < void > {
61
14
try {
62
15
this . server = await this . setupServer ( ) ;
63
-
64
- const transport = createStdioTransport ( ) ;
16
+ const transport = new StdioServerTransport ( ) ;
65
17
66
18
await this . server . connect ( transport ) ;
67
19
} catch ( error : unknown ) {
0 commit comments