实现一个免费可用的文生图的MCP Server

概述

  • 文生图模型为使用 Cloudflare Worker AI 部署 Flux 模型,是参照视频https://www.bilibili.com/video/BV1UbkcYcE24/?spm_id_from=333.337.search-card.all.click&vd_source=9ca2da6b1848bc903db417c336f9cb6b的复现
  • Cursor MCP Server实现是参照文章https://juejin.cn/post/7485267450880229402#heading-9实现

Cloudflare部署 Flux 模型

获取Cloudflare账号和token

  • 注册、登录等步骤省略

管理账号——账户API令牌——Workers AI——使用模版
在这里插入图片描述
继续以显示摘要
在这里插入图片描述
创建令牌
在这里插入图片描述

找到文生图模型github地址

Workers AI——模型——flux-1-schnell——了解更多

在这里插入图片描述
Guides——Tutorials——How to Build an Image Generator using Workers AI
在这里插入图片描述

https://developers.cloudflare.com/workers-ai/guides/tutorials/image-generation-playground/image-generator-flux/
在这里插入图片描述

在这里插入图片描述

部署文生图模型

github地址

https://github.com/kristianfreeman/workers-ai-image-playground?tab=readme-ov-file#readme

执行顺序:

  1. git clone到本地
  2. 修改配置文件
  • 将.dev.vars.example改为.dev.vars
  • 替换CLOUDFLARE_ACCOUNT_ID(账号)和CLOUDFLARE_API_TOKEN(令牌)


