05-mcp-server案例分享-用豆包大模型 1.6 手搓文生圖視頻 MCP-server發布到PyPI官網

1前言

上期給大家介紹過mcp-server案例分享-用豆包大模型 1.6 手搓文生圖視頻 MCP-server。當時部署的方式使用了一個私有云SSE的部署。當時缺少一個本地部署的方式,有的小伙伴給我留言能不能有一個本地話部署方式了。今天就給大家帶來一個本地化部署的方案。

話不多說下面介紹一下具體如何打包和操作的。

2.打包發布Python庫到PyPI

基于上期文章我們已經有了代碼mcp_ai_server.py

# doubao_mcp_server.py
import time
import base64
import requests
import asyncio
from typing import Any, Dict, Optional, Union
from openai import OpenAI
from mcp.server.fastmcp import FastMCP# 創建MCP服務器實例
mcp = FastMCP("AI Generation Server")# 全局配置
API_KEY = None
BASE_URL = "https://ark.cn-beijing.volces.com/api/v3"def initialize_client():"""初始化OpenAI客戶端"""if not API_KEY:raise ValueError("API key is required")return OpenAI(api_key=API_KEY, base_url=BASE_URL)@mcp.tool()
def set_api_key(api_key: str) -> str:"""設置豆包API密鑰"""global API_KEYAPI_KEY = api_keyreturn "API密鑰設置成功"@mcp.tool()
def text_to_image(prompt: str, size: str = "1024x1024", model: str = "doubao-seedream-3-0-t2i-250415"
) -> Dict[str, Any]:"""文生圖功能 - 根據文本描述生成圖片Args:prompt: 圖片描述提示詞size: 圖片尺寸,格式為"寬x高",如"1024x1024"model: 使用的模型名稱Returns:包含圖片URL或錯誤信息的字典"""try:client = initialize_client()params = {"model": model,"prompt": prompt,"size": size,"response_format": "url","n": 1,}response = client.images.generate(**params)if response.data and len(response.data) > 0:return {"success": True,"image_url": response.data[0].url,"message": "圖片生成成功"}else:return {"success": False,"error": "未返回圖片數據"}except Exception as e:return {"success": False,"error": f"生成圖片時出錯: {str(e)}"}@mcp.tool()
def image_to_video(prompt: str,image_base64: str,duration: str = "5",ratio: str = "16:9",model: str = "doubao-seedance-1-0-lite-i2v-250428"
) -> Dict[str, Any]:"""圖生視頻功能 - 根據圖片和文本描述生成視頻Args:prompt: 視頻描述提示詞image_base64: 圖片的base64編碼字符串duration: 視頻時長(秒)ratio: 視頻比例,如"16:9"model: 使用的模型名稱Returns:包含視頻URL或錯誤信息的字典"""try:# 構造圖片數據URLimage_data_url = f"data:image/jpeg;base64,{image_base64}"# 自動添加參數到提示詞if ratio and "--ratio" not in prompt:prompt += f" --ratio adaptive"if duration and "--duration" not in prompt and "--dur" not in prompt:prompt += f" --duration {duration}"headers = {"Content-Type": "application/json","Authorization": f"Bearer {API_KEY}"}# 構造請求內容content = [{"type": "text", "text": prompt},{"type": "image_url", "image_url": {"url": image_data_url}}]request_data = {"model": model,"content": content}# 創建視頻生成任務response = requests.post(f"{BASE_URL}/contents/generations/tasks",headers=headers,json=request_data)if response.status_code != 200:return {"success": False,"error": f"創建視頻生成任務失敗,狀態碼: {response.status_code}, 信息: {response.text}"}task_id = response.json().get("id")if not task_id:return {"success": False,"error": "未獲取到任務ID"}# 輪詢等待任務完成max_retries = 60for retry in range(max_retries):time.sleep(5)task_resp = requests.get(f"{BASE_URL}/contents/generations/tasks/{task_id}",headers=headers)if task_resp.status_code != 200:return {"success": False,"error": f"查詢任務失敗,狀態碼: {task_resp.status_code}"}task_data = task_resp.json()status = task_data.get("status")if status == "succeeded":video_url = task_data.get("content", {}).get("video_url")return {"success": True,"video_url": video_url,"message": "視頻生成成功","task_id": task_id}elif status in ("failed", "canceled"):return {"success": False,"error": f"任務{status}"}return {"success": False,"error": "視頻生成超時"}except Exception as e:return {"success": False,"error": f"生成視頻時出錯: {str(e)}"}@mcp.tool()
def text_to_video(prompt: str,duration: str = "5",ratio: str = "16:9",model: str = "doubao-seedance-1-0-lite-t2v-250428"
) -> Dict[str, Any]:"""文生視頻功能 - 根據文本描述生成視頻Args:prompt: 視頻描述提示詞duration: 視頻時長(秒)ratio: 視頻比例,如"16:9"model: 使用的模型名稱Returns:包含視頻URL或錯誤信息的字典"""try:# 自動添加參數到提示詞if ratio and "--ratio" not in prompt:prompt += f" --ratio {ratio}"if duration and "--duration" not in prompt and "--dur" not in prompt:prompt += f" --duration {duration}"headers = {"Content-Type": "application/json","Authorization": f"Bearer {API_KEY}"}request_data = {"model": model,"content": [{"type": "text", "text": prompt}]}# 創建視頻生成任務response = requests.post(f"{BASE_URL}/contents/generations/tasks",headers=headers,json=request_data)if response.status_code != 200:return {"success": False,"error": f"創建視頻生成任務失敗,狀態碼: {response.status_code}, 信息: {response.text}"}task_id = response.json().get("id")if not task_id:return {"success": False,"error": "未獲取到任務ID"}# 輪詢等待任務完成max_retries = 60for retry in range(max_retries):time.sleep(5)task_resp = requests.get(f"{BASE_URL}/contents/generations/tasks/{task_id}",headers=headers)if task_resp.status_code != 200:return {"success": False,"error": f"查詢任務失敗,狀態碼: {task_resp.status_code}"}task_data = task_resp.json()status = task_data.get("status")if status == "succeeded":video_url = task_data.get("content", {}).get("video_url")return {"success": True,"video_url": video_url,"message": "視頻生成成功","task_id": task_id}elif status in ("failed", "canceled"):return {"success": False,"error": f"任務{status}"}return {"success": False,"error": "視頻生成超時"}except Exception as e:return {"success": False,"error": f"生成視頻時出錯: {str(e)}"}@mcp.tool()
def encode_image_to_base64(image_path: str) -> Dict[str, Any]:"""將本地圖片文件編碼為base64字符串Args:image_path: 圖片文件路徑Returns:包含base64編碼字符串或錯誤信息的字典"""try:with open(image_path, 'rb') as image_file:encoded_string = base64.b64encode(image_file.read()).decode('utf-8')return {"success": True,"base64_string": encoded_string,"message": "圖片編碼成功"}except Exception as e:return {"success": False,"error": f"編碼圖片失敗: {str(e)}"}@mcp.resource("config://models")
def get_available_models() -> str:"""獲取可用的AI模型列表"""models = {"text_to_image": ["doubao-seedream-3-0-t2i-250415"],"image_to_video": ["doubao-seedance-1-0-lite-i2v-250428"],"text_to_video": ["doubao-seedance-1-0-lite-t2v-250428"]}return f"可用模型列表: {models}"@mcp.resource("config://settings")
def get_server_settings() -> str:"""獲取服務器配置信息"""settings = {"base_url": BASE_URL,"api_key_set": bool(API_KEY),"supported_image_sizes": ["512x512", "768x768", "1024x1024", "1024x1792", "1792x1024"],"supported_video_ratios": ["16:9", "9:16", "1:1"],"max_video_duration": "10s"}return f"服務器配置: {settings}"def main():"""主函數入口點"""mcp.run(transport="stdio")if __name__ == "__main__":main()

