@@ -732,6 +732,118 @@ function showToolHelp(serverName, toolName, tools) {
732732// Response formatting
733733// ---------------------------------------------------------------------------
734734
735+ /**
736+ * Extract JSON-RPC messages from a response body that may be:
737+ * - A JSON object
738+ * - A JSON string
739+ * - Server-Sent Events (SSE) payload containing multiple `data:` lines
740+ *
741+ * @param {unknown } responseBody
742+ * @returns {unknown[] }
743+ */
744+ function extractJSONRPCMessages ( responseBody ) {
745+ if ( responseBody == null ) {
746+ return [ ] ;
747+ }
748+
749+ if ( Array . isArray ( responseBody ) ) {
750+ return responseBody ;
751+ }
752+
753+ if ( typeof responseBody === "object" ) {
754+ return [ responseBody ] ;
755+ }
756+
757+ if ( typeof responseBody !== "string" ) {
758+ return [ ] ;
759+ }
760+
761+ const trimmed = responseBody . trim ( ) ;
762+ if ( ! trimmed ) {
763+ return [ ] ;
764+ }
765+
766+ try {
767+ return [ JSON . parse ( trimmed ) ] ;
768+ } catch {
769+ // Fall through to SSE parsing.
770+ }
771+
772+ /** @type {unknown[] } */
773+ const messages = [ ] ;
774+ for ( const line of trimmed . split ( / \r ? \n / ) ) {
775+ if ( ! line . startsWith ( "data:" ) ) {
776+ continue ;
777+ }
778+ const payload = line . slice ( 5 ) . trim ( ) ;
779+ if ( ! payload || payload === "[DONE]" ) {
780+ continue ;
781+ }
782+ try {
783+ messages . push ( JSON . parse ( payload ) ) ;
784+ } catch {
785+ // Ignore non-JSON SSE data lines.
786+ }
787+ }
788+
789+ return messages ;
790+ }
791+
792+ /**
793+ * Render MCP progress notifications to stderr.
794+ *
795+ * @param {unknown[] } messages - Parsed JSON-RPC message stream
796+ */
797+ function renderProgressMessages ( messages ) {
798+ for ( const message of messages ) {
799+ if ( ! message || typeof message !== "object" || ! ( "method" in message ) || message . method !== "notifications/progress" ) {
800+ continue ;
801+ }
802+
803+ const params = "params" in message && message . params && typeof message . params === "object" ? message . params : null ;
804+ if ( ! params ) {
805+ continue ;
806+ }
807+
808+ const progressText = "message" in params && params . message ? String ( params . message ) : "" ;
809+ const progress = "progress" in params && typeof params . progress === "number" ? params . progress : null ;
810+ const total = "total" in params && typeof params . total === "number" ? params . total : null ;
811+
812+ if ( progressText ) {
813+ process . stderr . write ( progressText + "\n" ) ;
814+ continue ;
815+ }
816+
817+ if ( progress != null && total != null ) {
818+ process . stderr . write ( `Progress: ${ progress } /${ total } \n` ) ;
819+ continue ;
820+ }
821+
822+ if ( progress != null ) {
823+ process . stderr . write ( `Progress: ${ progress } \n` ) ;
824+ continue ;
825+ }
826+
827+ process . stderr . write ( `Progress: ${ JSON . stringify ( params ) } \n` ) ;
828+ }
829+ }
830+
831+ /**
832+ * @param {unknown } message
833+ * @returns {boolean }
834+ */
835+ function isErrorMessage ( message ) {
836+ return ! ! ( message && typeof message === "object" && "error" in message ) ;
837+ }
838+
839+ /**
840+ * @param {unknown } message
841+ * @returns {boolean }
842+ */
843+ function isResultMessage ( message ) {
844+ return ! ! ( message && typeof message === "object" && "result" in message ) ;
845+ }
846+
735847/**
736848 * Format and display the MCP tool call response.
737849 *
@@ -740,7 +852,10 @@ function showToolHelp(serverName, toolName, tools) {
740852 */
741853function formatResponse ( responseBody , serverName ) {
742854 const core = global . core ;
743- const resp = responseBody ;
855+ const messages = extractJSONRPCMessages ( responseBody ) ;
856+ renderProgressMessages ( messages ) ;
857+
858+ const resp = messages . find ( isErrorMessage ) || messages . find ( isResultMessage ) || responseBody ;
744859
745860 // Check for JSON-RPC error
746861 if ( resp && typeof resp === "object" && "error" in resp && resp . error && typeof resp . error === "object" ) {
@@ -905,6 +1020,8 @@ if (require.main === module) {
9051020module . exports = {
9061021 parseToolArgs,
9071022 coerceToolArgValue,
1023+ extractJSONRPCMessages,
1024+ renderProgressMessages,
9081025 formatResponse,
9091026 main,
9101027} ;
0 commit comments