@better-i18n/mcp 0.0.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.
Files changed (46) hide show
  1. package/README.md +105 -0
  2. package/dist/base-tool.d.ts +43 -0
  3. package/dist/base-tool.d.ts.map +1 -0
  4. package/dist/base-tool.js +67 -0
  5. package/dist/base-tool.js.map +1 -0
  6. package/dist/client.d.ts +18 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +71 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/helpers.d.ts +30 -0
  11. package/dist/helpers.d.ts.map +1 -0
  12. package/dist/helpers.js +32 -0
  13. package/dist/helpers.js.map +1 -0
  14. package/dist/index.d.ts +10 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +121 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/tools/bulkCreateKeys.d.ts +8 -0
  19. package/dist/tools/bulkCreateKeys.d.ts.map +1 -0
  20. package/dist/tools/bulkCreateKeys.js +74 -0
  21. package/dist/tools/bulkCreateKeys.js.map +1 -0
  22. package/dist/tools/bulkUpdateTranslations.d.ts +8 -0
  23. package/dist/tools/bulkUpdateTranslations.d.ts.map +1 -0
  24. package/dist/tools/bulkUpdateTranslations.js +68 -0
  25. package/dist/tools/bulkUpdateTranslations.js.map +1 -0
  26. package/dist/tools/createTranslationKey.d.ts +8 -0
  27. package/dist/tools/createTranslationKey.d.ts.map +1 -0
  28. package/dist/tools/createTranslationKey.js +55 -0
  29. package/dist/tools/createTranslationKey.js.map +1 -0
  30. package/dist/tools/getProjectInfo.d.ts +8 -0
  31. package/dist/tools/getProjectInfo.d.ts.map +1 -0
  32. package/dist/tools/getProjectInfo.js +28 -0
  33. package/dist/tools/getProjectInfo.js.map +1 -0
  34. package/dist/tools/listKeys.d.ts +8 -0
  35. package/dist/tools/listKeys.d.ts.map +1 -0
  36. package/dist/tools/listKeys.js +43 -0
  37. package/dist/tools/listKeys.js.map +1 -0
  38. package/dist/tools/updateTranslation.d.ts +8 -0
  39. package/dist/tools/updateTranslation.d.ts.map +1 -0
  40. package/dist/tools/updateTranslation.js +61 -0
  41. package/dist/tools/updateTranslation.js.map +1 -0
  42. package/dist/types/index.d.ts +37 -0
  43. package/dist/types/index.d.ts.map +1 -0
  44. package/dist/types/index.js +5 -0
  45. package/dist/types/index.js.map +1 -0
  46. package/package.json +61 -0
