소스 검색

修正不输出思考内容的问题

关习习 1 개월 전
부모
커밋
f8e24010b5
2개의 변경된 파일77개의 추가작업 그리고 144개의 파일을 삭제
  1. 6 0
      main.py
  2. 71 144
      mcp_api_server.py

+ 6 - 0
main.py

@@ -36,6 +36,12 @@ def stream_response(messages, tools=None):
         # 提取delta内容
         delta = chunk.choices[0].delta
 
+        # 处理文本内容(最终回答)
+        if hasattr(delta, 'reasoning') and delta.reasoning:
+            content = delta.reasoning
+            full_response += content
+            print(content, end="", flush=True)  # 实时输出到控制台
+
         # 处理文本内容(最终回答)
         if hasattr(delta, 'content') and delta.content:
             content = delta.content

+ 71 - 144
mcp_api_server.py

@@ -2,11 +2,24 @@ import json
 import subprocess
 import asyncio
 import sys
+import os
 from mcp import ClientSession, StdioServerParameters
 from mcp.client.stdio import stdio_client
 from pydantic import BaseModel
-from http.server import HTTPServer, BaseHTTPRequestHandler
-from urllib.parse import urlparse, parse_qs
+from typing import Dict, List, Any, Optional
+import uvicorn
+from fastapi import FastAPI, HTTPException
+from fastapi.middleware.cors import CORSMiddleware
+
+class ToolModel(BaseModel):
+    name: str
+    description: Optional[str] = None
+    inputSchema: Optional[Dict] = None
+
+class CallRequest(BaseModel):
+    name: str
+    arguments: Optional[Dict] = {}
+
 
 class MCPServerManager:
     def __init__(self, config_file="mcp_config.json"):
@@ -146,6 +159,7 @@ class MCPServerManager:
         """
         将MCP结果转换为可JSON序列化的格式
         """
+        from pydantic import BaseModel
         if isinstance(result, BaseModel):
             return result.model_dump()
         elif isinstance(result, dict):
@@ -266,152 +280,65 @@ class MCPServerManager:
             else:
                 print(f"✗ {server_name} 命令不可用")
 
-class MCPAPIHandler(BaseHTTPRequestHandler):
+
+
+# 创建FastAPI应用
+app = FastAPI(title="MCP API Server", description="MCP服务API接口")
+
+# 添加CORS中间件
+app.add_middleware(
+    CORSMiddleware,
+    allow_origins=["*"],
+    allow_credentials=True,
+    allow_methods=["*"],
+    allow_headers=["*"],
+)
+
+# 创建全局MCP服务器管理器实例
+mcp_manager = MCPServerManager()
+
+
+@app.get("/")
+async def root():
+    return {"message": "MCP API Server is running"}
+
+
+@app.get("/tools", response_model=List[ToolModel])
+async def get_tools():
     """
-    MCP API HTTP请求处理器
+    获取所有MCP工具列表
     """
