从0-1使用Fastmcp开发一个MCP服务,并部署到阿里云百炼【1.环境准备】

发布于:2025-08-20 ⋅ 阅读:(21) ⋅ 点赞:(0)

目的:
在本地使用fastmcp开发一个mcp,然后注册到阿里云的百炼里面。实现在百炼里面创建智能体的时候直接引用自己开发的MCP

时间 章节 内容
2025-08-18 第一章,第二章 本地环境安装与验证
2025-08-19 第三章,第四章,第五章 了解阿里云百炼部署自定义MCP步骤;了解如何使用Fastmcp开发;前置准备
待完成 - 1.根据需求实现一个MCP中可以调用某应用的多个API即 @mcp.tool()、@mcp.prompt()、接入大模型实现根据问题自动选择合适的tool
待完成 - 2.将MCP使用UVX部署到阿里云函数计算中,并在百炼中注册MCP。
待完成 - 3.创建百炼Agent,调用MCP,验证结果
文章太长了,后续的开发再写一遍单独写

一、环境准备

1.安装 Node.js 和 UV

打开cmd,并输入下面代码安装node.js:
选择

winget install OpenJS.NodeJS

在这里插入图片描述
验证:node --version
在这里插入图片描述

管理员身份运行 PowerShell 执行以下命令安装 uv:

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

如果一直卡在这个界面可能是因为没有安装python环境,要先安装python环境。因为uv 的核心功能是管理 Python 环境、依赖包和执行 Python 代码,其本身并不包含 Python 解释器,必须依赖已安装的 Python 来运行。
在这里插入图片描述

安装python解释器和开发软件pycharm
1.下载python解释器,因为阿里云的函数计算最高支持3.12的,所以这里我们也下载3.12版本。官网地址:https://www.python.org/getit/
在这里插入图片描述
选择3.12.10,64位下载,或者直接访问这个链接https://www.python.org/ftp/python/3.12.10/python-3.12.10-amd64.exe
在这里插入图片描述在这里插入图片描述
验证安装结果,cmd输入python
在这里插入图片描述

2.安装pycharm
访问这个链接,直接下载:https://www.jetbrains.com/pycharm/download
在这里插入图片描述
安装完成之后,再次运行PowerShell 命令
在这里插入图片描述
关闭窗口后重新打开验证:uv --version
在这里插入图片描述

2.安装fastmcp

fastmcp官网地址:https://gofastmcp.com/getting-started/welcome
在本地先创建一个文件夹用来做项目管理,这里我新建一个D:\art\fastmcp
1.然后在这个目录下进入cmd,执行以下命令新建一个项目:

uv init 01_env_test

2.进入项目目录:

cd 01_env_test

3.使用 Python 内置模块创建虚拟环境

python -m venv .venv

4.激活虚拟环境

.\.venv\Scripts\activate

初始化之后就可以在目录下看到以下文件:
在这里插入图片描述
5.在这个目录下打开cmd,执行命令安装fastmcp

uv add fastmcp

查看安装结果:
在这里插入图片描述

二、运行Demo

1.打开项目,验证环境是否正常

打开Pycharm,选择打开项目,然后选择D:\art\fastmcp\01_env_test 这个目录
在这里插入图片描述
找到main函数,运行下,看下环境是否正常
在这里插入图片描述
导入from fastmcp import FastMCP,检查导入是否正常
把原来的代码注释掉,粘贴下面这段代码

from fastmcp import FastMCP

mcp = FastMCP("Demo 🚀")

@mcp.tool
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b

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

在这里插入图片描述
点击左下角打开命令行也可以查看版本信息

fastmcp version

在这里插入图片描述

2.创建一个服务端和客户端的Demo

新建一个服务端的文件:my_server.py
在这里插入图片描述
写一个函数,并使用 @mcp.tool 装饰器将其注册到服务器中
这里demo写的是输入一个string的名字,返回一个Hello +输入的名字

from fastmcp import FastMCP

mcp = FastMCP("My MCP Server")

@mcp.tool
def greet(name: str) -> str:
    return f"Hello, {name}!"

