UNPKG

@fusedashlabs/ui9000-workspace

Version:

UI9000 workspace MCP. One tool, show_workspace, draws a chart from your table. Set TYPESAFE_API_KEY to let Jev choose the chart.

53 lines (52 loc) • 1.85 kB
/** * stdio transport: newline-delimited JSON-RPC in, newline-delimited JSON out. * Nothing else may be written to stdout — a stray log breaks the frame stream. */ import { errorResponse, PARSE_ERROR } from './create-server.js'; const INTERNAL_ERROR = -32603; export function connectStdio(server, streams = { input: process.stdin, output: process.stdout }) { const { input, output } = streams; let buffer = ''; // One promise chain keeps replies in request order even when a handler awaits. let queue = Promise.resolve(); const onData = (chunk) => { buffer += typeof chunk === 'string' ? chunk : chunk.toString('utf8'); let newline = buffer.indexOf('\n'); while (newline !== -1) { const line = buffer.slice(0, newline); buffer = buffer.slice(newline + 1); queue = queue .then(() => dispatch(server, line, output)) .catch((error) => { const message = error instanceof Error ? error.message : 'Internal error'; write(output, errorResponse(0, INTERNAL_ERROR, message)); }); newline = buffer.indexOf('\n'); } }; input.on('data', onData); input.setEncoding?.('utf8'); return () => { input.off?.('data', onData); buffer = ''; }; } async function dispatch(server, line, output) { const text = line.trim(); if (text === '') return; let message; try { message = JSON.parse(text); } catch { write(output, errorResponse(0, PARSE_ERROR, 'Request line is not valid JSON.')); return; } const response = await server.handle(message); if (response !== null) write(output, response); } function write(output, response) { output.write(`${JSON.stringify(response)}\n`); }