@syntholoc/mcp 0.1.0 → 0.1.1

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.
@@ -1,156 +0,0 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { z } from 'zod';
3
- import {
4
- APPROVE_TRANSLATION,
5
- EXPORT_LOCALE,
6
- IMPORT_TRANSLATIONS,
7
- LIST_TRANSLATIONS,
8
- REJECT_TRANSLATION,
9
- SET_TRANSLATION,
10
- TRANSLATE_KEY,
11
- TRANSLATE_LOCALE,
12
- type GraphQLClient,
13
- } from '@syntholoc/sdk';
14
- import { jsonResult } from '../util';
15
-
16
- const FORMATS = ['JSON', 'YAML', 'CSV', 'PO', 'XLIFF', 'ANDROID_XML', 'IOS_STRINGS'] as const;
17
-
18
- export function registerTranslationTools(server: McpServer, gql: GraphQLClient): void {
19
- server.registerTool(
20
- 'translate_locale',
21
- {
22
- title: 'Translate locale',
23
- description:
24
- 'Queues AI translation of a locale (scope ALL | UNAPPROVED | UNTRANSLATED) and returns the ' +
25
- 'tracking `jobIds`. Executes immediately and unconditionally — the batch threshold is a ' +
26
- 'client-side policy for PROACTIVE syncs, not for this tool.',
27
- inputSchema: {
28
- projectId: z.string(),
29
- localeId: z.string(),
30
- scope: z.enum(['ALL', 'UNAPPROVED', 'UNTRANSLATED']).default('UNTRANSLATED'),
31
- },
32
- annotations: { openWorldHint: true },
33
- },
34
- async (vars) => jsonResult((await gql.request(TRANSLATE_LOCALE, vars)).translateLocale),
35
- );
36
-
37
- server.registerTool(
38
- 'translate_key',
39
- {
40
- title: 'Translate key',
41
- description: 'Queues AI translation of a single key into a locale. Returns tracking `jobIds`.',
42
- inputSchema: { projectId: z.string(), keyId: z.string(), localeId: z.string() },
43
- annotations: { openWorldHint: true },
44
- },
45
- async (vars) => jsonResult((await gql.request(TRANSLATE_KEY, vars)).translateKey),
46
- );
47
-
48
- server.registerTool(
49
- 'set_translation',
50
- {
51
- title: 'Set translation',
52
- description: 'Manually sets the translation text for a key in a locale.',
53
- inputSchema: {
54
- projectId: z.string(),
55
- keyId: z.string(),
56
- localeId: z.string(),
57
- text: z.string(),
58
- origin: z.string().optional(),
59
- },
60
- annotations: { idempotentHint: true, openWorldHint: true },
61
- },
62
- async ({ projectId, keyId, localeId, text, origin }) =>
63
- jsonResult(
64
- (await gql.request(SET_TRANSLATION, { projectId, input: { keyId, localeId, text, origin } }))
65
- .setTranslation,
66
- ),
67
- );
68
-
69
- server.registerTool(
70
- 'list_translations',
71
- {
72
- title: 'List translations',
73
- description: 'Lists translations for a locale with status, origin, model and QA score.',
74
- inputSchema: {
75
- projectId: z.string(),
76
- localeId: z.string(),
77
- skip: z.number().int().min(0).default(0),
78
- take: z.number().int().min(1).max(200).default(25),
79
- },
80
- annotations: { readOnlyHint: true, openWorldHint: true },
81
- },
82
- async (vars) => jsonResult((await gql.request(LIST_TRANSLATIONS, vars)).translations),
83
- );
84
-
85
- server.registerTool(
86
- 'approve_translation',
87
- {
88
- title: 'Approve translation',
89
- description: 'Marks a translation APPROVED.',
90
- inputSchema: { projectId: z.string(), translationId: z.string() },
91
- annotations: { idempotentHint: true, openWorldHint: true },
92
- },
93
- async ({ projectId, translationId }) =>
94
- jsonResult((await gql.request(APPROVE_TRANSLATION, { projectId, id: translationId })).approveTranslation),
95
- );
96
-
97
- server.registerTool(
98
- 'reject_translation',
99
- {
100
- title: 'Reject translation',
101
- description: 'Marks a translation REJECTED (queued for re-translation).',
102
- inputSchema: { projectId: z.string(), translationId: z.string() },
103
- annotations: { idempotentHint: true, openWorldHint: true },
104
- },
105
- async ({ projectId, translationId }) =>
106
- jsonResult((await gql.request(REJECT_TRANSLATION, { projectId, id: translationId })).rejectTranslation),
107
- );
108
-
109
- server.registerTool(
110
- 'export_locale',
111
- {
112
- title: 'Export locale',
113
- description:
114
- 'Exports a locale to a file string in the chosen format — the basis for writing translations ' +
115
- 'back into local files. Set `onlyApproved` to exclude drafts.',
116
- inputSchema: {
117
- projectId: z.string(),
118
- localeId: z.string(),
119
- format: z.enum(FORMATS).default('JSON'),
120
- onlyApproved: z.boolean().optional(),
121
- },
122
- annotations: { readOnlyHint: true, openWorldHint: true },
123
- },
124
- async (vars) => jsonResult({ content: (await gql.request(EXPORT_LOCALE, vars)).exportLocale }),
125
- );
126
-
127
- server.registerTool(
128
- 'import_translations',
129
- {
130
- title: 'Import translations',
131
- description:
132
- 'Imports ready-made translations for a locale (paste file content). `autoApprove` lands them ' +
133
- 'as APPROVED; `conflict` is OVERWRITE | SKIP_EXISTING | KEEP_APPROVED; `dryRun` previews.',
134
- inputSchema: {
135
- projectId: z.string(),
136
- localeId: z.string(),
137
- content: z.string(),
138
- format: z.enum(FORMATS),
139
- autoApprove: z.boolean().default(false),
140
- conflict: z.enum(['OVERWRITE', 'SKIP_EXISTING', 'KEEP_APPROVED']).default('OVERWRITE'),
141
- dryRun: z.boolean().default(false),
142
- },
143
- annotations: { idempotentHint: true, openWorldHint: true },
144
- },
145
- async ({ projectId, localeId, content, format, autoApprove, conflict, dryRun }) =>
146
- jsonResult(
147
- (
148
- await gql.request(IMPORT_TRANSLATIONS, {
149
- projectId,
150
- localeId,
151
- input: { content, format, autoApprove, conflict, dryRun },
152
- })
153
- ).importTranslations,
154
- ),
155
- );
156
- }
package/src/util.ts DELETED
@@ -1,9 +0,0 @@
1
- /** Shared helpers for MCP tool handlers. */
2
-
3
- export const sleep = (ms: number): Promise<void> =>
4
- new Promise<void>((resolve) => setTimeout(resolve, ms));
5
-
6
- /** Wraps a value as an MCP text result (pretty-printed JSON). */
7
- export function jsonResult(data: unknown): { content: { type: 'text'; text: string }[] } {
8
- return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
9
- }