官方也写了一个在本文件中测试的代码。完整代码如下,调用链路就是运行后先运行call_tool方法,然后带着参数调用了greet方法,最后返回了一个字符串拼接。

import asyncio
from fastmcp import FastMCP, Client

mcp = FastMCP("My MCP Server")

@mcp.tool()
def greet(name: str) -> str:
    return f"Hello, {name}!"

client = Client(mcp)

async def call_tool(name: str):
    async with client:
        result = await client.call_tool("greet", {"name": name})
        print(result)

asyncio.run(call_tool("666"))

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

在这里插入图片描述
测试完之后显示正常输出,然后就把创建客户端这个删掉,还是保留最开始的代码,不过下面新增一个main,让他可以运行就行,等下用命令行的方式让他运行起来,然后单独在写一个客户端来调用这个服务端,修改后的代码是:
在这里插入图片描述
新建一个客户端:my_client.py

import asyncio
from fastmcp import Client

client = Client("my_server.py")

async def call_tool(name: str):
    async with client:
        result = await client.call_tool("greet", {"name": name})
        print(result)

asyncio.run(call_tool("666")) 

调用测试,回到下面命令行这里,点击加号新增一个窗口,等下一个运行服务端,一个运行客户端来调用。
在这里插入图片描述
在第一个窗口运行以下代码启动服务端:

uv run my_server.py

在这里插入图片描述

在第二个窗口运行以下代码启动客户端调用:

  uv run my_client.py

在这里插入图片描述
这里可以按照预期显示正确的结果。

三、了解阿里云怎么部署自定义的MCP

官网地址:https://bailian.console.aliyun.com/?spm=5176.6660585.sfm_platform_public_cn-top.i1.581a7992l8NxMs&tab=doc#/doc/?type=app&url=2879604

在阿里云百炼平台除了开通阿里云百炼上面官方提供的的云部署 MCP 服务,也可以部署来自开源社区或其他来源的自定义 MCP 服务,并在智能体和工作流应用中使用这些 MCP 服务,或者导入在云原生 API 网关和阿里云 OpenAPI 创建的 MCP 服务。

我们的目的是部署自行开发的 MCP 服务,并使用函数计算 FC帮您托管它们。

部署步骤;
1.进入阿里云百炼MCP管理界面点击新建MCP服务。
在这里插入图片描述
2.选择使用脚本模式部署
在这里插入图片描述
3.配置MCP的基础信息,名字,描述,这里我们选UVX,地域,配置一下MCP服务,注意这里的MCP服务要求格式必须是下面这种格式。
在这里插入图片描述

{
  "mcpServers": {
    "memory": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-memory"]
    },
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/path/to/allowed/files"
      ]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>"
      }
    }
  }
}

4.提交之后他就会自动在函数计算中添加一个函数,在管理界面可以直接跳转过去,我们自定义开发的那个MCP,后续应该也是登录到函数计算,然后把代码上传到函数计算中就可以了。
在这里插入图片描述
在这里插入图片描述

在这一章主要要注意的是那个MCP服务器连接配置。
他是用于定义客户端需要对接的「本地 MCP 服务」的连接方式与参数,让客户端能找到并调用这些服务提供的工具 / 资源。
顶层字段:mcpServers
是整个配置的根节点,用于聚合所有需要对接的 MCP 服务器。每个子节点(如 “本地 MCP 服务”“远程 MCP 服务”)是一个独立的 MCP 服务器配置项,键名(如 “本地 MCP 服务”)是自定义的服务器名称(仅用于客户端内区分,无功能影响)。
子配置 1:“本地 MCP 服务”(本地运行的 MCP 服务器)
用于配置在客户端本地设备上启动并运行的 MCP 服务器

