localization-mcp-server 1.0.0 → 1.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.
package/dist/index.js CHANGED
@@ -1,4 +1,10 @@
1
1
  #!/usr/bin/env node
2
+ const args = process.argv.slice(2);
3
+ if (args[0] === "setup") {
4
+ const { runSetup } = await import("./setup.js");
5
+ await runSetup(args.slice(1));
6
+ process.exit(0);
7
+ }
2
8
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
9
  import { createServer } from "./server.js";
4
10
  // Load .env from the mcp-server directory (one level above dist/)
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,kEAAkE;AAClE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;IAC1C,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;IAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,uFAAuF,CACxF,CAAC;AACJ,CAAC;AAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;IAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+EAA+E,CAChF,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;AAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;IACxB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,kEAAkE;AAClE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;IAC1C,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;IAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,uFAAuF,CACxF,CAAC;AACJ,CAAC;AAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;IAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+EAA+E,CAChF,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;AAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runSetup(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AA0DA,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC5D"}
package/dist/setup.js ADDED
@@ -0,0 +1,87 @@
1
+ import { execSync } from "child_process";
2
+ const BOLD = "\x1b[1m";
3
+ const GREEN = "\x1b[32m";
4
+ const RED = "\x1b[31m";
5
+ const YELLOW = "\x1b[33m";
6
+ const RESET = "\x1b[0m";
7
+ const ok = (msg) => console.log(`${GREEN}✓${RESET} ${msg}`);
8
+ const fail = (msg) => console.error(`${RED}✗${RESET} ${msg}`);
9
+ const warn = (msg) => console.log(`${YELLOW}!${RESET} ${msg}`);
10
+ function parseArgs(args) {
11
+ const tokenIdx = args.indexOf("--token");
12
+ const backendIdx = args.indexOf("--backend-url");
13
+ return {
14
+ token: tokenIdx !== -1 ? args[tokenIdx + 1] : undefined,
15
+ backendUrl: backendIdx !== -1 ? args[backendIdx + 1] : undefined,
16
+ };
17
+ }
18
+ function checkClaudeCli() {
19
+ try {
20
+ execSync("claude --version", { stdio: "pipe" });
21
+ return true;
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ function removeOldRegistration() {
28
+ try {
29
+ execSync('claude mcp remove "localization" -s user', { stdio: "pipe" });
30
+ ok("Removed old registration");
31
+ }
32
+ catch {
33
+ // Not registered yet — fine
34
+ }
35
+ }
36
+ function register(token, backendUrl) {
37
+ execSync(`claude mcp add "localization" -s user -e MCP_TOKEN=${token} -e BACKEND_URL=${backendUrl} -- npx -y localization-mcp-server`, { stdio: "pipe" });
38
+ }
39
+ async function verifyToken(token, backendUrl) {
40
+ try {
41
+ const response = await fetch(`${backendUrl}/translations/projects`, {
42
+ headers: { Authorization: `Bearer ${token}` },
43
+ signal: AbortSignal.timeout(10_000),
44
+ });
45
+ return response.ok;
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ }
51
+ export async function runSetup(args) {
52
+ console.log(`\n${BOLD}Localization MCP — setup${RESET}\n`);
53
+ const { token, backendUrl = "http://localhost:8080" } = parseArgs(args);
54
+ if (!token) {
55
+ fail("Missing --token. Run the command generated by the admin panel.");
56
+ process.exit(1);
57
+ }
58
+ // 1. Check Claude CLI
59
+ if (!checkClaudeCli()) {
60
+ fail("Claude CLI not found. Install it from https://claude.ai/code");
61
+ process.exit(1);
62
+ }
63
+ ok("Claude CLI found");
64
+ // 2. Remove old registration
65
+ removeOldRegistration();
66
+ // 3. Register with correct token
67
+ try {
68
+ register(token, backendUrl);
69
+ ok("MCP server registered");
70
+ }
71
+ catch (e) {
72
+ fail(`Failed to register MCP server: ${e}`);
73
+ process.exit(1);
74
+ }
75
+ // 4. Verify token works
76
+ const valid = await verifyToken(token, backendUrl);
77
+ if (!valid) {
78
+ fail("Token verification failed — the token may be expired or the server is unreachable.");
79
+ warn("MCP is registered but will not work until the token is valid.");
80
+ warn("Re-run this command with a fresh token from the admin panel.");
81
+ process.exit(1);
82
+ }
83
+ ok("Token verified");
84
+ console.log(`\n${GREEN}${BOLD}Setup complete.${RESET}`);
85
+ console.log("Restart Claude for the changes to take effect.\n");
86
+ }
87
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "localization-mcp-server",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "MCP server for the localization system — controlled AI access to translations",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/index.ts CHANGED
@@ -1,4 +1,13 @@
1
1
  #!/usr/bin/env node
2
+
3
+ const args = process.argv.slice(2);
4
+
5
+ if (args[0] === "setup") {
6
+ const { runSetup } = await import("./setup.js");
7
+ await runSetup(args.slice(1));
8
+ process.exit(0);
9
+ }
10
+
2
11
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
12
  import { createServer } from "./server.js";
4
13
 
package/src/setup.ts ADDED
@@ -0,0 +1,100 @@
1
+ import { execSync } from "child_process";
2
+
3
+ const BOLD = "\x1b[1m";
4
+ const GREEN = "\x1b[32m";
5
+ const RED = "\x1b[31m";
6
+ const YELLOW = "\x1b[33m";
7
+ const RESET = "\x1b[0m";
8
+
9
+ const ok = (msg: string) => console.log(`${GREEN}✓${RESET} ${msg}`);
10
+ const fail = (msg: string) => console.error(`${RED}✗${RESET} ${msg}`);
11
+ const warn = (msg: string) => console.log(`${YELLOW}!${RESET} ${msg}`);
12
+
13
+ function parseArgs(args: string[]): { token?: string; backendUrl?: string } {
14
+ const tokenIdx = args.indexOf("--token");
15
+ const backendIdx = args.indexOf("--backend-url");
16
+ return {
17
+ token: tokenIdx !== -1 ? args[tokenIdx + 1] : undefined,
18
+ backendUrl: backendIdx !== -1 ? args[backendIdx + 1] : undefined,
19
+ };
20
+ }
21
+
22
+ function checkClaudeCli(): boolean {
23
+ try {
24
+ execSync("claude --version", { stdio: "pipe" });
25
+ return true;
26
+ } catch {
27
+ return false;
28
+ }
29
+ }
30
+
31
+ function removeOldRegistration(): void {
32
+ try {
33
+ execSync('claude mcp remove "localization" -s user', { stdio: "pipe" });
34
+ ok("Removed old registration");
35
+ } catch {
36
+ // Not registered yet — fine
37
+ }
38
+ }
39
+
40
+ function register(token: string, backendUrl: string): void {
41
+ execSync(
42
+ `claude mcp add "localization" -s user -e MCP_TOKEN=${token} -e BACKEND_URL=${backendUrl} -- npx -y localization-mcp-server`,
43
+ { stdio: "pipe" },
44
+ );
45
+ }
46
+
47
+ async function verifyToken(token: string, backendUrl: string): Promise<boolean> {
48
+ try {
49
+ const response = await fetch(`${backendUrl}/translations/projects`, {
50
+ headers: { Authorization: `Bearer ${token}` },
51
+ signal: AbortSignal.timeout(10_000),
52
+ });
53
+ return response.ok;
54
+ } catch {
55
+ return false;
56
+ }
57
+ }
58
+
59
+ export async function runSetup(args: string[]): Promise<void> {
60
+ console.log(`\n${BOLD}Localization MCP — setup${RESET}\n`);
61
+
62
+ const { token, backendUrl = "http://localhost:8080" } = parseArgs(args);
63
+
64
+ if (!token) {
65
+ fail("Missing --token. Run the command generated by the admin panel.");
66
+ process.exit(1);
67
+ }
68
+
69
+ // 1. Check Claude CLI
70
+ if (!checkClaudeCli()) {
71
+ fail("Claude CLI not found. Install it from https://claude.ai/code");
72
+ process.exit(1);
73
+ }
74
+ ok("Claude CLI found");
75
+
76
+ // 2. Remove old registration
77
+ removeOldRegistration();
78
+
79
+ // 3. Register with correct token
80
+ try {
81
+ register(token, backendUrl);
82
+ ok("MCP server registered");
83
+ } catch (e) {
84
+ fail(`Failed to register MCP server: ${e}`);
85
+ process.exit(1);
86
+ }
87
+
88
+ // 4. Verify token works
89
+ const valid = await verifyToken(token, backendUrl);
90
+ if (!valid) {
91
+ fail("Token verification failed — the token may be expired or the server is unreachable.");
92
+ warn("MCP is registered but will not work until the token is valid.");
93
+ warn("Re-run this command with a fresh token from the admin panel.");
94
+ process.exit(1);
95
+ }
96
+ ok("Token verified");
97
+
98
+ console.log(`\n${GREEN}${BOLD}Setup complete.${RESET}`);
99
+ console.log("Restart Claude for the changes to take effect.\n");
100
+ }