Skip to content

Commit 81c6ddf

Browse files
authored
feat: mcp tool (#487)
1 parent 1fed528 commit 81c6ddf

File tree

5 files changed

+122
-0
lines changed

5 files changed

+122
-0
lines changed

.changeset/rude-crabs-remember.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"lingo.dev": minor
3+
---
4+
5+
add mcp command

packages/cli/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"@inquirer/prompts": "^7.2.3",
4949
"@lingo.dev/_sdk": "workspace:*",
5050
"@lingo.dev/_spec": "workspace:*",
51+
"@modelcontextprotocol/sdk": "^1.5.0",
5152
"@paralleldrive/cuid2": "^2.2.2",
5253
"chalk": "^5.4.1",
5354
"cors": "^2.8.5",

packages/cli/src/cli/cmd/mcp.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { Command } from "interactive-commander";
2+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4+
import Z from "zod";
5+
import { ReplexicaEngine } from "@lingo.dev/_sdk";
6+
import { getSettings } from "../utils/settings";
7+
import { createAuthenticator } from "../utils/auth";
8+
9+
export default new Command()
10+
.command("mcp")
11+
.description("Use Lingo.dev model context provider with your AI agent")
12+
.helpOption("-h, --help", "Show help")
13+
.action(async (_, program) => {
14+
const apiKey = program.args[0];
15+
const settings = getSettings(apiKey);
16+
17+
if (!settings.auth.apiKey) {
18+
console.error("No API key provided");
19+
return;
20+
}
21+
22+
const authenticator = createAuthenticator({
23+
apiUrl: settings.auth.apiUrl,
24+
apiKey: settings.auth.apiKey!,
25+
});
26+
const auth = await authenticator.whoami();
27+
28+
if (!auth) {
29+
console.error("Not authenticated");
30+
return;
31+
} else {
32+
console.log(`Authenticated as ${auth.email}`);
33+
}
34+
35+
const replexicaEngine = new ReplexicaEngine({
36+
apiKey: settings.auth.apiKey,
37+
apiUrl: settings.auth.apiUrl,
38+
});
39+
40+
const server = new McpServer({
41+
name: "Lingo.dev",
42+
version: "1.0.0",
43+
});
44+
45+
server.tool(
46+
"translate",
47+
"Detect language and translate text with Lingo.dev.",
48+
{
49+
text: Z.string(),
50+
targetLocale: Z.string().regex(/^[a-z]{2}(-[A-Z]{2})?$/),
51+
},
52+
async ({ text, targetLocale }) => {
53+
const sourceLocale = await replexicaEngine.recognizeLocale(text);
54+
const data = await replexicaEngine.localizeText(text, {
55+
sourceLocale,
56+
targetLocale,
57+
});
58+
return { content: [{ type: "text", text: data }] };
59+
},
60+
);
61+
62+
const transport = new StdioServerTransport();
63+
await server.connect(transport);
64+
console.log("Lingo.dev MCP Server running on stdio");
65+
});

packages/cli/src/cli/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import configCmd from "./cmd/show";
1111
import i18nCmd from "./cmd/i18n";
1212
import lockfileCmd from "./cmd/lockfile";
1313
import cleanupCmd from "./cmd/cleanup";
14+
import mcpCmd from "./cmd/mcp";
1415

1516
import packageJson from "../../package.json";
1617

@@ -40,6 +41,7 @@ Website: https://lingo.dev
4041
.addCommand(configCmd)
4142
.addCommand(lockfileCmd)
4243
.addCommand(cleanupCmd)
44+
.addCommand(mcpCmd)
4345
.exitOverride((err) => {
4446
// Exit with code 0 when help or version is displayed
4547
if (err.code === "commander.helpDisplayed" || err.code === "commander.version" || err.code === "commander.help") {

pnpm-lock.yaml

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)