@i18n-agent/mcp-client 1.9.8 ā 1.12.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/CONTRIBUTING.md +2 -2
- package/README.md +6 -5
- package/{mcp-client.js ā i18n-agent.js} +124 -27
- package/install.js +36 -6
- package/package.json +5 -5
package/CONTRIBUTING.md
CHANGED
|
@@ -34,7 +34,7 @@ npm test
|
|
|
34
34
|
node install.js
|
|
35
35
|
|
|
36
36
|
# Test MCP client syntax
|
|
37
|
-
node -c
|
|
37
|
+
node -c i18n-agent.js
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
## š Types of Contributions
|
|
@@ -72,7 +72,7 @@ npm test
|
|
|
72
72
|
node install.js
|
|
73
73
|
|
|
74
74
|
# Check for syntax errors
|
|
75
|
-
node -c
|
|
75
|
+
node -c i18n-agent.js
|
|
76
76
|
node -c install.js
|
|
77
77
|
```
|
|
78
78
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# š i18n-agent MCP Client
|
|
2
2
|
|
|
3
|
-
Professional translation service client for Claude, Cursor, VS Code, and other AI IDEs using the Model Context Protocol (MCP).
|
|
3
|
+
Professional translation service client for Claude, Cursor, VS Code, Antigravity, and other AI IDEs using the Model Context Protocol (MCP).
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@i18n-agent/mcp-client)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -20,7 +20,7 @@ Professional translation service client for Claude, Cursor, VS Code, and other A
|
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
22
|
npm install -g @i18n-agent/mcp-client
|
|
23
|
-
|
|
23
|
+
i18n-agent
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
**Note:** Global installation is required due to npm bin naming limitations. The installer will detect all available AI IDEs and configure them automatically.
|
|
@@ -77,6 +77,7 @@ Analyze "Hello world! This is a test." for translation to Spanish
|
|
|
77
77
|
| **Cursor** | ā
Auto-configured | `~/.cursor/mcp_settings.json` | `~/.cursor/mcp_settings.json` | `~/.cursor/mcp_settings.json` |
|
|
78
78
|
| **VS Code** | ā
Auto-configured | `~/.vscode/mcp_settings.json` | `~/.vscode/mcp_settings.json` | `~/.vscode/mcp_settings.json` |
|
|
79
79
|
| **Codex (OpenAI)** | ā
Auto-configured | `~/.codex/mcp_settings.json` | `~/.codex/mcp_settings.json` | `~/.codex/mcp_settings.json` |
|
|
80
|
+
| **Antigravity (Google)** | ā
Auto-configured | `~/.gemini/antigravity/mcp_config.json` | `%USERPROFILE%\.gemini\antigravity\mcp_config.json` | `~/.config/antigravity/mcp_config.json` |
|
|
80
81
|
|
|
81
82
|
**Note:** The installer automatically detects your platform and uses the correct config paths.
|
|
82
83
|
|
|
@@ -156,7 +157,7 @@ Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
|
156
157
|
"mcpServers": {
|
|
157
158
|
"i18n-agent": {
|
|
158
159
|
"command": "node",
|
|
159
|
-
"args": ["/path/to/
|
|
160
|
+
"args": ["/path/to/i18n-agent.js"],
|
|
160
161
|
"env": {
|
|
161
162
|
"MCP_SERVER_URL": "https://mcp.i18nagent.ai",
|
|
162
163
|
"API_KEY": "your-api-key-here"
|
|
@@ -174,7 +175,7 @@ Create `.cursor/mcp_settings.json` or `.vscode/mcp_settings.json`:
|
|
|
174
175
|
"mcpServers": {
|
|
175
176
|
"i18n-agent": {
|
|
176
177
|
"command": "node",
|
|
177
|
-
"args": ["/path/to/
|
|
178
|
+
"args": ["/path/to/i18n-agent.js"],
|
|
178
179
|
"env": {
|
|
179
180
|
"MCP_SERVER_URL": "https://mcp.i18nagent.ai",
|
|
180
181
|
"API_KEY": "your-api-key-here"
|
|
@@ -252,7 +253,7 @@ This usually happens with Node Version Managers (nvm, fnm, n). The installer now
|
|
|
252
253
|
#!/bin/bash
|
|
253
254
|
export PATH="$(dirname $(which node)):$PATH"
|
|
254
255
|
cd ~/.claude
|
|
255
|
-
exec node node_modules/@i18n-agent/mcp-client/
|
|
256
|
+
exec node node_modules/@i18n-agent/mcp-client/i18n-agent.js
|
|
256
257
|
```
|
|
257
258
|
|
|
258
259
|
Make it executable:
|
|
@@ -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.
|
|
8
|
+
const MCP_CLIENT_VERSION = '1.12.0';
|
|
9
9
|
|
|
10
10
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
11
11
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
@@ -43,6 +43,40 @@ if (!process.env.API_KEY) {
|
|
|
43
43
|
const MCP_SERVER_URL = process.env.MCP_SERVER_URL;
|
|
44
44
|
const API_KEY = process.env.API_KEY;
|
|
45
45
|
|
|
46
|
+
// Heavy load detection - matches error message from service-mcp error-message-sanitizer
|
|
47
|
+
// Exact message: 'Our system is under heavy load, please resume your job later.'
|
|
48
|
+
const HEAVY_LOAD_PATTERNS = [
|
|
49
|
+
/Our system is under heavy load/i,
|
|
50
|
+
/system is under heavy load.*resume.*later/i,
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
const HEAVY_LOAD_MESSAGE = `ā³ System under heavy load
|
|
54
|
+
|
|
55
|
+
The translation service is experiencing high demand. Your job has been saved and can be resumed later.
|
|
56
|
+
|
|
57
|
+
ā ļø IMPORTANT FOR AI AGENTS:
|
|
58
|
+
⢠Do NOT retry or resume immediately - this will likely fail again
|
|
59
|
+
⢠Do NOT poll check_translation_status repeatedly
|
|
60
|
+
⢠Wait at least 5-10 minutes before attempting to resume
|
|
61
|
+
⢠The job is saved - no data is lost
|
|
62
|
+
|
|
63
|
+
š To resume later:
|
|
64
|
+
1. Wait for system load to decrease (5-10 minutes minimum)
|
|
65
|
+
2. Use resume_translation with the same jobId
|
|
66
|
+
3. If it fails again, wait longer before retrying
|
|
67
|
+
|
|
68
|
+
š” Tip: Inform the user about the delay and let them decide when to retry.`;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Check if an error message indicates heavy system load
|
|
72
|
+
* @param {string} errorMessage - The error message to check
|
|
73
|
+
* @returns {boolean} - True if the error indicates heavy load
|
|
74
|
+
*/
|
|
75
|
+
function isHeavyLoadError(errorMessage) {
|
|
76
|
+
if (!errorMessage) return false;
|
|
77
|
+
return HEAVY_LOAD_PATTERNS.some(pattern => pattern.test(errorMessage));
|
|
78
|
+
}
|
|
79
|
+
|
|
46
80
|
// Available tools
|
|
47
81
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
48
82
|
return {
|
|
@@ -689,26 +723,35 @@ async function handleTranslateText(args) {
|
|
|
689
723
|
throw new Error(errorMsg);
|
|
690
724
|
}
|
|
691
725
|
|
|
726
|
+
// Check for heavy load error (from service-mcp error-message-sanitizer)
|
|
727
|
+
const errorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
728
|
+
error.response?.data?.error?.message ||
|
|
729
|
+
error.response?.data?.message ||
|
|
730
|
+
error.message;
|
|
731
|
+
if (isHeavyLoadError(errorDetails)) {
|
|
732
|
+
throw new Error(`${HEAVY_LOAD_MESSAGE}\n[MCP v${MCP_CLIENT_VERSION}/STDIO/translate_text]`);
|
|
733
|
+
}
|
|
734
|
+
|
|
692
735
|
// Check if it's actually a service unavailable error (only for real infrastructure issues)
|
|
693
736
|
if (error.response?.status === 503) {
|
|
694
737
|
throw new Error(`i18n-agent encountered unexpected problem, and we are working on it, try again later.`);
|
|
695
738
|
}
|
|
696
|
-
|
|
697
|
-
if (error.code === 'ECONNREFUSED' ||
|
|
698
|
-
error.code === 'ETIMEDOUT' ||
|
|
739
|
+
|
|
740
|
+
if (error.code === 'ECONNREFUSED' ||
|
|
741
|
+
error.code === 'ETIMEDOUT' ||
|
|
699
742
|
error.code === 'ENOTFOUND' ||
|
|
700
743
|
error.response?.status === 502 ||
|
|
701
744
|
error.response?.status === 504) {
|
|
702
|
-
const serviceErrorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
703
|
-
error.response?.data?.error?.message ||
|
|
745
|
+
const serviceErrorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
746
|
+
error.response?.data?.error?.message ||
|
|
704
747
|
error.message;
|
|
705
748
|
const debugInfo = `Code: ${error.code || 'N/A'}\nStatus: ${error.response?.status || 'N/A'}\nStatusText: ${error.response?.statusText || 'N/A'}\nDetails: ${serviceErrorDetails}\nURL: ${error.config?.url || 'N/A'}\nTimestamp: ${new Date().toISOString()}`;
|
|
706
749
|
throw new Error(`Translation service error\n${debugInfo}\n[MCP v${MCP_CLIENT_VERSION}/STDIO/translate_text]`);
|
|
707
750
|
}
|
|
708
|
-
|
|
751
|
+
|
|
709
752
|
// For other errors, include all debug info in the error message
|
|
710
|
-
const generalErrorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
711
|
-
error.response?.data?.error?.message ||
|
|
753
|
+
const generalErrorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
754
|
+
error.response?.data?.error?.message ||
|
|
712
755
|
error.message;
|
|
713
756
|
const debugInfo = `Status: ${error.response?.status || 'N/A'}\nStatusText: ${error.response?.statusText || 'N/A'}\nDetails: ${generalErrorDetails}\nTimestamp: ${new Date().toISOString()}`;
|
|
714
757
|
throw new Error(`Error\n${debugInfo}\n[MCP v${MCP_CLIENT_VERSION}/STDIO/translate_text]`);
|
|
@@ -1046,26 +1089,31 @@ async function handleTranslateFile(args) {
|
|
|
1046
1089
|
throw new Error(errorMsg);
|
|
1047
1090
|
}
|
|
1048
1091
|
|
|
1092
|
+
// Check for heavy load error (from service-mcp error-message-sanitizer)
|
|
1093
|
+
if (isHeavyLoadError(timeoutErrorDetails)) {
|
|
1094
|
+
throw new Error(`${HEAVY_LOAD_MESSAGE}\n[MCP v${MCP_CLIENT_VERSION}/STDIO/translate_file]`);
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1049
1097
|
// Check if it's actually a service unavailable error (only for real infrastructure issues)
|
|
1050
1098
|
if (error.response?.status === 503 && content.length <= 50000) {
|
|
1051
1099
|
throw new Error(`i18n-agent encountered unexpected problem, and we are working on it, try again later.`);
|
|
1052
1100
|
}
|
|
1053
|
-
|
|
1054
|
-
if (error.code === 'ECONNREFUSED' ||
|
|
1055
|
-
error.code === 'ETIMEDOUT' ||
|
|
1101
|
+
|
|
1102
|
+
if (error.code === 'ECONNREFUSED' ||
|
|
1103
|
+
error.code === 'ETIMEDOUT' ||
|
|
1056
1104
|
error.code === 'ENOTFOUND' ||
|
|
1057
1105
|
error.response?.status === 502 ||
|
|
1058
1106
|
error.response?.status === 504) {
|
|
1059
|
-
const serviceErrorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
1060
|
-
error.response?.data?.error?.message ||
|
|
1107
|
+
const serviceErrorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
1108
|
+
error.response?.data?.error?.message ||
|
|
1061
1109
|
error.message;
|
|
1062
1110
|
const debugInfo = `Code: ${error.code || 'N/A'}\nStatus: ${error.response?.status || 'N/A'}\nStatusText: ${error.response?.statusText || 'N/A'}\nDetails: ${serviceErrorDetails}\nURL: ${error.config?.url || 'N/A'}\nTimestamp: ${new Date().toISOString()}`;
|
|
1063
1111
|
throw new Error(`Translation service error\n${debugInfo}\n[MCP v${MCP_CLIENT_VERSION}/STDIO/translate_file]`);
|
|
1064
1112
|
}
|
|
1065
|
-
|
|
1113
|
+
|
|
1066
1114
|
// For other errors, include all debug info in the error message
|
|
1067
|
-
const finalErrorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
1068
|
-
error.response?.data?.error?.message ||
|
|
1115
|
+
const finalErrorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
1116
|
+
error.response?.data?.error?.message ||
|
|
1069
1117
|
error.message;
|
|
1070
1118
|
const debugInfo = `Status: ${error.response?.status || 'N/A'}\nStatusText: ${error.response?.statusText || 'N/A'}\nDetails: ${finalErrorDetails}\nTimestamp: ${new Date().toISOString()}`;
|
|
1071
1119
|
throw new Error(`Error\n${debugInfo}\n[MCP v${MCP_CLIENT_VERSION}/STDIO/translate_file]`);
|
|
@@ -1122,48 +1170,64 @@ async function pollTranslationJob(jobId, estimatedTime) {
|
|
|
1122
1170
|
|
|
1123
1171
|
if (response.data.error) {
|
|
1124
1172
|
const errorMsg = response.data.error.message || response.data.error;
|
|
1125
|
-
|
|
1173
|
+
|
|
1174
|
+
// Check for heavy load error - stop polling immediately
|
|
1175
|
+
if (isHeavyLoadError(errorMsg.toString())) {
|
|
1176
|
+
throw new Error(`${HEAVY_LOAD_MESSAGE}\n\nJob ID: ${jobId}\n[MCP v${MCP_CLIENT_VERSION}/pollTranslationJob]`);
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
const isAuthError = errorMsg.toString().toLowerCase().includes('api key') ||
|
|
1126
1180
|
errorMsg.toString().toLowerCase().includes('api_key') ||
|
|
1127
1181
|
errorMsg.toString().toLowerCase().includes('unauthorized');
|
|
1128
|
-
const isCreditError = errorMsg.toString().toLowerCase().includes('credit') ||
|
|
1182
|
+
const isCreditError = errorMsg.toString().toLowerCase().includes('credit') ||
|
|
1129
1183
|
errorMsg.toString().toLowerCase().includes('quota') ||
|
|
1130
1184
|
errorMsg.toString().toLowerCase().includes('limit exceeded');
|
|
1131
|
-
|
|
1185
|
+
|
|
1132
1186
|
let finalErrorMsg = `Status check error: ${errorMsg}`;
|
|
1133
1187
|
if (!isAuthError && !isCreditError) {
|
|
1134
1188
|
finalErrorMsg += `. Please retry with a smaller chunk or split the content into multiple requests.`;
|
|
1135
1189
|
}
|
|
1136
1190
|
throw new Error(finalErrorMsg);
|
|
1137
1191
|
}
|
|
1138
|
-
|
|
1192
|
+
|
|
1139
1193
|
const result = response.data.result;
|
|
1140
1194
|
if (result && result.content && result.content[0]) {
|
|
1141
1195
|
const status = JSON.parse(result.content[0].text);
|
|
1142
|
-
|
|
1196
|
+
|
|
1143
1197
|
if (status.status === 'completed') {
|
|
1144
1198
|
return status.result;
|
|
1145
1199
|
} else if (status.status === 'failed') {
|
|
1146
1200
|
const errorMsg = status.error;
|
|
1147
|
-
|
|
1201
|
+
|
|
1202
|
+
// Check for heavy load error - stop polling immediately
|
|
1203
|
+
if (isHeavyLoadError(errorMsg.toString())) {
|
|
1204
|
+
throw new Error(`${HEAVY_LOAD_MESSAGE}\n\nJob ID: ${jobId}\n[MCP v${MCP_CLIENT_VERSION}/pollTranslationJob]`);
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
const isAuthError = errorMsg.toString().toLowerCase().includes('api key') ||
|
|
1148
1208
|
errorMsg.toString().toLowerCase().includes('api_key') ||
|
|
1149
1209
|
errorMsg.toString().toLowerCase().includes('unauthorized');
|
|
1150
|
-
const isCreditError = errorMsg.toString().toLowerCase().includes('credit') ||
|
|
1210
|
+
const isCreditError = errorMsg.toString().toLowerCase().includes('credit') ||
|
|
1151
1211
|
errorMsg.toString().toLowerCase().includes('quota') ||
|
|
1152
1212
|
errorMsg.toString().toLowerCase().includes('limit exceeded');
|
|
1153
|
-
|
|
1213
|
+
|
|
1154
1214
|
let finalErrorMsg = `Translation failed: ${errorMsg}`;
|
|
1155
1215
|
if (!isAuthError && !isCreditError) {
|
|
1156
1216
|
finalErrorMsg += `. Please retry with a smaller chunk or split the content into multiple requests.`;
|
|
1157
1217
|
}
|
|
1158
1218
|
throw new Error(finalErrorMsg);
|
|
1159
1219
|
}
|
|
1160
|
-
|
|
1220
|
+
|
|
1161
1221
|
// Still processing - continue polling
|
|
1162
1222
|
console.error(`Translation progress: ${status.progress}% (${status.message})`);
|
|
1163
1223
|
}
|
|
1164
1224
|
} catch (error) {
|
|
1225
|
+
// Check for heavy load error - stop polling immediately (don't continue)
|
|
1226
|
+
if (isHeavyLoadError(error.message)) {
|
|
1227
|
+
throw error; // Re-throw heavy load error to stop polling
|
|
1228
|
+
}
|
|
1165
1229
|
console.error(`Error polling job status: ${error.message}`);
|
|
1166
|
-
// Continue polling
|
|
1230
|
+
// Continue polling for other transient errors
|
|
1167
1231
|
}
|
|
1168
1232
|
}
|
|
1169
1233
|
|
|
@@ -1727,6 +1791,17 @@ async function handleCheckTranslationStatus(args) {
|
|
|
1727
1791
|
} catch (error) {
|
|
1728
1792
|
console.error('Check translation status error:', error);
|
|
1729
1793
|
|
|
1794
|
+
// Extract error message from various response formats
|
|
1795
|
+
const errorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
1796
|
+
error.response?.data?.error?.message ||
|
|
1797
|
+
error.response?.data?.message ||
|
|
1798
|
+
error.message;
|
|
1799
|
+
|
|
1800
|
+
// Check for heavy load error (from service-mcp error-message-sanitizer)
|
|
1801
|
+
if (isHeavyLoadError(errorDetails)) {
|
|
1802
|
+
throw new Error(`${HEAVY_LOAD_MESSAGE}\n\nJob ID: ${jobId}\n[MCP v${MCP_CLIENT_VERSION}/check_translation_status]`);
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1730
1805
|
// Handle 503 service unavailable
|
|
1731
1806
|
if (error.response?.status === 503) {
|
|
1732
1807
|
throw new Error(`i18n-agent encountered unexpected problem, and we are working on it, try again later.`);
|
|
@@ -1779,6 +1854,17 @@ async function handleResumeTranslation(args) {
|
|
|
1779
1854
|
} catch (error) {
|
|
1780
1855
|
console.error('Resume translation error:', error);
|
|
1781
1856
|
|
|
1857
|
+
// Extract error message from various response formats
|
|
1858
|
+
const errorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
1859
|
+
error.response?.data?.error?.message ||
|
|
1860
|
+
error.response?.data?.message ||
|
|
1861
|
+
error.message;
|
|
1862
|
+
|
|
1863
|
+
// Check for heavy load error (from service-mcp error-message-sanitizer)
|
|
1864
|
+
if (isHeavyLoadError(errorDetails)) {
|
|
1865
|
+
throw new Error(`${HEAVY_LOAD_MESSAGE}\n\nJob ID: ${jobId}\n[MCP v${MCP_CLIENT_VERSION}/resume_translation]`);
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1782
1868
|
// Handle 503 service unavailable
|
|
1783
1869
|
if (error.response?.status === 503) {
|
|
1784
1870
|
throw new Error(`i18n-agent encountered unexpected problem, and we are working on it, try again later.`);
|
|
@@ -1930,6 +2016,17 @@ async function handleDownloadTranslations(args) {
|
|
|
1930
2016
|
} catch (error) {
|
|
1931
2017
|
console.error('Download translations error:', error);
|
|
1932
2018
|
|
|
2019
|
+
// Extract error message from various response formats
|
|
2020
|
+
const errorDetails = error.response?.data?.result?.content?.[0]?.text ||
|
|
2021
|
+
error.response?.data?.error?.message ||
|
|
2022
|
+
error.response?.data?.message ||
|
|
2023
|
+
error.message;
|
|
2024
|
+
|
|
2025
|
+
// Check for heavy load error (from service-mcp error-message-sanitizer)
|
|
2026
|
+
if (isHeavyLoadError(errorDetails)) {
|
|
2027
|
+
throw new Error(`${HEAVY_LOAD_MESSAGE}\n\nJob ID: ${jobId}\n[MCP v${MCP_CLIENT_VERSION}/download_translations]`);
|
|
2028
|
+
}
|
|
2029
|
+
|
|
1933
2030
|
// Handle 503 service unavailable
|
|
1934
2031
|
if (error.response?.status === 503) {
|
|
1935
2032
|
throw new Error(`i18n-agent encountered unexpected problem, and we are working on it, try again later.`);
|
package/install.js
CHANGED
|
@@ -37,8 +37,32 @@ function getClaudeDesktopPath() {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
function getAntigravityPath() {
|
|
41
|
+
const platform = process.platform;
|
|
42
|
+
if (platform === 'darwin') {
|
|
43
|
+
// macOS
|
|
44
|
+
return {
|
|
45
|
+
configPath: path.join(os.homedir(), '.gemini/antigravity/mcp_config.json'),
|
|
46
|
+
displayPath: '~/.gemini/antigravity/mcp_config.json'
|
|
47
|
+
};
|
|
48
|
+
} else if (platform === 'win32') {
|
|
49
|
+
// Windows
|
|
50
|
+
return {
|
|
51
|
+
configPath: path.join(os.homedir(), '.gemini/antigravity/mcp_config.json'),
|
|
52
|
+
displayPath: '%USERPROFILE%\\.gemini\\antigravity\\mcp_config.json'
|
|
53
|
+
};
|
|
54
|
+
} else {
|
|
55
|
+
// Linux
|
|
56
|
+
return {
|
|
57
|
+
configPath: path.join(os.homedir(), '.config/antigravity/mcp_config.json'),
|
|
58
|
+
displayPath: '~/.config/antigravity/mcp_config.json'
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
40
63
|
// Supported IDE configurations
|
|
41
64
|
const claudePaths = getClaudeDesktopPath();
|
|
65
|
+
const antigravityPaths = getAntigravityPath();
|
|
42
66
|
const IDE_CONFIGS = {
|
|
43
67
|
claude: {
|
|
44
68
|
name: 'Claude Desktop',
|
|
@@ -64,6 +88,11 @@ const IDE_CONFIGS = {
|
|
|
64
88
|
name: 'Codex (OpenAI)',
|
|
65
89
|
configPath: path.join(os.homedir(), '.codex/mcp_settings.json'),
|
|
66
90
|
displayPath: '~/.codex/mcp_settings.json'
|
|
91
|
+
},
|
|
92
|
+
antigravity: {
|
|
93
|
+
name: 'Antigravity (Google)',
|
|
94
|
+
configPath: antigravityPaths.configPath,
|
|
95
|
+
displayPath: antigravityPaths.displayPath
|
|
67
96
|
}
|
|
68
97
|
};
|
|
69
98
|
|
|
@@ -83,9 +112,9 @@ Features:
|
|
|
83
112
|
const getMcpClientPaths = () => {
|
|
84
113
|
// Instead of using ephemeral npx cache, install to stable location
|
|
85
114
|
const stableDir = path.join(os.homedir(), '.claude', 'mcp-servers', 'i18n-agent');
|
|
86
|
-
const mcpClientPath = path.join(stableDir, '
|
|
115
|
+
const mcpClientPath = path.join(stableDir, 'i18n-agent.js');
|
|
87
116
|
const packageDir = stableDir;
|
|
88
|
-
return { mcpClientPath, packageDir, sourceFile: path.resolve(__dirname, '
|
|
117
|
+
return { mcpClientPath, packageDir, sourceFile: path.resolve(__dirname, 'i18n-agent.js') };
|
|
89
118
|
};
|
|
90
119
|
|
|
91
120
|
function copyMcpClientToStableLocation() {
|
|
@@ -94,7 +123,7 @@ function copyMcpClientToStableLocation() {
|
|
|
94
123
|
// Create stable directory
|
|
95
124
|
fs.mkdirSync(paths.packageDir, { recursive: true });
|
|
96
125
|
|
|
97
|
-
// Copy
|
|
126
|
+
// Copy i18n-agent.js to stable location
|
|
98
127
|
fs.copyFileSync(paths.sourceFile, paths.mcpClientPath);
|
|
99
128
|
|
|
100
129
|
// Copy package.json to stable location
|
|
@@ -598,6 +627,7 @@ Supported IDEs:
|
|
|
598
627
|
- Cursor
|
|
599
628
|
- VS Code (with MCP extension)
|
|
600
629
|
- Codex (OpenAI)
|
|
630
|
+
- Antigravity (Google)
|
|
601
631
|
|
|
602
632
|
Manual setup:
|
|
603
633
|
1. Create the configuration file for your IDE
|
|
@@ -808,7 +838,7 @@ Step 2: Add API key to your IDE`);
|
|
|
808
838
|
console.log(`
|
|
809
839
|
For Claude Code CLI (recommended):
|
|
810
840
|
claude mcp remove --scope user i18n-agent
|
|
811
|
-
claude mcp add --transport stdio --scope user i18n-agent -e MCP_SERVER_URL=https://mcp.i18nagent.ai -e API_KEY=your_key_here -- node ~/.claude/mcp-servers/i18n-agent/
|
|
841
|
+
claude mcp add --transport stdio --scope user i18n-agent -e MCP_SERVER_URL=https://mcp.i18nagent.ai -e API_KEY=your_key_here -- node ~/.claude/mcp-servers/i18n-agent/i18n-agent.js
|
|
812
842
|
`);
|
|
813
843
|
}
|
|
814
844
|
|
|
@@ -816,7 +846,7 @@ Step 2: Add API key to your IDE`);
|
|
|
816
846
|
console.log(`
|
|
817
847
|
For Codex CLI (recommended):
|
|
818
848
|
codex mcp remove i18n-agent
|
|
819
|
-
codex mcp add --env MCP_SERVER_URL=https://mcp.i18nagent.ai --env API_KEY=your_key_here i18n-agent node ~/.claude/mcp-servers/i18n-agent/
|
|
849
|
+
codex mcp add --env MCP_SERVER_URL=https://mcp.i18nagent.ai --env API_KEY=your_key_here i18n-agent node ~/.claude/mcp-servers/i18n-agent/i18n-agent.js
|
|
820
850
|
`);
|
|
821
851
|
}
|
|
822
852
|
|
|
@@ -873,7 +903,7 @@ Try these commands in your AI IDE:
|
|
|
873
903
|
const isMainModule = process.argv[1] && (
|
|
874
904
|
import.meta.url === `file://${process.argv[1]}` ||
|
|
875
905
|
import.meta.url.endsWith(process.argv[1]) ||
|
|
876
|
-
process.argv[1].includes('
|
|
906
|
+
process.argv[1].includes('i18n-agent')
|
|
877
907
|
);
|
|
878
908
|
|
|
879
909
|
if (isMainModule) {
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@i18n-agent/mcp-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "š i18n-agent MCP Client - 48 languages, AI-powered translation for Claude, Claude Code, Cursor, VS Code, Codex. Get API key at https://app.i18nagent.ai",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "i18n-agent.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"
|
|
7
|
+
"i18n-agent": "install.js"
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"install": "node install.js",
|
|
12
12
|
"test": "node test.js",
|
|
13
|
-
"postinstall": "echo '\nš i18n-agent MCP Client installed successfully!\nš” Run:
|
|
13
|
+
"postinstall": "echo '\nš i18n-agent MCP Client installed successfully!\nš” Run: i18n-agent (if installed globally) or node install.js\n'"
|
|
14
14
|
},
|
|
15
15
|
"repository": {
|
|
16
16
|
"type": "git",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"node": ">=16.0.0"
|
|
43
43
|
},
|
|
44
44
|
"files": [
|
|
45
|
-
"
|
|
45
|
+
"i18n-agent.js",
|
|
46
46
|
"namespace-detector.js",
|
|
47
47
|
"install.js",
|
|
48
48
|
"README.md",
|