字段 类型 含义与作用
type 字符串 通信传输类型,stdio 表示 “通过标准输入输出流(stdin/stdout)” 与本地服务器通信(本地服务的常用类型)。
command 字符串 启动本地 MCP 服务器的核心命令,此处 npx 是 Node.js 的包执行工具,用于临时安装并运行指定的 npm 包,我们到时候会使用UVX
args 数组 传递给 command(即 npx)的参数,用于细化启动逻辑:- -y:npx 的参数,强制 “自动确认”(避免安装包时弹出交互确认提示);- @your_acc_name/your_pkg_name:要通过 npx 执行的 npm 包名(即你的本地 MCP 服务代码所在的包,执行后会启动该包内置的 MCP 服务器)。
env 对象 启动本地服务器时需要注入的环境变量,键为环境变量名(如 YOUR_ENV_KEY),值为对应的变量值(如 YOUR_ENV_VALUE),用于给服务器传递敏感信息(如 API 密钥)或配置参数(服务器代码可读取这些变量)。

子配置 2:“远程 MCP 服务”(远程部署的 MCP 服务器)
用于配置部署在远程服务器上的 MCP 服务,通过 “SSE(Server-Sent Events,服务器发送事件)” 与客户端通信,字段含义如下:

字段 类型 含义与作用
type 字符串 通信传输类型,sse 表示 “通过服务器发送事件(SSE)” 与远程服务器通信(远程服务的常用类型,支持服务器主动向客户端推送数据)。
url 字符串 远程 MCP 服务的 SSE 通信地址(客户端通过该 URL 建立与远程服务的连接,进而调用其工具 / 资源),格式需符合远程服务的部署路径(如 https://your-mcp-server/sse)
  • 「本地 MCP 服务」:客户端会通过 npx 命令在本地启动指定的 npm 包(你的 MCP 服务代码),并通过标准输入输出与其通信,适合开发调试或本地专属服务。
  • 「远程 MCP 服务」:客户端直接通过 SSE 协议连接远程服务器的指定 URL,无需本地启动服务,适合团队共享或线上部署的 MCP 服务。其中Type的枚举值除了这两个还有websocket(双向实时通信)和http(基础远程通信)后续可以考虑使用这两种方式
{
  "mcpServers": {
    "本地 MCP 服务": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@your_acc_name/your_pkg_name"
      ],
      "env": {
        "YOUR_ENV_KEY": "YOUR_ENV_VALUE"
      }
    },
    "远程 MCP 服务": {
      "type": "sse",
      "url": "https://your-mcp-server/sse",
    }
  }
}

四、了解如何使用Fastmcp开发

1. FastMCP 与 MCP 的关系

MCP(Model Context Protocol,模型上下文协议)是一套定义客户端(如 Claude 桌面版)与服务器之间交互规范的协议,包含通信格式、核心功能模块、数据交换规则等,是整个交互体系的 “标准”。

FastMCP 则是 MCP 协议在特定编程语言(如 Python)中的 “便捷实现工具”,是 MCP SDK 的一部分。它封装了 MCP 协议的底层细节(如通信处理、功能注册逻辑等),通过简洁的 API(如装饰器 @mcp.tool())帮助开发者快速构建符合 MCP 规范的服务器,无需手动处理协议的复杂细节。

简单来说:MCP 是 “协议标准”,FastMCP 是 “实现该标准的便捷工具”,前者定义 “要做什么”,后者解决 “如何简单地做到”。

2.MCP 核心功能的具体含义

