yzsd-image 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/PUBLISH.md ADDED
@@ -0,0 +1,138 @@
1
+ # 发布到 npm 的步骤
2
+
3
+ ## 发布前准备
4
+
5
+ 1. **确保你有 npm 账号**
6
+ ```bash
7
+ npm login
8
+ ```
9
+
10
+ 2. **启用双因素认证 (2FA)**
11
+ - 访问 https://www.npmjs.com/settings/[你的用户名]/tfa
12
+ - 启用 2FA (使用 Google Authenticator 或其他 2FA 应用)
13
+ - npm 现在要求所有发布者启用 2FA
14
+
15
+ 3. **检查 package.json 中的信息**
16
+ - 确认 `name` 是唯一的(可以先在 npmjs.com 搜索)
17
+ - 填写 `author` 字段
18
+ - 确认 `version` 号
19
+
20
+ 4. **测试构建**
21
+ ```bash
22
+ npm run build
23
+ ```
24
+
25
+ ## 发布步骤
26
+
27
+ ```bash
28
+ cd D:\Workspace\Projects+++++\yzsd-image\yzsd-image
29
+
30
+ # 登录 npm (如果还没登录)
31
+ npm login
32
+
33
+ # 发布到 npm
34
+ npm publish
35
+ ```
36
+
37
+ ## 发布后使用
38
+
39
+ 用户可以通过以下方式使用:
40
+
41
+ ### 方式 1: npx (推荐,无需安装)
42
+
43
+ 在 Claude Desktop 配置文件中添加:
44
+
45
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
46
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
47
+
48
+ ```json
49
+ {
50
+ "mcpServers": {
51
+ "yzsd-image": {
52
+ "command": "npx",
53
+ "args": ["-y", "yzsd-image"],
54
+ "env": {
55
+ "YZSD_API_KEY": "your-api-key-here"
56
+ }
57
+ }
58
+ }
59
+ }
60
+ ```
61
+
62
+ ### 方式 2: 全局安装
63
+
64
+ ```bash
65
+ npm install -g yzsd-image
66
+ ```
67
+
68
+ 然后配置:
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "yzsd-image": {
74
+ "command": "yzsd-image",
75
+ "env": {
76
+ "YZSD_API_KEY": "your-api-key-here"
77
+ }
78
+ }
79
+ }
80
+ }
81
+ ```
82
+
83
+ ## 更新版本
84
+
85
+ 修改代码后发布新版本:
86
+
87
+ ```bash
88
+ # 更新补丁版本 (1.0.0 -> 1.0.1)
89
+ npm version patch
90
+
91
+ # 更新次版本 (1.0.0 -> 1.1.0)
92
+ npm version minor
93
+
94
+ # 更新主版本 (1.0.0 -> 2.0.0)
95
+ npm version major
96
+
97
+ # 发布
98
+ npm publish
99
+ ```
100
+
101
+ ## 项目结构说明
102
+
103
+ ```
104
+ yzsd-image/
105
+ ├── src/
106
+ │ └── index.ts # MCP server 主文件
107
+ ├── dist/ # 编译后的文件 (npm 发布这个)
108
+ │ └── index.js
109
+ ├── package.json # npm 配置
110
+ ├── tsconfig.json # TypeScript 配置
111
+ ├── README.md # 使用文档
112
+ ├── .gitignore
113
+ └── .npmignore
114
+ ```
115
+
116
+ ## 功能说明
117
+
118
+ ### 提供的 MCP 工具
119
+
120
+ 1. **generate_image** - 文生图
121
+ - prompt: 图片描述
122
+ - aspectRatio: 宽高比 (1:1, 16:9, 9:16, 等)
123
+ - size: 分辨率 (1K, 2K, 4K)
124
+ - outputPath: 输出路径
125
+
126
+ 2. **edit_image** - 图生图编辑
127
+ - inputPath: 输入图片路径
128
+ - prompt: 编辑描述
129
+ - aspectRatio: 输出宽高比
130
+ - outputPath: 输出路径
131
+
132
+ ### API 端点
133
+
134
+ 连接到: `https://token.1001xr.asia:8443`
135
+
136
+ API 端点:
137
+ - `/v1/images/generate` - 生成图片
138
+ - `/v1/images/edit` - 编辑图片
package/README.md ADDED
@@ -0,0 +1,146 @@
1
+ # yzsd-image
2
+
3
+ MCP server for YZSD AI image generation. Generate and edit images using AI through the Model Context Protocol.
4
+
5
+ ## Features
6
+
7
+ - **Text-to-Image**: Generate images from text descriptions
8
+ - **Image-to-Image**: Edit existing images with AI
9
+ - **Multiple Aspect Ratios**: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 21:9, 5:4, 4:5
10
+ - **3 Resolution Levels**: 1K (fast), 2K (recommended), 4K (high quality)
11
+ - **MCP Compatible**: Works with Claude Desktop, Cline, and other MCP clients
12
+
13
+ ## Installation
14
+
15
+ ### Using npx (Recommended)
16
+
17
+ No installation needed! Configure directly in your MCP client:
18
+
19
+ ```json
20
+ {
21
+ "mcpServers": {
22
+ "yzsd-image": {
23
+ "command": "npx",
24
+ "args": ["-y", "yzsd-image"],
25
+ "env": {
26
+ "YZSD_API_KEY": "your-api-key-here"
27
+ }
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ ### Global Installation
34
+
35
+ ```bash
36
+ npm install -g yzsd-image
37
+ ```
38
+
39
+ Then configure:
40
+
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "yzsd-image": {
45
+ "command": "yzsd-image",
46
+ "env": {
47
+ "YZSD_API_KEY": "your-api-key-here"
48
+ }
49
+ }
50
+ }
51
+ }
52
+ ```
53
+
54
+ ## Configuration
55
+
56
+ ### Claude Desktop
57
+
58
+ Edit your Claude Desktop config file:
59
+
60
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
61
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
62
+
63
+ Add:
64
+
65
+ ```json
66
+ {
67
+ "mcpServers": {
68
+ "yzsd-image": {
69
+ "command": "npx",
70
+ "args": ["-y", "yzsd-image"],
71
+ "env": {
72
+ "YZSD_API_KEY": "your-api-key-here"
73
+ }
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ ### Cline (VS Code Extension)
80
+
81
+ Add to your Cline MCP settings:
82
+
83
+ ```json
84
+ {
85
+ "yzsd-image": {
86
+ "command": "npx",
87
+ "args": ["-y", "yzsd-image"],
88
+ "env": {
89
+ "YZSD_API_KEY": "your-api-key-here"
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ ## Usage
96
+
97
+ Once configured, you can use the tools in your MCP client:
98
+
99
+ ### Generate Image
100
+
101
+ ```
102
+ Generate a beautiful landscape image with mountains and sunset, 16:9 aspect ratio, 2K resolution
103
+ ```
104
+
105
+ The MCP server provides the `generate_image` tool with parameters:
106
+ - `prompt` (required): Text description
107
+ - `aspectRatio` (optional): Default "1:1"
108
+ - `size` (optional): "1K", "2K", or "4K", default "2K"
109
+ - `outputPath` (optional): Where to save the image
110
+
111
+ ### Edit Image
112
+
113
+ ```
114
+ Edit the image at ./photo.jpg, change the background to a beach scene
115
+ ```
116
+
117
+ The MCP server provides the `edit_image` tool with parameters:
118
+ - `inputPath` (required): Path to input image
119
+ - `prompt` (required): Edit description
120
+ - `aspectRatio` (optional): Default "1:1"
121
+ - `outputPath` (optional): Where to save edited image
122
+
123
+ ## API Endpoint
124
+
125
+ This MCP server connects to: `https://token.1001xr.asia:8443`
126
+
127
+ ## Development
128
+
129
+ ```bash
130
+ # Clone the repository
131
+ git clone <your-repo-url>
132
+ cd yzsd-image
133
+
134
+ # Install dependencies
135
+ npm install
136
+
137
+ # Build
138
+ npm run build
139
+
140
+ # Test locally
141
+ node dist/index.js
142
+ ```
143
+
144
+ ## License
145
+
146
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
+ import axios from "axios";
6
+ import * as fs from "fs/promises";
7
+ import * as path from "path";
8
+ const API_BASE_URL = "https://token.1001xr.asia:8443";
9
+ const VALID_ASPECT_RATIOS = [
10
+ "1:1", "16:9", "9:16", "4:3", "3:4",
11
+ "3:2", "2:3", "21:9", "5:4", "4:5"
12
+ ];
13
+ const VALID_SIZES = ["1K", "2K", "4K"];
14
+ class YZSDImageServer {
15
+ server;
16
+ apiKey;
17
+ constructor() {
18
+ this.server = new Server({
19
+ name: "yzsd-image",
20
+ version: "1.0.0",
21
+ }, {
22
+ capabilities: {
23
+ tools: {},
24
+ },
25
+ });
26
+ this.apiKey = process.env.YZSD_API_KEY;
27
+ this.setupHandlers();
28
+ }
29
+ setupHandlers() {
30
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
31
+ tools: this.getTools(),
32
+ }));
33
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
34
+ const { name, arguments: args } = request.params;
35
+ try {
36
+ switch (name) {
37
+ case "generate_image":
38
+ return await this.handleGenerateImage(args);
39
+ case "edit_image":
40
+ return await this.handleEditImage(args);
41
+ default:
42
+ throw new Error(`Unknown tool: ${name}`);
43
+ }
44
+ }
45
+ catch (error) {
46
+ const errorMessage = error instanceof Error ? error.message : String(error);
47
+ return {
48
+ content: [
49
+ {
50
+ type: "text",
51
+ text: `Error: ${errorMessage}`,
52
+ },
53
+ ],
54
+ isError: true,
55
+ };
56
+ }
57
+ });
58
+ }
59
+ getTools() {
60
+ return [
61
+ {
62
+ name: "generate_image",
63
+ description: "Generate an AI image from text prompt using YZSD API. Supports multiple aspect ratios (1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 21:9, 5:4, 4:5) and resolutions (1K, 2K, 4K).",
64
+ inputSchema: {
65
+ type: "object",
66
+ properties: {
67
+ prompt: {
68
+ type: "string",
69
+ description: "Text description of the image to generate",
70
+ },
71
+ aspectRatio: {
72
+ type: "string",
73
+ description: "Aspect ratio for the image (default: 1:1)",
74
+ enum: VALID_ASPECT_RATIOS,
75
+ },
76
+ size: {
77
+ type: "string",
78
+ description: "Resolution size: 1K (fast), 2K (recommended), 4K (high quality)",
79
+ enum: VALID_SIZES,
80
+ },
81
+ outputPath: {
82
+ type: "string",
83
+ description: "Output file path (default: ./output.png)",
84
+ },
85
+ apiKey: {
86
+ type: "string",
87
+ description: "YZSD API key (optional, can use YZSD_API_KEY env var)",
88
+ },
89
+ },
90
+ required: ["prompt"],
91
+ },
92
+ },
93
+ {
94
+ name: "edit_image",
95
+ description: "Edit an existing image using AI based on text prompt. Upload a local image and describe the modifications you want.",
96
+ inputSchema: {
97
+ type: "object",
98
+ properties: {
99
+ inputPath: {
100
+ type: "string",
101
+ description: "Path to the input image file",
102
+ },
103
+ prompt: {
104
+ type: "string",
105
+ description: "Description of how to edit the image",
106
+ },
107
+ aspectRatio: {
108
+ type: "string",
109
+ description: "Output aspect ratio (default: 1:1)",
110
+ enum: VALID_ASPECT_RATIOS,
111
+ },
112
+ outputPath: {
113
+ type: "string",
114
+ description: "Output file path (default: ./edited.png)",
115
+ },
116
+ apiKey: {
117
+ type: "string",
118
+ description: "YZSD API key (optional, can use YZSD_API_KEY env var)",
119
+ },
120
+ },
121
+ required: ["inputPath", "prompt"],
122
+ },
123
+ },
124
+ ];
125
+ }
126
+ resolveApiKey(providedKey) {
127
+ const key = providedKey || this.apiKey;
128
+ if (!key) {
129
+ throw new Error("API key not found. Set YZSD_API_KEY environment variable or provide apiKey parameter.");
130
+ }
131
+ return key;
132
+ }
133
+ async handleGenerateImage(args) {
134
+ const { prompt, aspectRatio = "1:1", size = "2K", outputPath = "./output.png", apiKey, } = args;
135
+ const key = this.resolveApiKey(apiKey);
136
+ if (!VALID_ASPECT_RATIOS.includes(aspectRatio)) {
137
+ throw new Error(`Invalid aspect ratio. Must be one of: ${VALID_ASPECT_RATIOS.join(", ")}`);
138
+ }
139
+ if (!VALID_SIZES.includes(size)) {
140
+ throw new Error(`Invalid size. Must be one of: ${VALID_SIZES.join(", ")}`);
141
+ }
142
+ const response = await axios.post(`${API_BASE_URL}/v1/images/generate`, {
143
+ prompt,
144
+ aspect_ratio: aspectRatio,
145
+ size,
146
+ }, {
147
+ headers: {
148
+ "Authorization": `Bearer ${key}`,
149
+ "Content-Type": "application/json",
150
+ },
151
+ timeout: size === "4K" ? 120000 : size === "2K" ? 60000 : 30000,
152
+ });
153
+ const imageData = response.data.image || response.data.data?.[0]?.b64_json;
154
+ if (!imageData) {
155
+ throw new Error("No image data in response");
156
+ }
157
+ const buffer = Buffer.from(imageData, "base64");
158
+ const outputDir = path.dirname(outputPath);
159
+ await fs.mkdir(outputDir, { recursive: true });
160
+ await fs.writeFile(outputPath, buffer);
161
+ return {
162
+ content: [
163
+ {
164
+ type: "text",
165
+ text: `✓ Image generated successfully\n\nPrompt: ${prompt}\nAspect Ratio: ${aspectRatio}\nSize: ${size}\nOutput: ${outputPath}`,
166
+ },
167
+ ],
168
+ };
169
+ }
170
+ async handleEditImage(args) {
171
+ const { inputPath, prompt, aspectRatio = "1:1", outputPath = "./edited.png", apiKey, } = args;
172
+ const key = this.resolveApiKey(apiKey);
173
+ if (!VALID_ASPECT_RATIOS.includes(aspectRatio)) {
174
+ throw new Error(`Invalid aspect ratio. Must be one of: ${VALID_ASPECT_RATIOS.join(", ")}`);
175
+ }
176
+ const imageBuffer = await fs.readFile(inputPath);
177
+ const base64Image = imageBuffer.toString("base64");
178
+ const response = await axios.post(`${API_BASE_URL}/v1/images/edit`, {
179
+ image: base64Image,
180
+ prompt,
181
+ aspect_ratio: aspectRatio,
182
+ }, {
183
+ headers: {
184
+ "Authorization": `Bearer ${key}`,
185
+ "Content-Type": "application/json",
186
+ },
187
+ timeout: 120000,
188
+ });
189
+ const imageData = response.data.image || response.data.data?.[0]?.b64_json;
190
+ if (!imageData) {
191
+ throw new Error("No image data in response");
192
+ }
193
+ const buffer = Buffer.from(imageData, "base64");
194
+ const outputDir = path.dirname(outputPath);
195
+ await fs.mkdir(outputDir, { recursive: true });
196
+ await fs.writeFile(outputPath, buffer);
197
+ return {
198
+ content: [
199
+ {
200
+ type: "text",
201
+ text: `✓ Image edited successfully\n\nInput: ${inputPath}\nPrompt: ${prompt}\nAspect Ratio: ${aspectRatio}\nOutput: ${outputPath}`,
202
+ },
203
+ ],
204
+ };
205
+ }
206
+ async run() {
207
+ const transport = new StdioServerTransport();
208
+ await this.server.connect(transport);
209
+ console.error("YZSD Image MCP Server running on stdio");
210
+ }
211
+ }
212
+ const server = new YZSDImageServer();
213
+ server.run().catch(console.error);
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "yzsd-image",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for YZSD AI image generation",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "yzsd-image": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "prepare": "npm run build",
13
+ "start": "node dist/index.js"
14
+ },
15
+ "keywords": [
16
+ "mcp",
17
+ "ai",
18
+ "image-generation",
19
+ "yzsd"
20
+ ],
21
+ "author": "",
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "@modelcontextprotocol/sdk": "^1.0.4",
25
+ "axios": "^1.7.9"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^22.10.5",
29
+ "typescript": "^5.7.3"
30
+ },
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ }
34
+ }