tools.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import json
  2. import urllib.request
  3. import urllib.parse
  4. import urllib.error
  5. from html.parser import HTMLParser
  6. class MLStripper(HTMLParser):
  7. def __init__(self):
  8. super().__init__()
  9. self.reset()
  10. self.fed = []
  11. def handle_data(self, d):
  12. self.fed.append(d)
  13. def get_data(self):
  14. return ''.join(self.fed)
  15. def strip_tags(html):
  16. s = MLStripper()
  17. s.feed(html)
  18. return s.get_data()
  19. class Tools:
  20. def __init__(self, mcp_api_url="http://localhost:8000"):
  21. self.mcp_api_url = mcp_api_url
  22. def get_tool_list(self):
  23. # 基础工具
  24. tools = [
  25. {
  26. "type": "function",
  27. "function": {
  28. "name": "read_webpage",
  29. "description": "读取指定URL网页的文本内容",
  30. "parameters": {"type": "object", "properties": {"url": {"type": "string", "description": "要读取的网页URL"}}}
  31. }
  32. }
  33. ]
  34. # 获取所有MCP服务的实际工具
  35. try:
  36. req = urllib.request.Request(f"{self.mcp_api_url}/tools")
  37. with urllib.request.urlopen(req) as response:
  38. mcp_tools = json.loads(response.read().decode('utf-8'))
  39. # 为每个MCP工具创建独立的工具定义
  40. for tool in mcp_tools:
  41. tools.append({
  42. "type": "function",
  43. "function": {
  44. "name": tool.get("name"), # 工具名称已经带有_mcp后缀
  45. "description": tool.get("description", "未知工具"),
  46. "parameters": tool.get("inputSchema", {
  47. "type": "object",
  48. "properties": {},
  49. "required": []
  50. })
  51. }
  52. })
  53. except Exception as e:
  54. print(f"获取MCP工具列表时出错: {e}")
  55. return tools
  56. def call_tool(self, tool_name, parameters):
  57. print(f"🔧 正在执行工具: {tool_name}({parameters})")
  58. # 处理原有的工具
  59. if tool_name == "read_webpage":
  60. # 实现读取网页内容功能
  61. try:
  62. url = parameters["url"]
  63. req = urllib.request.Request(url, headers={
  64. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
  65. })
  66. with urllib.request.urlopen(req) as response:
  67. html = response.read().decode('utf-8')
  68. text = strip_tags(html)
  69. return text
  70. except Exception as e:
  71. return f"读取网页错误: {str(e)}"
  72. # 处理MCP工具
  73. elif tool_name.endswith("_mcp"):
  74. # 调用MCP API服务器
  75. try:
  76. # 构造请求数据
  77. data = {
  78. "name": tool_name,
  79. "arguments": parameters
  80. }
  81. # 发送POST请求到MCP API服务器
  82. req = urllib.request.Request(
  83. f"{self.mcp_api_url}/call",
  84. data=json.dumps(data).encode('utf-8'),
  85. headers={'Content-Type': 'application/json'}
  86. )
  87. with urllib.request.urlopen(req) as response:
  88. result = json.loads(response.read().decode('utf-8'))
  89. # 检查是否有错误
  90. if "error" in result:
  91. error_msg = result['error']
  92. return f"MCP调用错误: {error_msg}"
  93. # 返回结果
  94. return json.dumps(result, ensure_ascii=False)
  95. except urllib.error.HTTPError as e:
  96. return f"MCP调用HTTP错误: {e.code} - {e.reason}"
  97. except Exception as e:
  98. return f"MCP调用失败: {str(e)}"
  99. else:
  100. return f"未知工具: {tool_name}"
  101. if __name__ == "__main__":
  102. tools = Tools()
  103. print(tools.get_tool_list())