Files
SnowLuma/.pnpm-store/v11/files/ec/7c4942224072e531203fdcb52d65f2b0de6ad7316fd8ac493fc938e90e27a8704275909a964a3fab4ce5acc0f7caa942400c449b646efb177a7358584105eb
T
TanTan 2a69b23b47
Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Canceled after 0s
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

81 lines
2.8 KiB
Plaintext

import process from 'node:process';
import { ReadBuffer, serializeMessage } from '../shared/stdio.js';
/**
* Server transport for stdio: this communicates with an MCP client by reading from the current process' stdin and writing to stdout.
*
* This transport is only available in Node.js environments.
*/
export class StdioServerTransport {
constructor(_stdin = process.stdin, _stdout = process.stdout, options) {
this._stdin = _stdin;
this._stdout = _stdout;
this._started = false;
// Arrow functions to bind `this` properly, while maintaining function identity.
this._ondata = (chunk) => {
try {
this._readBuffer.append(chunk);
this.processReadBuffer();
}
catch (error) {
this.onerror?.(error);
this.close().catch(() => { });
}
};
this._onerror = (error) => {
this.onerror?.(error);
};
this._readBuffer = new ReadBuffer({ maxBufferSize: options?.maxBufferSize });
}
/**
* Starts listening for messages on stdin.
*/
async start() {
if (this._started) {
throw new Error('StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.');
}
this._started = true;
this._stdin.on('data', this._ondata);
this._stdin.on('error', this._onerror);
}
processReadBuffer() {
while (true) {
try {
const message = this._readBuffer.readMessage();
if (message === null) {
break;
}
this.onmessage?.(message);
}
catch (error) {
this.onerror?.(error);
}
}
}
async close() {
// Remove our event listeners first
this._stdin.off('data', this._ondata);
this._stdin.off('error', this._onerror);
// Check if we were the only data listener
const remainingDataListeners = this._stdin.listenerCount('data');
if (remainingDataListeners === 0) {
// Only pause stdin if we were the only listener
// This prevents interfering with other parts of the application that might be using stdin
this._stdin.pause();
}
// Clear the buffer and notify closure
this._readBuffer.clear();
this.onclose?.();
}
send(message) {
return new Promise(resolve => {
const json = serializeMessage(message);
if (this._stdout.write(json)) {
resolve();
}
else {
this._stdout.once('drain', resolve);
}
});
}
}
//# sourceMappingURL=stdio.js.map