手把手搭建自定义 MCP 本地服务 stdio 和 sse 模式,实现 AI 工具个性化调用

手把手搭建自定义 MCP 本地服务 stdio 和 sse 模式,实现 AI 工具个性化调用

MCP(Model Context Protocol)作为 AI 与外部工具的通信协议,能让大模型精准调用自定义功能,摆脱官方工具的限制。本文将从环境搭建、项目初始化、代码开发到 Cherry Studio 联调,完整实现一个自定义 MCP 服务,最终让 AI 通过该服务完成「1+3=5」的个性化计算,全程步骤清晰、可直接复刻。

一、前置准备:安装 uv 包管理工具(核心环境)

uv 是新一代 Python 包管理工具,比 pip/conda 更快,且能统一管理 Python 版本和项目依赖,是搭建 MCP 服务的最佳选择,仅需一行命令完成安装。

安装命令(PowerShell 执行)

powershell -ExecutionPolicy Bypass -c "irm https://github.com/astral-sh/uv/releases/download/0.9.27/uv-installer.ps1 | iex"

安装完成后无需额外配置,自动添加系统环境变量
验证安装:在终端输入uv --version,输出版本号即表示安装成功

二、Python 版本管理:安装 3.13(MCP 推荐版本)

MCP 对 Python 3.13 兼容性更佳,通过 uv 可一键安装并管理该版本,无需担心多版本冲突。

1. 查看当前已安装 Python 版本

uv python list 

2. 安装python 3.13

uv python install3.13

三、项目初始化:创建 MCP 服务专属工程

  1. 创建项目文件夹并进入
    建议按「根目录 - 项目目录」的结构创建,方便后续管理,以 Windows 为例:
    创建一个mcp_server文件夹, 初始化python项目
D:\AiMcpProject>cd D:\AiMcpProject D:\AiMcpProject>cd mcp_server D:\AiMcpProject\mcp_server> uv init . -p 3.13 Initialized project `mcp-server` at `D:\AiMcpProject\mcp_server`

四、安装 MCP SDK:核心依赖包

MCP SDK 是开发自定义 MCP 服务的基础,提供了FastMCP核心类和各类装饰器,支持uv/pip 两种安装方式,优先推荐 uv(更快、无依赖冲突)。

方式 1:uv 安装(推荐,速度更快)

uv add"mcp[cli]"
在这里插入图片描述

方式 2:pip 安装(备用,兼容所有环境)

pip install"mcp[cli]"
在这里插入图片描述

五、核心开发:编写自定义 MCP 服务代码

项目初始化后,打开main.py(PyCharm/VS Code 均可),编写核心业务代码。本次实现3 个核心功能:个性化加法工具、动态问候资源、多风格问候提示词,且特意将加法结果「多加 1」,用于后续验证服务是否被成功调用。

main.py 内容

完整代码(可直接复制使用)

from mcp.server import FastMCP # 初始化MCP服务,命名为Demo(服务标识,可自定义) mcp = FastMCP("Demo")# 1. 自定义加法工具:核心测试功能(a+b后多加1,用于联调验证)@mcp.tool()# 装饰器标记为MCP工具,供AI调用defadd(a:int, b:int)->int:"""Add two numbers(函数描述,AI会识别该描述并调用)"""return a + b +1# 个性化逻辑:比正常加法多1,验证核心标识# 2. 动态问候资源:通过自定义协议返回个性化内容@mcp.resource("greeting://{name}")# 自定义资源协议,支持参数传参defget_greeting(name:str)->str:"""Get a personalized greeting(资源描述,说明功能用途)"""returnf"Hello, {name}!"# 3. 多风格问候提示词:为AI生成指定风格的问候语提供模板@mcp.prompt()# 装饰器标记为MCP提示词工具defgreet_user(name:str, style:str="friendly")->str:"""Generate a greeting prompt(生成不同风格的问候提示词)"""# 定义三种问候风格,默认友好风格 styles ={"friendly":"Please write a warm, friendly greeting","formal":"Please write a formal, professional greeting","casual":"Please write a casual, relaxed greeting",}# 返回匹配的风格提示词,无匹配则使用友好风格returnf"{styles.get(style, styles['friendly'])} for someone named {name}."# 启动MCP服务:使用标准输入输出传输协议(stdio) 本地服务,兼容Cherry Studioif __name__ =="__main__": mcp.run(transport="stdio")