MCP 协议通过以下核心功能模块,实现客户端与服务器的协同工作,扩展大语言模型的能力:
1. Resources(资源)
定义:服务器提供的、客户端可读取的 “类文件数据”,是模型可访问的外部信息源。
具体形式:包括但不限于 API 响应结果(如天气数据)、本地文件内容(如文档、表格)、数据库查询结果、网页抓取内容等。
作用:为模型提供超出其训练数据范围的实时 / 私有信息,例如让模型通过访问服务器的 “新闻资源” 获取最新资讯,或通过 “企业文档资源” 回答内部问题。
2. Prompts(提示词)
定义:服务器预定义的 “提示模板” 或 “指令片段”,用于辅助用户快速完成特定任务。
具体形式:如邮件模板(“请以‘尊敬的客户,您好:’开头,说明订单延迟原因”)、代码生成模板(“用 Python 实现一个冒泡排序,包含注释”)、问答框架(“针对问题 {q},按‘原因 - 解决方案 - 注意事项’结构回答”)等。
作用:标准化模型输出格式,减少用户手动编写提示词的成本,提高交互效率。客户端可调用服务器的提示词模板,引导模型生成更符合需求的内容。
3. Tools(工具)
定义:服务器提供的、模型可调用的 “函数或服务”(需用户许可),是模型与外部系统交互的 “接口”。
具体形式:如天气查询工具(get_forecast(lat, lon))、数据计算工具(calculate_tax(income))、API 调用工具(send_email(to, content))等,通常包含输入参数、输出格式和功能描述。
作用:扩展模型的 “行动力”,让模型从 “只能生成文本” 升级为 “能执行操作”,例如调用工具查询实时天气、控制智能家居、生成图表等。
4. Sampling(采样)
定义:服务器提供的、用于控制模型生成内容的 “采样策略配置”,影响模型输出的风格和特性。
具体形式:包括采样参数(如温度 temperature 控制随机性,top_p 控制候选词范围)、输出长度限制(max_tokens)、格式约束(如强制 JSON 输出)等。
作用:让服务器可以根据场景需求 “定制” 模型的生成行为,例如在需要精确结果的场景(如代码生成)设置低温度(temperature=0.1),在需要创意的场景(如故事生成)设置高温度(temperature=0.8)。
5. Roots(根目录)
定义:服务器指定的 “资源访问根路径”,用于规范客户端对资源的访问范围。
具体形式:可以是文件系统的根目录(如 /data/resources)、数据库的特定表前缀(如 user_)、API 路径的基础前缀(如 /v1/internal/)等。
作用:限制客户端的访问边界,确保安全性(避免越权访问敏感资源),同时简化资源的组织和管理(客户端只需基于根目录路径访问子资源)。
6. Transports(传输层)
定义:客户端与服务器之间的 “通信方式与协议”,负责数据的编码、传输和解析。
具体形式:如 stdio(通过标准输入输出流通信,适用于本地服务)、sse(服务器发送事件,适用于远程服务单向推送)、websocket(双向实时通信,适用于高频交互)、http(基于 HTTP 协议的请求 - 响应,适用于简单调用)等。
作用:是 MCP 协议的 “物理基础”,确保客户端和服务器能跨环境(本地 / 远程)、跨设备稳定交换数据(如工具调用请求、资源查询结果等)。

这些核心功能共同构成了 MCP 协议的生态:服务器通过提供 Resources、Tools、Prompts 等能力,客户端(结合模型)通过 Transports 调用这些能力,并通过 Sampling 和 Roots 控制交互细节,最终实现模型能力的扩展。

3. FastMCP的传输协议

FastMCP框架支持三种传输协议:STDIO、Streamable HTTP、SSE

STDIO: 传输是本地 MCP 服务器执行的默认且兼容性最广的选项。它非常适合本地工具、命令行集成和 Claude Desktop 等客户端。但是,它的缺点是必须在本地运行 MCP 代码,这可能会给第三方服务器带来安全问题。

Streamable HTTP: 是一种现代、高效的传输方式,用于通过 HTTP 公开您的 MCP 服务器。它是基于 Web 的部署的推荐传输方式。

SSE: 是一种基于 HTTP 的协议,用于服务器到客户端流式处理。虽然 FastMCP 仍然支持 SSE,但它已被弃用,Streamable HTTP 是新项目的首选。

不同协议的服务端和客户端调用时的区别-具体实现后续补充

4.Fastmcp常用的三个装饰器

  • @mcp.tool()
  • @mcp.resource()
  • @mcp.prompt()
工具 - Tool

