search_mcp_server.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. """搜索 MCP 服务器 - 为 Agent 提供联网搜索能力"""
  2. import os
  3. from typing import Optional
  4. try:
  5. from fastmcp import FastMCP
  6. except ImportError:
  7. print("▸️ 需要安装 fastmcp: pip install fastmcp")
  8. exit(1)
  9. # 创建 MCP 服务器
  10. mcp = FastMCP("search-server")
  11. @mcp.tool()
  12. def web_search(query: str, max_results: int = 3) -> str:
  13. """
  14. 联网搜索工具
  15. Args:
  16. query: 搜索查询词
  17. max_results: 返回结果数量(默认3条)
  18. Returns:
  19. 搜索结果摘要
  20. """
  21. print(f"▸ 执行搜索: {query}")
  22. # 尝试使用 Tavily(推荐)
  23. tavily_key = os.getenv("TAVILY_API_KEY")
  24. if tavily_key:
  25. try:
  26. from tavily import TavilyClient
  27. client = TavilyClient(api_key=tavily_key)
  28. response = client.search(query=query, max_results=max_results)
  29. result = ""
  30. if response.get('answer'):
  31. result += f"▸ AI 答案:{response['answer']}\n\n"
  32. result += "▸ 相关结果:\n"
  33. for i, item in enumerate(response.get('results', [])[:max_results], 1):
  34. result += f"[{i}] {item.get('title', '')}\n"
  35. result += f" {item.get('content', '')[:200]}...\n"
  36. result += f" 来源: {item.get('url', '')}\n\n"
  37. return result
  38. except Exception as e:
  39. print(f"▸️ Tavily 搜索失败: {e}")
  40. # 尝试使用 SerpAPI
  41. serpapi_key = os.getenv("SERPAPI_API_KEY")
  42. if serpapi_key:
  43. try:
  44. from serpapi import GoogleSearch
  45. search = GoogleSearch({
  46. "q": query,
  47. "api_key": serpapi_key,
  48. "num": max_results,
  49. "gl": "cn",
  50. "hl": "zh-cn"
  51. })
  52. results = search.get_dict()
  53. result = "▸ 搜索结果:\n"
  54. # 优先返回答案框
  55. if "answer_box" in results and "answer" in results["answer_box"]:
  56. result += f"▸ 直接答案:{results['answer_box']['answer']}\n\n"
  57. # 知识图谱
  58. if "knowledge_graph" in results and "description" in results["knowledge_graph"]:
  59. result += f"▸ 知识图谱:{results['knowledge_graph']['description']}\n\n"
  60. # 有机结果
  61. if "organic_results" in results:
  62. for i, res in enumerate(results["organic_results"][:max_results], 1):
  63. result += f"[{i}] {res.get('title', '')}\n"
  64. result += f" {res.get('snippet', '')}\n"
  65. result += f" {res.get('link', '')}\n\n"
  66. return result
  67. except Exception as e:
  68. print(f"▸️ SerpAPI 搜索失败: {e}")
  69. # 如果都不可用
  70. return """▸ 搜索功能不可用,请配置以下 API 密钥之一:
  71. 1. Tavily API(推荐)
  72. - 设置环境变量: TAVILY_API_KEY
  73. - 获取地址: https://tavily.com/
  74. - 安装: pip install tavily-python
  75. 2. SerpAPI
  76. - 设置环境变量: SERPAPI_API_KEY
  77. - 获取地址: https://serpapi.com/
  78. - 安装: pip install google-search-results
  79. 配置后重新启动系统。"""
  80. @mcp.tool()
  81. def search_recent_info(topic: str) -> str:
  82. """
  83. 搜索最新信息(近期新闻、技术更新等)
  84. Args:
  85. topic: 搜索主题
  86. Returns:
  87. 最新信息摘要
  88. """
  89. # 添加时间限定词
  90. query = f"{topic} 最新 2024"
  91. return web_search(query, max_results=3)
  92. @mcp.tool()
  93. def search_code_examples(technology: str, task: str) -> str:
  94. """
  95. 搜索代码示例
  96. Args:
  97. technology: 技术栈(如 Python、JavaScript)
  98. task: 任务描述(如 "异步编程"、"文件处理")
  99. Returns:
  100. 代码示例和说明
  101. """
  102. query = f"{technology} {task} 代码示例 教程"
  103. return web_search(query, max_results=3)
  104. @mcp.tool()
  105. def verify_facts(statement: str) -> str:
  106. """
  107. 验证事实准确性
  108. Args:
  109. statement: 需要验证的陈述
  110. Returns:
  111. 验证结果
  112. """
  113. query = f"{statement} 事实验证"
  114. return web_search(query, max_results=3)
  115. if __name__ == "__main__":
  116. # 运行 MCP 服务器
  117. print("▸ 启动搜索 MCP 服务器...")
  118. print(" 提供工具: web_search, search_recent_info, search_code_examples, verify_facts")
  119. mcp.run()