网页搜索服务

为MCP代理提供从公共网络获取实时信息的服务,支持搜索查询、结果抓取和摘要生成,适用于需要实时数据支持的问答场景。

  • by Norbi0801
  • Python
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 Norbi0801/mcp-web-search

使用说明

MCP网络搜索服务器——架构草案

项目目标

为MCP代理提供一种从公共网络获取最新信息的方式,以便他们能够实时回答问题。该服务设计为独立运行,集成在当前的工作空间中 mcp-web-search 目录结构,并且可通过 Docker Compose 进行部署。

范围与假设

  • 初始集成通过解析搜索结果页面来定位公共DuckDuckGo HTML端点(无需API密钥);如有需要,稍后可以更换提供者。
  • 查询按顺序计划和执行:提交搜索表单 → 下载结果页面 → 跟踪所选链接并提取关键事实。
  • 初始、可配置的限制:
    • 每个代理支持5个并发查询。
    • 全球范围内每分钟60次查询。
  • 仅记录元数据:查询文本、代理标识符、访问的URL、HTTP状态码、延迟。元数据保留时间上限为30天。
  • 完整的结果数据体从未持久化存储在内存缓存之外(TTL < 1小时)。
  • 传输必须加密(搜索引擎和获取的页面使用HTTPS;MCP服务器入口使用TLS)。

组件和模块

