Type something to search...
构建高效的模型上下文协议服务器:使用jina.ai和python实现web搜索与事实核查功能

构建高效的模型上下文协议服务器:使用jina.ai和python实现web搜索与事实核查功能

在这篇文章中,我们将讨论模型上下文协议,它的重要性,以及构建一个MCP服务器的过程,以帮助我们与Jina.ai进行交互,并能够在Claude Desktop中使用Python和FastMCP添加网络搜索和事实核查功能。

Anthropic 宣布 这是在去年的感恩节期间。尽管引起了一些关注,但考虑到它可能是开发下一层AI软件堆栈的关键踏脚石,其认可度可能仍然不足。

什么

模型上下文协议 (MCP) 是一个针对大型语言模型 (LLMs) 和其他生成性人工智能工具的标准化通信协议。

可以将其视为“生成性人工智能的 HTTP”——就像 HTTP 标准化了网页浏览器与网页服务器之间的通信,MCP 标准化了 LLM 应用程序与工具和数据源之间的通信。

为什么我们需要MCP?

当前大型语言模型(LLM)开发面临几个障碍:

  1. 工具集成复杂性:每个LLM服务(如OpenAI、Anthropic等)都有其实现工具调用和函数调用的方式,这使得构建可移植工具变得复杂。

  2. 上下文管理:LLM需要访问各种数据源和工具,但安全高效地管理这种访问一直是个挑战。

  3. 标准化:没有标准协议,开发人员必须为他们希望支持的每个LLM平台重建集成层。

MCP通过提供以下解决方案来应对这些挑战:

  • 一种标准化的方式来向LLM暴露工具和数据
  • 一个安全的客户端-服务器架构
  • 一个一致的接口,无论底层LLM如何

MCP 是如何工作的?

MCP 遵循客户端-服务器架构,主要由三个组件组成:

  1. MCP 服务器:一个暴露以下内容的服务:

    • 工具(LLMs 可以调用的函数)
    • 资源(数据源)
    • 提示(模板化指令)
    • 上下文(动态信息)
  2. MCP 客户端:该应用程序连接到 MCP 服务器并管理 LLM 与服务器之间的通信。客户端支持仍处于早期阶段,目前只有少数工具实现了协议规范的任何部分,还有一些功能尚未被任何客户端支持。

Image 2

当然,还有 LLM…

工作流程

  1. 一个 MCP 服务器注册其能力(工具、资源等)

  2. 客户端连接到服务器或将其作为子进程启动

  3. 然后,LLM 可以通过标准化接口使用这些能力

传输协议

该协议支持多种传输机制:

  • SSE (服务器推送事件):通过HTTP双向通信,服务器进程与客户端隔离
  • Stdio (标准输入/输出):通过标准输入/输出管道进行通信;在这里,服务器进程基本上是客户端的子进程。

安全性

安全形势更加复杂。虽然使用 stdio 传输的服务器通常与客户端共同放置,因此 API 密钥不一定暴露在互联网上,但在我看来,它们似乎被相对随意地传递。

这些密钥需要在服务器启动时加载到客户端,以便可以传递给子进程,它们甚至出现在桌面应用程序的日志中,这让人感到担忧。

API 密钥的广泛使用是一个更广泛的问题,影响着生成性人工智能服务、平台和工具。像 Okta 和 Auth0 这样的公司正在研究 一个解决方案 来管理和授权生成性人工智能,而不完全依赖于密钥。

SDKs

Anthropic officially supports low-level SDKs for TypeScript, Python, and Kotlin. Some of the higher-level wrappers that have recently been created已经覆盖了一些现有的样板代码,并具有其他良好的功能,例如用于调试、检查和在客户端上安装服务器的打包CLI,以便更轻松地开发模型上下文协议服务器。

开始使用 Python SDK

我们现在将探讨如何创建一个几乎实用的工具,用于读取网站、通过网络回答搜索查询以及进行事实核查。我们将使用 Jina.ai

这是一项非常出色的服务,提供一个“搜索基础平台”,结合“嵌入、重排序器和小型语言模型”,帮助企业构建生成性人工智能和多模态搜索体验。

先决条件

您需要安装 uv。这是创建和管理 Python 项目的推荐方式。它是一个相对较新但令人兴奋的 Python 工具链的一部分,名为 astral.sh

uv 旨在成为一个管理项目、依赖项、虚拟环境、版本、代码检查以及执行 Python 脚本和模块的一站式商店。它是用 Rust 编写的。请随意处理这些信息。

您还需要安装 Claude Desktop 应用程序。对于我们的目的,Claude Desktop 应用将作为 MCP 客户端,并且是 Anthropic 的一个关键目标客户端。

项目设置

使用 uv 你可以初始化一个项目:

uv init mcp-jinaai-reader — python 3.11

这将创建一个名为 mcp-jinaai-reader 的文件夹,一个 .python-version,以及一个 pyproject.toml

cd mcp-jinaai-reader
uv venv

这将创建一个与我们选择的 Python 版本相对应的虚拟环境。

