1.前言
MCP Server(模型上下文协议服务器)是一种基于模型上下文协议(Model Context Protocol,简称MCP)构建的轻量级服务程序,旨在实现大型语言模型(LLM)与外部资源之间的高效、安全连接。MCP协议由Anthropic公司于2024年11月开源,其核心目标是解决AI应用中数据分散、接口不统一等问题,为开发者提供标准化的接口,使AI模型能够灵活访问本地资源和远程服务,从而提升AI助手的响应质量和工作效率。
MCP Server 的架构与工作原理
MCP Server 采用客户端-服务器(Client-Server)架构,其中客户端(MCP Client)负责与服务器建立连接,发起请求,而服务器端则处理请求并返回响应。这种架构确保了数据交互的高效性与安全性。例如,客户端可以向服务器发送请求,如“查询数据库中的某个记录”或“调用某个API”,而服务器则根据请求类型,调用相应的资源或工具,完成任务并返回结果。
MCP Server 支持动态发现和实时更新机制。例如,当新的资源或工具被添加到服务器时,客户端可以自动感知并使用这些新功能,从而提高系统的灵活性和扩展性
MCP Server 的主要功能
- 资源暴露与工具提供:
MCP Server 可以将本地文件、数据库、API等资源作为数据实体暴露给AI模型,同时提供工具功能,帮助AI完成复杂任务,如数据检索、内容生成、实时更新等。例如,它支持对MySQL、PostgreSQL等数据库的查询和操作,也支持对本地文件系统的读写和目录管理。 - 会话管理与动态通知:
MCP Server 能够管理客户端与服务器的连接,确保会话的时效性和稳定性,同时通过实时推送机制,将最新的资源信息及时传递给AI模型,以保证数据的准确性和实时性。 - 安全性与隐私保护:
MCP Server 采用加密认证和访问控制机制,确保数据传输的安全性,避免敏感信息泄露。例如,它支持本地运行,避免将敏感数据上传至第三方平台,从而保护用户隐私。 - 标准化与模块化:
MCP Server 提供了标准化的通信协议,支持两种传输协议(STDIO和SSE),并允许开发者通过插件扩展功能,使其具备灵活性和扩展性。例如,它支持通过HTTP标准POST请求与客户端进行交互,同时支持WebSocket实现实时数据推送。 - 多场景应用:
MCP Server 可以应用于多种场景,包括但不限于:- 本地资源集成:如文件操作、数据库管理、API调用等。
- 云服务交互:如与GitHub、Slack、Google Drive等云服务的集成。
- AI助手扩展:如为ChatGPT等AI助手提供上下文支持和工具调用能力
目前mcp-server发展速度非常快。在短短1个多月的时间目前mcp-server已经发展超过5000个mcp-server
前端时间也给大家分享过一个速来围观!vs code + cline 联手 MCP-server,解锁大模型万物互联新玩法! 使用cline 实现mysql数据库的mcp-server 的一个案例。之前的这个案例主要介绍了如何使用这个mcp-server。今天给大家带来的是我们基于一个叫做fastapi_mcp的一个框架实现即梦AI 文生视频的一个mcp-server.那么话不多说下面带大家实现这个MCP- server.
我们这里使用Cherry Studio实现这个文生视频的mcp-server
上图中我们输入需要调用的工具名称,提示词 以及需要调用文生视频mcp-server apikey后 后端模型通过意图识别判断调用了这个文生视频的mcp-server从而实现了调用即梦AI 创建一个文生视频。返回的视频链接我们可以在即梦AI 看到预览
2.MCP Server 制作
在制作这个MCP Server之前我们首选介绍一下fastapi_mcp,它的实现fastapi的mcp接口实现。项目的源码地址是
https://github.com/tadata-org/fastapi_mcp
它的主要实现参考下面的代码
from fastapi import FastAPI
from fastapi_mcp import add_mcp_server
app = FastAPI()
mcp_server = add_mcp_server(
app,# Your FastAPI app
mount_path="/mcp",# Where to mount the MCP server
name="My API MCP",# Name for the MCP server
describe_all_responses=True,# False by default. Include all possible response schemas in tool descriptions, instead of just the successful response.
describe_full_response_schema=True# False by default. Include full JSON schema in tool descriptions, instead of just an LLM-friendly response example.)# Optionally add custom tools in addition to existing APIs.@mcp_server.tool()asyncdefget_server_time()->str:"""Get the current server time."""from datetime import datetime
return datetime.now().isoformat()
通过上面的函数就将我们之前对外暴露的fastap 服务转换成支持mcp -server了
我们的即梦AI文生视频的mcp -server 主要功能如下:
1. 视频生成服务
该服务通过调用极梦(剪映)的API来生成AI视频,主要功能点包括:
- 视频生成接口 :提供 /jimeng/generate_video/ 接口,接收文本提示词、视频宽高比、时长和帧率等参数,生成对应的AI视频
- 认证机制 :实现了基于Bearer Token的认证系统,通过 verify_auth_token 函数验证请求的合法性
- 视频处理流程 :
- 调用极梦API生成视频
- 轮询检查视频生成状态
- 下载生成的视频到本地临时存储
- 上传视频到腾讯云COS对象存储
- 返回视频URL和预览信息
2. MCP工具集成
服务集成了FastAPI MCP(Model Control Protocol)框架,提供了可被其他服务调用的工具:
- MCP服务器配置 :通过 add_mcp_server 将服务注册为MCP服务
- 视频生成工具 :提供 generate_video_mcp 工具,可以被其他支持MCP协议的服务(如AI助手)调用
3. 辅助功能
- 文件管理 :
- 生成带时间戳的唯一文件名
- 下载视频到本地
- 上传视频到腾讯云COS
- 清理临时文件
- 配置管理 :从配置文件读取API密钥、存储路径等信息
- 日志记录 :详细记录API调用、视频生成过程和错误信息
4. 错误处理
- 完善的异常处理机制,包括API调用失败、视频生成超时、文件处理错误等情况
- 返回标准化的HTTP错误响应
技术特点
- 使用FastAPI构建高性能异步API
- 集成腾讯云COS对象存储服务
- 实现MCP协议支持,便于与AI系统集成
- 完善的日志和错误处理机制
这个服务主要用于根据文本提示词生成AI视频,并提供标准化的接口供其他系统调用。
以上这个服务代码主要是基于我之前写的即梦AI 文生视频fastapi 服务端接口服务。主体功能还是原来的代码逻辑只是增加了一下上面代码中fastapi_mcp、@mcp_server.tool() 从而实现fastapi_mcp功能。
改造后的代码如下:
jimeng_video_service.py
from fastapi import FastAPI, HTTPException,Depends, Header
from pydantic import BaseModel
import logging
import time
import requests
import uuid
import configparser
import json
import os
import datetime
import random
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
from fastapi_mcp import add_mcp_server
# 设置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI(
title="Jimeng Video Service API",
description="一个用于生成AI视频的服务 API",
version="1.0.0",)# 读取配置文件
config = configparser.ConfigParser()# 在读取配置文件部分添加 COS 配置
config.read('f:\\work\\code\\2024pythontest\\jimeng\\config.ini', encoding='utf-8')# 添加 COS 配置读取
region = config.get('common','region')
secret_id = config.get('common','secret_id')
secret_key = config.get('common','secret_key')
bucket = config.get('common','bucket')# 在读取 video_output_path 后添加目录检查和创建逻辑
video_output_path = config.get('common','video_output_path')ifnot os.path.exists(video_output_path):
os.makedirs(video_output_path)
logger.info(f"创建视频输出目录: {video_output_path}")classVideoRequest(BaseModel):
prompt:str
aspect_ratio:str="16:9"
duration_ms:int=5000
fps:int=24defverify_auth_token(authorization:str= Header(None)):"""验证 Authorization Header 中的 Bearer Token"""ifnot authorization:raise HTTPException(status_code=401, detail="Missing Authorization Header")
scheme, _, token = authorization.partition(" ")if scheme.lower()!="bearer":raise HTTPException(status_code=401, detail="Invalid Authorization Scheme")# 从配置文件读取有效token列表
valid_tokens = json.loads(config.get('auth','valid_tokens'))if token notin valid_tokens:raise HTTPException(status_code=403, detail="Invalid or Expired Token")return token
# 修改视频生成接口,添加鉴权依赖# 添加新的辅助函数defgenerate_timestamp_filename_for_video(extension='mp4'):
timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
random_number = random.randint(1000,9999)
filename =f"video_{timestamp}_{random_number}.{extension}"return filename
defdownload_video(url, output_path):
response = requests.get(url, stream=True)
response.raise_for_status()
filename = generate_timestamp_filename_for_video()
file_path = os.path.join(output_path, filename)withopen(file_path,'wb')asfile:for chunk in response.iter_content(chunk_size=8192):if chunk:file.write(chunk)return filename, file_path
defupload_to_cos(region, secret_id, secret_key, bucket, file_name, base_path):
config = CosConfig(
Region=region,
SecretId=secret_id,
SecretKey=secret_key
)
client = CosS3Client(config)
file_path = os.path.join(base_path, file_name)
response = client.upload_file(
Bucket=bucket,
LocalFilePath=file_path,
Key=file_name,
PartSize=10,
MAXThread=10,
EnableMD5=False)if response['ETag']:
url =f"https://{bucket}.cos.{region}.myqcloud.com/{file_name}"return url
returnNone# 修改 generate_video 函数中的返回部分@app.post("/jimeng/generate_video/")asyncdefgenerate_video(request: VideoRequest, auth_token:str= Depends(verify_auth_token)):try:
logger.info(f"generate_video API 调用开始,提示词: {request.prompt}")
start_time = time.time()# 从配置文件中获取视频API相关配置
video_api_cookie = config.get('video_api','cookie')
video_api_sign = config.get('video_api','sign')# 初始化视频生成API相关配置
video_api_headers ={'accept':'application/json, text/plain, */*','accept-language':'zh-CN,zh;q=0.9','app-sdk-version':'48.0.0','appid':'513695','appvr':'5.8.0','content-type':'application/json','cookie': video_api_cookie,'device-time':str(int(time.time())),'lan':'zh-Hans','loc':'cn','origin':'https://jimeng.jianying.com','pf':'7','priority':'u=1, i','referer':'https://jimeng.jianying.com/ai-tool/video/generate','sec-ch-ua':'"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"','sec-ch-ua-mobile':'?0','sec-ch-ua-platform':'"Windows"','sec-fetch-dest':'empty','sec-fetch-mode':'cors','sec-fetch-site':'same-origin','sign': video_api_sign,'sign-ver':'1','user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'}
video_api_base ="https://jimeng.jianying.com/mweb/v1"# 生成唯一的submit_id
submit_id =str(uuid.uuid4())# 准备请求数据
generate_video_payload ={"submit_id": submit_id,"task_extra":"{\"promptSource\":\"custom\",\"originSubmitId\":\"0340110f-5a94-42a9-b737-f4518f90361f\",\"isDefaultSeed\":1,\"originTemplateId\":\"\",\"imageNameMapping\":{},\"isUseAiGenPrompt\":false,\"batchNumber\":1}","http_common_info":{"aid":513695},"input":{"video_aspect_ratio": request.aspect_ratio,"seed":2934141961,"video_gen_inputs":[{"prompt": request.prompt,"fps": request.fps,"duration_ms": request.duration_ms,"video_mode":2,"template_id":""}],"priority":0,"model_req_key":"dreamina_ic_generate_video_model_vgfm_lite"},"mode":"workbench","history_option":{},"commerce_info":{"resource_id":"generate_video","resource_id_type":"str","resource_sub_type":"aigc","benefit_type":"basic_video_operation_vgfm_lite"},"client_trace_data":{}}# 发送生成视频请求
generate_video_url =f"{video_api_base}/generate_video?aid=513695"
logger.info(f"发送视频生成请求...")
response = requests.post(generate_video_url, headers=video_api_headers, json=generate_video_payload)if response.status_code !=200:raise HTTPException(status_code=500, detail=f"视频生成请求失败,状态码:{response.status_code}")
response_data = response.json()ifnot response_data or"data"notin response_data or"aigc_data"notin response_data["data"]:raise HTTPException(status_code=500, detail="视频生成接口返回格式错误")
task_id = response_data["data"]["aigc_data"]["task"]["task_id"]
logger.info(f"视频生成任务已创建,任务ID: {task_id}")# 轮询检查视频生成状态
mget_generate_task_url =f"{video_api_base}/mget_generate_task?aid=513695"
mget_generate_task_payload ={"task_id_list":[task_id]}# 最多尝试30次,每次间隔2秒for attempt inrange(30):
time.sleep(2)
logger.info(f"检查视频状态,第 {attempt +1} 次尝试...")
response = requests.post(mget_generate_task_url, headers=video_api_headers, json=mget_generate_task_payload)if response.status_code !=200:
logger.warning(f"状态检查失败,状态码:{response.status_code}")continue
response_data = response.json()ifnot response_data or"data"notin response_data or"task_map"notin response_data["data"]:
logger.warning("状态检查返回格式错误")continue
task_data = response_data["data"]["task_map"].get(task_id)ifnot task_data:
logger.warning(f"未找到任务 {task_id} 的状态信息")continue
task_status = task_data.get("status")
logger.info(f"任务状态: {task_status}")if task_status ==50:# 视频生成完成if"item_list"in task_data and task_data["item_list"]and"video"in task_data["item_list"][0]:
video_data = task_data["item_list"][0]["video"]if"transcoded_video"in video_data and"origin"in video_data["transcoded_video"]:
video_url = video_data["transcoded_video"]["origin"]["video_url"]
elapsed_time = time.time()- start_time
logger.info(f"视频生成成功,耗时 {elapsed_time:.2f} 秒,URL: {video_url}")# 下载视频到本地try:
filename, file_path = download_video(video_url, video_output_path)
logger.info(f"视频已下载到本地: {file_path}")# 上传到腾讯 COS
cos_url = upload_to_cos(region, secret_id, secret_key, bucket, filename, video_output_path)if cos_url:
logger.info(f"视频已上传到 COS: {cos_url}")# 删除本地文件
os.remove(file_path)return{"video_url": cos_url,"task_id": task_id,"markdown":f"<video controls><source src='{cos_url}' type='video/mp4'>视频预览</video>"}else:raise HTTPException(status_code=500, detail="上传视频到 COS 失败")except Exception as e:
logger.error(f"处理视频文件失败: {str(e)}")raise HTTPException(status_code=500, detail=f"处理视频文件失败: {str(e)}")raise HTTPException(status_code=500, detail="视频生成完成但未找到下载地址")raise HTTPException(status_code=500, detail="视频生成超时")except Exception as e:
logger.error(f"视频生成失败: {str(e)}")raise HTTPException(status_code=500, detail=str(e))# 修改 MCP 服务器配置
mcp_server = add_mcp_server(
app,
mount_path="/mcp",
name="Jimeng Video MCP",
description="集成了智能视频生成功能的 MCP 服务",
base_url="http://localhost:8088")# 添加自定义 MCP 工具@mcp_server.tool()asyncdefgenerate_video_mcp(
prompt:str,
aspect_ratio:str="16:9",
duration_ms:int=5000,
fps:int=24,
authorization:str= Header(...))->dict:"""
生成一个基于文本提示的 AI 视频。
Args:
prompt: 用于生成视频的文本提示词
aspect_ratio: 视频宽高比,默认为 "16:9"
duration_ms: 视频时长(毫秒),默认为 5000
fps: 视频帧率,默认为 24
authorization: Bearer token 用于认证(必填)
Returns:
dict: 包含以下字段的字典:
- video_url: 生成视频的 URL
- task_id: 任务 ID
- markdown: 视频预览的 markdown 代码
"""
request = VideoRequest(
prompt=prompt,
aspect_ratio=aspect_ratio,
duration_ms=duration_ms,
fps=fps
)returnawait generate_video(request, auth_token=verify_auth_token(authorization))if __name__ =="__main__":import uvicorn
# 修改启动配置
uvicorn.run(
app,
host="0.0.0.0",
port=8088,
log_level="info",reload=False# 禁用热重载以避免初始化问题)
上述代码编写完成后我们启动它
3.MCP Server 运行
点击trae run python file 完成 服务端启动
当然你也可以使用python jimeng_video_service.py 启动这个服务
上述启动和我们普通的fastapi 服务端启动类似。启动后他对外提供一个叫做http://localhost:8088/mcp sse服务
4 .Cherry Studio 配置mcp server
我们下载最新的Cherry Studio,这里为什么下载最新的 我记得早期1.0之前的版本好像是不支持mcp server的 新版本是支持的,支持不支持大家可以看这个
点开这里,我们添加一个服务器,选择SSE
我们在URL 填写上面创建的SSE服务器地址http://localhost:8088/mcp 点击保存按钮完成设置。这里点击保存后,客户端Cherry Studio会想服务器发起请求。
看到这个就说明客户端和服务器之间产生通讯。
5 .Cherry Studio 调用mcp server
这里我们选择一个模型支持function call 的模型,怎么判断呢模型设置里面有个小工具按钮,我们这里拿火山引擎提供的deepseek-V3模型作为案例
打开一个聊天对话窗口 选择火山引擎提供的deepseek-V3
选择模型后下面聊天窗口就会多出MCP Server小窗口,我们选择开启MCP服务器并开启我们需要的文生视频MCPserver
以上设置完成后,我们就可以进入聊天对话界面了。为了方便测试我们输入以下提示词
请帮我调用即梦AI文生视频mcpserver 工具,用户输入的提示词“小马过河”,需要的authorization 为”bearer sk-zhouhui1122444”
因为mcpserver 需要2个必填参数 一个是提示词,一个是鉴权,所以这2个值需要用户输入。当然你也可以一个一个填写通过模型引导你填入。我这里偷懒就直接把需要的2个参考一并告诉模型,这样它就不需要和客户交互直接执行函数调用了。怎么查看必填项呢
我们可以在之前的mcpserver 设置查看到
这2个必填项主要是服务端代码来实现的。
填写提示词后 deepseek-v3模型会通过意图识别自动开启函数调用
在调用过程中我们也可以看后端程序的运行,直到后面返回结果给前端
这里比较遗憾的是cherry studio 不知道怎么实现视频的预览,所以需要我们把生成的视频URL 链接复制到浏览器上重新下载才能看到效果。
总结
总体来说实现这个mcp server 难度不大,主要还是借助了fastapi_mcp 以及sse方式实现了这个文生视频的MCP server。感兴趣小伙伴可以基于这块框架把我之前写的fastapi 服务端接口一并改成支持mcp server服务,通过改造几个程序大家更容易理解和掌握目前最流行的
MCP server了,今天的分享就到这里结束了,感兴趣的小伙伴可以关注支持,我们下个文章见。
零基础如何高效学习大模型?
你是否懂 AI,是否具备利用大模型去开发应用能力,是否能够对大模型进行调优,将会是决定自己职业前景的重要参数。
为了帮助大家打破壁垒,快速了解大模型核心技术原理,学习相关大模型技术。从原理出发真正入局大模型。在这里我和鲁为民博士系统梳理大模型学习脉络,这份 LLM大模型资料
分享出来:包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程
等, 😝有需要的小伙伴,可以 扫描下方二维码免费领取🆓**⬇️⬇️⬇️
【大模型全套视频教程】
教程从当下的市场现状和趋势出发,分析各个岗位人才需求,带你充分了解自身情况,get 到适合自己的 AI 大模型入门学习路线。
从基础的 prompt 工程入手,逐步深入到 Agents,其中更是详细介绍了 LLM 最重要的编程框架 LangChain。最后把微调与预训练进行了对比介绍与分析。
同时课程详细介绍了AI大模型技能图谱知识树,规划属于你自己的大模型学习路线,并且专门提前收集了大家对大模型常见的疑问,集中解答所有疑惑!
深耕 AI 领域技术专家带你快速入门大模型
跟着行业技术专家免费学习的机会非常难得,相信跟着学习下来能够对大模型有更加深刻的认知和理解,也能真正利用起大模型,从而“弯道超车”,实现职业跃迁!
【精选AI大模型权威PDF书籍/教程】
精心筛选的经典与前沿并重的电子书和教程合集,包含《深度学习》等一百多本书籍和讲义精要等材料。绝对是深入理解理论、夯实基础的不二之选。
【AI 大模型面试题 】
除了 AI 入门课程,我还给大家准备了非常全面的**「AI 大模型面试题」,**包括字节、腾讯等一线大厂的 AI 岗面经分享、LLMs、Transformer、RAG 面试真题等,帮你在面试大模型工作中更快一步。
【大厂 AI 岗位面经分享(92份)】
【AI 大模型面试真题(102 道)】
【LLMs 面试真题(97 道)】
【640套 AI 大模型行业研究报告】
【AI大模型完整版学习路线图(2025版)】
明确学习方向,2025年 AI 要学什么,这一张图就够了!
👇👇点击下方卡片链接免费领取全部内容👇👇
抓住AI浪潮,重塑职业未来!
科技行业正处于深刻变革之中。英特尔等巨头近期进行结构性调整,缩减部分传统岗位,同时AI相关技术岗位(尤其是大模型方向)需求激增,已成为不争的事实。具备相关技能的人才在就业市场上正变得炙手可热。
行业趋势洞察:
- 转型加速: 传统IT岗位面临转型压力,拥抱AI技术成为关键。
- 人才争夺战: 拥有3-5年经验、扎实AI技术功底和真实项目经验的工程师,在头部大厂及明星AI企业中的薪资竞争力显著提升(部分核心岗位可达较高水平)。
- 门槛提高: “具备AI项目实操经验”正迅速成为简历筛选的重要标准,预计未来1-2年将成为普遍门槛。
与其观望,不如行动!
面对变革,主动学习、提升技能才是应对之道。掌握AI大模型核心原理、主流应用技术与项目实战经验,是抓住时代机遇、实现职业跃迁的关键一步。
01 为什么分享这份学习资料?
当前,我国在AI大模型领域的高质量人才供给仍显不足,行业亟需更多有志于此的专业力量加入。
因此,我们决定将这份精心整理的AI大模型学习资料,无偿分享给每一位真心渴望进入这个领域、愿意投入学习的伙伴!
我们希望能为你的学习之路提供一份助力。如果在学习过程中遇到技术问题,也欢迎交流探讨,我们乐于分享所知。
*02 这份资料的价值在哪里?*
专业背书,系统构建:
-
本资料由我与鲁为民博士共同整理。鲁博士拥有清华大学学士和美国加州理工学院博士学位,在人工智能领域造诣深厚:
-
- 在IEEE Transactions等顶级学术期刊及国际会议发表论文超过50篇。
- 拥有多项中美发明专利。
- 荣获吴文俊人工智能科学技术奖(中国人工智能领域重要奖项)。
-
目前,我有幸与鲁博士共同进行人工智能相关研究。
内容实用,循序渐进:
-
资料体系化覆盖了从基础概念入门到核心技术进阶的知识点。
-
包含丰富的视频教程与实战项目案例,强调动手实践能力。
-
无论你是初探AI领域的新手,还是已有一定技术基础希望深入大模型的学习者,这份资料都能为你提供系统性的学习路径和宝贵的实践参考,助力你提升技术能力,向大模型相关岗位转型发展。
抓住机遇,开启你的AI学习之旅!