luma-mcp 1.1.0 → 1.2.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/.env.example CHANGED
@@ -3,7 +3,7 @@
3
3
  # ==========================================
4
4
  # 模型提供商选择
5
5
  # ==========================================
6
- # 可选值: zhipu, siliconflow
6
+ # 可选值: zhipu, siliconflow, qwen
7
7
  # 默认: zhipu
8
8
  MODEL_PROVIDER=zhipu
9
9
 
@@ -17,12 +17,18 @@ ZHIPU_API_KEY=your-zhipu-api-key-here
17
17
  # ==========================================
18
18
  # SILICONFLOW_API_KEY=your-siliconflow-api-key-here
19
19
 
20
+ # ==========================================
21
+ # 阿里云通义千问 Qwen3-VL 配置(使用阿里云时需要)
22
+ # ==========================================
23
+ # DASHSCOPE_API_KEY=your-dashscope-api-key-here
24
+
20
25
  # ==========================================
21
26
  # 通用配置(可选)
22
27
  # ==========================================
23
28
  # 模型名称(留空则使用默认值)
24
29
  # zhipu 默认: glm-4.5v
25
30
  # siliconflow 默认: deepseek-ai/DeepSeek-OCR
31
+ # qwen 默认: qwen3-vl-flash
26
32
  # MODEL_NAME=
27
33
 
28
34
  # 最大生成 tokens(默认: 4096)
@@ -0,0 +1,66 @@
1
+ name: Create Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*.*.*'
7
+
8
+ jobs:
9
+ release:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: write
13
+
14
+ steps:
15
+ - name: Checkout code
16
+ uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+
20
+ - name: Setup Node.js
21
+ uses: actions/setup-node@v4
22
+ with:
23
+ node-version: '18'
24
+ registry-url: 'https://registry.npmjs.org'
25
+
26
+ - name: Install dependencies
27
+ run: npm ci
28
+
29
+ - name: Build
30
+ run: npm run build
31
+
32
+ - name: Extract version from tag
33
+ id: version
34
+ run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
35
+
36
+ - name: Extract changelog for this version
37
+ id: changelog
38
+ run: |
39
+ VERSION=${{ steps.version.outputs.VERSION }}
40
+ echo "Extracting changelog for version $VERSION"
41
+
42
+ # Extract changelog content between version headers
43
+ sed -n "/## \[${VERSION}\]/,/## \[/p" CHANGELOG.md | sed '$d' > release_notes.md
44
+
45
+ # If empty, use a default message
46
+ if [ ! -s release_notes.md ]; then
47
+ echo "Release version ${VERSION}" > release_notes.md
48
+ fi
49
+
50
+ cat release_notes.md
51
+
52
+ - name: Create GitHub Release
53
+ uses: softprops/action-gh-release@v1
54
+ with:
55
+ tag_name: v${{ steps.version.outputs.VERSION }}
56
+ name: Release v${{ steps.version.outputs.VERSION }}
57
+ body_path: release_notes.md
58
+ draft: false
59
+ prerelease: false
60
+ env:
61
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
62
+
63
+ - name: Publish to npm
64
+ run: npm publish --access public
65
+ env:
66
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/CHANGELOG.md CHANGED
@@ -2,6 +2,41 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.2.0] - 2025-11-17
6
+
7
+ ### Added
8
+ - 🎉 **第三个视觉模型**: 新增阿里云通义千问 Qwen3-VL-Flash 支持
9
+ - 💡 **思考模式**: Qwen3-VL-Flash 支持深度思考模式(enable_thinking),提升复杂场景分析准确性
10
+ - ⚡ **高性价比**: Flash 版本速度更快、成本更低,适合大量使用
11
+ - 🔌 **OpenAI 兼容**: 使用阿里云百炼的 OpenAI 兼容 API,统一接口设计
12
+ - 🌐 **多地域支持**: 默认使用北京地域,支持新加坡地域配置
13
+
14
+ ### Changed
15
+ - ⚙️ 新增 `MODEL_PROVIDER=qwen` 和 `DASHSCOPE_API_KEY` 环境变量配置
16
+ - 📝 更新所有文档(中英文),添加 Qwen3-VL-Flash 配置示例
17
+ - 💰 默认使用 qwen3-vl-flash 模型,兹顾性能与成本
18
+ - 🏗️ 重构客户端构造函数,统一参数传递方式
19
+
20
+ ### Technical Details
21
+ - 新增文件:
22
+ - `src/qwen-client.ts` - 阿里云通义千问 VL API 客户端实现
23
+ - 修改文件:
24
+ - `src/config.ts` - 添加 'qwen' 提供商支持
25
+ - `src/zhipu-client.ts` - 重构构造函数,支持独立参数
26
+ - `src/siliconflow-client.ts` - 重构构造函数,支持独立参数
27
+ - `src/index.ts` - 添加 Qwen 客户端初始化逻辑
28
+ - `package.json` - 更新版本至 1.2.0,添加 qwen/aliyun/dashscope 关键词
29
+
30
+ ## [1.1.1] - 2025-11-13
31
+
32
+ ### Added
33
+ - 🖼️ **Data URI 支持**: 支持接收 base64 编码的图片数据 (data:image/png;base64,...)
34
+ - 🚀 **为未来做准备**: 当 MCP 客户端支持时,可直接传递用户粘贴的图片
35
+
36
+ ### Changed
37
+ - 📝 更新工具描述,说明支持三种输入格式:本地路径、URL、Data URI
38
+ - ✅ 新增 Data URI 格式验证(MIME 类型、大小限制)
39
+
5
40
  ## [1.1.0] - 2025-11-13
6
41
 
7
42
  ### Added
@@ -26,7 +61,7 @@ All notable changes to this project will be documented in this file.
26
61
  - `src/index.ts` - 根据配置动态选择客户端
27
62
  - `README.md` - 完整的双模型使用文档
28
63
 
29
- ## [1.0.3] - 2025-11-XX
64
+ ## [1.0.3] - 2025-11-12
30
65
 
31
66
  ### Features
32
67
  - 基于智谱 GLM-4.5V 的视觉理解能力
@@ -38,13 +73,20 @@ All notable changes to this project will be documented in this file.
38
73
 
