luma-mcp 1.2.1 → 1.2.3

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.
@@ -17,18 +17,6 @@ jobs:
17
17
  with:
18
18
  fetch-depth: 0
19
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
20
  - name: Extract version from tag
33
21
  id: version
34
22
  run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
@@ -59,8 +47,3 @@ jobs:
59
47
  prerelease: false
60
48
  env:
61
49
  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,39 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.2.3] - 2025-11-21
6
+
7
+ ### Changed
8
+ - 🧹 **代码清理**: 移除 Claude 特定调试注释和实验性代码
9
+ - 📝 **工具描述优化**: 简化和专业化工具说明,提升 AI 模型调用成功率
10
+ - 🔧 **路径处理通用化**: 重构 @ 前缀路径处理,移除平台特定命名
11
+
12
+ ### Technical Details
13
+ - 移除 Claude 资源读取相关的实验性代码
14
+ - 重命名 `stripAtPrefix()` 为 `normalizeImageSourcePath()`
15
+ - 清理所有客户端适配器中的调试日志和注释
16
+ - 统一代码风格和注释规范
17
+
18
+ ## [1.2.2] - 2025-11-20
19
+
20
+ ### Added
21
+ - ✨ **@ 路径支持**: 自动处理 Claude Code 的 @ 文件引用前缀,修复第一次调用失败的问题
22
+ - 📝 **智能 Prompt**: 通用请求自动添加详细指引,保证全面分析
23
+
24
+ ### Changed
25
+ - 🔧 **Prompt 统一**: 简化为单一通用 prompt,智能处理不同场景
26
+ - ✨ **表述优化**: 融合 Minimax 的经典表述,强调“不遗漏细节”和“完整提取”
27
+ - 📚 **文档更新**: 更新项目结构,添加 qwen-client.ts 和测试文件
28
+
29
+ ### Fixed
30
+ - 🐛 **@ 路径问题**: 修复 Claude Code 中 `@folder/image.png` 导致的路径错误
31
+ - 🐛 **编译错误**: 修复 image-processor.ts 中重复声明的变量
32
+
33
+ ### Technical Details
34
+ - 新增 `stripAtPrefix()` 函数处理 Claude Code 的文件引用语法
35
+ - 简化 `buildAnalysisPrompt()` 从两套逻辑到单一逻辑
36
+ - 添加智能请求检测,自动补充详细分析指引
37
+
5
38
  ## [1.2.1] - 2025-11-18
6
39
 
7
40
  ### Changed
package/README.md CHANGED
@@ -412,13 +412,17 @@ luma-mcp/
412
412
  │ ├── vision-client.ts # 视觉模型客户端接口
413
413
  │ ├── zhipu-client.ts # GLM-4.5V API 客户端
414
414
  │ ├── siliconflow-client.ts # DeepSeek-OCR API 客户端
415
+ │ ├── qwen-client.ts # Qwen3-VL API 客户端
415
416
  │ ├── image-processor.ts # 图片处理
416
417
  │ ├── prompts.ts # 提示词模板
417
418
  │ └── utils/
418
419
  │ ├── logger.ts # 日志工具
419
420
  │ └── helpers.ts # 工具函数
420
421
  ├── test/
421
- └── test-local.ts # 本地测试脚本
422
+ ├── test-local.ts # 本地测试脚本
423
+ │ ├── test-qwen.ts # Qwen 测试脚本
424
+ │ ├── test-deepseek-raw.ts # DeepSeek 原始测试脚本
425
+ │ └── test-data-uri.ts # Data URI 测试脚本
422
426
  ├── docs/
423
427
  │ ├── design.md # 设计文档
424
428
  │ ├── installation.md # 安装指南
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * 图片处理工具
3
- * 负责读取、压缩和编码图片
4
- * 支持本地文件和远程URL
3
+ * 负责读取、压缩和编码图片(支持本地文件和远程 URL)
5
4
  */
6
5
  /**
7
6
  * 验证图片来源(文件或URL)
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"image-processor.d.ts","sourceRoot":"","sources":["../src/image-processor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiDH;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,MAAW,GACrB,OAAO,CAAC,IAAI,CAAC,CAsCf;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkCtE"}
@@ -1,15 +1,16 @@
1
1
  /**
2
2
  * 图片处理工具
3
- * 负责读取、压缩和编码图片
4
- * 支持本地文件和远程URL
3
+ * 负责读取、压缩和编码图片(支持本地文件和远程 URL)
5
4
  */
