@@ -61,6 +61,31 @@ export class BunResponseAdapter extends EventEmitter {
61
61
62
62
write ( chunk : any ) : boolean {
63
63
this . _body += chunk ;
64
+
65
+ // Check if this is a complete SSE event with JSON-RPC response
66
+ // The MCP SDK sends SSE events in the format: "event: message\ndata: {json}\n\n"
67
+ if ( this . _body . includes ( 'event: message\ndata: ' ) && this . _body . endsWith ( '\n\n' ) ) {
68
+ // Extract the JSON part to check if it's complete
69
+ const dataMatch = this . _body . match ( / d a t a : ( .+ ) \n \n $ / ) ;
70
+ if ( dataMatch && dataMatch [ 1 ] ) {
71
+ try {
72
+ const json = JSON . parse ( dataMatch [ 1 ] ) ;
73
+ // Check if this is a complete JSON-RPC response
74
+ if ( json . jsonrpc && json . id !== undefined && ( json . result !== undefined || json . error !== undefined ) ) {
75
+ // The MCP SDK has written a complete response but isn't ending it
76
+ // This is a workaround for the SDK bug where it waits for all batch responses
77
+ process . nextTick ( ( ) => {
78
+ if ( ! this . _ended ) {
79
+ this . end ( ) ;
80
+ }
81
+ } ) ;
82
+ }
83
+ } catch ( e ) {
84
+ // Not valid JSON yet, keep accumulating
85
+ }
86
+ }
87
+ }
88
+
64
89
return true ;
65
90
}
66
91
@@ -72,7 +97,6 @@ export class BunResponseAdapter extends EventEmitter {
72
97
encodingOrCb ?: BufferEncoding | ( ( ) => void ) ,
73
98
cb ?: ( ) => void
74
99
) : this {
75
- console . log ( 'BunResponseAdapter.end() called' ) ;
76
100
let chunk : any ;
77
101
let callback : ( ( ) => void ) | undefined ;
78
102
@@ -93,11 +117,21 @@ export class BunResponseAdapter extends EventEmitter {
93
117
94
118
if ( ! this . _ended ) {
95
119
this . _ended = true ;
96
-
97
- console . log ( 'Creating response with status:' , this . _statusCode , 'body length:' , this . _body . length ) ;
120
+
121
+ // If this is an SSE response, extract the JSON data from the SSE format
122
+ let responseBody = this . _body ;
123
+ if ( this . _headers [ 'Content-Type' ] === 'text/event-stream' && this . _body . includes ( 'event: message\ndata: ' ) ) {
124
+ // Parse SSE format to extract JSON
125
+ const match = this . _body . match ( / d a t a : ( .+ ?) (?: \n \n | $ ) / ) ;
126
+ if ( match && match [ 1 ] ) {
127
+ responseBody = match [ 1 ] ;
128
+ // Update content type to JSON since we're extracting the JSON data
129
+ this . _headers [ 'Content-Type' ] = 'application/json' ;
130
+ }
131
+ }
98
132
99
133
// Create the Bun Response
100
- const response = new Response ( this . _body , {
134
+ const response = new Response ( responseBody , {
101
135
status : this . _statusCode ,
102
136
headers : this . _headers ,
103
137
} ) ;
@@ -116,6 +150,18 @@ export class BunResponseAdapter extends EventEmitter {
116
150
117
151
return this ;
118
152
}
153
+
154
+ // Add method to ensure response is sent
155
+ ensureResponseSent ( ) : void {
156
+ if ( ! this . _ended ) {
157
+ this . end ( ) ;
158
+ }
159
+ }
160
+
161
+ // Add method to check body length
162
+ getBodyLength ( ) : number {
163
+ return this . _body . length ;
164
+ }
119
165
}
120
166
121
167
export // Adapter to convert Bun Request to Node.js IncomingMessage-like object
0 commit comments