代码核心说明

  1. FastMCP(“Demo”):快速初始化 MCP 服务,Demo为服务名称,在 Cherry Studio 中会显示该名称
  2. 三大核心装饰器:
    @mcp.tool():标记可调用工具,AI 能直接执行并返回结果(如加法计算)
    @mcp.resource():标记资源服务,通过自定义协议提供静态 / 动态资源(如个性化问候)
    @mcp.prompt():标记提示词工具,为 AI 生成指定风格的内容提供模板

六、客户端准备:安装 Cherry Studio(MCP 联调工具)

Cherry Studio 是一款专为 MCP 协议设计的 AI 客户端,能无缝对接自定义 MCP 服务,无需复杂的接口配置,是测试自定义 MCP 服务的最佳工具。

1. 下载安装

官网下载地址:https://www.cherry-ai.com/download

支持 Windows/macOS 系统,一键安装无附加组件
安装完成后打开,完成基础注册 / 登录(免费可用)

2. 安装 Cherry 内置工具(基础准备)

在这里插入图片描述


在这里插入图片描述


添加MCP 服务器

在这里插入图片描述

七、关键步骤:Cherry Studio 添加自定义 MCP 服务

在这里插入图片描述


输入完后,点保存并打开。

在这里插入图片描述

八、联调测试:验证自定义 MCP 服务是否生效

回到首页,输入使用MCP 1+3 等于多少? 发送输出5 证明已调用到我们自己写的MCP 服务中。

在这里插入图片描述

九、在Trace 中配置MCP stdi模式使用

1. 配置mcp:

{"mcpServers":{"mcp-stdio-add":{"command":"python", "args":["D:\\AiMcpProject\\mcp_server\\main.py"], "env":{}}}}
在这里插入图片描述

2.输入 使用 mcp-stdio-add 工具计算 1+3 的和,发送即可

在这里插入图片描述

十、 运行 MCP see模式

main.py 配置 see 和端口 8001

if __name__ =="__main__": mcp.settings.port =8001 mcp.run(transport="sse")

完整代码(可直接复制使用)

from mcp.server import FastMCP # Create an MCP server mcp = FastMCP("Demo")# Add an addition [email protected]()defadd(a:int, b:int)->int:"""Add two numbers"""return a + b +1#多加1 测试是走了我们自己的mcp# Add a dynamic greeting [email protected]("greeting://{name}")defget_greeting(name:str)->str:"""Get a personalized greeting"""returnf"Hello, {name}!"# Add a [email protected]()defgreet_user(name:str, style:str="friendly")->str:"""Generate a greeting prompt""" styles ={"friendly":"Please write a warm, friendly greeting","formal":"Please write a formal, professional greeting","casual":"Please write a casual, relaxed greeting",}returnf"{styles.get(style, styles['friendly'])} for someone named {name}."# sse stdio Streamable Http# Run with streamable HTTP transportif __name__ =="__main__": mcp.settings.port =8001 mcp.run(transport="sse")

运行程序:

在这里插入图片描述

Trace 配置MCP sse:

输入 使用 mcp-stdio-add 工具计算 1+3 的和,发送即可, 会输出结果 和 python端输出接口请求

在这里插入图片描述

Read more

用 Java 实现控制台版图书管理系统:从需求到代码的完整实践

用 Java 实现控制台版图书管理系统:从需求到代码的完整实践

