import sys import os import asyncio # 路径兼容 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from backend.core.logger import setup_logging # 初始化日志 (写在 FastMCP 初始化之前) setup_logging() from mcp.server.fastmcp import FastMCP from backend.services.crawler_service import crawler_service mcp = FastMCP("WikiCrawler-V3") @mcp.tool() async def kb_add_website(url: str) -> str: """[Admin] Add a website map task.""" try: res = crawler_service.map_site(url) return f"Task Registered. ID: {res['task_id']}, Links Found: {res['count']}" except Exception as e: return f"Error: {e}" @mcp.tool() async def kb_check_status(task_id: int) -> str: """[Monitor] Check detailed progress and active threads.""" data = crawler_service.get_task_status(task_id) if not data: return "Task not found." s = data['stats'] threads = data['active_threads'] report = ( f"Progress: {s['completed']}/{s['total']} (Pending: {s['pending']})\n" f"Active Threads: {len(threads)}\n" ) if threads: report += "Currently Crawling:\n" + "\n".join([f"- {t}" for t in threads[:5]]) return report @mcp.tool() async def kb_run_crawler(task_id: int, batch_size: int = 5) -> str: """[Action] Trigger crawler batch.""" # MCP 同步调用以获得反馈 res = crawler_service.process_queue_concurrent(task_id, batch_size) return f"Batch Finished. Count: {res.get('count', 0)}" @mcp.tool() async def kb_search(query: str, task_id: int = None) -> str: """[User] Search knowledge base.""" res = crawler_service.search(query, task_id, 5) results = res.get('results', []) if not results: return "No results." output = [] for i, r in enumerate(results): score_display = f"{r['score']:.4f}" + (" (Reranked)" if r.get('reranked') else "") meta = r.get('meta_info', {}) path = meta.get('header_path', 'Root') output.append(f"[{i+1}] Score: {score_display}\nPath: {path}\nContent: {r['content'][:200]}...") return "\n\n".join(output) if __name__ == "__main__": mcp.run()