在 MCP Server 开发中,工具是将函数暴露给 MCP 客户端,使其成为可执行功能的关键组件。工具作为核心构建块,赋予了 LLM 与外部系统交互、执行代码以及访问训练数据之外信息的能力。在 FastMCP 中,工具本质上是通过 MCP 协议暴露给 LLM 的 Python 函数。
实现原理
基于@mcp.tool()装饰器,在函数定义时自动提取函数签名(参数类型、数量)、描述等元信息,注册到 FastMCP 服务实例的工具管理列表;同时生成参数校验逻辑和 MCP 协议格式的调用接口,使 LLM 可按协议规范发起请求并触发函数执行。
执行流程
LLM 根据工具定义的模式,向服务器发送包含参数的请求。
FastMCP 依据函数签名对传入的参数进行严格验证,确保参数的正确性和完整性。
经过验证的参数将作为输入,执行对应的 Python 函数。
函数执行结果返回给 LLM,LLM 可以在后续的响应中使用该结果。

通过这种机制,LLM 能够执行诸如查询数据库、调用 API、进行复杂计算或访问文件等多样化任务,从而突破训练数据的限制,极大地扩展了自身功能。

资源和模板 - Resources

资源和模板用于向 MCP 客户端公开数据源和动态内容生成器。资源代表了 MCP 客户端可以读取的数据或文件,而资源模板进一步扩展了这一概念,它允许客户端根据 URI 中传递的参数请求动态生成的资源。
实现原理
通过@mcp.resource装饰器,将数据返回函数或静态数据地址注册到服务实例的资源管理字典,同时绑定对应的访问 URI;客户端请求时,FastMCP 匹配 URI 对应的资源逻辑,静态资源直接返回数据,动态资源执行函数生成内容后按 MCP 协议格式返回。
处理流程
FastMCP 查找与请求 URI 对应的资源定义。
如果是动态资源(由函数定义),则执行该函数生成相应内容。
将生成的内容(可以是文本、JSON 格式数据或二进制数据)返回给客户端。

借助资源和模板,LLM 可以访问与对话相关的文件、数据库内容、配置信息或动态生成的各类数据,满足不同场景下的需求。

提示 - Prompt

提示是为 MCP 客户端创建的可重复使用的参数化提示模板。它本质上是一种消息模板,能够帮助 LLM 生成结构化、具有明确目的性的响应。在 FastMCP 中,主要通过@mcp.prompt装饰器来简化提示模板的定义。
实现原理
利用@mcp.prompt装饰器,提取提示模板中的参数占位符(如{user_name})和模板内容,注册到服务实例的提示管理列表;客户端请求时,先校验传入的参数是否匹配占位符需求,再填充参数生成完整提示消息,按协议返回给 LLM。
处理流程
FastMCP 找到与请求对应的提示定义。
如果提示包含参数,会根据函数签名对参数进行验证,确保参数符合模板要求。
使用经过验证的输入执行相关函数,生成提示消息。
将生成的消息返回给 LLM,用于指导其生成响应。

通过提示模板,开发者可以定义统一、可复用的消息模板,使 LLM 在不同客户端和环境中都能生成风格一致、符合预期的响应。

五、开发前梳理接下来要做的事

1.开发流程

1.明确开发目标与功能范围
确定 MCP 服务需提供的核心能力,如工具(Tools)、资源(Resources)类型(例:数据查询工具、本地文档资源等)。
确认服务对接阿里云百炼的交互场景,明确工具 / 资源的调用逻辑(如是否需要用户授权、参数格式要求)。

2.环境与依赖准备
参考第一章

