@fastcoder/vision-mcp-server 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.
Files changed (107) hide show
  1. package/README.md +263 -0
  2. package/README.zh-CN.md +210 -0
  3. package/build/core/api-common.d.ts +89 -0
  4. package/build/core/api-common.d.ts.map +1 -0
  5. package/build/core/api-common.js +119 -0
  6. package/build/core/api-common.js.map +1 -0
  7. package/build/core/base-image-service.d.ts +38 -0
  8. package/build/core/base-image-service.d.ts.map +1 -0
  9. package/build/core/base-image-service.js +92 -0
  10. package/build/core/base-image-service.js.map +1 -0
  11. package/build/core/chat-service.d.ts +42 -0
  12. package/build/core/chat-service.d.ts.map +1 -0
  13. package/build/core/chat-service.js +97 -0
  14. package/build/core/chat-service.js.map +1 -0
  15. package/build/core/environment.d.ts +76 -0
  16. package/build/core/environment.d.ts.map +1 -0
  17. package/build/core/environment.js +132 -0
  18. package/build/core/environment.js.map +1 -0
  19. package/build/core/error-handler.d.ts +124 -0
  20. package/build/core/error-handler.d.ts.map +1 -0
  21. package/build/core/error-handler.js +248 -0
  22. package/build/core/error-handler.js.map +1 -0
  23. package/build/core/file-service.d.ts +36 -0
  24. package/build/core/file-service.d.ts.map +1 -0
  25. package/build/core/file-service.js +141 -0
  26. package/build/core/file-service.js.map +1 -0
  27. package/build/index.d.ts +3 -0
  28. package/build/index.d.ts.map +1 -0
  29. package/build/index.js +119 -0
  30. package/build/index.js.map +1 -0
  31. package/build/prompts/data-viz.d.ts +5 -0
  32. package/build/prompts/data-viz.d.ts.map +1 -0
  33. package/build/prompts/data-viz.js +98 -0
  34. package/build/prompts/data-viz.js.map +1 -0
  35. package/build/prompts/diagram-analysis.d.ts +5 -0
  36. package/build/prompts/diagram-analysis.d.ts.map +1 -0
  37. package/build/prompts/diagram-analysis.js +102 -0
  38. package/build/prompts/diagram-analysis.js.map +1 -0
  39. package/build/prompts/error-diagnosis.d.ts +5 -0
  40. package/build/prompts/error-diagnosis.d.ts.map +1 -0
  41. package/build/prompts/error-diagnosis.js +69 -0
  42. package/build/prompts/error-diagnosis.js.map +1 -0
  43. package/build/prompts/general-image.d.ts +5 -0
  44. package/build/prompts/general-image.d.ts.map +1 -0
  45. package/build/prompts/general-image.js +45 -0
  46. package/build/prompts/general-image.js.map +1 -0
  47. package/build/prompts/index.d.ts +8 -0
  48. package/build/prompts/index.d.ts.map +1 -0
  49. package/build/prompts/index.js +8 -0
  50. package/build/prompts/index.js.map +1 -0
  51. package/build/prompts/text-extraction.d.ts +5 -0
  52. package/build/prompts/text-extraction.d.ts.map +1 -0
  53. package/build/prompts/text-extraction.js +45 -0
  54. package/build/prompts/text-extraction.js.map +1 -0
  55. package/build/prompts/ui-diff.d.ts +5 -0
  56. package/build/prompts/ui-diff.d.ts.map +1 -0
  57. package/build/prompts/ui-diff.js +190 -0
  58. package/build/prompts/ui-diff.js.map +1 -0
  59. package/build/prompts/ui-to-artifact.d.ts +10 -0
  60. package/build/prompts/ui-to-artifact.d.ts.map +1 -0
  61. package/build/prompts/ui-to-artifact.js +89 -0
  62. package/build/prompts/ui-to-artifact.js.map +1 -0
  63. package/build/tools/data-viz.d.ts +5 -0
  64. package/build/tools/data-viz.d.ts.map +1 -0
  65. package/build/tools/data-viz.js +93 -0
  66. package/build/tools/data-viz.js.map +1 -0
  67. package/build/tools/diagram-analysis.d.ts +5 -0
  68. package/build/tools/diagram-analysis.d.ts.map +1 -0
  69. package/build/tools/diagram-analysis.js +93 -0
  70. package/build/tools/diagram-analysis.js.map +1 -0
  71. package/build/tools/error-diagnosis.d.ts +5 -0
  72. package/build/tools/error-diagnosis.d.ts.map +1 -0
  73. package/build/tools/error-diagnosis.js +93 -0
  74. package/build/tools/error-diagnosis.js.map +1 -0
  75. package/build/tools/general-image.d.ts +5 -0
  76. package/build/tools/general-image.d.ts.map +1 -0
  77. package/build/tools/general-image.js +81 -0
  78. package/build/tools/general-image.js.map +1 -0
  79. package/build/tools/index.d.ts +8 -0
  80. package/build/tools/index.d.ts.map +1 -0
  81. package/build/tools/index.js +9 -0
  82. package/build/tools/index.js.map +1 -0
  83. package/build/tools/text-extraction.d.ts +5 -0
  84. package/build/tools/text-extraction.d.ts.map +1 -0
  85. package/build/tools/text-extraction.js +93 -0
  86. package/build/tools/text-extraction.js.map +1 -0
  87. package/build/tools/ui-diff.d.ts +5 -0
  88. package/build/tools/ui-diff.d.ts.map +1 -0
  89. package/build/tools/ui-diff.js +98 -0
  90. package/build/tools/ui-diff.js.map +1 -0
  91. package/build/tools/ui-to-artifact.d.ts +5 -0
  92. package/build/tools/ui-to-artifact.d.ts.map +1 -0
  93. package/build/tools/ui-to-artifact.js +117 -0
  94. package/build/tools/ui-to-artifact.js.map +1 -0
  95. package/build/types/index.d.ts +26 -0
  96. package/build/types/index.d.ts.map +1 -0
  97. package/build/types/index.js +43 -0
  98. package/build/types/index.js.map +1 -0
  99. package/build/utils/logger.d.ts +24 -0
  100. package/build/utils/logger.d.ts.map +1 -0
  101. package/build/utils/logger.js +119 -0
  102. package/build/utils/logger.js.map +1 -0
  103. package/build/utils/validation.d.ts +87 -0
  104. package/build/utils/validation.d.ts.map +1 -0
  105. package/build/utils/validation.js +155 -0
  106. package/build/utils/validation.js.map +1 -0
  107. package/package.json +70 -0
