XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 1
返回提交历史

XFEstudio/gpt4free

fix(mcp): redirect standard output to stderr in stdio mode to protect JSON-RPC framing

b4768cc1
Anand Mall <anand@example.com>
提交于

代码差异

1 个文件 +45 -39
Modified g4f/mcp/server.py +45 -39
@@ -195,50 +195,56 @@ class MCPServer:
195 195
196 196 async def run(self):
197 197 """Run the MCP server with stdio transport"""
198 # Write server info to stderr for debugging
199 sys.stderr.write(
200 f"Starting {self.server_info['name']} v{self.server_info['version']}\n"
201 )
202 sys.stderr.flush()
203
204 while True:
205 try:
206 # Read line from stdin
207 line = await asyncio.get_event_loop().run_in_executor(
208 None, sys.stdin.readline
209 )
210
211 if not line:
212 break
198 real_stdout = sys.stdout
199 sys.stdout = sys.stderr
213 200
214 # Parse JSON-RPC request
215 request_data = json.loads(line)
216 request = MCPRequest(
217 jsonrpc=request_data.get("jsonrpc", "2.0"),
218 id=request_data.get("id"),
219 method=request_data.get("method"),
220 params=request_data.get("params"),
221 )
201 try:
202 # Write server info to stderr for debugging
203 sys.stderr.write(
204 f"Starting {self.server_info['name']} v{self.server_info['version']}\n"
205 )
206 sys.stderr.flush()
222 207
223 # Handle request
224 response = await self.handle_request(request)
208 while True:
209 try:
210 # Read line from stdin
211 line = await asyncio.get_event_loop().run_in_executor(
212 None, sys.stdin.readline
213 )
225 214
226 # Write response to stdout
227 response_dict = {"jsonrpc": response.jsonrpc, "id": response.id}
228 if response.result is not None:
229 response_dict["result"] = response.result
230 if response.error is not None:
231 response_dict["error"] = response.error
215 if not line:
216 break
232 217
233 sys.stdout.write(json.dumps(response_dict) + "\n")
234 sys.stdout.flush()
218 # Parse JSON-RPC request
219 request_data = json.loads(line)
220 request = MCPRequest(
221 jsonrpc=request_data.get("jsonrpc", "2.0"),
222 id=request_data.get("id"),
223 method=request_data.get("method"),
224 params=request_data.get("params"),
225 )
235 226
236 except json.JSONDecodeError as e:
237 sys.stderr.write(f"JSON decode error: {e}\n")
238 sys.stderr.flush()
239 except Exception as e:
240 sys.stderr.write(f"Error: {e}\n")
241 sys.stderr.flush()
227 # Handle request
228 response = await self.handle_request(request)
229
230 # Write response to protocol stdout
231 response_dict = {"jsonrpc": response.jsonrpc, "id": response.id}
232 if response.result is not None:
233 response_dict["result"] = response.result
234 if response.error is not None:
235 response_dict["error"] = response.error
236
237 real_stdout.write(json.dumps(response_dict) + "\n")
238 real_stdout.flush()
239
240 except json.JSONDecodeError as e:
241 sys.stderr.write(f"JSON decode error: {e}\n")
242 sys.stderr.flush()
243 except Exception as e:
244 sys.stderr.write(f"Error: {e}\n")
245 sys.stderr.flush()
246 finally:
247 sys.stdout = real_stdout
242 248
243 249 async def run_http(
244 250 self, host: str = "0.0.0.0", port: int = 8765, origin: Optional[str] = None