* 发送请求到 MCP 服务器
(sessionId: string, request: Partial<MCPMessage>)
| 168 | * 发送请求到 MCP 服务器 |
| 169 | */ |
| 170 | private async sendRequest(sessionId: string, request: Partial<MCPMessage>): Promise<any> { |
| 171 | const connection = this.connections.get(sessionId); |
| 172 | const session = this.sessions.get(sessionId); |
| 173 | |
| 174 | if (!connection || !session?.connected) { |
| 175 | throw new Error(`Session ${sessionId} is not connected`); |
| 176 | } |
| 177 | |
| 178 | const message: MCPMessage = { |
| 179 | jsonrpc: '2.0', |
| 180 | id: ++this.messageId, |
| 181 | ...request, |
| 182 | }; |
| 183 | |
| 184 | return new Promise((resolve, reject) => { |
| 185 | const timeout = setTimeout(() => { |
| 186 | reject(new Error('Request timeout')); |
| 187 | }, session.config.timeout || 30000); |
| 188 | |
| 189 | const handleMessage = (data: any) => { |
| 190 | try { |
| 191 | const response = typeof data === 'string' ? JSON.parse(data) : data; |
| 192 | |
| 193 | if (response.id === message.id) { |
| 194 | clearTimeout(timeout); |
| 195 | connection.off?.('message', handleMessage); |
| 196 | |
| 197 | if (response.error) { |
| 198 | reject(new Error(response.error.message)); |
| 199 | } else { |
| 200 | resolve(response.result); |
| 201 | } |
| 202 | } |
| 203 | } catch (error) { |
| 204 | reject(error); |
| 205 | } |
| 206 | }; |
| 207 | |
| 208 | if (connection instanceof WebSocket) { |
| 209 | connection.on('message', handleMessage); |
| 210 | connection.send(JSON.stringify(message)); |
| 211 | } else { |
| 212 | // Handle stdio connection |
| 213 | const responseHandler = (data: Buffer) => { |
| 214 | try { |
| 215 | const response = JSON.parse(data.toString().trim()); |
| 216 | if (response.id === message.id) { |
| 217 | clearTimeout(timeout); |
| 218 | connection.stdout?.off('data', responseHandler); |
| 219 | |
| 220 | if (response.error) { |
| 221 | reject(new Error(response.error.message)); |
| 222 | } else { |
| 223 | resolve(response.result); |
| 224 | } |
| 225 | } |
| 226 | } catch (error) { |
| 227 | // Ignore JSON parse errors for partial messages |
no test coverage detected