创建环境后,它将提供有关如何在会话中激活它的说明。

source .venv/bin/activate

添加一个 src 目录并安装我们需要的一个依赖项。

在项目根目录创建一个 .env 文件,并将你的 JINAAI_API_KEY 添加到该文件中。通常,服务器运行所需的任何 API 密钥或其他环境变量都将放在此文件中。

JINAAI_API_KEY=jina_************

src 目录中,创建一个 server.py 文件……你应该准备好编码了。

服务器代码

from mcp.server.fastmcp import FastMCP
import httpx
from urllib.parse import urlparse
import os

从导入开始:httpx 将是我们在这里用来发起 HTTP 请求的库。urlparse 方法帮助我们判断一个字符串是否可能是有效的 URL。

mcp = FastMCP("search", dependencies=["mcp[cli]"])

这初始化了服务器;第一个参数是工具的名称。当前一个 bug 需要将 mcp[cli] 添加为依赖项,这在理想情况下是不必要的,但可能很快会被修复。

如果您有其他依赖项,您必须在这里添加它们,以便客户端知道您需要在运行客户端之前安装它们;我们稍后会看到这如何运作。

JINAAI_SEARCH_URL = "https://s.jina.ai/"
JINAAI_READER_URL = "https://r.jina.ai/"
JINAAI_GROUNDING_URL = "https://g.jina.ai/"
JINAAI_API_KEY = os.getenv("JINAAI_API_KEY")

您可能能推测出这里的模式,但 Jina 使用不同的子域来路由特定的请求。搜索端点期望一个查询,读取端点期望一个 URL,而基础端点可以为大型语言模型提供特定的响应或答案。

基础是一个更大的主题,并与其他技术结合使用,例如 RAG 和微调,以帮助大型语言模型减少幻觉并改善决策。

我们的第一个工具

@mcp.tool()
async def read(query_or_url: str) -> str:
  """
  从 URL 读取内容或执行搜索查询。
  """
  try:
    if not JINAAI_API_KEY:
       return "JINAAI_API_KEY 环境变量未设置"
    headers = { 
      "Authorization": f"Bearer {JINAAI_API_KEY}",
      "X-Retain-Images": "none",
      "X-Timeout": "20",
      "X-Locale": "en-US",
    }
    async with httpx.AsyncClient() as client:
      if is_valid_url(query_or_url):
        headers["X-With-Links-Summary"] = "true"
        url = f"{JINAAI_READER_URL}{query_or_url}"
      else:
        url = f"{JINAAI_SEARCH_URL}{query_or_url}"
      response = await client.get(url, headers=headers)
      return response.text
  except Exception as e:
    return str(e)

注解 @mcp.tool 执行了大量的工作。库中还存在用于资源和提示的类似注解。该注解提取函数签名和返回类型的详细信息,以创建输入和输出模式,以便大型语言模型调用该工具。它配置工具,使客户端理解服务器的能力。它还将函数调用注册为配置工具的处理程序。

接下来,您会注意到该函数是 async 的。无需运行时配置,也不需要 asyncio.run 的内容。如果您出于某种原因需要将服务器作为独立服务运行,您确实需要自己处理其中的一些内容。FastMCP 仓库中有一个示例说明如何做到这一点。

函数主体相对简单;它验证是否接收到一个 URL,设置适当的头部,调用 Jina 端点,并返回文本。

def is_valid_url(url: str) -> bool:
 """
 验证给定字符串是否是一个有效的 URL。
 """
 try: 
   result = urlparse(url)
   return all([result.scheme in ("http", "https"), result.netloc])
 except:
   return False

这是一个相当简单的函数,用于确定可能的 URL 字符串的有效性。

第二个工具

@mcp.tool()
async def fact_check(query: str) -> str:
    """
    Perform a fact-checking query.
    """
    try:
        if not JINAAI_API_KEY:
            return "JINAAI_API_KEY environment variable is not set"

        headers = { 
            "Authorization": f"Bearer {JINAAI_API_KEY}",
            "Accept": "application/json",
        }

        async with httpx.AsyncClient() as client:
            url = f"{JINAAI_GROUNDING_URL}{query}"
            response = await client.get(url, headers=headers)
            res = response.json()
            if res["code"] != 200:
                return "Failed to fetch fact-check result"

        return res["data"]["reason"]
    except Exception as e:
        return str(e)

测试和调试

mcp dev src/server.py with-editable .

运行上述命令将启动 mcp 检查器。这是 sdk 提供的一个工具,用于测试和调试服务器响应。— with-editable 标志允许您在不重新启动检查器的情况下更改服务器(强烈推荐)。

您应该看到:

🔍 MCP 检查器正在 http://localhost:5173 上运行 🚀

默认情况下,检查器在 5173 端口运行,而服务器(您刚刚编写的代码)将在 3000 端口运行;您可以通过在调用之前设置 SERVER_PORTCLIENT_PORT 来更改此设置。

SERVER_PORT=3000 mcp dev src/server.py

检查器

Image 3

