bailian-image-understanding-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # 百炼图片理解 MCP 服务器
2
+
3
+ 让 Claude 能"看懂"图片的 MCP 工具,基于阿里云通义千问 VL 模型。
4
+
5
+ ## 为什么需要这个工具
6
+
7
+ Claude 本身不具备视觉能力,通过这个 MCP 服务器,你可以:
8
+
9
+ - 发送图片链接或本地图片给 Claude 分析
10
+ - 截图后直接粘贴,让 Claude 解释内容
11
+ - 处理 base64 编码的图片数据
12
+
13
+ 支持的模型:
14
+ - **qwen-vl-plus**(默认):性价比之选
15
+ - **qwen3-vl-plus**:第二代,性能更强
16
+ - **qwen-vl-max**:最强能力,适合复杂场景
17
+
18
+ ## 安装配置
19
+
20
+ ### 1. 获取 API Key
21
+
22
+ 访问 [阿里云百炼平台](https://bailian.console.aliyun.com/),开通大模型推理服务后创建 API Key。
23
+
24
+ ### 2. 安装
25
+
26
+ **方式一:直接安装(推荐)**
27
+
28
+ ```bash
29
+ npm install -g bailian-image-understanding-mcp
30
+ ```
31
+
32
+ **方式二:从源码构建**
33
+
34
+ ```bash
35
+ git clone <repo>
36
+ cd image-understanding
37
+ npm install && npm run build
38
+ npm pack
39
+ npm install -g bailian-image-understanding-mcp-*.tgz
40
+ ```
41
+
42
+ ### 3. 配置 Claude Desktop
43
+
44
+ 编辑 `~/Library/Application Support/Claude/claude_desktop_config.json`:
45
+
46
+ ```json
47
+ {
48
+ "mcpServers": {
49
+ "bailian-image": {
50
+ "command": "node",
51
+ "args": ["$(npm root -g)/bailian-image-understanding-mcp/dist/index.js"],
52
+ "env": {
53
+ "DASHSCOPE_API_KEY": "你的API密钥"
54
+ }
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ ### 4. 重启 Claude Desktop
61
+
62
+ 配置完成后重启,即可在对话中使用图片分析功能。
63
+
64
+ ## 在 Claude 中使用
65
+
66
+ 配置好后,直接对话即可:
67
+
68
+ ```
69
+ 请帮我看看这张图片是什么:https://example.com/screenshot.png
70
+ ```
71
+
72
+ ```
73
+ [粘贴图片] 这张图的布局怎么实现的?
74
+ ```
75
+
76
+ ## 支持的图片格式
77
+
78
+ - **HTTP URL**:`https://example.com/image.jpg`
79
+ - **本地路径**:`/Users/xxx/Pictures/screenshot.png`
80
+ - **base64**:`data:image/png;base64,iVBORw0KG...`
81
+
82
+ ## 环境变量
83
+
84
+ | 变量 | 说明 | 默认值 |
85
+ |-----|------|--------|
86
+ | DASHSCOPE_API_KEY | API密钥(必需) | - |
87
+ | QWEN_VISION_MODEL | 模型选择 | qwen-vl-plus |
88
+ | BAILIAN_REGION | 服务区域 | cn-beijing |
89
+
90
+ 可用区域:`cn-beijing` | `cn-singapore` | `us-virginia`
91
+
92
+ ## 开发调试
93
+
94
+ ```bash
95
+ # 安装依赖
96
+ npm install
97
+
98
+ # 开发模式(自动编译)
99
+ npm run dev
100
+
101
+ # 构建
102
+ npm run build
103
+
104
+ # 测试
105
+ node test/test-api.js
106
+ ```
107
+
108
+ ## 相关链接
109
+
110
+ - [阿里云百炼](https://bailian.console.aliyun.com/)
111
+ - [通义千问 VL 文档](https://help.aliyun.com/zh/dashscope/developer-reference/tongyi-qianwen-vl-plus-api)
112
+ - [MCP 协议](https://modelcontextprotocol.io/)
113
+
114
+ ## 致谢
115
+
116
+ 本项目基于 [@mcpcn/image-understanding-mcp](https://www.npmjs.com/package/@mcpcn/image-understanding-mcp) 改造
117
+
118
+ ## 许可证
119
+
120
+ MIT
@@ -0,0 +1,3 @@
1
+ export declare const DEFAULT_VISION_MODEL: string;
2
+ export declare const SUPPORTED_VISION_MODELS: string[];
3
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,QAAkD,CAAC;AAEpF,eAAO,MAAM,uBAAuB,EAAE,MAAM,EAI3C,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,7 @@
1
+ export const DEFAULT_VISION_MODEL = process.env.QWEN_VISION_MODEL || 'qwen-vl-plus';
2
+ export const SUPPORTED_VISION_MODELS = [
3
+ 'qwen-vl-plus',
4
+ 'qwen3-vl-plus',
5
+ 'qwen-vl-max',
6
+ ];
7
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,cAAc,CAAC;AAEpF,MAAM,CAAC,MAAM,uBAAuB,GAAa;IAC/C,cAAc;IACd,eAAe;IACf,aAAa;CACd,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,116 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
+ import { ImageUnderstandingTool } from './tools/image-recognition.js';
6
+ import { DEFAULT_VISION_MODEL, SUPPORTED_VISION_MODELS } from './config.js';
7
+ const API_KEY = process.env.DASHSCOPE_API_KEY || process.env.BAILIAN_API_KEY;
8
+ if (!API_KEY) {
9
+ console.error('错误: 未找到API密钥,请设置环境变量 DASHSCOPE_API_KEY');
10
+ process.exit(1);
11
+ }
12
+ const REGION = process.env.BAILIAN_REGION || 'cn-beijing';
13
+ const MODEL = process.env.QWEN_VISION_MODEL || DEFAULT_VISION_MODEL;
14
+ const imageUnderstanding = new ImageUnderstandingTool(API_KEY, REGION, MODEL);
15
+ const server = new Server({
16
+ name: 'bailian-image-understanding-mcp',
17
+ version: '1.0.0',
18
+ }, {
19
+ capabilities: {
20
+ tools: {},
21
+ },
22
+ });
23
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
24
+ return {
25
+ tools: [
26
+ {
27
+ name: 'analyze_image',
28
+ description: `使用阿里云百炼通义千问视觉模型(${DEFAULT_VISION_MODEL})分析图片`,
29
+ inputSchema: {
30
+ type: 'object',
31
+ properties: {
32
+ imageUrl: {
33
+ type: 'string',
34
+ description: '图片URL或base64编码',
35
+ },
36
+ prompt: {
37
+ type: 'string',
38
+ description: '分析要求',
39
+ default: '请详细描述这张图片的内容',
40
+ },
41
+ model: {
42
+ type: 'string',
43
+ enum: SUPPORTED_VISION_MODELS,
44
+ description: '模型版本',
45
+ },
46
+ temperature: {
47
+ type: 'number',
48
+ minimum: 0,
49
+ maximum: 1,
50
+ description: '温度参数(0-1)',
51
+ },
52
+ maxTokens: {
53
+ type: 'number',
54
+ minimum: 1,
55
+ maximum: 8192,
56
+ description: '最大输出token数',
57
+ },
58
+ },
59
+ required: ['imageUrl'],
60
+ },
61
+ },
62
+ ],
63
+ };
64
+ });
65
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
66
+ const { name, arguments: args } = request.params;
67
+ try {
68
+ switch (name) {
69
+ case 'analyze_image': {
70
+ const params = (args ?? {});
71
+ if (!params.imageUrl) {
72
+ throw new Error('imageUrl参数是必需的');
73
+ }
74
+ const result = await imageUnderstanding.analyzeImage(params);
75
+ return {
76
+ content: [{
77
+ type: 'text',
78
+ text: JSON.stringify(result, null, 2),
79
+ }],
80
+ isError: !result.success,
81
+ };
82
+ }
83
+ default:
84
+ throw new Error(`未知的工具: ${name}`);
85
+ }
86
+ }
87
+ catch (error) {
88
+ return {
89
+ content: [{
90
+ type: 'text',
91
+ text: JSON.stringify({
92
+ success: false,
93
+ error: error instanceof Error ? error.message : '未知错误',
94
+ }, null, 2),
95
+ }],
96
+ isError: true,
97
+ };
98
+ }
99
+ });
100
+ async function main() {
101
+ const transport = new StdioServerTransport();
102
+ await server.connect(transport);
103
+ }
104
+ process.on('uncaughtException', (error) => {
105
+ console.error(error);
106
+ process.exit(1);
107
+ });
108
+ process.on('unhandledRejection', (reason) => {
109
+ console.error(reason);
110
+ process.exit(1);
111
+ });
112
+ main().catch((error) => {
113
+ console.error('服务器启动失败:', error);
114
+ process.exit(1);
115
+ });
116
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ImageAnalysisParams, AnalysisResult } from '../types/index.js';
2
+ export declare class ImageUnderstandingTool {
3
+ private apiKey;
4
+ private baseUrl;
5
+ private defaultModel;
6
+ constructor(apiKey: string, region?: string, defaultModel?: string);
7
+ analyzeImage(params: ImageAnalysisParams): Promise<AnalysisResult>;
8
+ validateApiKey(): Promise<boolean>;
9
+ getSupportedModels(): string[];
10
+ }
11
+ //# sourceMappingURL=image-recognition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-recognition.d.ts","sourceRoot":"","sources":["../../src/tools/image-recognition.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EAGf,MAAM,mBAAmB,CAAC;AAuC3B,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAS;gBAEjB,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAqB,EAAE,YAAY,GAAE,MAA6B;IAehG,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IAqGlE,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAexC,kBAAkB,IAAI,MAAM,EAAE;CAG/B"}
@@ -0,0 +1,159 @@
1
+ import axios from 'axios';
2
+ import { z } from 'zod';
3
+ import { readFileSync, existsSync } from 'fs';
4
+ import { DEFAULT_VISION_MODEL, SUPPORTED_VISION_MODELS } from '../config.js';
5
+ const ImageAnalysisParamsSchema = z.object({
6
+ imageUrl: z.string().min(1),
7
+ prompt: z.string().optional().default('请详细描述这张图片的内容'),
8
+ model: z.enum(SUPPORTED_VISION_MODELS).optional().default(DEFAULT_VISION_MODEL),
9
+ temperature: z.number().min(0).max(1).optional().default(0.7),
10
+ maxTokens: z.number().min(1).max(8192).optional().default(1024)
11
+ });
12
+ function isBase64(str) {
13
+ return str.startsWith('data:image/');
14
+ }
15
+ function isHttpUrl(str) {
16
+ return str.startsWith('http://') || str.startsWith('https://');
17
+ }
18
+ function fileToBase64(filePath) {
19
+ if (!existsSync(filePath)) {
20
+ throw new Error(`文件不存在: ${filePath}`);
21
+ }
22
+ const buffer = readFileSync(filePath);
23
+ const base64 = buffer.toString('base64');
24
+ const extToMime = {
25
+ '.jpg': 'image/jpeg',
26
+ '.jpeg': 'image/jpeg',
27
+ '.gif': 'image/gif',
28
+ '.webp': 'image/webp',
29
+ };
30
+ const ext = filePath.slice(filePath.lastIndexOf('.'));
31
+ const mimeType = extToMime[ext] || 'image/png';
32
+ return `data:${mimeType};base64,${base64}`;
33
+ }
34
+ export class ImageUnderstandingTool {
35
+ apiKey;
36
+ baseUrl;
37
+ defaultModel;
38
+ constructor(apiKey, region = 'cn-beijing', defaultModel = DEFAULT_VISION_MODEL) {
39
+ if (!apiKey)
40
+ throw new Error('API密钥不能为空');
41
+ this.apiKey = apiKey;
42
+ this.defaultModel = defaultModel;
43
+ const regionUrls = {
44
+ 'cn-beijing': 'https://dashscope.aliyuncs.com/compatible-mode/v1',
45
+ 'cn-singapore': 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',
46
+ 'us-virginia': 'https://dashscope-us.aliyuncs.com/compatible-mode/v1'
47
+ };
48
+ this.baseUrl = regionUrls[region] || regionUrls['cn-beijing'];
49
+ }
50
+ async analyzeImage(params) {
51
+ try {
52
+ const validatedParams = ImageAnalysisParamsSchema.parse(params);
53
+ const modelToUse = validatedParams.model || this.defaultModel;
54
+ let finalImageUrl = validatedParams.imageUrl;
55
+ if (isHttpUrl(validatedParams.imageUrl)) {
56
+ try {
57
+ await axios.head(validatedParams.imageUrl, { timeout: 10000 });
58
+ }
59
+ catch (error) {
60
+ return {
61
+ success: false,
62
+ analysis: '',
63
+ model: DEFAULT_VISION_MODEL,
64
+ error: `无法访问图片URL: ${error instanceof Error ? error.message : '未知错误'}`
65
+ };
66
+ }
67
+ }
68
+ else if (!isBase64(validatedParams.imageUrl)) {
69
+ try {
70
+ finalImageUrl = fileToBase64(validatedParams.imageUrl);
71
+ }
72
+ catch (error) {
73
+ return {
74
+ success: false,
75
+ analysis: '',
76
+ model: DEFAULT_VISION_MODEL,
77
+ error: `读取本地文件失败: ${error instanceof Error ? error.message : '未知错误'}`
78
+ };
79
+ }
80
+ }
81
+ const requestBody = {
82
+ model: modelToUse,
83
+ messages: [{
84
+ role: 'user',
85
+ content: [
86
+ { type: 'text', text: validatedParams.prompt },
87
+ { type: 'image_url', image_url: { url: finalImageUrl } }
88
+ ]
89
+ }],
90
+ temperature: validatedParams.temperature,
91
+ max_tokens: validatedParams.maxTokens,
92
+ stream: false
93
+ };
94
+ const response = await axios.post(`${this.baseUrl}/chat/completions`, requestBody, {
95
+ headers: {
96
+ 'Authorization': `Bearer ${this.apiKey}`,
97
+ 'Content-Type': 'application/json'
98
+ },
99
+ timeout: 60000
100
+ });
101
+ if (!response.data?.choices?.[0]?.message?.content) {
102
+ throw new Error('API返回格式异常');
103
+ }
104
+ return {
105
+ success: true,
106
+ analysis: response.data.choices[0].message.content,
107
+ model: response.data.model,
108
+ tokenUsage: {
109
+ promptTokens: response.data.usage.prompt_tokens,
110
+ completionTokens: response.data.usage.completion_tokens,
111
+ totalTokens: response.data.usage.total_tokens
112
+ }
113
+ };
114
+ }
115
+ catch (error) {
116
+ if (error instanceof z.ZodError) {
117
+ return {
118
+ success: false,
119
+ analysis: '',
120
+ model: DEFAULT_VISION_MODEL,
121
+ error: `参数错误: ${error.errors[0].message}`
122
+ };
123
+ }
124
+ if (axios.isAxiosError(error)) {
125
+ const status = error.response?.status;
126
+ const msg = error.response?.data?.error?.message || error.message;
127
+ return {
128
+ success: false,
129
+ analysis: '',
130
+ model: DEFAULT_VISION_MODEL,
131
+ error: `API请求失败 (${status || '网络错误'}): ${msg}`
132
+ };
133
+ }
134
+ return {
135
+ success: false,
136
+ analysis: '',
137
+ model: DEFAULT_VISION_MODEL,
138
+ error: error instanceof Error ? error.message : '未知错误'
139
+ };
140
+ }
141
+ }
142
+ async validateApiKey() {
143
+ try {
144
+ const testImageUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAABCAYAAAB+KahGAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH6gHyXAAAA0JJREFUGMVJjEAAAGGAAElFTk//8nJ7+/vQzI0fH9+nv37f//73e3d/f7+/fvH8/Pz4+/n5+/j6+vv8//z9/vz//+///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5DwAAAAAAALbWA0M1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFlWA0hlR2A0RptOV4ptOVYptOXaptCXa4xCXZxW3atF3T4lF3LolF3TolF3XglF3n4nF3n4nF3P4vF3P4vF3f/fF3f/fF3n9/F3n9/F39//F3//Fg/////////////////////////////////f/////////////////////////3////////////////////////9///////////////////7///////////////////H//////////////////D//////////////////AP///////////////wD/////////////8B/////////////4P/////////////nw/////////////f/////////////+P/////////////3f/////////9f/5ff/wP/wf/3f4Pn4f9n3f9v3f//3f//9////////////////////f////////////////////3////////////////////9////////////////////5////////////////////ff////////////////fwD////////////8B////////////4P////////////nw';
145
+ const result = await this.analyzeImage({
146
+ imageUrl: testImageUrl,
147
+ prompt: '这是什么?'
148
+ });
149
+ return result.success;
150
+ }
151
+ catch {
152
+ return false;
153
+ }
154
+ }
155
+ getSupportedModels() {
156
+ return SUPPORTED_VISION_MODELS;
157
+ }
158
+ }
159
+ //# sourceMappingURL=image-recognition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-recognition.js","sourceRoot":"","sources":["../../src/tools/image-recognition.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ export interface BailianResponse {
2
+ id: string;
3
+ object: string;
4
+ created: number;
5
+ model: string;
6
+ choices: Array<{
7
+ index: number;
8
+ message: {
9
+ role: 'assistant';
10
+ content: string;
11
+ };
12
+ finish_reason: string;
13
+ }>;
14
+ usage: {
15
+ prompt_tokens: number;
16
+ completion_tokens: number;
17
+ total_tokens: number;
18
+ };
19
+ request_id?: string;
20
+ }
21
+ export interface ImageContent {
22
+ type: 'text' | 'image_url';
23
+ text?: string;
24
+ image_url?: {
25
+ url: string;
26
+ };
27
+ }
28
+ export interface ImageMessage {
29
+ role: 'user';
30
+ content: string | ImageContent[];
31
+ }
32
+ export interface BailianRequest {
33
+ model: string;
34
+ messages: ImageMessage[];
35
+ stream?: boolean;
36
+ temperature?: number;
37
+ top_p?: number;
38
+ max_tokens?: number;
39
+ }
40
+ export interface ImageAnalysisParams {
41
+ imageUrl: string;
42
+ prompt?: string;
43
+ model?: string;
44
+ temperature?: number;
45
+ maxTokens?: number;
46
+ }
47
+ export interface AnalysisResult {
48
+ success: boolean;
49
+ analysis: string;
50
+ model: string;
51
+ tokenUsage?: {
52
+ promptTokens: number;
53
+ completionTokens: number;
54
+ totalTokens: number;
55
+ };
56
+ error?: string;
57
+ }
58
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE;YACP,IAAI,EAAE,WAAW,CAAC;YAClB,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC,CAAC;IACH,KAAK,EAAE;QACL,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE;QACV,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "bailian-image-understanding-mcp",
3
+ "version": "1.0.0",
4
+ "description": "阿里云百炼通义千问Qwen-VL图片内容理解MCP工具",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "bailian-image-mcp": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/index.js",
14
+ "clean": "rm -rf dist",
15
+ "pack": "npm pack"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
+ "keywords": [
22
+ "mcp",
23
+ "image-understanding",
24
+ "bailian",
25
+ "qwen",
26
+ "qwen-vl",
27
+ "aliyun",
28
+ "typescript"
29
+ ],
30
+ "author": "",
31
+ "license": "MIT",
32
+ "dependencies": {
33
+ "@modelcontextprotocol/sdk": "^1.0.4",
34
+ "axios": "^1.7.9",
35
+ "zod": "^3.24.1"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^22.13.9",
39
+ "typescript": "^5.8.2"
40
+ }
41
+ }