手把手学习写一个MCP服务,获取热榜文章

142 阅读3分钟

写在前面

【前情回顾】最近都在传的大模型MCP到底是个啥

之前的文章讲了MCP是什么,以及怎么用。光会用不行,还得研究研究怎么去开发MCP服务。

开发准备

关于MCP Server的开发,这里找到了官方文档:modelcontextprotocol.io/introductio…

其架构如上图所示,比较直观,不再赘述。

我们这次写的是MCP服务,客户端就用之前文章中的Cherry Studio代替,就不单独开发客户端了。

从官方文档中我们可以看到,MCP是支持多个语言的

这里我选择python

UV工具

按照文档中的提示,需要安装uv命令,这是用于启动MCP服务的发动机

windows

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

linux

curl -LsSf https://astral.sh/uv/install.sh | sh

我这里是用的windows,然后将该路径配置到环境变量中

重启终端,就可以使用uv命令了,实际上如果我们已经通过Cherry Studio上安装uv之后,并且是通过Cherry Studio进行MCP调用的话,这一步不需要也行。

MCP Server

我大概看了一下文档中给的示例代码,是获取美国天气的,大概看了一下架构,总结出3个要点

  • 需要通过mcp库进行服务创建和启动
pip install mcp
  • MCP 全程需要通过 asyncio 进行异步调用
  • 尽可能的声明参数类型,返回类型,以及加上方法的注释,来让大模型明白怎么使用

一个MCP服务的代码架构基本如下

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("server name")

# 工具声明 需用异步
@mcp.tool()
async def tool_name(param: int) -> []:
    """
    注释描述
    参数描述
    返回描述
    """
    data = []
    return data


# 运行服务
if __name__ == "__main__":
    mcp.run()

示例开发

这里我不用官方给的示例,我写了一个用来获取掘金热榜文章的MCP服务,直接贴上代码,大家可以参考学习,写的比较简单

import httpx
from mcp.server.fastmcp import FastMCP


mcp = FastMCP("hot articles")

JUEJIN_BASE_URL = "https://api.juejin.cn/content_api/v1/content/article_rank?category_id=1&type=hot"
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36"

ARTICLE_BASE_URL = "https://juejin.cn/post/"



async def get_juejin_articles_rank():
    headers = {
        "User-Agent": USER_AGENT,
    }
    async with httpx.AsyncClient() as client:
        try:
            response = await client.get(JUEJIN_BASE_URL, headers=headers)
            response.raise_for_status()

            return response.json()["data"]
        except Exception as e:
            return None

def data_format(data):
    article_list = []
    for content in data:
        article = {
            "title": content["content"]["title"],
            "url": ARTICLE_BASE_URL + content["content"]["content_id"],
            "author": content["author"]["name"]
        }
        article_list.append(article)
    return article_list


@mcp.tool()
async def mcp_tool_get_juejin_articles_rank(count: int):
    """
    获取掘金文章
    :param count: 控制获取的文章数量
    :return: 文章列表
    """
    data = await get_juejin_articles_rank()
    if not data:
       return []
    data = data_format(data)
    if count > len(data):
        count = len(data)
    return data[:count]


if __name__ == "__main__":
    mcp.run()

可以看到,基本符合我上面所提到的MCP Server代码模板

MCP使用

接下来,我们继续再Cherry Studio中使用

先在MCP服务器里配置,因为这次是咱们自己本地开发的,所以通过绝对路径的方式进行服务执行就行,让Cherry Studio帮我们执行服务

uv run 绝对路径Path\mcp_server.py

然后我们回到对话框中

选择启动该MCP服务

然后进行对话

可以看到成功执行!