From e43803ec21894cdd86b90ea94b94d22336cb6bd8 Mon Sep 17 00:00:00 2001 From: mshe <666666666@666666666.666666666> Date: Mon, 8 Jun 2026 14:57:20 +0800 Subject: [PATCH] mcp --- app.py | 103 +++++++++++++++++++++++++++++++++++++++--- pre_install_spider.sh | 4 +- requirements.txt | 6 ++- spider/mail_qq.py | 8 +--- 4 files changed, 105 insertions(+), 16 deletions(-) mode change 100644 => 100755 app.py diff --git a/app.py b/app.py old mode 100644 new mode 100755 index 5d20a01..bdeb174 --- a/app.py +++ b/app.py @@ -1,12 +1,101 @@ -from flask import Flask +from fastmcp import FastMCP +from spider.mail_qq import start as a1 +mcp = FastMCP("spider-server") +import logging +logging.basicConfig(level=logging.INFO) +# 日志会输出到 stderr,不会污染 stdout +logging.info("服务器启动") +@mcp.tool() +def mail_qq_spider(account: str) -> str: + """qq邮箱爬虫,第一个参数是用户名""" + return a1(account) -app = Flask(__name__) +# 添加一个简单的工具 +@mcp.tool() +def hello(name: str) -> str: + """Say hello to someone""" + return f"Hello, {name}!" +# 运行服务器 +if __name__ == "__main__": + mcp.run(transport="sse") + # mcp.run(transport="stdio") + + +from fastmcp import FastMCP +import subprocess +import asyncio +import tempfile +import os -@app.route('/') -def hello_world(): # put application's code here - return 'Hello World!' +mcp = FastMCP("VNC Spider Manager") +@mcp.tool() +async def run_spider_in_vnc(index: int, username: str = None) -> str: + """在 VNC 会话中运行爬虫 + + Args: + index: VNC 显示编号 + username: 用户名(默认 user{index}) + """ + + if username is None: + username = f"user{index}" + + try: + # 创建临时脚本 + with tempfile.NamedTemporaryFile(mode='w', suffix='.sh', delete=False) as f: + f.write(f"""#!/bin/bash +PUBLIC_DIR="/shared" +username="{username}" +export DISPLAY=:{index} -if __name__ == '__main__': - app.run() +echo "启动 VNC 服务" +sudo su - "$username" -c "vncserver :{index} -geometry 1280x800 -depth 24 -localhost no" +sudo su - "$username" -c "export DISPLAY=:{index} && xhost +" 2>/dev/null +sleep 3 + +cd $PUBLIC_DIR/learn-spider +sudo -E ./run.sh + +sudo su - "$username" -c "vncserver -kill :{index}" 2>/dev/null +""") + script_path = f.name + + # 执行脚本 + os.chmod(script_path, 0o755) + + process = await asyncio.create_subprocess_exec( + script_path, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + + stdout, stderr = await process.communicate() + + # 清理临时文件 + os.unlink(script_path) + + if process.returncode == 0: + return f"✅ 爬虫执行成功\n输出:\n{stdout.decode()}" + else: + return f"❌ 爬虫执行失败\n错误:\n{stderr.decode()}" + + except Exception as e: + return f"❌ 执行出错: {str(e)}" + +@mcp.tool() +async def stop_vnc_server(index: int, username: str = None) -> str: + """停止 VNC 服务器""" + + if username is None: + username = f"user{index}" + + result = subprocess.run( + f'sudo su - {username} -c "vncserver -kill :{index}"', + shell=True, + capture_output=True, + text=True + ) + + return f"VNC 服务器已停止: {result.stdout}" diff --git a/pre_install_spider.sh b/pre_install_spider.sh index 6f102c2..7a31607 100755 --- a/pre_install_spider.sh +++ b/pre_install_spider.sh @@ -1,6 +1,6 @@ #!/bin/bash -apt install -y python3.12-dev python3.12-venv -python3 -m venv .venv --system-site-packages +apt install -y python3.13-dev python3.13-venv +python3.13 -m venv .venv --system-site-packages source .venv/bin/activate .venv/bin/pip install -r requirements.txt -i https://mirrors.cloud.tencent.com/pypi/simple/ .venv/bin/playwright install chromium diff --git a/requirements.txt b/requirements.txt index f11f711..c20b6e4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,4 +29,8 @@ pandas==2.2.1 # 数据分析 numpy==1.26.4 # 科学计算 # 爬虫框架 -scrapy==2.11.1 # 重量级爬虫框架 \ No newline at end of file +scrapy==2.11.1 # 重量级爬虫框架 + + +fastmcp +mcp[cli] \ No newline at end of file diff --git a/spider/mail_qq.py b/spider/mail_qq.py index 3864cbe..ca5ad20 100644 --- a/spider/mail_qq.py +++ b/spider/mail_qq.py @@ -105,12 +105,7 @@ def crawl_with_saved_state(auth_file): browser.close() - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description='爬虫脚本') - parser.add_argument('account', help='用户') - args = parser.parse_args() - account = args.account +def start(account): print(f"用户名{account}") if not account: print("请输入用户名") @@ -121,3 +116,4 @@ if __name__ == "__main__": crawl_with_saved_state(file_path) else: save_login_state(file_path,"收件箱") +