如果一切顺利,你应该会看到类似于上面的内容,在左侧你可以添加所需的环境变量,这里 JINAAI_API_KEY 是唯一的一个。

如果你点击顶部菜单栏中的 Tools,然后选择 List Tools,你应该会看到我们创建的工具,请注意文档字符串作为工具的描述。

点击特定工具将弹出文本框,供你输入调用该工具所需的参数。

安装服务器

在您确认一切正常后,您现在可以在 Claude Desktop App 客户端上安装服务器。

mcp install src/server.py -f .env

我相信未来会支持其他客户端,但目前您只需执行此操作。-f .env 将环境变量传递给应用客户端。

其背后的原理是更新 claude_desktop_config.json 并提供运行服务器所需的命令和参数。默认情况下,它使用 uv,该工具必须在您的 PATH 中可用。

如果您现在打开 Claude Desktop App,进入菜单栏并点击 Claude > 设置,然后点击 开发者,您应该会看到在初始化服务器时设置的工具名称。

Image 4

点击它应该会弹出其配置。您不仅会知道它是如何执行的,而且在 高级选项 中,您还会看到已设置的环境变量 😬。

您也可以直接编辑此配置,但我并不一定推荐这样做。

利润

如果一切顺利,当你进入桌面应用程序时,你应该不会看到任何错误(如果有错误,进入 设置 应该会给你一个按钮来查看日志并从那里进行调查)。

此外,你应该看到一个锤子符号,显示你可以使用的工具数量(注意:除非你安装了其他 MCP 服务器,否则你的数量应该是 2)。

你不需要直接调用工具,而是像往常一样与应用程序聊天,当它遇到认为工具有帮助的情况时,它会询问你是否想使用它。这里不需要额外的代码或配置。

我认为它依赖于工具名称和描述来决定是否合适,因此值得精心编写一个清晰简单的工具描述。

你会收到如下提示:

你可以直接与它“聊天”,诚然,写得不够好的工具有时会遇到问题。偶尔它会决定无法访问互联网,有时它无法检索结果,但有时你会得到这个:

这个过程有一种相对自然的流畅感,它读取页面,提供摘要,然后你要求它去特定文章并阅读。

最终备注

希望这能让你对 MCP 服务器有一些了解。还有很多内容可以阅读和观看,但我再推荐一个网站:glama.ai。他们维护了一份相当全面的可下载和试用的 MCP 服务器列表,包括其他比我们的玩具示例更可靠的网络搜索工具。感谢你的关注。

Related Posts

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

AI 研究报告和论文写作 合并两个系统指令以获得两个模型的最佳效果 Perplexity AI 的 Deep Research 工具提供专家级的研究报告,而 OpenAI 的 ChatGPT-o3-mini-high 擅长推理。我发现你可以将它们结合起来生成令人难以置信的论文,这些论文比任何一个模型单独撰写的都要好。你只需要将这个一次性提示复制到 **

阅读更多
让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

Non members click here作为一名软件开发人员,多年来的一个发现总是让我感到惊讶,那就是人们还在 Excel

阅读更多
使用 ChatGPT 搜索网络功能的 10 种创意方法

使用 ChatGPT 搜索网络功能的 10 种创意方法

例如,提示和输出 你知道可以使用 ChatGPT 的“搜索网络”功能来完成许多任务,而不仅仅是基本的网络搜索吗? 对于那些不知道的人,ChatGPT 新的“搜索网络”功能提供实时信息。 截至撰写此帖时,该功能仅对使用 ChatGPT 4o 和 4o-mini 的付费会员开放。 ![](https://images.weserv.nl/?url=https://cdn-im

阅读更多
掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

10 个常见问题解答 本文是我推出的一个名为“10 个常见问题解答”的新系列的一部分。在本系列中,我旨在通过回答关于该主题的十个最常见问题来分解复杂的概念。我的目标是使用简单的语言和相关的类比,使这些想法易于理解。 图片来自 [Solen Feyissa](https://unsplash.com/@solenfeyissa?utm_source=medium&utm_medi

阅读更多
在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和科技这样一个动态的行业中,保持领先意味着不断提升你的技能。无论你是希望深入了解人工智能模型性能、掌握数据分析,还是希望通过人工智能转变传统领域如法律,这些课程都是你成功的捷径。以下是一个精心策划的高价值课程列表,可以助力你的职业发展,并让你始终处于创新的前沿。 1. 生成性人工智能简介课程: [生成性人工智能简介](https://genai.works

阅读更多
揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

在AI军备竞赛中分辨事实与虚构 DeepSeek AI真的是它所宣传的游戏规则改变者,还是仅仅聪明的营销和战略炒作?👀 虽然一些人将其视为AI效率的革命性飞跃,但另一些人则认为它的成功建立在借用(甚至窃取的)创新和可疑的做法之上。传言称,DeepSeek的首席执行官在疫情期间像囤积卫生纸一样囤积Nvidia芯片——这只是冰山一角。 从其声称的550万美元培训预算到使用Open

阅读更多
Type something to search...