3.MCP 服务核心开发阶段

  • 初始化 FastMCP 服务实例
  • 确定服务名称(需与后续百炼注册的服务名一致),通过 FastMCP 类初始化实例,绑定服务标识。
  • 配置服务基础参数,如默认传输协议(暂选本地调试用的 stdio,后续部署到百炼时切换为 HTTP)、日志级别。
  • 定义工具(Tools)与资源(Resources)
  • 梳理工具的功能逻辑、输入参数(需明确参数类型、必填项)与输出格式,确保符合百炼智能体的调用预期。
  • 规划资源的内容结构(如静态文档、API 响应数据),确定资源的访问方式(如通过资源名称调用)。
  • 注册工具与资源到 FastMCP 使用 FastMCP提供的装饰器(如@mcp.tool()、@mcp.resource()),将工具函数、资源函数注册到服务实例。
  • 为工具添加描述信息(用于百炼控制台展示)、参数校验规则(如必填项检查、格式校验),为资源设置访问权限(如是否允许所有智能体访问)。
  • 编写辅助逻辑 实现参数预处理逻辑(如参数格式转换、默认值填充),确保工具接收的参数符合业务要求。
  • 添加错误处理逻辑(如异常捕获、错误信息标准化),避免服务因异常崩溃,同时便于百炼端排查问题。
  • 集成日志记录功能,记录工具 / 资源的调用日志(如请求参数、响应结果、耗时),用于后续调试与监控。 配置环境变量 梳理服务依赖的敏感信息(如 API 密钥、第三方服务地址)、配置参数(如超时时间),通过环境变量管理(避免硬编码)。
  • 定义环境变量的键名与取值规则,确保后续部署到百炼时可通过env字段注入。

4.本地测试与优化

  • 启动本地 MCP 服务 配置服务启动参数(如绑定本地 IP、端口),通过 FastMCP 的run()方法启动服务,选择 stdio
  • 传输协议进行本地调试。 验证服务启动状态,确认无初始化报错,工具 / 资源注册成功(可通过访问本地接口或日志查看注册列表)。
  • 测试工具与资源的可用性 使用接口测试工具(如 curl、Postman),模拟百炼智能体的调用逻辑,发送工具调用请求、资源访问请求。
  • 检查响应结果:是否符合预期格式、错误场景(如参数缺失、业务异常)是否返回正确提示,日志是否完整记录关键信息。 优化服务稳定性与兼容性针对测试中发现的问题(如参数校验不严格、响应延迟),优化工具 / 资源的代码逻辑。
  • 调整服务配置,如增加超时重试机制、限制单工具的调用频率,确保服务在高并发场景下稳定运行。 验证服务与百炼传输协议的兼容性(如切换为HTTP 协议后,测试远程调用是否正常)。

5.部署

  • 调整服务配置适配百炼 修改 FastMCP 的传输协议为百炼支持的类型(如 HTTP),配置服务的公网访问地址。按照百炼mcpServers配置格式,编写服务的连接配置(如command设为UVX,args指定服务启动入口,env注入环境变量)。 准备部署依赖与代码包
  • 整理服务的依赖清单(如生成requirements.txt),确保所有依赖在百炼函数计算环境中可安装。
  • 打包服务代码(含主程序文件、依赖配置文件、环境变量模板),确认代码结构符合百炼函数计算的部署要求(如入口文件位置)。
  • 验证服务可访问性若使用本地设备开发,通过内网穿透工具将本地服务端口映射到公网,获取公网访问地址(用于后续百炼测试)。
  • 测试公网地址的可用性(如通过外部设备调用工具 / 资源),确认网络通畅,无防火墙、端口限制问题。

2.开发demo

1.创建项目与安装依赖

# 1. 创建项目目录
uv init aliyun_bailian_mcp
cd aliyun_bailian_mcp

# 2. 激活虚拟环境
uv venv
source .venv/bin/activate  # macOS/Linux
# .venv\Scripts\activate  # Windows

# 3. 安装依赖
uv add "mcp[cli]"  # FastMCP核心库
uv add pydantic    # 参数校验
uv add python-dotenv  # 环境变量管理
uv add logging  # 日志(Python内置,无需额外安装)

2.创建环境变量文件(.env)

# .env - 敏感信息与配置参数
BAILIAN_API_KEY=your_aliyun_bailian_api_key  # 百炼API密钥
MCP_SERVICE_PORT=8000  # 服务端口(与百炼配置一致)
MCP_SERVICE_NAME=my_bailian_mcp  # 服务名(需与百炼注册名一致)
TIMEOUT=30  # 工具调用超时时间(秒)

3.开发MCP 服务核心代码(main.py)

from typing import Dict, Optional
from dotenv import load_dotenv
import os
import logging
from pydantic import BaseModel, Field
from mcp.server.fastmcp import FastMCP

