Skip to main content
Glama
waifuai

MCP Waifu Queue

by waifuai

MCP Waifu 队列

本项目实现了一个用于对话式 AI “老婆”角色的 MCP(模型上下文协议)服务器,通过 Redis 队列利用 OpenRouter API 进行异步处理。它使用 FastMCP 库来简化服务器的设置和管理。

目录

Related MCP server: local-agent-context

功能

  • 通过 OpenRouter 进行文本生成,使用 ~/.model-openrouter 或 openrouter/free 中的模型。

  • 使用 Redis 进行请求排队,以异步处理并发请求。

  • 使用 FastMCP 的符合 MCP 标准的 API。

  • 通过 MCP 资源跟踪作业状态。

  • 通过环境变量(.env 文件)进行配置。

  • API 密钥加载:

    • OpenRouter: OPENROUTER_API_KEY 或 ~/.api-openrouter

  • 主目录中的模型选择文件:

    • ~/.model-openrouter 用于指定 OpenRouter 模型名称

架构

该项目包含几个关键组件:

  • main.py: 主入口点,初始化 FastMCP 应用程序并定义 MCP 工具/资源。

  • respond.py: 包含使用 OpenRouter API 的核心文本生成逻辑。

  • task_queue.py: 处理与 Redis 队列的交互(使用 python-rq),将生成请求入队。

  • utils.py: 包含实用函数,特别是 call_predict_response,由工作进程执行以调用 respond.py 中的生成逻辑。

  • worker.py: 一个 Redis 工作进程(python-rq),处理来自队列的作业,调用 call_predict_response。

  • config.py: 使用 pydantic-settings 管理配置。

  • models.py: 定义用于 MCP 请求和响应验证的 Pydantic 模型。

请求流程如下:

  1. 客户端向 generate_text MCP 工具(在 main.py 中定义)发送请求。

  2. 该工具将请求(提示词)入队到 Redis 队列(由 task_queue.py 处理)。

  3. worker.py 进程从队列中获取作业。

  4. 工作进程执行 call_predict_response 函数(来自 utils.py)。

  5. call_predict_response 调用 predict_response 函数(在 respond.py 中),该函数与 OpenRouter API 进行交互。

  6. 生成的文本(或错误消息)由 predict_response 返回,并由 RQ 存储为作业结果。

  7. 客户端可以使用 job://{job_id} MCP 资源(在 main.py 中定义)检索作业状态和结果。

graph LR
    subgraph Client
        A[User/Client] -->|1. Send Prompt via MCP Tool| B(mcp-waifu-queue: main.py)
    end
    subgraph mcp-waifu-queue Server
        B -->|2. Enqueue Job (prompt)| C[Redis Queue]
        B -->|7. Return Job ID| A
        D[RQ Worker (worker.py)] --|>| C
        D -->|3. Dequeue Job & Execute| E(utils.call_predict_response)
        E -->|4. Call Generation Logic| F(respond.predict_response)
        F -->|5. Call OpenRouter API| G[OpenRouter API]
        G -->|6. Return Response| F
        F --> E
        E -->|Update Job Result in Redis| C
        A -->|8. Check Status via MCP Resource| B
        B -->|9. Fetch Job Status/Result| C
        B -->|10. Return Status/Result| A
    end

先决条件

  • Python 3.7+

  • pip 或 uv(Python 包安装程序)

  • Redis 服务器(已安装并运行)

  • OpenRouter API 密钥

您可以在 Redis 官方网站上找到在您的系统上安装 Redis 的说明:https://redis.io/docs/getting-started/ 您可以从以下地址获取 OpenRouter API 密钥:https://openrouter.ai/

安装

  1. 克隆仓库:

    git clone <YOUR_REPOSITORY_URL>
    cd mcp-waifu-queue
  2. 使用 uv 创建并激活虚拟环境:

    python -m uv venv .venv
    .venv/Scripts/python.exe -m ensurepip
    .venv/Scripts/python.exe -m pip install uv
  3. 安装依赖项:

    .venv/Scripts/python.exe -m uv pip install -r requirements.txt
    .venv/Scripts/python.exe -m uv pip install -r requirements-dev.txt