3. 执行npm install
4. 执行npm run preview(生产为preview)
在这里插入图片描述
在这里插入图片描述
5. 打开网页(http://localhost:8788),选择flux-1-schnell

在这里插入图片描述

输入prompt进行测试
在这里插入图片描述

Cursor调用MCP Server

实现一个调用Cloudflare Workers AI模型的MCP Server

参照文章(https://juejin.cn/post/7485267450880229402#heading-9)进行项目设置

项目设置

让我们从创建项目和安装依赖开始:

mkdir mcp-image-generator
cd mcp-image-generator
npm init -y
npm install @modelcontextprotocol/sdk zod dotenv
npm install --save-dev typescript @types/node

接下来,创建一个基本的TypeScript配置文件。在项目根目录创建tsconfig.json:

{"compilerOptions": {"target": "ES2020","module": "NodeNext","moduleResolution": "NodeNext","esModuleInterop": true,"outDir": "./dist","strict": true},"include": ["src/**/*"]
}

然后,创建一个.env文件来存储你的Cloudflare凭证:
ini 体验AI代码助手 代码解读复制代码CLOUDFLARE_ACCOUNT_ID=你的账户ID
CLOUDFLARE_API_TOKEN=你的API令牌

别忘了将这个文件添加到.gitignore,保护你的API密钥不被意外公开。

构建MCP服务器

直接替换src/index.ts文件

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import fs from 'fs';
import path from 'path';
import os from 'os';
import * as dotenv from 'dotenv';// 加载环境变量
dotenv.config();// 创建MCP服务器
const server = new McpServer({name: "AI图片生成助手",version: "1.0.0"
});// 添加一个文生图工具
server.tool("generate-image-from-text","使用Cloudflare的Flux模型生成图像",{prompt: z.string().min(1, "提示文本不能为空").max(2048, "提示文本不能超过2048个字符").describe("用于生成图像的文本描述"),steps: z.number().int("步数必须是整数").max(8, "步数最大为8").default(4).describe("扩散步数,值越高质量越好但耗时更长"),outputPath: z.string().min(1, "输出路径不能为空").describe("生成图片的保存目录路径"),filename: z.string().min(1, "文件名不能为空").describe("保存的图片文件名,不需要包含扩展名")},async ({ prompt, steps = 4, outputPath, filename }) => {const CLOUDFLARE_ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID;const CLOUDFLARE_API_TOKEN = process.env.CLOUDFLARE_API_TOKEN;const url = `https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/ai/run/@cf/black-forest-labs/flux-1-schnell`;console.log(url);try {// 调用Cloudflare APIconst response = await fetch(url, {method: 'POST',headers: {'Authorization': `Bearer ${CLOUDFLARE_API_TOKEN}`,'Content-Type': 'application/json'},body: JSON.stringify({prompt: prompt})});// 解析响应const responseData = await response.json() as { image?: string;[key: string]: unknown };if (!response.ok) {return {content: [{ type: "text", text: `调用API失败: ${response.status} ${response.statusText}` }]};}// 提取图像数据let imageBase64 = null;if (responseData.image) {imageBase64 = responseData.image as string;} else if (responseData.result && typeof responseData.result === 'object') {const resultObj = responseData.result as Record<string, unknown>;if (resultObj.image) {imageBase64 = resultObj.image as string;} else if (resultObj.data) {imageBase64 = resultObj.data as string;}}if (!imageBase64) {return {content: [{ type: "text", text: "API返回的数据中没有图像" }]};}// 图像处理逻辑将在下一步添加// 保存图像文件let targetFilePath = path.join(outputPath, `${filename}.jpg`);let actualSavePath = targetFilePath;let message = '';try {// 确保输出目录存在if (!fs.existsSync(outputPath)) {fs.mkdirSync(outputPath, { recursive: true });}// 测试目录是否可写const testFileName = path.join(outputPath, '.write-test');fs.writeFileSync(testFileName, '');fs.unlinkSync(testFileName);// 将Base64图像保存为文件const imageBuffer = Buffer.from(imageBase64, 'base64');fs.writeFileSync(targetFilePath, imageBuffer);message = `图像已成功生成并保存到: ${targetFilePath}`;} catch (fileError) {// 备用方案:保存到临时目录const tempDir = path.join(os.tmpdir(), 'mcp_generated_images');if (!fs.existsSync(tempDir)) {fs.mkdirSync(tempDir, { recursive: true });}actualSavePath = path.join(tempDir, `${filename}.jpg`);const imageBuffer = Buffer.from(imageBase64, 'base64');fs.writeFileSync(actualSavePath, imageBuffer);message = `由于权限问题无法保存到 ${targetFilePath},已保存到临时位置: ${actualSavePath}`;}return {content: [{ type: "text", text: message }]};} catch (error: unknown) {const errorMessage = error instanceof Error ? error.message : String(error);return {content: [{ type: "text", text: `发生错误: ${errorMessage}` }]};}
}
);// 启动服务器
const transport = new StdioServerTransport();
await server.connect(transport);
编译和运行

在package.json中添加以下脚本:

"scripts": {"build": "tsc","start": "node dist/index.js"
}

然后编译并运行你的服务器:

npm run build
在Cursor中配置MCP服务

在这里插入图片描述
在这里插入图片描述

{"mcpServers": {"imageGenerator": {"command": "node","args": ["/Users/admin/Desktop/work/study/mcp-image-generator/dist/index.js" # 替换为你的路径]}}
}

重启Cursor使配置生效

测试效果

输入

Please generate a picture of an animal fox and save it to the directory /Users/admin/Desktop/work/study/mcp-image-generator/pictures with the filename fox.

在这里插入图片描述
Run tool,查看图片
在这里插入图片描述

参考

https://juejin.cn/post/7485267450880229402
https://www.cnblogs.com/foxhank/p/18378208
https://github.com/fengin/image-gen-server?tab=readme-ov-file
https://cursor.directory/mcp
https://zhuanlan.zhihu.com/p/27327515233
https://blog.csdn.net/m0_65096391/article/details/147570383

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/83055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ES6 深克隆与浅克隆详解:原理、实现与应用场景

ES6 深克隆与浅克隆详解&#xff1a;原理、实现与应用场景 一、克隆的本质与必要性 在 JavaScript 中&#xff0c;数据分为两大类型&#xff1a; 基本类型&#xff1a;Number、String、Boolean、null、undefined、Symbol、BigInt引用类型&#xff1a;Object、Array、Functio…

新闻数据加载(鸿蒙App开发实战)

本案例基于ArkTS的声明式开发范式&#xff0c;介绍了数据请求和onTouch事件的使用。包含以下功能&#xff1a; 数据请求。列表下拉刷新。列表上拉加载。 网络数据请求需要权限&#xff1a;ohos.permission.INTERNET 一、案例效果截图 操作说明&#xff1a; 点击应用进入主页…

办公效率王Word批量转PDF 50 +文档一键转换保留原格式零错乱

各位办公小能手们&#xff0c;我跟你们说啊&#xff01;在办公的时候&#xff0c;咱经常会碰到要把一堆Word文档转成PDF格式的情况&#xff0c;比如说要统一文件格式、保护文档内容或者方便分享啥的。这时候&#xff0c;就需要用到Word批量转换成PDF的软件啦。下面我就给你们好…

一张Billing项目的流程图

流程图 工作记录 2016-11-11 序号 工作 相关人员 1 修改Payment Posted的导出。 Claim List的页面加了导出。 Historical Job 加了Applied的显示和详细。 郝 识别引擎监控 Ps (iCDA LOG :剔除了160篇ASG_BLANK之后的结果): LOG_File 20161110.txt BLANK_CDA/ALL 45/10…

SpringAI系列4: Tool Calling 工具调用 【感觉这版本有bug】

前言&#xff1a;在最近发布的 Spring AI 1.0.0.M6 版本中&#xff0c;其中一个重大变化是 Function Calling 被废弃&#xff0c;被 Tool Calling 取代。Tool Calling工具调用&#xff08;也称为函数调用&#xff09;是AI应用中的常见模式&#xff0c;允许模型通过一组API或工具…

第六十三节:深度学习-模型推理与后处理

深度学习模型训练完成后,如何高效地将其部署到实际应用中并进行准确预测?这正是模型推理与后处理的核心任务。OpenCV 的 dnn 模块为此提供了强大支持,本文将深入探讨 OpenCV 在深度学习模型推理与后处理中的关键技术与实践。 第一部分:基础概念与环境搭建 1.1 核心概念解析…

uniapp开发企业微信小程序时 wx.qy.login 在uniapp中使用的时候,需要导包吗?

在 UniApp 中使用 “wx.qy.login” 不需要手动导包&#xff0c;但需要满足以下条件&#xff1a; 一、环境要求与配置 1&#xfffd; 企业微信环境判断 必须确保当前运行环境是企业微信客户端&#xff0c;通过 “uni.getSystemInfoSync().environment” 判断是否为 “wxwork”…

ONLYOFFICE文档API:更强的安全功能

在数字化办公时代&#xff0c;文档的安全性与隐私保护已成为企业和个人用户的核心关切。如何确保信息在存储、传输及协作过程中的安全&#xff0c;是开发者与IT管理者亟需解决的问题。ONLYOFFICE作为一款功能强大的开源办公套件&#xff0c;不仅提供了高效的文档编辑与协作体验…

Linux系统编程之共享内存

概述 在Linux系统中&#xff0c;共享内存也是一种高效的进程间通信机制&#xff0c;允许两个或多个进程共享同一块物理内存区域。通过这种方式&#xff0c;不同进程可以直接访问和操作相同的数据&#xff0c;从而避免了数据的复制。由于数据直接在内存中共享&#xff0c;没有额…

零知开源——STM32F407VET6驱动Flappy Bird游戏教程

简介 本教程使用STM32F407VET6零知增强板驱动3.5寸TFT触摸屏实现经典Flappy Bird游戏。通过触摸屏控制小鸟跳跃&#xff0c;躲避障碍物柱体&#xff0c;挑战最高分。项目涉及STM32底层驱动、图形库移植、触摸控制和游戏逻辑设计。 目录 简介 一、硬件准备 二、软件架构 三、…

Elasticsearch创建快照仓库报错处理

创建快照仓库报错&#xff1a; 根据报错提示的信息&#xff0c;问题可能出在 Elasticsearch 的配置中。当你尝试创建一个文件系统&#xff08;fs&#xff09;类型的快照仓库时&#xff0c;虽然已经指定了 location 参数&#xff0c;但 Elasticsearch 仍然报错&#xff0c;这通…

服务器如何配置防火墙管理端口访问?

配置服务器防火墙来管理端口访问&#xff0c;是保障云服务器安全的核心步骤。下面我将根据你使用的不同操作系统&#xff08;Linux: Ubuntu/Debian/CentOS&#xff1b;Windows Server&#xff09;介绍常用防火墙配置方法。 ✅ 一、Linux 防火墙配置&#xff08;UFW / firewalld…

Redis最佳实践——安全与稳定性保障之连接池管理详解

Redis 在电商应用的连接池管理全面详解 一、连接池核心原理与架构 1. 连接池工作模型 #mermaid-svg-G7I3ukCljlJZAXaA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-G7I3ukCljlJZAXaA .error-icon{fill:#552222;}…

打印机无法远程打印?可以本地打印,本地网络打印机设置给异地使用

很多小伙伴常有打印、远程打印的需求&#xff0c;特别是对于电商人、跨境电商、教师、产品经理、实验人员等群体来说掌握这项技能可谓是能够在很多场景下带来便捷&#xff0c;大幅提升做事效率&#xff01;打印机是家庭和企业经常用到的设备&#xff0c;很多情况下会遇到本地可…

【Linux】进程地址空间揭秘(初步认识)

10.进程地址空间&#xff08;初步认识&#xff09; 文章目录 10.进程地址空间&#xff08;初步认识&#xff09;一、进程地址空间的实验现象解析二、进程地址空间三、虚拟内存管理补充&#xff1a;数据的写时拷贝&#xff08;浅谈&#xff09;补充&#xff1a;页表&#xff08;…

深入探讨redis:主从复制

前言 如果某个服务器程序&#xff0c;只部署在一个物理服务器上就可能会面临一下问题(单点问题) 可用性问题&#xff0c;如果这个机器挂了&#xff0c;那么对应的客户端服务也相继断开性能/支持的并发量有限 所以为了解决这些问题&#xff0c;就要引入分布式系统&#xff0c…

MacOS安装Docker Desktop并汉化

1. 安装Docker Desktop 到Docker Desktop For Mac下载对应系统的Docker Desktop 安装包&#xff0c;下载后安装&#xff0c;没有账号需要注册&#xff0c;然后登陆即可。 2. 汉化 前往汉化包下载链接下载对应系统的.asar文件 然后将安装好的文件覆盖原先的文件app.asar文件…

索引的选择与Change Buffer

1. 索引选择与Change Buffer 问题引出&#xff1a;普通索引 vs 唯一索引 ——如何选择&#xff1f; 在实际业务中&#xff0c;如果一个字段的值天然具有唯一性&#xff08;如身份证号&#xff09;&#xff0c;并且业务代码已确保无重复写入&#xff0c;那就存在两种选择&…

lua注意事项

感觉是lua的一大坑啊&#xff0c;它还不如函数内部就局部变量呢 注意函数等内部&#xff0c;全部给加上local得了

【多线程初阶】死锁的产生 如何避免死锁

文章目录 关于死锁一.死锁的三种情况1.一个线程,一把锁,连续多次加锁2.两个线程,两把锁3.N个线程,M把锁 --哲学家就餐问题 二.如何避免死锁死锁是如何构成的(四个必要条件)打破死锁 三.死锁小结 关于死锁 一.死锁的三种情况 1.一个线程,一把锁,连续多次加锁 -->由synchroni…