package/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # @better-i18n/mcp
2
+
3
+ MCP (Model Context Protocol) server for [Better i18n](https://better-i18n.com). Enables AI assistants like Claude and GPT to manage translations directly from your IDE.
4
+
5
+ ## Features
6
+
7
+ - 🤖 **AI-Powered Translation** - Let AI handle your i18n workflow
8
+ - ⚡ **Instant Startup** - No filesystem scanning, starts immediately
9
+ - 📝 **Create & Update Keys** - Add new keys with source text and translations
10
+ - 🔄 **Bulk Operations** - Create/update multiple keys at once
11
+ - 🔍 **Smart Filtering** - Find keys by name, namespace, or search
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ # With npx (no install needed)
17
+ npx @better-i18n/mcp
18
+
19
+ # Or install globally
20
+ npm install -g @better-i18n/mcp
21
+ ```
22
+
23
+ ## Setup
24
+
25
+ ### 1. Get Your API Key
26
+
27
+ 1. Go to [dash.better-i18n.com](https://dash.better-i18n.com)
28
+ 2. Navigate to Settings → API Keys
29
+ 3. Create and copy your API key
30
+
31
+ ### 2. Add i18n config to your project
32
+
33
+ ```ts
34
+ // i18n.ts
35
+ import { createI18n } from "@better-i18n/next";
36
+
37
+ export const i18n = createI18n({
38
+ project: "your-org/your-project", // Format: "org-slug/project-slug"
39
+ defaultLocale: "en",
40
+ });
41
+ ```
42
+
43
+ The AI assistant will read this file to get the `project` value and include it in all tool calls.
44
+
45
+ ### 3. Configure Cursor
46
+
47
+ Add to `~/.cursor/mcp.json`:
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "better-i18n": {
53
+ "command": "npx",
54
+ "args": ["@better-i18n/mcp"],
55
+ "env": {
56
+ "BETTER_I18N_API_KEY": "your-api-key-here"
57
+ }
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ## Available Tools
64
+
65
+ All tools require a `project` parameter in `org/project` format (e.g., `aliosman-co/personal`).
66
+
67
+ | Tool | Description |
68
+ |------|-------------|
69
+ | `getProjectInfo` | Get project overview: namespaces, languages, key count |
70
+ | `listKeys` | List all translation keys with filtering |
71
+ | `createTranslationKey` | Create a single key with source text |
72
+ | `bulkCreateKeys` | Create multiple keys at once (more efficient) |
73
+ | `updateTranslation` | Update a single translation |
74
+ | `bulkUpdateTranslations` | Update multiple translations at once (more efficient) |
75
+
76
+ ## Example Prompts
77
+
78
+ Ask your AI assistant:
79
+
80
+ > "List all my translation keys"
81
+
82
+ > "Add Turkish translations for all keys missing Turkish"
83
+
84
+ > "Create a new key nav.home with text 'Home' and translate to German and Turkish"
85
+
86
+ > "Show me translation coverage stats"
87
+
88
+ ## How It Works
89
+
90
+ 1. AI reads `project` value from your `i18n.ts` config
91
+ 2. AI uses tools with `project` parameter for each request
92
+ 3. Changes sync to Better i18n dashboard via API
93
+ 4. CDN serves updated translations to your app
94
+
95
+ ## Environment Variables
96
+
97
+ | Variable | Required | Description |
98
+ |----------|----------|-------------|
99
+ | `BETTER_I18N_API_KEY` | Yes | Your API key |
100
+ | `BETTER_I18N_API_URL` | No | API URL (default: dash.better-i18n.com) |
101
+ | `BETTER_I18N_DEBUG` | No | Enable verbose logging |
102
+
103
+ ## License
104
+
105
+ MIT © [Better i18n](https://better-i18n.com)
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Base Tool Utilities
3
+ *
4
+ * Common patterns and helpers for MCP tools.
5
+ * All tools work with project-scoped operations.
6
+ */
7
+ import { z } from "zod";
8
+ import { type ParsedProject } from "./helpers.js";
9
+ import type { ToolResult } from "./types/index.js";
10
+ /**
11
+ * Common project schema - all tools require this
12
+ */
13
+ export declare const projectSchema: z.ZodObject<{
14
+ project: z.ZodString;
15
+ }, "strip", z.ZodTypeAny, {
16
+ project: string;
17
+ }, {
18
+ project: string;
19
+ }>;
20
+ /**
21
+ * Project field definition for tool inputSchema
22
+ */
23
+ export declare const projectInputProperty: {
24
+ project: {
25
+ type: "string";
26
+ description: string;
27
+ };
28
+ };
29
+ /**
30
+ * Creates a successful tool result
31
+ */
32
+ export declare function success(data: Record<string, unknown>): ToolResult;
33
+ /**
34
+ * Creates an error tool result
35
+ */
36
+ export declare function error(message: string): ToolResult;
37
+ /**
38
+ * Wraps tool execution with common error handling
39
+ */
40
+ export declare function executeTool<T extends {
41
+ project: string;
42
+ }>(args: unknown, schema: z.ZodType<T>, handler: (input: T, parsed: ParsedProject) => Promise<ToolResult>): Promise<ToolResult>;
43
+ //# sourceMappingURL=base-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-tool.d.ts","sourceRoot":"","sources":["../src/base-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;EAExB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;CAMhC,CAAC;AAEF;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CASjE;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAUjD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EAC7D,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,UAAU,CAAC,GAChE,OAAO,CAAC,UAAU,CAAC,CAWrB"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Base Tool Utilities
3
+ *
4
+ * Common patterns and helpers for MCP tools.
5
+ * All tools work with project-scoped operations.
6
+ */
7
+ import { z } from "zod";
8
+ import { parseProject } from "./helpers.js";
9
+ /**
10
+ * Common project schema - all tools require this
11
+ */
12
+ export const projectSchema = z.object({
13
+ project: z.string().min(1),
14
+ });
15
+ /**
16
+ * Project field definition for tool inputSchema
17
+ */
18
+ export const projectInputProperty = {
19
+ project: {
20
+ type: "string",
21
+ description: "Project identifier in 'org/project' format (e.g., 'aliosman-co/personal'). Get this from the project's i18n.ts config file.",
22
+ },
23
+ };
24
+ /**
25
+ * Creates a successful tool result
26
+ */
27
+ export function success(data) {
28
+ return {
29
+ content: [
30
+ {
31
+ type: "text",
32
+ text: JSON.stringify(data, null, 2),
33
+ },
34
+ ],
35
+ };
36
+ }
37
+ /**
38
+ * Creates an error tool result
39
+ */
40
+ export function error(message) {
41
+ return {
42
+ content: [
43
+ {
44
+ type: "text",
45
+ text: message,
46
+ },
47
+ ],
48
+ isError: true,
49
+ };
50
+ }
51
+ /**
52
+ * Wraps tool execution with common error handling
53
+ */
54
+ export async function executeTool(args, schema, handler) {
55
+ try {
56
+ const input = schema.parse(args);
57
+ const parsed = parseProject(input.project);
58
+ return await handler(input, parsed);
59
+ }
60
+ catch (err) {
61
+ if (err instanceof z.ZodError) {
62
+ return error(`Validation error: ${err.errors.map(e => e.message).join(", ")}`);
63
+ }
64
+ return error(err instanceof Error ? err.message : String(err));
65
+ }
66
+ }
67
+ //# sourceMappingURL=base-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-tool.js","sourceRoot":"","sources":["../src/base-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAsB,MAAM,cAAc,CAAC;AAGhE;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3B,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,OAAO,EAAE;QACP,IAAI,EAAE,QAAiB;QACvB,WAAW,EACT,6HAA6H;KAChI;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,IAA6B;IACnD,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;aACpC;SACF;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,OAAe;IACnC,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,OAAO;aACd;SACF;QACD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAa,EACb,MAAoB,EACpB,OAAiE;IAEjE,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,OAAO,MAAM,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC,qBAAqB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,OAAO,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,CAAC;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * tRPC client for Better i18n API with API key authentication
3
+ */
4
+ export interface ClientConfig {
5
+ apiUrl: string;
6
+ apiKey: string;
7
+ debug?: boolean;
8
+ }
9
+ /**
10
+ * Create a tRPC client authenticated with API key
11
+ *
12
+ * @param config - API URL, API key, and optional organization ID
13
+ * @returns Configured tRPC client
14
+ */
15
+ export declare function createBetterI18nClient(config: ClientConfig & {
16
+ organizationId?: string;
17
+ }): import("@trpc/client").TRPCClient<any>;
18
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,0CAgExF"}
package/dist/client.js ADDED
@@ -0,0 +1,71 @@
1
+ /**
2
+ * tRPC client for Better i18n API with API key authentication
3
+ */
4
+ import { createTRPCClient, httpBatchLink } from "@trpc/client";
5
+ /**
6
+ * Create a tRPC client authenticated with API key
7
+ *
8
+ * @param config - API URL, API key, and optional organization ID
9
+ * @returns Configured tRPC client
10
+ */
11
+ export function createBetterI18nClient(config) {
12
+ // Ensure URL ends with /api/trpc for tRPC endpoint
13
+ const url = config.apiUrl.endsWith("/api/trpc")
14
+ ? config.apiUrl
15
+ : `${config.apiUrl.replace(/\/$/, "")}/api/trpc`;
16
+ if (config.debug) {
17
+ console.error(`[better-i18n] tRPC endpoint: ${url}`);
18
+ }
19
+ // Track logged requests to avoid duplicate logs (tRPC batching can call headers multiple times)
20
+ let lastLoggedUrl = "";
21
+ return createTRPCClient({
22
+ links: [
23
+ httpBatchLink({
24
+ url,
25
+ headers: () => {
26
+ const headers = {
27
+ "x-api-key": config.apiKey,
28
+ };
29
+ if (config.organizationId) {
30
+ headers["x-organization-id"] = config.organizationId;
31
+ }
32
+ return headers;
33
+ },
34
+ fetch: async (input, init) => {
35
+ const inputUrl = String(input);
36
+ // Only log if this is a different request (avoid duplicate logs from tRPC batching)
37
+ if (config.debug && inputUrl !== lastLoggedUrl) {
38
+ lastLoggedUrl = inputUrl;
39
+ // Parse the URL to show a cleaner log
40
+ try {
41
+ const parsedUrl = new URL(inputUrl);
42
+ const procedure = parsedUrl.pathname.split("/").pop();
43
+ console.error(`[better-i18n] → ${procedure}`);
44
+ }
45
+ catch {
46
+ console.error(`[better-i18n] → ${inputUrl}`);
47
+ }
48
+ }
49
+ const response = await fetch(input, init);
50
+ if (config.debug && inputUrl === lastLoggedUrl) {
51
+ if (response.ok) {
52
+ console.error(`[better-i18n] ← ${response.status} OK`);
53
+ }
54
+ else {
55
+ const clonedResponse = response.clone();
56
+ try {
57
+ const text = await clonedResponse.text();
58
+ console.error(`[better-i18n] ← ${response.status} ERROR: ${text.substring(0, 200)}`);
59
+ }
60
+ catch {
61
+ console.error(`[better-i18n] ← ${response.status} ERROR`);
62
+ }
63
+ }
64
+ }
65
+ return response;
66
+ },
67
+ }),
68
+ ],
69
+ });
70
+ }
71
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAY/D;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAkD;IACvF,mDAAmD;IACnD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC7C,CAAC,CAAC,MAAM,CAAC,MAAM;QACf,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC;IAEnD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,gGAAgG;IAChG,IAAI,aAAa,GAAG,EAAE,CAAC;IAEvB,OAAO,gBAAgB,CAAY;QACjC,KAAK,EAAE;YACL,aAAa,CAAC;gBACZ,GAAG;gBACH,OAAO,EAAE,GAAG,EAAE;oBACZ,MAAM,OAAO,GAA2B;wBACtC,WAAW,EAAE,MAAM,CAAC,MAAM;qBAC3B,CAAC;oBACF,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;wBAC1B,OAAO,CAAC,mBAAmB,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC;oBACvD,CAAC;oBACD,OAAO,OAAO,CAAC;gBACjB,CAAC;gBACD,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;oBAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;oBAE/B,oFAAoF;oBACpF,IAAI,MAAM,CAAC,KAAK,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;wBAC/C,aAAa,GAAG,QAAQ,CAAC;wBAEzB,sCAAsC;wBACtC,IAAI,CAAC;4BACH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;4BACpC,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;4BACtD,OAAO,CAAC,KAAK,CAAC,mBAAmB,SAAS,EAAE,CAAC,CAAC;wBAChD,CAAC;wBAAC,MAAM,CAAC;4BACP,OAAO,CAAC,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;wBAC/C,CAAC;oBACH,CAAC;oBAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;oBAE1C,IAAI,MAAM,CAAC,KAAK,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;wBAC/C,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;4BAChB,OAAO,CAAC,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;wBACzD,CAAC;6BAAM,CAAC;4BACN,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;4BACxC,IAAI,CAAC;gCACH,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC;gCACzC,OAAO,CAAC,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,WAAW,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;4BACvF,CAAC;4BAAC,MAAM,CAAC;gCACP,OAAO,CAAC,KAAK,CAAC,mBAAmB,QAAQ,CAAC,MAAM,QAAQ,CAAC,CAAC;4BAC5D,CAAC;wBACH,CAAC;oBACH,CAAC;oBAED,OAAO,QAAQ,CAAC;gBAClB,CAAC;aACF,CAAC;SACH;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * MCP Server Helpers
3
+ *
4
+ * Shared utility functions for MCP tools.
5
+ * Uses the same project format as @better-i18n/next package.
6
+ */
7
+ /**
8
+ * Parsed project identifier - same structure as @better-i18n/next
9
+ */
10
+ export interface ParsedProject {
11
+ workspaceId: string;
12
+ projectSlug: string;
13
+ }
14
+ /**
15
+ * Parse project string "org/slug" into workspaceId and projectSlug.
16
+ * Same format used in @better-i18n/next package's i18n.ts config.
17
+ *
18
+ * @param project - Project identifier (e.g., "aliosman-co/personal")
19
+ * @returns Parsed project with workspaceId and projectSlug
20
+ * @throws Error if format is invalid
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const { workspaceId, projectSlug } = parseProject("aliosman-co/personal");
25
+ * // workspaceId: "aliosman-co"
26
+ * // projectSlug: "personal"
27
+ * ```
28
+ */
29
+ export declare function parseProject(project: string): ParsedProject;
30
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAW3D"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * MCP Server Helpers
3
+ *
4
+ * Shared utility functions for MCP tools.
5
+ * Uses the same project format as @better-i18n/next package.
6
+ */
7
+ /**
8
+ * Parse project string "org/slug" into workspaceId and projectSlug.
9
+ * Same format used in @better-i18n/next package's i18n.ts config.
10
+ *
11
+ * @param project - Project identifier (e.g., "aliosman-co/personal")
12
+ * @returns Parsed project with workspaceId and projectSlug
13
+ * @throws Error if format is invalid
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const { workspaceId, projectSlug } = parseProject("aliosman-co/personal");
18
+ * // workspaceId: "aliosman-co"
19
+ * // projectSlug: "personal"
20
+ * ```
21
+ */
22
+ export function parseProject(project) {
23
+ const parts = project.split("/");
24
+ if (parts.length !== 2 || !parts[0] || !parts[1]) {
25
+ throw new Error(`Invalid project format "${project}". Expected "org/project" (e.g., "aliosman-co/personal")`);
26
+ }
27
+ return {
28
+ workspaceId: parts[0],
29
+ projectSlug: parts[1],
30
+ };
31
+ }
32
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CACb,2BAA2B,OAAO,0DAA0D,CAC7F,CAAC;IACJ,CAAC;IACD,OAAO;QACL,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;QACrB,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;KACtB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Better i18n MCP Server
4
+ *
5
+ * Model Context Protocol server for Better i18n translation management.
6
+ * Enables AI assistants (Claude, ChatGPT, etc.) to manage translations
7
+ * directly from IDEs like Cursor.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG"}
package/dist/index.js ADDED
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Better i18n MCP Server
4
+ *
5
+ * Model Context Protocol server for Better i18n translation management.
6
+ * Enables AI assistants (Claude, ChatGPT, etc.) to manage translations
7
+ * directly from IDEs like Cursor.
8
+ */
9
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
10
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
11
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
12
+ import { createBetterI18nClient } from "./client.js";
13
+ import { bulkCreateKeys } from "./tools/bulkCreateKeys.js";
14
+ import { bulkUpdateTranslations } from "./tools/bulkUpdateTranslations.js";
15
+ import { createTranslationKey } from "./tools/createTranslationKey.js";
16
+ import { getProjectInfo } from "./tools/getProjectInfo.js";
17
+ import { listKeys } from "./tools/listKeys.js";
18
+ import { updateTranslation } from "./tools/updateTranslation.js";
19
+ class BetterI18nServer {
20
+ server;
21
+ apiClient;
22
+ constructor() {
23
+ this.server = new Server({
24
+ name: "better-i18n",
25
+ version: "0.0.1",
26
+ }, {
27
+ capabilities: {
28
+ tools: {},
29
+ },
30
+ });
31
+ this.apiClient = null;
32
+ }
33
+ async init() {
34
+ // Auto-detect if running from source (local dev) vs npm package (production)
35
+ const scriptPath = process.argv[1] || "";
36
+ const isLocalDev = scriptPath.includes("packages/mcp/src") ||
37
+ scriptPath.includes("better-i18n/packages/mcp");
38
+ // Read configuration from environment
39
+ const apiUrl = process.env.BETTER_I18N_API_URL ||
40
+ (isLocalDev ? "http://localhost:8787" : "https://dash.better-i18n.com");
41
+ const apiKey = process.env.BETTER_I18N_API_KEY;
42
+ const debug = process.env.BETTER_I18N_DEBUG === "true" || isLocalDev;
43
+ console.error(`[better-i18n] Mode: ${isLocalDev ? "LOCAL DEV" : "PRODUCTION"}`);
44
+ console.error(`[better-i18n] API URL: ${apiUrl}`);
45
+ if (!apiKey) {
46
+ console.error("[better-i18n] ERROR: BETTER_I18N_API_KEY environment variable is required");
47
+ console.error("[better-i18n] Get your API key from: https://dash.better-i18n.com/settings/api-keys");
48
+ process.exit(1);
49
+ }
50
+ // Create Better i18n API client
51
+ this.apiClient = createBetterI18nClient({ apiUrl, apiKey, debug });
52
+ this.setupHandlers();
53
+ console.error("[better-i18n] MCP Server ready");
54
+ }
55
+ setupHandlers() {
56
+ // List available tools
57
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
58
+ tools: [
59
+ getProjectInfo.definition,
60
+ listKeys.definition,
61
+ createTranslationKey.definition,
62
+ bulkCreateKeys.definition,
63
+ updateTranslation.definition,
64
+ bulkUpdateTranslations.definition,
65
+ ],
66
+ }));
67
+ // Execute tools
68
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
69
+ const { name, arguments: args } = request.params;
70
+ try {
71
+ let result;
72
+ switch (name) {
73
+ case "getProjectInfo":
74
+ result = await getProjectInfo.execute(this.apiClient, args);
75
+ break;
76
+ case "createTranslationKey":
77
+ result = await createTranslationKey.execute(this.apiClient, args);
78
+ break;
79
+ case "updateTranslation":
80
+ result = await updateTranslation.execute(this.apiClient, args);
81
+ break;
82
+ case "listKeys":
83
+ result = await listKeys.execute(this.apiClient, args);
84
+ break;
85
+ case "bulkCreateKeys":
86
+ result = await bulkCreateKeys.execute(this.apiClient, args);
87
+ break;
88
+ case "bulkUpdateTranslations":
89
+ result = await bulkUpdateTranslations.execute(this.apiClient, args);
90
+ break;
91
+ default:
92
+ throw new Error(`Unknown tool: ${name}`);
93
+ }
94
+ return result;
95
+ }
96
+ catch (error) {
97
+ return {
98
+ content: [
99
+ {
100
+ type: "text",
101
+ text: `Error executing ${name}: ${error instanceof Error ? error.message : String(error)}`,
102
+ },
103
+ ],
104
+ isError: true,
105
+ };
106
+ }
107
+ });
108
+ }
109
+ async run() {
110
+ const transport = new StdioServerTransport();
111
+ await this.server.connect(transport);
112
+ console.error("[better-i18n] MCP Server running on stdio");
113
+ }
114
+ }
115
+ // Start the server
116
+ const server = new BetterI18nServer();
117
+ server.init().then(() => server.run()).catch((error) => {
118
+ console.error("[better-i18n] Fatal error:", error);
119
+ process.exit(1);
120
+ });
121
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * bulkCreateKeys MCP Tool
3
+ *
4
+ * Creates multiple translation keys with all translations in a single request.
5
+ */
6
+ import type { Tool } from "../types/index.js";
7
+ export declare const bulkCreateKeys: Tool;
8
+ //# sourceMappingURL=bulkCreateKeys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulkCreateKeys.d.ts","sourceRoot":"","sources":["../../src/tools/bulkCreateKeys.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAa9C,eAAO,MAAM,cAAc,EAAE,IA8D5B,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * bulkCreateKeys MCP Tool
3
+ *
4
+ * Creates multiple translation keys with all translations in a single request.
5
+ */
6
+ import { z } from "zod";
7
+ import { executeTool, projectInputProperty, projectSchema, success, } from "../base-tool.js";
8
+ const inputSchema = projectSchema.extend({
9
+ keys: z.array(z.object({
10
+ key: z.string(),
11
+ namespace: z.string().optional(),
12
+ sourceText: z.string(),
13
+ translations: z.record(z.string(), z.string()).optional(),
14
+ })),
15
+ });
16
+ export const bulkCreateKeys = {
17
+ definition: {
18
+ name: "bulkCreateKeys",
19
+ description: "Create multiple translation keys in a SINGLE efficient request. ALWAYS use this instead of calling createTranslationKey multiple times when adding 2 or more keys.",
20
+ inputSchema: {
21
+ type: "object",
22
+ properties: {
23
+ ...projectInputProperty,
24
+ keys: {
25
+ type: "array",
26
+ description: "Array of translation keys to create",
27
+ items: {
28
+ type: "object",
29
+ properties: {
30
+ key: {
31
+ type: "string",
32
+ description: "Translation key WITHOUT namespace prefix when namespace is provided.",
33
+ },
34
+ namespace: {
35
+ type: "string",
36
+ description: "Namespace for the key. Defaults to 'default'.",
37
+ },
38
+ sourceText: {
39
+ type: "string",
40
+ description: "English source text",
41
+ },
42
+ translations: {
43
+ type: "object",
44
+ description: "Translations for other languages. Keys are language codes, values are translated text.",
45
+ },
46
+ },
47
+ required: ["key", "sourceText"],
48
+ },
49
+ },
50
+ },
51
+ required: ["project", "keys"],
52
+ },
53
+ },
54
+ execute: (client, args) => executeTool(args, inputSchema, async (input, { workspaceId, projectSlug }) => {
55
+ const formattedKeys = input.keys.map((k) => ({
56
+ key: k.key,
57
+ namespace: k.namespace || "default",
58
+ sourceText: k.sourceText,
59
+ translations: k.translations,
60
+ }));
61
+ const result = await client.mcp.bulkCreateKeys.mutate({
62
+ orgSlug: workspaceId,
63
+ projectSlug,
64
+ keys: formattedKeys,
65
+ });
66
+ return success({
67
+ success: true,
68
+ project: input.project,
69
+ keysCreated: result.keysCreated,
70
+ keys: result.keys,
71
+ });
72
+ }),
73
+ };
74
+ //# sourceMappingURL=bulkCreateKeys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulkCreateKeys.js","sourceRoot":"","sources":["../../src/tools/bulkCreateKeys.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,OAAO,GACR,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,KAAK,CACX,CAAC,CAAC,MAAM,CAAC;QACP,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;QACf,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAChC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;QACtB,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;KAC1D,CAAC,CACH;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAS;IAClC,UAAU,EAAE;QACV,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,oKAAoK;QACtK,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,oBAAoB;gBACvB,IAAI,EAAE;oBACJ,IAAI,EAAE,OAAO;oBACb,WAAW,EAAE,qCAAqC;oBAClD,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,GAAG,EAAE;gCACH,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,sEAAsE;6BACpF;4BACD,SAAS,EAAE;gCACT,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,+CAA+C;6BAC7D;4BACD,UAAU,EAAE;gCACV,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,qBAAqB;6BACnC;4BACD,YAAY,EAAE;gCACZ,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,wFAAwF;6BACtG;yBACF;wBACD,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC;qBAChC;iBACF;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;SAC9B;KACF;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CACxB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QAC3E,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3C,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,SAAS;YACnC,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,YAAY,EAAE,CAAC,CAAC,YAAY;SAC7B,CAAC,CAAC,CAAC;QAEJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC;YACpD,OAAO,EAAE,WAAW;YACpB,WAAW;YACX,IAAI,EAAE,aAAa;SACpB,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;YACb,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB,CAAC,CAAC;IACL,CAAC,CAAC;CACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * bulkUpdateTranslations MCP Tool
3
+ *
4
+ * Updates translations for multiple keys in a single request.
5
+ */
6
+ import type { Tool } from "../types/index.js";
7
+ export declare const bulkUpdateTranslations: Tool;
8
+ //# sourceMappingURL=bulkUpdateTranslations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulkUpdateTranslations.d.ts","sourceRoot":"","sources":["../../src/tools/bulkUpdateTranslations.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAY9C,eAAO,MAAM,sBAAsB,EAAE,IAyDpC,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * bulkUpdateTranslations MCP Tool
3
+ *
4
+ * Updates translations for multiple keys in a single request.
5
+ */
6
+ import { z } from "zod";
7
+ import { executeTool, projectInputProperty, projectSchema, success, } from "../base-tool.js";
8
+ const inputSchema = projectSchema.extend({
9
+ updates: z.array(z.object({
10
+ key: z.string(),
11
+ namespace: z.string().optional(),
12
+ translations: z.record(z.string(), z.string()),
13
+ })),
14
+ });
15
+ export const bulkUpdateTranslations = {
16
+ definition: {
17
+ name: "bulkUpdateTranslations",
18
+ description: "Update translations for multiple keys in a SINGLE efficient request. ALWAYS use this instead of calling updateTranslation multiple times when updating 2 or more translations.",
19
+ inputSchema: {
20
+ type: "object",
21
+ properties: {
22
+ ...projectInputProperty,
23
+ updates: {
24
+ type: "array",
25
+ description: "Array of translation updates",
26
+ items: {
27
+ type: "object",
28
+ properties: {
29
+ key: {
30
+ type: "string",
31
+ description: "Translation key WITHOUT namespace prefix when namespace is provided.",
32
+ },
33
+ namespace: {
34
+ type: "string",
35
+ description: "Namespace for the key. Defaults to 'default'.",
36
+ },
37
+ translations: {
38
+ type: "object",
39
+ description: "Translations for target languages. Keys are language codes, values are translated text.",
40
+ },
41
+ },
42
+ required: ["key", "translations"],
43
+ },
44
+ },
45
+ },
46
+ required: ["project", "updates"],
47
+ },
48
+ },
49
+ execute: (client, args) => executeTool(args, inputSchema, async (input, { workspaceId, projectSlug }) => {
50
+ const formattedUpdates = input.updates.map((u) => ({
51
+ key: u.key,
52
+ namespace: u.namespace || "default",
53
+ translations: u.translations,
54
+ }));
55
+ const result = await client.mcp.bulkUpdateTranslations.mutate({
56
+ orgSlug: workspaceId,
57
+ projectSlug,
58
+ updates: formattedUpdates,
59
+ });
60
+ return success({
61
+ success: true,
62
+ project: input.project,
63
+ keysUpdated: result.keysUpdated,
64
+ updates: result.updates,
65
+ });
66
+ }),
67
+ };
68
+ //# sourceMappingURL=bulkUpdateTranslations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulkUpdateTranslations.js","sourceRoot":"","sources":["../../src/tools/bulkUpdateTranslations.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,OAAO,GACR,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;IACvC,OAAO,EAAE,CAAC,CAAC,KAAK,CACd,CAAC,CAAC,MAAM,CAAC;QACP,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;QACf,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAChC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;KAC/C,CAAC,CACH;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAS;IAC1C,UAAU,EAAE;QACV,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EACT,gLAAgL;QAClL,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,oBAAoB;gBACvB,OAAO,EAAE;oBACP,IAAI,EAAE,OAAO;oBACb,WAAW,EAAE,8BAA8B;oBAC3C,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,GAAG,EAAE;gCACH,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,sEAAsE;6BACpF;4BACD,SAAS,EAAE;gCACT,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,+CAA+C;6BAC7D;4BACD,YAAY,EAAE;gCACZ,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,yFAAyF;6BACvG;yBACF;wBACD,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC;qBAClC;iBACF;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;SACjC;KACF;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CACxB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QAC3E,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjD,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,SAAS;YACnC,YAAY,EAAE,CAAC,CAAC,YAAY;SAC7B,CAAC,CAAC,CAAC;QAEJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,MAAM,CAAC;YAC5D,OAAO,EAAE,WAAW;YACpB,WAAW;YACX,OAAO,EAAE,gBAAgB;SAC1B,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;YACb,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC;IACL,CAAC,CAAC;CACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * createTranslationKey MCP Tool
3
+ *
4
+ * Creates a new translation key with source text in the default language.
5
+ */
6
+ import type { Tool } from "../types/index.js";
7
+ export declare const createTranslationKey: Tool;
8
+ //# sourceMappingURL=createTranslationKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTranslationKey.d.ts","sourceRoot":"","sources":["../../src/tools/createTranslationKey.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAQ9C,eAAO,MAAM,oBAAoB,EAAE,IA6ClC,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * createTranslationKey MCP Tool
3
+ *
4
+ * Creates a new translation key with source text in the default language.
5
+ */
6
+ import { z } from "zod";
7
+ import { executeTool, projectInputProperty, projectSchema, success, } from "../base-tool.js";
8
+ const inputSchema = projectSchema.extend({
9
+ key: z.string().min(1),
10
+ sourceValue: z.string().min(1),
11
+ namespace: z.string().optional(),
12
+ });
13
+ export const createTranslationKey = {
14
+ definition: {
15
+ name: "createTranslationKey",
16
+ description: "Create a SINGLE translation key with source text. IMPORTANT: If you need to create 2 or more keys, use bulkCreateKeys instead.",
17
+ inputSchema: {
18
+ type: "object",
19
+ properties: {
20
+ ...projectInputProperty,
21
+ key: {
22
+ type: "string",
23
+ description: "Translation key WITHOUT namespace prefix when namespace is provided.",
24
+ },
25
+ sourceValue: {
26
+ type: "string",
27
+ description: "Source text in default language (usually English)",
28
+ },
29
+ namespace: {
30
+ type: "string",
31
+ description: "Namespace for the key. Defaults to 'default'.",
32
+ },
33
+ },
34
+ required: ["project", "key", "sourceValue"],
35
+ },
36
+ },
37
+ execute: (client, args) => executeTool(args, inputSchema, async (input, { workspaceId, projectSlug }) => {
38
+ const result = await client.mcp.createKey.mutate({
39
+ orgSlug: workspaceId,
40
+ projectSlug,
41
+ key: input.key,
42
+ namespace: input.namespace || "default",
43
+ sourceText: input.sourceValue,
44
+ });
45
+ return success({
46
+ success: true,
47
+ keyId: result.keyId,
48
+ key: input.key,
49
+ namespace: input.namespace || "default",
50
+ sourceText: input.sourceValue,
51
+ project: input.project,
52
+ });
53
+ }),
54
+ };
55
+ //# sourceMappingURL=createTranslationKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTranslationKey.js","sourceRoot":"","sources":["../../src/tools/createTranslationKey.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,OAAO,GACR,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;IACvC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAS;IACxC,UAAU,EAAE;QACV,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EACT,gIAAgI;QAClI,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,oBAAoB;gBACvB,GAAG,EAAE;oBACH,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,sEAAsE;iBACpF;gBACD,WAAW,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,mDAAmD;iBACjE;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,+CAA+C;iBAC7D;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,aAAa,CAAC;SAC5C;KACF;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CACxB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QAC3E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC;YAC/C,OAAO,EAAE,WAAW;YACpB,WAAW;YACX,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,SAAS;YACvC,UAAU,EAAE,KAAK,CAAC,WAAW;SAC9B,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;YACb,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,SAAS;YACvC,UAAU,EAAE,KAAK,CAAC,WAAW;YAC7B,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC;IACL,CAAC,CAAC;CACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * getProjectInfo MCP Tool
3
+ *
4
+ * Gets project information including available namespaces, languages, and stats.
5
+ */
6
+ import type { Tool } from "../types/index.js";
7
+ export declare const getProjectInfo: Tool;
8
+ //# sourceMappingURL=getProjectInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getProjectInfo.d.ts","sourceRoot":"","sources":["../../src/tools/getProjectInfo.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAI9C,eAAO,MAAM,cAAc,EAAE,IAsB5B,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * getProjectInfo MCP Tool
3
+ *
4
+ * Gets project information including available namespaces, languages, and stats.
5
+ */
6
+ import { executeTool, projectInputProperty, projectSchema, success, } from "../base-tool.js";
7
+ const inputSchema = projectSchema;
8
+ export const getProjectInfo = {
9
+ definition: {
10
+ name: "getProjectInfo",
11
+ description: "Get project information including available namespaces, languages, and key count. Use this to understand the project structure before adding or updating translations.",
12
+ inputSchema: {
13
+ type: "object",
14
+ properties: {
15
+ ...projectInputProperty,
16
+ },
17
+ required: ["project"],
18
+ },
19
+ },
20
+ execute: (client, args) => executeTool(args, inputSchema, async (input, { workspaceId, projectSlug }) => {
21
+ const result = await client.mcp.getProjectInfo.query({
22
+ orgSlug: workspaceId,
23
+ projectSlug,
24
+ });
25
+ return success(result);
26
+ }),
27
+ };
28
+ //# sourceMappingURL=getProjectInfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getProjectInfo.js","sourceRoot":"","sources":["../../src/tools/getProjectInfo.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,OAAO,GACR,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,GAAG,aAAa,CAAC;AAElC,MAAM,CAAC,MAAM,cAAc,GAAS;IAClC,UAAU,EAAE;QACV,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,wKAAwK;QAC1K,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,oBAAoB;aACxB;YACD,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;KACF;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CACxB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QAC3E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC;YACnD,OAAO,EAAE,WAAW;YACpB,WAAW;SACZ,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC,CAAC;CACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * listKeys MCP Tool
3
+ *
4
+ * Lists ALL translation keys in a project with their source text and translations.
5
+ */
6
+ import type { Tool } from "../types/index.js";
7
+ export declare const listKeys: Tool;
8
+ //# sourceMappingURL=listKeys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listKeys.d.ts","sourceRoot":"","sources":["../../src/tools/listKeys.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAO9C,eAAO,MAAM,QAAQ,EAAE,IAiCtB,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * listKeys MCP Tool
3
+ *
4
+ * Lists ALL translation keys in a project with their source text and translations.
5
+ */
6
+ import { z } from "zod";
7
+ import { executeTool, projectInputProperty, projectSchema, success, } from "../base-tool.js";
8
+ const inputSchema = projectSchema.extend({
9
+ search: z.string().optional(),
10
+ namespaces: z.array(z.string()).optional(),
11
+ });
12
+ export const listKeys = {
13
+ definition: {
14
+ name: "listKeys",
15
+ description: "Get all translation keys with their source text and translations. Returns ALL keys in a single response. Use 'namespaces' to filter by namespace or 'search' to search within key names and source text.",
16
+ inputSchema: {
17
+ type: "object",
18
+ properties: {
19
+ ...projectInputProperty,
20
+ search: {
21
+ type: "string",
22
+ description: "Search term to find in key names or source text.",
23
+ },
24
+ namespaces: {
25
+ type: "array",
26
+ items: { type: "string" },
27
+ description: "Filter by specific namespaces (e.g., ['nav', 'home']).",
28
+ },
29
+ },
30
+ required: ["project"],
31
+ },
32
+ },
33
+ execute: (client, args) => executeTool(args, inputSchema, async (input, { workspaceId, projectSlug }) => {
34
+ const result = await client.mcp.getAllTranslations.query({
35
+ orgSlug: workspaceId,
36
+ projectSlug,
37
+ search: input.search,
38
+ namespaces: input.namespaces,
39
+ });
40
+ return success(result);
41
+ }),
42
+ };
43
+ //# sourceMappingURL=listKeys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listKeys.js","sourceRoot":"","sources":["../../src/tools/listKeys.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,OAAO,GACR,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;IACvC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAS;IAC5B,UAAU,EAAE;QACV,IAAI,EAAE,UAAU;QAChB,WAAW,EACT,0MAA0M;QAC5M,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,oBAAoB;gBACvB,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,kDAAkD;iBAChE;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,WAAW,EAAE,wDAAwD;iBACtE;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;KACF;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CACxB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QAC3E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,CAAC;YACvD,OAAO,EAAE,WAAW;YACpB,WAAW;YACX,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC,CAAC;CACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * updateTranslation MCP Tool
3
+ *
4
+ * Updates or creates a translation for a specific language.
5
+ */
6
+ import type { Tool } from "../types/index.js";
7
+ export declare const updateTranslation: Tool;
8
+ //# sourceMappingURL=updateTranslation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateTranslation.d.ts","sourceRoot":"","sources":["../../src/tools/updateTranslation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAS9C,eAAO,MAAM,iBAAiB,EAAE,IAkD/B,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * updateTranslation MCP Tool
3
+ *
4
+ * Updates or creates a translation for a specific language.
5
+ */
6
+ import { z } from "zod";
7
+ import { executeTool, projectInputProperty, projectSchema, success, } from "../base-tool.js";
8
+ const inputSchema = projectSchema.extend({
9
+ key: z.string().min(1),
10
+ languageCode: z.string().min(2).max(10),
11
+ value: z.string(),
12
+ namespace: z.string().optional(),
13
+ });
14
+ export const updateTranslation = {
15
+ definition: {
16
+ name: "updateTranslation",
17
+ description: "Update or create a SINGLE translation for a specific language. IMPORTANT: If you need to update 2 or more translations, use bulkUpdateTranslations instead.",
18
+ inputSchema: {
19
+ type: "object",
20
+ properties: {
21
+ ...projectInputProperty,
22
+ key: {
23
+ type: "string",
24
+ description: "Translation key WITHOUT namespace prefix when namespace is provided.",
25
+ },
26
+ languageCode: {
27
+ type: "string",
28
+ description: "Language code (e.g., 'en', 'tr', 'de', 'fr')",
29
+ },
30
+ value: {
31
+ type: "string",
32
+ description: "Translation text",
33
+ },
34
+ namespace: {
35
+ type: "string",
36
+ description: "Namespace for the key. Defaults to 'default'.",
37
+ },
38
+ },
39
+ required: ["project", "key", "languageCode", "value"],
40
+ },
41
+ },
42
+ execute: (client, args) => executeTool(args, inputSchema, async (input, { workspaceId, projectSlug }) => {
43
+ await client.mcp.updateTranslation.mutate({
44
+ orgSlug: workspaceId,
45
+ projectSlug,
46
+ key: input.key,
47
+ namespace: input.namespace || "default",
48
+ languageCode: input.languageCode,
49
+ value: input.value,
50
+ });
51
+ return success({
52
+ success: true,
53
+ key: input.key,
54
+ namespace: input.namespace || "default",
55
+ languageCode: input.languageCode,
56
+ value: input.value,
57
+ project: input.project,
58
+ });
59
+ }),
60
+ };
61
+ //# sourceMappingURL=updateTranslation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateTranslation.js","sourceRoot":"","sources":["../../src/tools/updateTranslation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,OAAO,GACR,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;IACvC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACvC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAS;IACrC,UAAU,EAAE;QACV,IAAI,EAAE,mBAAmB;QACzB,WAAW,EACT,6JAA6J;QAC/J,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,oBAAoB;gBACvB,GAAG,EAAE;oBACH,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,sEAAsE;iBACpF;gBACD,YAAY,EAAE;oBACZ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,8CAA8C;iBAC5D;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,kBAAkB;iBAChC;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,+CAA+C;iBAC7D;aACF;YACD,QAAQ,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,CAAC;SACtD;KACF;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CACxB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QAC3E,MAAM,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC;YACxC,OAAO,EAAE,WAAW;YACpB,WAAW;YACX,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,SAAS;YACvC,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,KAAK,EAAE,KAAK,CAAC,KAAK;SACnB,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;YACb,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,SAAS;YACvC,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC;IACL,CAAC,CAAC;CACL,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Shared types for MCP server
3
+ */
4
+ /**
5
+ * MCP Tool definition
6
+ */
7
+ export interface ToolDefinition {
8
+ name: string;
9
+ description: string;
10
+ inputSchema: {
11
+ type: "object";
12
+ properties: Record<string, any>;
13
+ required?: string[];
14
+ };
15
+ }
16
+ /**
17
+ * MCP Tool execution result - compatible with @modelcontextprotocol/sdk
18
+ */
19
+ export interface ToolResult {
20
+ content: Array<{
21
+ type: "text" | "image" | "resource";
22
+ text?: string;
23
+ data?: string;
24
+ uri?: string;
25
+ mimeType?: string;
26
+ }>;
27
+ isError?: boolean;
28
+ [key: string]: unknown;
29
+ }
30
+ /**
31
+ * MCP Tool implementation
32
+ */
33
+ export interface Tool {
34
+ definition: ToolDefinition;
35
+ execute: (client: any, args: unknown) => Promise<ToolResult>;
36
+ }
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;QACpC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,UAAU,EAAE,cAAc,CAAC;IAC3B,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CAC9D"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shared types for MCP server
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@better-i18n/mcp",
3
+ "version": "0.0.1",
4
+ "description": "MCP server for Better i18n translation management - AI-powered translation workflow for Cursor, Claude, and other AI assistants",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "bin": {
10
+ "better-i18n-mcp": "./dist/index.js"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "package.json",
15
+ "README.md"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/better-i18n/better-i18n.git",
23
+ "directory": "packages/mcp"
24
+ },
25
+ "homepage": "https://better-i18n.com",
26
+ "bugs": {
27
+ "url": "https://github.com/better-i18n/better-i18n/issues"
28
+ },
29
+ "keywords": [
30
+ "mcp",
31
+ "model-context-protocol",
32
+ "i18n",
33
+ "internationalization",
34
+ "translation",
35
+ "better-i18n",
36
+ "cursor",
37
+ "claude",
38
+ "ai",
39
+ "localization"
40
+ ],
41
+ "scripts": {
42
+ "build": "tsc",
43
+ "start": "node ./dist/index.js",
44
+ "dev": "bun run src/index.ts",
45
+ "typecheck": "tsc --noEmit",
46
+ "clean": "rm -rf dist",
47
+ "prepublishOnly": "npm run clean && npm run build"
48
+ },
49
+ "dependencies": {
50
+ "@modelcontextprotocol/sdk": "^1.0.4",
51
+ "@trpc/client": "^11.0.0",
52
+ "zod": "^3.25.1"
53
+ },
54
+ "devDependencies": {
55
+ "@types/node": "^20.0.0",
56
+ "typescript": "~5.9.2"
57
+ },
58
+ "engines": {
59
+ "node": ">=18.0.0"
60
+ }
61
+ }