carmate-image-mcp 0.0.0-stage → 1.3.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,248 @@
1
- # Temporary Holding Version
1
+ # Carmate Image MCP服务器
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Carmate Image(Model Context Protocol)服务器,基于智谱 GLM-Image 国产视觉模型提供文生图功能的MCP工具。
4
+
5
+ ## 功能特性
6
+
7
+ - ✅ **文生图**:根据文本描述生成图片,支持多种尺寸和批量生成
8
+ - ✅ **GLM-Image 直连**:直连智谱开放平台 GLM-Image 国产生图模型
9
+ - 📥 **自动下载**:生成的图片自动下载到本地
10
+ - ⏱️ **智能轮询**:每5秒轮询一次任务状态,避免频繁请求
11
+ - 🛡️ **错误重试**:网络错误自动重试(最多3次)
12
+ - 📊 **详细日志**:日志输出到stderr,不污染MCP协议流
13
+
14
+ ## 快速开始
15
+
16
+ ### 方法一:使用 Claude Code CLI(推荐)
17
+
18
+ 如果您使用 Claude Code CLI,可以直接运行以下命令进行安装:
19
+
20
+ ```bash
21
+ claude mcp add carmate-image-mcp npx --env ZHIPU_API_KEY=<your_api_key> -- -y carmate-image-mcp
22
+ ```
23
+
24
+ 将 `<your_api_key>` 替换为您的智谱开放平台 API 密钥。
25
+
26
+ ### 方法二:使用 npx(Claude Desktop)
27
+
28
+ 无需安装,直接使用 npx 运行。在Claude Desktop的配置文件中添加:
29
+
30
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
31
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
32
+
33
+ ```json
34
+ {
35
+ "mcpServers": {
36
+ "carmate-image": {
37
+ "command": "npx",
38
+ "args": ["-y", "carmate-image-mcp"],
39
+ "env": {
40
+ "ZHIPU_API_KEY": "your_api_key_here"
41
+ }
42
+ }
43
+ }
44
+ }
45
+ ```
46
+
47
+ ### 方法三:本地开发
48
+
49
+ 如果您想修改代码或进行本地开发:
50
+
51
+ ```bash
52
+ # 克隆项目
53
+ git clone <your-repo-url>
54
+ cd carmate-image-mcp
55
+
56
+ # 安装依赖
57
+ npm install
58
+
59
+ # 构建项目
60
+ npm run build
61
+ ```
62
+
63
+ 然后在Claude Desktop配置中使用本地版本:
64
+
65
+ ```json
66
+ {
67
+ "mcpServers": {
68
+ "carmate-image": {
69
+ "command": "node",
70
+ "args": ["/absolute/path/to/carmate-image-mcp/dist/index.js"],
71
+ "env": {
72
+ "ZHIPU_API_KEY": "your_api_key_here"
73
+ }
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ ### 环境变量说明
80
+
81
+ 创建 `.env` 文件或设置环境变量:
82
+
83
+ ```bash
84
+ # 必需:智谱开放平台API密钥
85
+ ZHIPU_API_KEY=your_api_key_here
86
+
87
+ # 可选:智谱API基础URL(默认:https://open.bigmodel.cn/api)
88
+ ZHIPU_API_BASE_URL=https://open.bigmodel.cn/api
89
+
90
+ # 可选:日志级别(默认:info)
91
+ LOG_LEVEL=info
92
+
93
+ # 可选:下载目录(默认:./downloads)
94
+ DOWNLOAD_DIR=./downloads
95
+ ```
96
+
97
+ ### 获取API密钥
98
+
99
+ 按照以下步骤获取智谱 API 密钥:
100
+
101
+ 1. 访问 [智谱开放平台](https://bigmodel.cn/usercenter/proj-mgmt/apikeys)
102
+ 2. 登录后进入 **API Keys** 页面
103
+ 3. 创建并复制生成的 API 密钥
104
+ 4. 设置为 `ZHIPU_API_KEY` 环境变量
105
+
106
+ > **注意**:API 密钥是敏感信息,请妥善保管,不要泄露给他人。
107
+
108
+ ## 使用方法
109
+
110
+ 配置完成后,重启Claude Desktop,然后您就可以在对话中使用以下功能:
111
+
112
+ ### 可用工具
113
+
114
+ #### generate_image - 文生图
115
+
116
+ 使用智谱 GLM-Image 根据文本描述生成图片。
117
+
118
+ **参数:**
119
+ - `prompt` (string, 必需): 图片生成的文本提示词
120
+ - 上限 1000 字符(GLM-Image 输入限制)
121
+ - `image_size` (string, 可选): 图片尺寸比例
122
+ - 可选值: `auto`, `1:1`, `16:9`, `9:16`, `4:3`, `3:4`
123
+ - 默认: `auto`(映射为 `1280x1280`)
124
+ - 自动映射为智谱推荐尺寸(如 `1:1` → `1280x1280`、`16:9` → `1728x960`)
125
+ - `image_count` (integer, 可选): 生成的图片数量
126
+ - 范围: 1-4(通过并发多个异步任务实现)
127
+ - 默认: 1
128
+ - `model` (string, 可选): 智谱模型编码
129
+ - 默认: `glm-image`
130
+
131
+ **返回:**
132
+ ```json
133
+ {
134
+ "success": true,
135
+ "task_id": "2026111416523604709d3a3f02465c",
136
+ "local_path": "/path/to/downloads/images/task_id_0.png",
137
+ "cdn_url": "https://maas-watermark-prod-new.cn-wlcb.ufileos.com/...",
138
+ "prompt": "你的提示词",
139
+ "image_size": "1:1",
140
+ "image_count": 1,
141
+ "generation_time": 46.2
142
+ }
143
+ ```
144
+
145
+ 多图生成时额外返回 `task_ids`、`local_paths`、`cdn_urls` 数组。
146
+
147
+ ## 使用示例
148
+
149
+ ### 示例1:生成单张图片
150
+
151
+ ```
152
+ 帮我生成一张图片:一只可爱的橘猫在花园里玩耍,1:1比例
153
+ ```
154
+
155
+ ### 示例2:生成多张图片
156
+
157
+ ```
158
+ 用以下提示词生成3张图片:日落时分的海滩,海浪轻轻拍打沙滩,16:9比例
159
+ ```
160
+
161
+ ### 示例3:指定尺寸
162
+
163
+ ```
164
+ 生成一张9:16竖屏图片:手机壁纸风格的星空银河
165
+ ```
166
+
167
+ ## 技术规格
168
+
169
+ ### 轮询配置
170
+
171
+ - **轮询间隔**: 5秒
172
+ - **超时时间**: 10分钟(600秒)
173
+
174
+ ### 重试策略
175
+
176
+ - **最大重试次数**: 3次
177
+ - **重试延迟**: 指数退避(1秒、2秒、4秒)
178
+
179
+ ### 文件存储
180
+
181
+ 生成的图片保存在 `./downloads/images/` 目录,文件命名格式:`{task_id}_{index}.{ext}`。
182
+
183
+ > 智谱返回的图片URL为临时链接(有效期30天),生成后会自动下载到本地。
184
+
185
+ ## 开发
186
+
187
+ ### 构建
188
+
189
+ ```bash
190
+ npm run build
191
+ ```
192
+
193
+ ### 开发模式
194
+
195
+ ```bash
196
+ npm run dev
197
+ ```
198
+
199
+ ### 直接运行
200
+
201
+ ```bash
202
+ npm start
203
+ ```
204
+
205
+ ## 错误处理
206
+
207
+ 服务器会处理以下错误情况:
208
+
209
+ - **缺少API密钥**: 启动时检查`ZHIPU_API_KEY`环境变量
210
+ - **网络错误**: 自动重试最多3次
211
+ - **任务超时**: 超过10分钟后停止轮询
212
+ - **任务失败**: 返回详细的错误信息
213
+
214
+ ## 许可证
215
+
216
+ MIT
217
+
218
+ ## 支持
219
+
220
+ 如有问题,请访问 [智谱开放平台文档](https://docs.bigmodel.cn) 或提交Issue。
221
+
222
+ ## 更新日志
223
+
224
+ ### v1.3.0
225
+ - 文生图改为智谱 GLM-Image 直连(国产视觉模型,绕过外部网关)
226
+ - **重大变更**:移除青萍AI网关依赖(`QINGPING_API_KEY` 等配置项下线,`ZHIPU_API_KEY` 为唯一必需密钥)
227
+ - **重大变更**:移除 `generate_image_from_images`(图生图)、`generate_video`/`get_video_status`(文生视频)、`reset_session`(会话)工具
228
+ - `image_size` 比例自动映射智谱推荐尺寸;`image_count` 并发多任务生成
229
+ - 修复日志输出污染 stdio 协议流的问题(日志统一写 stderr)
230
+
231
+ ### v1.2.0
232
+ - 文生图功能添加模型参数支持
233
+ - 图生图功能添加模型参数支持
234
+ - 统一模型参数配置接口
235
+ - 支持自定义模型选择
236
+
237
+ ### v1.1.0
238
+ - 新增图生图功能(generate_image_from_images)
239
+ - 支持1-4张参考图片URL
240
+ - 完整的参数验证和错误处理
241
+ - 复用现有的轮询和下载机制
242
+
243
+ ### v1.0.0
244
+ - 初始版本发布
245
+ - 支持文生图功能
246
+ - 自动会话管理
247
+ - 自动文件下载
248
+ - 智能轮询机制
@@ -0,0 +1,34 @@
1
+ import { Logger } from '../utils/logger.js';
2
+ import type { ZhipuAsyncResult, ZhipuImageGenerationOptions } from '../types/index.js';
3
+ export declare class ZhipuImageAPI {
4
+ private client;
5
+ private logger;
6
+ private downloadDir;
7
+ constructor(apiKey: string, baseURL: string, logger: Logger, downloadDir: string);
8
+ /**
9
+ * 创建智谱异步文生图任务,返回任务ID
10
+ */
11
+ generate(options: ZhipuImageGenerationOptions): Promise<string>;
12
+ /**
13
+ * 查询智谱异步任务结果
14
+ */
15
+ getTaskStatus(taskId: string): Promise<ZhipuAsyncResult>;
16
+ /**
17
+ * 轮询等待任务完成(SUCCESS/FAIL),失败时抛出错误
18
+ */
19
+ waitForCompletion(taskId: string): Promise<ZhipuAsyncResult>;
20
+ /**
21
+ * 并发创建 image_count 个任务,全部完成后下载并聚合结果
22
+ */
23
+ generateAndDownload(options: ZhipuImageGenerationOptions): Promise<{
24
+ taskIds: string[];
25
+ localPaths: string[];
26
+ cdnUrls: string[];
27
+ generationTime: number;
28
+ }>;
29
+ private post;
30
+ private get;
31
+ private wrapError;
32
+ private sleep;
33
+ }
34
+ //# sourceMappingURL=zhipu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zhipu.d.ts","sourceRoot":"","sources":["../../src/api/zhipu.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG5C,OAAO,KAAK,EAEV,gBAAgB,EAChB,2BAA2B,EAC5B,MAAM,mBAAmB,CAAC;AAgB3B,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAS;gBAG1B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM;IAerB;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAAC,MAAM,CAAC;IAsCrE;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI9D;;OAEG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAsClE;;OAEG;IACG,mBAAmB,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAAC;QACvE,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;YAiDY,IAAI;YA+BJ,GAAG;IA+BjB,OAAO,CAAC,SAAS;IAkDjB,OAAO,CAAC,KAAK;CAGd"}
@@ -0,0 +1,208 @@
1
+ import axios from 'axios';
2
+ import path from 'path';
3
+ import { poll } from '../utils/poll.js';
4
+ import { downloadFile, generateFileName, ensureDir } from '../utils/file.js';
5
+ import { ErrorCode, MCPError } from '../types/index.js';
6
+ /** 工具比例参数 → 智谱像素尺寸映射(智谱推荐枚举值,长宽为32的倍数) */
7
+ const SIZE_MAP = {
8
+ auto: '1280x1280',
9
+ '1:1': '1280x1280',
10
+ '4:3': '1472x1088',
11
+ '3:4': '1088x1472',
12
+ '16:9': '1728x960',
13
+ '9:16': '960x1728'
14
+ };
15
+ const POLL_INTERVAL = 5000; // 5秒
16
+ const POLL_TIMEOUT = 600000; // 10分钟
17
+ export class ZhipuImageAPI {
18
+ client;
19
+ logger;
20
+ downloadDir;
21
+ constructor(apiKey, baseURL, logger, downloadDir) {
22
+ this.logger = logger;
23
+ this.downloadDir = path.join(downloadDir, 'images');
24
+ this.client = axios.create({
25
+ baseURL,
26
+ timeout: 30000,
27
+ headers: {
28
+ Authorization: `Bearer ${apiKey}`,
29
+ 'Content-Type': 'application/json'
30
+ }
31
+ });
32
+ }
33
+ /**
34
+ * 创建智谱异步文生图任务,返回任务ID
35
+ */
36
+ async generate(options) {
37
+ if (options.prompt.length > 1000) {
38
+ throw new MCPError(ErrorCode.TASK_FAILED, 'GLM-Image 的 prompt 长度不能超过1000字符');
39
+ }
40
+ const model = options.model;
41
+ const size = SIZE_MAP[options.image_size] || SIZE_MAP.auto;
42
+ this.logger.info('创建智谱文生图任务', {
43
+ model,
44
+ prompt: options.prompt.substring(0, 50) + '...',
45
+ image_size: options.image_size,
46
+ size
47
+ });
48
+ const response = await this.post('/paas/v4/async/images/generations', {
49
+ model,
50
+ prompt: options.prompt,
51
+ size
52
+ });
53
+ if (!response.id) {
54
+ throw new MCPError(ErrorCode.TASK_FAILED, '智谱文生图任务创建失败:未返回任务ID');
55
+ }
56
+ this.logger.info('智谱文生图任务已创建', { task_id: response.id });
57
+ return response.id;
58
+ }
59
+ /**
60
+ * 查询智谱异步任务结果
61
+ */
62
+ async getTaskStatus(taskId) {
63
+ return this.get(`/paas/v4/async-result/${taskId}`);
64
+ }
65
+ /**
66
+ * 轮询等待任务完成(SUCCESS/FAIL),失败时抛出错误
67
+ */
68
+ async waitForCompletion(taskId) {
69
+ this.logger.info('等待智谱文生图任务完成', { task_id: taskId });
70
+ const startTime = Date.now();
71
+ const result = await poll({
72
+ pollFn: () => this.getTaskStatus(taskId),
73
+ conditionFn: (data) => {
74
+ return data.task_status === 'SUCCESS' || data.task_status === 'FAIL';
75
+ },
76
+ interval: POLL_INTERVAL,
77
+ timeout: POLL_TIMEOUT,
78
+ onProgress: (data) => {
79
+ this.logger.debug('任务状态更新', {
80
+ task_id: taskId,
81
+ status: data.task_status
82
+ });
83
+ }
84
+ });
85
+ const elapsed = (Date.now() - startTime) / 1000;
86
+ if (result.task_status === 'FAIL') {
87
+ throw new MCPError(ErrorCode.TASK_FAILED, `图片生成失败(智谱任务 ${taskId})`, { task_id: taskId, result });
88
+ }
89
+ this.logger.info('智谱文生图任务完成', {
90
+ task_id: taskId,
91
+ elapsed: `${elapsed.toFixed(2)}s`
92
+ });
93
+ return result;
94
+ }
95
+ /**
96
+ * 并发创建 image_count 个任务,全部完成后下载并聚合结果
97
+ */
98
+ async generateAndDownload(options) {
99
+ const startTime = Date.now();
100
+ // 1. 并发创建 N 个任务
101
+ const taskIds = await Promise.all(Array.from({ length: options.image_count }, () => this.generate(options)));
102
+ // 2. 并发等待全部任务完成
103
+ const results = await Promise.all(taskIds.map((id) => this.waitForCompletion(id)));
104
+ // 3. 下载全部图片
105
+ await ensureDir(this.downloadDir);
106
+ const localPaths = [];
107
+ const cdnUrls = [];
108
+ for (let i = 0; i < results.length; i++) {
109
+ const url = results[i].image_result?.[0]?.url;
110
+ if (!url) {
111
+ throw new MCPError(ErrorCode.TASK_FAILED, `任务 ${taskIds[i]} 未返回图片URL`, { task_id: taskIds[i], result: results[i] });
112
+ }
113
+ const fileName = generateFileName(taskIds[i], 0, url);
114
+ const localPath = path.join(this.downloadDir, fileName);
115
+ this.logger.info('下载图片', { task_id: taskIds[i], url });
116
+ await downloadFile(url, localPath);
117
+ localPaths.push(localPath);
118
+ cdnUrls.push(url);
119
+ }
120
+ const generationTime = (Date.now() - startTime) / 1000;
121
+ return {
122
+ taskIds,
123
+ localPaths,
124
+ cdnUrls,
125
+ generationTime
126
+ };
127
+ }
128
+ async post(path, data, retries = 3) {
129
+ let lastError = null;
130
+ for (let attempt = 0; attempt < retries; attempt++) {
131
+ try {
132
+ const response = await this.client.post(path, data);
133
+ return response.data;
134
+ }
135
+ catch (error) {
136
+ lastError =
137
+ error instanceof MCPError
138
+ ? error
139
+ : this.wrapError(error);
140
+ if (lastError instanceof MCPError) {
141
+ const code = lastError.code;
142
+ if (code !== ErrorCode.API_TIMEOUT && code !== ErrorCode.API_ERROR) {
143
+ throw lastError;
144
+ }
145
+ }
146
+ if (attempt < retries - 1) {
147
+ const delay = Math.pow(2, attempt) * 1000;
148
+ this.logger.debug(`重试 ${attempt + 1}/${retries},等待 ${delay}ms`);
149
+ await this.sleep(delay);
150
+ }
151
+ }
152
+ }
153
+ throw lastError;
154
+ }
155
+ async get(path, retries = 3) {
156
+ let lastError = null;
157
+ for (let attempt = 0; attempt < retries; attempt++) {
158
+ try {
159
+ const response = await this.client.get(path);
160
+ return response.data;
161
+ }
162
+ catch (error) {
163
+ lastError =
164
+ error instanceof MCPError
165
+ ? error
166
+ : this.wrapError(error);
167
+ if (lastError instanceof MCPError) {
168
+ const code = lastError.code;
169
+ if (code !== ErrorCode.API_TIMEOUT && code !== ErrorCode.API_ERROR) {
170
+ throw lastError;
171
+ }
172
+ }
173
+ if (attempt < retries - 1) {
174
+ const delay = Math.pow(2, attempt) * 1000;
175
+ this.logger.debug(`重试 ${attempt + 1}/${retries},等待 ${delay}ms`);
176
+ await this.sleep(delay);
177
+ }
178
+ }
179
+ }
180
+ throw lastError;
181
+ }
182
+ wrapError(error) {
183
+ if (error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT') {
184
+ return new MCPError(ErrorCode.API_TIMEOUT, '请求智谱API超时,请检查网络连接', { originalError: error.message });
185
+ }
186
+ if (error.response) {
187
+ const status = error.response.status;
188
+ const data = error.response.data;
189
+ const zhipuMessage = data?.error?.message;
190
+ const zhipuCode = data?.error?.code;
191
+ if (status === 401 || status === 403) {
192
+ return new MCPError(ErrorCode.API_ERROR, '智谱API密钥无效或已过期', { status });
193
+ }
194
+ if (status === 429) {
195
+ return new MCPError(ErrorCode.API_RATE_LIMIT, '智谱API请求过于频繁,请稍后重试', { status });
196
+ }
197
+ return new MCPError(ErrorCode.API_ERROR, zhipuMessage ? `智谱API错误: ${zhipuMessage}` : `智谱API错误: ${status}`, { status, code: zhipuCode, data });
198
+ }
199
+ if (error.request) {
200
+ return new MCPError(ErrorCode.API_ERROR, '网络错误,无法连接到智谱API服务器', { originalError: error.message });
201
+ }
202
+ return new MCPError(ErrorCode.API_ERROR, error.message || '未知错误');
203
+ }
204
+ sleep(ms) {
205
+ return new Promise(resolve => setTimeout(resolve, ms));
206
+ }
207
+ }
208
+ //# sourceMappingURL=zhipu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zhipu.js","sourceRoot":"","sources":["../../src/api/zhipu.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Config } from './types/index.js';
2
+ export declare function loadConfig(): Config;
3
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG/C,wBAAgB,UAAU,IAAI,MAAM,CAgBnC"}
package/dist/config.js ADDED
@@ -0,0 +1,14 @@
1
+ import { ErrorCode, MCPError } from './types/index.js';
2
+ export function loadConfig() {
3
+ const zhipuApiKey = process.env.ZHIPU_API_KEY;
4
+ if (!zhipuApiKey) {
5
+ throw new MCPError(ErrorCode.MISSING_API_KEY, 'ZHIPU_API_KEY环境变量未设置,请先设置智谱开放平台API密钥');
6
+ }
7
+ return {
8
+ zhipuApiKey,
9
+ zhipuBaseURL: process.env.ZHIPU_API_BASE_URL || 'https://open.bigmodel.cn/api',
10
+ logLevel: process.env.LOG_LEVEL || 'info',
11
+ downloadDir: process.env.DOWNLOAD_DIR || './downloads'
12
+ };
13
+ }
14
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,UAAU,UAAU;IACxB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAE9C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,eAAe,EACzB,sCAAsC,CACvC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,WAAW;QACX,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,8BAA8B;QAC9E,QAAQ,EAAG,OAAO,CAAC,GAAG,CAAC,SAAgC,IAAI,MAAM;QACjE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,aAAa;KACvD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { CarmateMCPServer } from './server.js';
3
+ async function main() {
4
+ const server = new CarmateMCPServer();
5
+ await server.start();
6
+ }
7
+ main().catch((error) => {
8
+ console.error('服务器启动失败:', error);
9
+ process.exit(1);
10
+ });
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACtC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare class CarmateMCPServer {
2
+ private server;
3
+ private logger;
4
+ private config;
5
+ private zhipuAPI;
6
+ constructor();
7
+ private setupHandlers;
8
+ start(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAWA,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,QAAQ,CAAgB;;IA4BhC,OAAO,CAAC,aAAa;IA2Ef,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
package/dist/server.js ADDED
@@ -0,0 +1,104 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
4
+ import { loadConfig } from './config.js';
5
+ import { Logger } from './utils/logger.js';
6
+ import { ZhipuImageAPI } from './api/zhipu.js';
7
+ import { handleGenerateImage } from './tools/image.js';
8
+ export class CarmateMCPServer {
9
+ server;
10
+ logger;
11
+ config;
12
+ zhipuAPI;
13
+ constructor() {
14
+ this.logger = new Logger(process.env.LOG_LEVEL || 'info');
15
+ this.config = loadConfig();
16
+ this.zhipuAPI = new ZhipuImageAPI(this.config.zhipuApiKey, this.config.zhipuBaseURL, this.logger, this.config.downloadDir);
17
+ this.server = new Server({
18
+ name: 'carmate-image-mcp',
19
+ version: '1.0.0'
20
+ }, {
21
+ capabilities: {
22
+ tools: {}
23
+ }
24
+ });
25
+ this.setupHandlers();
26
+ }
27
+ setupHandlers() {
28
+ // 列出工具
29
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => {
30
+ return {
31
+ tools: [
32
+ {
33
+ name: 'generate_image',
34
+ description: '使用智谱GLM-Image的文本生成图片功能,根据文本描述生成图片并自动下载到本地',
35
+ inputSchema: {
36
+ type: 'object',
37
+ properties: {
38
+ prompt: {
39
+ type: 'string',
40
+ description: '图片生成的文本提示词,描述想要生成的图片内容',
41
+ minLength: 1,
42
+ maxLength: 1000
43
+ },
44
+ image_size: {
45
+ type: 'string',
46
+ description: '图片尺寸比例',
47
+ enum: ['auto', '1:1', '16:9', '9:16', '4:3', '3:4'],
48
+ default: 'auto'
49
+ },
50
+ image_count: {
51
+ type: 'integer',
52
+ description: '生成的图片数量',
53
+ minimum: 1,
54
+ maximum: 4,
55
+ default: 1
56
+ },
57
+ model: {
58
+ type: 'string',
59
+ description: '智谱模型编码',
60
+ default: 'glm-image'
61
+ }
62
+ },
63
+ required: ['prompt']
64
+ }
65
+ }
66
+ ]
67
+ };
68
+ });
69
+ // 处理工具调用
70
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
71
+ const { name, arguments: args } = request.params;
72
+ this.logger.info('工具调用', { name, args });
73
+ try {
74
+ switch (name) {
75
+ case 'generate_image':
76
+ return await handleGenerateImage(args, this.zhipuAPI);
77
+ default:
78
+ throw new Error(`未知工具: ${name}`);
79
+ }
80
+ }
81
+ catch (error) {
82
+ this.logger.error('工具调用错误', { name, error });
83
+ return {
84
+ content: [
85
+ {
86
+ type: 'text',
87
+ text: JSON.stringify({
88
+ success: false,
89
+ error: error instanceof Error ? error.message : '未知错误'
90
+ })
91
+ }
92
+ ],
93
+ isError: true
94
+ };
95
+ }
96
+ });
97
+ }
98
+ async start() {
99
+ const transport = new StdioServerTransport();
100
+ await this.server.connect(transport);
101
+ this.logger.info('Carmate Image MCP服务器已启动');
102
+ }
103
+ }
104
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,OAAO,gBAAgB;IACnB,MAAM,CAAS;IACf,MAAM,CAAS;IACf,MAAM,CAAgC;IACtC,QAAQ,CAAgB;IAEhC;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;QAE3B,IAAI,CAAC,QAAQ,GAAG,IAAI,aAAa,CAC/B,IAAI,CAAC,MAAM,CAAC,WAAW,EACvB,IAAI,CAAC,MAAM,CAAC,YAAY,EACxB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,MAAM,CAAC,WAAW,CACxB,CAAC;QAEF,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CACtB;YACE,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,OAAO;SACjB,EACD;YACE,YAAY,EAAE;gBACZ,KAAK,EAAE,EAAE;aACV;SACF,CACF,CAAC;QAEF,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,aAAa;QACnB,OAAO;QACP,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;YAC/D,OAAO;gBACL,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,gBAAgB;wBACtB,WAAW,EAAE,2CAA2C;wBACxD,WAAW,EAAE;4BACX,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE;gCACV,MAAM,EAAE;oCACN,IAAI,EAAE,QAAQ;oCACd,WAAW,EAAE,wBAAwB;oCACrC,SAAS,EAAE,CAAC;oCACZ,SAAS,EAAE,IAAI;iCAChB;gCACD,UAAU,EAAE;oCACV,IAAI,EAAE,QAAQ;oCACd,WAAW,EAAE,QAAQ;oCACrB,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC;oCACnD,OAAO,EAAE,MAAM;iCAChB;gCACD,WAAW,EAAE;oCACX,IAAI,EAAE,SAAS;oCACf,WAAW,EAAE,SAAS;oCACtB,OAAO,EAAE,CAAC;oCACV,OAAO,EAAE,CAAC;oCACV,OAAO,EAAE,CAAC;iCACX;gCACD,KAAK,EAAE;oCACL,IAAI,EAAE,QAAQ;oCACd,WAAW,EAAE,QAAQ;oCACrB,OAAO,EAAE,WAAW;iCACrB;6BACF;4BACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;yBACrB;qBACF;iBACF;aACF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,SAAS;QACT,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACrE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;YAEjD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAEzC,IAAI,CAAC;gBACH,QAAQ,IAAI,EAAE,CAAC;oBACb,KAAK,gBAAgB;wBACnB,OAAO,MAAM,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAExD;wBACE,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC7C,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,OAAO,EAAE,KAAK;gCACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;6BACvD,CAAC;yBACH;qBACF;oBACD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAC9C,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import { ZhipuImageAPI } from '../api/zhipu.js';
2
+ export declare function handleGenerateImage(args: any, zhipuAPI: ZhipuImageAPI): Promise<{
3
+ content: Array<{
4
+ type: string;
5
+ text: string;
6
+ }>;
7
+ }>;
8
+ //# sourceMappingURL=image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/tools/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAMhD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,aAAa,GACtB,OAAO,CAAC;IACT,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD,CAAC,CAiFD"}
@@ -0,0 +1,74 @@
1
+ export async function handleGenerateImage(args, zhipuAPI) {
2
+ const params = args;
3
+ // 验证参数
4
+ if (!params.prompt || typeof params.prompt !== 'string') {
5
+ throw new Error('prompt参数必须是非空字符串');
6
+ }
7
+ if (params.prompt.length > 1000) {
8
+ throw new Error('prompt长度不能超过1000字符(GLM-Image 输入上限)');
9
+ }
10
+ const imageCount = params.image_count ?? 1;
11
+ if (imageCount < 1 || imageCount > 4) {
12
+ throw new Error('image_count必须在1-4之间');
13
+ }
14
+ const imageSize = params.image_size ?? 'auto';
15
+ const validSizes = ['auto', '1:1', '16:9', '9:16', '4:3', '3:4'];
16
+ if (!validSizes.includes(imageSize)) {
17
+ throw new Error(`image_size必须是以下值之一: ${validSizes.join(', ')}`);
18
+ }
19
+ const model = params.model ?? 'glm-image';
20
+ if (typeof model !== 'string' || model.trim() === '') {
21
+ throw new Error('model参数必须是非空字符串');
22
+ }
23
+ try {
24
+ const result = await zhipuAPI.generateAndDownload({
25
+ prompt: params.prompt,
26
+ image_size: imageSize,
27
+ image_count: imageCount,
28
+ model: model
29
+ });
30
+ const response = {
31
+ success: true,
32
+ task_id: result.taskIds[0],
33
+ prompt: params.prompt,
34
+ image_size: imageSize,
35
+ image_count: imageCount,
36
+ generation_time: result.generationTime
37
+ };
38
+ if (result.taskIds.length > 1) {
39
+ response.task_ids = result.taskIds;
40
+ }
41
+ if (result.localPaths.length === 1) {
42
+ response.local_path = result.localPaths[0];
43
+ response.cdn_url = result.cdnUrls[0];
44
+ }
45
+ else {
46
+ response.local_paths = result.localPaths;
47
+ response.cdn_urls = result.cdnUrls;
48
+ }
49
+ return {
50
+ content: [
51
+ {
52
+ type: 'text',
53
+ text: JSON.stringify(response, null, 2)
54
+ }
55
+ ]
56
+ };
57
+ }
58
+ catch (error) {
59
+ const errorResponse = {
60
+ success: false,
61
+ prompt: params.prompt,
62
+ error: error instanceof Error ? error.message : '未知错误'
63
+ };
64
+ return {
65
+ content: [
66
+ {
67
+ type: 'text',
68
+ text: JSON.stringify(errorResponse, null, 2)
69
+ }
70
+ ]
71
+ };
72
+ }
73
+ }
74
+ //# sourceMappingURL=image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/tools/image.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ export interface ZhipuAsyncCreateResponse {
2
+ model?: string;
3
+ id: string;
4
+ request_id?: string;
5
+ task_status: 'PROCESSING' | 'SUCCESS' | 'FAIL';
6
+ }
7
+ export interface ZhipuAsyncResult {
8
+ model?: string;
9
+ task_status: 'PROCESSING' | 'SUCCESS' | 'FAIL';
10
+ image_result?: Array<{
11
+ url: string;
12
+ }>;
13
+ request_id?: string;
14
+ }
15
+ export interface ZhipuImageGenerationOptions {
16
+ prompt: string;
17
+ image_size: 'auto' | '1:1' | '16:9' | '9:16' | '4:3' | '3:4';
18
+ image_count: number;
19
+ model: string;
20
+ }
21
+ export interface GenerateImageParams {
22
+ prompt: string;
23
+ image_size?: 'auto' | '1:1' | '16:9' | '9:16' | '4:3' | '3:4';
24
+ image_count?: number;
25
+ model?: string;
26
+ }
27
+ export interface ImageGenerationResult {
28
+ success: boolean;
29
+ task_id?: string;
30
+ task_ids?: string[];
31
+ local_path?: string;
32
+ local_paths?: string[];
33
+ cdn_url?: string;
34
+ cdn_urls?: string[];
35
+ prompt: string;
36
+ image_size?: string;
37
+ image_count?: number;
38
+ generation_time?: number;
39
+ error?: string;
40
+ }
41
+ export interface Config {
42
+ /** 智谱开放平台密钥 */
43
+ zhipuApiKey: string;
44
+ zhipuBaseURL: string;
45
+ logLevel: 'debug' | 'info' | 'warn' | 'error';
46
+ downloadDir: string;
47
+ }
48
+ export declare enum ErrorCode {
49
+ MISSING_API_KEY = "MISSING_API_KEY",
50
+ API_ERROR = "API_ERROR",
51
+ API_TIMEOUT = "API_TIMEOUT",
52
+ API_RATE_LIMIT = "API_RATE_LIMIT",
53
+ TASK_FAILED = "TASK_FAILED",
54
+ TASK_TIMEOUT = "TASK_TIMEOUT",
55
+ DOWNLOAD_FAILED = "DOWNLOAD_FAILED",
56
+ FILE_WRITE_ERROR = "FILE_WRITE_ERROR"
57
+ }
58
+ export declare class MCPError extends Error {
59
+ code: ErrorCode;
60
+ details?: any | undefined;
61
+ constructor(code: ErrorCode, message: string, details?: any | undefined);
62
+ }
63
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,CAAC;CAChD;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,CAAC;IAC/C,YAAY,CAAC,EAAE,KAAK,CAAC;QACnB,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAGD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAGD,MAAM,WAAW,MAAM;IACrB,eAAe;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC9C,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,oBAAY,SAAS;IACnB,eAAe,oBAAoB;IACnC,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,cAAc,mBAAmB;IACjC,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,eAAe,oBAAoB;IACnC,gBAAgB,qBAAqB;CACtC;AAED,qBAAa,QAAS,SAAQ,KAAK;IAExB,IAAI,EAAE,SAAS;IAEf,OAAO,CAAC,EAAE,GAAG;gBAFb,IAAI,EAAE,SAAS,EACtB,OAAO,EAAE,MAAM,EACR,OAAO,CAAC,EAAE,GAAG,YAAA;CAKvB"}
@@ -0,0 +1,23 @@
1
+ // 错误类型
2
+ export var ErrorCode;
3
+ (function (ErrorCode) {
4
+ ErrorCode["MISSING_API_KEY"] = "MISSING_API_KEY";
5
+ ErrorCode["API_ERROR"] = "API_ERROR";
6
+ ErrorCode["API_TIMEOUT"] = "API_TIMEOUT";
7
+ ErrorCode["API_RATE_LIMIT"] = "API_RATE_LIMIT";
8
+ ErrorCode["TASK_FAILED"] = "TASK_FAILED";
9
+ ErrorCode["TASK_TIMEOUT"] = "TASK_TIMEOUT";
10
+ ErrorCode["DOWNLOAD_FAILED"] = "DOWNLOAD_FAILED";
11
+ ErrorCode["FILE_WRITE_ERROR"] = "FILE_WRITE_ERROR";
12
+ })(ErrorCode || (ErrorCode = {}));
13
+ export class MCPError extends Error {
14
+ code;
15
+ details;
16
+ constructor(code, message, details) {
17
+ super(message);
18
+ this.code = code;
19
+ this.details = details;
20
+ this.name = 'MCPError';
21
+ }
22
+ }
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAyDA,OAAO;AACP,MAAM,CAAN,IAAY,SASX;AATD,WAAY,SAAS;IACnB,gDAAmC,CAAA;IACnC,oCAAuB,CAAA;IACvB,wCAA2B,CAAA;IAC3B,8CAAiC,CAAA;IACjC,wCAA2B,CAAA;IAC3B,0CAA6B,CAAA;IAC7B,gDAAmC,CAAA;IACnC,kDAAqC,CAAA;AACvC,CAAC,EATW,SAAS,KAAT,SAAS,QASpB;AAED,MAAM,OAAO,QAAS,SAAQ,KAAK;IAExB;IAEA;IAHT,YACS,IAAe,EACtB,OAAe,EACR,OAAa;QAEpB,KAAK,CAAC,OAAO,CAAC,CAAC;QAJR,SAAI,GAAJ,IAAI,CAAW;QAEf,YAAO,GAAP,OAAO,CAAM;QAGpB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ export declare function ensureDir(dir: string): Promise<void>;
2
+ export declare function generateFileName(taskId: string, index: number, url: string): string;
3
+ export declare function downloadFile(url: string, localPath: string, onProgress?: (progress: number) => void): Promise<void>;
4
+ //# sourceMappingURL=file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/utils/file.ts"],"names":[],"mappings":"AAKA,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU1D;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGnF;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC,CAsDf"}
@@ -0,0 +1,58 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { Logger } from './logger.js';
4
+ import { MCPError, ErrorCode } from '../types/index.js';
5
+ export async function ensureDir(dir) {
6
+ try {
7
+ await fs.mkdir(dir, { recursive: true });
8
+ }
9
+ catch (error) {
10
+ throw new MCPError(ErrorCode.FILE_WRITE_ERROR, `无法创建目录: ${dir}`, { originalError: error });
11
+ }
12
+ }
13
+ export function generateFileName(taskId, index, url) {
14
+ const ext = url.split('.').pop()?.split('?')[0] || 'jpg';
15
+ return `${taskId}_${index}.${ext}`;
16
+ }
17
+ export async function downloadFile(url, localPath, onProgress) {
18
+ const logger = new Logger('info');
19
+ logger.debug(`开始下载: ${url} -> ${localPath}`);
20
+ try {
21
+ // 确保目录存在
22
+ const dir = path.dirname(localPath);
23
+ await ensureDir(dir);
24
+ const { default: axios } = await import('axios');
25
+ const response = await axios({
26
+ method: 'GET',
27
+ url,
28
+ responseType: 'stream'
29
+ });
30
+ const writer = (await fs.open(localPath, 'w')).createWriteStream();
31
+ let downloadedBytes = 0;
32
+ const totalBytes = parseInt(response.headers['content-length'] || '0', 10);
33
+ response.data.on('data', (chunk) => {
34
+ downloadedBytes += chunk.length;
35
+ if (onProgress && totalBytes > 0) {
36
+ onProgress((downloadedBytes / totalBytes) * 100);
37
+ }
38
+ });
39
+ return new Promise((resolve, reject) => {
40
+ writer.on('finish', () => {
41
+ logger.debug(`下载完成: ${localPath}`);
42
+ resolve();
43
+ });
44
+ writer.on('error', (error) => {
45
+ logger.error(`下载失败: ${localPath}`, error);
46
+ reject(new MCPError(ErrorCode.DOWNLOAD_FAILED, `文件写入失败: ${localPath}`, { originalError: error }));
47
+ });
48
+ response.data.pipe(writer);
49
+ });
50
+ }
51
+ catch (error) {
52
+ if (error instanceof MCPError) {
53
+ throw error;
54
+ }
55
+ throw new MCPError(ErrorCode.DOWNLOAD_FAILED, `文件下载失败: ${url}`, { originalError: error });
56
+ }
57
+ }
58
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/utils/file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare class Logger {
2
+ private level;
3
+ constructor(level?: string);
4
+ private log;
5
+ debug(msg: string, meta?: any): void;
6
+ info(msg: string, meta?: any): void;
7
+ warn(msg: string, meta?: any): void;
8
+ error(msg: string, meta?: any): void;
9
+ }
10
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAOA,qBAAa,MAAM;IACjB,OAAO,CAAC,KAAK,CAAW;gBAEZ,KAAK,GAAE,MAAe;IAKlC,OAAO,CAAC,GAAG;IAKX,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAMpC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAMnC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAMnC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;CAKrC"}
@@ -0,0 +1,39 @@
1
+ var LogLevel;
2
+ (function (LogLevel) {
3
+ LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
4
+ LogLevel[LogLevel["INFO"] = 1] = "INFO";
5
+ LogLevel[LogLevel["WARN"] = 2] = "WARN";
6
+ LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
7
+ })(LogLevel || (LogLevel = {}));
8
+ export class Logger {
9
+ level;
10
+ constructor(level = 'info') {
11
+ this.level = LogLevel[level.toUpperCase()] ?? LogLevel.INFO;
12
+ }
13
+ // 注意:stdio MCP 的 stdout 是 JSON-RPC 协议专用通道,日志必须全部写 stderr
14
+ log(prefix, msg, meta) {
15
+ const metaStr = meta ? ' ' + JSON.stringify(meta, null, 2) : '';
16
+ process.stderr.write(`${prefix} ${msg}${metaStr}\n`);
17
+ }
18
+ debug(msg, meta) {
19
+ if (this.level <= LogLevel.DEBUG) {
20
+ this.log('[DEBUG]', msg, meta);
21
+ }
22
+ }
23
+ info(msg, meta) {
24
+ if (this.level <= LogLevel.INFO) {
25
+ this.log('[INFO]', msg, meta);
26
+ }
27
+ }
28
+ warn(msg, meta) {
29
+ if (this.level <= LogLevel.WARN) {
30
+ this.log('[WARN]', msg, meta);
31
+ }
32
+ }
33
+ error(msg, meta) {
34
+ if (this.level <= LogLevel.ERROR) {
35
+ this.log('[ERROR]', msg, meta);
36
+ }
37
+ }
38
+ }
39
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,IAAK,QAKJ;AALD,WAAK,QAAQ;IACX,yCAAS,CAAA;IACT,uCAAQ,CAAA;IACR,uCAAQ,CAAA;IACR,yCAAS,CAAA;AACX,CAAC,EALI,QAAQ,KAAR,QAAQ,QAKZ;AAED,MAAM,OAAO,MAAM;IACT,KAAK,CAAW;IAExB,YAAY,QAAgB,MAAM;QAChC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,EAA2B,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC;IACvF,CAAC;IAED,yDAAyD;IACjD,GAAG,CAAC,MAAc,EAAE,GAAW,EAAE,IAAU;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,GAAG,GAAG,OAAO,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,GAAW,EAAE,IAAU;QAC3B,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAW,EAAE,IAAU;QAC1B,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAW,EAAE,IAAU;QAC1B,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAW,EAAE,IAAU;QAC3B,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ export interface PollOptions<T> {
2
+ pollFn: () => Promise<T>;
3
+ conditionFn: (result: T) => boolean;
4
+ interval: number;
5
+ timeout: number;
6
+ onProgress?: (result: T) => void;
7
+ }
8
+ export declare function poll<T>(options: PollOptions<T>): Promise<T>;
9
+ //# sourceMappingURL=poll.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../../src/utils/poll.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IACzB,WAAW,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;CAClC;AAED,wBAAsB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CA2CjE"}
@@ -0,0 +1,36 @@
1
+ import { Logger } from './logger.js';
2
+ import { MCPError, ErrorCode } from '../types/index.js';
3
+ export async function poll(options) {
4
+ const { pollFn, conditionFn, interval, timeout, onProgress } = options;
5
+ const startTime = Date.now();
6
+ const logger = new Logger('info');
7
+ logger.debug(`开始轮询,间隔: ${interval}ms,超时: ${timeout}ms`);
8
+ while (true) {
9
+ const elapsed = Date.now() - startTime;
10
+ if (elapsed > timeout) {
11
+ throw new MCPError(ErrorCode.TASK_TIMEOUT, `任务超时:在 ${timeout / 1000} 秒内未完成`, { elapsed });
12
+ }
13
+ try {
14
+ const result = await pollFn();
15
+ if (onProgress) {
16
+ onProgress(result);
17
+ }
18
+ if (conditionFn(result)) {
19
+ logger.debug(`轮询完成,耗时: ${elapsed}ms`);
20
+ return result;
21
+ }
22
+ logger.debug(`任务进行中,${interval / 1000}秒后重试...`);
23
+ await sleep(interval);
24
+ }
25
+ catch (error) {
26
+ if (error instanceof MCPError) {
27
+ throw error;
28
+ }
29
+ throw new MCPError(ErrorCode.API_ERROR, '轮询过程中发生错误', { originalError: error });
30
+ }
31
+ }
32
+ }
33
+ function sleep(ms) {
34
+ return new Promise(resolve => setTimeout(resolve, ms));
35
+ }
36
+ //# sourceMappingURL=poll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/utils/poll.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAUxD,MAAM,CAAC,KAAK,UAAU,IAAI,CAAI,OAAuB;IACnD,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IACvE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;IAElC,MAAM,CAAC,KAAK,CAAC,YAAY,QAAQ,UAAU,OAAO,IAAI,CAAC,CAAC;IAExD,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAEvC,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;YACtB,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,YAAY,EACtB,UAAU,OAAO,GAAG,IAAI,QAAQ,EAChC,EAAE,OAAO,EAAE,CACZ,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,EAAE,CAAC;YAE9B,IAAI,UAAU,EAAE,CAAC;gBACf,UAAU,CAAC,MAAM,CAAC,CAAC;YACrB,CAAC;YAED,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxB,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,IAAI,CAAC,CAAC;gBACtC,OAAO,MAAM,CAAC;YAChB,CAAC;YAED,MAAM,CAAC,KAAK,CAAC,SAAS,QAAQ,GAAG,IAAI,SAAS,CAAC,CAAC;YAChD,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;gBAC9B,MAAM,KAAK,CAAC;YACd,CAAC;YACD,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,SAAS,EACnB,WAAW,EACX,EAAE,aAAa,EAAE,KAAK,EAAE,CACzB,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,54 @@
1
1
  {
2
2
  "name": "carmate-image-mcp",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.3.0",
4
+ "description": "Carmate Image MCP服务器 - 基于智谱GLM-Image提供文生图功能的MCP工具",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "carmate-image-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "start": "node dist/index.js",
19
+ "type-check": "tsc --noEmit",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "keywords": [
23
+ "mcp",
24
+ "model-context-protocol",
25
+ "carmate-image",
26
+ "image-generation",
27
+ "glm-image",
28
+ "zhipu",
29
+ "ai",
30
+ "claude",
31
+ "anthropic"
32
+ ],
33
+ "author": "lusyoe <lusyoe@163.com>",
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/lusyoe/qingping-ai-mcp.git"
38
+ },
39
+ "bugs": {
40
+ "url": "https://github.com/lusyoe/qingping-ai-mcp/issues"
41
+ },
42
+ "homepage": "https://github.com/lusyoe/qingping-ai-mcp#readme",
43
+ "dependencies": {
44
+ "@modelcontextprotocol/sdk": "^1.0.4",
45
+ "axios": "^1.7.9"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^22.10.2",
49
+ "typescript": "^5.7.2"
50
+ },
51
+ "engines": {
52
+ "node": ">=18.0.0"
53
+ }
54
+ }