# 1. 初始化环境与日志
load_dotenv()  # 加载.env文件
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    handlers=[logging.StreamHandler()]
)
logger = logging.getLogger(os.getenv("MCP_SERVICE_NAME", "default_mcp"))

# 2. 初始化FastMCP服务实例
mcp = FastMCP(
    service_name=os.getenv("MCP_SERVICE_NAME"),  # 服务名与百炼注册一致
    log_level=logging.INFO
)

# 3. 定义工具参数模型(参数校验)
class DataQueryParams(BaseModel):
    """数据查询工具的输入参数模型"""
    query_key: str = Field(..., description="查询关键词(如城市名、产品ID),必填")
    query_type: str = Field(default="basic", description="查询类型:basic(基础数据)、detail(详细数据)")

# 4. 定义工具函数并注册
@mcp.tool(
    description="数据查询工具:根据关键词查询基础/详细数据(如天气、产品信息)",
    parameters=DataQueryParams  # 绑定参数校验模型
)
async def query_data(params: DataQueryParams) -> str:
    """
    工具核心逻辑:模拟根据关键词查询数据
    :param params: 输入参数(符合DataQueryParams规则)
    :return: 格式化的查询结果
    """
    try:
        logger.info(f"收到数据查询请求:query_key={params.query_key}, query_type={params.query_type}")
        
        # 模拟参数预处理
        query_key = params.query_key.strip()
        if not query_key:
            return "错误:查询关键词不能为空"
        
        # 模拟业务逻辑(实际场景可替换为API调用、数据库查询)
        mock_data = {
            "basic": f"【基础数据】关键词:{query_key},状态:正常",
            "detail": f"【详细数据】关键词:{query_key},类型:{params.query_type},更新时间:2024-05-20,内容:测试数据"
        }
        result = mock_data.get(params.query_type, mock_data["basic"])
        
        logger.info(f"数据查询完成:result={result}")
        return result
    
    except Exception as e:
        error_msg = f"数据查询失败:{str(e)}"
        logger.error(error_msg)
        return error_msg

# 5. 定义资源函数并注册
@mcp.resource(name="service_info")
def get_service_info() -> Dict:
    """
    资源核心逻辑:返回MCP服务的基础信息(静态资源)
    :return: 服务信息字典
    """
    logger.info("获取服务信息资源请求")
    return {
        "service_name": os.getenv("MCP_SERVICE_NAME"),
        "version": "1.0.0",
        "support_tools": ["query_data"],
        "timeout": int(os.getenv("TIMEOUT", 30)),
        "provider": "Aliyun Bailian User"
    }

# 6. 服务启动入口
if __name__ == "__main__":
    # 配置启动参数(本地调试用HTTP协议,便于后续百炼对接)
    host = "0.0.0.0"  # 绑定所有网络接口,允许外部访问
    port = int(os.getenv("MCP_SERVICE_PORT", 8000))
    
    logger.info(f"启动MCP服务:{os.getenv('MCP_SERVICE_NAME')},地址:http://{host}:{port}")
    # 启动服务(传输协议设为HTTP,适配百炼部署)
    mcp.run(
        transport="http",
        host=host,
        port=port
    )

4.生成百炼 MCP 服务配置文件

{
  "mcpServers": {
    "my_bailian_mcp": {  // 服务名(与FastMCP初始化的service_name一致)
      "type": "http",  // 百炼支持的传输协议
      "command": "uvx",  // 百炼推荐的启动命令(替代npx)
      "args": [
        "main:mcp.run",  // 服务入口:main.py文件的mcp实例的run方法
        "--transport", "http",
        "--host", "0.0.0.0",
        "--port", "8000"
      ],
      "env": {
        "MCP_SERVICE_NAME": "my_bailian_mcp",
        "MCP_SERVICE_PORT": "8000",
        "TIMEOUT": "30",
        "BAILIAN_API_KEY": "your_actual_bailian_api_key"  // 百炼API密钥(部署时替换为真实值)
      }
    }
  }
}

5.部署后测试

curl http://localhost:8000/mcp/resource/service_info

网站公告

今日签到

点亮在社区的每一天
去签到