39
74
  **模型对比**:
40
75
 
41
- | 特性 | GLM-4.5V | DeepSeek-OCR |
42
- |----------|----------|--------------|
43
- | 费用 | 收费 | **免费** |
44
- | 中文理解 | 优秀 | 良好 |
45
- | OCR 能力 | 良好 | **优秀** |
46
- | 思考模式 | | |
76
+ || 特性 | GLM-4.5V | DeepSeek-OCR | Qwen3-VL-Flash |
77
+ ||----------|----------|--------------|----------------|
78
+ || 提供商 | 智谱清言 | 硅基流动 | 阿里云百炼 |
79
+ || 费用 | 收费 | **免费** | 收费 |
80
+ || 中文理解 | 优秀 | 良好 | **优秀** |
81
+ || OCR 能力 | 良好 | **优秀** | 优秀 |
82
+ || 思考模式 | ✅ | ❌ | ✅ |
83
+ || 速度/成本 | 中等 | 免费 | **快/低** |
84
+ || 综合能力 | 良好 | OCR专精 | **优秀** |
85
+ || 3D定位 | ❌ | ❌ | ✅ |
47
86
 
48
87
  **推荐使用场景**:
49
88
  - 需要 OCR/文字识别 → **DeepSeek-OCR** (免费)
50
- - 需要深度图片理解 → **GLM-4.5V**
89
+ - 需要深度图片理解 → **Qwen3-VL-Flash** 或 **GLM-4.5V**
90
+ - 需要思考模式 → **Qwen3-VL-Flash** 或 **GLM-4.5V**
91
+ - 需要高性价比 → **Qwen3-VL-Flash** (速度快、成本低)
92
+ - 需要 3D 定位/复杂分析 → **Qwen3-VL-Flash**
package/README.md CHANGED
@@ -6,12 +6,14 @@
6
6
 
7
7
  ## 特性
8
8
 
9
- - **多模型支持**: 支持 GLM-4.5V(智谱)和 DeepSeek-OCR(硅基流动)
9
+ - **多模型支持**: 支持三个视觉模型
10
+ - GLM-4.5V(智谱清言)- 付费,中文理解优秀
11
+ - DeepSeek-OCR(硅基流动)- **免费使用**,OCR能力强
12
+ - Qwen3-VL-Flash(阿里云通义千问)- 付费,速度快成本低,支持思考模式
10
13
  - **简单设计**: 单一 `analyze_image` 工具处理所有图片分析任务
11
14
  - **智能理解**: 自动识别代码、UI、错误等不同场景
12
15
  - **全面支持**: 代码截图、界面设计、错误诊断、OCR 文字识别
13
16
  - **标准 MCP 协议**: 无缝集成 Claude Desktop、Cline 等 MCP 客户端
14
- - **免费选项**: DeepSeek-OCR 通过硅基流动提供免费调用
15
17
  - **URL 支持**: 支持本地文件和远程图片 URL
16
18
  - **重试机制**: 内置指数退避重试,提高可靠性
17
19
 
@@ -23,6 +25,7 @@
23
25
  - **选择一种模型**:
24
26
  - **方案 A**: 智谱 AI API Key ([获取地址](https://open.bigmodel.cn/)) - 中文理解优秀
25
27
  - **方案 B**: 硅基流动 API Key ([获取地址](https://cloud.siliconflow.cn/)) - **免费使用**,OCR 能力强
28
+ - **方案 C**: 阿里云百炼 API Key ([获取地址](https://bailian.console.aliyun.com/)) - 速度快成本低,支持思考模式
26
29
 
27
30
  ### 安装
28
31
 
@@ -82,6 +85,23 @@ npx luma-mcp
82
85
  }
83
86
  ```
84
87
 
88
+ **方案 C: 使用阿里云通义千问 Qwen3-VL-Flash**:
89
+
90
+ ```json
91
+ {
92
+ "mcpServers": {
93
+ "luma": {
94
+ "command": "npx",
95
+ "args": ["-y", "luma-mcp"],
96
+ "env": {
97
+ "MODEL_PROVIDER": "qwen",
98
+ "DASHSCOPE_API_KEY": "your-dashscope-api-key"
99
+ }
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
85
105
  **本地开发(智谱)**:
86
106
 
87
107
  ```json
@@ -154,6 +174,23 @@ npx luma-mcp
154
174
  }
155
175
  ```
156
176
 
177
+ **方案 C: 使用阿里云通义千问 Qwen3-VL-Flash**:
178
+
179
+ ```json
180
+ {
181
+ "mcpServers": {
182
+ "luma": {
183
+ "command": "npx",
184
+ "args": ["-y", "luma-mcp"],
185
+ "env": {
186
+ "MODEL_PROVIDER": "qwen",
187
+ "DASHSCOPE_API_KEY": "your-dashscope-api-key"
188
+ }
189
+ }
190
+ }
191
+ }
192
+ ```
193
+
157
194
  #### Claude Code (命令行)
158
195
 
159
196
  **使用智谱 GLM-4.5V**:
@@ -166,6 +203,11 @@ claude mcp add -s user luma-mcp --env ZHIPU_API_KEY=your-api-key -- npx -y luma-
166
203
  claude mcp add -s user luma-mcp --env MODEL_PROVIDER=siliconflow --env SILICONFLOW_API_KEY=your-api-key -- npx -y luma-mcp
167
204
  ```
168
205
 
206
+ **使用阿里云通义千问 Qwen3-VL-Flash**:
207
+ ```bash
208
+ claude mcp add -s user luma-mcp --env MODEL_PROVIDER=qwen --env DASHSCOPE_API_KEY=your-api-key -- npx -y luma-mcp
209
+ ```
210
+
169
211
  #### 其他工具
170
212
 
171
213
  更多 MCP 客户端配置方法请参考[智谱官方文档](https://docs.bigmodel.cn/cn/coding-plan/mcp/vision-mcp-server#claude-code)
@@ -247,10 +289,11 @@ npm run test:local https://example.com/image.jpg
247
289
 
248
290
  **参数**:
249
291
 
250
- - `image_source` (必需): 图片路径或 URL
292
+ - `image_source` (必需): 图片来源,支持三种格式
293
+ - **本地文件**: 绝对路径或相对路径(例:`./image.png`, `C:\Users\...\image.jpg`)
294
+ - **远程 URL**: https:// 开头的 URL(例:`https://example.com/pic.jpg`)
295
+ - **Data URI**: Base64 编码的图片数据(例:`data:image/png;base64,iVBORw0KGg...`)
251
296
  - 支持格式: JPG, PNG, WebP, GIF
252
- - 本地文件: 绝对路径或相对路径
253
- - 远程图片: https:// 开头的 URL
254
297
  - `prompt` (必需): 分析指令或问题
255
298
 
256
299
  **示例**:
@@ -273,6 +316,12 @@ analyze_image({
273
316
  image_source: "https://example.com/ui.png",
274
317
  prompt: "分析这个界面的布局和可用性问题"
275
318
  })
319
+
320
+ // Data URI (当客户端支持时)
321
+ analyze_image({
322
+ image_source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...",
323
+ prompt: "识别图片中的所有文字"
324
+ })
276
325
  ```
277
326
 
278
327
  ## 环境变量
@@ -381,6 +430,18 @@ luma-mcp/
381
430
 
382
431
  支持 JPG、PNG、WebP、GIF 格式。建议使用 JPG 格式以获得更好的压缩率。
383
432
 
433
+ ### 什么是 Data URI?
434
+
435
+ Data URI 是一种将图片数据嵌入字符串的方式,格式为:
436
+ ```
437
+ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...
438
+ ```
439
+
440
+ **使用场景**:
441
+ - 当 MCP 客户端(如 Claude Desktop)支持时,可以直接传递用户粘贴的图片
442
+ - 无需保存为临时文件,更加高效
443
+ - 当前支持状态:**服务器已支持**,等待客户端实现
444
+
384
445
  ### 图片大小限制?
385
446
 
386
447
  - 最大文件大小: 10MB
@@ -443,6 +504,16 @@ MIT License
443
504
 
444
505
  ## 更新日志
445
506
 
507
+ ### [1.1.1] - 2025-11-13
508
+
509
+ #### 新增
510
+ - 🖼️ **Data URI 支持**: 支持接收 base64 编码的图片数据(`data:image/png;base64,...`)
511
+ - 🚀 **为未来做准备**: 当 MCP 客户端支持时,可直接传递用户粘贴的图片
512
+
513
+ #### 修改
514
+ - 更新工具描述,说明支持三种输入格式:本地路径、URL、Data URI
515
+ - 新增 Data URI 格式验证(MIME 类型、大小限制)
516
+
446
517
  ### [1.1.0] - 2025-11-13
447
518
 
448
519
  #### 新增
package/build/config.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * 配置管理模块
3
3
  * 从环境变量读取配置
4
4
  */
5
- export type ModelProvider = 'zhipu' | 'siliconflow';
5
+ export type ModelProvider = 'zhipu' | 'siliconflow' | 'qwen';
6
6
  export interface LumaConfig {
7
7
  provider: ModelProvider;
8
8
  apiKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,aAAa,CAAC;AAEpD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,UAAU,CAiCvC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,aAAa,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,UAAU,CAwCvC"}
package/build/config.js CHANGED
@@ -18,6 +18,13 @@ export function loadConfig() {
18
18
  throw new Error('SILICONFLOW_API_KEY environment variable is required when using SiliconFlow provider');
19
19
  }
20
20
  }
21
+ else if (provider === 'qwen') {
22
+ apiKey = process.env.DASHSCOPE_API_KEY;
23
+ defaultModel = 'qwen3-vl-flash';
24
+ if (!apiKey) {
25
+ throw new Error('DASHSCOPE_API_KEY environment variable is required when using Qwen provider');
26
+ }
27
+ }
21
28
  else {
22
29
  apiKey = process.env.ZHIPU_API_KEY;
23
30
  defaultModel = 'glm-4.5v';
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,aAAa;IACb,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,EAAE,IAAI,OAAO,CAAkB,CAAC;IAEzF,kBAAkB;IAClB,IAAI,MAA0B,CAAC;IAC/B,IAAI,YAAoB,CAAC;IAEzB,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;QAC/B,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACzC,YAAY,GAAG,0BAA0B,CAAC;QAE1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,sFAAsF,CAAC,CAAC;QAC1G,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QACnC,YAAY,GAAG,UAAU,CAAC;QAE1B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAED,OAAO;QACL,QAAQ;QACR,MAAM;QACN,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,YAAY;QAC7C,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,MAAM,EAAE,EAAE,CAAC;QACzD,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,KAAK,CAAC;QACzD,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC;QAC5C,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM;KACvD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,aAAa;IACb,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,EAAE,IAAI,OAAO,CAAkB,CAAC;IAEzF,kBAAkB;IAClB,IAAI,MAA0B,CAAC;IAC/B,IAAI,YAAoB,CAAC;IAEzB,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;QAC/B,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACzC,YAAY,GAAG,0BAA0B,CAAC;QAE1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,sFAAsF,CAAC,CAAC;QAC1G,CAAC;IACH,CAAC;SAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC/B,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QACvC,YAAY,GAAG,gBAAgB,CAAC;QAEhC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QACnC,YAAY,GAAG,UAAU,CAAC;QAE1B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAED,OAAO;QACL,QAAQ;QACR,MAAM;QACN,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,YAAY;QAC7C,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,MAAM,EAAE,EAAE,CAAC;QACzD,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,KAAK,CAAC;QACzD,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC;QAC5C,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM;KACvD,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"image-processor.d.ts","sourceRoot":"","sources":["../src/image-processor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BpG;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBtE"}
1
+ {"version":3,"file":"image-processor.d.ts","sourceRoot":"","sources":["../src/image-processor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA6BH;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA6CpG;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BtE"}
@@ -7,10 +7,45 @@ import { readFile, stat } from 'fs/promises';
7
7
  import sharp from 'sharp';
8
8
  import { isUrl } from './utils/helpers.js';
9
9
  import { logger } from './utils/logger.js';
10
+ // 判断是否为 Data URI(data:image/png;base64,....)
11
+ function isDataUri(input) {
12
+ return typeof input === 'string' && input.startsWith('data:') && /;base64,/.test(input);
13
+ }
14
+ // 从 Data URI 获取 mimeType
15
+ function getMimeFromDataUri(input) {
16
+ const match = input.match(/^data:([^;]+);base64,/i);
17
+ return match ? match[1].toLowerCase() : null;
18
+ }
19
+ // 估算 Data URI 的原始字节大小(不含头部)
20
+ function estimateBytesFromDataUri(input) {
21
+ try {
22
+ const base64 = input.split(',')[1] || '';
23
+ // base64 长度 * 3/4,忽略 padding 近似即可
24
+ return Math.floor((base64.length * 3) / 4);
25
+ }
26
+ catch {
27
+ return 0;
28
+ }
29
+ }
10
30
  /**
11
31
  * 验证图片来源(文件或URL)
12
32
  */
13
33
  export async function validateImageSource(imageSource, maxSizeMB = 10) {
34
+ // 如果是 Data URI,则验证 mime 与大小后直接返回
35
+ if (isDataUri(imageSource)) {
36
+ const mime = getMimeFromDataUri(imageSource);
37
+ const allowed = ['image/png', 'image/jpeg', 'image/jpg', 'image/webp', 'image/gif'];
38
+ if (!mime || !allowed.includes(mime)) {
39
+ throw new Error(`Unsupported data URI mimeType: ${mime || 'unknown'}. Supported: ${allowed.join(', ')}`);
40
+ }
41
+ const bytes = estimateBytesFromDataUri(imageSource);
42
+ const sizeMB = bytes / (1024 * 1024);
43
+ if (sizeMB > maxSizeMB) {
44
+ throw new Error(`Image data URI too large: ${sizeMB.toFixed(2)}MB (max: ${maxSizeMB}MB)`);
45
+ }
46
+ logger.debug('Image source is data URI, validated', { mime, sizeMB: sizeMB.toFixed(2) });
47
+ return;
48
+ }
14
49
  // 如果是URL,直接返回
15
50
  if (isUrl(imageSource)) {
16
51
  logger.debug('Image source is URL, skipping validation', { imageSource });
@@ -42,6 +77,11 @@ export async function validateImageSource(imageSource, maxSizeMB = 10) {
42
77
  */
43
78
  export async function imageToBase64(imagePath) {
44
79
  try {
80
+ // 如果是 Data URI,直接返回(已是 data:*;base64, 格式)
81
+ if (isDataUri(imagePath)) {
82
+ logger.info('Using data URI image');
83
+ return imagePath;
84
+ }
45
85
  // 如果是URL,直接返回
46
86
  if (isUrl(imagePath)) {
47
87
  logger.info('Using remote image URL', { url: imagePath });
@@ -1 +1 @@
1
- {"version":3,"file":"image-processor.js","sourceRoot":"","sources":["../src/image-processor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"image-processor.js","sourceRoot":"","sources":["../src/image-processor.ts"],"names":[],"mappings":"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"}
package/build/index.js CHANGED
@@ -12,6 +12,7 @@ import { z } from 'zod';
12
12
  import { loadConfig } from './config.js';
13
13
  import { ZhipuClient } from './zhipu-client.js';
14
14
  import { SiliconFlowClient } from './siliconflow-client.js';
15
+ import { QwenClient } from './qwen-client.js';
15
16
  import { imageToBase64, validateImageSource } from './image-processor.js';
16
17
  import { buildAnalysisPrompt } from './prompts.js';
17
18
  import { withRetry, createSuccessResponse, createErrorResponse } from './utils/helpers.js';
@@ -23,9 +24,16 @@ async function createServer() {
23
24
  // 加载配置
24
25
  const config = loadConfig();
25
26
  // 根据配置选择模型客户端
26
- const visionClient = config.provider === 'siliconflow'
27
- ? new SiliconFlowClient(config)
28
- : new ZhipuClient(config);
27
+ let visionClient;
28
+ if (config.provider === 'siliconflow') {
29
+ visionClient = new SiliconFlowClient(config.apiKey, config.model, config.maxTokens, config.temperature);
30
+ }
31
+ else if (config.provider === 'qwen') {
32
+ visionClient = new QwenClient(config.apiKey, config.model, config.maxTokens, config.temperature);
33
+ }
34
+ else {
35
+ visionClient = new ZhipuClient(config.apiKey, config.model, config.maxTokens, config.temperature, config.topP);
36
+ }
29
37
  logger.info('Vision client initialized', {
30
38
  provider: config.provider,
31
39
  model: visionClient.getModelName()
@@ -47,16 +55,20 @@ async function createServer() {
47
55
  const imageDataUrl = await imageToBase64(imageSource);
48
56
  // 3. 构建提示词
49
57
  // DeepSeek-OCR 需要简洁的 prompt,不支持复杂格式化
58
+ // Qwen/GLM 使用结构化 prompt
50
59
  const fullPrompt = config.provider === 'siliconflow'
51
60
  ? prompt // DeepSeek-OCR: 直接使用原始 prompt
52
- : buildAnalysisPrompt(prompt); // GLM-4.5V: 使用结构化 prompt
61
+ : buildAnalysisPrompt(prompt); // Qwen/GLM: 使用结构化 prompt
53
62
  // 4. 调用视觉模型分析图片
54
63
  return await visionClient.analyzeImage(imageDataUrl, fullPrompt);
55
64
  }, 2, // 最多重试2次
56
65
  1000 // 初始延补1秒
57
66
  );
58
67
  // 注册工具 - 使用 McpServer.tool() API
59
- server.tool('analyze_image', `使用视觉模型分析图片内容。支持 GLM-4.5V(智谱)和 DeepSeek-OCR(硅基流动)。
68
+ server.tool('analyze_image', `使用视觉模型分析图片内容。支持三个视觉模型:
69
+ - GLM-4.5V(智谱清言)- 付费,中文理解优秀
70
+ - DeepSeek-OCR(硅基流动)- 免费,OCR能力强
71
+ - Qwen3-VL-Flash(阿里云通义千问)- 付费,速度快成本低,支持思考模式
60
72
 
61
73
  **何时自动调用此工具**:
62
74
  1. 用户提供了图片文件路径(包括临时路径、相对路径、绝对路径)
@@ -70,7 +82,7 @@ async function createServer() {
70
82
  **支持来源**:本地文件、远程URL、临时文件(包括截图)。
71
83
 
72
84
  如果你是不支持视觉的AI模型,看到图片路径时应主动调用此工具来分析图片内容。`, {
73
- image_source: z.string().describe('图片来源:本地文件路径(含临时路径)、远程URL。支持 PNG/JPG/WebP/GIF。例如:"./image.png"、"/tmp/screenshot.png"、"C:\\Users\\...\\image.jpg"、"https://example.com/pic.jpg"'),
85
+ image_source: z.string().describe('图片来源:支持三种格式:1) 本地文件路径(含临时路径)、2) 远程URL(https://)、3) Data URI(data:image/png;base64,...)。支持 PNG/JPG/WebP/GIF。例如:"./image.png"、"/tmp/screenshot.png"、"C:\\Users\\...\\image.jpg"、"https://example.com/pic.jpg"、"data:image/png;base64,iVBORw0KG..."'),
74
86
  prompt: z.string().describe('必须:详细的分析指令。如果用户没有提供具体问题,默认使用:"请详细分析这张图片的内容"。对于具体任务:代码分析、UI设计、错误诊断、文字识别等,应提供明确的指令。例如:"这段代码为什么报错?"、"分析这个UI的布局和风格"、"识别图片中的所有文字"'),
75
87
  }, async (params) => {
76
88
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 阿里云通义千问VL客户端
3
+ * 使用 OpenAI 兼容接口
4
+ * API 文档: https://help.aliyun.com/zh/model-studio/vision
5
+ */
6
+ import { VisionClient } from './vision-client.js';
7
+ export declare class QwenClient implements VisionClient {
8
+ private client;
9
+ private apiKey;
10
+ private model;
11
+ private maxTokens;
12
+ private temperature;
13
+ constructor(apiKey: string, model?: string, maxTokens?: number, temperature?: number);
14
+ analyzeImage(imageDataUrl: string, prompt: string, enableThinking?: boolean): Promise<string>;
15
+ getModelName(): string;
16
+ }
17
+ //# sourceMappingURL=qwen-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qwen-client.d.ts","sourceRoot":"","sources":["../src/qwen-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,qBAAa,UAAW,YAAW,YAAY;IAC7C,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAyB,EAAE,SAAS,GAAE,MAAa,EAAE,WAAW,GAAE,MAAY;IAiB3G,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAoDnG,YAAY,IAAI,MAAM;CAGvB"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * 阿里云通义千问VL客户端
3
+ * 使用 OpenAI 兼容接口
4
+ * API 文档: https://help.aliyun.com/zh/model-studio/vision
5
+ */
6
+ import axios from 'axios';
7
+ import { buildAnalysisPrompt } from './prompts.js';
8
+ export class QwenClient {
9
+ client;
10
+ apiKey;
11
+ model;
12
+ maxTokens;
13
+ temperature;
14
+ constructor(apiKey, model = 'qwen3-vl-flash', maxTokens = 4096, temperature = 0.7) {
15
+ this.apiKey = apiKey;
16
+ this.model = model;
17
+ this.maxTokens = maxTokens;
18
+ this.temperature = temperature;
19
+ // 使用阿里云百炼的 OpenAI 兼容接口
20
+ this.client = axios.create({
21
+ baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
22
+ headers: {
23
+ 'Authorization': `Bearer ${apiKey}`,
24
+ 'Content-Type': 'application/json',
25
+ },
26
+ timeout: 180000, // 180秒超时
27
+ });
28
+ }
29
+ async analyzeImage(imageDataUrl, prompt, enableThinking) {
30
+ try {
31
+ // Qwen3-VL 支持思考模式,使用 extra_body 传递非标准参数
32
+ const requestBody = {
33
+ model: this.model,
34
+ messages: [
35
+ {
36
+ role: 'user',
37
+ content: [
38
+ {
39
+ type: 'image_url',
40
+ image_url: {
41
+ url: imageDataUrl
42
+ }
43
+ },
44
+ {
45
+ type: 'text',
46
+ text: buildAnalysisPrompt(prompt)
47
+ }
48
+ ]
49
+ }
50
+ ],
51
+ max_tokens: this.maxTokens,
52
+ temperature: this.temperature,
53
+ stream: false
54
+ };
55
+ // 如果启用思考模式,添加 extra_body 参数
56
+ if (enableThinking) {
57
+ requestBody.extra_body = {
58
+ enable_thinking: true,
59
+ thinking_budget: 81920 // 最大思考 Token 数
60
+ };
61
+ }
62
+ const response = await this.client.post('/chat/completions', requestBody);
63
+ if (!response.data?.choices?.[0]?.message?.content) {
64
+ throw new Error('Invalid response format from Qwen API');
65
+ }
66
+ return response.data.choices[0].message.content;
67
+ }
68
+ catch (error) {
69
+ if (axios.isAxiosError(error)) {
70
+ const errorMessage = error.response?.data?.error?.message || error.message;
71
+ throw new Error(`Qwen API error: ${errorMessage}`);
72
+ }
73
+ throw error;
74
+ }
75
+ }
76
+ getModelName() {
77
+ return `Qwen (${this.model})`;
78
+ }
79
+ }
80
+ //# sourceMappingURL=qwen-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qwen-client.js","sourceRoot":"","sources":["../src/qwen-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAwB,MAAM,OAAO,CAAC;AAE7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,OAAO,UAAU;IACb,MAAM,CAAgB;IACtB,MAAM,CAAS;IACf,KAAK,CAAS;IACd,SAAS,CAAS;IAClB,WAAW,CAAS;IAE5B,YAAY,MAAc,EAAE,QAAgB,gBAAgB,EAAE,YAAoB,IAAI,EAAE,cAAsB,GAAG;QAC/G,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAE/B,uBAAuB;QACvB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YACzB,OAAO,EAAE,mDAAmD;YAC5D,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,MAAM,EAAE;gBACnC,cAAc,EAAE,kBAAkB;aACnC;YACD,OAAO,EAAE,MAAM,EAAE,SAAS;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,YAAoB,EAAE,MAAc,EAAE,cAAwB;QAC/E,IAAI,CAAC;YACH,wCAAwC;YACxC,MAAM,WAAW,GAAQ;gBACvB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,WAAW;gCACjB,SAAS,EAAE;oCACT,GAAG,EAAE,YAAY;iCAClB;6BACF;4BACD;gCACE,IAAI,EAAE,MAAM;gCACZ,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC;6BAClC;yBACF;qBACF;iBACF;gBACD,UAAU,EAAE,IAAI,CAAC,SAAS;gBAC1B,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,MAAM,EAAE,KAAK;aACd,CAAC;YAEF,4BAA4B;YAC5B,IAAI,cAAc,EAAE,CAAC;gBACnB,WAAW,CAAC,UAAU,GAAG;oBACvB,eAAe,EAAE,IAAI;oBACrB,eAAe,EAAE,KAAK,CAAE,eAAe;iBACxC,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;YAE1E,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;gBACnD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;YAC3D,CAAC;YAED,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;QAElD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC;gBAC3E,MAAM,IAAI,KAAK,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,YAAY;QACV,OAAO,SAAS,IAAI,CAAC,KAAK,GAAG,CAAC;IAChC,CAAC;CACF"}
@@ -2,15 +2,17 @@
2
2
  * 硅基流动 DeepSeek-OCR API 客户端
3
3
  * 基于 OpenAI 兼容 API
4
4
  */
5
- import type { LumaConfig } from './config.js';
6
5
  import type { VisionClient } from './vision-client.js';
7
6
  /**
8
7
  * 硅基流动 API 客户端
9
8
  */
10
9
  export declare class SiliconFlowClient implements VisionClient {
11
- private config;
10
+ private apiKey;
11
+ private model;
12
+ private maxTokens;
13
+ private temperature;
12
14
  private apiEndpoint;
13
- constructor(config: LumaConfig);
15
+ constructor(apiKey: string, model?: string, maxTokens?: number, temperature?: number);
14
16
  /**
15
17
  * 分析图片
16
18
  */
@@ -1 +1 @@
1
- {"version":3,"file":"siliconflow-client.d.ts","sourceRoot":"","sources":["../src/siliconflow-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA2CvD;;GAEG;AACH,qBAAa,iBAAkB,YAAW,YAAY;IACpD,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,WAAW,CAAoD;gBAE3D,MAAM,EAAE,UAAU;IAI9B;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAsEnG;;OAEG;IACH,YAAY,IAAI,MAAM;CAGvB"}
1
+ {"version":3,"file":"siliconflow-client.d.ts","sourceRoot":"","sources":["../src/siliconflow-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA2CvD;;GAEG;AACH,qBAAa,iBAAkB,YAAW,YAAY;IACpD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAoD;gBAE3D,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAmC,EAAE,SAAS,GAAE,MAAa,EAAE,WAAW,GAAE,MAAY;IAO3H;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAqEnG;;OAEG;IACH,YAAY,IAAI,MAAM;CAGvB"}
@@ -8,17 +8,23 @@ import { logger } from './utils/logger.js';
8
8
  * 硅基流动 API 客户端
9
9
  */
10
10
  export class SiliconFlowClient {
11
- config;
11
+ apiKey;
12
+ model;
13
+ maxTokens;
14
+ temperature;
12
15
  apiEndpoint = 'https://api.siliconflow.cn/v1/chat/completions';
13
- constructor(config) {
14
- this.config = config;
16
+ constructor(apiKey, model = 'deepseek-ai/DeepSeek-OCR', maxTokens = 4096, temperature = 0.7) {
17
+ this.apiKey = apiKey;
18
+ this.model = model;
19
+ this.maxTokens = maxTokens;
20
+ this.temperature = temperature;
15
21
  }
16
22
  /**
17
23
  * 分析图片
18
24
  */
19
25
  async analyzeImage(imageDataUrl, prompt, enableThinking) {
20
26
  const requestBody = {
21
- model: this.config.model,
27
+ model: this.model,
22
28
  messages: [
23
29
  {
24
30
  role: 'user',
@@ -36,18 +42,17 @@ export class SiliconFlowClient {
36
42
  ],
37
43
  },
38
44
  ],
39
- temperature: this.config.temperature,
40
- max_tokens: this.config.maxTokens,
41
- top_p: this.config.topP,
45
+ temperature: this.temperature,
46
+ max_tokens: this.maxTokens,
42
47
  stream: false,
43
48
  };
44
49
  logger.info('Calling SiliconFlow DeepSeek-OCR API', {
45
- model: this.config.model,
50
+ model: this.model,
46
51
  });
47
52
  try {
48
53
  const response = await axios.post(this.apiEndpoint, requestBody, {
49
54
  headers: {
50
- 'Authorization': `Bearer ${this.config.apiKey}`,
55
+ 'Authorization': `Bearer ${this.apiKey}`,
51
56
  'Content-Type': 'application/json',
52
57
  },
53
58
  timeout: 60000, // 60秒超时
@@ -79,7 +84,7 @@ export class SiliconFlowClient {
79
84
  * 获取模型名称
80
85
  */
81
86
  getModelName() {
82
- return this.config.model;
87
+ return `DeepSeek (${this.model})`;
83
88
  }
84
89
  }
85
90
  //# sourceMappingURL=siliconflow-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"siliconflow-client.js","sourceRoot":"","sources":["../src/siliconflow-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"siliconflow-client.js","sourceRoot":"","sources":["../src/siliconflow-client.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,18 @@
1
1
  /**
2
2
  * 智谱 GLM-4.5V API 客户端
3
3
  */
4
- import type { LumaConfig } from './config.js';
5
4
  import type { VisionClient } from './vision-client.js';
6
5
  /**
7
6
  * 智谱 API 客户端
8
7
  */
9
8
  export declare class ZhipuClient implements VisionClient {
10
- private config;
9
+ private apiKey;
10
+ private model;
11
+ private maxTokens;
12
+ private temperature;
13
+ private topP;
11
14
  private apiEndpoint;
12
- constructor(config: LumaConfig);
15
+ constructor(apiKey: string, model?: string, maxTokens?: number, temperature?: number, topP?: number);
13
16
  /**
14
17
  * 分析图片
15
18
  */
@@ -1 +1 @@
1
- {"version":3,"file":"zhipu-client.d.ts","sourceRoot":"","sources":["../src/zhipu-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA4CvD;;GAEG;AACH,qBAAa,WAAY,YAAW,YAAY;IAC9C,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,WAAW,CAA2D;gBAElE,MAAM,EAAE,UAAU;IAI9B;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IA4EnG;;OAEG;IACH,YAAY,IAAI,MAAM;CAGvB"}
1
+ {"version":3,"file":"zhipu-client.d.ts","sourceRoot":"","sources":["../src/zhipu-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA4CvD;;GAEG;AACH,qBAAa,WAAY,YAAW,YAAY;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,WAAW,CAA2D;gBAElE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAmB,EAAE,SAAS,GAAE,MAAa,EAAE,WAAW,GAAE,MAAY,EAAE,IAAI,GAAE,MAAY;IAQ/H;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IA4EnG;;OAEG;IACH,YAAY,IAAI,MAAM;CAGvB"}
@@ -7,17 +7,25 @@ import { logger } from './utils/logger.js';
7
7
  * 智谱 API 客户端
8
8
  */
9
9
  export class ZhipuClient {
10
- config;
10
+ apiKey;
11
+ model;
12
+ maxTokens;
13
+ temperature;
14
+ topP;
11
15
  apiEndpoint = 'https://open.bigmodel.cn/api/paas/v4/chat/completions';
12
- constructor(config) {
13
- this.config = config;
16
+ constructor(apiKey, model = 'glm-4.5v', maxTokens = 4096, temperature = 0.7, topP = 0.7) {
17
+ this.apiKey = apiKey;
18
+ this.model = model;
19
+ this.maxTokens = maxTokens;
20
+ this.temperature = temperature;
21
+ this.topP = topP;
14
22
  }
15
23
  /**
16
24
  * 分析图片
17
25
  */
18
26
  async analyzeImage(imageDataUrl, prompt, enableThinking) {
19
27
  const requestBody = {
20
- model: this.config.model,
28
+ model: this.model,
21
29
  messages: [
22
30
  {
23
31
  role: 'user',
@@ -35,23 +43,23 @@ export class ZhipuClient {
35
43
  ],
36
44
  },
37
45
  ],
38
- temperature: this.config.temperature,
39
- max_tokens: this.config.maxTokens,
40
- top_p: this.config.topP,
46
+ temperature: this.temperature,
47
+ max_tokens: this.maxTokens,
48
+ top_p: this.topP,
41
49
  thinking: { type: 'enabled' }, // 默认启用思考模式,提高分析准确性
42
50
  };
43
51
  // 允许显式禁用 thinking(如需要更快速度)
44
- if (this.config.enableThinking === false || enableThinking === false) {
52
+ if (enableThinking === false) {
45
53
  delete requestBody.thinking;
46
54
  }
47
55
  logger.info('Calling GLM-4.5V API', {
48
- model: this.config.model,
56
+ model: this.model,
49
57
  thinking: !!requestBody.thinking
50
58
  });
51
59
  try {
52
60
  const response = await axios.post(this.apiEndpoint, requestBody, {
53
61
  headers: {
54
- 'Authorization': `Bearer ${this.config.apiKey}`,
62
+ 'Authorization': `Bearer ${this.apiKey}`,
55
63
  'Content-Type': 'application/json',
56
64
  },
57
65
  timeout: 60000, // 60秒超时
@@ -83,7 +91,7 @@ export class ZhipuClient {
83
91
  * 获取模型名称
84
92
  */
85
93
  getModelName() {
86
- return this.config.model;
94
+ return `GLM (${this.model})`;
87
95
  }
88
96
  }
89
97
  //# sourceMappingURL=zhipu-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"zhipu-client.js","sourceRoot":"","sources":["../src/zhipu-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"zhipu-client.js","sourceRoot":"","sources":["../src/zhipu-client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "luma-mcp",
3
- "version": "1.1.0",
4
- "description": "Multi-model vision understanding MCP server. Supports GLM-4.5V (Zhipu) and DeepSeek-OCR (SiliconFlow - Free)",
3
+ "version": "1.2.0",
4
+ "description": "Multi-model vision understanding MCP server. Supports GLM-4.5V (Zhipu), DeepSeek-OCR (SiliconFlow - Free), and Qwen3-VL-Plus (Aliyun)",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "luma-mcp": "build/index.js"
@@ -21,6 +21,9 @@
21
21
  "zhipu",
22
22
  "deepseek-ocr",
23
23
  "siliconflow",
24
+ "qwen3-vl",
25
+ "aliyun",
26
+ "dashscope",
24
27
  "ocr",
25
28
  "free",
26
29
  "image-understanding",
@@ -0,0 +1,64 @@
1
+ /**
2
+ * 测试 Data URI 支持
3
+ */
4
+
5
+ import { validateImageSource, imageToBase64 } from '../src/image-processor.js';
6
+
7
+ // 一个有效的 1x1 像素 PNG 图片的 Data URI
8
+ const validDataUri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
9
+
10
+ // 无效的 Data URI(不支持的格式)
11
+ const invalidDataUri = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgc3R5bGU9ImZpbGw6I2ZmZiIgLz48L3N2Zz4=';
12
+
13
+ async function testDataUri() {
14
+ console.log('🧪 测试 Data URI 支持\n');
15
+
16
+ // 测试 1: 验证有效的 Data URI
17
+ try {
18
+ console.log('测试 1: 验证有效的 PNG Data URI');
19
+ await validateImageSource(validDataUri);
20
+ console.log('✅ 通过:有效的 Data URI 验证成功\n');
21
+ } catch (error) {
22
+ console.log(`❌ 失败: ${error instanceof Error ? error.message : String(error)}\n`);
23
+ }
24
+
25
+ // 测试 2: 验证无效的 Data URI(不支持的格式)
26
+ try {
27
+ console.log('测试 2: 验证不支持的格式 (SVG)');
28
+ await validateImageSource(invalidDataUri);
29
+ console.log('❌ 失败:应该抛出错误\n');
30
+ } catch (error) {
31
+ console.log(`✅ 通过:正确拒绝不支持的格式 - ${error instanceof Error ? error.message : String(error)}\n`);
32
+ }
33
+
34
+ // 测试 3: Data URI 转换(应该直接返回)
35
+ try {
36
+ console.log('测试 3: Data URI 转换');
37
+ const result = await imageToBase64(validDataUri);
38
+ if (result === validDataUri) {
39
+ console.log('✅ 通过:Data URI 正确传递(未修改)\n');
40
+ } else {
41
+ console.log('❌ 失败:Data URI 被修改了\n');
42
+ }
43
+ } catch (error) {
44
+ console.log(`❌ 失败: ${error instanceof Error ? error.message : String(error)}\n`);
45
+ }
46
+
47
+ // 测试 4: 大小验证(创建一个超过10MB的Data URI)
48
+ try {
49
+ console.log('测试 4: 验证大小限制 (>10MB)');
50
+ // 创建一个约 15MB 的 base64 字符串(20MB * 3/4 = 15MB)
51
+ const largeBase64 = 'A'.repeat(20 * 1024 * 1024);
52
+ const largeDataUri = `data:image/png;base64,${largeBase64}`;
53
+ await validateImageSource(largeDataUri);
54
+ console.log('❌ 失败:应该拒绝过大的文件\n');
55
+ } catch (error) {
56
+ console.log(`✅ 通过:正确拒绝超大文件 - ${error instanceof Error ? error.message : String(error)}\n`);
57
+ }
58
+
59
+ console.log('==========================================');
60
+ console.log('✅ Data URI 测试完成!');
61
+ console.log('==========================================\n');
62
+ }
63
+
64
+ testDataUri().catch(console.error);
@@ -9,7 +9,13 @@ import * as path from 'path';
9
9
  async function testDeepSeekOCR(imagePath: string) {
10
10
  console.log('\n🧪 测试 DeepSeek-OCR API(原始调用)\n');
11
11
 
12
- const apiKey = 'sk-skrldwndjawxvzzomztwmoinnwmvumezqyejysqutjwkjcdt';
12
+ const apiKey = process.env.SILICONFLOW_API_KEY;
13
+
14
+ if (!apiKey) {
15
+ console.error('❌ 错误: 需要设置 SILICONFLOW_API_KEY 环境变量');
16
+ console.error('示例: $env:SILICONFLOW_API_KEY="your-api-key"');
17
+ process.exit(1);
18
+ }
13
19
 
14
20
  // 读取图片并转为 base64
15
21
  const imageBuffer = fs.readFileSync(imagePath);
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Qwen 客户端测试
3
+ * 测试阿里云通义千问VL视觉理解
4
+ */
5
+
6
+ import { QwenClient } from '../src/qwen-client.js';
7
+ import { imageToBase64 } from '../src/image-processor.js';
8
+
9
+ async function testQwen() {
10
+ const apiKey = process.env.DASHSCOPE_API_KEY;
11
+
12
+ if (!apiKey) {
13
+ console.error('❌ 错误: 需要设置 DASHSCOPE_API_KEY 环境变量');
14
+ console.log('设置方法:');
15
+ console.log(' macOS/Linux: export DASHSCOPE_API_KEY="your-api-key"');
16
+ console.log(' Windows: $env:DASHSCOPE_API_KEY="your-api-key"');
17
+ process.exit(1);
18
+ }
19
+
20
+ // 获取图片路径
21
+ const imagePath = process.argv[2];
22
+ if (!imagePath) {
23
+ console.error('❌ 错误: 请提供图片路径');
24
+ console.log('用法: tsx test/test-qwen.ts <图片路径>');
25
+ console.log('示例: tsx test/test-qwen.ts ./test.png');
26
+ process.exit(1);
27
+ }
28
+
29
+ console.log('🚀 开始测试 Qwen3-VL-Flash...\n');
30
+
31
+ try {
32
+ // 1. 初始化客户端
33
+ console.log('1️⃣ 初始化 Qwen 客户端...');
34
+ const client = new QwenClient(
35
+ apiKey,
36
+ 'qwen3-vl-flash', // 使用高性价比的 Flash 版本
37
+ 4096,
38
+ 0.7
39
+ );
40
+ console.log(`✅ 客户端初始化成功: ${client.getModelName()}\n`);
41
+
42
+ // 2. 读取图片
43
+ console.log('2️⃣ 读取图片...');
44
+ const imageData = await imageToBase64(imagePath);
45
+ console.log(`✅ 图片读取成功 (${imagePath})\n`);
46
+
47
+ // 3. 测试基础分析
48
+ console.log('3️⃣ 测试基础分析(不启用思考模式)...');
49
+ const basicResult = await client.analyzeImage(
50
+ imageData,
51
+ '请详细分析这张图片的内容',
52
+ false
53
+ );
54
+ console.log('📊 基础分析结果:');
55
+ console.log(basicResult);
56
+ console.log('\n');
57
+
58
+ // 4. 测试思考模式
59
+ console.log('4️⃣ 测试思考模式(enable_thinking=true)...');
60
+ const thinkingResult = await client.analyzeImage(
61
+ imageData,
62
+ '请详细分析这张图片的内容,包括所有细节',
63
+ true // 启用思考模式
64
+ );
65
+ console.log('🧠 思考模式分析结果:');
66
+ console.log(thinkingResult);
67
+ console.log('\n');
68
+
69
+ // 5. 测试 OCR
70
+ console.log('5️⃣ 测试 OCR 能力...');
71
+ const ocrResult = await client.analyzeImage(
72
+ imageData,
73
+ '识别图片中的所有文字',
74
+ false
75
+ );
76
+ console.log('📝 OCR 结果:');
77
+ console.log(ocrResult);
78
+ console.log('\n');
79
+
80
+ console.log('✅ 所有测试完成!');
81
+
82
+ } catch (error) {
83
+ console.error('❌ 测试失败:', error instanceof Error ? error.message : error);
84
+ process.exit(1);
85
+ }
86
+ }
87
+
88
+ testQwen();