@i18n-agent/mcp-client 1.7.6 → 1.7.8

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 (2) hide show
  1. package/mcp-client.js +170 -27
  2. package/package.json +1 -1
package/mcp-client.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * Integrates with Claude Code CLI to provide translation capabilities
6
6
  */
7
7
 
8
- const MCP_CLIENT_VERSION = '1.7.6';
8
+ const MCP_CLIENT_VERSION = '1.7.8';
9
9
 
10
10
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
11
11
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
@@ -218,6 +218,34 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
218
218
  required: ['jobId'],
219
219
  },
220
220
  },
221
+ {
222
+ name: 'resume_translation',
223
+ description: 'Resume a failed or interrupted async translation job from its last checkpoint. This allows you to continue processing from where it stopped instead of starting over.',
224
+ inputSchema: {
225
+ type: 'object',
226
+ properties: {
227
+ jobId: {
228
+ type: 'string',
229
+ description: 'The job ID of the translation job to resume',
230
+ },
231
+ },
232
+ required: ['jobId'],
233
+ },
234
+ },
235
+ {
236
+ name: 'download_translations',
237
+ description: 'Download completed translations by writing them to /tmp/i18n-translations-{jobId}/. Returns metadata with file paths instead of large translation content to avoid token bloat. Consumer can then read or copy files as needed.',
238
+ inputSchema: {
239
+ type: 'object',
240
+ properties: {
241
+ jobId: {
242
+ type: 'string',
243
+ description: 'The job ID of the completed translation',
244
+ },
245
+ },
246
+ required: ['jobId'],
247
+ },
248
+ },
221
249
  ],
222
250
  };
223
251
  });
@@ -248,7 +276,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
248
276
 
249
277
  case 'check_translation_status':
250
278
  return await handleCheckTranslationStatus(args);
251
-
279
+
280
+ case 'resume_translation':
281
+ return await handleResumeTranslation(args);
282
+
283
+ case 'download_translations':
284
+ return await handleDownloadTranslations(args);
285
+
252
286
  default:
253
287
  throw new McpError(
254
288
  ErrorCode.MethodNotFound,
@@ -630,7 +664,26 @@ async function handleTranslateFile(args) {
630
664
 
631
665
  // Check if this is a large file that might need async processing
632
666
  const isLargeFile = content.length > 50000; // > 50KB
633
-
667
+
668
+ // Build arguments object, filtering out undefined values (they get stripped by JSON.stringify)
669
+ const requestArgs = {
670
+ apiKey: API_KEY,
671
+ filePath,
672
+ fileContent: content,
673
+ fileType,
674
+ sourceLanguage,
675
+ targetAudience,
676
+ industry,
677
+ preserveKeys,
678
+ outputFormat
679
+ };
680
+
681
+ // Add optional parameters only if defined
682
+ if (targetLanguage !== undefined) requestArgs.targetLanguage = targetLanguage;
683
+ if (targetLanguages !== undefined) requestArgs.targetLanguages = targetLanguages;
684
+ if (region !== undefined) requestArgs.region = region;
685
+ if (context !== undefined) requestArgs.context = context;
686
+
634
687
  // Use MCP JSON-RPC protocol for translate_file
635
688
  const mcpRequest = {
636
689
  jsonrpc: '2.0',
@@ -638,21 +691,7 @@ async function handleTranslateFile(args) {
638
691
  method: 'tools/call',
639
692
  params: {
640
693
  name: 'translate_file',
641
- arguments: {
642
- apiKey: API_KEY,
643
- filePath,
644
- fileContent: content,
645
- fileType,
646
- targetLanguage,
647
- targetLanguages,
648
- sourceLanguage,
649
- targetAudience,
650
- industry,
651
- region,
652
- context,
653
- preserveKeys,
654
- outputFormat
655
- }
694
+ arguments: requestArgs
656
695
  }
657
696
  };
658
697
 
@@ -1315,11 +1354,11 @@ function getCodeBlockLanguage(fileType) {
1315
1354
  // Handler for checking translation status
1316
1355
  async function handleCheckTranslationStatus(args) {
1317
1356
  const { jobId } = args;
1318
-
1357
+
1319
1358
  if (!jobId) {
1320
1359
  throw new Error('jobId is required');
1321
1360
  }
1322
-
1361
+
1323
1362
  const mcpRequest = {
1324
1363
  jsonrpc: '2.0',
1325
1364
  id: Date.now(),
@@ -1329,41 +1368,145 @@ async function handleCheckTranslationStatus(args) {
1329
1368
  arguments: { jobId }
1330
1369
  }
1331
1370
  };
1332
-
1371
+
1333
1372
  try {
1334
1373
  const response = await axios.post(MCP_SERVER_URL, mcpRequest, {
1335
1374
  headers: { 'Content-Type': 'application/json' },
1336
1375
  timeout: 30000
1337
1376
  });
1338
-
1377
+
1339
1378
  if (response.data.error) {
1340
1379
  throw new Error(`Translation status error: ${response.data.error.message || response.data.error}`);
1341
1380
  }
1342
-
1381
+
1343
1382
  return response.data.result;
1344
1383
  } catch (error) {
1345
1384
  console.error('Check translation status error:', error);
1346
-
1385
+
1347
1386
  // Handle 503 service unavailable
1348
1387
  if (error.response?.status === 503) {
1349
1388
  throw new Error(`i18n-agent encountered unexpected problem, and we are working on it, try again later.`);
1350
1389
  }
1351
-
1390
+
1352
1391
  // Handle 404 not found
1353
1392
  if (error.response?.status === 404) {
1354
1393
  throw new Error(`Translation job ${jobId} not found. The job may have expired or the ID is incorrect.`);
1355
1394
  }
1356
-
1395
+
1357
1396
  // Handle timeout
1358
1397
  if (error.code === 'ECONNABORTED') {
1359
1398
  throw new Error(`Status check timed out. The service may be experiencing high load. Please try again.`);
1360
1399
  }
1361
-
1400
+
1362
1401
  // Generic error
1363
1402
  throw new Error(`Unable to check translation status: ${error.message}`);
1364
1403
  }
1365
1404
  }
1366
1405
 
1406
+ // Handler for resuming translation jobs
1407
+ async function handleResumeTranslation(args) {
1408
+ const { jobId } = args;
1409
+
1410
+ if (!jobId) {
1411
+ throw new Error('jobId is required');
1412
+ }
1413
+
1414
+ const mcpRequest = {
1415
+ jsonrpc: '2.0',
1416
+ id: Date.now(),
1417
+ method: 'tools/call',
1418
+ params: {
1419
+ name: 'resume_translation',
1420
+ arguments: { jobId }
1421
+ }
1422
+ };
1423
+
1424
+ try {
1425
+ const response = await axios.post(MCP_SERVER_URL, mcpRequest, {
1426
+ headers: { 'Content-Type': 'application/json' },
1427
+ timeout: 30000
1428
+ });
1429
+
1430
+ if (response.data.error) {
1431
+ throw new Error(`Resume translation error: ${response.data.error.message || response.data.error}`);
1432
+ }
1433
+
1434
+ return response.data.result;
1435
+ } catch (error) {
1436
+ console.error('Resume translation error:', error);
1437
+
1438
+ // Handle 503 service unavailable
1439
+ if (error.response?.status === 503) {
1440
+ throw new Error(`i18n-agent encountered unexpected problem, and we are working on it, try again later.`);
1441
+ }
1442
+
1443
+ // Handle 404 not found
1444
+ if (error.response?.status === 404) {
1445
+ throw new Error(`Translation job ${jobId} not found. The job may have expired or the ID is incorrect.`);
1446
+ }
1447
+
1448
+ // Handle timeout
1449
+ if (error.code === 'ECONNABORTED') {
1450
+ throw new Error(`Resume request timed out. The service may be experiencing high load. Please try again.`);
1451
+ }
1452
+
1453
+ // Generic error
1454
+ throw new Error(`Unable to resume translation: ${error.message}`);
1455
+ }
1456
+ }
1457
+
1458
+ // Handler for downloading completed translations
1459
+ async function handleDownloadTranslations(args) {
1460
+ const { jobId } = args;
1461
+
1462
+ if (!jobId) {
1463
+ throw new Error('jobId is required');
1464
+ }
1465
+
1466
+ const mcpRequest = {
1467
+ jsonrpc: '2.0',
1468
+ id: Date.now(),
1469
+ method: 'tools/call',
1470
+ params: {
1471
+ name: 'download_translations',
1472
+ arguments: { jobId }
1473
+ }
1474
+ };
1475
+
1476
+ try {
1477
+ const response = await axios.post(MCP_SERVER_URL, mcpRequest, {
1478
+ headers: { 'Content-Type': 'application/json' },
1479
+ timeout: 30000
1480
+ });
1481
+
1482
+ if (response.data.error) {
1483
+ throw new Error(`Download translations error: ${response.data.error.message || response.data.error}`);
1484
+ }
1485
+
1486
+ return response.data.result;
1487
+ } catch (error) {
1488
+ console.error('Download translations error:', error);
1489
+
1490
+ // Handle 503 service unavailable
1491
+ if (error.response?.status === 503) {
1492
+ throw new Error(`i18n-agent encountered unexpected problem, and we are working on it, try again later.`);
1493
+ }
1494
+
1495
+ // Handle 404 not found
1496
+ if (error.response?.status === 404) {
1497
+ throw new Error(`Translation job ${jobId} not found. The job may have expired or the ID is incorrect.`);
1498
+ }
1499
+
1500
+ // Handle timeout
1501
+ if (error.code === 'ECONNABORTED') {
1502
+ throw new Error(`Download request timed out. The service may be experiencing high load. Please try again.`);
1503
+ }
1504
+
1505
+ // Generic error
1506
+ throw new Error(`Unable to download translations: ${error.message}`);
1507
+ }
1508
+ }
1509
+
1367
1510
  // Start the server
1368
1511
  async function main() {
1369
1512
  const transport = new StdioServerTransport();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@i18n-agent/mcp-client",
3
- "version": "1.7.6",
3
+ "version": "1.7.8",
4
4
  "description": "MCP client for i18n-agent translation service with async job support and enhanced progress tracking - supports Claude, Cursor, VS Code, and other AI IDEs",
5
5
  "main": "mcp-client.js",
6
6
  "bin": {