@questlang/mcp-server 0.1.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 +21 -0
- package/README.md +88 -0
- package/SKILL.md +50 -0
- package/dist/client.d.ts +31 -0
- package/dist/client.js +120 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +105 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +84 -0
- package/dist/init.js.map +1 -0
- package/dist/parsers/android-xml.d.ts +2 -0
- package/dist/parsers/android-xml.js +41 -0
- package/dist/parsers/android-xml.js.map +1 -0
- package/dist/parsers/csv.d.ts +2 -0
- package/dist/parsers/csv.js +55 -0
- package/dist/parsers/csv.js.map +1 -0
- package/dist/parsers/index.d.ts +5 -0
- package/dist/parsers/index.js +55 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/ios-strings.d.ts +2 -0
- package/dist/parsers/ios-strings.js +42 -0
- package/dist/parsers/ios-strings.js.map +1 -0
- package/dist/parsers/json.d.ts +2 -0
- package/dist/parsers/json.js +41 -0
- package/dist/parsers/json.js.map +1 -0
- package/dist/parsers/po.d.ts +2 -0
- package/dist/parsers/po.js +77 -0
- package/dist/parsers/po.js.map +1 -0
- package/dist/parsers/xliff.d.ts +2 -0
- package/dist/parsers/xliff.js +48 -0
- package/dist/parsers/xliff.js.map +1 -0
- package/dist/tools/balance.d.ts +4 -0
- package/dist/tools/balance.js +4 -0
- package/dist/tools/balance.js.map +1 -0
- package/dist/tools/estimate.d.ts +11 -0
- package/dist/tools/estimate.js +43 -0
- package/dist/tools/estimate.js.map +1 -0
- package/dist/tools/glossary.d.ts +7 -0
- package/dist/tools/glossary.js +28 -0
- package/dist/tools/glossary.js.map +1 -0
- package/dist/tools/orders.d.ts +10 -0
- package/dist/tools/orders.js +13 -0
- package/dist/tools/orders.js.map +1 -0
- package/dist/tools/review.d.ts +3 -0
- package/dist/tools/review.js +52 -0
- package/dist/tools/review.js.map +1 -0
- package/dist/tools/scan.d.ts +12 -0
- package/dist/tools/scan.js +65 -0
- package/dist/tools/scan.js.map +1 -0
- package/dist/tools/status.d.ts +12 -0
- package/dist/tools/status.js +41 -0
- package/dist/tools/status.js.map +1 -0
- package/dist/tools/translate.d.ts +8 -0
- package/dist/tools/translate.js +21 -0
- package/dist/tools/translate.js.map +1 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export async function getOrderStatus(client, orderId) {
|
|
2
|
+
const order = await client.getOrder(orderId);
|
|
3
|
+
const result = {
|
|
4
|
+
status: order.status,
|
|
5
|
+
progress: (order.translationProgress ?? order.progress ?? 0),
|
|
6
|
+
};
|
|
7
|
+
const files = order.files;
|
|
8
|
+
if (files?.[0]?.translatedUrl) {
|
|
9
|
+
result.downloadUrl = files[0].translatedUrl;
|
|
10
|
+
}
|
|
11
|
+
if (order.error) {
|
|
12
|
+
result.error = order.error;
|
|
13
|
+
}
|
|
14
|
+
// Include validation report summary if present
|
|
15
|
+
const validationReport = order.validationReport;
|
|
16
|
+
if (validationReport) {
|
|
17
|
+
const totalCells = validationReport.totalCellsWithIssues;
|
|
18
|
+
const byCategory = validationReport.issuesByCategory;
|
|
19
|
+
if (totalCells != null && byCategory) {
|
|
20
|
+
const categoryParts = Object.entries(byCategory)
|
|
21
|
+
.map(([cat, count]) => `${cat}: ${count}`)
|
|
22
|
+
.join(', ');
|
|
23
|
+
result.validationSummary = `${totalCells} cells with issues (${categoryParts})`;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Include quality review status if present
|
|
27
|
+
if (order.qualityReviewStatus) {
|
|
28
|
+
result.qualityReviewStatus = order.qualityReviewStatus;
|
|
29
|
+
}
|
|
30
|
+
if (order.status === 'completed') {
|
|
31
|
+
try {
|
|
32
|
+
const content = await client.downloadOrder(orderId);
|
|
33
|
+
result.translatedContent = content;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Download failed, still return status
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/tools/status.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAuB,EAAE,OAAe;IAC3E,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE7C,MAAM,MAAM,GAAiB;QAC3B,MAAM,EAAE,KAAK,CAAC,MAAgB;QAC9B,QAAQ,EAAE,CAAC,KAAK,CAAC,mBAAmB,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAW;KACvE,CAAC;IAEF,MAAM,KAAK,GAAG,KAAK,CAAC,KAAmD,CAAC;IACxE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC;QAC9B,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,aAAuB,CAAC;IACxD,CAAC;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAe,CAAC;IACvC,CAAC;IAED,+CAA+C;IAC/C,MAAM,gBAAgB,GAAG,KAAK,CAAC,gBAAuD,CAAC;IACvF,IAAI,gBAAgB,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,gBAAgB,CAAC,oBAA0C,CAAC;QAC/E,MAAM,UAAU,GAAG,gBAAgB,CAAC,gBAAsD,CAAC;QAC3F,IAAI,UAAU,IAAI,IAAI,IAAI,UAAU,EAAE,CAAC;YACrC,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;iBAC7C,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,KAAK,EAAE,CAAC;iBACzC,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,MAAM,CAAC,iBAAiB,GAAG,GAAG,UAAU,uBAAuB,aAAa,GAAG,CAAC;QAClF,CAAC;IACH,CAAC;IAED,2CAA2C;IAC3C,IAAI,KAAK,CAAC,mBAAmB,EAAE,CAAC;QAC9B,MAAM,CAAC,mBAAmB,GAAG,KAAK,CAAC,mBAA6B,CAAC;IACnE,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACpD,MAAM,CAAC,iBAAiB,GAAG,OAAO,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { QuestlangClient } from '../client.js';
|
|
2
|
+
import type { GameContext } from '../types.js';
|
|
3
|
+
interface TranslateResult {
|
|
4
|
+
orderId: string;
|
|
5
|
+
message: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function translateFile(client: QuestlangClient, filePath: string, targetLanguages: string[], sourceLanguage?: string, model?: string, gameContext?: GameContext): Promise<TranslateResult>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { basename } from 'node:path';
|
|
3
|
+
import { parseFile, toCsvContent } from '../parsers/index.js';
|
|
4
|
+
export async function translateFile(client, filePath, targetLanguages, sourceLanguage, model, gameContext) {
|
|
5
|
+
const content = await readFile(filePath, 'utf-8');
|
|
6
|
+
const filename = basename(filePath);
|
|
7
|
+
const parsed = parseFile(content, filename);
|
|
8
|
+
const csvContent = toCsvContent(parsed.entries);
|
|
9
|
+
const csvBuffer = new TextEncoder().encode(csvContent);
|
|
10
|
+
const result = await client.translateAsync(csvBuffer, filename.replace(/\.[^.]+$/, '.csv'), {
|
|
11
|
+
targetLanguages,
|
|
12
|
+
sourceLanguage: sourceLanguage || parsed.sourceLanguage,
|
|
13
|
+
model,
|
|
14
|
+
gameContext,
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
orderId: result.orderId,
|
|
18
|
+
message: 'Translation started. Use questlang_get_order_status to check progress.',
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=translate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.js","sourceRoot":"","sources":["../../src/tools/translate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAO9D,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAuB,EACvB,QAAgB,EAChB,eAAyB,EACzB,cAAuB,EACvB,KAAc,EACd,WAAyB;IAEzB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAEvD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE;QAC1F,eAAe;QACf,cAAc,EAAE,cAAc,IAAI,MAAM,CAAC,cAAc;QACvD,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,wEAAwE;KAClF,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface ParsedEntry {
|
|
2
|
+
key: string;
|
|
3
|
+
value: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ParseResult {
|
|
6
|
+
entries: ParsedEntry[];
|
|
7
|
+
format: string;
|
|
8
|
+
sourceLanguage?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface QuestlangConfig {
|
|
11
|
+
apiKey: string;
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
}
|
|
14
|
+
export interface GameContext {
|
|
15
|
+
worldName?: string;
|
|
16
|
+
genre?: string;
|
|
17
|
+
setting?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface TranslateOptions {
|
|
20
|
+
targetLanguages: string[];
|
|
21
|
+
sourceLanguage?: string;
|
|
22
|
+
model?: string;
|
|
23
|
+
gameContext?: GameContext;
|
|
24
|
+
}
|
|
25
|
+
export interface OrderSummary {
|
|
26
|
+
orderId: string;
|
|
27
|
+
status: string;
|
|
28
|
+
progress: number;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
modelName: string;
|
|
31
|
+
}
|
|
32
|
+
export interface GlossaryEntry {
|
|
33
|
+
term: string;
|
|
34
|
+
translations: Record<string, string>;
|
|
35
|
+
type?: string;
|
|
36
|
+
context?: string;
|
|
37
|
+
inflections?: string[];
|
|
38
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@questlang/mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for AI-powered i18n file translation. Translates JSON, CSV, Android XML, iOS .strings, PO, and XLIFF into 20 languages.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://questlang.ru/skill",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/questlang/mcp-server"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"mcp",
|
|
14
|
+
"mcp-server",
|
|
15
|
+
"translation",
|
|
16
|
+
"i18n",
|
|
17
|
+
"localization",
|
|
18
|
+
"l10n",
|
|
19
|
+
"game-translation",
|
|
20
|
+
"claude-code",
|
|
21
|
+
"cursor",
|
|
22
|
+
"vscode",
|
|
23
|
+
"json",
|
|
24
|
+
"csv",
|
|
25
|
+
"android-xml",
|
|
26
|
+
"ios-strings",
|
|
27
|
+
"po",
|
|
28
|
+
"xliff"
|
|
29
|
+
],
|
|
30
|
+
"bin": { "questlang-mcp": "dist/index.js" },
|
|
31
|
+
"files": ["dist", "SKILL.md", "README.md", "LICENSE"],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"start": "node dist/index.js",
|
|
35
|
+
"dev": "tsx src/index.ts",
|
|
36
|
+
"test": "NODE_OPTIONS='--experimental-vm-modules' jest",
|
|
37
|
+
"prepublishOnly": "npm run build"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@modelcontextprotocol/sdk": "^1.0",
|
|
41
|
+
"zod": "^3.22"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/jest": "^29.5.14",
|
|
45
|
+
"@types/node": "^20.11.0",
|
|
46
|
+
"jest": "^29.7.0",
|
|
47
|
+
"ts-jest": "^29.4.6",
|
|
48
|
+
"tsx": "^4.19.2",
|
|
49
|
+
"typescript": "^5.3.3"
|
|
50
|
+
},
|
|
51
|
+
"engines": { "node": ">=18.0.0" }
|
|
52
|
+
}
|