配置

  1. 通过 $HOME 中的文件设置模型名称:

    • OpenRouter 模型文件:

      echo "openrouter/free" > ~/.model-openrouter
  2. API 密钥: 优先使用环境变量,并支持文件回退:

    • OpenRouter: OPENROUTER_API_KEY 或 ~/.api-openrouter GXP6

    (将 YOUR_API_KEY_HERE 替换为您实际的密钥)

  3. 其他设置: 将 .env.example 文件复制到 .env:

    cp .env.example .env
  4. 修改 .env 文件以设置其余配置值:

    • MAX_NEW_TOKENS: 响应的最大 token 数(默认:2048)。

    • REDIS_URL: Redis 服务器的 URL(默认:redis://localhost:6379)。

    • FLASK_ENV, FLASK_APP: 可选,如果其他地方使用了 Flask 则相关,并非 MCP 服务器/工作进程操作的核心。

运行服务

  1. 确保 Redis 正在运行。 如果您在本地安装了它,您可能需要启动 Redis 服务器进程(例如 redis-server 命令,或通过服务管理器)。

  2. 启动 RQ 工作进程: 打开一个终端,激活您的虚拟环境(source .venv/bin/activate 或类似命令),然后运行:

    python -m mcp_waifu_queue.worker

    此命令启动工作进程,它将监听 .env 文件中定义的 Redis 队列中的作业。保持此终端运行。

  3. 启动 MCP 服务器: 打开另一个终端,激活虚拟环境,并使用类似 uvicorn 的工具运行 MCP 服务器(您可能需要安装它:pip install uvicorn 或 uv pip install uvicorn):

    uvicorn mcp_waifu_queue.main:app --reload --port 8000 # Example port

    将 8000 替换为您想要的端口。--reload 标志对于开发很有用。

    或者,您可以使用 start-services.sh 脚本(主要为 Linux/macOS 环境设计),它会尝试在后台启动 Redis(如果未运行)和工作进程:

    # Ensure the script is executable: chmod +x ./scripts/start-services.sh
    ./scripts/start-services.sh
    # Then start the MCP server manually as shown above.

MCP API

服务器提供以下符合 MCP 标准的端点:

工具

  • generate_text

    • 描述: 通过后台队列向 OpenRouter API 发送文本生成请求。

    • 输入: {"prompt": "Your text prompt here"} (类型:GenerateTextRequest)

    • 输出: {"job_id": "rq:job:..."} (排队作业的唯一 ID)

资源

  • job://{job_id}

    • 描述: 检索先前提交的作业的状态和结果。

    • URI 参数: job_id (generate_text 工具返回的 ID)。

    • 输出: {"status": "...", "result": "..."} (类型:JobStatusResponse)

      • status: 作业的当前状态(例如,“queued”、“started”、“finished”、“failed”)。RQ 在内部使用略有不同的术语(“started” vs “processing”,“finished” vs “completed”)。资源会对这些进行映射。

      • result: 如果作业状态为“completed”,则为生成的文本,否则为 null。如果作业失败,结果可能是 null 或包含错误信息,具体取决于 RQ 的处理方式。

测试

该项目包含测试。确保您已安装测试依赖项(pip install -e .[test] 或 uv pip install -e .[test])。

使用 pytest 运行测试:

pytest tests

注意: 测试可能需要模拟 Redis (fakeredis),并根据其实现可能需要模拟 OpenRouter API 调用。

故障排除

  • 错误:OpenRouter API key not available: 确保已设置 OPENROUTER_API_KEY,或者 ~/.api-openrouter 文件存在且包含您的密钥(单行,无空格)。

  • 作业卡在“queued”: 验证 RQ 工作进程 (python -m mcp_waifu_queue.worker) 是否在单独的终端中运行,并连接到 .env 中指定的同一个 Redis 实例。检查工作进程日志以获取错误信息。

  • ConnectionRefusedError (Redis): 确保您的 Redis 服务器正在运行,并且可以在 .env 中指定的 REDIS_URL 处访问。

  • MCP 服务器连接问题: 确保 MCP 服务器 (uvicorn ...) 正在运行,并且您连接到了正确的主机/端口。

贡献

  1. Fork 该仓库。

  2. 为您的功能或错误修复创建一个新分支 (git checkout -b feature/your-feature-name)。

  3. 进行更改并提交 (git commit -am 'Add some feature')。

  4. 将您的分支推送到您的 Fork 仓库 (git push origin feature/your-feature-name)。

  5. 在原始仓库上创建 Pull Request。

请遵守项目的编码标准和 linting 规则 (ruff)。

许可证

本项目采用 MIT-0 许可证 - 有关详细信息,请参阅 LICENSE 文件。

Related MCP Connectors

Related MCP Servers