@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
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Proprietary Software License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 TranslateImage
|
|
4
|
+
|
|
5
|
+
All rights reserved.
|
|
6
|
+
|
|
7
|
+
This software and associated documentation files (the "Software") are the
|
|
8
|
+
proprietary property of TranslateImage and are protected by copyright law.
|
|
9
|
+
|
|
10
|
+
You may not use, copy, modify, merge, publish, distribute, sublicense, or
|
|
11
|
+
sell copies of the Software without explicit written permission from
|
|
12
|
+
TranslateImage.
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
|
15
|
+
all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
# @translateimage/mcp-server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for TranslateImage - AI-powered image translation.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides a Model Context Protocol server that exposes TranslateImage translation capabilities to Claude and other MCP-compatible clients. It enables AI assistants to:
|
|
8
|
+
|
|
9
|
+
- Translate text in images while preserving layout
|
|
10
|
+
- Extract text from images using OCR
|
|
11
|
+
- Remove text from images using inpainting
|
|
12
|
+
- Translate Shopify product images at scale
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### From npm
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @translateimage/mcp-server
|
|
20
|
+
# or
|
|
21
|
+
pnpm add @translateimage/mcp-server
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### From source
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git clone https://github.com/translateimage/mcp-server
|
|
28
|
+
cd mcp-server
|
|
29
|
+
pnpm install
|
|
30
|
+
pnpm build
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
### Get Your API Key
|
|
36
|
+
|
|
37
|
+
1. Go to [TranslateImage Dashboard](https://translateimage.io/dashboard)
|
|
38
|
+
2. Navigate to **Settings** → **API Keys**
|
|
39
|
+
3. Create a new API key for MCP integration
|
|
40
|
+
|
|
41
|
+
### AI Agent Integration
|
|
42
|
+
|
|
43
|
+
Add to your AI Agent configuration (`claude_desktop_config.json`):
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"mcpServers": {
|
|
48
|
+
"translateimage": {
|
|
49
|
+
"command": "npx",
|
|
50
|
+
"args": ["@translateimage/mcp-server"],
|
|
51
|
+
"env": {
|
|
52
|
+
"TRANSLATEIMAGE_API_KEY": "your-translateimage-api-key"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Config file locations:**
|
|
60
|
+
|
|
61
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
62
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
63
|
+
- Linux: `~/.config/Claude/claude_desktop_config.json`
|
|
64
|
+
|
|
65
|
+
### HTTP Server
|
|
66
|
+
|
|
67
|
+
For remote access or web integrations:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Set environment variables
|
|
71
|
+
export TRANSLATEIMAGE_API_KEY=your-translateimage-api-key
|
|
72
|
+
export PORT=3001
|
|
73
|
+
export ALLOWED_ORIGINS=http://localhost:3000
|
|
74
|
+
|
|
75
|
+
# Start HTTP server
|
|
76
|
+
npx @translateimage/mcp-server --http
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Or run directly:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
node dist/bin/http.js
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The HTTP server exposes a single endpoint:
|
|
86
|
+
|
|
87
|
+
- `POST /mcp` - JSON-RPC endpoint for MCP requests
|
|
88
|
+
- `GET /mcp` - Returns 405 (SSE not supported in stateless mode)
|
|
89
|
+
|
|
90
|
+
## Environment Variables
|
|
91
|
+
|
|
92
|
+
| Variable | Required | Description |
|
|
93
|
+
| ------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
94
|
+
| `TRANSLATEIMAGE_API_KEY` | Yes | Your TranslateImage API key from the dashboard. Required for all tools. |
|
|
95
|
+
| `ALLOWED_ORIGINS` | No | Comma-separated list of allowed CORS origins for HTTP server. Default: `http://localhost:3000,http://localhost:3001` |
|
|
96
|
+
| `PORT` | No | HTTP server port. Default: `3001` |
|
|
97
|
+
|
|
98
|
+
## Tools Reference
|
|
99
|
+
|
|
100
|
+
### Core Tools
|
|
101
|
+
|
|
102
|
+
#### `translate_image`
|
|
103
|
+
|
|
104
|
+
Translate text in images while preserving the original layout. Detects text, translates it to the target language, and renders the translation back onto the image.
|
|
105
|
+
|
|
106
|
+
**Input:**
|
|
107
|
+
|
|
108
|
+
| Parameter | Type | Required | Description |
|
|
109
|
+
| ------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
110
|
+
| `image` | object | Yes | Image input (see [Image Input](#image-input)) |
|
|
111
|
+
| `target_lang` | string | Yes | Target language code (e.g., `"en"`, `"ja"`, `"zh"`, `"es"`) |
|
|
112
|
+
| `translator` | string | Yes | Translator model: `"gemini-2.5-flash"`, `"deepseek"`, `"grok-4-fast"`, `"kimi-k2"`, `"gemini-3-flash"`, `"gpt-5.1"` |
|
|
113
|
+
| `font` | string | No | Font for rendered text: `"NotoSans"` (default), `"WildWords"`, `"BadComic"`, `"MaShanZheng"`, `"KomikaJam"`, `"Bangers"`, `"Edo"`, `"RIDIBatang"`, `"Bushidoo"`, `"Hayah"`, `"Itim"`, `"Mogul Irina"` |
|
|
114
|
+
|
|
115
|
+
**Output:**
|
|
116
|
+
|
|
117
|
+
| Field | Type | Description |
|
|
118
|
+
| ----------------- | ------ | ---------------------------------------------------------- |
|
|
119
|
+
| `translatedImage` | string | Base64-encoded translated image (PNG) |
|
|
120
|
+
| `inpaintedImage` | string | Base64-encoded image with text removed |
|
|
121
|
+
| `textRegions` | array | Array of detected/translated text regions with positioning |
|
|
122
|
+
|
|
123
|
+
**Example:**
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"image": { "url": "https://example.com/manga-page.jpg" },
|
|
128
|
+
"target_lang": "en",
|
|
129
|
+
"translator": "gemini-2.5-flash",
|
|
130
|
+
"font": "WildWords"
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
#### `extract_text`
|
|
137
|
+
|
|
138
|
+
Extract text from images using OCR (Optical Character Recognition). Returns detected paragraphs with bounding boxes and detected language information.
|
|
139
|
+
|
|
140
|
+
**Input:**
|
|
141
|
+
|
|
142
|
+
| Parameter | Type | Required | Description |
|
|
143
|
+
| --------- | ------ | -------- | --------------------------------------------- |
|
|
144
|
+
| `image` | object | Yes | Image input (see [Image Input](#image-input)) |
|
|
145
|
+
|
|
146
|
+
**Output:**
|
|
147
|
+
|
|
148
|
+
| Field | Type | Description |
|
|
149
|
+
| ------------ | ------ | ------------------------------------------------------------------------- |
|
|
150
|
+
| `paragraphs` | array | Array of detected paragraphs with text, bounding boxes, and language info |
|
|
151
|
+
| `width` | number | Image width in pixels |
|
|
152
|
+
| `height` | number | Image height in pixels |
|
|
153
|
+
| `angle` | number | Detected text angle/rotation in degrees |
|
|
154
|
+
|
|
155
|
+
**Paragraph structure:**
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
{
|
|
159
|
+
boundingBox: [x1, y1, x2, y2], // Bounding box coordinates
|
|
160
|
+
text: string, // Paragraph text
|
|
161
|
+
lines: [{ // Array of lines
|
|
162
|
+
boundingBox: [x1, y1, x2, y2],
|
|
163
|
+
text: string,
|
|
164
|
+
words: [{
|
|
165
|
+
boundingBox: [x1, y1, x2, y2],
|
|
166
|
+
text: string,
|
|
167
|
+
confidence: number // 0-1
|
|
168
|
+
}]
|
|
169
|
+
}],
|
|
170
|
+
detectedLanguage: {
|
|
171
|
+
language: string, // Language name
|
|
172
|
+
code: string, // Language code
|
|
173
|
+
confidence: number // 0-1
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Example:**
|
|
179
|
+
|
|
180
|
+
```json
|
|
181
|
+
{
|
|
182
|
+
"image": { "base64": "iVBORw0KGgo...", "mimeType": "image/png" }
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
#### `remove_text`
|
|
189
|
+
|
|
190
|
+
Remove text from images using inpainting. Detects text regions and fills them with appropriate background content.
|
|
191
|
+
|
|
192
|
+
**Input:**
|
|
193
|
+
|
|
194
|
+
| Parameter | Type | Required | Description |
|
|
195
|
+
| --------- | ------ | -------- | --------------------------------------------- |
|
|
196
|
+
| `image` | object | Yes | Image input (see [Image Input](#image-input)) |
|
|
197
|
+
|
|
198
|
+
**Output:**
|
|
199
|
+
|
|
200
|
+
| Field | Type | Description |
|
|
201
|
+
| -------------- | ------ | ------------------------------------------------------ |
|
|
202
|
+
| `cleanedImage` | string | Base64-encoded image with text removed/inpainted (PNG) |
|
|
203
|
+
|
|
204
|
+
**Example:**
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"image": { "url": "https://example.com/image-with-text.png" }
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
#### `image_to_text`
|
|
215
|
+
|
|
216
|
+
Extract text from images using AI and optionally translate to specified languages. Provides high-quality OCR with language detection and translation capabilities.
|
|
217
|
+
|
|
218
|
+
**Input:**
|
|
219
|
+
|
|
220
|
+
| Parameter | Type | Required | Description |
|
|
221
|
+
| ----------------- | -------- | -------- | --------------------------------------------- |
|
|
222
|
+
| `image` | object | Yes | Image input (see [Image Input](#image-input)) |
|
|
223
|
+
| `targetLanguages` | string[] | No | Target language codes for translation |
|
|
224
|
+
|
|
225
|
+
**Output:**
|
|
226
|
+
|
|
227
|
+
| Field | Type | Description |
|
|
228
|
+
| ------------------ | ------ | ------------------------------------------------------------------- |
|
|
229
|
+
| `extractedText` | string | Text extracted from the image |
|
|
230
|
+
| `detectedLanguage` | string | Detected language of the extracted text |
|
|
231
|
+
| `translations` | object | Translations keyed by language code (if `targetLanguages` provided) |
|
|
232
|
+
|
|
233
|
+
**Example:**
|
|
234
|
+
|
|
235
|
+
```json
|
|
236
|
+
{
|
|
237
|
+
"image": { "url": "https://example.com/document.jpg" },
|
|
238
|
+
"targetLanguages": ["en", "es", "fr"]
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
### Shopify Tools
|
|
245
|
+
|
|
246
|
+
#### `shopify_translate_product`
|
|
247
|
+
|
|
248
|
+
Translate product images for a Shopify store. Fetches product media from Shopify and translates text in images to the target language.
|
|
249
|
+
|
|
250
|
+
**Input:**
|
|
251
|
+
|
|
252
|
+
| Parameter | Type | Required | Description |
|
|
253
|
+
| -------------------------------- | ------ | -------- | -------------------------------------------- |
|
|
254
|
+
| `shopifyCredentials` | object | Yes | Shopify credentials |
|
|
255
|
+
| `shopifyCredentials.shopDomain` | string | Yes | Shop domain (e.g., `"myshop.myshopify.com"`) |
|
|
256
|
+
| `shopifyCredentials.accessToken` | string | Yes | Shopify API access token |
|
|
257
|
+
| `productId` | string | Yes | Shopify product ID |
|
|
258
|
+
| `targetLanguage` | string | Yes | Target language code |
|
|
259
|
+
| `translator` | string | Yes | Translator model |
|
|
260
|
+
|
|
261
|
+
**Output:**
|
|
262
|
+
|
|
263
|
+
| Field | Type | Description |
|
|
264
|
+
| ------------------ | ------ | --------------------------- |
|
|
265
|
+
| `productId` | string | Shopify product ID |
|
|
266
|
+
| `productTitle` | string | Product title |
|
|
267
|
+
| `status` | string | Translation status |
|
|
268
|
+
| `imagesTranslated` | number | Number of images translated |
|
|
269
|
+
|
|
270
|
+
**Example:**
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"shopifyCredentials": {
|
|
275
|
+
"shopDomain": "myshop.myshopify.com",
|
|
276
|
+
"accessToken": "shpat_xxxxx"
|
|
277
|
+
},
|
|
278
|
+
"productId": "gid://shopify/Product/123456789",
|
|
279
|
+
"targetLanguage": "ja",
|
|
280
|
+
"translator": "gemini-2.5-flash"
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
#### `shopify_batch_translate`
|
|
287
|
+
|
|
288
|
+
Batch translate product images for multiple Shopify products.
|
|
289
|
+
|
|
290
|
+
**Input:**
|
|
291
|
+
|
|
292
|
+
| Parameter | Type | Required | Description |
|
|
293
|
+
| -------------------- | -------- | -------- | ---------------------------- |
|
|
294
|
+
| `shopifyCredentials` | object | Yes | Shopify credentials |
|
|
295
|
+
| `productIds` | string[] | Yes | Array of Shopify product IDs |
|
|
296
|
+
| `targetLanguage` | string | Yes | Target language code |
|
|
297
|
+
| `translator` | string | Yes | Translator model |
|
|
298
|
+
|
|
299
|
+
**Output:**
|
|
300
|
+
|
|
301
|
+
| Field | Type | Description |
|
|
302
|
+
| ---------------- | ------ | -------------------------- |
|
|
303
|
+
| `totalProducts` | number | Total products processed |
|
|
304
|
+
| `successCount` | number | Successful translations |
|
|
305
|
+
| `failureCount` | number | Failed translations |
|
|
306
|
+
| `targetLanguage` | string | Target language used |
|
|
307
|
+
| `results` | array | Individual product results |
|
|
308
|
+
|
|
309
|
+
**Example:**
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
{
|
|
313
|
+
"shopifyCredentials": {
|
|
314
|
+
"shopDomain": "myshop.myshopify.com",
|
|
315
|
+
"accessToken": "shpat_xxxxx"
|
|
316
|
+
},
|
|
317
|
+
"productIds": ["gid://shopify/Product/123", "gid://shopify/Product/456"],
|
|
318
|
+
"targetLanguage": "en",
|
|
319
|
+
"translator": "deepseek"
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
#### `shopify_shop_stats`
|
|
326
|
+
|
|
327
|
+
Get statistics about a Shopify shop including total products, products with images, and total image count.
|
|
328
|
+
|
|
329
|
+
**Input:**
|
|
330
|
+
|
|
331
|
+
| Parameter | Type | Required | Description |
|
|
332
|
+
| -------------------- | ------ | -------- | ------------------- |
|
|
333
|
+
| `shopifyCredentials` | object | Yes | Shopify credentials |
|
|
334
|
+
|
|
335
|
+
**Output:**
|
|
336
|
+
|
|
337
|
+
| Field | Type | Description |
|
|
338
|
+
| -------------------- | ------- | ------------------------------------- |
|
|
339
|
+
| `shopName` | string | Shop name |
|
|
340
|
+
| `totalProducts` | number | Total products in shop |
|
|
341
|
+
| `productsWithImages` | number | Products with at least one image |
|
|
342
|
+
| `totalImages` | number | Total image count |
|
|
343
|
+
| `isPartial` | boolean | Whether scan was partial (large shop) |
|
|
344
|
+
|
|
345
|
+
**Example:**
|
|
346
|
+
|
|
347
|
+
```json
|
|
348
|
+
{
|
|
349
|
+
"shopifyCredentials": {
|
|
350
|
+
"shopDomain": "myshop.myshopify.com",
|
|
351
|
+
"accessToken": "shpat_xxxxx"
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
#### `shopify_scan_products`
|
|
359
|
+
|
|
360
|
+
Scan Shopify product images for text detection. Identifies which images contain translatable text.
|
|
361
|
+
|
|
362
|
+
**Input:**
|
|
363
|
+
|
|
364
|
+
| Parameter | Type | Required | Description |
|
|
365
|
+
| -------------------- | ------ | -------- | ------------------------------------------- |
|
|
366
|
+
| `shopifyCredentials` | object | Yes | Shopify credentials |
|
|
367
|
+
| `productId` | string | No | Specific product ID to scan |
|
|
368
|
+
| `maxProducts` | number | No | Max products to scan (default: 10, max: 50) |
|
|
369
|
+
|
|
370
|
+
**Output:**
|
|
371
|
+
|
|
372
|
+
| Field | Type | Description |
|
|
373
|
+
| ----------------- | ------- | ------------------------- |
|
|
374
|
+
| `productsScanned` | number | Products scanned |
|
|
375
|
+
| `imagesScanned` | number | Images scanned |
|
|
376
|
+
| `imagesWithText` | number | Images with detected text |
|
|
377
|
+
| `isPartial` | boolean | Whether scan was partial |
|
|
378
|
+
| `stoppedReason` | string | Reason if stopped early |
|
|
379
|
+
| `results` | array | Detailed scan results |
|
|
380
|
+
|
|
381
|
+
**Example:**
|
|
382
|
+
|
|
383
|
+
```json
|
|
384
|
+
{
|
|
385
|
+
"shopifyCredentials": {
|
|
386
|
+
"shopDomain": "myshop.myshopify.com",
|
|
387
|
+
"accessToken": "shpat_xxxxx"
|
|
388
|
+
},
|
|
389
|
+
"productId": "gid://shopify/Product/123456789"
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## Image Input
|
|
396
|
+
|
|
397
|
+
All tools that accept images support three input methods:
|
|
398
|
+
|
|
399
|
+
### URL
|
|
400
|
+
|
|
401
|
+
```json
|
|
402
|
+
{
|
|
403
|
+
"image": {
|
|
404
|
+
"url": "https://example.com/image.jpg"
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Base64 with MIME type
|
|
410
|
+
|
|
411
|
+
```json
|
|
412
|
+
{
|
|
413
|
+
"image": {
|
|
414
|
+
"base64": "iVBORw0KGgo...",
|
|
415
|
+
"mimeType": "image/png"
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Data URL
|
|
421
|
+
|
|
422
|
+
```json
|
|
423
|
+
{
|
|
424
|
+
"image": {
|
|
425
|
+
"base64": "data:image/png;base64,iVBORw0KGgo..."
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**Supported MIME types:** `image/jpeg`, `image/png`, `image/webp`, `image/gif`
|
|
431
|
+
|
|
432
|
+
**Size limit:** 10MB
|
|
433
|
+
|
|
434
|
+
## Programmatic Usage
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
import { createMcpServer, McpServerConfig } from "@translateimage/mcp-server";
|
|
438
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
439
|
+
|
|
440
|
+
const config: McpServerConfig = {
|
|
441
|
+
// Server-side configuration (loaded from environment)
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
const server = createMcpServer(config);
|
|
445
|
+
const transport = new StdioServerTransport();
|
|
446
|
+
|
|
447
|
+
await server.connect(transport);
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
## Development
|
|
451
|
+
|
|
452
|
+
```bash
|
|
453
|
+
# Install dependencies
|
|
454
|
+
pnpm install
|
|
455
|
+
|
|
456
|
+
# Type check
|
|
457
|
+
pnpm typecheck
|
|
458
|
+
|
|
459
|
+
# Build
|
|
460
|
+
pnpm build
|
|
461
|
+
|
|
462
|
+
# Run tests
|
|
463
|
+
pnpm test
|
|
464
|
+
|
|
465
|
+
# Run tests with coverage
|
|
466
|
+
pnpm test --coverage
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## Architecture
|
|
470
|
+
|
|
471
|
+
```
|
|
472
|
+
packages/mcp-server/
|
|
473
|
+
├── src/
|
|
474
|
+
│ ├── index.ts # Package exports
|
|
475
|
+
│ ├── server.ts # createMcpServer factory
|
|
476
|
+
│ ├── schemas/ # Zod schemas for all tools
|
|
477
|
+
│ ├── utils/ # Image handling, errors, config
|
|
478
|
+
│ └── tools/ # Tool implementations
|
|
479
|
+
│ ├── index.ts # Tool registration
|
|
480
|
+
│ ├── translate.ts # translate_image
|
|
481
|
+
│ ├── ocr.ts # extract_text
|
|
482
|
+
│ ├── text-removal.ts # remove_text
|
|
483
|
+
│ ├── image-to-text.ts # image_to_text
|
|
484
|
+
│ └── shopify/ # Shopify integration tools
|
|
485
|
+
├── bin/
|
|
486
|
+
│ ├── stdio.ts # CLI entry point
|
|
487
|
+
│ └── http.ts # HTTP server entry point
|
|
488
|
+
└── __tests__/ # Test files
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
## Troubleshooting
|
|
492
|
+
|
|
493
|
+
### "API key missing" error
|
|
494
|
+
|
|
495
|
+
Ensure you've set your TranslateImage API key:
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
export TRANSLATEIMAGE_API_KEY=your-api-key
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
Or in AI Agent config, add it to the `env` section.
|
|
502
|
+
|
|
503
|
+
### "Origin not allowed" error (HTTP server)
|
|
504
|
+
|
|
505
|
+
Add your origin to `ALLOWED_ORIGINS`:
|
|
506
|
+
|
|
507
|
+
```bash
|
|
508
|
+
export ALLOWED_ORIGINS=http://localhost:3000,http://yourdomain.com
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### Image size exceeds limit
|
|
512
|
+
|
|
513
|
+
Images must be under 10MB. Compress or resize large images before sending.
|
|
514
|
+
|
|
515
|
+
### AI Agent not detecting server
|
|
516
|
+
|
|
517
|
+
1. Ensure the config file path is correct for your OS
|
|
518
|
+
2. Restart AI Agent after config changes
|
|
519
|
+
3. Check that `npx @translateimage/mcp-server` runs without errors
|
|
520
|
+
|
|
521
|
+
### HTTP server returns 405
|
|
522
|
+
|
|
523
|
+
The HTTP server runs in stateless mode and doesn't support SSE. Use POST requests to `/mcp` only.
|
|
524
|
+
|
|
525
|
+
## API Key & Billing
|
|
526
|
+
|
|
527
|
+
- Get your API key from the [TranslateImage Dashboard](https://translateimage.io/dashboard)
|
|
528
|
+
- Usage is billed based on your subscription plan
|
|
529
|
+
- Monitor usage in the dashboard under **Settings** → **Usage**
|
|
530
|
+
|
|
531
|
+
## License
|
|
532
|
+
|
|
533
|
+
Proprietary - All rights reserved
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../bin/http.ts"],"names":[],"mappings":""}
|
package/dist/bin/http.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import express from "express";
|
|
3
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
|
+
import { createMcpServer } from "../src/server.js";
|
|
5
|
+
import { loadConfigFromEnv } from "../src/utils/config.js";
|
|
6
|
+
const app = express();
|
|
7
|
+
const config = loadConfigFromEnv();
|
|
8
|
+
app.use(express.json());
|
|
9
|
+
const allowedOrigins = (process.env.ALLOWED_ORIGINS || "http://localhost:3000,http://localhost:3001")
|
|
10
|
+
.split(",")
|
|
11
|
+
.map((origin) => origin.trim());
|
|
12
|
+
app.use((req, res, next) => {
|
|
13
|
+
const origin = req.headers.origin;
|
|
14
|
+
if (origin && !allowedOrigins.includes(origin)) {
|
|
15
|
+
return res.status(403).json({
|
|
16
|
+
jsonrpc: "2.0",
|
|
17
|
+
error: { code: -32603, message: "Origin not allowed" },
|
|
18
|
+
id: null,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
next();
|
|
22
|
+
});
|
|
23
|
+
app.post("/mcp", async (req, res) => {
|
|
24
|
+
try {
|
|
25
|
+
const server = createMcpServer(config);
|
|
26
|
+
const transport = new StreamableHTTPServerTransport({
|
|
27
|
+
sessionIdGenerator: undefined,
|
|
28
|
+
});
|
|
29
|
+
await server.connect(transport);
|
|
30
|
+
await transport.handleRequest(req, res, req.body);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
34
|
+
res.status(500).json({
|
|
35
|
+
jsonrpc: "2.0",
|
|
36
|
+
error: { code: -32603, message: errorMessage },
|
|
37
|
+
id: null,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
app.get("/mcp", (req, res) => {
|
|
42
|
+
res.status(405).json({
|
|
43
|
+
jsonrpc: "2.0",
|
|
44
|
+
error: { code: -32603, message: "SSE not supported in stateless mode" },
|
|
45
|
+
id: null,
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
const port = parseInt(process.env.PORT || "3001", 10);
|
|
49
|
+
app.listen(port, () => {
|
|
50
|
+
console.log(`MCP HTTP server listening on port ${port}`);
|
|
51
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../bin/stdio.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { createMcpServer } from "../src/server.js";
|
|
4
|
+
import { loadConfigFromEnv } from "../src/utils/config.js";
|
|
5
|
+
async function main() {
|
|
6
|
+
const config = loadConfigFromEnv();
|
|
7
|
+
const server = createMcpServer(config);
|
|
8
|
+
const transport = new StdioServerTransport();
|
|
9
|
+
await server.connect(transport);
|
|
10
|
+
}
|
|
11
|
+
main().catch((error) => {
|
|
12
|
+
console.error("Failed to start MCP server:", error);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const LanguageCodeSchema: z.ZodString;
|
|
3
|
+
/**
|
|
4
|
+
* Image input schema - handles URL, base64, or data URLs
|
|
5
|
+
* Refinements:
|
|
6
|
+
* - Requires either url OR base64 (at least one)
|
|
7
|
+
* - If base64 is raw (not starting with "data:"), mimeType is required
|
|
8
|
+
* - If base64 starts with "data:", mimeType is extracted automatically
|
|
9
|
+
*/
|
|
10
|
+
export declare const ImageInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
11
|
+
url: z.ZodOptional<z.ZodString>;
|
|
12
|
+
base64: z.ZodOptional<z.ZodString>;
|
|
13
|
+
mimeType: z.ZodOptional<z.ZodEnum<["image/jpeg", "image/png", "image/webp", "image/gif"]>>;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
url?: string | undefined;
|
|
16
|
+
base64?: string | undefined;
|
|
17
|
+
mimeType?: "image/jpeg" | "image/png" | "image/webp" | "image/gif" | undefined;
|
|
18
|
+
}, {
|
|
19
|
+
url?: string | undefined;
|
|
20
|
+
base64?: string | undefined;
|
|
21
|
+
mimeType?: "image/jpeg" | "image/png" | "image/webp" | "image/gif" | undefined;
|
|
22
|
+
}>, {
|
|
23
|
+
url?: string | undefined;
|
|
24
|
+
base64?: string | undefined;
|
|
25
|
+
mimeType?: "image/jpeg" | "image/png" | "image/webp" | "image/gif" | undefined;
|
|
26
|
+
}, {
|
|
27
|
+
url?: string | undefined;
|
|
28
|
+
base64?: string | undefined;
|
|
29
|
+
mimeType?: "image/jpeg" | "image/png" | "image/webp" | "image/gif" | undefined;
|
|
30
|
+
}>, {
|
|
31
|
+
url?: string | undefined;
|
|
32
|
+
base64?: string | undefined;
|
|
33
|
+
mimeType?: "image/jpeg" | "image/png" | "image/webp" | "image/gif" | undefined;
|
|
34
|
+
}, {
|
|
35
|
+
url?: string | undefined;
|
|
36
|
+
base64?: string | undefined;
|
|
37
|
+
mimeType?: "image/jpeg" | "image/png" | "image/webp" | "image/gif" | undefined;
|
|
38
|
+
}>;
|
|
39
|
+
export type ImageInput = z.infer<typeof ImageInputSchema>;
|
|
40
|
+
//# sourceMappingURL=common.d.ts.map
|