Skip to main content
Glama

MediaCrawler MCP Server

by mcp-service
README.md7.93 kB
# 生产部署说明 ## 架构概述 本项目使用 **程序化 uvicorn** (Programmatic uvicorn) 方式部署,而不是传统的 `uvicorn app:app` 命令行方式。 ### 为什么这样设计? #### 1. **多服务协调** 我们需要同时运行三种服务: - **STDIO MCP Service**: 用于本地客户端 - **SSE MCP Service** (端口 9090): 用于Web客户端 - **Admin Service** (端口 9091): 用于人工管理 这些服务需要在同一个进程中协调运行,共享配置和资源。 #### 2. **FastMCP 的特殊性** FastMCP 提供了 `run_stdio_async()` 和 `run_sse_async()` 方法,这些方法需要特殊处理: - STDIO 模式需要读取 stdin/stdout - SSE 模式我们 patch 了它的实现 (见 `app/api_service.py:53-61`) #### 3. **代码中已经使用 uvicorn** **SSE 服务** (`app/api_service.py:94-101`): ```python config = uvicorn.Config( starlette_app, host=app.settings.host, port=app.settings.port, log_level=app.settings.log_level.lower(), ) server = uvicorn.Server(config) await server.serve() ``` **Admin 服务** (`main.py:22-30`): ```python config = uvicorn.Config( admin_app, host="0.0.0.0", port=port, log_level="info", loop="asyncio" ) server = uvicorn.Server(config) await server.serve() ``` ### 当前启动流程 ``` Docker CMD: python -u main.py --transport sse --admin ↓ main() 函数 ↓ ┌──────┴──────┐ ↓ ↓ MCP Service Admin Service (port 9090) (port 9091) ↓ ↓ uvicorn.Server uvicorn.Server ↓ ↓ └──────┬──────┘ ↓ asyncio.gather() (并发运行) ``` ## 为什么不用 `uvicorn app:app` 命令? ### 传统方式的限制 如果用传统的 uvicorn 命令: ```bash # 只能启动一个服务 uvicorn app.admin:admin_app --host 0.0.0.0 --port 9091 ``` 问题: 1. ❌ 只能启动一个服务 (要么 MCP,要么 Admin) 2. ❌ 无法处理 STDIO 模式 3. ❌ 无法协调多个服务的生命周期 4. ❌ 无法共享应用状态和配置 ### 当前方式的优势 ```bash python -u main.py --transport sse --admin ``` 优势: 1. ✅ 同时运行多个服务 (MCP + Admin) 2. ✅ 支持三种传输模式 (stdio/sse/both) 3. ✅ 统一的配置管理 4. ✅ 共享资源 (数据库连接、Redis、Logger) 5. ✅ 内部使用 uvicorn.Server,性能相同 ## 生产环境考虑 ### 1. 进程管理 **当前方案** (推荐): ```yaml # docker-compose.yml services: mcp-tools: command: python -u main.py --transport sse --admin restart: unless-stopped ``` **替代方案** (如果需要独立进程管理): ```yaml # 使用 supervisord 分别管理两个服务 command: supervisord -c /app/deploy/supervisord.conf ``` ### 2. 性能调优 #### 单容器多Worker (不推荐) 由于我们有自定义的启动逻辑,使用多个 uvicorn worker 会有问题: ```bash # ❌ 这样不行 gunicorn app:app --workers 4 --worker-class uvicorn.workers.UvicornWorker ``` #### 多容器扩展 (推荐) 使用 Docker Compose 或 Kubernetes 扩展容器数量: ```bash # Docker Compose docker-compose up --scale mcp-tools=3 # Kubernetes kubectl scale deployment mcp-tools --replicas=3 ``` ### 3. 监控和日志 当前配置: - `python -u`: 无缓冲输出,实时查看日志 - 日志输出到 stdout/stderr,方便 Docker 收集 - 可以用 `docker logs` 查看 建议添加: - Prometheus metrics endpoint - Sentry 错误追踪 - ELK/Loki 日志聚合 ## 常见问题 ### Q: 为什么不用 gunicorn? A: Gunicorn 是为传统 WSGI/ASGI 应用设计的,我们的启动逻辑是自定义的: - FastMCP 的 STDIO 模式需要特殊处理 - 多个异步服务需要 `asyncio.gather` 协调 - 使用 gunicorn 会失去这些灵活性 ### Q: 性能会不会差? A: **不会**,因为: - 内部使用 `uvicorn.Server`,性能完全相同 - Uvicorn 本身就是高性能 ASGI 服务器 - 单个容器可以处理大量并发连接 - 需要扩展时,直接扩展容器数量 ### Q: 如何做负载均衡? A: 在容器前加负载均衡器: ``` Nginx/Traefik ↓ ┌─────────┼─────────┐ ↓ ↓ ↓ Container1 Container2 Container3 (9090/9091) (9090/9091) (9090/9091) ``` ### Q: 如何优雅停机? A: 添加信号处理: ```python # main.py import signal def shutdown_handler(sig, frame): get_logger().info("收到停机信号,开始优雅关闭...") # 清理资源 sys.exit(0) signal.signal(signal.SIGTERM, shutdown_handler) signal.signal(signal.SIGINT, shutdown_handler) ``` ## 开发 vs 生产 ### 开发环境 ```bash # 直接运行 python main.py --transport both --admin # 或使用热重载 uvicorn app.admin:admin_app --reload --port 9091 ``` ### 生产环境 ```bash # Docker docker-compose up -d # 查看日志 docker-compose logs -f mcp-tools # 重启服务 docker-compose restart mcp-tools ``` ## 总结 当前的部署方式 (`python -u main.py --transport sse --admin`) **已经是生产就绪的**: ✅ 使用 uvicorn 作为 ASGI 服务器 ✅ 支持多服务并发运行 ✅ 配置灵活,易于管理 ✅ Docker 友好,日志清晰 ✅ 可以通过扩展容器数量来扩展 如果有特殊需求 (如独立进程管理),可以考虑使用 supervisord,但当前方案已经满足大部分生产场景。 --- ## 📖 快速部署指南 ### 前提条件 1. **Docker Desktop 已安装并运行** (Windows/macOS) 或 Docker Engine (Linux) 2. **项目根目录下有 .env 文件** ### 部署步骤 ```bash # 1. 进入 deploy 目录 cd deploy # 2. 确保 start.sh 有执行权限 (Linux/macOS) chmod +x start.sh start-prod.sh # 3. 启动服务(首次部署) ./start.sh prod --build # 4. 查看服务状态 docker compose ps # 5. 查看日志 docker compose logs -f # 6. 访问服务 # MCP Service: http://localhost:9090/sse # Admin Service: http://localhost:9091 ``` ### 常用操作 ```bash cd deploy # 启动服务 ./start.sh prod # 停止服务 docker compose down # 重启服务 docker compose restart mcp-service # 查看日志 docker compose logs -f mcp-service # 清理并重新部署 ./start.sh prod --clean --build ``` ### Windows 用户注意事项 如果无法运行 `./start.sh`,可以直接使用 Docker Compose 命令: ```powershell # 进入 deploy 目录 cd deploy # 启动服务 docker compose up -d --build # 查看状态 docker compose ps # 查看日志 docker compose logs -f # 停止服务 docker compose down ``` ### 排查 Docker 问题 如果遇到 Docker 连接错误: ``` unable to get image: error during connect: open //./pipe/dockerDesktopLinuxEngine ``` **解决方法:** 1. 确认 Docker Desktop 正在运行 2. 在 Windows 系统托盘中查看 Docker 图标 3. 如果没有启动,双击 Docker Desktop 启动 4. 等待 Docker 完全启动后再次尝试 验证 Docker 运行状态: ```bash docker info docker compose version ``` ### 服务访问地址 启动成功后,可以访问以下地址: - **MCP SSE Service:** http://localhost:9090/sse - **Admin Service:** http://localhost:9091 - **Health Check:** http://localhost:9090/health ### 目录说明 ``` deploy/ ├── docker-compose.yml # ⭐ Docker Compose 主配置 ├── start.sh # ⭐ 智能启动脚本 ├── start-prod.sh # 生产启动脚本(容器内用) ├── Dockerfile # Docker 镜像构建文件(符号链接) ├── init-db.sql # 数据库初始化脚本 ├── nginx.conf # Nginx 反向代理配置 ├── supervisord.conf # Supervisor 进程管理配置 └── README.md # 本文档 ``` ### 相关文档 - **架构说明:** 见上方 "架构概述" 部分 - **项目文档:** `../CLAUDE.md` - **API 文档:** `../ADMIN_SERVICE.md` - **部署架构:** `../DEPLOYMENT.md`

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mcp-service/media-crawler-mcp-service'

If you have feedback or need assistance with the MCP directory API, please join our Discord server