文档检索服务

基于FastMCP的检索代理,提供文档搜索和获取功能,适用于Dify等MCP兼容主机。

  • by jl1nie
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 jl1nie/mcp-sample

使用说明

MCP检索侧边容器(或MCP检索辅助组件)

基于FastMCP的检索代理,该代理提供(或暴露) search_documents, get_documents,以及 health_check 通过可流式传输的HTTP传输工具。设计为作为Dify(1.9+)的边车组件运行,但也可与任何MCP兼容的主机一起使用。

特点/特性

  • 用于同步REST后端的带重试/退避机制的异步HTTP客户端。
  • 对搜索响应进行TTL(生存时间)缓存,以减轻后端负载。
  • 用于快速回答和查询优化的提示模板。
  • /healthz 并且 /config 共享MCP服务器的辅助路线。
  • 综合测试:模拟HTTP层加上针对FastAPI存根的集成套件。

要求

  • Python 3.11及以上版本
  • 紫外线 用于依赖管理和任务执行
  • (可选)使用 Docker 和 Docker Compose 进行容器部署

入门指南/开始使用

  1. 创建虚拟环境并安装依赖项:
    uv venv .venv
    uv pip install fastmcp httpx cachetools pytest pytest-asyncio fastapi uvicorn
    
  2. 激活环境(bash/zsh):
    source .venv/bin/activate
    
  3. 在本地运行MCP服务器:
    uv run python server.py
    # Server listens on http://127.0.0.1:8080/mcp/
    
  4. 更希望将其与另一个容器放在相邻位置?使用提供的Compose文件来启动边车容器:
    docker compose up -d mcp-retrieval
    
    设置环境变量 .env 或者在命令中内联(ENDPOINT_URL, MCP_SERVER_API_KEY等),并调整 Compose 定义的网络以匹配您的 MCP 主机所使用的网络,以便 sidecar 能够解析其内部服务。

环境变量在(相关文档中)有说明 server.py;其中关键的包括:

变量 描述 默认值
ENDPOINT_URL 外部REST搜索API的基准URL (必填)
API_KEY 后端的承载令牌 空
MCP_SERVER_API_KEY 持有令牌的客户端必须发送以访问此MCP服务器 空
REQUEST_TIMEOUT_S 每次请求的超时时间 20
PROXY_URL HTTP(S) 代理URL(用于企业中间人攻击) 空
CACHE_TTL_S 搜索缓存TTL(秒) 60
CACHE_MAX_ITEMS 搜索缓存最大条目数 500
LOG_LEVEL 日志级别 (INFO, DEBUG,…) INFO

MCP 主机示例

要从Dify连接到这台服务器 dify-plugin-tools-mcp_sse 插件,向插件的MCP服务器配置中添加一个条目,指向边车的可流式HTTP端点,并包含在(某处)定义的承载令牌 MCP_SERVER_API_KEY:

{
  "mcpServers": {
    "retrieval-sidecar": {
      "transport": "streamable_http",
      "url": "http://127.0.0.1:8080/mcp",
      "headers": {
        "Authorization": "Bearer ${MCP_SERVER_API_KEY}"
      },
      "timeout": 50
    }
  }
}

设置 MCP_SERVER_API_KEY 在你的 .env (并将其加载到Dify插件的环境中),这样插件在调用这个MCP服务器时就能发送预期的承载令牌。

测试

Make目标封装了首选的(选项/设置/配置等,具体根据上下文确定) uv 命令:

  • make test — 全套(设施/服务)uv run pytest -q)
  • make test-unit — 对(某物)进行了模拟传输测试 tests/test_search_mock.py
  • make test-integration — 对模拟API进行集成测试
  • make test-e2e — 运行集成套件;如果(条件满足)自动启动存根 ENDPOINT_URL 未设置,则使用提供的端点
  • make stub — 在(某处)运行 FastAPI 模板 127.0.0.1:18080

直接调用也同样有效:

uv run pytest -q

Docker

使用提供的构件构建并运行边车服务:

docker compose build
docker compose up

通过环境变量或(某种方式)暴露运行时配置 .env 由 Compose 引用的文件。该服务加入一个名为 dify_network 默认情况下(用以下内容覆盖) DIFY_DOCKER_NETWORK)。

对于在编排网络内部进行的端到端(E2E)测试,请使用补充的编排文件启动存根服务,并将MCP容器指向该服务:

docker compose -f docker-compose.stub.yaml up -d stub-api
docker compose run --rm \
  -e ENDPOINT_URL=http://mcp-retrieval-stub:18080 \
  mcp-retrieval \
  make test-e2

上述命令在容器化环境中运行相同的集成套件,并自动跳过存根引导程序,因为 ENDPOINT_URL 已提供。之后使用(相应方法或工具)关闭该存根 docker compose -f docker-compose.stub.yaml down。

要同时运行MCP服务器和存根(例如,用于本地QA环境),请将组合文件合并:

docker compose -f docker-compose.yaml -f docker-compose.stub.yaml up -d

这使得存根在生产环境中成为可选的,同时便于在测试中启用它。

开发小贴士

  • tests/test_search_mock.py 使用 httpx.MockTransport 用于确定性单元测试。
  • tests/test_integration_stub.py 取决于 uvicorn;夹具启动 stub_api/app.py 在后台线程中。
  • 日志记录采用结构化JSON格式;避免打印敏感信息—— /config 路由掩码自动识别敏感值。