模块 角色
main.py MCP(模型上下文协议)入口点,用于存储工具和资源注册表。
search_client.py 搜索提供商客户端处理认证流程和配额。
crawler.py 在遵守robots.txt协议和请求限制的前提下,获取并清理结果页面。
summarizer.py 将结果整合成摘要(例如,提取概述加重点)。
rate_limiter.py 每个代理和全局令牌桶限制,并集成了指标监控。
telemetry.py Prometheus 指标、JSON 日志(标准输出)以及可选的 OTEL 追踪。
config.py 从(指定位置)加载配置 .env (API密钥、限制、超时)。
service.py 协调工作流程(限制 → 搜索客户端 → 爬虫 → 总结)。
cache.py 简单的查询缓存,支持可配置的TTL(默认10分钟)。
tools.py 适应 WebSearchService 对MCP工具的响应。
app.py 模拟HTTP服务器(FastAPI)提供一个演示端点。
server.py 官方MCP SDK的集成点(可选,需要 mcp (软件包)。
storage.py (可选) 轻量级的元数据存储,用于未来Postgres/pgvector数据的保留。

计划中的目录布局:

mcp-web-search/
├── README.md
├── main.py
├── search_client.py
├── crawler.py
├── summarizer.py
├── rate_limiter.py
├── telemetry.py
├── config.py
├── tests/
│   └── __init__.py
├── docker/
│   └── Dockerfile
├── docker-compose.yml (symlinked at the workspace root)
├── .env.example
└── pyproject.toml

请求流程

  1. 代理调用 web_search.query 带有查询文本和可选参数(语言、最大结果数)的工具。
  2. main.py 实施每个代理和全局限制,并移交至 search_client.
  3. search_client 向搜索引擎发出查询并接收一系列顶级搜索结果。
  4. crawler 获取选定的结果(并行进行,每个域名有相应的限制和超时设置)。
  5. summarizer 将片段缝合成摘要,并附上引用列表/网址列表。
  6. 响应返回给代理,并记录元数据以供日志记录/指标分析。

遥测与可观测性

  • 日志在标准输出上以 JSON 格式输出(INFO/ERROR)查询标识符和已访问的 URL。
  • 指标 (普罗米修斯):
    • web_search_queries_total{agent}
    • web_search_query_latency_seconds
    • web_search_pages_fetched_total{domain}
    • web_search_rate_limiter_drops_total{reason}
  • 警报服务级别目标(SLO)为99%的查询在8秒内完成;如果吞吐量降至每分钟少于两次成功查询,则页面将进入待命状态(部署后进行调整)。
  • 痕迹 (可选):如果需要端到端追踪,请与OTEL导出器集成。

附加文件

  • docs/mcp_web_search_plan.md – 网络搜索服务器的详细架构规划。

CLI 使用方法(临时)

为了快速验证框架,您可以运行一个单独的查询:

uv pip install -e .
python main.py --query "latest ai security research" --max-results 3
# or fetch the full contents of a page:
python main.py --fetch-url "https://example.com"
# When using `uv` on WSL, set a local cache if you see cache/link issues:
# mkdir -p .uvcache
# export UV_CACHE_DIR="$PWD/.uvcache"
# export UV_LINK_MODE=copy
# uv sync

默认的代理标识符是 cli-agent; 用……覆盖它 --agent-id 如有需要。 针对DuckDuckGo HTML发出查询(https://html.duckduckgo.com/html/)。 设定 USE_STUB_DATA=true 以完全避免网络流量,并依赖内置的测试装置。

搜索引擎提供商

  • SEARCH_PROVIDER=duckduckgo_html – 使用DuckDuckGo的HTML(https://html.duckduckgo.com/html/) 没有API密钥。
  • SEARCH_API_URL – 默认为 https://html.duckduckgo.com/html/在使用自定义代理时进行替换。
  • SEARCH_USER_AGENT – 用于搜索HTTP请求的用户代理头部。
  • SEARCH_LANGUAGE – kl 参数(例如。 us-en, pl-pl传递给API和HTML端点。
  • 替代提供商(例如,Bing)需要一个密钥(SEARCH_API_KEY) 并更新 SEARCH_PROVIDER。

页面检索

  • MCP工具 web_search.fetch_page 返回状态码、内容类型、完整的HTML页面以及页面的纯文本版本。
  • CLI缓存响应(CACHE_TTL_SECONDS) 并暴露出 fetched_pages[...].text_preview 对于前三个结果。

结果缓存

  • ENABLE_QUERY_CACHE (默认 true) – 启用内存查询缓存。
  • CACHE_TTL_SECONDS (默认 600) – 最大缓存条目生命周期;设置为 0 有效禁用缓存或调用 QueryCache.clear() 冲洗。

运行MCP服务器(标准输入输出,实验性)

  1. 创建/激活虚拟环境:
    cd /mnt/c/Users/norbe/Documents/AI Organisation/sandbox/mcp-web-search
    python -m venv .venv       # or uv venv .venv
    source .venv/bin/activate  # Scripts/activate.bat on Windows
    
  2. 安装包含MCP附加功能的软件包:
    pip install -e .[mcp]
    
  3. 在本地启动stdio服务器(支持两者) uv run 以及本地的Python二进制文件):
    uv run main.py --serve-stdio
    # or
    .venv/bin/python main.py --serve-stdio
    
    (寻找 Starting MCP stdio server 剧情梗概。)
  4. 通过编辑来配置Codex ~/.codex/config.toml 如“连接到Codex”部分所示。
  5. 如果MCP SDK没有提供stdio传输接口,则进行扩展 server.py 根据(具体情况),为每种情况提供专门的替代方案(例如,WebSocket) mcp 软件包文档。

模拟HTTP API(演示)

uv pip install uvicorn[standard]
python main.py --serve-http

服务器监听在 http://localhost:8000/web-search?query=... 并在您配置真实提供程序之前,使用模拟数据返回 JSON。

测试

uv pip install -e .[dev]
# if pytest is missing on PATH (e.g. system Python), install it locally:
# python -m pip install pytest
pytest --maxfail=1 --disable-warnings

MCP 集成(可选)

  • 安装SDK: uv pip install -e .[mcp]。
  • 扩展 server.py:create_mcp_server 使用所需的传输方式(例如,WebSocket、stdio),如文档中所述 mcp 文档。
  • 暴露的工具:
    • web_search.query(query: str, max_results: int = 5, agent_id: str = "mcp")
    • web_search.fetch_page(url: str)
  • 服务器运行后,请将Codex指向此工具标识符(有关配置详情,请参阅Codex CLI存储库)。

MCP运输整合计划

  1. 选择一个与Codex兼容的传输方式(stdio或WebSocket),并安装推荐版本的 mcp 软件包/包裹。
  2. 在 server.py,实现事件循环(例如。, server.run_stdio() 或者一个定制的WebSocket循环,并将其连接到 main.py 在……后面 --serve-stdio 或者一个新的 --serve-ws 旗帜。
  3. 配置工具注册表(web_search.query, web_search.fetch_page) 附上适当的 schema/description 阻止(或设置)以便客户端可以验证参数。
  4. 如有必要,请为Codex准备一个工具清单/描述符(JSON/YAML格式),并通过Docker Compose或CLI配置将其暴露出来。

连接到Codex(配置示例)

  1. 依赖项: uv pip install -e .[mcp]
  2. 宣言: the manifest.json 该文件描述了两种工具;如需使用,请在Codex配置中提供其路径。
  3. 配置在 ~/.codex/config.toml:
    [mcp_servers.mcp-web-search]
    command = "uv"
    args = ["run", "python", "main.py", "--serve-stdio"]
    cwd = "*****/mcp-web-search"
    startup_timeout_sec = 30
    manifest_path = "*****/mcp-web-search/manifest.json"
    env = { SEARCH_LANGUAGE = "us-en" }
    
  4. 重启《索引》(或《典籍》): 保存后,重启客户端 mcp-web-search 服务器将公开/暴露 web_search.query 和 web_search.fetch_page 工具。

安全与合规

  • 仅允许出站连接到受信任的域(可配置允许列表)。
  • 在日志中对敏感数据进行掩码处理(例如,URL中的认证参数)。
  • 保留日志30天;在需要时对代理标识符进行轮换和匿名化处理。
  • 收集搜索API使用权限/许可证(将密钥存储在 .env(永远不要提交到仓库中)。