diff --git a/packages/eko-nodejs/src/mcp/stdio.ts b/packages/eko-nodejs/src/mcp/stdio.ts index 598580a2..0da9cd4e 100644 --- a/packages/eko-nodejs/src/mcp/stdio.ts +++ b/packages/eko-nodejs/src/mcp/stdio.ts @@ -18,6 +18,7 @@ export class SimpleStdioMcpClient implements IMcpClient { private options?: SpawnOptionsWithoutStdio; private process: ChildProcessWithoutNullStreams | null = null; private requestMap: Map void>; + private stdoutBuffer: string = ""; constructor( command: string, @@ -38,18 +39,29 @@ export class SimpleStdioMcpClient implements IMcpClient { this.process.kill(); } catch (e) {} } + this.stdoutBuffer = ""; this.process = spawn(this.command, this.args, this.options); this.process.stdout.on("data", (data) => { - const response = data.toString().trim(); - Log.debug("MCP Client, onmessage", this.command, this.args, response); - if (!response.startsWith("{")) { - return; - } - const message = JSON.parse(response); - if (message.id) { - const callback = this.requestMap.get(message.id); - if (callback) { - callback(message); + this.stdoutBuffer += data.toString(); + const lines = this.stdoutBuffer.split("\n"); + // Keep the last (possibly incomplete) segment in the buffer + this.stdoutBuffer = lines.pop() || ""; + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed || !trimmed.startsWith("{")) { + continue; + } + Log.debug("MCP Client, onmessage", this.command, this.args, trimmed); + try { + const message = JSON.parse(trimmed); + if (message.id) { + const callback = this.requestMap.get(message.id); + if (callback) { + callback(message); + } + } + } catch (e) { + Log.warn("MCP Client, failed to parse JSON message:", trimmed, e); } } });