包代碼開發

將您MCP server本地腳本打包,需要在doubao_mcp_server目錄新建一個文件__init__.py

init.py

from .doubao_mcp_server import main__all__ = ["main"]

本地測試

打包后測試可以將這個mcp server作為模塊來運行,而不是直接通過腳本運行。

# 以模塊運行
uv run -m mcp_ai_server

或者也可以在MCP 客戶端比如Cherry Studio上配置config測試

{"mcpServers": {"r-FY6A48OrPGz5fknShHt": {"name": "doubao-mcp-server","type": "stdio","description": "","isActive": true,"registryUrl": "https://pypi.tuna.tsinghua.edu.cn/simple","command": "uv","args": ["--directory","F:\\work\\code\\AIcode\\doubao_mcp_server","run","doubao-mcp-server.py"]}}

Cherry Studio上 界面配置

image-20250615113705259

點擊保存驗證一下,查看下工具列表

image-20250615113848740

看到這個說明可以在客戶端使用這個MCP-Server了。

作為一個包發布到PyPI

編寫pyproject.toml

您需要確保在您的項目根目錄,存在一個完整的pyproject.toml文件(在前面的步驟中應該已經自動生成)。這個文件的內容包括:

  • 包的元信息:名字、版本、描述、作者
  • 依賴項
  • 構建系統配置
  • MCP入口

pyproject.toml文件:

[project]
name = “doubao-mcp-server”
version = “0.1.0”
description = “主要實現的是火山引擎的提供的豆包文生圖、文生視頻、圖生視頻MCP-Server”
authors = [
{name = “wwzhouhui”,email = “75271002@qq.com”}
]
readme = “README.md”
requires-python = “>=3.13”
dependencies = [
“mcp[cli]>=1.9.4”, # 添加requests依賴
“requests>=2.31.0”,
“openai>=1.86.0”,
]

[project.scripts]
doubao-mcp-server = “doubao_mcp_server:main”

[build-system]
requires = [“hatchling”]
build-backend = “hatchling.build”

Python包創建一個README.md

這個地方我們省略

編譯打包

構建你Python包,這個地方我稍微講一下

cd  F:\work\code\AIcode\doubao_mcp_server
uv build

image-20250615115940544

image-20250615120014779

檢查打包文件

在dist/目錄下看見.whl和.tar.gz的兩個文件

image-20250615120057036

準備PyPI賬戶

我需要登錄PyPI官網:https://pypi.org/account/login/ 注冊一個賬號(如果之前沒有的話)

關于PyPI注冊比較麻煩,這里不做詳細展開。主要是注冊之后還需要微軟的Authenticator 手機上安裝,然后通過雙重身份驗證完成登錄

image-20250615122125953

image-20250615122157980

完整雙重身份驗證后,我們就可以實現打包文件上傳了。

image-20250615122337017

pypi api token創建

雙重身份驗證通過后,我們點擊“add api token” 創建一個api

image-20250615122644450

image-20250615122725171

image-20250615122807168

復制上面的token用記事本保存好。

上傳您的Python包

我們在命令行窗口輸入如下命令

uv publish --token  pypi-xxxxxx 

image-20250615123128330

我們去pypi 查看我們上傳的包

image-20250615123327343

打開view 我們就查看剛剛上傳的詳細的依賴包

image-20250615153449187

MCP客戶端測試

一旦發布完成, 用戶就可以通過uvx安裝和使用您的 MCP server。uvx會創建一個臨時環境,安裝依賴并執行這個包,非常的簡潔優雅。

接下來我們使用trae 來下載安裝我們剛才上傳的pypi依賴包

我們在trae 添加如下mcp-server配置

{"mcpServers": {"doubao-mcp-server": {"command": "uvx","args": ["doubao-mcp-server"],"env": {"DOUBAO_API_KEY": "your-api-key-here"}}}
}

配置完成后

image-20250615153553068

我們測試一下

image-20250615155831976

image-20250615155855206

image-20250615155932459

有點丑,不過確實已經弄個調用生產圖片了。

3.部署到魔搭MCP廣場

我們也可以把這個MCP部署到魔搭社區的MCP廣場上給大家使用。

  • 進入魔搭MCP廣場

    MCP廣場地址:modelscope.cn/mcp

    img

  • 基礎信息填寫

    創建類型:選擇“GitHub快速創建”

    英文名稱:英文MCP Server名字,

    中文名稱:中文MCP Server名字,

    來源地址:代碼我們已經上傳github地址:https://github.com/wwwzhouhui/doubao_mcp_server

    所有者:默認已填好

    托管類型:選擇“可托管部署”

    image-20250615172025838

完成部署

image-20250615174149106

上面填寫APIkey 就可以體驗了。按照下面填寫APIkey

image-20250615175744287

生成SSE URL 地址(上面地址有效期時間24個小時,也可以設置長期有效)

{"mcpServers": {"DoubaoMCPServer-MCP_Agent_Challenge": {"type": "sse","url": "https://mcp.api-inference.modelscope.net/aee3086059a34e/sse"}}
}

接下來我們也可以在魔搭的應用廣場上體驗了。我們點擊“試用” 就可以在魔搭社區免費體驗了。

image-20250615180327469

摩搭社區MCP應用廣場測試

進入應用廣場 輸入下面的提示詞

文生圖

給我畫一個 小白兔吃蘿卜

image-20250615180612926

image-20250615180819895

這樣我們在魔搭社區里面也可以使用我我們剛才部署打包的MCP-server了。

文生視頻

提示詞:給我生成一個小白兔吃蘿卜的視頻

image-20250615182331935

4.總結

今天主要帶大家了解并實現了基于豆包大模型 1.6 發布的文生圖、文生視頻、圖生視頻功能的 MCP-Server 本地化部署與發布方案。通過將 MCP Server 腳本打包為 Python 庫并發布至 PyPI,我們成功實現了可跨平臺調用的 AI 生成服務。借助火山引擎提供的文生圖、文生視頻、圖生視頻模型 API,我們構建了一個功能完整的 MCP-Server,支持通過文本描述生成高質量圖片和視頻內容。

通過本文的方案,開發者可以輕松搭建自己的文生圖、文生視頻、圖生視頻服務,為應用程序添加強大的 AI 生成能力。感興趣的小伙伴可以按照本文步驟去嘗試搭建自己的 MCP-Server。今天的分享就到這里結束了,我們下一篇文章見。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85289.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85289.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85289.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MCP Parameters 增加描述

場景:本地MCP開發完后是否發現CLINE上顯示的Parameters 顯示No description 方法1 :使用參數元數據 (Annotated) 可以使用 Pydantic 的with 類提供有關參數的其他元數據Annotated。這種方法更受歡迎,因為它更現代,并且將類型提示…

STM32 GPIO 寄存器開發

🔧 ?一、核心寄存器概覽? ?寄存器??功能??位寬??關鍵位域??GPIOx_CRL/CRH?配置引腳模式(輸入/輸出/復用/模擬)和輸出參數32位每4位控制1個引腳:CNF[1:0](模式) MODE[1:0](速度&am…

powershell 獲取 用戶及進程列表

在PowerShell中獲取用戶的進程列表,可以通過幾種方法實現。以下是一些常見的方法: 方法1:使用Get-WmiObject Get-WmiObject命令可以用來查詢Windows Management Instrumentation (WMI)數據庫,從而獲取關于進程和用戶的信息。 # …

量化面試綠皮書:15. 假幣一

文中內容僅限技術學習與代碼實踐參考,市場存在不確定性,技術分析需謹慎驗證,不構成任何投資建議。 15. 假幣一 有 10個袋子,每個袋子里有 100個相同的硬幣。 在除一個以外的所有袋子中,每枚硬幣重10 克。 然而&#x…

Java求職者面試:Spring AI、MCP、RAG、向量數據庫與Embedding模型技術解析

Java求職者面試:Spring AI、MCP、RAG、向量數據庫與Embedding模型技術解析 第一輪:基礎概念問題 1. 請解釋Spring AI是什么?它與傳統Spring框架有何不同? Spring AI是Spring生態系統的一部分,專注于人工智能和機器學…

tp框架導出excel的時候報錯:unexcepted identifier “Closure“,excepting variable

記錄一個簡單的錯誤。 背景 用的是PhpOffice/PhpSpreadsheet 在本地環境下是可以正常導出excel的。但是線上就不行。 就會報錯unexcepted identifier “Closure”,好像是不能用匿名函數。 首先 本地可以正常導出,然后服務器上不可以。看了各種日志。ph…

[Java惡補day24] 74. 搜索二維矩陣

給你一個滿足下述兩條屬性的 m x n 整數矩陣: 每行中的整數從左到右按非嚴格遞增順序排列。 每行的第一個整數大于前一行的最后一個整數。 給你一個整數 target ,如果 target 在矩陣中,返回 true ;否則,返回 false 。 …

解鎖VSCode:從入門到精通的全攻略

目錄 一、VSCode 初相識二、安裝與基礎設置2.1 下載安裝2.2 基礎設置三、核心功能深度剖析3.1 強大的代碼編輯3.2 高效的版本控制集成3.3 實用的調試工具四、插件擴展,拓展無限可能4.1 插件市場探秘4.2 必備插件推薦五、個性化定制,打造專屬開發環境5.1 快捷鍵設置5.2 用戶代…

RFC4291-IPv6地址架構

RFC4291 IP Version 6 Addressing Architecture Author:Once Day Date:2025年6月15日 本文翻譯自RFC 4291 - IP Version 6 Addressing Architecture 這篇文章總結了IPv6的基礎概念,屬于IPv6協議入門內容。 文章目錄 RFC4291 IP Version 6 …

基礎數據結構第03天:順序表(實戰篇)

目錄 求奇數的乘積 數值統計 青年歌手大獎賽_評委會打分 猜數字 拿硬幣 值相等的最小索引 最大連續1的個數 差的絕對值為K的數對數目 數組中兩元素的最大乘積 數組元素和與數字和的絕對差 K個元素的最大和 等差三元組的數目 移除元素 基于排列構建數組 數組串聯…

10.OpenCV—聯合QT界面顯示

1.顯示在graphicsView控件上 .h文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow>#include <QGraphicsPixmapItem> //1.聲明頭文件 namespace Ui { class MainWindow; }class MainWindow : public QMainWindow {Q_OBJECTpublic:explicit Ma…

ChromaDB深度技術研究報告

第一章: ChromaDB核心概念與架構 1.1 向量數據庫:新一代AI應用基石 向量數據庫是為存儲、管理和搜索向量嵌入(Vector Embeddings)而專門設計的數據庫系統。在高維空間中,向量嵌入是數據(如文本、圖片、音頻等)的數值表示。向量數據庫的核心能力在于,它能夠高效地執行相…

react 自定義狀態管理庫

核心實現原理 &#xff1a; 全局狀態容器&#xff1a;維護單一狀態源 訂閱機制&#xff1a;組件訂閱狀態變化 狀態更新調度&#xff1a;通過 Hooks 觸發組件重渲染 基礎版實現–核心代碼 // 1. 創建全局狀態存儲 const createStore (initialState) > {let state initial…

解決idea無法正常加載lombok包

問題 近期發現了一個問題&#xff0c;就是很多同學在導包的&#xff0c;lombok經常會爆紅&#xff0c;經過研究找到了解決方法。 解決 1、更改lombok包的版本 通過手動調整pom.xml文件的lombok&#xff0c;通常講版本調整為1.18.20&#xff0c;或者1.18.32。 <dependenc…

0_1樹和圖

樹的概念 樹(tree)是一種能夠分層存儲數據的重要數據結構,樹中的每個元素被稱為樹的節點,每個節點有若干個指針指向子節點。從節點的角度來看,樹是由唯一的起始節點引出的節點集合。這個起始結點稱為根(root)。樹中節點的子樹數目稱為節點的度(degree)。在面試中,關于樹的…

從0搭建出海 Demo:免費香港服務器實戰指南

你有沒有在通勤地鐵上、午飯后摸魚時&#xff0c;突然冒出一個想法&#xff1a;“要不我也做個應用試試&#xff1f;好像不少人靠這個補貼生活開銷啊&#xff01;” 結果隨手搜了幾篇“海外項目經驗分享”&#xff0c;瞬間被一堆術語勸退&#xff1a;CDN、備案、分發平臺、服務…

《仿盒馬》app開發技術分享--未完成訂單列表展示邏輯優化(61)

技術棧 Appgallery connect 前言&#xff1a; 上一節我們實現訂單與優惠券的聯合提交時&#xff0c;我去到訂單列表頁面查看生成的訂單信息&#xff0c;發現現在的訂單從信息展示到價格計算全都是有問題的。所以緊急的把對應的問題修改一下。 問題來源&#xff1a; async …

手搓多模態-08 主模型的搭建(上)

前情回顧 在之前的章節我們已經構建好了視覺編碼器&#xff0c;預處理模塊&#xff0c;以及gemma模型的頂層。gemma模型的頂層&#xff0c;主要是構建圖中圈出的輸入&#xff0c;它把視覺編碼器里每個圖像patch的編碼維度對齊到自然語言token的嵌入維度&#xff0c;并組裝成了一…

Matlab 角點探測

文章目錄 一、簡介二、實現代碼三、實現效果一、簡介 這里實現一種角點探測功能,其思路仍然是借助圖像的局部梯度信息,實現亞像素精度的角點定位。該功能核心思想是利用角點周圍的局部梯度信息,通過加權最小二乘優化的方式迭代調整角點位置,使定位精度達到亞像素級別。整個…

錯誤監控----比如實現sentry一些思路

錯誤監控 ?、引? 1.為什么需要前端錯誤監控 你的腳本在哪些邊界條件下會報錯&#xff1f; 你的腳本和樣式兼容性如何&#xff1f; 有哪些地區不能正常訪問你的?站&#xff1f; 出現問題之后&#xff0c;你如何快速定位排查&#xff0c;把損失降到最低&#xff1f; 如果你想解…