youling-agent-mcp
Version:
MCP服务器实现POMDP研发任务拆解
144 lines • 4.81 kB
JavaScript
/**
* MCP stdio传输层实现
* 用于支持通过标准输入/输出与MCP客户端通信
*/
import { createInterface } from 'readline';
import { logger } from '../../bin/logger.js';
// JSON-RPC 2.0协议常量
const JSON_RPC_VERSION = '2.0';
/**
* Stdio传输层类 - 用于MCP服务器与客户端之间的双向通信
* 实现Transport接口以与McpServer兼容
*/
export class StdioTransport {
/**
* 构造函数
* @param options 配置选项
*/
constructor(options) {
this.server = null;
this.isReady = false;
this.serverName = options.serverName;
this.version = options.version;
// 创建readline接口,用于从stdin读取数据
this.rl = createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
// 监听行输入
this.rl.on('line', this.handleLine.bind(this));
// 监听关闭事件
this.rl.on('close', () => {
logger.debug('STDIO连接已关闭');
process.exit(0);
});
}
/**
* 实现 Transport 接口的 start 方法
* 启动传输层并发送就绪状态
*/
async start() {
// 注意: MCP服务器实例将通过connect方法设置
// 在这里仅发送就绪状态消息
this.sendReadyStatus();
logger.debug('已启动stdio传输层并发送就绪消息');
return Promise.resolve();
}
/**
* 实现 Transport 接口的 send 方法
* 用于发送JSON-RPC消息给客户端
* @param message JSON-RPC消息
* @param options 发送选项
*/
async send(message, options) {
// 将JSON-RPC消息写入stdout
process.stdout.write(JSON.stringify(message) + '\n');
logger.debug('发送STDIO消息', { id: message.id, method: message.method });
return Promise.resolve();
}
/**
* 处理接收到的行
* @param line 接收到的行
*/
async handleLine(line) {
try {
// 解析JSON-RPC请求
const request = JSON.parse(line);
logger.debug('收到STDIO请求', { request });
if (!this.server) {
logger.error('MCP服务器实例未初始化');
this.sendErrorResponse(-32603, 'Internal error: Server not initialized', request?.id);
return;
}
// 处理请求 - 使用MCP服务器的processRequest方法
try {
// 简单会话ID - 对于stdio传输层,我们使用静态会话ID
const sessionId = 'stdio-session';
await this.server.processRequest(sessionId, request);
// 注意:响应将通过send方法返回
}
catch (error) {
logger.error('处理请求时出错', { error });
this.sendErrorResponse(error.code || -32603, error.message || 'Internal error', request?.id, error.data);
}
}
catch (error) {
logger.error('解析请求失败', { error: error.message, line });
this.sendErrorResponse(-32700, 'Parse error', null);
}
}
/**
* 发送就绪状态
*/
sendReadyStatus() {
const statusMessage = {
jsonrpc: JSON_RPC_VERSION,
method: 'server/status',
params: {
status: 'ready',
mode: 'stdio',
name: this.serverName,
version: this.version,
protocol: 'MCP (JSON-RPC 2.0)',
streaming: true
}
};
// 直接写入stdout,避免console.log可能添加的额外格式
process.stdout.write(JSON.stringify(statusMessage) + '\n');
this.isReady = true;
logger.debug('STDIO模式MCP服务器就绪');
}
/**
* 发送JSON-RPC错误响应
* @param code 错误代码
* @param message 错误消息
* @param id 请求ID
* @param data 错误数据
*/
sendErrorResponse(code, message, id, data) {
const errorResponse = {
jsonrpc: JSON_RPC_VERSION,
error: {
code,
message
},
id
};
if (data !== undefined) {
errorResponse.error.data = data;
}
process.stdout.write(JSON.stringify(errorResponse) + '\n');
logger.debug('发送STDIO错误响应', { code, message, id });
}
/**
* 关闭传输层 - 实现Transport接口要求
*/
close() {
logger.debug('STDIO传输层正在关闭...');
this.rl.close();
}
}
// 添加默认导出
export default StdioTransport;
//# sourceMappingURL=stdio-transport.js.map