-    
-    # 类变量,用于存储MCPServerManager实例
-    server_manager = None
-    
-    def _set_headers(self, status_code=200, content_type='application/json'):
-        """
-        设置HTTP响应头
-        """
-        self.send_response(status_code)
-        self.send_header('Content-type', content_type)
-        self.send_header('Access-Control-Allow-Origin', '*')
-        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
-        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
-        self.end_headers()
-    
-    def do_OPTIONS(self):
-        """
-        处理CORS预检请求
-        """
-        self._set_headers()
-    
-    def do_GET(self):
-        """
-        处理GET请求
-        """
-        parsed_path = urlparse(self.path)
-        
-        # 处理 /tools 接口
-        if parsed_path.path == '/tools':
-            self._handle_tools_request()
-        else:
-            self._set_headers(404)
-            self.wfile.write(json.dumps({"error": "未找到接口"}).encode('utf-8'))
-    
-    def do_POST(self):
-        """
-        处理POST请求
-        """
-        parsed_path = urlparse(self.path)
-        
-        # 处理 /call 接口
-        if parsed_path.path == '/call':
-            self._handle_call_request()
-        else:
-            self._set_headers(404)
-            self.wfile.write(json.dumps({"error": "未找到接口"}).encode('utf-8'))
-    
-    def _handle_tools_request(self):
-        """
-        处理 /tools 请求,返回所有MCP工具列表
-        """
-        try:
-            # 在新的事件循环中运行异步代码
-            loop = asyncio.new_event_loop()
-            asyncio.set_event_loop(loop)
-            
-            tools = loop.run_until_complete(
-                self.server_manager.get_all_mcp_tools()
-            )
-            loop.close()
-            
-            self._set_headers()
-            self.wfile.write(json.dumps(tools, ensure_ascii=False).encode('utf-8'))
-        except Exception as e:
-            self._set_headers(500)
-            self.wfile.write(json.dumps({"error": str(e)}).encode('utf-8'))
-    
-    def _handle_call_request(self):
-        """
-        处理 /call 请求,调用指定的MCP工具
-        """
-        try:
-            # 读取请求体
-            content_length = int(self.headers['Content-Length'])
-            post_data = self.rfile.read(content_length)
-            
-            # 解析JSON数据
-            data = json.loads(post_data.decode('utf-8'))
-            
-            # 获取必要参数
-            tool_name = data.get('name')
-            arguments = data.get('arguments', {})
-            
-            if not tool_name:
-                self._set_headers(400)
-                self.wfile.write(json.dumps({"error": "缺少工具名称"}).encode('utf-8'))
-                return
-            
-            # 在新的事件循环中运行异步代码
-            loop = asyncio.new_event_loop()
-            asyncio.set_event_loop(loop)
-            
-            result = loop.run_until_complete(
-                self.server_manager.call_mcp_tool(tool_name, arguments)
-            )
-            loop.close()
-            
-            # 检查是否有错误
-            if isinstance(result, dict) and "error" in result:
-                self._set_headers(500)
-            else:
-                self._set_headers()
-            
-            self.wfile.write(json.dumps(result, ensure_ascii=False).encode('utf-8'))
-        except json.JSONDecodeError:
-            self._set_headers(400)
-            self.wfile.write(json.dumps({"error": "无效的JSON格式"}).encode('utf-8'))
-        except Exception as e:
-            self._set_headers(500)
-            self.wfile.write(json.dumps({"error": str(e)}).encode('utf-8'))
+    try:
+        tools = await mcp_manager.get_all_mcp_tools()
+        return tools
+    except Exception as e:
+        raise HTTPException(status_code=500, detail=str(e))
+
 
-class MCPAPIServer:
+@app.post("/call")
+async def call_tool(request: CallRequest):
     """
-    MCP API服务器主类
+    调用指定的MCP工具
     """
-    
-    def __init__(self, host='localhost', port=8000, config_file='mcp_config.json'):
-        self.host = host
-        self.port = port
-        self.server_manager = MCPServerManager(config_file)
-        # 将server_manager设置为请求处理器的类变量
-        MCPAPIHandler.server_manager = self.server_manager
-    
-    def start(self):
-        """
-        启动MCP API服务器
-        """
-        # 初始化所有服务器
-        print("正在初始化MCP服务器...")
-        loop = asyncio.new_event_loop()
-        asyncio.set_event_loop(loop)
-        loop.run_until_complete(self.server_manager.initialize_all_servers())
-        loop.close()
-        print("MCP服务器初始化完成")
-        
-        # 启动HTTP服务器
-        server_address = (self.host, self.port)
-        httpd = HTTPServer(server_address, MCPAPIHandler)
-        print(f"启动MCP API服务器: http://{self.host}:{self.port}")
-        httpd.serve_forever()
+    try:
+        result = await mcp_manager.call_mcp_tool(request.name, request.arguments)
+        # 检查是否有错误
+        if isinstance(result, dict) and "error" in result:
+            raise HTTPException(status_code=500, detail=result["error"])
+        return result
+    except HTTPException:
+        raise
+    except Exception as e:
+        raise HTTPException(status_code=500, detail=str(e))
+
 
 if __name__ == "__main__":
-    # 创建并启动MCP API服务器
-    api_server = MCPAPIServer()
-    api_server.start()
+    # 初始化所有服务器
+    print("正在初始化MCP服务器...")
+    loop = asyncio.get_event_loop()
+    loop.run_until_complete(mcp_manager.initialize_all_servers())
+    print("MCP服务器初始化完成")
+    
+    # 启动FastAPI服务器
+    print("启动MCP API服务器: http://localhost:8000")
+    uvicorn.run("mcp_api_server:app", host="localhost", port=8000, reload=False)