6
- import { readFile, stat } from 'fs/promises';
7
- import sharp from 'sharp';
8
- import { isUrl } from './utils/helpers.js';
9
- import { logger } from './utils/logger.js';
5
+ import { readFile, stat } from "fs/promises";
6
+ import sharp from "sharp";
7
+ import { isUrl } from "./utils/helpers.js";
8
+ import { logger } from "./utils/logger.js";
10
9
  // 判断是否为 Data URI(data:image/png;base64,....)
11
10
  function isDataUri(input) {
12
- return typeof input === 'string' && input.startsWith('data:') && /;base64,/.test(input);
11
+ return (typeof input === "string" &&
12
+ input.startsWith("data:") &&
13
+ /;base64,/.test(input));
13
14
  }
14
15
  // 从 Data URI 获取 mimeType
15
16
  function getMimeFromDataUri(input) {
@@ -19,7 +20,7 @@ function getMimeFromDataUri(input) {
19
20
  // 估算 Data URI 的原始字节大小(不含头部)
20
21
  function estimateBytesFromDataUri(input) {
21
22
  try {
22
- const base64 = input.split(',')[1] || '';
23
+ const base64 = input.split(",")[1] || "";
23
24
  // base64 长度 * 3/4,忽略 padding 近似即可
24
25
  return Math.floor((base64.length * 3) / 4);
25
26
  }
@@ -27,47 +28,49 @@ function estimateBytesFromDataUri(input) {
27
28
  return 0;
28
29
  }
29
30
  }
31
+ /**
32
+ * 规范化本地图像路径(例如去掉前缀符号)
33
+ * 某些客户端会使用 "@path/to/file" 作为文件引用,这里统一转换为真实路径
34
+ */
35
+ function normalizeImageSourcePath(source) {
36
+ if (typeof source === "string" && source.startsWith("@")) {
37
+ const normalized = source.slice(1);
38
+ logger.debug("Normalized @-prefixed image path", {
39
+ original: source,
40
+ normalized,
41
+ });
42
+ return normalized;
43
+ }
44
+ return source;
45
+ }
30
46
  /**
31
47
  * 验证图片来源(文件或URL)
32
48
  */
33
49
  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
- }
49
- // 如果是URL,直接返回
50
- if (isUrl(imageSource)) {
51
- logger.debug('Image source is URL, skipping validation', { imageSource });
50
+ // 先规范化可能带有前缀符号的本地路径(如 "@image.png")
51
+ const normalizedSource = normalizeImageSourcePath(imageSource);
52
+ // 如果是 URL,直接返回
53
+ if (isUrl(normalizedSource)) {
54
+ logger.debug("Image source is URL, skipping validation");
52
55
  return;
53
56
  }
54
57
  // 验证本地文件
55
58
  try {
56
- const stats = await stat(imageSource);
59
+ const stats = await stat(normalizedSource);
57
60
  const fileSizeMB = stats.size / (1024 * 1024);
58
61
  if (fileSizeMB > maxSizeMB) {
59
62
  throw new Error(`Image file too large: ${fileSizeMB.toFixed(2)}MB (max: ${maxSizeMB}MB)`);
60
63
  }
61
64
  // 验证文件格式
62
- const ext = imageSource.toLowerCase().split('.').pop();
63
- const supportedFormats = ['jpg', 'jpeg', 'png', 'webp', 'gif'];
65
+ const ext = normalizedSource.toLowerCase().split(".").pop();
66
+ const supportedFormats = ["jpg", "jpeg", "png", "webp", "gif"];
64
67
  if (!ext || !supportedFormats.includes(ext)) {
65
- throw new Error(`Unsupported image format: ${ext}. Supported: ${supportedFormats.join(', ')}`);
68
+ throw new Error(`Unsupported image format: ${ext}. Supported: ${supportedFormats.join(", ")}`);
66
69
  }
67
70
  }
68
71
  catch (error) {
69
- if (error.code === 'ENOENT') {
70
- throw new Error(`Image file not found: ${imageSource}`);
72
+ if (error.code === "ENOENT") {
73
+ throw new Error(`Image file not found: ${normalizedSource}`);
71
74
  }
72
75
  throw error;
73
76
  }
@@ -77,30 +80,29 @@ export async function validateImageSource(imageSource, maxSizeMB = 10) {
77
80
  */
78
81
  export async function imageToBase64(imagePath) {
79
82
  try {
80
- // 如果是 Data URI,直接返回(已是 data:*;base64, 格式)
81
- if (isDataUri(imagePath)) {
82
- logger.info('Using data URI image');
83
- return imagePath;
84
- }
85
- // 如果是URL,直接返回
86
- if (isUrl(imagePath)) {
87
- logger.info('Using remote image URL', { url: imagePath });
88
- return imagePath;
83
+ // 规范化本地路径(处理可能的前缀符号)
84
+ const normalizedPath = normalizeImageSourcePath(imagePath);
85
+ // 如果是 URL,直接返回
86
+ if (isUrl(normalizedPath)) {
87
+ logger.info("Using remote image URL", { url: normalizedPath });
88
+ return normalizedPath;
89
89
  }
90
90
  // 本地文件:读取并编码
91
- let imageBuffer = await readFile(imagePath);
91
+ let imageBuffer = await readFile(normalizedPath);
92
92
  // 检查文件大小,如果超过 2MB 则压缩
93
93
  if (imageBuffer.length > 2 * 1024 * 1024) {
94
- logger.info('Compressing large image', { originalSize: `${(imageBuffer.length / (1024 * 1024)).toFixed(2)}MB` });
94
+ logger.info("Compressing large image", {
95
+ originalSize: `${(imageBuffer.length / (1024 * 1024)).toFixed(2)}MB`,
96
+ });
95
97
  imageBuffer = Buffer.from(await compressImage(imageBuffer));
96
98
  }
97
99
  // 转换为 base64
98
- const base64 = imageBuffer.toString('base64');
99
- const mimeType = getMimeType(imagePath);
100
+ const base64 = imageBuffer.toString("base64");
101
+ const mimeType = getMimeType(normalizedPath);
100
102
  return `data:${mimeType};base64,${base64}`;
101
103
  }
102
104
  catch (error) {
103
- throw new Error(`Failed to process image: ${error instanceof Error ? error.message : 'Unknown error'}`);
105
+ throw new Error(`Failed to process image: ${error instanceof Error ? error.message : "Unknown error"}`);
104
106
  }
105
107
  }
106
108
  /**
@@ -109,8 +111,8 @@ export async function imageToBase64(imagePath) {
109
111
  async function compressImage(imageBuffer) {
110
112
  return sharp(imageBuffer)
111
113
  .resize(2048, 2048, {
112
- fit: 'inside',
113
- withoutEnlargement: true
114
+ fit: "inside",
115
+ withoutEnlargement: true,
114
116
  })
115
117
  .jpeg({ quality: 85 })
116
118
  .toBuffer();
@@ -119,19 +121,19 @@ async function compressImage(imageBuffer) {
119
121
  * 根据文件扩展名获取 MIME 类型
120
122
  */
121
123
  function getMimeType(filePath) {
122
- const ext = filePath.toLowerCase().split('.').pop();
124
+ const ext = filePath.toLowerCase().split(".").pop();
123
125
  switch (ext) {
124
- case 'jpg':
125
- case 'jpeg':
126
- return 'image/jpeg';
127
- case 'png':
128
- return 'image/png';
129
- case 'webp':
130
- return 'image/webp';
131
- case 'gif':
132
- return 'image/gif';
126
+ case "jpg":
127
+ case "jpeg":
128
+ return "image/jpeg";
129
+ case "png":
130
+ return "image/png";
131
+ case "webp":
132
+ return "image/webp";
133
+ case "gif":
134
+ return "image/gif";
133
135
  default:
134
- return 'image/jpeg'; // 默认使用 jpeg
136
+ return "image/jpeg"; // 默认使用 jpeg
135
137
  }
136
138
  }
137
139
  //# sourceMappingURL=image-processor.js.map
@@ -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":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,6CAA6C;AAC7C,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;QACzB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CACvB,CAAC;AACJ,CAAC;AAED,yBAAyB;AACzB,SAAS,kBAAkB,CAAC,KAAa;IACvC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC;AAED,4BAA4B;AAC5B,SAAS,wBAAwB,CAAC,KAAa;IAC7C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,kCAAkC;QAClC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,wBAAwB,CAAC,MAAc;IAC9C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE;YAC/C,QAAQ,EAAE,MAAM;YAChB,UAAU;SACX,CAAC,CAAC;QACH,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,WAAmB,EACnB,YAAoB,EAAE;IAEtB,oCAAoC;IACpC,MAAM,gBAAgB,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC;IAE/D,eAAe;IACf,IAAI,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IAED,SAAS;IACT,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC3C,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QAE9C,IAAI,UAAU,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,yBAAyB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,SAAS,KAAK,CACzE,CAAC;QACJ,CAAC;QAED,SAAS;QACT,MAAM,GAAG,GAAG,gBAAgB,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC5D,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAE/D,IAAI,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CACb,6BAA6B,GAAG,gBAAgB,gBAAgB,CAAC,IAAI,CACnE,IAAI,CACL,EAAE,CACJ,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAAa,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,yBAAyB,gBAAgB,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,IAAI,CAAC;QACH,qBAAqB;QACrB,MAAM,cAAc,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAC;QAE3D,eAAe;QACf,IAAI,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC,CAAC;YAC/D,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,aAAa;QACb,IAAI,WAAW,GAAW,MAAM,QAAQ,CAAC,cAAc,CAAC,CAAC;QAEzD,sBAAsB;QACtB,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE;gBACrC,YAAY,EAAE,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;aACrE,CAAC,CAAC;YACH,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;QAC9D,CAAC;QAED,aAAa;QACb,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;QAE7C,OAAO,QAAQ,QAAQ,WAAW,MAAM,EAAE,CAAC;IAC7C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,4BACE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAC3C,EAAE,CACH,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa,CAAC,WAAmB;IAC9C,OAAO,KAAK,CAAC,WAAW,CAAC;SACtB,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE;QAClB,GAAG,EAAE,QAAQ;QACb,kBAAkB,EAAE,IAAI;KACzB,CAAC;SACD,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;SACrB,QAAQ,EAAE,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,QAAgB;IACnC,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAEpD,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,KAAK,CAAC;QACX,KAAK,MAAM;YACT,OAAO,YAAY,CAAC;QACtB,KAAK,KAAK;YACR,OAAO,WAAW,CAAC;QACrB,KAAK,MAAM;YACT,OAAO,YAAY,CAAC;QACtB,KAAK,KAAK;YACR,OAAO,WAAW,CAAC;QACrB;YACE,OAAO,YAAY,CAAC,CAAC,YAAY;IACrC,CAAC;AACH,CAAC"}
package/build/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * Luma MCP Server
4
- * 视觉理解 MCP 服务器,powered by GLM-4.5V
4
+ * 通用图像理解 MCP 服务器,支持多家视觉模型提供商
5
5
  */
6
6
  export {};
7
7
  //# sourceMappingURL=index.d.ts.map
package/build/index.js CHANGED
@@ -1,47 +1,47 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * Luma MCP Server
4
- * 视觉理解 MCP 服务器,powered by GLM-4.5V
4
+ * 通用图像理解 MCP 服务器,支持多家视觉模型提供商
5
5
  */
6
6
  // 第一件事:重定向console到stderr,避免污染MCP的stdout
7
- import { setupConsoleRedirection, logger } from './utils/logger.js';
7
+ import { setupConsoleRedirection, logger } from "./utils/logger.js";
8
8
  setupConsoleRedirection();
9
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
10
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
11
- import { z } from 'zod';
12
- import { loadConfig } from './config.js';
13
- import { ZhipuClient } from './zhipu-client.js';
14
- import { SiliconFlowClient } from './siliconflow-client.js';
15
- import { QwenClient } from './qwen-client.js';
16
- import { imageToBase64, validateImageSource } from './image-processor.js';
17
- import { buildAnalysisPrompt } from './prompts.js';
18
- import { withRetry, createSuccessResponse, createErrorResponse } from './utils/helpers.js';
9
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
10
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
11
+ import { z } from "zod";
12
+ import { loadConfig } from "./config.js";
13
+ import { ZhipuClient } from "./zhipu-client.js";
14
+ import { SiliconFlowClient } from "./siliconflow-client.js";
15
+ import { QwenClient } from "./qwen-client.js";
16
+ import { imageToBase64, validateImageSource } from "./image-processor.js";
17
+ import { buildAnalysisPrompt } from "./prompts.js";
18
+ import { withRetry, createSuccessResponse, createErrorResponse, } from "./utils/helpers.js";
19
19
  /**
20
20
  * 创建 MCP 服务器
21
21
  */
22
22
  async function createServer() {
23
- logger.info('Initializing Luma MCP Server');
23
+ logger.info("Initializing Luma MCP Server");
24
24
  // 加载配置
25
25
  const config = loadConfig();
26
26
  // 根据配置选择模型客户端
27
27
  let visionClient;
28
- if (config.provider === 'siliconflow') {
28
+ if (config.provider === "siliconflow") {
29
29
  visionClient = new SiliconFlowClient(config.apiKey, config.model, config.maxTokens, config.temperature);
30
30
  }
31
- else if (config.provider === 'qwen') {
31
+ else if (config.provider === "qwen") {
32
32
  visionClient = new QwenClient(config.apiKey, config.model, config.maxTokens, config.temperature);
33
33
  }
34
34
  else {
35
35
  visionClient = new ZhipuClient(config.apiKey, config.model, config.maxTokens, config.temperature, config.topP);
36
36
  }
37
- logger.info('Vision client initialized', {
37
+ logger.info("Vision client initialized", {
38
38
  provider: config.provider,
39
- model: visionClient.getModelName()
39
+ model: visionClient.getModelName(),
40
40
  });
41
41
  // 创建服务器 - 使用 McpServer
42
42
  const server = new McpServer({
43
- name: 'luma-mcp',
44
- version: '1.0.0',
43
+ name: "luma-mcp",
44
+ version: "1.0.0",
45
45
  }, {
46
46
  capabilities: {
47
47
  tools: {},
@@ -53,53 +53,42 @@ async function createServer() {
53
53
  await validateImageSource(imageSource);
54
54
  // 2. 处理图片(读取或返回URL)
55
55
  const imageDataUrl = await imageToBase64(imageSource);
56
- // 3. 构建提示词
57
- // DeepSeek-OCR 需要简洁的 prompt,不支持复杂格式化
58
- // Qwen/GLM 使用结构化 prompt
59
- const fullPrompt = config.provider === 'siliconflow'
60
- ? prompt // DeepSeek-OCR: 直接使用原始 prompt
61
- : buildAnalysisPrompt(prompt); // Qwen/GLM: 使用结构化 prompt
56
+ // 3. 构建分析提示词(部分提供商使用原始提示词,部分使用结构化提示词)
57
+ const fullPrompt = config.provider === "siliconflow"
58
+ ? prompt
59
+ : buildAnalysisPrompt(prompt);
62
60
  // 4. 调用视觉模型分析图片
63
61
  return await visionClient.analyzeImage(imageDataUrl, fullPrompt);
64
62
  }, 2, // 最多重试2次
65
63
  1000 // 初始延补1秒
66
64
  );
67
65
  // 注册工具 - 使用 McpServer.tool() API
68
- server.tool('analyze_image', `使用视觉模型分析图片内容。支持三个视觉模型:
69
- - GLM-4.5V(智谱清言)- 付费,中文理解优秀
70
- - DeepSeek-OCR(硅基流动)- 免费,OCR能力强
71
- - Qwen3-VL-Flash(阿里云通义千问)- 付费,速度快成本低,支持思考模式
72
-
73
- **何时自动调用此工具**:
74
- 1. 用户提供了图片文件路径(包括临时路径、相对路径、绝对路径)
75
- 2. 用户提供了图片URL(https://开头)
76
- 3. 用户粘贴了图片到聊天框(会生成临时路径)
77
- 4. 用户要求分析、理解、查看、识别图片内容
78
- 5. 用户询问关于图片中的代码、UI、错误信息等问题
79
-
80
- **支持场景**:代码截图、UI界面、错误信息、通用图片分析。
81
- **支持格式**:JPG、PNG、WebP、GIF。
82
- **支持来源**:本地文件、远程URL、临时文件(包括截图)。
83
-
84
- 如果你是不支持视觉的AI模型,看到图片路径时应主动调用此工具来分析图片内容。`, {
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..."'),
86
- prompt: z.string().describe('必须:详细的分析指令。如果用户没有提供具体问题,默认使用:"请详细分析这张图片的内容"。对于具体任务:代码分析、UI设计、错误诊断、文字识别等,应提供明确的指令。例如:"这段代码为什么报错?"、"分析这个UI的布局和风格"、"识别图片中的所有文字"'),
66
+ server.tool("analyze_image", "图像分析工具:对截图、设计稿、照片等图片进行详细理解和中文描述(支持本地文件和 HTTP(S) 图片 URL,最大 10MB)", {
67
+ image_source: z
68
+ .string()
69
+ .describe("要分析的图片来源:本地文件路径或 HTTP(S) 图片 URL(支持 PNG、JPG、JPEG、WebP、GIF,最大 10MB)"),
70
+ prompt: z
71
+ .string()
72
+ .optional()
73
+ .describe("可选的任务说明,例如“帮我详细描述这张 UI 设计图的布局和组件”。如果不填,将自动生成整图的详细中文描述。"),
87
74
  }, async (params) => {
88
75
  try {
89
- logger.info('Analyzing image', {
76
+ // 如果没有提供 prompt,使用默认值
77
+ const prompt = params.prompt || "请详细分析这张图片的内容";
78
+ logger.info("Analyzing image", {
90
79
  source: params.image_source,
91
- prompt: params.prompt,
80
+ prompt,
92
81
  });
93
82
  // 执行分析(带重试)
94
- const result = await analyzeWithRetry(params.image_source, params.prompt);
95
- logger.info('Image analysis completed successfully');
83
+ const result = await analyzeWithRetry(params.image_source, prompt);
84
+ logger.info("Image analysis completed successfully");
96
85
  return createSuccessResponse(result);
97
86
  }
98
87
  catch (error) {
99
- logger.error('Image analysis failed', {
88
+ logger.error("Image analysis failed", {
100
89
  error: error instanceof Error ? error.message : String(error),
101
90
  });
102
- return createErrorResponse(error instanceof Error ? error.message : 'Unknown error');
91
+ return createErrorResponse(error instanceof Error ? error.message : "Unknown error");
103
92
  }
104
93
  });
105
94
  return server;
@@ -112,30 +101,33 @@ async function main() {
112
101
  const server = await createServer();
113
102
  const transport = new StdioServerTransport();
114
103
  await server.connect(transport);
115
- logger.info('Luma MCP server started successfully on stdio');
104
+ logger.info("Luma MCP server started successfully on stdio");
116
105
  }
117
106
  catch (error) {
118
- logger.error('Failed to start Luma MCP server', {
107
+ logger.error("Failed to start Luma MCP server", {
119
108
  error: error instanceof Error ? error.message : String(error),
120
109
  });
121
110
  process.exit(1);
122
111
  }
123
112
  }
124
113
  // 全局错误处理
125
- process.on('uncaughtException', (error) => {
126
- logger.error('Uncaught exception', { error: error.message, stack: error.stack });
114
+ process.on("uncaughtException", (error) => {
115
+ logger.error("Uncaught exception", {
116
+ error: error.message,
117
+ stack: error.stack,
118
+ });
127
119
  process.exit(1);
128
120
  });
129
- process.on('unhandledRejection', (reason) => {
130
- logger.error('Unhandled rejection', { reason });
121
+ process.on("unhandledRejection", (reason) => {
122
+ logger.error("Unhandled rejection", { reason });
131
123
  process.exit(1);
132
124
  });
133
- process.on('SIGINT', () => {
134
- logger.info('Received SIGINT, shutting down gracefully');
125
+ process.on("SIGINT", () => {
126
+ logger.info("Received SIGINT, shutting down gracefully");
135
127
  process.exit(0);
136
128
  });
137
- process.on('SIGTERM', () => {
138
- logger.info('Received SIGTERM, shutting down gracefully');
129
+ process.on("SIGTERM", () => {
130
+ logger.info("Received SIGTERM, shutting down gracefully");
139
131
  process.exit(0);
140
132
  });
141
133
  main();
@@ -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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"}
@@ -4,5 +4,5 @@
4
4
  /**
5
5
  * 构建图片分析提示词
6
6
  */
7
- export declare function buildAnalysisPrompt(question?: string): string;
7
+ export declare function buildAnalysisPrompt(userPrompt: string): string;
8
8
  //# sourceMappingURL=prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAkC7D"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAuB9D"}
package/build/prompts.js CHANGED
@@ -4,40 +4,26 @@
4
4
  /**
5
5
  * 构建图片分析提示词
6
6
  */
7
- export function buildAnalysisPrompt(question) {
8
- if (question) {
9
- // 有用户问题时,直接回答问题
10
- return `
7
+ export function buildAnalysisPrompt(userPrompt) {
8
+ // 判断是否为通用请求(过于简单或模糊)
9
+ const isGenericRequest = /^(分析|查看|识别|描述|理解|看一下|看看|分析一下|请分析|analyze|describe|view|check)/i.test(userPrompt)
10
+ && userPrompt.length < 30;
11
+ // 如果是通用请求,添加详细指引
12
+ const finalPrompt = isGenericRequest
13
+ ? `请详细分析这张图片的内容,包括图片中的主要元素、文字、场景等所有可见信息。`
14
+ : userPrompt;
15
+ return `
11
16
  <image_analysis>
12
- 请仔细观察这张图片,并回答以下问题:
13
-
14
- ${question}
17
+ ${finalPrompt}
15
18
 
16
19
  分析要求:
17
- 1. 系统性观察:从整体到细节,全面观察图片内容
18
- 2. 准确识别:精确识别所有文字、符号、代码、数字等
19
- 3. 结构化输出:使用清晰的标题和列表组织信息
20
- 4. 中文表达:使用清晰准确的中文描述
21
- 5. 具体可执行:如果涉及代码或问题,提供具体的解决方案
22
-
23
- 请开始分析:
24
- </image_analysis>
25
- `.trim();
26
- }
27
- else {
28
- // 没有问题时,通用描述
29
- return `
30
- <image_analysis>
31
- 请详细描述这张图片的内容,包括:
32
-
33
- 1. **主要内容**:图片展示了什么
34
- 2. **关键元素**:重要的视觉元素、文字、符号
35
- 3. **布局结构**:元素的组织和排列
36
- 4. **文字内容**:提取所有可见文字
20
+ 1. **系统性观察**:从整体到细节,全面观察图片内容(不遗漏任何细节)
21
+ 2. **准确识别**:精确识别并完整提取所有文字、符号、代码、数字等
22
+ 3. **结构化输出**:使用清晰的标题和列表组织信息
23
+ 4. **具体可执行**:如果涉及问题或代码,提供具体的解决方案
37
24
 
38
25
  请用中文清晰描述。
39
26
  </image_analysis>
40
27
  `.trim();
41
- }
42
28
  }
43
29
  //# sourceMappingURL=prompts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAiB;IACnD,IAAI,QAAQ,EAAE,CAAC;QACb,gBAAgB;QAChB,OAAO;;;;EAIT,QAAQ;;;;;;;;;;;CAWT,CAAC,IAAI,EAAE,CAAC;IACP,CAAC;SAAM,CAAC;QACN,aAAa;QACb,OAAO;;;;;;;;;;;CAWV,CAAC,IAAI,EAAE,CAAC;IACP,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAkB;IACpD,qBAAqB;IACrB,MAAM,gBAAgB,GAAG,gEAAgE,CAAC,IAAI,CAAC,UAAU,CAAC;WACrG,UAAU,CAAC,MAAM,GAAG,EAAE,CAAC;IAE5B,iBAAiB;IACjB,MAAM,WAAW,GAAG,gBAAgB;QAClC,CAAC,CAAC,uCAAuC;QACzC,CAAC,CAAC,UAAU,CAAC;IAEf,OAAO;;EAEP,WAAW;;;;;;;;;;CAUZ,CAAC,IAAI,EAAE,CAAC;AACT,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"vision-client.d.ts","sourceRoot":"","sources":["../src/vision-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE9F;;OAEG;IACH,YAAY,IAAI,MAAM,CAAC;CACxB"}
1
+ {"version":3,"file":"vision-client.d.ts","sourceRoot":"","sources":["../src/vision-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,YAAY,CACV,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,OAAO,GACvB,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB;;OAEG;IACH,YAAY,IAAI,MAAM,CAAC;CACxB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "luma-mcp",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "Multi-model vision understanding MCP server. Supports GLM-4.5V (Zhipu), DeepSeek-OCR (SiliconFlow - Free), and Qwen3-VL-Flash (Aliyun)",
5
5
  "type": "module",
6
6
  "bin": {