我不是广告 个人主页-爱因斯晨 文章专栏-JAVA学习 好久不见~最近变了很多,也在忙。也有点儿小体会吧,最近遇到了很多事儿,我也想了很多。我个人的想法还是:不能给自己的以后留下任何污点,因为路还很长,我这才刚开始。要坚守自己的底线吧!“苟非吾之所有,虽一毫而莫取” 最后,衷心祝大家,身心健康,注意好身体! > 不知道大家喜欢听歌嘛?最近发现一个可以白嫖会员的东西,苹果音乐可以白嫖会员(新用户两个月,老用户一个月),苹果安卓都能用,领取之后记得关闭自动续费哦~曲库还是很多的,大家可以点击链接领取。领取链接绝对免费!绝对白嫖! 作为一名 Java 开发者,我们常常忙于框架和中间件的使用,却容易忽略基础语法的实战价值。今天,我将带大家从零开始实现一个控制台版图书管理系统,这个项目虽然简单,却涵盖了 Java 核心基础的大部分知识点,非常适合初学者巩固基础,也能让资深开发者重温 Java 设计的初心。 项目需求分析 在开始编码之前,我们需要明确这个图书管理系统应该具备哪些核心功能。

By Ne0inhk
【Java 开发日记】为什么要有 time _wait 状态,服务端这个状态过多是什么原因?

【Java 开发日记】为什么要有 time _wait 状态,服务端这个状态过多是什么原因?

目录 为什么要有 TIME_WAIT 状态? 原因一:可靠地终止TCP连接(确保最后的ACK能到达对方) 原因二:让旧连接的重复报文段在网络中自然消失(防止影响新连接) 服务端 TIME_WAIT 状态过多是什么原因? 原因一:服务端使用了短连接,并且是它主动关闭连接 原因二:客户端的非正常行为 原因三:负载均衡器的健康检查 总结 面试回答 为什么要有 TIME_WAIT 状态? TIME_WAIT,俗称2MSL等待状态,是TCP连接主动关闭一方(通常是客户端,但也可能是服务端)在发送最后一次ACK确认报文后,会进入的一个状态。它需要等待2倍的最大报文段生存时间后,才会最终进入CLOSED状态,释放连接资源。 设计TIME_WAIT状态主要有两个核心原因,它们是确保TCP协议可靠性的基石: 原因一:可靠地终止TCP连接(确保最后的ACK能到达对方) 这是最主要的原因。让我们回顾一下TCP四次挥手的正常流程: 1. 主动关闭方(假设为A)

By Ne0inhk
Java 时间类(上):JDK7 及以前时间类 Date、SimpleDateFormat、Calendar 最全总结

Java 时间类(上):JDK7 及以前时间类 Date、SimpleDateFormat、Calendar 最全总结

🏠个人主页:黎雁 🎬作者简介:C/C++/JAVA后端开发学习者 ❄️个人专栏:C语言、数据结构(C语言)、EasyX、JAVA、游戏、规划、程序人生 ✨ 从来绝巘须孤往,万里同尘即玉京 文章目录 * Java 时间类(上):JDK7 及以前时间类 Date、SimpleDateFormat、Calendar 最全总结 🕒 * 📝 文章摘要 * 一、时间相关基础知识点 ⏱ * 1. 时间标准 * 2. 时间单位与换算 * 二、Date 时间类 📅 * 1. 概述 * 2. 构造方法 * 3. 成员方法 * 4. 代码示例 * 三、SimpleDateFormat 格式化与解析 ✍️ * 1. 作用

By Ne0inhk
JavaScript DOM 核心操作:从内容到节点的实战指南

JavaScript DOM 核心操作:从内容到节点的实战指南

DOM(文档对象模型)是前端开发中操作页面结构、内容和样式的核心,本文聚焦 DOM 中元素内容、属性、样式的读写修改,以及节点的增删改,结合实战示例讲解核心用法与最佳实践。 一、操作元素内容 元素内容操作分为纯文本处理和带 HTML 结构的处理,核心使用 innerText 和 innerHTML 两个属性,二者特性对比如下: 方法识别 HTML 标签保留换行 / 空格标准性适用场景innerText❌❌非标准(IE)仅读取 / 修改纯文本innerHTML✅✅W3C 标准读取 / 修改带 HTML 结构的内容 1. innerText:纯文本操作 仅处理文本内容,会忽略 HTML 标签和源码中的换行 / 空格,适合简单文本读写。 // 读操作:获取元素纯文本内容 var text = element.innerText;

By Ne0inhk