@translateimage/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.
- package/LICENSE +23 -0
- package/README.md +533 -0
- package/dist/bin/http.d.ts +3 -0
- package/dist/bin/http.d.ts.map +1 -0
- package/dist/bin/http.js +51 -0
- package/dist/bin/stdio.d.ts +3 -0
- package/dist/bin/stdio.d.ts.map +1 -0
- package/dist/bin/stdio.js +14 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +3 -0
- package/dist/src/schemas/common.d.ts +40 -0
- package/dist/src/schemas/common.d.ts.map +1 -0
- package/dist/src/schemas/common.js +31 -0
- package/dist/src/schemas/image-to-text.d.ts +69 -0
- package/dist/src/schemas/image-to-text.d.ts.map +1 -0
- package/dist/src/schemas/image-to-text.js +26 -0
- package/dist/src/schemas/index.d.ts +7 -0
- package/dist/src/schemas/index.d.ts.map +1 -0
- package/dist/src/schemas/index.js +6 -0
- package/dist/src/schemas/ocr.d.ts +333 -0
- package/dist/src/schemas/ocr.d.ts.map +1 -0
- package/dist/src/schemas/ocr.js +46 -0
- package/dist/src/schemas/shopify.d.ts +860 -0
- package/dist/src/schemas/shopify.d.ts.map +1 -0
- package/dist/src/schemas/shopify.js +183 -0
- package/dist/src/schemas/text-removal.d.ts +60 -0
- package/dist/src/schemas/text-removal.d.ts.map +1 -0
- package/dist/src/schemas/text-removal.js +16 -0
- package/dist/src/schemas/translate.d.ts +197 -0
- package/dist/src/schemas/translate.d.ts.map +1 -0
- package/dist/src/schemas/translate.js +70 -0
- package/dist/src/server.d.ts +4 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +7 -0
- package/dist/src/tools/image-to-text.d.ts +4 -0
- package/dist/src/tools/image-to-text.d.ts.map +1 -0
- package/dist/src/tools/image-to-text.js +12 -0
- package/dist/src/tools/index.d.ts +8 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +202 -0
- package/dist/src/tools/ocr.d.ts +4 -0
- package/dist/src/tools/ocr.d.ts.map +1 -0
- package/dist/src/tools/ocr.js +28 -0
- package/dist/src/tools/shopify/batch-translate.d.ts +26 -0
- package/dist/src/tools/shopify/batch-translate.d.ts.map +1 -0
- package/dist/src/tools/shopify/batch-translate.js +143 -0
- package/dist/src/tools/shopify/index.d.ts +19 -0
- package/dist/src/tools/shopify/index.d.ts.map +1 -0
- package/dist/src/tools/shopify/index.js +28 -0
- package/dist/src/tools/shopify/scan-products.d.ts +38 -0
- package/dist/src/tools/shopify/scan-products.d.ts.map +1 -0
- package/dist/src/tools/shopify/scan-products.js +178 -0
- package/dist/src/tools/shopify/shop-stats.d.ts +12 -0
- package/dist/src/tools/shopify/shop-stats.d.ts.map +1 -0
- package/dist/src/tools/shopify/shop-stats.js +89 -0
- package/dist/src/tools/shopify/translate-product.d.ts +19 -0
- package/dist/src/tools/shopify/translate-product.d.ts.map +1 -0
- package/dist/src/tools/shopify/translate-product.js +121 -0
- package/dist/src/tools/text-removal.d.ts +4 -0
- package/dist/src/tools/text-removal.d.ts.map +1 -0
- package/dist/src/tools/text-removal.js +10 -0
- package/dist/src/tools/translate.d.ts +4 -0
- package/dist/src/tools/translate.d.ts.map +1 -0
- package/dist/src/tools/translate.js +16 -0
- package/dist/src/utils/api-client.d.ts +46 -0
- package/dist/src/utils/api-client.d.ts.map +1 -0
- package/dist/src/utils/api-client.js +124 -0
- package/dist/src/utils/config.d.ts +7 -0
- package/dist/src/utils/config.d.ts.map +1 -0
- package/dist/src/utils/config.js +11 -0
- package/dist/src/utils/errors.d.ts +17 -0
- package/dist/src/utils/errors.d.ts.map +1 -0
- package/dist/src/utils/errors.js +35 -0
- package/dist/src/utils/image.d.ts +34 -0
- package/dist/src/utils/image.d.ts.map +1 -0
- package/dist/src/utils/image.js +105 -0
- package/dist/src/utils/index.d.ts +5 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +4 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { McpError } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export declare class ImageTranslationError extends McpError {
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
}
|
|
5
|
+
export declare class InvalidInputError extends McpError {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
export declare class ApiKeyMissingError extends McpError {
|
|
9
|
+
constructor(keyName?: string);
|
|
10
|
+
}
|
|
11
|
+
export declare class ImageTooLargeError extends McpError {
|
|
12
|
+
constructor(message: string);
|
|
13
|
+
}
|
|
14
|
+
export declare class UnsupportedFormatError extends McpError {
|
|
15
|
+
constructor(message: string);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAa,MAAM,oCAAoC,CAAC;AAEzE,qBAAa,qBAAsB,SAAQ,QAAQ;gBACrC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,kBAAmB,SAAQ,QAAQ;gBAClC,OAAO,GAAE,MAAc;CASpC;AAED,qBAAa,kBAAmB,SAAQ,QAAQ;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,sBAAuB,SAAQ,QAAQ;gBACtC,OAAO,EAAE,MAAM;CAI5B"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export class ImageTranslationError extends McpError {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(ErrorCode.InternalError, message);
|
|
5
|
+
this.name = "ImageTranslationError";
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export class InvalidInputError extends McpError {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(ErrorCode.InvalidParams, message);
|
|
11
|
+
this.name = "InvalidInputError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class ApiKeyMissingError extends McpError {
|
|
15
|
+
constructor(keyName = "API") {
|
|
16
|
+
const envVar = keyName === "TranslateImage"
|
|
17
|
+
? "TRANSLATEIMAGE_API_KEY"
|
|
18
|
+
: `${keyName.toUpperCase()}_API_KEY`;
|
|
19
|
+
const message = `${keyName} API key is required. Set the ${envVar} environment variable.`;
|
|
20
|
+
super(ErrorCode.InvalidParams, message);
|
|
21
|
+
this.name = "ApiKeyMissingError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export class ImageTooLargeError extends McpError {
|
|
25
|
+
constructor(message) {
|
|
26
|
+
super(ErrorCode.InvalidParams, message);
|
|
27
|
+
this.name = "ImageTooLargeError";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class UnsupportedFormatError extends McpError {
|
|
31
|
+
constructor(message) {
|
|
32
|
+
super(ErrorCode.InvalidParams, message);
|
|
33
|
+
this.name = "UnsupportedFormatError";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ImageInput } from "../schemas/common.js";
|
|
2
|
+
/**
|
|
3
|
+
* Converts a URL to base64 and MIME type
|
|
4
|
+
*/
|
|
5
|
+
export declare function urlToBase64(url: string): Promise<{
|
|
6
|
+
base64: string;
|
|
7
|
+
mimeType: string;
|
|
8
|
+
}>;
|
|
9
|
+
/**
|
|
10
|
+
* Validates if a string is valid base64
|
|
11
|
+
*/
|
|
12
|
+
export declare function isValidBase64(str: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Converts base64 string to Blob
|
|
15
|
+
*/
|
|
16
|
+
export declare function base64ToBlob(base64: string, mimeType: string): Blob;
|
|
17
|
+
/**
|
|
18
|
+
* Converts Blob to base64 string using Node.js Buffer (efficient for large images)
|
|
19
|
+
*/
|
|
20
|
+
export declare function blobToBase64(blob: Blob): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Validates image size (throws if > 10MB)
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateImageSize(blob: Blob): void;
|
|
25
|
+
/**
|
|
26
|
+
* Validates MIME type is supported
|
|
27
|
+
*/
|
|
28
|
+
export declare function validateMimeType(mimeType: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Resolves ImageInput to a Blob with validation
|
|
31
|
+
* Handles URL, base64 (raw and data URL), and validates size/format
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveImageInput(input: ImageInput): Promise<Blob>;
|
|
34
|
+
//# sourceMappingURL=image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../src/utils/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAWlD;;GAEG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAW/C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAMlD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAOnE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAG9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAOlD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAOvD;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCxE"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { ImageTooLargeError, UnsupportedFormatError } from "./errors.js";
|
|
2
|
+
const ALLOWED_MIME_TYPES = [
|
|
3
|
+
"image/jpeg",
|
|
4
|
+
"image/png",
|
|
5
|
+
"image/webp",
|
|
6
|
+
"image/gif",
|
|
7
|
+
];
|
|
8
|
+
const MAX_IMAGE_SIZE = 10 * 1024 * 1024; // 10MB
|
|
9
|
+
/**
|
|
10
|
+
* Converts a URL to base64 and MIME type
|
|
11
|
+
*/
|
|
12
|
+
export async function urlToBase64(url) {
|
|
13
|
+
const response = await fetch(url);
|
|
14
|
+
if (!response.ok) {
|
|
15
|
+
throw new Error(`Failed to fetch image from URL: ${response.statusText}`);
|
|
16
|
+
}
|
|
17
|
+
const blob = await response.blob();
|
|
18
|
+
const base64 = await blobToBase64(blob);
|
|
19
|
+
const mimeType = blob.type || "image/png";
|
|
20
|
+
return { base64, mimeType };
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Validates if a string is valid base64
|
|
24
|
+
*/
|
|
25
|
+
export function isValidBase64(str) {
|
|
26
|
+
try {
|
|
27
|
+
return btoa(atob(str)) === str;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Converts base64 string to Blob
|
|
35
|
+
*/
|
|
36
|
+
export function base64ToBlob(base64, mimeType) {
|
|
37
|
+
const binaryString = atob(base64);
|
|
38
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
39
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
40
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
41
|
+
}
|
|
42
|
+
return new Blob([bytes], { type: mimeType });
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Converts Blob to base64 string using Node.js Buffer (efficient for large images)
|
|
46
|
+
*/
|
|
47
|
+
export async function blobToBase64(blob) {
|
|
48
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
49
|
+
return Buffer.from(arrayBuffer).toString("base64");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Validates image size (throws if > 10MB)
|
|
53
|
+
*/
|
|
54
|
+
export function validateImageSize(blob) {
|
|
55
|
+
if (blob.size > MAX_IMAGE_SIZE) {
|
|
56
|
+
const sizeMB = (blob.size / (1024 * 1024)).toFixed(2);
|
|
57
|
+
throw new ImageTooLargeError(`Image too large: ${sizeMB}MB exceeds 10MB limit`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Validates MIME type is supported
|
|
62
|
+
*/
|
|
63
|
+
export function validateMimeType(mimeType) {
|
|
64
|
+
if (!ALLOWED_MIME_TYPES.includes(mimeType)) {
|
|
65
|
+
const format = mimeType.split("/")[1] || mimeType;
|
|
66
|
+
throw new UnsupportedFormatError(`Unsupported image format: ${format}. Supported: png, jpeg, webp, gif`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Resolves ImageInput to a Blob with validation
|
|
71
|
+
* Handles URL, base64 (raw and data URL), and validates size/format
|
|
72
|
+
*/
|
|
73
|
+
export async function resolveImageInput(input) {
|
|
74
|
+
let blob;
|
|
75
|
+
let mimeType;
|
|
76
|
+
if (input.url) {
|
|
77
|
+
// Fetch from URL
|
|
78
|
+
const { base64, mimeType: fetchedMimeType } = await urlToBase64(input.url);
|
|
79
|
+
mimeType = fetchedMimeType;
|
|
80
|
+
blob = base64ToBlob(base64, mimeType);
|
|
81
|
+
}
|
|
82
|
+
else if (input.base64) {
|
|
83
|
+
// Handle base64 input
|
|
84
|
+
if (input.base64.startsWith("data:")) {
|
|
85
|
+
// Parse data URL
|
|
86
|
+
const [header, base64Data] = input.base64.split(",");
|
|
87
|
+
const mimeMatch = header.match(/data:([^;]+)/);
|
|
88
|
+
mimeType = mimeMatch ? mimeMatch[1] : "image/png";
|
|
89
|
+
blob = base64ToBlob(base64Data, mimeType);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// Raw base64 - mimeType must be provided (validated by schema)
|
|
93
|
+
mimeType = input.mimeType || "image/png";
|
|
94
|
+
blob = base64ToBlob(input.base64, mimeType);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
throw new Error("Either url or base64 must be provided");
|
|
99
|
+
}
|
|
100
|
+
// Validate MIME type
|
|
101
|
+
validateMimeType(mimeType);
|
|
102
|
+
// Validate size
|
|
103
|
+
validateImageSize(blob);
|
|
104
|
+
return blob;
|
|
105
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC"}
|