如何在modelscope上上传自己的MCP服务
我在网上看了一些,跟着这些教程来实现,发现踩了很多坑,所以想在这里记录一下,正常不踩坑的流程!
首先我们先确定自己的MCP服务需要提供什么功能,目前我以一个模拟算命的例子来说说明,并且使用了gradio来实现前端的页面。为什么要用gradio,一会用用到modelsocpe的时候大家就知道了。好了我先提供一下代码,大家先看看,代码有点长,里面的逻辑很多也是写死的,只是做个示范而已,切勿当真
1.代码编写和测试
import gradio as gr
import pandas as pd
import numpy as np
from datetime import datetime
import random# 天干
TIAN_GAN = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"]
# 地支
DI_ZHI = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"]
# 五行
WU_XING = ["金", "木", "水", "火", "土"]
# 生肖
SHENG_XIAO = ["鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"]# 运势类别
FORTUNE_CATEGORIES = ["事业", "财运", "健康", "爱情", "学业"]
# 运势评级
FORTUNE_RATINGS = ["大吉", "吉", "平", "凶", "大凶"]
# 运势描述模板
FORTUNE_TEMPLATES = {"事业": ["今年事业蒸蒸日上,有望获得重大突破。","职场上将遇到贵人相助,事业发展顺利。","工作中需谨慎行事,避免冲动决策。","事业发展可能遇到阻碍,需耐心等待时机。","今年事业运势低迷,建议稳守当前位置,避免冒险。"],"财运": ["财源广进,投资有望获得丰厚回报。","财运稳定,收入有所增长。","财务状况平稳,宜量入为出。","财运欠佳,需谨慎理财,避免大额支出。","财务压力较大,需严格控制开支,避免投资风险。"],"健康": ["身体健康状况极佳,精力充沛。","整体健康良好,注意适当锻炼。","健康状况一般,注意作息规律。","身体易感疲劳,需多加休息,注意饮食。","健康状况堪忧,建议定期体检,加强保健。"],"爱情": ["桃花运旺盛,单身者有望遇到理想伴侣。","感情生活甜蜜和谐,关系更进一步。","感情状况平稳,需增进沟通交流。","感情易生波折,需耐心处理矛盾。","感情运势低迷,易遇人际关系困扰。"],"学业": ["学习能力超群,知识吸收迅速,成绩优异。","学习状态良好,能够稳步提升。","学习进度一般,需加强自律性。","学习效率下降,需调整学习方法。","学习困难重重,需寻求他人指导帮助。"]
}def calculate_bazi(year, month, day, hour, minute):"""计算八字"""# 简化计算,实际八字计算更复杂year_idx = (year - 4) % 10 # 天干年year_branch_idx = (year - 4) % 12 # 地支年month_idx = ((year_idx % 5) * 2 + month) % 10 # 天干月month_branch_idx = month % 12 # 地支月day_idx = (year * 5 + year // 4 + day) % 10 # 天干日day_branch_idx = (year * 5 + year // 4 + day) % 12 # 地支日hour_idx = (day_idx * 2 + hour // 2) % 10 # 天干时hour_branch_idx = hour // 2 % 12 # 地支时year_pillar = TIAN_GAN[year_idx] + DI_ZHI[year_branch_idx]month_pillar = TIAN_GAN[month_idx] + DI_ZHI[month_branch_idx]day_pillar = TIAN_GAN[day_idx] + DI_ZHI[day_branch_idx]hour_pillar = TIAN_GAN[hour_idx] + DI_ZHI[hour_branch_idx]shengxiao = SHENG_XIAO[year_branch_idx]return {"year_pillar": year_pillar,"month_pillar": month_pillar,"day_pillar": day_pillar,"hour_pillar": hour_pillar,"shengxiao": shengxiao}def analyze_wuxing(bazi):"""分析五行强弱"""# 简化分析,实际分析更复杂wuxing_count = {wx: 0 for wx in WU_XING}# 根据天干地支计算五行数量for pillar in [bazi["year_pillar"], bazi["month_pillar"], bazi["day_pillar"], bazi["hour_pillar"]]:tian_gan = pillar[0]di_zhi = pillar[1]# 天干五行对应if tian_gan in ["甲", "乙"]:wuxing_count["木"] += 1elif tian_gan in ["丙", "丁"]:wuxing_count["火"] += 1elif tian_gan in ["戊", "己"]:wuxing_count["土"] += 1elif tian_gan in ["庚", "辛"]:wuxing_count["金"] += 1elif tian_gan in ["壬", "癸"]:wuxing_count["水"] += 1# 地支五行对应(简化)if di_zhi in ["寅", "卯"]:wuxing_count["木"] += 1elif di_zhi in ["巳", "午"]:wuxing_count["火"] += 1elif di_zhi in ["辰", "戌", "丑", "未"]:wuxing_count["土"] += 1elif di_zhi in ["申", "酉"]:wuxing_count["金"] += 1elif di_zhi in ["亥", "子"]:wuxing_count["水"] += 1# 找出最强和最弱的五行strongest = max(wuxing_count, key=wuxing_count.get)weakest = min(wuxing_count, key=wuxing_count.get)return {"wuxing_count": wuxing_count,"strongest": strongest,"weakest": weakest}def generate_fortune(bazi, wuxing_analysis, current_year):"""生成运势预测"""# 使用八字和五行分析生成运势fortune = {}# 根据生肖和当前年份计算运势基础值shengxiao_idx = SHENG_XIAO.index(bazi["shengxiao"])current_year_idx = (current_year - 4) % 12base_luck = (shengxiao_idx - current_year_idx) % 12# 根据五行强弱调整运势strongest = wuxing_analysis["strongest"]weakest = wuxing_analysis["weakest"]for category in FORTUNE_CATEGORIES:# 基础运势评分 (0-4)base_score = (base_luck + hash(category + strongest)) % 5# 根据五行调整if category == "事业" and strongest in ["木", "火"]:base_score = min(base_score + 1, 4)elif category == "财运" and strongest in ["金", "土"]:base_score = min(base_score + 1, 4)elif category == "健康" and weakest in ["金", "水"]:base_score = max(base_score - 1, 0)elif category == "爱情" and strongest in ["火", "土"]:base_score = min(base_score + 1, 4)elif category == "学业" and strongest in ["水", "木"]:base_score = min(base_score + 1, 4)# 添加一些随机性adjusted_score = max(0, min(4, base_score + random.randint(-1, 1)))fortune[category] = {"rating": FORTUNE_RATINGS[adjusted_score],"description": FORTUNE_TEMPLATES[category][adjusted_score]}return fortunedef predict_fortune(name, gender, birth_year, birth_month, birth_day, birth_hour, birth_minute):"""根据生辰八字预测运势"""try:# 验证输入并设置默认值if not name or name.strip() == "":name = "无名氏"if not gender or gender not in ["男", "女"]:gender = "男"# 设置默认值current_year = datetime.now().yearbirth_year = int(birth_year) if birth_year and birth_year.strip() != "" else current_year - 30birth_month = int(birth_month) if birth_month and birth_month.strip() != "" else 1birth_day = int(birth_day) if birth_day and birth_day.strip() != "" else 1birth_hour = int(birth_hour) if birth_hour and birth_hour.strip() != "" else 12birth_minute = int(birth_minute) if birth_minute and birth_minute.strip() != "" else 0# 验证日期有效性datetime(birth_year, birth_month, birth_day, birth_hour, birth_minute)# 计算八字bazi = calculate_bazi(birth_year, birth_month, birth_day, birth_hour, birth_minute)# 分析五行wuxing_analysis = analyze_wuxing(bazi)# 获取当前年份current_year = datetime.now().year# 生成运势fortune = generate_fortune(bazi, wuxing_analysis, current_year)# 生成结果文本result = f"## {name}的八字分析\n\n"result += f"**姓名**: {name} ({gender})\n\n"result += f"**生辰八字**: {bazi['year_pillar']} {bazi['month_pillar']} {bazi['day_pillar']} {bazi['hour_pillar']}\n\n"result += f"**生肖**: {bazi['shengxiao']}\n\n"result += "## 五行分析\n\n"for wx, count in wuxing_analysis["wuxing_count"].items():result += f"**{wx}**: {'●' * count}\n\n"result += f"**最旺**: {wuxing_analysis['strongest']} **最弱**: {wuxing_analysis['weakest']}\n\n"result += "## 运势预测\n\n"for category in FORTUNE_CATEGORIES:result += f"**{category}**: {fortune[category]['rating']}\n\n"result += f"{fortune[category]['description']}\n\n"result += "## 运势建议\n\n"if wuxing_analysis['weakest'] == "金":result += "- 佩戴金属饰品有助于增强运势\n"elif wuxing_analysis['weakest'] == "木":result += "- 多接触绿色植物,有助于提升运势\n"elif wuxing_analysis['weakest'] == "水":result += "- 多喝水,亲近水源环境有利于运势提升\n"elif wuxing_analysis['weakest'] == "火":result += "- 适当增加红色元素在生活中,有助于提升运势\n"elif wuxing_analysis['weakest'] == "土":result += "- 多接触大地,户外活动有助于增强运势\n"if wuxing_analysis['strongest'] == "金":result += "- 注意避免过于固执,保持灵活思维\n"elif wuxing_analysis['strongest'] == "木":result += "- 注意控制脾气,保持心态平和\n"elif wuxing_analysis['strongest'] == "水":result += "- 注意不要过于犹豫不决,提高决断力\n"elif wuxing_analysis['strongest'] == "火":result += "- 注意避免冲动行事,保持冷静\n"elif wuxing_analysis['strongest'] == "土":result += "- 注意不要过于保守,适当尝试新事物\n"return resultexcept ValueError as e:return f"输入错误: {str(e)}"except Exception as e:return f"计算错误: {str(e)}"def create_ui():with gr.Blocks(title="生辰八字运势预测") as app:with gr.Row():gr.Markdown("# 生辰八字运势预测系统")with gr.Row():with gr.Column(scale=2):with gr.Group():gr.Markdown("### 个人信息")name = gr.Textbox(label="姓名 *", placeholder="请输入您的姓名")gender = gr.Radio(["男", "女"], label="性别 *", value="男")with gr.Group():gr.Markdown("### 出生信息")birth_year = gr.Textbox(label="出生年份 *", placeholder="例如: 1990")with gr.Row():birth_month = gr.Textbox(label="出生月份 *", placeholder="例如: 1-12", scale=1)birth_day = gr.Textbox(label="出生日期 *", placeholder="例如: 1-31", scale=1)with gr.Row():birth_hour = gr.Textbox(label="出生时辰 (小时) - 可选", placeholder="例如: 0-23", scale=1)birth_minute = gr.Textbox(label="出生时辰 (分钟) - 可选", placeholder="例如: 0-59", scale=1)with gr.Group():with gr.Row():submit_btn = gr.Button("预测运势", variant="primary", scale=2)example_btn = gr.Button("填写示例", variant="secondary", scale=1)with gr.Column(scale=3):with gr.Group():output = gr.Markdown(label="运势分析结果", elem_classes="scrollable-output")# 添加CSS样式,使输出区域可滚动gr.HTML("""<style>.scrollable-output {max-height: 500px;overflow-y: auto;padding: 10px;}</style>""")with gr.Row():with gr.Accordion("使用说明与注意事项", open=True):gr.Markdown("""### 使用说明1. 输入您的姓名和性别(如未填写将使用默认值)2. 输入您的出生年、月、日(如未填写将使用默认值)3. 输入出生时、分(可选,更精确)4. 点击"预测运势"按钮获取分析结果5. 或点击"填写示例"按钮快速填入示例数据### 注意事项- 本系统仅供娱乐参考,请勿过度迷信- 运势分析基于传统八字理论,结合现代算法- 更准确的分析请咨询专业命理师- 如未填写必要信息,系统将使用默认值进行计算""")def fill_example():return "张三", "男", "1990", "6", "15", "12", "30"submit_btn.click(fn=predict_fortune,inputs=[name, gender, birth_year, birth_month, birth_day, birth_hour, birth_minute],outputs=output)example_btn.click(fn=fill_example,inputs=[],outputs=[name, gender, birth_year, birth_month, birth_day, birth_hour, birth_minute])return appapp = create_ui()
app.launch(mcp_server=True)
值得注意的是app.launch(mcp_server=True),这个地方一定要写mcp_server=True,不然之后再modelscope后会有问题,同时安装mcp==1.8.1,gradio[mcp],这个地方我标红了,之后会再强调这个环境的,这里我们本地运行看看效果
我们复制这个http://127.0.0.1:7860链接,然后在浏览器中打开,填入需要的信息,就是下面这个样子的
这样我就确定了,本地部署这个服务是成功了,代码也是没有问题的
2.modelscope创空间
我们来到modelscope,然后找到创空间,点击我要创建,选择编程式创建,如下
然后会进入到这个界面
我们按照需要填写的信息填写内容即可,我给看看我的示例
好了,下面是及其关键的地方了,一定要注意!!!!!
一定要选择gradio5.29.0,我就是在这里踩坑了,我之前用5.42.0和5.34.1这版本,最后MCP服务创建不成功,耗了我2个小时啊!!!!!
之后下面的选项选择免费的就行了
填写完成后,点击创建创空间就可以完成空间的创建了,相当于一个台云服务器了
创建完成后会跳转到这个页面
我们复制这个命令git clone http://oauth2:ms-9654accb-6edf-42b9-9fe7-295e6a522f72@www.modelscope.cn/studios/guligedong/fortunetelling.git
然后把仓库拉下来,仓库怎么拉,不用我再说了吧,仓库拉下后里面没有文件,大概是这个样子的
重点1:我们把刚刚写的代码放进去,并且命名为app.py,切记!!!是app.py
重定2:创建一个requirements.txt,里面写如下内容,这样一会这些库一会才会在云服务器上安装
最后我们的文件中一共就有这些文件
然后再上传到仓库就可以了,上传成功后,我们就可以在modelscope上看到这些代码了,如下
我们等待一会审核成功在执行后面的操作,一般会等个5分钟8分钟的
审核成功后,在设置中,找到上线按钮,点击上线就可以了,如下图
然后回到空间内容页面,他会出现如下界面
等个几分钟,就会有画面,我们耐心等一下,等好了,就是如下界面
你会发现这个和你在你电脑本地部署的页面就一模一样了,此时这个服务相当于就在云服务器上部署起来了。
3.MCP服务的创建
当我们成功创空间后,我们找到通过API使用
点击后找到mcp
然后找到关键的地方
重点:这里面的东西复制一下,一会MCP创建服务的时候会用到!!!!
我们现在来创建MCP
点击创建MCP后会来到如下页面
首先,选择自定义创建
然后填写名字和你刚刚创空间的那个网址,托管类型选择可托管部署,类型随便填,我写的开发者工具,如下图
这里提醒一下,来源地址这一项,就是这个
好了就剩最后一步了,服务配置,就行刚刚我让你复制的那些东西粘贴进来就可以了
然后readne随便写一写就行了
然后点击创建,当这个地方都好了之后,MCP服务就创建成功了!!!大功告成了!!!
然后我们会到MCP广场,搜索自己的MCP服务,应该就有了
4.Trae 上测试MCP服务
点击连接后,复制信息,打开trae,然后手动添加刚刚复制的信息
配置好后,我们就可以在trae上用这个MCP服务了,我们来测试一下
然后就会自动调用MCP服务来工作了,如下图
到此圆满结束
至此敬礼