@@ -0,0 +1,119 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ /**
5
+ * Logger utility that writes to stderr and a log file.
6
+ * Stderr keeps MCP JSON on stdout clean; file provides persistent logs.
7
+ */
8
+ class Logger {
9
+ logStream;
10
+ constructor(logFilePath) {
11
+ if (logFilePath) {
12
+ this.setLogFile(logFilePath);
13
+ }
14
+ }
15
+ setLogFile(logFilePath) {
16
+ try {
17
+ const dir = path.dirname(logFilePath);
18
+ fs.mkdirSync(dir, { recursive: true });
19
+ if (this.logStream) {
20
+ this.logStream.end();
21
+ }
22
+ this.logStream = fs.createWriteStream(logFilePath, { flags: 'a' });
23
+ }
24
+ catch (err) {
25
+ const timestamp = new Date().toISOString();
26
+ const msg = `[${timestamp}] ERROR: Failed to initialize log file '${logFilePath}': ${String(err)}`;
27
+ process.stderr.write(msg + '\n');
28
+ }
29
+ }
30
+ safeStringify(obj) {
31
+ // Serialize Error objects so that message/stack and custom fields are visible
32
+ const replacer = (_key, value) => {
33
+ if (value instanceof Error) {
34
+ const base = {
35
+ name: value.name,
36
+ message: value.message,
37
+ stack: value.stack
38
+ };
39
+ // Include enumerable own properties (e.g., code, statusCode, details, context)
40
+ for (const k of Object.keys(value)) {
41
+ if (!(k in base)) {
42
+ base[k] = value[k];
43
+ }
44
+ }
45
+ return base;
46
+ }
47
+ return value;
48
+ };
49
+ try {
50
+ return JSON.stringify(obj, replacer);
51
+ }
52
+ catch {
53
+ try {
54
+ return String(obj);
55
+ }
56
+ catch {
57
+ return '[Unserializable]';
58
+ }
59
+ }
60
+ }
61
+ write(level, message, ...args) {
62
+ const timestamp = new Date().toISOString();
63
+ const serializedArgs = args.length > 0 ? ` ${this.safeStringify(args)}` : '';
64
+ const logMessage = `[${timestamp}] ${level.toUpperCase()}: ${message}${serializedArgs}`;
65
+ // Write to stderr (visible console output without polluting stdout)
66
+ process.stderr.write(logMessage + '\n');
67
+ // Write to log file if configured
68
+ if (this.logStream) {
69
+ this.logStream.write(logMessage + '\n');
70
+ }
71
+ }
72
+ info(message, ...args) {
73
+ this.write('info', message, ...args);
74
+ }
75
+ error(message, ...args) {
76
+ this.write('error', message, ...args);
77
+ }
78
+ warn(message, ...args) {
79
+ this.write('warn', message, ...args);
80
+ }
81
+ debug(message, ...args) {
82
+ this.write('debug', message, ...args);
83
+ }
84
+ log(message, ...args) {
85
+ this.write('info', message, ...args);
86
+ }
87
+ }
88
+ export const logger = new Logger();
89
+ /**
90
+ * Override global console to redirect to stderr
91
+ * This prevents console output from interfering with MCP JSON protocol
92
+ */
93
+ export function setupConsoleRedirection() {
94
+ const originalConsole = { ...console };
95
+ // Cross-platform log file path:
96
+ // - If env VISION_MCP_LOG_PATH is set, use it
97
+ // - Otherwise use user home directory: ~/.vision/vision-mcp-YYYY-MM-DD.log (Windows/macOS/Linux)
98
+ const resolveLogFilePath = () => {
99
+ const envPath = process.env.VISION_MCP_LOG_PATH;
100
+ if (envPath && envPath.trim().length > 0) {
101
+ return path.resolve(envPath);
102
+ }
103
+ const homeDir = os.homedir();
104
+ const now = new Date();
105
+ const yyyy = now.getFullYear();
106
+ const mm = String(now.getMonth() + 1).padStart(2, '0');
107
+ const dd = String(now.getDate()).padStart(2, '0');
108
+ const dateStr = `${yyyy}-${mm}-${dd}`;
109
+ return path.join(homeDir, '.vision', `vision-mcp-${dateStr}.log`);
110
+ };
111
+ logger.setLogFile(resolveLogFilePath());
112
+ console.info = logger.info.bind(logger);
113
+ console.error = logger.error.bind(logger);
114
+ console.warn = logger.warn.bind(logger);
115
+ console.debug = logger.debug.bind(logger);
116
+ console.log = logger.log.bind(logger);
117
+ return originalConsole;
118
+ }
119
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Runtime type validator
4
+ */
5
+ export declare class RuntimeValidator {
6
+ /**
7
+ * Validate data against specified Zod schema
8
+ */
9
+ static validate<T>(data: unknown, schema: z.ZodSchema<T>, options?: {
10
+ throwOnError?: boolean;
11
+ customMessage?: string;
12
+ logErrors?: boolean;
13
+ }): {
14
+ success: boolean;
15
+ data?: T;
16
+ error?: {
17
+ message: string;
18
+ code: string;
19
+ };
20
+ };
21
+ /**
22
+ * Safe validation, does not throw exceptions
23
+ */
24
+ static safeValidate<T>(data: unknown, schema: z.ZodSchema<T>): ReturnType<typeof RuntimeValidator.validate<T>>;
25
+ /**
26
+ * Parse Zod error to standard validation error format
27
+ */
28
+ static parseZodError(error: z.ZodError): Array<{
29
+ message: string;
30
+ field: string;
31
+ code: string;
32
+ expected: string;
33
+ received: string;
34
+ }>;
35
+ /**
36
+ * Get expected type description
37
+ */
38
+ static getExpectedType(issue: z.ZodIssue): string;
39
+ /**
40
+ * Sanitize sensitive data for logging
41
+ */
42
+ static sanitizeData(data: unknown): unknown;
43
+ }
44
+ /**
45
+ * Common validation schemas
46
+ */
47
+ export declare const CommonSchemas: {
48
+ /** Non-empty string */
49
+ nonEmptyString: z.ZodString;
50
+ /** Positive integer */
51
+ positiveInteger: z.ZodNumber;
52
+ /** Non-negative integer */
53
+ nonNegativeInteger: z.ZodNumber;
54
+ /** URL format */
55
+ url: z.ZodString;
56
+ /** Email format */
57
+ email: z.ZodString;
58
+ /** UUID format */
59
+ uuid: z.ZodString;
60
+ /** File path */
61
+ filePath: z.ZodEffects<z.ZodString, string, string>;
62
+ /** Tool name */
63
+ toolName: z.ZodString;
64
+ };
65
+ /**
66
+ * Tool parameter validation schema builder
67
+ */
68
+ export declare class ToolSchemaBuilder<T extends Record<string, z.ZodTypeAny>> {
69
+ private schema;
70
+ /**
71
+ * Add required field
72
+ */
73
+ required<K extends keyof T>(name: K, schema: z.ZodTypeAny): ToolSchemaBuilder<T>;
74
+ /**
75
+ * Add optional field
76
+ */
77
+ optional<K extends keyof T>(name: K, schema: z.ZodTypeAny): ToolSchemaBuilder<T>;
78
+ /**
79
+ * Add field with default value
80
+ */
81
+ withDefault<K extends keyof T>(name: K, schema: z.ZodTypeAny, defaultValue: z.input<z.ZodTypeAny>): ToolSchemaBuilder<T>;
82
+ /**
83
+ * Build final validation schema
84
+ */
85
+ build(): z.ZodObject<Record<keyof T, z.ZodTypeAny>>;
86
+ }
87
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;GAEG;AACH,qBAAa,gBAAgB;IAC3B;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,CAAC,EACf,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACtB,OAAO,GAAE;QACP,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,OAAO,CAAC;KAChB,GACL;QACD,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,CAAC,EAAE,CAAC,CAAC;QACT,KAAK,CAAC,EAAE;YACN,OAAO,EAAE,MAAM,CAAC;YAChB,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;KACH;IAoCD;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,CAAC,EACnB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GACrB,UAAU,CAAC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAIlD;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC7C,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IAaF;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,MAAM;IAajD;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;CAgB5C;AAED;;GAEG;AACH,eAAO,MAAM,aAAa;IACxB,uBAAuB;;IAEvB,uBAAuB;;IAEvB,2BAA2B;;IAK3B,iBAAiB;;IAEjB,mBAAmB;;IAEnB,kBAAkB;;IAElB,gBAAgB;;IAKhB,gBAAgB;;CAOjB,CAAC;AAEF;;GAEG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC;IACnE,OAAO,CAAC,MAAM,CAA8C;IAE5D;;OAEG;IACH,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,EACxB,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,CAAC,CAAC,UAAU,GACnB,iBAAiB,CAAC,CAAC,CAAC;IAKvB;;OAEG;IACH,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,EACxB,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,CAAC,CAAC,UAAU,GACnB,iBAAiB,CAAC,CAAC,CAAC;IAKvB;;OAEG;IACH,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,EAC3B,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,CAAC,CAAC,UAAU,EACpB,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,GAClC,iBAAiB,CAAC,CAAC,CAAC;IAKvB;;OAEG;IACH,KAAK,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;CAGpD"}
@@ -0,0 +1,155 @@
1
+ import { z } from 'zod';
2
+ import { ValidationError } from '../types/index.js';
3
+ /**
4
+ * Runtime type validator
5
+ */
6
+ export class RuntimeValidator {
7
+ /**
8
+ * Validate data against specified Zod schema
9
+ */
10
+ static validate(data, schema, options = {}) {
11
+ const { throwOnError = true, customMessage, logErrors = true } = options;
12
+ try {
13
+ const result = schema.parse(data);
14
+ return {
15
+ success: true,
16
+ data: result
17
+ };
18
+ }
19
+ catch (error) {
20
+ const validationErrors = this.parseZodError(error);
21
+ if (logErrors) {
22
+ console.warn('Validation failed', {
23
+ errors: validationErrors,
24
+ data: this.sanitizeData(data)
25
+ });
26
+ }
27
+ if (throwOnError) {
28
+ const message = customMessage ||
29
+ `Validation failed: ${validationErrors.map(e => e.message).join(', ')}`;
30
+ throw new ValidationError(message, { errors: validationErrors });
31
+ }
32
+ return {
33
+ success: false,
34
+ error: {
35
+ message: validationErrors.map(e => e.message).join(', '),
36
+ code: 'VALIDATION_ERROR'
37
+ }
38
+ };
39
+ }
40
+ }
41
+ /**
42
+ * Safe validation, does not throw exceptions
43
+ */
44
+ static safeValidate(data, schema) {
45
+ return this.validate(data, schema, { throwOnError: false });
46
+ }
47
+ /**
48
+ * Parse Zod error to standard validation error format
49
+ */
50
+ static parseZodError(error) {
51
+ return error.issues.map(issue => ({
52
+ message: issue.message,
53
+ field: issue.path.join('.'),
54
+ code: issue.code,
55
+ expected: this.getExpectedType(issue),
56
+ received: 'received' in issue
57
+ ? String(issue.received)
58
+ : 'unknown'
59
+ }));
60
+ }
61
+ /**
62
+ * Get expected type description
63
+ */
64
+ static getExpectedType(issue) {
65
+ switch (issue.code) {
66
+ case 'invalid_type':
67
+ return issue.expected;
68
+ case 'too_small':
69
+ return `minimum ${issue.minimum}`;
70
+ case 'too_big':
71
+ return `maximum ${issue.maximum}`;
72
+ default:
73
+ return 'valid value';
74
+ }
75
+ }
76
+ /**
77
+ * Sanitize sensitive data for logging
78
+ */
79
+ static sanitizeData(data) {
80
+ if (typeof data !== 'object' || data === null) {
81
+ return data;
82
+ }
83
+ const sensitiveKeys = ['password', 'token', 'secret', 'key', 'auth'];
84
+ const sanitized = { ...data };
85
+ for (const key of Object.keys(sanitized)) {
86
+ if (sensitiveKeys.some(sensitive => key.toLowerCase().includes(sensitive))) {
87
+ sanitized[key] = '[REDACTED]';
88
+ }
89
+ }
90
+ return sanitized;
91
+ }
92
+ }
93
+ /**
94
+ * Common validation schemas
95
+ */
96
+ export const CommonSchemas = {
97
+ /** Non-empty string */
98
+ nonEmptyString: z.string().min(1, 'String cannot be empty'),
99
+ /** Positive integer */
100
+ positiveInteger: z.number().int().positive('Must be a positive integer'),
101
+ /** Non-negative integer */
102
+ nonNegativeInteger: z
103
+ .number()
104
+ .int()
105
+ .min(0, 'Must be a non-negative integer'),
106
+ /** URL format */
107
+ url: z.string().url('Must be a valid URL'),
108
+ /** Email format */
109
+ email: z.string().email('Must be a valid email address'),
110
+ /** UUID format */
111
+ uuid: z.string().uuid('Must be a valid UUID'),
112
+ /** File path */
113
+ filePath: z
114
+ .string()
115
+ .min(1)
116
+ .refine(path => !path.includes('..'), 'File path cannot contain ".."'),
117
+ /** Tool name */
118
+ toolName: z
119
+ .string()
120
+ .regex(/^[a-z][a-z0-9-]*[a-z0-9]$/, 'Tool name must be lowercase, start with letter, and contain only letters, numbers, and hyphens')
121
+ };
122
+ /**
123
+ * Tool parameter validation schema builder
124
+ */
125
+ export class ToolSchemaBuilder {
126
+ schema = {};
127
+ /**
128
+ * Add required field
129
+ */
130
+ required(name, schema) {
131
+ this.schema[name] = schema;
132
+ return this;
133
+ }
134
+ /**
135
+ * Add optional field
136
+ */
137
+ optional(name, schema) {
138
+ this.schema[name] = schema.optional();
139
+ return this;
140
+ }
141
+ /**
142
+ * Add field with default value
143
+ */
144
+ withDefault(name, schema, defaultValue) {
145
+ this.schema[name] = schema.default(() => defaultValue);
146
+ return this;
147
+ }
148
+ /**
149
+ * Build final validation schema
150
+ */
151
+ build() {
152
+ return z.object(this.schema);
153
+ }
154
+ }
155
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@fastcoder/vision-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP Server for Vision Analysis - A Model Context Protocol server that provides image analysis capabilities using OpenAI API",
5
+ "main": "build/index.js",
6
+ "type": "module",
7
+ "types": "build/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./build/index.d.ts",
11
+ "default": "./build/index.js"
12
+ }
13
+ },
14
+ "bin": {
15
+ "vision-mcp-server": "./build/index.js"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/calandnong/vision-mcp-server.git"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/calandnong/vision-mcp-server/issues"
23
+ },
24
+ "homepage": "https://github.com/calandnong/vision-mcp-server#readme",
25
+ "scripts": {
26
+ "build": "tsc && chmod 755 build/index.js",
27
+ "start": "node build/index.js",
28
+ "dev": "tsx watch src/index.ts",
29
+ "inspector": "npx @modelcontextprotocol/inspector --transport stdio node build/index.js",
30
+ "inspector:dev": "npx @modelcontextprotocol/inspector --transport stdio tsx src/index.ts",
31
+ "test": "vitest",
32
+ "test:run": "vitest run",
33
+ "test:coverage": "vitest run --coverage",
34
+ "prepare": "npm run build",
35
+ "clean": "rm -rf build"
36
+ },
37
+ "keywords": [
38
+ "vision",
39
+ "mcp",
40
+ "openai",
41
+ "image-analysis",
42
+ "ocr",
43
+ "ui-analysis"
44
+ ],
45
+ "author": "Vision MCP Team",
46
+ "license": "Apache-2.0",
47
+ "files": [
48
+ "build",
49
+ "README.md",
50
+ "README.zh-CN.md"
51
+ ],
52
+ "engines": {
53
+ "node": ">=18.0.0"
54
+ },
55
+ "publishConfig": {
56
+ "access": "public"
57
+ },
58
+ "dependencies": {
59
+ "@modelcontextprotocol/sdk": "^1.17.5",
60
+ "zod": "^3.23.8"
61
+ },
62
+ "devDependencies": {
63
+ "@modelcontextprotocol/inspector": "^0.18.0",
64
+ "@types/node": "^24.3.1",
65
+ "@vitest/coverage-v8": "^2.1.0",
66
+ "tsx": "^4.19.0",
67
+ "typescript": "^5.9.2",
68
+ "vitest": "^2.1.0"
69
+ }
70
+ }