@better-i18n/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/README.md +158 -0
- package/dist/client.d.ts +17 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +34 -0
- package/dist/client.js.map +1 -0
- package/dist/context.d.ts +23 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +142 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +149 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/bulkCreateKeys.d.ts +9 -0
- package/dist/tools/bulkCreateKeys.d.ts.map +1 -0
- package/dist/tools/bulkCreateKeys.js +113 -0
- package/dist/tools/bulkCreateKeys.js.map +1 -0
- package/dist/tools/bulkUpdateTranslations.d.ts +9 -0
- package/dist/tools/bulkUpdateTranslations.d.ts.map +1 -0
- package/dist/tools/bulkUpdateTranslations.js +107 -0
- package/dist/tools/bulkUpdateTranslations.js.map +1 -0
- package/dist/tools/createTranslationKey.d.ts +9 -0
- package/dist/tools/createTranslationKey.d.ts.map +1 -0
- package/dist/tools/createTranslationKey.js +95 -0
- package/dist/tools/createTranslationKey.js.map +1 -0
- package/dist/tools/getProjectInfo.d.ts +9 -0
- package/dist/tools/getProjectInfo.d.ts.map +1 -0
- package/dist/tools/getProjectInfo.js +67 -0
- package/dist/tools/getProjectInfo.js.map +1 -0
- package/dist/tools/listKeys.d.ts +9 -0
- package/dist/tools/listKeys.d.ts.map +1 -0
- package/dist/tools/listKeys.js +113 -0
- package/dist/tools/listKeys.js.map +1 -0
- package/dist/tools/updateTranslation.d.ts +9 -0
- package/dist/tools/updateTranslation.d.ts.map +1 -0
- package/dist/tools/updateTranslation.js +101 -0
- package/dist/tools/updateTranslation.js.map +1 -0
- package/dist/types/index.d.ts +44 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# @better-i18n/mcp-server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for [Better i18n](https://better-i18n.com) translation management. Enables AI assistants like Claude (via Cursor) to manage your translations directly from your IDE.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🤖 **AI-Powered Translation Management** - Let AI handle your translations
|
|
8
|
+
- 📝 **Create Translation Keys** - Add new keys with source text and translations
|
|
9
|
+
- 🔄 **Bulk Operations** - Create/update multiple keys at once
|
|
10
|
+
- 🔍 **Smart Search** - Find keys by name, namespace, or missing translations
|
|
11
|
+
- 🌍 **Multi-language Support** - Manage all your target languages
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
### Global Installation (Recommended)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g @better-i18n/mcp-server
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### With npx
|
|
22
|
+
|
|
23
|
+
You can also run it directly without installing:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx @better-i18n/mcp-server
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Setup
|
|
30
|
+
|
|
31
|
+
### 1. Get Your API Key
|
|
32
|
+
|
|
33
|
+
1. Go to [better-i18n.com/settings/api-keys](https://better-i18n.com/settings/api-keys)
|
|
34
|
+
2. Create a new API key
|
|
35
|
+
3. Copy the key (you won't see it again!)
|
|
36
|
+
|
|
37
|
+
### 2. Add i18n.config.ts to Your Project
|
|
38
|
+
|
|
39
|
+
Create an `i18n.config.ts` in your project root:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { createI18n } from "@better-i18n/next"; // or your framework
|
|
43
|
+
|
|
44
|
+
export const i18n = createI18n({
|
|
45
|
+
workspaceId: "your-org-slug", // Your organization slug
|
|
46
|
+
projectSlug: "your-project", // Your project slug
|
|
47
|
+
defaultLocale: "en",
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 3. Configure Your IDE
|
|
52
|
+
|
|
53
|
+
#### Cursor
|
|
54
|
+
|
|
55
|
+
Add to your MCP settings (`~/.cursor/mcp.json` or project's `.cursor/mcp.json`):
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"mcpServers": {
|
|
60
|
+
"better-i18n": {
|
|
61
|
+
"command": "npx",
|
|
62
|
+
"args": ["@better-i18n/mcp-server"],
|
|
63
|
+
"env": {
|
|
64
|
+
"BETTER_I18N_API_KEY": "your-api-key-here"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Or with global install:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"mcpServers": {
|
|
76
|
+
"better-i18n": {
|
|
77
|
+
"command": "better-i18n-mcp",
|
|
78
|
+
"env": {
|
|
79
|
+
"BETTER_I18N_API_KEY": "your-api-key-here"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Available Tools
|
|
87
|
+
|
|
88
|
+
### `getProjectInfo`
|
|
89
|
+
Get project information including available namespaces, languages, and key count.
|
|
90
|
+
|
|
91
|
+
### `listKeys`
|
|
92
|
+
List translation keys with optional filtering:
|
|
93
|
+
- `search` - Search by key name
|
|
94
|
+
- `namespaces` - Filter by namespaces
|
|
95
|
+
- `missingLanguage` - Find keys missing a specific language translation
|
|
96
|
+
|
|
97
|
+
### `createTranslationKey`
|
|
98
|
+
Create a single translation key with source text and optional translations.
|
|
99
|
+
|
|
100
|
+
### `bulkCreateKeys`
|
|
101
|
+
Create multiple translation keys with all translations in one request.
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"keys": [
|
|
106
|
+
{
|
|
107
|
+
"key": "nav.home",
|
|
108
|
+
"namespace": "nav",
|
|
109
|
+
"sourceText": "Home",
|
|
110
|
+
"translations": { "tr": "Ana Sayfa", "de": "Startseite" }
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### `updateTranslation`
|
|
117
|
+
Update a single translation for a specific language.
|
|
118
|
+
|
|
119
|
+
### `bulkUpdateTranslations`
|
|
120
|
+
Update translations for multiple keys at once.
|
|
121
|
+
|
|
122
|
+
## Example Workflow
|
|
123
|
+
|
|
124
|
+
Ask your AI assistant:
|
|
125
|
+
|
|
126
|
+
> "Add Turkish translations for all keys in the nav namespace that are missing Turkish"
|
|
127
|
+
|
|
128
|
+
The AI will:
|
|
129
|
+
1. Use `listKeys` with `missingLanguage: "tr"` and `namespaces: ["nav"]`
|
|
130
|
+
2. Use `bulkUpdateTranslations` to add the Turkish translations
|
|
131
|
+
|
|
132
|
+
## Environment Variables
|
|
133
|
+
|
|
134
|
+
| Variable | Required | Description |
|
|
135
|
+
|----------|----------|-------------|
|
|
136
|
+
| `BETTER_I18N_API_KEY` | Yes | Your API key from better-i18n.com |
|
|
137
|
+
| `BETTER_I18N_API_URL` | No | API URL (default: https://better-i18n.com) |
|
|
138
|
+
|
|
139
|
+
## Development
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Clone the repo
|
|
143
|
+
git clone https://github.com/better-i18n/better-i18n.git
|
|
144
|
+
cd packages/mcp-server
|
|
145
|
+
|
|
146
|
+
# Install dependencies
|
|
147
|
+
npm install
|
|
148
|
+
|
|
149
|
+
# Run in development mode
|
|
150
|
+
npm run dev
|
|
151
|
+
|
|
152
|
+
# Build
|
|
153
|
+
npm run build
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
MIT © [Better i18n](https://better-i18n.com)
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tRPC client for Paris API with API key authentication
|
|
3
|
+
*/
|
|
4
|
+
export interface ClientConfig {
|
|
5
|
+
apiUrl: string;
|
|
6
|
+
apiKey: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Create a tRPC client authenticated with API key
|
|
10
|
+
*
|
|
11
|
+
* @param config - API URL, API key, and optional organization ID
|
|
12
|
+
* @returns Configured tRPC client
|
|
13
|
+
*/
|
|
14
|
+
export declare function createParisClient(config: ClientConfig & {
|
|
15
|
+
organizationId?: string;
|
|
16
|
+
}): import("@trpc/client").TRPCClient<any>;
|
|
17
|
+
//# 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;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,0CAuBnF"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tRPC client for Paris 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 createParisClient(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
|
+
return createTRPCClient({
|
|
17
|
+
links: [
|
|
18
|
+
httpBatchLink({
|
|
19
|
+
url,
|
|
20
|
+
headers: () => {
|
|
21
|
+
const headers = {
|
|
22
|
+
// Better Auth expects API key in x-api-key header
|
|
23
|
+
"x-api-key": config.apiKey,
|
|
24
|
+
};
|
|
25
|
+
if (config.organizationId) {
|
|
26
|
+
headers["x-organization-id"] = config.organizationId;
|
|
27
|
+
}
|
|
28
|
+
return headers;
|
|
29
|
+
},
|
|
30
|
+
}),
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# 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;AAW/D;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAkD;IAClF,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,OAAO,gBAAgB,CAAY;QACjC,KAAK,EAAE;YACL,aAAa,CAAC;gBACZ,GAAG;gBACH,OAAO,EAAE,GAAG,EAAE;oBACZ,MAAM,OAAO,GAA2B;wBACtC,kDAAkD;wBAClD,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;aACF,CAAC;SACH;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project context detection
|
|
3
|
+
*
|
|
4
|
+
* Automatically detects Better i18n project configuration by searching for
|
|
5
|
+
* createI18n usage from @better-i18n/next or @better-i18n/core in the workspace.
|
|
6
|
+
*/
|
|
7
|
+
export interface ProjectContext {
|
|
8
|
+
workspaceId: string;
|
|
9
|
+
projectSlug: string;
|
|
10
|
+
defaultLocale: string;
|
|
11
|
+
cdnBaseUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Find and parse createI18n configuration in workspace
|
|
15
|
+
*
|
|
16
|
+
* Searches for files importing createI18n from @better-i18n packages
|
|
17
|
+
* and extracts the configuration.
|
|
18
|
+
*
|
|
19
|
+
* @param startDir - Starting directory (defaults to process.cwd())
|
|
20
|
+
* @returns Project context or null if not found
|
|
21
|
+
*/
|
|
22
|
+
export declare function detectProjectContext(startDir?: string): Promise<ProjectContext | null>;
|
|
23
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,GAAE,MAAsB,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA0BhC"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project context detection
|
|
3
|
+
*
|
|
4
|
+
* Automatically detects Better i18n project configuration by searching for
|
|
5
|
+
* createI18n usage from @better-i18n/next or @better-i18n/core in the workspace.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, existsSync, readdirSync, statSync } from "node:fs";
|
|
8
|
+
import { dirname, join } from "node:path";
|
|
9
|
+
/**
|
|
10
|
+
* Find and parse createI18n configuration in workspace
|
|
11
|
+
*
|
|
12
|
+
* Searches for files importing createI18n from @better-i18n packages
|
|
13
|
+
* and extracts the configuration.
|
|
14
|
+
*
|
|
15
|
+
* @param startDir - Starting directory (defaults to process.cwd())
|
|
16
|
+
* @returns Project context or null if not found
|
|
17
|
+
*/
|
|
18
|
+
export async function detectProjectContext(startDir = process.cwd()) {
|
|
19
|
+
try {
|
|
20
|
+
// Find workspace root
|
|
21
|
+
const workspaceRoot = findWorkspaceRoot(startDir);
|
|
22
|
+
console.error(`[better-i18n] Searching for createI18n in ${workspaceRoot}...`);
|
|
23
|
+
// Search for files with createI18n import
|
|
24
|
+
const configFile = findCreateI18nFile(workspaceRoot);
|
|
25
|
+
if (configFile) {
|
|
26
|
+
console.error(`[better-i18n] Found createI18n in ${configFile}`);
|
|
27
|
+
const config = parseI18nConfig(configFile);
|
|
28
|
+
if (config.workspaceId && config.projectSlug) {
|
|
29
|
+
console.error(`[better-i18n] Detected project: ${config.workspaceId}/${config.projectSlug}`);
|
|
30
|
+
return config;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
console.error("[better-i18n] Error detecting project context:", error);
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Find workspace root by looking for .git or package.json with workspaces
|
|
41
|
+
*/
|
|
42
|
+
function findWorkspaceRoot(startDir) {
|
|
43
|
+
let currentDir = startDir;
|
|
44
|
+
const maxDepth = 10;
|
|
45
|
+
let depth = 0;
|
|
46
|
+
while (depth < maxDepth) {
|
|
47
|
+
// Check for .git directory
|
|
48
|
+
if (existsSync(join(currentDir, ".git"))) {
|
|
49
|
+
return currentDir;
|
|
50
|
+
}
|
|
51
|
+
// Check for workspace root (package.json with workspaces)
|
|
52
|
+
const pkgPath = join(currentDir, "package.json");
|
|
53
|
+
if (existsSync(pkgPath)) {
|
|
54
|
+
try {
|
|
55
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
56
|
+
if (pkg.workspaces) {
|
|
57
|
+
return currentDir;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Ignore parse errors
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const parentDir = dirname(currentDir);
|
|
65
|
+
if (parentDir === currentDir)
|
|
66
|
+
break;
|
|
67
|
+
currentDir = parentDir;
|
|
68
|
+
depth++;
|
|
69
|
+
}
|
|
70
|
+
return startDir;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Search for files containing createI18n import from @better-i18n packages
|
|
74
|
+
*/
|
|
75
|
+
function findCreateI18nFile(workspaceRoot) {
|
|
76
|
+
const files = [];
|
|
77
|
+
// Recursively search for TypeScript/JavaScript files
|
|
78
|
+
function searchDir(dir, depth = 0) {
|
|
79
|
+
if (depth > 5)
|
|
80
|
+
return; // Limit recursion depth
|
|
81
|
+
try {
|
|
82
|
+
const entries = readdirSync(dir);
|
|
83
|
+
for (const entry of entries) {
|
|
84
|
+
// Skip common directories
|
|
85
|
+
if (["node_modules", ".git", "dist", "build", ".next"].includes(entry)) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const fullPath = join(dir, entry);
|
|
89
|
+
const stat = statSync(fullPath);
|
|
90
|
+
if (stat.isDirectory()) {
|
|
91
|
+
searchDir(fullPath, depth + 1);
|
|
92
|
+
}
|
|
93
|
+
else if (/\.(ts|tsx|js|jsx)$/.test(entry)) {
|
|
94
|
+
files.push(fullPath);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
// Ignore permission errors
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
searchDir(workspaceRoot);
|
|
103
|
+
// Search through found files for createI18n import
|
|
104
|
+
for (const file of files) {
|
|
105
|
+
try {
|
|
106
|
+
const content = readFileSync(file, "utf-8");
|
|
107
|
+
// Check for createI18n import from @better-i18n packages
|
|
108
|
+
if (/import\s+.*createI18n.*from\s+['"]@better-i18n\/(next|core)['"]/.test(content) &&
|
|
109
|
+
/createI18n\s*\(/.test(content)) {
|
|
110
|
+
return file;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// Ignore read errors
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Parse file to extract createI18n configuration
|
|
121
|
+
*
|
|
122
|
+
* Uses regex to extract workspaceId, projectSlug, defaultLocale, and cdnBaseUrl
|
|
123
|
+
* from the createI18n call.
|
|
124
|
+
*/
|
|
125
|
+
function parseI18nConfig(filePath) {
|
|
126
|
+
const content = readFileSync(filePath, "utf-8");
|
|
127
|
+
// Extract values using regex
|
|
128
|
+
const workspaceMatch = content.match(/workspaceId:\s*['"]([^'"]+)['"]/);
|
|
129
|
+
const projectMatch = content.match(/projectSlug:\s*['"]([^'"]+)['"]/);
|
|
130
|
+
const localeMatch = content.match(/defaultLocale:\s*['"]([^'"]+)['"]/);
|
|
131
|
+
const cdnMatch = content.match(/cdnBaseUrl:\s*['"]([^'"]+)['"]/);
|
|
132
|
+
if (!workspaceMatch || !projectMatch) {
|
|
133
|
+
throw new Error(`Invalid createI18n config in ${filePath}: missing workspaceId or projectSlug`);
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
workspaceId: workspaceMatch[1],
|
|
137
|
+
projectSlug: projectMatch[1],
|
|
138
|
+
defaultLocale: localeMatch?.[1] || "en",
|
|
139
|
+
cdnBaseUrl: cdnMatch?.[1],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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,149 @@
|
|
|
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 { createParisClient } from "./client.js";
|
|
13
|
+
import { detectProjectContext } from "./context.js";
|
|
14
|
+
import { bulkCreateKeys } from "./tools/bulkCreateKeys.js";
|
|
15
|
+
import { bulkUpdateTranslations } from "./tools/bulkUpdateTranslations.js";
|
|
16
|
+
import { createTranslationKey } from "./tools/createTranslationKey.js";
|
|
17
|
+
import { getProjectInfo } from "./tools/getProjectInfo.js";
|
|
18
|
+
import { listKeys } from "./tools/listKeys.js";
|
|
19
|
+
import { updateTranslation } from "./tools/updateTranslation.js";
|
|
20
|
+
class ParisI18nServer {
|
|
21
|
+
server;
|
|
22
|
+
parisClient;
|
|
23
|
+
context;
|
|
24
|
+
constructor() {
|
|
25
|
+
this.server = new Server({
|
|
26
|
+
name: "better-i18n",
|
|
27
|
+
version: "0.1.0",
|
|
28
|
+
}, {
|
|
29
|
+
capabilities: {
|
|
30
|
+
tools: {},
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
// Will be initialized in init()
|
|
34
|
+
this.parisClient = null;
|
|
35
|
+
this.context = {
|
|
36
|
+
projectContext: null,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
async init() {
|
|
40
|
+
// Read configuration from environment
|
|
41
|
+
const apiUrl = process.env.BETTER_I18N_API_URL || "http://localhost:3000";
|
|
42
|
+
const apiKey = process.env.BETTER_I18N_API_KEY;
|
|
43
|
+
const envOrgId = process.env.BETTER_I18N_ORG_ID;
|
|
44
|
+
if (!apiKey) {
|
|
45
|
+
console.error("[better-i18n] ERROR: BETTER_I18N_API_KEY environment variable is required");
|
|
46
|
+
console.error("[better-i18n] Get your API key from: https://better-i18n.com/settings/api-keys");
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
// Detect project context from workspace
|
|
50
|
+
this.context.projectContext = await detectProjectContext();
|
|
51
|
+
// Resolve organization ID
|
|
52
|
+
let organizationId = envOrgId;
|
|
53
|
+
if (!organizationId && this.context.projectContext?.workspaceId) {
|
|
54
|
+
// Try to lookup org ID from slug using the API
|
|
55
|
+
try {
|
|
56
|
+
const authUrl = apiUrl.replace(/\/$/, "") + "/api/auth/organization/list";
|
|
57
|
+
const response = await fetch(authUrl, {
|
|
58
|
+
headers: { "x-api-key": apiKey },
|
|
59
|
+
});
|
|
60
|
+
if (response.ok) {
|
|
61
|
+
const orgs = await response.json();
|
|
62
|
+
const matchingOrg = orgs.find((org) => org.slug === this.context.projectContext?.workspaceId);
|
|
63
|
+
if (matchingOrg) {
|
|
64
|
+
organizationId = matchingOrg.id;
|
|
65
|
+
console.error(`[better-i18n] Resolved org "${matchingOrg.slug}" -> ${organizationId}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
console.error("[better-i18n] Warning: Could not lookup organization ID:", err);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Create Paris API client with organization context
|
|
74
|
+
this.parisClient = createParisClient({ apiUrl, apiKey, organizationId });
|
|
75
|
+
if (this.context.projectContext) {
|
|
76
|
+
console.error(`[better-i18n] Detected project: ${this.context.projectContext.workspaceId}/${this.context.projectContext.projectSlug}`);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
console.error("[better-i18n] Warning: No i18n.config.ts found. Tools will require explicit projectSlug parameter.");
|
|
80
|
+
}
|
|
81
|
+
this.setupHandlers();
|
|
82
|
+
}
|
|
83
|
+
setupHandlers() {
|
|
84
|
+
// List available tools
|
|
85
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
86
|
+
tools: [
|
|
87
|
+
getProjectInfo.definition,
|
|
88
|
+
listKeys.definition,
|
|
89
|
+
createTranslationKey.definition,
|
|
90
|
+
bulkCreateKeys.definition,
|
|
91
|
+
updateTranslation.definition,
|
|
92
|
+
bulkUpdateTranslations.definition,
|
|
93
|
+
],
|
|
94
|
+
}));
|
|
95
|
+
// Execute tools
|
|
96
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
97
|
+
const { name, arguments: args } = request.params;
|
|
98
|
+
try {
|
|
99
|
+
let result;
|
|
100
|
+
switch (name) {
|
|
101
|
+
case "getProjectInfo":
|
|
102
|
+
result = await getProjectInfo.execute(this.parisClient, args, this.context);
|
|
103
|
+
break;
|
|
104
|
+
case "createTranslationKey":
|
|
105
|
+
result = await createTranslationKey.execute(this.parisClient, args, this.context);
|
|
106
|
+
break;
|
|
107
|
+
case "updateTranslation":
|
|
108
|
+
result = await updateTranslation.execute(this.parisClient, args, this.context);
|
|
109
|
+
break;
|
|
110
|
+
case "listKeys":
|
|
111
|
+
result = await listKeys.execute(this.parisClient, args, this.context);
|
|
112
|
+
break;
|
|
113
|
+
case "bulkCreateKeys":
|
|
114
|
+
result = await bulkCreateKeys.execute(this.parisClient, args, this.context);
|
|
115
|
+
break;
|
|
116
|
+
case "bulkUpdateTranslations":
|
|
117
|
+
result = await bulkUpdateTranslations.execute(this.parisClient, args, this.context);
|
|
118
|
+
break;
|
|
119
|
+
default:
|
|
120
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
121
|
+
}
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
return {
|
|
126
|
+
content: [
|
|
127
|
+
{
|
|
128
|
+
type: "text",
|
|
129
|
+
text: `Error executing ${name}: ${error instanceof Error ? error.message : String(error)}`,
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
isError: true,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
async run() {
|
|
138
|
+
const transport = new StdioServerTransport();
|
|
139
|
+
await this.server.connect(transport);
|
|
140
|
+
console.error("[better-i18n] MCP Server running on stdio");
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Start the server
|
|
144
|
+
const server = new ParisI18nServer();
|
|
145
|
+
server.init().then(() => server.run()).catch((error) => {
|
|
146
|
+
console.error("[better-i18n] Fatal error:", error);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
});
|
|
149
|
+
//# 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,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bulkCreateKeys MCP Tool
|
|
3
|
+
*
|
|
4
|
+
* Creates multiple translation keys with all translations in a single request.
|
|
5
|
+
* Perfect for adding entire components or pages worth of translations at once.
|
|
6
|
+
*/
|
|
7
|
+
import type { Tool } from "../types/index.js";
|
|
8
|
+
export declare const bulkCreateKeys: Tool;
|
|
9
|
+
//# sourceMappingURL=bulkCreateKeys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulkCreateKeys.d.ts","sourceRoot":"","sources":["../../src/tools/bulkCreateKeys.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAY9C,eAAO,MAAM,cAAc,EAAE,IA0G5B,CAAC"}
|