@intlayer/mcp 8.9.4-canary.0 → 8.9.5

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,10 +1,21 @@
1
1
  import { dirname as dirname$1 } from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { isESModule } from "@intlayer/config/utils";
4
+ import { createMCPClient } from "@ai-sdk/mcp";
4
5
 
5
6
  //#region src/client/client.ts
6
7
  const dirname = isESModule ? dirname$1(fileURLToPath(import.meta.url)) : __dirname;
8
+ const loadMCPTools = async (serverURL) => {
9
+ const client = await createMCPClient({ transport: {
10
+ type: "http",
11
+ url: serverURL
12
+ } });
13
+ return {
14
+ client,
15
+ tools: await client.tools()
16
+ };
17
+ };
7
18
 
8
19
  //#endregion
9
- export { dirname };
20
+ export { dirname, loadMCPTools };
10
21
  //# sourceMappingURL=client.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.mjs","names":["pathDirname"],"sources":["../../../src/client/client.ts"],"sourcesContent":["import { dirname as pathDirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { isESModule } from '@intlayer/config/utils';\n\nexport const dirname: string = isESModule\n ? pathDirname(fileURLToPath(import.meta.url))\n : __dirname;\n"],"mappings":";;;;;AAIA,MAAa,UAAkB,aAC3BA,UAAY,cAAc,OAAO,KAAK,IAAI,CAAC,GAC3C"}
1
+ {"version":3,"file":"client.mjs","names":["pathDirname"],"sources":["../../../src/client/client.ts"],"sourcesContent":["import { dirname as pathDirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createMCPClient, type MCPClient } from '@ai-sdk/mcp';\nimport { isESModule } from '@intlayer/config/utils';\n\nexport type { MCPClient };\n\nexport const dirname: string = isESModule\n ? pathDirname(fileURLToPath(import.meta.url))\n : __dirname;\n\nexport const loadMCPTools = async (\n serverURL: string\n): Promise<{ client: MCPClient; tools: Record<string, any> }> => {\n const client = await createMCPClient({\n transport: { type: 'http', url: serverURL },\n });\n const tools = await client.tools();\n return { client, tools };\n};\n"],"mappings":";;;;;;AAOA,MAAa,UAAkB,aAC3BA,UAAY,cAAc,OAAO,KAAK,IAAI,CAAC,GAC3C;AAEJ,MAAa,eAAe,OAC1B,cAC+D;CAC/D,MAAM,SAAS,MAAM,gBAAgB,EACnC,WAAW;EAAE,MAAM;EAAQ,KAAK;EAAW,EAC5C,CAAC;CAEF,OAAO;EAAE;EAAQ,aADG,OAAO,OAAO;EACV"}
@@ -3,14 +3,119 @@ import { loadAPITools } from "../tools/api.mjs";
3
3
  import { loadInstallSkillsTool } from "../tools/installSkills.mjs";
4
4
  import { loadDocsTools } from "../tools/docs.mjs";
5
5
  import { dirname as dirname$1, resolve } from "node:path";
6
+ import z from "zod";
7
+ import { readFileSync } from "node:fs";
6
8
  import { fileURLToPath } from "node:url";
7
9
  import { isESModule } from "@intlayer/config/utils";
8
- import { readFileSync } from "node:fs";
9
- import { McpServer } from "/Users/aymericpineau/Documents/intlayer_/node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js";
10
10
 
11
11
  //#region src/server/server.ts
12
12
  const dirname = isESModule ? dirname$1(fileURLToPath(import.meta.url)) : __dirname;
13
13
  const packageJson = JSON.parse(readFileSync(resolve(dirname, "../../../package.json"), "utf8"));
14
+ var McpServer = class {
15
+ _tools = /* @__PURE__ */ new Map();
16
+ _info;
17
+ constructor(info) {
18
+ this._info = info;
19
+ }
20
+ registerTool(name, config, handler) {
21
+ const shape = config.inputSchema ?? {};
22
+ let inputSchema;
23
+ try {
24
+ inputSchema = z.toJSONSchema(z.object(shape));
25
+ } catch {
26
+ inputSchema = {
27
+ type: "object",
28
+ properties: {}
29
+ };
30
+ }
31
+ this._tools.set(name, {
32
+ name,
33
+ description: config.description,
34
+ annotations: config.annotations,
35
+ inputSchema,
36
+ handler
37
+ });
38
+ }
39
+ async handleMessage(message) {
40
+ const { id, method, params } = message;
41
+ const isNotification = id === void 0;
42
+ switch (method) {
43
+ case "initialize": return {
44
+ jsonrpc: "2.0",
45
+ id,
46
+ result: {
47
+ protocolVersion: "2024-11-05",
48
+ capabilities: { tools: {} },
49
+ serverInfo: this._info
50
+ }
51
+ };
52
+ case "tools/list": return {
53
+ jsonrpc: "2.0",
54
+ id,
55
+ result: { tools: Array.from(this._tools.values()).map((t) => ({
56
+ name: t.name,
57
+ description: t.description,
58
+ inputSchema: t.inputSchema,
59
+ ...t.annotations && { annotations: t.annotations }
60
+ })) }
61
+ };
62
+ case "tools/call": {
63
+ const { name, arguments: args } = params ?? {};
64
+ const tool = this._tools.get(name);
65
+ if (!tool) {
66
+ if (isNotification) return null;
67
+ return {
68
+ jsonrpc: "2.0",
69
+ id,
70
+ error: {
71
+ code: -32601,
72
+ message: `Tool not found: ${name}`
73
+ }
74
+ };
75
+ }
76
+ try {
77
+ const result = await tool.handler(args ?? {});
78
+ if (isNotification) return null;
79
+ return {
80
+ jsonrpc: "2.0",
81
+ id,
82
+ result
83
+ };
84
+ } catch (error) {
85
+ if (isNotification) return null;
86
+ return {
87
+ jsonrpc: "2.0",
88
+ id,
89
+ error: {
90
+ code: -32e3,
91
+ message: error instanceof Error ? error.message : String(error)
92
+ }
93
+ };
94
+ }
95
+ }
96
+ case "ping":
97
+ if (isNotification) return null;
98
+ return {
99
+ jsonrpc: "2.0",
100
+ id,
101
+ result: {}
102
+ };
103
+ default:
104
+ if (isNotification) return null;
105
+ return {
106
+ jsonrpc: "2.0",
107
+ id,
108
+ error: {
109
+ code: -32601,
110
+ message: `Method not found: ${method}`
111
+ }
112
+ };
113
+ }
114
+ }
115
+ async connect(transport) {
116
+ await transport.start(this);
117
+ }
118
+ };
14
119
  const loadServer = ({ isLocal }) => {
15
120
  const server = new McpServer({
16
121
  name: "intlayer",
@@ -36,5 +141,5 @@ const loadServer = ({ isLocal }) => {
36
141
  };
37
142
 
38
143
  //#endregion
39
- export { dirname, loadServer };
144
+ export { McpServer, dirname, loadServer };
40
145
  //# sourceMappingURL=server.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.mjs","names":["pathDirname"],"sources":["../../../src/server/server.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { dirname as pathDirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { isESModule } from '@intlayer/config/utils';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { loadAPITools } from '../tools/api';\nimport { loadCLITools } from '../tools/cli';\nimport { loadDocsTools } from '../tools/docs';\nimport { loadInstallSkillsTool } from '../tools/installSkills';\n\nexport const dirname: string = isESModule\n ? pathDirname(fileURLToPath(import.meta.url))\n : __dirname;\n\nconst packageJson: Record<string, any> = JSON.parse(\n readFileSync(resolve(dirname, '../../../package.json'), 'utf8')\n);\n\ntype LoadServer = (options: { isLocal: boolean }) => McpServer;\n\nexport const loadServer: LoadServer = ({ isLocal }) => {\n const server = new McpServer({\n name: 'intlayer',\n version: packageJson.version,\n });\n\n if (isLocal) {\n try {\n loadCLITools(server);\n loadInstallSkillsTool(server);\n } catch (error) {\n console.error('Error loading CLI tools:', error);\n }\n }\n\n try {\n loadDocsTools(server);\n } catch (error) {\n console.error('Error loading docs tools:', error);\n }\n\n try {\n loadAPITools(server);\n } catch (error) {\n console.error('Error loading API tools:', error);\n }\n\n return server;\n};\n"],"mappings":";;;;;;;;;;;AAUA,MAAa,UAAkB,aAC3BA,UAAY,cAAc,OAAO,KAAK,IAAI,CAAC,GAC3C;AAEJ,MAAM,cAAmC,KAAK,MAC5C,aAAa,QAAQ,SAAS,wBAAwB,EAAE,OAAO,CAChE;AAID,MAAa,cAA0B,EAAE,cAAc;CACrD,MAAM,SAAS,IAAI,UAAU;EAC3B,MAAM;EACN,SAAS,YAAY;EACtB,CAAC;CAEF,IAAI,SACF,IAAI;EACF,aAAa,OAAO;EACpB,sBAAsB,OAAO;UACtB,OAAO;EACd,QAAQ,MAAM,4BAA4B,MAAM;;CAIpD,IAAI;EACF,cAAc,OAAO;UACd,OAAO;EACd,QAAQ,MAAM,6BAA6B,MAAM;;CAGnD,IAAI;EACF,aAAa,OAAO;UACb,OAAO;EACd,QAAQ,MAAM,4BAA4B,MAAM;;CAGlD,OAAO"}
1
+ {"version":3,"file":"server.mjs","names":["pathDirname"],"sources":["../../../src/server/server.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { dirname as pathDirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { isESModule } from '@intlayer/config/utils';\nimport z from 'zod';\nimport { loadAPITools } from '../tools/api';\nimport { loadCLITools } from '../tools/cli';\nimport { loadDocsTools } from '../tools/docs';\nimport { loadInstallSkillsTool } from '../tools/installSkills';\n\nexport const dirname: string = isESModule\n ? pathDirname(fileURLToPath(import.meta.url))\n : __dirname;\n\nconst packageJson: Record<string, any> = JSON.parse(\n readFileSync(resolve(dirname, '../../../package.json'), 'utf8')\n);\n\ntype ToolResult = {\n content: { type: string; text: string }[];\n isError?: boolean;\n};\n\ntype StoredTool = {\n name: string;\n description?: string;\n annotations?: Record<string, any>;\n inputSchema: Record<string, any>;\n handler: (params: any) => Promise<ToolResult>;\n};\n\nexport interface McpTransport {\n start(server: McpServer): Promise<void>;\n}\n\nexport class McpServer {\n private readonly _tools = new Map<string, StoredTool>();\n private readonly _info: { name: string; version: string };\n\n constructor(info: { name: string; version: string }) {\n this._info = info;\n }\n\n registerTool(\n name: string,\n config: {\n title?: string;\n description?: string;\n inputSchema?: Record<string, any>;\n annotations?: Record<string, any>;\n },\n handler: (params: any) => Promise<ToolResult>\n ): void {\n const shape = config.inputSchema ?? {};\n let inputSchema: Record<string, any>;\n try {\n inputSchema = z.toJSONSchema(z.object(shape)) as Record<string, any>;\n } catch {\n inputSchema = { type: 'object', properties: {} };\n }\n this._tools.set(name, {\n name,\n description: config.description,\n annotations: config.annotations,\n inputSchema,\n handler,\n });\n }\n\n async handleMessage(message: any): Promise<any> {\n const { id, method, params } = message;\n const isNotification = id === undefined;\n\n switch (method) {\n case 'initialize':\n return {\n jsonrpc: '2.0',\n id,\n result: {\n protocolVersion: '2024-11-05',\n capabilities: { tools: {} },\n serverInfo: this._info,\n },\n };\n\n case 'tools/list':\n return {\n jsonrpc: '2.0',\n id,\n result: {\n tools: Array.from(this._tools.values()).map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n ...(t.annotations && { annotations: t.annotations }),\n })),\n },\n };\n\n case 'tools/call': {\n const { name, arguments: args } = params ?? {};\n const tool = this._tools.get(name);\n if (!tool) {\n if (isNotification) return null;\n return {\n jsonrpc: '2.0',\n id,\n error: { code: -32601, message: `Tool not found: ${name}` },\n };\n }\n try {\n const result = await tool.handler(args ?? {});\n if (isNotification) return null;\n return { jsonrpc: '2.0', id, result };\n } catch (error) {\n if (isNotification) return null;\n return {\n jsonrpc: '2.0',\n id,\n error: {\n code: -32000,\n message: error instanceof Error ? error.message : String(error),\n },\n };\n }\n }\n\n case 'ping':\n if (isNotification) return null;\n return { jsonrpc: '2.0', id, result: {} };\n\n default:\n if (isNotification) return null;\n return {\n jsonrpc: '2.0',\n id,\n error: { code: -32601, message: `Method not found: ${method}` },\n };\n }\n }\n\n async connect(transport: McpTransport): Promise<void> {\n await transport.start(this);\n }\n}\n\ntype LoadServer = (options: { isLocal: boolean }) => McpServer;\n\nexport const loadServer: LoadServer = ({ isLocal }) => {\n const server = new McpServer({\n name: 'intlayer',\n version: packageJson.version,\n });\n\n if (isLocal) {\n try {\n loadCLITools(server);\n loadInstallSkillsTool(server);\n } catch (error) {\n console.error('Error loading CLI tools:', error);\n }\n }\n\n try {\n loadDocsTools(server);\n } catch (error) {\n console.error('Error loading docs tools:', error);\n }\n\n try {\n loadAPITools(server);\n } catch (error) {\n console.error('Error loading API tools:', error);\n }\n\n return server;\n};\n"],"mappings":";;;;;;;;;;;AAUA,MAAa,UAAkB,aAC3BA,UAAY,cAAc,OAAO,KAAK,IAAI,CAAC,GAC3C;AAEJ,MAAM,cAAmC,KAAK,MAC5C,aAAa,QAAQ,SAAS,wBAAwB,EAAE,OAAO,CAChE;AAmBD,IAAa,YAAb,MAAuB;CACrB,AAAiB,yBAAS,IAAI,KAAyB;CACvD,AAAiB;CAEjB,YAAY,MAAyC;EACnD,KAAK,QAAQ;;CAGf,aACE,MACA,QAMA,SACM;EACN,MAAM,QAAQ,OAAO,eAAe,EAAE;EACtC,IAAI;EACJ,IAAI;GACF,cAAc,EAAE,aAAa,EAAE,OAAO,MAAM,CAAC;UACvC;GACN,cAAc;IAAE,MAAM;IAAU,YAAY,EAAE;IAAE;;EAElD,KAAK,OAAO,IAAI,MAAM;GACpB;GACA,aAAa,OAAO;GACpB,aAAa,OAAO;GACpB;GACA;GACD,CAAC;;CAGJ,MAAM,cAAc,SAA4B;EAC9C,MAAM,EAAE,IAAI,QAAQ,WAAW;EAC/B,MAAM,iBAAiB,OAAO;EAE9B,QAAQ,QAAR;GACE,KAAK,cACH,OAAO;IACL,SAAS;IACT;IACA,QAAQ;KACN,iBAAiB;KACjB,cAAc,EAAE,OAAO,EAAE,EAAE;KAC3B,YAAY,KAAK;KAClB;IACF;GAEH,KAAK,cACH,OAAO;IACL,SAAS;IACT;IACA,QAAQ,EACN,OAAO,MAAM,KAAK,KAAK,OAAO,QAAQ,CAAC,CAAC,KAAK,OAAO;KAClD,MAAM,EAAE;KACR,aAAa,EAAE;KACf,aAAa,EAAE;KACf,GAAI,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa;KACpD,EAAE,EACJ;IACF;GAEH,KAAK,cAAc;IACjB,MAAM,EAAE,MAAM,WAAW,SAAS,UAAU,EAAE;IAC9C,MAAM,OAAO,KAAK,OAAO,IAAI,KAAK;IAClC,IAAI,CAAC,MAAM;KACT,IAAI,gBAAgB,OAAO;KAC3B,OAAO;MACL,SAAS;MACT;MACA,OAAO;OAAE,MAAM;OAAQ,SAAS,mBAAmB;OAAQ;MAC5D;;IAEH,IAAI;KACF,MAAM,SAAS,MAAM,KAAK,QAAQ,QAAQ,EAAE,CAAC;KAC7C,IAAI,gBAAgB,OAAO;KAC3B,OAAO;MAAE,SAAS;MAAO;MAAI;MAAQ;aAC9B,OAAO;KACd,IAAI,gBAAgB,OAAO;KAC3B,OAAO;MACL,SAAS;MACT;MACA,OAAO;OACL,MAAM;OACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;OAChE;MACF;;;GAIL,KAAK;IACH,IAAI,gBAAgB,OAAO;IAC3B,OAAO;KAAE,SAAS;KAAO;KAAI,QAAQ,EAAE;KAAE;GAE3C;IACE,IAAI,gBAAgB,OAAO;IAC3B,OAAO;KACL,SAAS;KACT;KACA,OAAO;MAAE,MAAM;MAAQ,SAAS,qBAAqB;MAAU;KAChE;;;CAIP,MAAM,QAAQ,WAAwC;EACpD,MAAM,UAAU,MAAM,KAAK;;;AAM/B,MAAa,cAA0B,EAAE,cAAc;CACrD,MAAM,SAAS,IAAI,UAAU;EAC3B,MAAM;EACN,SAAS,YAAY;EACtB,CAAC;CAEF,IAAI,SACF,IAAI;EACF,aAAa,OAAO;EACpB,sBAAsB,OAAO;UACtB,OAAO;EACd,QAAQ,MAAM,4BAA4B,MAAM;;CAIpD,IAAI;EACF,cAAc,OAAO;UACd,OAAO;EACd,QAAQ,MAAM,6BAA6B,MAAM;;CAGnD,IAAI;EACF,aAAa,OAAO;UACb,OAAO;EACd,QAAQ,MAAM,4BAA4B,MAAM;;CAGlD,OAAO"}
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { loadServer } from "./server.mjs";
3
3
  import { randomUUID } from "node:crypto";
4
- import { StreamableHTTPServerTransport } from "/Users/aymericpineau/Documents/intlayer_/node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/streamableHttp.js";
5
4
  import dotenv from "dotenv";
6
5
  import express from "express";
7
6
 
@@ -19,7 +18,7 @@ dotenv.config({
19
18
  });
20
19
  app.use((req, res, next) => {
21
20
  res.header("Access-Control-Allow-Origin", "*");
22
- res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
21
+ res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
23
22
  res.header("Access-Control-Allow-Headers", "Content-Type, mcp-session-id");
24
23
  if (req.method === "OPTIONS") {
25
24
  res.sendStatus(200);
@@ -29,40 +28,54 @@ app.use((req, res, next) => {
29
28
  });
30
29
  app.use(express.json());
31
30
  const router = express.Router();
32
- const transports = {};
31
+ const sessions = /* @__PURE__ */ new Map();
33
32
  router.post("/", async (req, res) => {
34
33
  const sessionId = req.headers["mcp-session-id"];
35
- let transport;
36
- if (sessionId && transports[sessionId]) transport = transports[sessionId];
37
- else if (!sessionId) {
38
- transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID() });
39
- transport.onclose = () => {
40
- if (transport.sessionId) delete transports[transport.sessionId];
41
- };
42
- await loadServer({ isLocal: false }).connect(transport);
34
+ let server;
35
+ let currentSessionId;
36
+ if (sessionId && sessions.has(sessionId)) {
37
+ server = sessions.get(sessionId);
38
+ currentSessionId = sessionId;
39
+ } else if (!sessionId) {
40
+ currentSessionId = randomUUID();
41
+ server = loadServer({ isLocal: false });
42
+ sessions.set(currentSessionId, server);
43
+ res.setHeader("mcp-session-id", currentSessionId);
43
44
  } else {
44
45
  res.status(400).send({ messages: "Bad session id." });
45
46
  return;
46
47
  }
47
- await transport.handleRequest(req, res, req.body);
48
- const newSessionId = transport.sessionId;
49
- if (newSessionId && !transports[newSessionId]) transports[newSessionId] = transport;
48
+ try {
49
+ const response = await server.handleMessage(req.body);
50
+ if (response !== null && response !== void 0) res.json(response);
51
+ else res.status(202).end();
52
+ } catch (error) {
53
+ res.status(500).json({
54
+ jsonrpc: "2.0",
55
+ id: req.body?.id ?? null,
56
+ error: {
57
+ code: -32e3,
58
+ message: "Internal server error"
59
+ }
60
+ });
61
+ }
50
62
  });
51
- router.get("/", async (req, res) => {
63
+ router.get("/", (req, res) => {
52
64
  const sessionId = req.headers["mcp-session-id"];
53
- if (!sessionId || !transports[sessionId]) {
65
+ if (!sessionId || !sessions.has(sessionId)) {
54
66
  res.status(400).send({ messages: "Bad session id." });
55
67
  return;
56
68
  }
57
- await transports[sessionId].handleRequest(req, res);
69
+ res.status(200).end();
58
70
  });
59
- router.delete("/", async (req, res) => {
71
+ router.delete("/", (req, res) => {
60
72
  const sessionId = req.headers["mcp-session-id"];
61
- if (!sessionId || !transports[sessionId]) {
73
+ if (!sessionId || !sessions.has(sessionId)) {
62
74
  res.status(400).send({ messages: "Bad session id." });
63
75
  return;
64
76
  }
65
- await transports[sessionId].handleRequest(req, res);
77
+ sessions.delete(sessionId);
78
+ res.status(200).end();
66
79
  });
67
80
  app.use("/", router);
68
81
  app.use("/health", (_req, res) => {
@@ -1 +1 @@
1
- {"version":3,"file":"sse.mjs","names":[],"sources":["../../../src/server/sse.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { randomUUID } from 'node:crypto';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport dotenv from 'dotenv';\nimport express, { type Request, type Response } from 'express';\nimport { loadServer } from './server';\n\nconst app = express();\nconst env = app.get('env');\n\ndotenv.config({\n path: [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env'],\n quiet: true,\n});\n\napp.use((req, res, next) => {\n res.header('Access-Control-Allow-Origin', '*');\n res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Content-Type, mcp-session-id');\n if (req.method === 'OPTIONS') {\n res.sendStatus(200);\n return;\n }\n next();\n});\n\napp.use(express.json());\nconst router = express.Router();\n\nconst transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};\n\nrouter.post('/', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n let transport: StreamableHTTPServerTransport;\n\n if (sessionId && transports[sessionId]) {\n transport = transports[sessionId];\n } else if (!sessionId) {\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n });\n transport.onclose = () => {\n if (transport.sessionId) {\n delete transports[transport.sessionId];\n }\n };\n const server = loadServer({ isLocal: false });\n await server.connect(transport);\n } else {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n\n await transport.handleRequest(req, res, req.body);\n\n const newSessionId = transport.sessionId;\n if (newSessionId && !transports[newSessionId]) {\n transports[newSessionId] = transport;\n }\n});\n\nrouter.get('/', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n\n await transports[sessionId].handleRequest(req, res);\n});\n\nrouter.delete('/', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n\n await transports[sessionId].handleRequest(req, res);\n});\n\napp.use('/', router);\napp.use('/health', (_req: Request, res: Response) => {\n res.send('OK');\n});\n\nconst PORT = process.env.PORT ?? 3000;\napp.listen(PORT, () => {\n console.info(`MCP Streamable HTTP Server listening on port ${PORT}`);\n});\n"],"mappings":";;;;;;;;AAQA,MAAM,MAAM,SAAS;AACrB,MAAM,MAAM,IAAI,IAAI,MAAM;AAE1B,OAAO,OAAO;CACZ,MAAM;EAAC,QAAQ,IAAI;EAAS,QAAQ;EAAO;EAAc;EAAO;CAChE,OAAO;CACR,CAAC;AAEF,IAAI,KAAK,KAAK,KAAK,SAAS;CAC1B,IAAI,OAAO,+BAA+B,IAAI;CAC9C,IAAI,OAAO,gCAAgC,qBAAqB;CAChE,IAAI,OAAO,gCAAgC,+BAA+B;CAC1E,IAAI,IAAI,WAAW,WAAW;EAC5B,IAAI,WAAW,IAAI;EACnB;;CAEF,MAAM;EACN;AAEF,IAAI,IAAI,QAAQ,MAAM,CAAC;AACvB,MAAM,SAAS,QAAQ,QAAQ;AAE/B,MAAM,aAAqE,EAAE;AAE7E,OAAO,KAAK,KAAK,OAAO,KAAc,QAAkB;CACtD,MAAM,YAAY,IAAI,QAAQ;CAE9B,IAAI;CAEJ,IAAI,aAAa,WAAW,YAC1B,YAAY,WAAW;MAClB,IAAI,CAAC,WAAW;EACrB,YAAY,IAAI,8BAA8B,EAC5C,0BAA0B,YAAY,EACvC,CAAC;EACF,UAAU,gBAAgB;GACxB,IAAI,UAAU,WACZ,OAAO,WAAW,UAAU;;EAIhC,MADe,WAAW,EAAE,SAAS,OAAO,CAChC,CAAC,QAAQ,UAAU;QAC1B;EACL,IAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;EACrD;;CAGF,MAAM,UAAU,cAAc,KAAK,KAAK,IAAI,KAAK;CAEjD,MAAM,eAAe,UAAU;CAC/B,IAAI,gBAAgB,CAAC,WAAW,eAC9B,WAAW,gBAAgB;EAE7B;AAEF,OAAO,IAAI,KAAK,OAAO,KAAc,QAAkB;CACrD,MAAM,YAAY,IAAI,QAAQ;CAE9B,IAAI,CAAC,aAAa,CAAC,WAAW,YAAY;EACxC,IAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;EACrD;;CAGF,MAAM,WAAW,WAAW,cAAc,KAAK,IAAI;EACnD;AAEF,OAAO,OAAO,KAAK,OAAO,KAAc,QAAkB;CACxD,MAAM,YAAY,IAAI,QAAQ;CAE9B,IAAI,CAAC,aAAa,CAAC,WAAW,YAAY;EACxC,IAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;EACrD;;CAGF,MAAM,WAAW,WAAW,cAAc,KAAK,IAAI;EACnD;AAEF,IAAI,IAAI,KAAK,OAAO;AACpB,IAAI,IAAI,YAAY,MAAe,QAAkB;CACnD,IAAI,KAAK,KAAK;EACd;AAEF,MAAM,OAAO,QAAQ,IAAI,QAAQ;AACjC,IAAI,OAAO,YAAY;CACrB,QAAQ,KAAK,gDAAgD,OAAO;EACpE"}
1
+ {"version":3,"file":"sse.mjs","names":[],"sources":["../../../src/server/sse.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { randomUUID } from 'node:crypto';\nimport dotenv from 'dotenv';\nimport express, { type Request, type Response } from 'express';\nimport { loadServer, type McpServer } from './server';\n\nconst app = express();\nconst env = app.get('env');\n\ndotenv.config({\n path: [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env'],\n quiet: true,\n});\n\napp.use((req, res, next) => {\n res.header('Access-Control-Allow-Origin', '*');\n res.header('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Content-Type, mcp-session-id');\n if (req.method === 'OPTIONS') {\n res.sendStatus(200);\n return;\n }\n next();\n});\n\napp.use(express.json());\nconst router = express.Router();\n\nconst sessions = new Map<string, McpServer>();\n\nrouter.post('/', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n let server: McpServer;\n let currentSessionId: string;\n\n if (sessionId && sessions.has(sessionId)) {\n server = sessions.get(sessionId)!;\n currentSessionId = sessionId;\n } else if (!sessionId) {\n currentSessionId = randomUUID();\n server = loadServer({ isLocal: false });\n sessions.set(currentSessionId, server);\n res.setHeader('mcp-session-id', currentSessionId);\n } else {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n\n try {\n const response = await server.handleMessage(req.body);\n if (response !== null && response !== undefined) {\n res.json(response);\n } else {\n res.status(202).end();\n }\n } catch (error) {\n res.status(500).json({\n jsonrpc: '2.0',\n id: req.body?.id ?? null,\n error: { code: -32000, message: 'Internal server error' },\n });\n }\n});\n\nrouter.get('/', (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n if (!sessionId || !sessions.has(sessionId)) {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n res.status(200).end();\n});\n\nrouter.delete('/', (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n if (!sessionId || !sessions.has(sessionId)) {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n sessions.delete(sessionId);\n res.status(200).end();\n});\n\napp.use('/', router);\napp.use('/health', (_req: Request, res: Response) => {\n res.send('OK');\n});\n\nconst PORT = process.env.PORT ?? 3000;\napp.listen(PORT, () => {\n console.info(`MCP Streamable HTTP Server listening on port ${PORT}`);\n});\n"],"mappings":";;;;;;;AAOA,MAAM,MAAM,SAAS;AACrB,MAAM,MAAM,IAAI,IAAI,MAAM;AAE1B,OAAO,OAAO;CACZ,MAAM;EAAC,QAAQ,IAAI;EAAS,QAAQ;EAAO;EAAc;EAAO;CAChE,OAAO;CACR,CAAC;AAEF,IAAI,KAAK,KAAK,KAAK,SAAS;CAC1B,IAAI,OAAO,+BAA+B,IAAI;CAC9C,IAAI,OAAO,gCAAgC,6BAA6B;CACxE,IAAI,OAAO,gCAAgC,+BAA+B;CAC1E,IAAI,IAAI,WAAW,WAAW;EAC5B,IAAI,WAAW,IAAI;EACnB;;CAEF,MAAM;EACN;AAEF,IAAI,IAAI,QAAQ,MAAM,CAAC;AACvB,MAAM,SAAS,QAAQ,QAAQ;AAE/B,MAAM,2BAAW,IAAI,KAAwB;AAE7C,OAAO,KAAK,KAAK,OAAO,KAAc,QAAkB;CACtD,MAAM,YAAY,IAAI,QAAQ;CAE9B,IAAI;CACJ,IAAI;CAEJ,IAAI,aAAa,SAAS,IAAI,UAAU,EAAE;EACxC,SAAS,SAAS,IAAI,UAAU;EAChC,mBAAmB;QACd,IAAI,CAAC,WAAW;EACrB,mBAAmB,YAAY;EAC/B,SAAS,WAAW,EAAE,SAAS,OAAO,CAAC;EACvC,SAAS,IAAI,kBAAkB,OAAO;EACtC,IAAI,UAAU,kBAAkB,iBAAiB;QAC5C;EACL,IAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;EACrD;;CAGF,IAAI;EACF,MAAM,WAAW,MAAM,OAAO,cAAc,IAAI,KAAK;EACrD,IAAI,aAAa,QAAQ,aAAa,QACpC,IAAI,KAAK,SAAS;OAElB,IAAI,OAAO,IAAI,CAAC,KAAK;UAEhB,OAAO;EACd,IAAI,OAAO,IAAI,CAAC,KAAK;GACnB,SAAS;GACT,IAAI,IAAI,MAAM,MAAM;GACpB,OAAO;IAAE,MAAM;IAAQ,SAAS;IAAyB;GAC1D,CAAC;;EAEJ;AAEF,OAAO,IAAI,MAAM,KAAc,QAAkB;CAC/C,MAAM,YAAY,IAAI,QAAQ;CAC9B,IAAI,CAAC,aAAa,CAAC,SAAS,IAAI,UAAU,EAAE;EAC1C,IAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;EACrD;;CAEF,IAAI,OAAO,IAAI,CAAC,KAAK;EACrB;AAEF,OAAO,OAAO,MAAM,KAAc,QAAkB;CAClD,MAAM,YAAY,IAAI,QAAQ;CAC9B,IAAI,CAAC,aAAa,CAAC,SAAS,IAAI,UAAU,EAAE;EAC1C,IAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;EACrD;;CAEF,SAAS,OAAO,UAAU;CAC1B,IAAI,OAAO,IAAI,CAAC,KAAK;EACrB;AAEF,IAAI,IAAI,KAAK,OAAO;AACpB,IAAI,IAAI,YAAY,MAAe,QAAkB;CACnD,IAAI,KAAK,KAAK;EACd;AAEF,MAAM,OAAO,QAAQ,IAAI,QAAQ;AACjC,IAAI,OAAO,YAAY;CACrB,QAAQ,KAAK,gDAAgD,OAAO;EACpE"}
@@ -1,13 +1,45 @@
1
1
  #!/usr/bin/env node
2
2
  import { loadServer } from "./server.mjs";
3
- import { StdioServerTransport } from "/Users/aymericpineau/Documents/intlayer_/node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js";
3
+ import * as readline from "node:readline";
4
4
 
5
5
  //#region src/server/stdio.ts
6
+ var StdioTransport = class {
7
+ async start(server) {
8
+ const rl = readline.createInterface({
9
+ input: process.stdin,
10
+ terminal: false
11
+ });
12
+ const send = (message) => {
13
+ process.stdout.write(`${JSON.stringify(message)}\n`);
14
+ };
15
+ rl.on("line", async (line) => {
16
+ const trimmed = line.trim();
17
+ if (!trimmed) return;
18
+ try {
19
+ const message = JSON.parse(trimmed);
20
+ const response = await server.handleMessage(message);
21
+ if (response !== null && response !== void 0) send(response);
22
+ } catch {
23
+ send({
24
+ jsonrpc: "2.0",
25
+ id: null,
26
+ error: {
27
+ code: -32700,
28
+ message: "Parse error"
29
+ }
30
+ });
31
+ }
32
+ });
33
+ console.error("Intlayer MCP Server running on stdio");
34
+ await new Promise((resolve) => {
35
+ rl.on("close", resolve);
36
+ });
37
+ }
38
+ };
6
39
  const server = loadServer({ isLocal: true });
7
40
  const main = async () => {
8
- const transport = new StdioServerTransport();
41
+ const transport = new StdioTransport();
9
42
  await server.connect(transport);
10
- console.error("Intlayer MCP Server running on stdio");
11
43
  };
12
44
  main().catch((error) => {
13
45
  console.error("Fatal error in main():", error);
@@ -1 +1 @@
1
- {"version":3,"file":"stdio.mjs","names":[],"sources":["../../../src/server/stdio.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { loadServer } from './server';\n\nconst server = loadServer({ isLocal: true });\n\nconst main = async () => {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n console.error('Intlayer MCP Server running on stdio');\n};\n\nmain().catch((error) => {\n console.error('Fatal error in main():', error);\n process.exit(1);\n});\n"],"mappings":";;;;;AAKA,MAAM,SAAS,WAAW,EAAE,SAAS,MAAM,CAAC;AAE5C,MAAM,OAAO,YAAY;CACvB,MAAM,YAAY,IAAI,sBAAsB;CAC5C,MAAM,OAAO,QAAQ,UAAU;CAE/B,QAAQ,MAAM,uCAAuC;;AAGvD,MAAM,CAAC,OAAO,UAAU;CACtB,QAAQ,MAAM,0BAA0B,MAAM;CAC9C,QAAQ,KAAK,EAAE;EACf"}
1
+ {"version":3,"file":"stdio.mjs","names":[],"sources":["../../../src/server/stdio.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as readline from 'node:readline';\nimport { loadServer, type McpServer, type McpTransport } from './server';\n\nclass StdioTransport implements McpTransport {\n async start(server: McpServer): Promise<void> {\n const rl = readline.createInterface({\n input: process.stdin,\n terminal: false,\n });\n\n const send = (message: any) => {\n process.stdout.write(`${JSON.stringify(message)}\\n`);\n };\n\n rl.on('line', async (line) => {\n const trimmed = line.trim();\n if (!trimmed) return;\n try {\n const message = JSON.parse(trimmed);\n const response = await server.handleMessage(message);\n if (response !== null && response !== undefined) {\n send(response);\n }\n } catch {\n send({\n jsonrpc: '2.0',\n id: null,\n error: { code: -32700, message: 'Parse error' },\n });\n }\n });\n\n console.error('Intlayer MCP Server running on stdio');\n\n await new Promise<void>((resolve) => {\n rl.on('close', resolve);\n });\n }\n}\n\nconst server = loadServer({ isLocal: true });\n\nconst main = async () => {\n const transport = new StdioTransport();\n await server.connect(transport);\n};\n\nmain().catch((error) => {\n console.error('Fatal error in main():', error);\n process.exit(1);\n});\n"],"mappings":";;;;;AAKA,IAAM,iBAAN,MAA6C;CAC3C,MAAM,MAAM,QAAkC;EAC5C,MAAM,KAAK,SAAS,gBAAgB;GAClC,OAAO,QAAQ;GACf,UAAU;GACX,CAAC;EAEF,MAAM,QAAQ,YAAiB;GAC7B,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,QAAQ,CAAC,IAAI;;EAGtD,GAAG,GAAG,QAAQ,OAAO,SAAS;GAC5B,MAAM,UAAU,KAAK,MAAM;GAC3B,IAAI,CAAC,SAAS;GACd,IAAI;IACF,MAAM,UAAU,KAAK,MAAM,QAAQ;IACnC,MAAM,WAAW,MAAM,OAAO,cAAc,QAAQ;IACpD,IAAI,aAAa,QAAQ,aAAa,QACpC,KAAK,SAAS;WAEV;IACN,KAAK;KACH,SAAS;KACT,IAAI;KACJ,OAAO;MAAE,MAAM;MAAQ,SAAS;MAAe;KAChD,CAAC;;IAEJ;EAEF,QAAQ,MAAM,uCAAuC;EAErD,MAAM,IAAI,SAAe,YAAY;GACnC,GAAG,GAAG,SAAS,QAAQ;IACvB;;;AAIN,MAAM,SAAS,WAAW,EAAE,SAAS,MAAM,CAAC;AAE5C,MAAM,OAAO,YAAY;CACvB,MAAM,YAAY,IAAI,gBAAgB;CACtC,MAAM,OAAO,QAAQ,UAAU;;AAGjC,MAAM,CAAC,OAAO,UAAU;CACtB,QAAQ,MAAM,0BAA0B,MAAM;CAC9C,QAAQ,KAAK,EAAE;EACf"}
@@ -1,6 +1,6 @@
1
1
  import z from "zod";
2
- import { getConfiguration } from "@intlayer/config";
3
2
  import { getIntlayerAPI } from "@intlayer/api";
3
+ import config from "@intlayer/config/built";
4
4
 
5
5
  //#region src/tools/api.ts
6
6
  const authSchema = {
@@ -8,7 +8,6 @@ const authSchema = {
8
8
  clientSecret: z.string().optional().describe("Intlayer OAuth2 client secret. Falls back to INTLAYER_CLIENT_SECRET env var.")
9
9
  };
10
10
  const getAPI = async (clientId, clientSecret) => {
11
- const config = getConfiguration();
12
11
  const resolvedClientId = clientId ?? config.editor.clientId;
13
12
  const resolvedClientSecret = clientSecret ?? config.editor.clientSecret;
14
13
  if (!resolvedClientId || !resolvedClientSecret) throw new Error("Intlayer credentials not found. Provide clientId/clientSecret or set INTLAYER_CLIENT_ID/INTLAYER_CLIENT_SECRET.");
@@ -77,7 +76,7 @@ const loadAPITools = (server) => {
77
76
  key: z.string().describe("Unique key for the dictionary"),
78
77
  title: z.string().optional().describe("Human-readable title"),
79
78
  description: z.string().optional().describe("Description of the dictionary"),
80
- content: z.record(z.unknown()).optional().describe("Initial content as JSON object")
79
+ content: z.record(z.string(), z.unknown()).optional().describe("Initial content as JSON object")
81
80
  },
82
81
  annotations: { destructiveHint: false }
83
82
  }, async ({ clientId, clientSecret, key, title, description, content }) => {
@@ -101,7 +100,7 @@ const loadAPITools = (server) => {
101
100
  key: z.string().optional().describe("New key for the dictionary"),
102
101
  title: z.string().optional().describe("New title"),
103
102
  description: z.string().optional().describe("New description"),
104
- content: z.record(z.unknown()).optional().describe("Updated content as JSON object")
103
+ content: z.record(z.string(), z.unknown()).optional().describe("Updated content as JSON object")
105
104
  },
106
105
  annotations: { destructiveHint: true }
107
106
  }, async ({ clientId, clientSecret, id, key, title, description, content }) => {
@@ -1 +1 @@
1
- {"version":3,"file":"api.mjs","names":[],"sources":["../../../src/tools/api.ts"],"sourcesContent":["import { getConfiguration } from '@intlayer/config';\nimport { getIntlayerAPI } from '@intlayer/api';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport z from 'zod';\n\ntype LoadAPITools = (server: McpServer) => void;\n\nconst authSchema = {\n clientId: z\n .string()\n .optional()\n .describe(\n 'Intlayer OAuth2 client ID (access key). Falls back to INTLAYER_CLIENT_ID env var.'\n ),\n clientSecret: z\n .string()\n .optional()\n .describe(\n 'Intlayer OAuth2 client secret. Falls back to INTLAYER_CLIENT_SECRET env var.'\n ),\n};\n\nconst getAPI = async (clientId?: string, clientSecret?: string) => {\n const config = getConfiguration();\n const resolvedClientId = clientId ?? config.editor.clientId;\n const resolvedClientSecret = clientSecret ?? config.editor.clientSecret;\n\n if (!resolvedClientId || !resolvedClientSecret) {\n throw new Error(\n 'Intlayer credentials not found. Provide clientId/clientSecret or set INTLAYER_CLIENT_ID/INTLAYER_CLIENT_SECRET.'\n );\n }\n\n const configWithCreds = {\n ...config,\n editor: { ...config.editor, clientId: resolvedClientId, clientSecret: resolvedClientSecret },\n };\n\n const tempAPI = getIntlayerAPI({}, configWithCreds);\n const tokenResult = await tempAPI.oAuth.getOAuth2AccessToken();\n const token = (tokenResult as any)?.data?.access_token as string | undefined;\n\n if (!token) {\n throw new Error('Failed to obtain OAuth2 access token. Check your credentials.');\n }\n\n return getIntlayerAPI(\n { headers: { Authorization: `Bearer ${token}` } },\n config\n );\n};\n\nconst ok = (data: unknown) => ({\n content: [{ type: 'text' as const, text: JSON.stringify(data, null, 2) }],\n});\n\nconst fail = (label: string, error: unknown) => ({\n content: [\n {\n type: 'text' as const,\n text: `${label} failed: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true as const,\n});\n\nexport const loadAPITools: LoadAPITools = (server) => {\n // ── Dictionaries ──────────────────────────────────────────────────────────\n\n server.registerTool(\n 'intlayer-dictionaries-list',\n {\n title: 'List Dictionaries',\n description:\n 'List all dictionaries for the selected project. Returns keys, IDs, and metadata.',\n inputSchema: {\n ...authSchema,\n page: z.number().optional().describe('Page number (1-based)'),\n pageSize: z.number().optional().describe('Items per page'),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ clientId, clientSecret, page, pageSize }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.dictionary.getDictionaries({ page, pageSize } as any);\n return ok(result);\n } catch (error) {\n return fail('List dictionaries', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-dictionary-get',\n {\n title: 'Get Dictionary',\n description: 'Get a dictionary by its key, including its full content.',\n inputSchema: {\n ...authSchema,\n dictionaryKey: z.string().describe('The dictionary key'),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ clientId, clientSecret, dictionaryKey }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.dictionary.getDictionary(dictionaryKey);\n return ok(result);\n } catch (error) {\n return fail('Get dictionary', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-dictionary-create',\n {\n title: 'Create Dictionary',\n description: 'Create a new dictionary in the selected project.',\n inputSchema: {\n ...authSchema,\n key: z.string().describe('Unique key for the dictionary'),\n title: z.string().optional().describe('Human-readable title'),\n description: z.string().optional().describe('Description of the dictionary'),\n content: z.record(z.unknown()).optional().describe('Initial content as JSON object'),\n },\n annotations: { destructiveHint: false },\n },\n async ({ clientId, clientSecret, key, title, description, content }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.dictionary.addDictionary({ key, title, description, content } as any);\n return ok(result);\n } catch (error) {\n return fail('Create dictionary', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-dictionary-update',\n {\n title: 'Update Dictionary',\n description: 'Update an existing dictionary content or metadata.',\n inputSchema: {\n ...authSchema,\n id: z.string().describe('Dictionary ID'),\n key: z.string().optional().describe('New key for the dictionary'),\n title: z.string().optional().describe('New title'),\n description: z.string().optional().describe('New description'),\n content: z.record(z.unknown()).optional().describe('Updated content as JSON object'),\n },\n annotations: { destructiveHint: true },\n },\n async ({ clientId, clientSecret, id, key, title, description, content }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.dictionary.updateDictionary({ id, key, title, description, content } as any);\n return ok(result);\n } catch (error) {\n return fail('Update dictionary', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-dictionary-delete',\n {\n title: 'Delete Dictionary',\n description: 'Delete a dictionary by its ID. This action is irreversible.',\n inputSchema: {\n ...authSchema,\n dictionaryId: z.string().describe('Dictionary ID to delete'),\n },\n annotations: { destructiveHint: true },\n },\n async ({ clientId, clientSecret, dictionaryId }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.dictionary.deleteDictionary(dictionaryId);\n return ok(result);\n } catch (error) {\n return fail('Delete dictionary', error);\n }\n }\n );\n\n // ── Tags ──────────────────────────────────────────────────────────────────\n\n server.registerTool(\n 'intlayer-tags-list',\n {\n title: 'List Tags',\n description: 'List all tags for the selected organization.',\n inputSchema: {\n ...authSchema,\n page: z.number().optional().describe('Page number (1-based)'),\n pageSize: z.number().optional().describe('Items per page'),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ clientId, clientSecret, page, pageSize }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.tag.getTags({ page, pageSize } as any);\n return ok(result);\n } catch (error) {\n return fail('List tags', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-tag-create',\n {\n title: 'Create Tag',\n description:\n 'Create a new tag in the organization. Tags can be used to group dictionaries and provide AI context.',\n inputSchema: {\n ...authSchema,\n key: z.string().describe('Unique tag key'),\n name: z.string().optional().describe('Display name for the tag'),\n description: z.string().optional().describe('Description of the tag'),\n color: z.string().optional().describe('Tag color (hex code)'),\n instructions: z.string().optional().describe('AI instructions to apply when this tag is used'),\n },\n annotations: { destructiveHint: false },\n },\n async ({ clientId, clientSecret, key, name, description, color, instructions }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.tag.addTag({ key, name, description, color, instructions } as any);\n return ok(result);\n } catch (error) {\n return fail('Create tag', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-tag-update',\n {\n title: 'Update Tag',\n description: 'Update an existing tag.',\n inputSchema: {\n ...authSchema,\n tagId: z.string().describe('Tag ID to update'),\n key: z.string().optional().describe('New key'),\n name: z.string().optional().describe('New display name'),\n description: z.string().optional().describe('New description'),\n color: z.string().optional().describe('New color (hex code)'),\n instructions: z.string().optional().describe('New AI instructions'),\n },\n annotations: { destructiveHint: true },\n },\n async ({ clientId, clientSecret, tagId, key, name, description, color, instructions }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.tag.updateTag(tagId, { key, name, description, color, instructions } as any);\n return ok(result);\n } catch (error) {\n return fail('Update tag', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-tag-delete',\n {\n title: 'Delete Tag',\n description: 'Delete a tag by its ID.',\n inputSchema: {\n ...authSchema,\n tagId: z.string().describe('Tag ID to delete'),\n },\n annotations: { destructiveHint: true },\n },\n async ({ clientId, clientSecret, tagId }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.tag.deleteTag(tagId);\n return ok(result);\n } catch (error) {\n return fail('Delete tag', error);\n }\n }\n );\n\n // ── Organizations ─────────────────────────────────────────────────────────\n\n server.registerTool(\n 'intlayer-organizations-list',\n {\n title: 'List Organizations',\n description: 'List all organizations the authenticated user belongs to.',\n inputSchema: {\n ...authSchema,\n page: z.number().optional().describe('Page number (1-based)'),\n pageSize: z.number().optional().describe('Items per page'),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ clientId, clientSecret, page, pageSize }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.organization.getOrganizations({ page, pageSize } as any);\n return ok(result);\n } catch (error) {\n return fail('List organizations', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-organization-select',\n {\n title: 'Select Organization',\n description:\n 'Select an organization as the current active organization. Required before accessing organization-specific resources.',\n inputSchema: {\n ...authSchema,\n organizationId: z.string().describe('Organization ID to select'),\n },\n annotations: { destructiveHint: false },\n },\n async ({ clientId, clientSecret, organizationId }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.organization.selectOrganization(organizationId);\n return ok(result);\n } catch (error) {\n return fail('Select organization', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-organization-update',\n {\n title: 'Update Organization',\n description: 'Update the selected organization name or settings.',\n inputSchema: {\n ...authSchema,\n name: z.string().optional().describe('New organization name'),\n customInstructions: z.string().optional().describe('Custom AI instructions for this organization'),\n },\n annotations: { destructiveHint: true },\n },\n async ({ clientId, clientSecret, name, customInstructions }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.organization.updateOrganization({ name, customInstructions } as any);\n return ok(result);\n } catch (error) {\n return fail('Update organization', error);\n }\n }\n );\n\n // ── Projects ──────────────────────────────────────────────────────────────\n\n server.registerTool(\n 'intlayer-cms-projects-list',\n {\n title: 'List CMS Projects',\n description:\n 'List all Intlayer CMS projects for the selected organization. These are server-side projects, not local project directories.',\n inputSchema: {\n ...authSchema,\n page: z.number().optional().describe('Page number (1-based)'),\n pageSize: z.number().optional().describe('Items per page'),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ clientId, clientSecret, page, pageSize }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.project.getProjects({ page, pageSize } as any);\n return ok(result);\n } catch (error) {\n return fail('List CMS projects', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-cms-project-select',\n {\n title: 'Select CMS Project',\n description:\n 'Select a CMS project as the current active project. Required before accessing project-specific dictionaries.',\n inputSchema: {\n ...authSchema,\n projectId: z.string().describe('Project ID to select'),\n },\n annotations: { destructiveHint: false },\n },\n async ({ clientId, clientSecret, projectId }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.project.selectProject(projectId);\n return ok(result);\n } catch (error) {\n return fail('Select CMS project', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-cms-project-create',\n {\n title: 'Create CMS Project',\n description: 'Create a new CMS project in the selected organization.',\n inputSchema: {\n ...authSchema,\n name: z.string().describe('Project name'),\n },\n annotations: { destructiveHint: false },\n },\n async ({ clientId, clientSecret, name }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.project.addProject({ name } as any);\n return ok(result);\n } catch (error) {\n return fail('Create CMS project', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-cms-project-update',\n {\n title: 'Update CMS Project',\n description: 'Update the selected CMS project settings.',\n inputSchema: {\n ...authSchema,\n name: z.string().optional().describe('New project name'),\n },\n annotations: { destructiveHint: true },\n },\n async ({ clientId, clientSecret, name }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.project.updateProject({ name } as any);\n return ok(result);\n } catch (error) {\n return fail('Update CMS project', error);\n }\n }\n );\n};\n"],"mappings":";;;;;AAOA,MAAM,aAAa;CACjB,UAAU,EACP,QAAQ,CACR,UAAU,CACV,SACC,oFACD;CACH,cAAc,EACX,QAAQ,CACR,UAAU,CACV,SACC,+EACD;CACJ;AAED,MAAM,SAAS,OAAO,UAAmB,iBAA0B;CACjE,MAAM,SAAS,kBAAkB;CACjC,MAAM,mBAAmB,YAAY,OAAO,OAAO;CACnD,MAAM,uBAAuB,gBAAgB,OAAO,OAAO;CAE3D,IAAI,CAAC,oBAAoB,CAAC,sBACxB,MAAM,IAAI,MACR,kHACD;CAUH,MAAM,SAAS,MAFC,eAAe,EAAE,EAAE;EAJjC,GAAG;EACH,QAAQ;GAAE,GAAG,OAAO;GAAQ,UAAU;GAAkB,cAAc;GAAsB;EAG5C,CACjB,CAAC,MAAM,sBAAsB,GAC1B,MAAM;CAE1C,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,gEAAgE;CAGlF,OAAO,eACL,EAAE,SAAS,EAAE,eAAe,UAAU,SAAS,EAAE,EACjD,OACD;;AAGH,MAAM,MAAM,UAAmB,EAC7B,SAAS,CAAC;CAAE,MAAM;CAAiB,MAAM,KAAK,UAAU,MAAM,MAAM,EAAE;CAAE,CAAC,EAC1E;AAED,MAAM,QAAQ,OAAe,WAAoB;CAC/C,SAAS,CACP;EACE,MAAM;EACN,MAAM,GAAG,MAAM,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;EACjF,CACF;CACD,SAAS;CACV;AAED,MAAa,gBAA8B,WAAW;CAGpD,OAAO,aACL,8BACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,GAAG;GACH,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,wBAAwB;GAC7D,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,iBAAiB;GAC3D;EACD,aAAa,EAAE,cAAc,MAAM;EACpC,EACD,OAAO,EAAE,UAAU,cAAc,MAAM,eAAe;EACpD,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,WAAW,gBAAgB;IAAE;IAAM;IAAU,CAAQ,CAC7D;WACV,OAAO;GACd,OAAO,KAAK,qBAAqB,MAAM;;GAG5C;CAED,OAAO,aACL,2BACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,GAAG;GACH,eAAe,EAAE,QAAQ,CAAC,SAAS,qBAAqB;GACzD;EACD,aAAa,EAAE,cAAc,MAAM;EACpC,EACD,OAAO,EAAE,UAAU,cAAc,oBAAoB;EACnD,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,WAAW,cAAc,cAAc,CAC/C;WACV,OAAO;GACd,OAAO,KAAK,kBAAkB,MAAM;;GAGzC;CAED,OAAO,aACL,8BACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,GAAG;GACH,KAAK,EAAE,QAAQ,CAAC,SAAS,gCAAgC;GACzD,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,uBAAuB;GAC7D,aAAa,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,gCAAgC;GAC5E,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,UAAU,CAAC,SAAS,iCAAiC;GACrF;EACD,aAAa,EAAE,iBAAiB,OAAO;EACxC,EACD,OAAO,EAAE,UAAU,cAAc,KAAK,OAAO,aAAa,cAAc;EACtE,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,WAAW,cAAc;IAAE;IAAK;IAAO;IAAa;IAAS,CAAQ,CAC7E;WACV,OAAO;GACd,OAAO,KAAK,qBAAqB,MAAM;;GAG5C;CAED,OAAO,aACL,8BACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,GAAG;GACH,IAAI,EAAE,QAAQ,CAAC,SAAS,gBAAgB;GACxC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,6BAA6B;GACjE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,YAAY;GAClD,aAAa,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,kBAAkB;GAC9D,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,UAAU,CAAC,SAAS,iCAAiC;GACrF;EACD,aAAa,EAAE,iBAAiB,MAAM;EACvC,EACD,OAAO,EAAE,UAAU,cAAc,IAAI,KAAK,OAAO,aAAa,cAAc;EAC1E,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,WAAW,iBAAiB;IAAE;IAAI;IAAK;IAAO;IAAa;IAAS,CAAQ,CACpF;WACV,OAAO;GACd,OAAO,KAAK,qBAAqB,MAAM;;GAG5C;CAED,OAAO,aACL,8BACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,GAAG;GACH,cAAc,EAAE,QAAQ,CAAC,SAAS,0BAA0B;GAC7D;EACD,aAAa,EAAE,iBAAiB,MAAM;EACvC,EACD,OAAO,EAAE,UAAU,cAAc,mBAAmB;EAClD,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,WAAW,iBAAiB,aAAa,CACjD;WACV,OAAO;GACd,OAAO,KAAK,qBAAqB,MAAM;;GAG5C;CAID,OAAO,aACL,sBACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,GAAG;GACH,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,wBAAwB;GAC7D,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,iBAAiB;GAC3D;EACD,aAAa,EAAE,cAAc,MAAM;EACpC,EACD,OAAO,EAAE,UAAU,cAAc,MAAM,eAAe;EACpD,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,IAAI,QAAQ;IAAE;IAAM;IAAU,CAAQ,CAC9C;WACV,OAAO;GACd,OAAO,KAAK,aAAa,MAAM;;GAGpC;CAED,OAAO,aACL,uBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,GAAG;GACH,KAAK,EAAE,QAAQ,CAAC,SAAS,iBAAiB;GAC1C,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,2BAA2B;GAChE,aAAa,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,yBAAyB;GACrE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,uBAAuB;GAC7D,cAAc,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,iDAAiD;GAC/F;EACD,aAAa,EAAE,iBAAiB,OAAO;EACxC,EACD,OAAO,EAAE,UAAU,cAAc,KAAK,MAAM,aAAa,OAAO,mBAAmB;EACjF,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,IAAI,OAAO;IAAE;IAAK;IAAM;IAAa;IAAO;IAAc,CAAQ,CAC1E;WACV,OAAO;GACd,OAAO,KAAK,cAAc,MAAM;;GAGrC;CAED,OAAO,aACL,uBACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,GAAG;GACH,OAAO,EAAE,QAAQ,CAAC,SAAS,mBAAmB;GAC9C,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,UAAU;GAC9C,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,mBAAmB;GACxD,aAAa,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,kBAAkB;GAC9D,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,uBAAuB;GAC7D,cAAc,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,sBAAsB;GACpE;EACD,aAAa,EAAE,iBAAiB,MAAM;EACvC,EACD,OAAO,EAAE,UAAU,cAAc,OAAO,KAAK,MAAM,aAAa,OAAO,mBAAmB;EACxF,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,IAAI,UAAU,OAAO;IAAE;IAAK;IAAM;IAAa;IAAO;IAAc,CAAQ,CACpF;WACV,OAAO;GACd,OAAO,KAAK,cAAc,MAAM;;GAGrC;CAED,OAAO,aACL,uBACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,GAAG;GACH,OAAO,EAAE,QAAQ,CAAC,SAAS,mBAAmB;GAC/C;EACD,aAAa,EAAE,iBAAiB,MAAM;EACvC,EACD,OAAO,EAAE,UAAU,cAAc,YAAY;EAC3C,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,IAAI,UAAU,MAAM,CAC5B;WACV,OAAO;GACd,OAAO,KAAK,cAAc,MAAM;;GAGrC;CAID,OAAO,aACL,+BACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,GAAG;GACH,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,wBAAwB;GAC7D,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,iBAAiB;GAC3D;EACD,aAAa,EAAE,cAAc,MAAM;EACpC,EACD,OAAO,EAAE,UAAU,cAAc,MAAM,eAAe;EACpD,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,aAAa,iBAAiB;IAAE;IAAM;IAAU,CAAQ,CAChE;WACV,OAAO;GACd,OAAO,KAAK,sBAAsB,MAAM;;GAG7C;CAED,OAAO,aACL,gCACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,GAAG;GACH,gBAAgB,EAAE,QAAQ,CAAC,SAAS,4BAA4B;GACjE;EACD,aAAa,EAAE,iBAAiB,OAAO;EACxC,EACD,OAAO,EAAE,UAAU,cAAc,qBAAqB;EACpD,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,aAAa,mBAAmB,eAAe,CACvD;WACV,OAAO;GACd,OAAO,KAAK,uBAAuB,MAAM;;GAG9C;CAED,OAAO,aACL,gCACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,GAAG;GACH,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,wBAAwB;GAC7D,oBAAoB,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,+CAA+C;GACnG;EACD,aAAa,EAAE,iBAAiB,MAAM;EACvC,EACD,OAAO,EAAE,UAAU,cAAc,MAAM,yBAAyB;EAC9D,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,aAAa,mBAAmB;IAAE;IAAM;IAAoB,CAAQ,CAC5E;WACV,OAAO;GACd,OAAO,KAAK,uBAAuB,MAAM;;GAG9C;CAID,OAAO,aACL,8BACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,GAAG;GACH,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,wBAAwB;GAC7D,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,iBAAiB;GAC3D;EACD,aAAa,EAAE,cAAc,MAAM;EACpC,EACD,OAAO,EAAE,UAAU,cAAc,MAAM,eAAe;EACpD,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,QAAQ,YAAY;IAAE;IAAM;IAAU,CAAQ,CACtD;WACV,OAAO;GACd,OAAO,KAAK,qBAAqB,MAAM;;GAG5C;CAED,OAAO,aACL,+BACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,GAAG;GACH,WAAW,EAAE,QAAQ,CAAC,SAAS,uBAAuB;GACvD;EACD,aAAa,EAAE,iBAAiB,OAAO;EACxC,EACD,OAAO,EAAE,UAAU,cAAc,gBAAgB;EAC/C,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,QAAQ,cAAc,UAAU,CACxC;WACV,OAAO;GACd,OAAO,KAAK,sBAAsB,MAAM;;GAG7C;CAED,OAAO,aACL,+BACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,GAAG;GACH,MAAM,EAAE,QAAQ,CAAC,SAAS,eAAe;GAC1C;EACD,aAAa,EAAE,iBAAiB,OAAO;EACxC,EACD,OAAO,EAAE,UAAU,cAAc,WAAW;EAC1C,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,QAAQ,WAAW,EAAE,MAAM,CAAQ,CAC3C;WACV,OAAO;GACd,OAAO,KAAK,sBAAsB,MAAM;;GAG7C;CAED,OAAO,aACL,+BACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,GAAG;GACH,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,mBAAmB;GACzD;EACD,aAAa,EAAE,iBAAiB,MAAM;EACvC,EACD,OAAO,EAAE,UAAU,cAAc,WAAW;EAC1C,IAAI;GAGF,OAAO,GAAG,OADW,MADH,OAAO,UAAU,aAAa,EACvB,QAAQ,cAAc,EAAE,MAAM,CAAQ,CAC9C;WACV,OAAO;GACd,OAAO,KAAK,sBAAsB,MAAM;;GAG7C"}
1
+ {"version":3,"file":"api.mjs","names":[],"sources":["../../../src/tools/api.ts"],"sourcesContent":["import { getIntlayerAPI } from '@intlayer/api';\nimport { default as config } from '@intlayer/config/built';\nimport z from 'zod';\nimport type { McpServer } from './docs';\n\ntype LoadAPITools = (server: McpServer) => void;\n\nconst authSchema = {\n clientId: z\n .string()\n .optional()\n .describe(\n 'Intlayer OAuth2 client ID (access key). Falls back to INTLAYER_CLIENT_ID env var.'\n ),\n clientSecret: z\n .string()\n .optional()\n .describe(\n 'Intlayer OAuth2 client secret. Falls back to INTLAYER_CLIENT_SECRET env var.'\n ),\n};\n\nconst getAPI = async (clientId?: string, clientSecret?: string) => {\n const resolvedClientId = clientId ?? config.editor.clientId;\n const resolvedClientSecret = clientSecret ?? config.editor.clientSecret;\n\n if (!resolvedClientId || !resolvedClientSecret) {\n throw new Error(\n 'Intlayer credentials not found. Provide clientId/clientSecret or set INTLAYER_CLIENT_ID/INTLAYER_CLIENT_SECRET.'\n );\n }\n\n const configWithCreds = {\n ...config,\n editor: {\n ...config.editor,\n clientId: resolvedClientId,\n clientSecret: resolvedClientSecret,\n },\n };\n\n const tempAPI = getIntlayerAPI({}, configWithCreds);\n const tokenResult = await tempAPI.oAuth.getOAuth2AccessToken();\n const token = (tokenResult as any)?.data?.access_token as string | undefined;\n\n if (!token) {\n throw new Error(\n 'Failed to obtain OAuth2 access token. Check your credentials.'\n );\n }\n\n return getIntlayerAPI(\n { headers: { Authorization: `Bearer ${token}` } },\n config\n );\n};\n\nconst ok = (data: unknown) => ({\n content: [{ type: 'text' as const, text: JSON.stringify(data, null, 2) }],\n});\n\nconst fail = (label: string, error: unknown) => ({\n content: [\n {\n type: 'text' as const,\n text: `${label} failed: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true as const,\n});\n\nexport const loadAPITools: LoadAPITools = (server) => {\n // ── Dictionaries ──────────────────────────────────────────────────────────\n\n server.registerTool(\n 'intlayer-dictionaries-list',\n {\n title: 'List Dictionaries',\n description:\n 'List all dictionaries for the selected project. Returns keys, IDs, and metadata.',\n inputSchema: {\n ...authSchema,\n page: z.number().optional().describe('Page number (1-based)'),\n pageSize: z.number().optional().describe('Items per page'),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ clientId, clientSecret, page, pageSize }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.dictionary.getDictionaries({\n page,\n pageSize,\n });\n return ok(result);\n } catch (error) {\n return fail('List dictionaries', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-dictionary-get',\n {\n title: 'Get Dictionary',\n description: 'Get a dictionary by its key, including its full content.',\n inputSchema: {\n ...authSchema,\n dictionaryKey: z.string().describe('The dictionary key'),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ clientId, clientSecret, dictionaryKey }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.dictionary.getDictionary(dictionaryKey);\n return ok(result);\n } catch (error) {\n return fail('Get dictionary', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-dictionary-create',\n {\n title: 'Create Dictionary',\n description: 'Create a new dictionary in the selected project.',\n inputSchema: {\n ...authSchema,\n key: z.string().describe('Unique key for the dictionary'),\n title: z.string().optional().describe('Human-readable title'),\n description: z\n .string()\n .optional()\n .describe('Description of the dictionary'),\n content: z\n .record(z.string(), z.unknown())\n .optional()\n .describe('Initial content as JSON object'),\n },\n annotations: { destructiveHint: false },\n },\n async ({ clientId, clientSecret, key, title, description, content }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.dictionary.addDictionary({\n key,\n title,\n description,\n content,\n });\n return ok(result);\n } catch (error) {\n return fail('Create dictionary', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-dictionary-update',\n {\n title: 'Update Dictionary',\n description: 'Update an existing dictionary content or metadata.',\n inputSchema: {\n ...authSchema,\n id: z.string().describe('Dictionary ID'),\n key: z.string().optional().describe('New key for the dictionary'),\n title: z.string().optional().describe('New title'),\n description: z.string().optional().describe('New description'),\n content: z\n .record(z.string(), z.unknown())\n .optional()\n .describe('Updated content as JSON object'),\n },\n annotations: { destructiveHint: true },\n },\n async ({\n clientId,\n clientSecret,\n id,\n key,\n title,\n description,\n content,\n }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.dictionary.updateDictionary({\n id,\n key,\n title,\n description,\n content,\n });\n return ok(result);\n } catch (error) {\n return fail('Update dictionary', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-dictionary-delete',\n {\n title: 'Delete Dictionary',\n description:\n 'Delete a dictionary by its ID. This action is irreversible.',\n inputSchema: {\n ...authSchema,\n dictionaryId: z.string().describe('Dictionary ID to delete'),\n },\n annotations: { destructiveHint: true },\n },\n async ({ clientId, clientSecret, dictionaryId }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.dictionary.deleteDictionary(dictionaryId);\n return ok(result);\n } catch (error) {\n return fail('Delete dictionary', error);\n }\n }\n );\n\n // ── Tags ──────────────────────────────────────────────────────────────────\n\n server.registerTool(\n 'intlayer-tags-list',\n {\n title: 'List Tags',\n description: 'List all tags for the selected organization.',\n inputSchema: {\n ...authSchema,\n page: z.number().optional().describe('Page number (1-based)'),\n pageSize: z.number().optional().describe('Items per page'),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ clientId, clientSecret, page, pageSize }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.tag.getTags({ page, pageSize });\n return ok(result);\n } catch (error) {\n return fail('List tags', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-tag-create',\n {\n title: 'Create Tag',\n description:\n 'Create a new tag in the organization. Tags can be used to group dictionaries and provide AI context.',\n inputSchema: {\n ...authSchema,\n key: z.string().describe('Unique tag key'),\n name: z.string().optional().describe('Display name for the tag'),\n description: z.string().optional().describe('Description of the tag'),\n color: z.string().optional().describe('Tag color (hex code)'),\n instructions: z\n .string()\n .optional()\n .describe('AI instructions to apply when this tag is used'),\n },\n annotations: { destructiveHint: false },\n },\n async ({\n clientId,\n clientSecret,\n key,\n name,\n description,\n color,\n instructions,\n }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.tag.addTag({\n key,\n name,\n description,\n color,\n instructions,\n });\n return ok(result);\n } catch (error) {\n return fail('Create tag', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-tag-update',\n {\n title: 'Update Tag',\n description: 'Update an existing tag.',\n inputSchema: {\n ...authSchema,\n tagId: z.string().describe('Tag ID to update'),\n key: z.string().optional().describe('New key'),\n name: z.string().optional().describe('New display name'),\n description: z.string().optional().describe('New description'),\n color: z.string().optional().describe('New color (hex code)'),\n instructions: z.string().optional().describe('New AI instructions'),\n },\n annotations: { destructiveHint: true },\n },\n async ({\n clientId,\n clientSecret,\n tagId,\n key,\n name,\n description,\n color,\n instructions,\n }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.tag.updateTag(tagId, {\n key,\n name,\n description,\n color,\n instructions,\n });\n return ok(result);\n } catch (error) {\n return fail('Update tag', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-tag-delete',\n {\n title: 'Delete Tag',\n description: 'Delete a tag by its ID.',\n inputSchema: {\n ...authSchema,\n tagId: z.string().describe('Tag ID to delete'),\n },\n annotations: { destructiveHint: true },\n },\n async ({ clientId, clientSecret, tagId }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.tag.deleteTag(tagId);\n return ok(result);\n } catch (error) {\n return fail('Delete tag', error);\n }\n }\n );\n\n // ── Organizations ─────────────────────────────────────────────────────────\n\n server.registerTool(\n 'intlayer-organizations-list',\n {\n title: 'List Organizations',\n description: 'List all organizations the authenticated user belongs to.',\n inputSchema: {\n ...authSchema,\n page: z.number().optional().describe('Page number (1-based)'),\n pageSize: z.number().optional().describe('Items per page'),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ clientId, clientSecret, page, pageSize }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.organization.getOrganizations({\n page,\n pageSize,\n });\n return ok(result);\n } catch (error) {\n return fail('List organizations', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-organization-select',\n {\n title: 'Select Organization',\n description:\n 'Select an organization as the current active organization. Required before accessing organization-specific resources.',\n inputSchema: {\n ...authSchema,\n organizationId: z.string().describe('Organization ID to select'),\n },\n annotations: { destructiveHint: false },\n },\n async ({ clientId, clientSecret, organizationId }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result =\n await api.organization.selectOrganization(organizationId);\n return ok(result);\n } catch (error) {\n return fail('Select organization', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-organization-update',\n {\n title: 'Update Organization',\n description: 'Update the selected organization name or settings.',\n inputSchema: {\n ...authSchema,\n name: z.string().optional().describe('New organization name'),\n customInstructions: z\n .string()\n .optional()\n .describe('Custom AI instructions for this organization'),\n },\n annotations: { destructiveHint: true },\n },\n async ({ clientId, clientSecret, name, customInstructions }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.organization.updateOrganization({\n name,\n customInstructions,\n });\n return ok(result);\n } catch (error) {\n return fail('Update organization', error);\n }\n }\n );\n\n // ── Projects ──────────────────────────────────────────────────────────────\n\n server.registerTool(\n 'intlayer-cms-projects-list',\n {\n title: 'List CMS Projects',\n description:\n 'List all Intlayer CMS projects for the selected organization. These are server-side projects, not local project directories.',\n inputSchema: {\n ...authSchema,\n page: z.number().optional().describe('Page number (1-based)'),\n pageSize: z.number().optional().describe('Items per page'),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ clientId, clientSecret, page, pageSize }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.project.getProjects({ page, pageSize });\n return ok(result);\n } catch (error) {\n return fail('List CMS projects', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-cms-project-select',\n {\n title: 'Select CMS Project',\n description:\n 'Select a CMS project as the current active project. Required before accessing project-specific dictionaries.',\n inputSchema: {\n ...authSchema,\n projectId: z.string().describe('Project ID to select'),\n },\n annotations: { destructiveHint: false },\n },\n async ({ clientId, clientSecret, projectId }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.project.selectProject(projectId);\n return ok(result);\n } catch (error) {\n return fail('Select CMS project', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-cms-project-create',\n {\n title: 'Create CMS Project',\n description: 'Create a new CMS project in the selected organization.',\n inputSchema: {\n ...authSchema,\n name: z.string().describe('Project name'),\n },\n annotations: { destructiveHint: false },\n },\n async ({ clientId, clientSecret, name }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.project.addProject({ name });\n return ok(result);\n } catch (error) {\n return fail('Create CMS project', error);\n }\n }\n );\n\n server.registerTool(\n 'intlayer-cms-project-update',\n {\n title: 'Update CMS Project',\n description: 'Update the selected CMS project settings.',\n inputSchema: {\n ...authSchema,\n name: z.string().optional().describe('New project name'),\n },\n annotations: { destructiveHint: true },\n },\n async ({ clientId, clientSecret, name }) => {\n try {\n const api = await getAPI(clientId, clientSecret);\n const result = await api.project.updateProject({ name });\n return ok(result);\n } catch (error) {\n return fail('Update CMS project', error);\n }\n }\n );\n};\n"],"mappings":"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"}
@@ -5,6 +5,30 @@ import { ALL_LOCALES } from "@intlayer/types/allLocales";
5
5
  import z from "zod";
6
6
 
7
7
  //#region src/tools/cli.ts
8
+ const configOptionsSchema = z.object({
9
+ baseDir: z.string().optional().describe("Base directory for the project"),
10
+ env: z.string().optional().describe("Environment name"),
11
+ envFile: z.string().optional().describe("Path to the environment file"),
12
+ override: z.object({
13
+ editor: z.object({
14
+ clientId: z.string().optional().describe("Intlayer CMS client ID"),
15
+ clientSecret: z.string().optional().describe("Intlayer CMS client secret"),
16
+ backendURL: z.string().optional().describe("Intlayer CMS backend URL")
17
+ }).optional(),
18
+ internationalization: z.object({
19
+ locales: z.array(z.nativeEnum(ALL_LOCALES)).optional().describe("Available locales"),
20
+ defaultLocale: z.nativeEnum(ALL_LOCALES).optional().describe("Default locale")
21
+ }).optional(),
22
+ log: z.object({
23
+ mode: z.enum([
24
+ "default",
25
+ "verbose",
26
+ "disabled"
27
+ ]).optional().describe("Log mode"),
28
+ prefix: z.string().optional().describe("Log prefix")
29
+ }).optional()
30
+ }).optional().describe("Config override - use when running remotely or without a local config file")
31
+ }).optional().describe("Configuration options. Required when running remotely or when no intlayer config file is present");
8
32
  const loadCLITools = async (server) => {
9
33
  server.registerTool("intlayer-init", {
10
34
  title: "Initialize Intlayer",
@@ -30,26 +54,14 @@ const loadCLITools = async (server) => {
30
54
  description: "Build the dictionaries. List all content declarations files `.content.{ts,tsx,js,json,...}` to update the content callable using the `useIntlayer` hook.",
31
55
  inputSchema: {
32
56
  watch: z.boolean().optional().describe("Watch for changes"),
33
- baseDir: z.string().optional().describe("Base directory"),
34
- env: z.string().optional().describe("Environment"),
35
- envFile: z.string().optional().describe("Environment file"),
36
- verbose: z.boolean().optional().describe("Verbose output"),
37
- prefix: z.string().optional().describe("Log prefix")
57
+ configOptions: configOptionsSchema
38
58
  },
39
59
  annotations: { destructiveHint: true }
40
- }, async ({ watch, baseDir, env, envFile, verbose, prefix }) => {
60
+ }, async ({ watch, configOptions }) => {
41
61
  try {
42
- const log = {};
43
- if (verbose) log.mode = "verbose";
44
- if (prefix) log.prefix = prefix;
45
62
  await build({
46
63
  watch,
47
- configOptions: {
48
- baseDir,
49
- env,
50
- envFile,
51
- override: { log }
52
- }
64
+ configOptions
53
65
  });
54
66
  return { content: [{
55
67
  type: "text",
@@ -88,7 +100,8 @@ const loadCLITools = async (server) => {
88
100
  apiKey: z.string().optional(),
89
101
  customPrompt: z.string().optional(),
90
102
  applicationContext: z.string().optional()
91
- }).optional().describe("AI options")
103
+ }).optional().describe("AI options"),
104
+ configOptions: configOptionsSchema
92
105
  },
93
106
  annotations: { destructiveHint: true }
94
107
  }, async (props) => {
@@ -136,7 +149,8 @@ const loadCLITools = async (server) => {
136
149
  uncommitted: z.boolean().optional(),
137
150
  unpushed: z.boolean().optional(),
138
151
  untracked: z.boolean().optional()
139
- }).optional().describe("Git options")
152
+ }).optional().describe("Git options"),
153
+ configOptions: configOptionsSchema
140
154
  },
141
155
  annotations: { destructiveHint: true }
142
156
  }, async (props) => {
@@ -175,7 +189,8 @@ const loadCLITools = async (server) => {
175
189
  description: "Pull dictionaries from the CMS",
176
190
  inputSchema: {
177
191
  dictionaries: z.array(z.string()).optional().describe("List of dictionaries to pull"),
178
- newDictionariesPath: z.string().optional().describe("Path to save new dictionaries")
192
+ newDictionariesPath: z.string().optional().describe("Path to save new dictionaries"),
193
+ configOptions: configOptionsSchema
179
194
  },
180
195
  annotations: { destructiveHint: true }
181
196
  }, async (props) => {
@@ -196,15 +211,7 @@ const loadCLITools = async (server) => {
196
211
  title: "List Content Declarations",
197
212
  description: "List the content declaration (.content.{ts,tsx,js,json,...}) files present in the project. That files contain the multilingual content of the application and are used to build the dictionaries.",
198
213
  inputSchema: {
199
- configOptions: z.object({
200
- baseDir: z.string().optional(),
201
- env: z.string().optional(),
202
- envFile: z.string().optional(),
203
- override: z.object({ log: z.object({
204
- prefix: z.string().optional(),
205
- verbose: z.boolean().optional()
206
- }).optional() }).optional()
207
- }).optional().describe("Configuration options"),
214
+ configOptions: configOptionsSchema,
208
215
  absolute: z.boolean().optional().describe("Output the results as absolute paths instead of relative paths"),
209
216
  json: z.boolean().optional().describe("Output the results as JSON instead of formatted text")
210
217
  },
@@ -226,15 +233,7 @@ const loadCLITools = async (server) => {
226
233
  server.registerTool("intlayer-content-test", {
227
234
  title: "Test Translations",
228
235
  description: "Test if there are missing translations in the content declaration files. That files contain the multilingual content of the application and are used to build the dictionaries.",
229
- inputSchema: { configOptions: z.object({
230
- baseDir: z.string().optional(),
231
- env: z.string().optional(),
232
- envFile: z.string().optional(),
233
- override: z.object({ log: z.object({
234
- prefix: z.string().optional(),
235
- verbose: z.boolean().optional()
236
- }).optional() }).optional()
237
- }).optional().describe("Configuration options") },
236
+ inputSchema: { configOptions: configOptionsSchema },
238
237
  annotations: { readOnlyHint: true }
239
238
  }, async (props) => {
240
239
  try {
@@ -256,15 +255,7 @@ const loadCLITools = async (server) => {
256
255
  inputSchema: {
257
256
  file: z.union([z.string(), z.array(z.string())]).optional().describe("List of files to extract"),
258
257
  outputContentDeclarations: z.string().optional().describe("Path to output content declaration files"),
259
- configOptions: z.object({
260
- baseDir: z.string().optional(),
261
- env: z.string().optional(),
262
- envFile: z.string().optional(),
263
- override: z.object({ log: z.object({
264
- prefix: z.string().optional(),
265
- verbose: z.boolean().optional()
266
- }).optional() }).optional()
267
- }).optional().describe("Configuration options")
258
+ configOptions: configOptionsSchema
268
259
  },
269
260
  annotations: { destructiveHint: true }
270
261
  }, async (props) => {
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":[],"sources":["../../../src/tools/cli.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport { listProjects } from '@intlayer/chokidar/cli';\nimport {\n build,\n extract,\n fill,\n init,\n listContentDeclarationRows,\n listMissingTranslations,\n pull,\n push,\n} from '@intlayer/cli';\nimport { ALL_LOCALES } from '@intlayer/types/allLocales';\nimport type { LogConfig } from '@intlayer/types/config';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport z from 'zod';\n\ntype LoadCLITools = (server: McpServer) => Promise<void>;\n\nexport const loadCLITools: LoadCLITools = async (server) => {\n server.registerTool(\n 'intlayer-init',\n {\n title: 'Initialize Intlayer',\n description: 'Initialize Intlayer in the project',\n inputSchema: {\n projectRoot: z.string().describe('Project root directory'),\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async ({ projectRoot }) => {\n try {\n await init(projectRoot);\n\n return {\n content: [\n {\n type: 'text',\n text: 'Initialization successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Initialization failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-build',\n {\n title: 'Build Dictionaries',\n description:\n 'Build the dictionaries. List all content declarations files `.content.{ts,tsx,js,json,...}` to update the content callable using the `useIntlayer` hook.',\n inputSchema: {\n watch: z.boolean().optional().describe('Watch for changes'),\n baseDir: z.string().optional().describe('Base directory'),\n env: z.string().optional().describe('Environment'),\n envFile: z.string().optional().describe('Environment file'),\n verbose: z.boolean().optional().describe('Verbose output'),\n prefix: z.string().optional().describe('Log prefix'),\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async ({ watch, baseDir, env, envFile, verbose, prefix }) => {\n try {\n const log: Partial<LogConfig> = {};\n if (verbose) {\n log.mode = 'verbose';\n }\n if (prefix) {\n log.prefix = prefix;\n }\n\n await build({\n watch,\n configOptions: {\n baseDir,\n env,\n envFile,\n override: {\n log,\n },\n },\n });\n\n return {\n content: [\n {\n type: 'text',\n text: 'Build successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Build failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-fill',\n {\n title: 'Fill Translations',\n description:\n 'Fill the dictionaries with missing translations / review translations using Intlayer servers',\n inputSchema: {\n sourceLocale: z\n .nativeEnum(ALL_LOCALES)\n .optional()\n .describe('Source locale'),\n outputLocales: z\n .union([\n z.nativeEnum(ALL_LOCALES),\n z.array(z.nativeEnum(ALL_LOCALES)),\n ])\n .optional()\n .describe('Output locales'),\n file: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('File path'),\n mode: z.enum(['complete', 'review']).optional().describe('Fill mode'),\n keys: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('Keys to include'),\n excludedKeys: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('Keys to exclude'),\n pathFilter: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('Path filter'),\n gitOptions: z\n .object({\n gitDiff: z.boolean().optional(),\n gitDiffBase: z.string().optional(),\n gitDiffCurrent: z.string().optional(),\n uncommitted: z.boolean().optional(),\n unpushed: z.boolean().optional(),\n untracked: z.boolean().optional(),\n })\n .optional()\n .describe('Git options'),\n aiOptions: z\n .object({\n provider: z.string().optional(),\n temperature: z.number().optional(),\n model: z.string().optional(),\n apiKey: z.string().optional(),\n customPrompt: z.string().optional(),\n applicationContext: z.string().optional(),\n })\n .optional()\n .describe('AI options'),\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async (props) => {\n try {\n const { gitOptions, ...rest } = props;\n const fillOptions: any = { ...rest, gitOptions: undefined };\n\n if (gitOptions) {\n const { gitDiff, uncommitted, unpushed, untracked, ...restGit } =\n gitOptions;\n const mode = [];\n if (gitDiff) mode.push('gitDiff');\n if (uncommitted) mode.push('uncommitted');\n if (unpushed) mode.push('unpushed');\n if (untracked) mode.push('untracked');\n\n fillOptions.gitOptions = { ...restGit, mode };\n }\n\n await fill(fillOptions);\n\n return {\n content: [\n {\n type: 'text',\n text: 'Fill successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Fill failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-push',\n {\n title: 'Push Dictionaries',\n description: 'Push local dictionaries to the server',\n inputSchema: {\n deleteLocaleDictionary: z\n .boolean()\n .optional()\n .describe('Delete local dictionary after push'),\n keepLocaleDictionary: z\n .boolean()\n .optional()\n .describe('Keep local dictionary after push'),\n dictionaries: z\n .array(z.string())\n .optional()\n .describe('List of dictionaries to push'),\n gitOptions: z\n .object({\n gitDiff: z.boolean().optional(),\n gitDiffBase: z.string().optional(),\n gitDiffCurrent: z.string().optional(),\n uncommitted: z.boolean().optional(),\n unpushed: z.boolean().optional(),\n untracked: z.boolean().optional(),\n })\n .optional()\n .describe('Git options'),\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async (props) => {\n try {\n const { gitOptions, ...rest } = props;\n const pushOptions: any = { ...rest, gitOptions: undefined };\n\n if (gitOptions) {\n const { gitDiff, uncommitted, unpushed, untracked, ...restGit } =\n gitOptions;\n const mode = [];\n if (gitDiff) mode.push('gitDiff');\n if (uncommitted) mode.push('uncommitted');\n if (unpushed) mode.push('unpushed');\n if (untracked) mode.push('untracked');\n\n pushOptions.gitOptions = { ...restGit, mode };\n }\n\n await push(pushOptions);\n\n return {\n content: [\n {\n type: 'text',\n text: 'Push successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Push failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-pull',\n {\n title: 'Pull Dictionaries',\n description: 'Pull dictionaries from the CMS',\n inputSchema: {\n dictionaries: z\n .array(z.string())\n .optional()\n .describe('List of dictionaries to pull'),\n newDictionariesPath: z\n .string()\n .optional()\n .describe('Path to save new dictionaries'),\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async (props) => {\n try {\n await pull(props);\n\n return {\n content: [\n {\n type: 'text',\n text: 'Pull successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Pull failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-content-list',\n {\n title: 'List Content Declarations',\n description:\n 'List the content declaration (.content.{ts,tsx,js,json,...}) files present in the project. That files contain the multilingual content of the application and are used to build the dictionaries.',\n inputSchema: {\n configOptions: z\n .object({\n baseDir: z.string().optional(),\n env: z.string().optional(),\n envFile: z.string().optional(),\n override: z\n .object({\n log: z\n .object({\n prefix: z.string().optional(),\n verbose: z.boolean().optional(),\n })\n .optional(),\n })\n .optional(),\n })\n .optional()\n .describe('Configuration options'),\n absolute: z\n .boolean()\n .optional()\n .describe(\n 'Output the results as absolute paths instead of relative paths'\n ),\n json: z\n .boolean()\n .optional()\n .describe('Output the results as JSON instead of formatted text'),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async (props) => {\n try {\n const rows = listContentDeclarationRows(props);\n return {\n content: [\n {\n type: 'text',\n text: props.json\n ? JSON.stringify(rows)\n : JSON.stringify(rows, null, 2),\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Content list failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-content-test',\n {\n title: 'Test Translations',\n description:\n 'Test if there are missing translations in the content declaration files. That files contain the multilingual content of the application and are used to build the dictionaries.',\n inputSchema: {\n configOptions: z\n .object({\n baseDir: z.string().optional(),\n env: z.string().optional(),\n envFile: z.string().optional(),\n override: z\n .object({\n log: z\n .object({\n prefix: z.string().optional(),\n verbose: z.boolean().optional(),\n })\n .optional(),\n })\n .optional(),\n })\n .optional()\n .describe('Configuration options'),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async (props) => {\n try {\n const missingTranslations = listMissingTranslations(\n props?.configOptions\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(missingTranslations, null, 2),\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Content test failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-extract',\n {\n title: 'Extract strings from Component',\n description:\n 'Extract strings from an existing component to be placed in a .content file close to the component. Trigger this action to make an existing component multilingual. If the component does not exist, create a normal component including text in JSX, and then trigger this tool to extract it.',\n inputSchema: {\n file: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('List of files to extract'),\n outputContentDeclarations: z\n .string()\n .optional()\n .describe('Path to output content declaration files'),\n configOptions: z\n .object({\n baseDir: z.string().optional(),\n env: z.string().optional(),\n envFile: z.string().optional(),\n override: z\n .object({\n log: z\n .object({\n prefix: z.string().optional(),\n verbose: z.boolean().optional(),\n })\n .optional(),\n })\n .optional(),\n })\n .optional()\n .describe('Configuration options'),\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async (props) => {\n try {\n await extract({\n files: Array.isArray(props.file)\n ? props.file\n : props.file\n ? [props.file]\n : undefined,\n configOptions: props.configOptions,\n });\n\n return {\n content: [\n {\n type: 'text',\n text: 'Extract successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Extract failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-projects-list',\n {\n title: 'List Projects',\n description:\n 'List all Intlayer projects in the directory. Search for configuration files to find all Intlayer projects.',\n inputSchema: {\n baseDir: z\n .string()\n .optional()\n .describe('Base directory to search from'),\n gitRoot: z\n .boolean()\n .optional()\n .describe(\n 'Search from the git root directory instead of the base directory'\n ),\n absolute: z\n .boolean()\n .optional()\n .describe(\n 'Output the results as absolute paths instead of relative paths'\n ),\n json: z\n .boolean()\n .optional()\n .describe('Output the results as JSON instead of formatted text'),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async (props) => {\n try {\n const { searchDir, projectsPath } = await listProjects({\n baseDir: props.baseDir,\n gitRoot: props.gitRoot,\n });\n\n // Handle absolute option similar to CLI command\n const projectsRelativePath = projectsPath\n .map((projectPath) =>\n props.absolute ? projectPath : relative(searchDir, projectPath)\n )\n .map((projectPath) => (projectPath === '' ? '.' : projectPath));\n\n const outputPaths = props.absolute\n ? projectsPath\n : projectsRelativePath;\n\n return {\n content: [\n {\n type: 'text',\n text: props.json\n ? JSON.stringify(outputPaths)\n : JSON.stringify(\n { searchDir, projectsPath: outputPaths },\n null,\n 2\n ),\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Projects list failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.mjs","names":[],"sources":["../../../src/tools/cli.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport { listProjects } from '@intlayer/chokidar/cli';\nimport {\n build,\n extract,\n fill,\n init,\n listContentDeclarationRows,\n listMissingTranslations,\n pull,\n push,\n} from '@intlayer/cli';\nimport { ALL_LOCALES } from '@intlayer/types/allLocales';\nimport z from 'zod';\nimport type { McpServer } from './docs';\n\nconst configOptionsSchema = z\n .object({\n baseDir: z.string().optional().describe('Base directory for the project'),\n env: z.string().optional().describe('Environment name'),\n envFile: z.string().optional().describe('Path to the environment file'),\n override: z\n .object({\n editor: z\n .object({\n clientId: z.string().optional().describe('Intlayer CMS client ID'),\n clientSecret: z\n .string()\n .optional()\n .describe('Intlayer CMS client secret'),\n backendURL: z\n .string()\n .optional()\n .describe('Intlayer CMS backend URL'),\n })\n .optional(),\n internationalization: z\n .object({\n locales: z\n .array(z.nativeEnum(ALL_LOCALES))\n .optional()\n .describe('Available locales'),\n defaultLocale: z\n .nativeEnum(ALL_LOCALES)\n .optional()\n .describe('Default locale'),\n })\n .optional(),\n log: z\n .object({\n mode: z\n .enum(['default', 'verbose', 'disabled'])\n .optional()\n .describe('Log mode'),\n prefix: z.string().optional().describe('Log prefix'),\n })\n .optional(),\n })\n .optional()\n .describe(\n 'Config override - use when running remotely or without a local config file'\n ),\n })\n .optional()\n .describe(\n 'Configuration options. Required when running remotely or when no intlayer config file is present'\n );\n\ntype LoadCLITools = (server: McpServer) => Promise<void>;\n\nexport const loadCLITools: LoadCLITools = async (server) => {\n server.registerTool(\n 'intlayer-init',\n {\n title: 'Initialize Intlayer',\n description: 'Initialize Intlayer in the project',\n inputSchema: {\n projectRoot: z.string().describe('Project root directory'),\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async ({ projectRoot }) => {\n try {\n await init(projectRoot);\n\n return {\n content: [\n {\n type: 'text',\n text: 'Initialization successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Initialization failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-build',\n {\n title: 'Build Dictionaries',\n description:\n 'Build the dictionaries. List all content declarations files `.content.{ts,tsx,js,json,...}` to update the content callable using the `useIntlayer` hook.',\n inputSchema: {\n watch: z.boolean().optional().describe('Watch for changes'),\n configOptions: configOptionsSchema,\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async ({ watch, configOptions }) => {\n try {\n await build({ watch, configOptions });\n\n return {\n content: [\n {\n type: 'text',\n text: 'Build successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Build failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-fill',\n {\n title: 'Fill Translations',\n description:\n 'Fill the dictionaries with missing translations / review translations using Intlayer servers',\n inputSchema: {\n sourceLocale: z\n .nativeEnum(ALL_LOCALES)\n .optional()\n .describe('Source locale'),\n outputLocales: z\n .union([\n z.nativeEnum(ALL_LOCALES),\n z.array(z.nativeEnum(ALL_LOCALES)),\n ])\n .optional()\n .describe('Output locales'),\n file: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('File path'),\n mode: z.enum(['complete', 'review']).optional().describe('Fill mode'),\n keys: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('Keys to include'),\n excludedKeys: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('Keys to exclude'),\n pathFilter: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('Path filter'),\n gitOptions: z\n .object({\n gitDiff: z.boolean().optional(),\n gitDiffBase: z.string().optional(),\n gitDiffCurrent: z.string().optional(),\n uncommitted: z.boolean().optional(),\n unpushed: z.boolean().optional(),\n untracked: z.boolean().optional(),\n })\n .optional()\n .describe('Git options'),\n aiOptions: z\n .object({\n provider: z.string().optional(),\n temperature: z.number().optional(),\n model: z.string().optional(),\n apiKey: z.string().optional(),\n customPrompt: z.string().optional(),\n applicationContext: z.string().optional(),\n })\n .optional()\n .describe('AI options'),\n configOptions: configOptionsSchema,\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async (props) => {\n try {\n const { gitOptions, ...rest } = props;\n const fillOptions: any = { ...rest, gitOptions: undefined };\n\n if (gitOptions) {\n const { gitDiff, uncommitted, unpushed, untracked, ...restGit } =\n gitOptions;\n const mode = [];\n if (gitDiff) mode.push('gitDiff');\n if (uncommitted) mode.push('uncommitted');\n if (unpushed) mode.push('unpushed');\n if (untracked) mode.push('untracked');\n\n fillOptions.gitOptions = { ...restGit, mode };\n }\n\n await fill(fillOptions);\n\n return {\n content: [\n {\n type: 'text',\n text: 'Fill successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Fill failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-push',\n {\n title: 'Push Dictionaries',\n description: 'Push local dictionaries to the server',\n inputSchema: {\n deleteLocaleDictionary: z\n .boolean()\n .optional()\n .describe('Delete local dictionary after push'),\n keepLocaleDictionary: z\n .boolean()\n .optional()\n .describe('Keep local dictionary after push'),\n dictionaries: z\n .array(z.string())\n .optional()\n .describe('List of dictionaries to push'),\n gitOptions: z\n .object({\n gitDiff: z.boolean().optional(),\n gitDiffBase: z.string().optional(),\n gitDiffCurrent: z.string().optional(),\n uncommitted: z.boolean().optional(),\n unpushed: z.boolean().optional(),\n untracked: z.boolean().optional(),\n })\n .optional()\n .describe('Git options'),\n configOptions: configOptionsSchema,\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async (props) => {\n try {\n const { gitOptions, ...rest } = props;\n const pushOptions: any = { ...rest, gitOptions: undefined };\n\n if (gitOptions) {\n const { gitDiff, uncommitted, unpushed, untracked, ...restGit } =\n gitOptions;\n const mode = [];\n if (gitDiff) mode.push('gitDiff');\n if (uncommitted) mode.push('uncommitted');\n if (unpushed) mode.push('unpushed');\n if (untracked) mode.push('untracked');\n\n pushOptions.gitOptions = { ...restGit, mode };\n }\n\n await push(pushOptions);\n\n return {\n content: [\n {\n type: 'text',\n text: 'Push successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Push failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-pull',\n {\n title: 'Pull Dictionaries',\n description: 'Pull dictionaries from the CMS',\n inputSchema: {\n dictionaries: z\n .array(z.string())\n .optional()\n .describe('List of dictionaries to pull'),\n newDictionariesPath: z\n .string()\n .optional()\n .describe('Path to save new dictionaries'),\n configOptions: configOptionsSchema,\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async (props) => {\n try {\n await pull(props);\n\n return {\n content: [\n {\n type: 'text',\n text: 'Pull successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Pull failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-content-list',\n {\n title: 'List Content Declarations',\n description:\n 'List the content declaration (.content.{ts,tsx,js,json,...}) files present in the project. That files contain the multilingual content of the application and are used to build the dictionaries.',\n inputSchema: {\n configOptions: configOptionsSchema,\n absolute: z\n .boolean()\n .optional()\n .describe(\n 'Output the results as absolute paths instead of relative paths'\n ),\n json: z\n .boolean()\n .optional()\n .describe('Output the results as JSON instead of formatted text'),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async (props) => {\n try {\n const rows = listContentDeclarationRows(props);\n return {\n content: [\n {\n type: 'text',\n text: props.json\n ? JSON.stringify(rows)\n : JSON.stringify(rows, null, 2),\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Content list failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-content-test',\n {\n title: 'Test Translations',\n description:\n 'Test if there are missing translations in the content declaration files. That files contain the multilingual content of the application and are used to build the dictionaries.',\n inputSchema: {\n configOptions: configOptionsSchema,\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async (props) => {\n try {\n const missingTranslations = listMissingTranslations(\n props?.configOptions\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(missingTranslations, null, 2),\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Content test failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-extract',\n {\n title: 'Extract strings from Component',\n description:\n 'Extract strings from an existing component to be placed in a .content file close to the component. Trigger this action to make an existing component multilingual. If the component does not exist, create a normal component including text in JSX, and then trigger this tool to extract it.',\n inputSchema: {\n file: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('List of files to extract'),\n outputContentDeclarations: z\n .string()\n .optional()\n .describe('Path to output content declaration files'),\n configOptions: configOptionsSchema,\n },\n annotations: {\n destructiveHint: true,\n },\n },\n async (props) => {\n try {\n await extract({\n files: Array.isArray(props.file)\n ? props.file\n : props.file\n ? [props.file]\n : undefined,\n configOptions: props.configOptions,\n });\n\n return {\n content: [\n {\n type: 'text',\n text: 'Extract successful.',\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Extract failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'intlayer-projects-list',\n {\n title: 'List Projects',\n description:\n 'List all Intlayer projects in the directory. Search for configuration files to find all Intlayer projects.',\n inputSchema: {\n baseDir: z\n .string()\n .optional()\n .describe('Base directory to search from'),\n gitRoot: z\n .boolean()\n .optional()\n .describe(\n 'Search from the git root directory instead of the base directory'\n ),\n absolute: z\n .boolean()\n .optional()\n .describe(\n 'Output the results as absolute paths instead of relative paths'\n ),\n json: z\n .boolean()\n .optional()\n .describe('Output the results as JSON instead of formatted text'),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async (props) => {\n try {\n const { searchDir, projectsPath } = await listProjects({\n baseDir: props.baseDir,\n gitRoot: props.gitRoot,\n });\n\n const projectsRelativePath = projectsPath\n .map((projectPath) =>\n props.absolute ? projectPath : relative(searchDir, projectPath)\n )\n .map((projectPath) => (projectPath === '' ? '.' : projectPath));\n\n const outputPaths = props.absolute\n ? projectsPath\n : projectsRelativePath;\n\n return {\n content: [\n {\n type: 'text',\n text: props.json\n ? JSON.stringify(outputPaths)\n : JSON.stringify(\n { searchDir, projectsPath: outputPaths },\n null,\n 2\n ),\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n {\n type: 'text',\n text: `Projects list failed: ${errorMessage}`,\n },\n ],\n };\n }\n }\n );\n};\n"],"mappings":";;;;;;;AAgBA,MAAM,sBAAsB,EACzB,OAAO;CACN,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,iCAAiC;CACzE,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,mBAAmB;CACvD,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,+BAA+B;CACvE,UAAU,EACP,OAAO;EACN,QAAQ,EACL,OAAO;GACN,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,yBAAyB;GAClE,cAAc,EACX,QAAQ,CACR,UAAU,CACV,SAAS,6BAA6B;GACzC,YAAY,EACT,QAAQ,CACR,UAAU,CACV,SAAS,2BAA2B;GACxC,CAAC,CACD,UAAU;EACb,sBAAsB,EACnB,OAAO;GACN,SAAS,EACN,MAAM,EAAE,WAAW,YAAY,CAAC,CAChC,UAAU,CACV,SAAS,oBAAoB;GAChC,eAAe,EACZ,WAAW,YAAY,CACvB,UAAU,CACV,SAAS,iBAAiB;GAC9B,CAAC,CACD,UAAU;EACb,KAAK,EACF,OAAO;GACN,MAAM,EACH,KAAK;IAAC;IAAW;IAAW;IAAW,CAAC,CACxC,UAAU,CACV,SAAS,WAAW;GACvB,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,aAAa;GACrD,CAAC,CACD,UAAU;EACd,CAAC,CACD,UAAU,CACV,SACC,6EACD;CACJ,CAAC,CACD,UAAU,CACV,SACC,mGACD;AAIH,MAAa,eAA6B,OAAO,WAAW;CAC1D,OAAO,aACL,iBACA;EACE,OAAO;EACP,aAAa;EACb,aAAa,EACX,aAAa,EAAE,QAAQ,CAAC,SAAS,yBAAyB,EAC3D;EACD,aAAa,EACX,iBAAiB,MAClB;EACF,EACD,OAAO,EAAE,kBAAkB;EACzB,IAAI;GACF,MAAM,KAAK,YAAY;GAEvB,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM;IACP,CACF,EACF;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,0BALV,iBAAiB,QAAQ,MAAM,UAAU;IAMtC,CACF,EACF;;GAGN;CAED,OAAO,aACL,kBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,oBAAoB;GAC3D,eAAe;GAChB;EACD,aAAa,EACX,iBAAiB,MAClB;EACF,EACD,OAAO,EAAE,OAAO,oBAAoB;EAClC,IAAI;GACF,MAAM,MAAM;IAAE;IAAO;IAAe,CAAC;GAErC,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM;IACP,CACF,EACF;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,iBALV,iBAAiB,QAAQ,MAAM,UAAU;IAMtC,CACF,EACF;;GAGN;CAED,OAAO,aACL,iBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,cAAc,EACX,WAAW,YAAY,CACvB,UAAU,CACV,SAAS,gBAAgB;GAC5B,eAAe,EACZ,MAAM,CACL,EAAE,WAAW,YAAY,EACzB,EAAE,MAAM,EAAE,WAAW,YAAY,CAAC,CACnC,CAAC,CACD,UAAU,CACV,SAAS,iBAAiB;GAC7B,MAAM,EACH,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CACxC,UAAU,CACV,SAAS,YAAY;GACxB,MAAM,EAAE,KAAK,CAAC,YAAY,SAAS,CAAC,CAAC,UAAU,CAAC,SAAS,YAAY;GACrE,MAAM,EACH,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CACxC,UAAU,CACV,SAAS,kBAAkB;GAC9B,cAAc,EACX,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CACxC,UAAU,CACV,SAAS,kBAAkB;GAC9B,YAAY,EACT,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CACxC,UAAU,CACV,SAAS,cAAc;GAC1B,YAAY,EACT,OAAO;IACN,SAAS,EAAE,SAAS,CAAC,UAAU;IAC/B,aAAa,EAAE,QAAQ,CAAC,UAAU;IAClC,gBAAgB,EAAE,QAAQ,CAAC,UAAU;IACrC,aAAa,EAAE,SAAS,CAAC,UAAU;IACnC,UAAU,EAAE,SAAS,CAAC,UAAU;IAChC,WAAW,EAAE,SAAS,CAAC,UAAU;IAClC,CAAC,CACD,UAAU,CACV,SAAS,cAAc;GAC1B,WAAW,EACR,OAAO;IACN,UAAU,EAAE,QAAQ,CAAC,UAAU;IAC/B,aAAa,EAAE,QAAQ,CAAC,UAAU;IAClC,OAAO,EAAE,QAAQ,CAAC,UAAU;IAC5B,QAAQ,EAAE,QAAQ,CAAC,UAAU;IAC7B,cAAc,EAAE,QAAQ,CAAC,UAAU;IACnC,oBAAoB,EAAE,QAAQ,CAAC,UAAU;IAC1C,CAAC,CACD,UAAU,CACV,SAAS,aAAa;GACzB,eAAe;GAChB;EACD,aAAa,EACX,iBAAiB,MAClB;EACF,EACD,OAAO,UAAU;EACf,IAAI;GACF,MAAM,EAAE,YAAY,GAAG,SAAS;GAChC,MAAM,cAAmB;IAAE,GAAG;IAAM,YAAY;IAAW;GAE3D,IAAI,YAAY;IACd,MAAM,EAAE,SAAS,aAAa,UAAU,WAAW,GAAG,YACpD;IACF,MAAM,OAAO,EAAE;IACf,IAAI,SAAS,KAAK,KAAK,UAAU;IACjC,IAAI,aAAa,KAAK,KAAK,cAAc;IACzC,IAAI,UAAU,KAAK,KAAK,WAAW;IACnC,IAAI,WAAW,KAAK,KAAK,YAAY;IAErC,YAAY,aAAa;KAAE,GAAG;KAAS;KAAM;;GAG/C,MAAM,KAAK,YAAY;GAEvB,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM;IACP,CACF,EACF;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,gBALV,iBAAiB,QAAQ,MAAM,UAAU;IAMtC,CACF,EACF;;GAGN;CAED,OAAO,aACL,iBACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,wBAAwB,EACrB,SAAS,CACT,UAAU,CACV,SAAS,qCAAqC;GACjD,sBAAsB,EACnB,SAAS,CACT,UAAU,CACV,SAAS,mCAAmC;GAC/C,cAAc,EACX,MAAM,EAAE,QAAQ,CAAC,CACjB,UAAU,CACV,SAAS,+BAA+B;GAC3C,YAAY,EACT,OAAO;IACN,SAAS,EAAE,SAAS,CAAC,UAAU;IAC/B,aAAa,EAAE,QAAQ,CAAC,UAAU;IAClC,gBAAgB,EAAE,QAAQ,CAAC,UAAU;IACrC,aAAa,EAAE,SAAS,CAAC,UAAU;IACnC,UAAU,EAAE,SAAS,CAAC,UAAU;IAChC,WAAW,EAAE,SAAS,CAAC,UAAU;IAClC,CAAC,CACD,UAAU,CACV,SAAS,cAAc;GAC1B,eAAe;GAChB;EACD,aAAa,EACX,iBAAiB,MAClB;EACF,EACD,OAAO,UAAU;EACf,IAAI;GACF,MAAM,EAAE,YAAY,GAAG,SAAS;GAChC,MAAM,cAAmB;IAAE,GAAG;IAAM,YAAY;IAAW;GAE3D,IAAI,YAAY;IACd,MAAM,EAAE,SAAS,aAAa,UAAU,WAAW,GAAG,YACpD;IACF,MAAM,OAAO,EAAE;IACf,IAAI,SAAS,KAAK,KAAK,UAAU;IACjC,IAAI,aAAa,KAAK,KAAK,cAAc;IACzC,IAAI,UAAU,KAAK,KAAK,WAAW;IACnC,IAAI,WAAW,KAAK,KAAK,YAAY;IAErC,YAAY,aAAa;KAAE,GAAG;KAAS;KAAM;;GAG/C,MAAM,KAAK,YAAY;GAEvB,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM;IACP,CACF,EACF;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,gBALV,iBAAiB,QAAQ,MAAM,UAAU;IAMtC,CACF,EACF;;GAGN;CAED,OAAO,aACL,iBACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,cAAc,EACX,MAAM,EAAE,QAAQ,CAAC,CACjB,UAAU,CACV,SAAS,+BAA+B;GAC3C,qBAAqB,EAClB,QAAQ,CACR,UAAU,CACV,SAAS,gCAAgC;GAC5C,eAAe;GAChB;EACD,aAAa,EACX,iBAAiB,MAClB;EACF,EACD,OAAO,UAAU;EACf,IAAI;GACF,MAAM,KAAK,MAAM;GAEjB,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM;IACP,CACF,EACF;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,gBALV,iBAAiB,QAAQ,MAAM,UAAU;IAMtC,CACF,EACF;;GAGN;CAED,OAAO,aACL,yBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,eAAe;GACf,UAAU,EACP,SAAS,CACT,UAAU,CACV,SACC,iEACD;GACH,MAAM,EACH,SAAS,CACT,UAAU,CACV,SAAS,uDAAuD;GACpE;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,UAAU;EACf,IAAI;GACF,MAAM,OAAO,2BAA2B,MAAM;GAC9C,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,MAAM,OACR,KAAK,UAAU,KAAK,GACpB,KAAK,UAAU,MAAM,MAAM,EAAE;IAClC,CACF,EACF;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,wBALV,iBAAiB,QAAQ,MAAM,UAAU;IAMtC,CACF,EACF;;GAGN;CAED,OAAO,aACL,yBACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,eAAe,qBAChB;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,UAAU;EACf,IAAI;GACF,MAAM,sBAAsB,wBAC1B,OAAO,cACR;GACD,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,KAAK,UAAU,qBAAqB,MAAM,EAAE;IACnD,CACF,EACF;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,wBALV,iBAAiB,QAAQ,MAAM,UAAU;IAMtC,CACF,EACF;;GAGN;CAED,OAAO,aACL,oBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,MAAM,EACH,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CACxC,UAAU,CACV,SAAS,2BAA2B;GACvC,2BAA2B,EACxB,QAAQ,CACR,UAAU,CACV,SAAS,2CAA2C;GACvD,eAAe;GAChB;EACD,aAAa,EACX,iBAAiB,MAClB;EACF,EACD,OAAO,UAAU;EACf,IAAI;GACF,MAAM,QAAQ;IACZ,OAAO,MAAM,QAAQ,MAAM,KAAK,GAC5B,MAAM,OACN,MAAM,OACJ,CAAC,MAAM,KAAK,GACZ;IACN,eAAe,MAAM;IACtB,CAAC;GAEF,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM;IACP,CACF,EACF;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,mBALV,iBAAiB,QAAQ,MAAM,UAAU;IAMtC,CACF,EACF;;GAGN;CAED,OAAO,aACL,0BACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,SAAS,EACN,QAAQ,CACR,UAAU,CACV,SAAS,gCAAgC;GAC5C,SAAS,EACN,SAAS,CACT,UAAU,CACV,SACC,mEACD;GACH,UAAU,EACP,SAAS,CACT,UAAU,CACV,SACC,iEACD;GACH,MAAM,EACH,SAAS,CACT,UAAU,CACV,SAAS,uDAAuD;GACpE;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,UAAU;EACf,IAAI;GACF,MAAM,EAAE,WAAW,iBAAiB,MAAM,aAAa;IACrD,SAAS,MAAM;IACf,SAAS,MAAM;IAChB,CAAC;GAEF,MAAM,uBAAuB,aAC1B,KAAK,gBACJ,MAAM,WAAW,cAAc,SAAS,WAAW,YAAY,CAChE,CACA,KAAK,gBAAiB,gBAAgB,KAAK,MAAM,YAAa;GAEjE,MAAM,cAAc,MAAM,WACtB,eACA;GAEJ,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,MAAM,OACR,KAAK,UAAU,YAAY,GAC3B,KAAK,UACH;KAAE;KAAW,cAAc;KAAa,EACxC,MACA,EACD;IACN,CACF,EACF;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,yBALV,iBAAiB,QAAQ,MAAM,UAAU;IAMtC,CACF,EACF;;GAGN"}
@@ -73,7 +73,7 @@ const loadDocsTools = async (server) => {
73
73
  annotations: { readOnlyHint: true }
74
74
  }, async ({ query, limit }) => {
75
75
  try {
76
- const { searchDoc } = getSearchAPI();
76
+ const { searchDoc } = getSearchAPI(void 0);
77
77
  const response = await searchDoc({
78
78
  input: query,
79
79
  limit: limit?.toString(),
@@ -1 +1 @@
1
- {"version":3,"file":"docs.mjs","names":[],"sources":["../../../src/tools/docs.ts"],"sourcesContent":["import { getSearchAPI } from '@intlayer/api';\nimport type { DocKey } from '@intlayer/docs';\nimport {\n getDoc,\n getDocBySlug,\n getDocMetadataRecord,\n getDocsKeys,\n} from '@intlayer/docs';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport z from 'zod';\n\ntype LoadDocsTools = (server: McpServer) => Promise<void>;\n\nexport const loadDocsTools: LoadDocsTools = async (server) => {\n const docsKeys = getDocsKeys();\n\n server.registerTool(\n 'get-doc-list',\n {\n title: 'Get Doc List',\n description:\n 'Get the list of docs names and their metadata to get more details about what doc to retrieve',\n inputSchema: {},\n annotations: {\n readOnlyHint: true,\n },\n },\n async () => {\n try {\n const docsMetadataRecord = await getDocMetadataRecord();\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(docsMetadataRecord, null, 2),\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Get doc list failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'get-doc',\n {\n title: 'Get Doc by Key',\n description:\n 'Get a doc by his key. Example: `./docs/en/getting-started.md`. List all docs metadata first to get more details about what doc key to retrieve.',\n inputSchema: {\n docKey: z.enum(docsKeys as [string, ...string[]]),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ docKey }) => {\n try {\n const doc = await getDoc(docKey as DocKey);\n return {\n content: [{ type: 'text', text: doc }],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [{ type: 'text', text: `Get doc failed: ${errorMessage}` }],\n };\n }\n }\n );\n\n server.registerTool(\n 'get-doc-by-slug',\n {\n title: 'Get Doc by Slug',\n description:\n 'Get an array of docs by their slugs. If not slug is provided, return all docs (1.2Mb). List all docs metadata first to get more details about what doc to retrieve.',\n inputSchema: {\n slug: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe(\n 'Slug of the docs. If not provided, return all docs. If not provided, return all docs.'\n ),\n strict: z\n .boolean()\n .optional()\n .describe(\n 'Strict mode - only return docs that match all slugs, by excluding additional slugs'\n ),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ slug, strict }) => {\n try {\n const doc = await getDocBySlug(slug ?? [], undefined, strict);\n return {\n content: doc.map((d) => ({ type: 'text', text: d })),\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Get doc by slug failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'fetch-doc-chunks',\n {\n title: 'Fetch Doc Chunks',\n description:\n 'Fetch related doc chunks using keywords or questions. This tool will return the most relevant chunks of documentation based on the input query.',\n inputSchema: {\n query: z.string().describe('The keywords or question to search for'),\n limit: z\n .number()\n .optional()\n .describe('The number of chunks to retrieve (default: 10)'),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ query, limit }) => {\n try {\n const { searchDoc } = getSearchAPI();\n const response = await searchDoc({\n input: query,\n limit: limit?.toString(),\n returnContent: 'true',\n });\n\n if (!response.data || !Array.isArray(response.data)) {\n return {\n content: [{ type: 'text', text: 'No relevant chunks found.' }],\n };\n }\n\n const chunks = response.data;\n\n return {\n content: chunks.map((chunk: any) => ({\n type: 'text',\n text: [\n `File: ${chunk.fileKey}`,\n `Title: ${chunk.docName}`,\n `URL: ${chunk.docUrl}`,\n `Chunk: ${chunk.chunkNumber}`,\n `Content:`,\n chunk.content,\n ].join('\\n'),\n })),\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Fetch doc chunks failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n};\n"],"mappings":";;;;;AAaA,MAAa,gBAA+B,OAAO,WAAW;CAC5D,MAAM,WAAW,aAAa;CAE9B,OAAO,aACL,gBACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EAAE;EACf,aAAa,EACX,cAAc,MACf;EACF,EACD,YAAY;EACV,IAAI;GACF,MAAM,qBAAqB,MAAM,sBAAsB;GAEvD,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,KAAK,UAAU,oBAAoB,MAAM,EAAE;IAClD,CACF,EACF;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,wBAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAGuB,CAC/D,EACF;;GAGN;CAED,OAAO,aACL,WACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,QAAQ,EAAE,KAAK,SAAkC,EAClD;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,EAAE,aAAa;EACpB,IAAI;GAEF,OAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,MAFhB,OAAO,OAAiB;IAEH,CAAC,EACvC;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,mBAFhC,iBAAiB,QAAQ,MAAM,UAAU;IAE0B,CAAC,EACrE;;GAGN;CAED,OAAO,aACL,mBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,MAAM,EACH,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CACxC,UAAU,CACV,SACC,wFACD;GACH,QAAQ,EACL,SAAS,CACT,UAAU,CACV,SACC,qFACD;GACJ;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,EAAE,MAAM,aAAa;EAC1B,IAAI;GAEF,OAAO,EACL,UAAS,MAFO,aAAa,QAAQ,EAAE,EAAE,QAAW,OAAO,EAE9C,KAAK,OAAO;IAAE,MAAM;IAAQ,MAAM;IAAG,EAAE,EACrD;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,2BAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAG0B,CAClE,EACF;;GAGN;CAED,OAAO,aACL,oBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,OAAO,EAAE,QAAQ,CAAC,SAAS,yCAAyC;GACpE,OAAO,EACJ,QAAQ,CACR,UAAU,CACV,SAAS,iDAAiD;GAC9D;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,EAAE,OAAO,YAAY;EAC1B,IAAI;GACF,MAAM,EAAE,cAAc,cAAc;GACpC,MAAM,WAAW,MAAM,UAAU;IAC/B,OAAO;IACP,OAAO,OAAO,UAAU;IACxB,eAAe;IAChB,CAAC;GAEF,IAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,QAAQ,SAAS,KAAK,EACjD,OAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM;IAA6B,CAAC,EAC/D;GAKH,OAAO,EACL,SAHa,SAAS,KAGN,KAAK,WAAgB;IACnC,MAAM;IACN,MAAM;KACJ,SAAS,MAAM;KACf,UAAU,MAAM;KAChB,QAAQ,MAAM;KACd,UAAU,MAAM;KAChB;KACA,MAAM;KACP,CAAC,KAAK,KAAK;IACb,EAAE,EACJ;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,4BAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAG2B,CACnE,EACF;;GAGN"}
1
+ {"version":3,"file":"docs.mjs","names":[],"sources":["../../../src/tools/docs.ts"],"sourcesContent":["import { getSearchAPI } from '@intlayer/api';\nimport type { DocKey } from '@intlayer/docs';\nimport {\n getDoc,\n getDocBySlug,\n getDocMetadataRecord,\n getDocsKeys,\n} from '@intlayer/docs';\nimport z from 'zod';\n\nexport type ToolResult = {\n content: { type: string; text: string }[];\n isError?: boolean;\n};\nexport type McpServer = {\n registerTool(\n name: string,\n config: any,\n handler: (params: any) => Promise<ToolResult>\n ): void;\n};\n\ntype LoadDocsTools = (server: McpServer) => Promise<void>;\n\nexport const loadDocsTools: LoadDocsTools = async (server) => {\n const docsKeys = getDocsKeys();\n\n server.registerTool(\n 'get-doc-list',\n {\n title: 'Get Doc List',\n description:\n 'Get the list of docs names and their metadata to get more details about what doc to retrieve',\n inputSchema: {},\n annotations: {\n readOnlyHint: true,\n },\n },\n async () => {\n try {\n const docsMetadataRecord = await getDocMetadataRecord();\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(docsMetadataRecord, null, 2),\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Get doc list failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'get-doc',\n {\n title: 'Get Doc by Key',\n description:\n 'Get a doc by his key. Example: `./docs/en/getting-started.md`. List all docs metadata first to get more details about what doc key to retrieve.',\n inputSchema: {\n docKey: z.enum(docsKeys as [string, ...string[]]),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ docKey }) => {\n try {\n const doc = await getDoc(docKey as DocKey);\n return {\n content: [{ type: 'text', text: doc }],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [{ type: 'text', text: `Get doc failed: ${errorMessage}` }],\n };\n }\n }\n );\n\n server.registerTool(\n 'get-doc-by-slug',\n {\n title: 'Get Doc by Slug',\n description:\n 'Get an array of docs by their slugs. If not slug is provided, return all docs (1.2Mb). List all docs metadata first to get more details about what doc to retrieve.',\n inputSchema: {\n slug: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe(\n 'Slug of the docs. If not provided, return all docs. If not provided, return all docs.'\n ),\n strict: z\n .boolean()\n .optional()\n .describe(\n 'Strict mode - only return docs that match all slugs, by excluding additional slugs'\n ),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ slug, strict }) => {\n try {\n const doc = await getDocBySlug(slug ?? [], undefined, strict);\n return {\n content: doc.map((d) => ({ type: 'text', text: d })),\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Get doc by slug failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'fetch-doc-chunks',\n {\n title: 'Fetch Doc Chunks',\n description:\n 'Fetch related doc chunks using keywords or questions. This tool will return the most relevant chunks of documentation based on the input query.',\n inputSchema: {\n query: z.string().describe('The keywords or question to search for'),\n limit: z\n .number()\n .optional()\n .describe('The number of chunks to retrieve (default: 10)'),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ query, limit }) => {\n try {\n const { searchDoc } = getSearchAPI(undefined);\n const response = await searchDoc({\n input: query,\n limit: limit?.toString(),\n returnContent: 'true',\n });\n\n if (!response.data || !Array.isArray(response.data)) {\n return {\n content: [{ type: 'text', text: 'No relevant chunks found.' }],\n };\n }\n\n const chunks = response.data;\n\n return {\n content: chunks.map((chunk: any) => ({\n type: 'text',\n text: [\n `File: ${chunk.fileKey}`,\n `Title: ${chunk.docName}`,\n `URL: ${chunk.docUrl}`,\n `Chunk: ${chunk.chunkNumber}`,\n `Content:`,\n chunk.content,\n ].join('\\n'),\n })),\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Fetch doc chunks failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n};\n"],"mappings":";;;;;AAwBA,MAAa,gBAA+B,OAAO,WAAW;CAC5D,MAAM,WAAW,aAAa;CAE9B,OAAO,aACL,gBACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EAAE;EACf,aAAa,EACX,cAAc,MACf;EACF,EACD,YAAY;EACV,IAAI;GACF,MAAM,qBAAqB,MAAM,sBAAsB;GAEvD,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,KAAK,UAAU,oBAAoB,MAAM,EAAE;IAClD,CACF,EACF;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,wBAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAGuB,CAC/D,EACF;;GAGN;CAED,OAAO,aACL,WACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,QAAQ,EAAE,KAAK,SAAkC,EAClD;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,EAAE,aAAa;EACpB,IAAI;GAEF,OAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,MAFhB,OAAO,OAAiB;IAEH,CAAC,EACvC;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,mBAFhC,iBAAiB,QAAQ,MAAM,UAAU;IAE0B,CAAC,EACrE;;GAGN;CAED,OAAO,aACL,mBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,MAAM,EACH,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CACxC,UAAU,CACV,SACC,wFACD;GACH,QAAQ,EACL,SAAS,CACT,UAAU,CACV,SACC,qFACD;GACJ;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,EAAE,MAAM,aAAa;EAC1B,IAAI;GAEF,OAAO,EACL,UAAS,MAFO,aAAa,QAAQ,EAAE,EAAE,QAAW,OAAO,EAE9C,KAAK,OAAO;IAAE,MAAM;IAAQ,MAAM;IAAG,EAAE,EACrD;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,2BAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAG0B,CAClE,EACF;;GAGN;CAED,OAAO,aACL,oBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,OAAO,EAAE,QAAQ,CAAC,SAAS,yCAAyC;GACpE,OAAO,EACJ,QAAQ,CACR,UAAU,CACV,SAAS,iDAAiD;GAC9D;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,EAAE,OAAO,YAAY;EAC1B,IAAI;GACF,MAAM,EAAE,cAAc,aAAa,OAAU;GAC7C,MAAM,WAAW,MAAM,UAAU;IAC/B,OAAO;IACP,OAAO,OAAO,UAAU;IACxB,eAAe;IAChB,CAAC;GAEF,IAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,QAAQ,SAAS,KAAK,EACjD,OAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM;IAA6B,CAAC,EAC/D;GAKH,OAAO,EACL,SAHa,SAAS,KAGN,KAAK,WAAgB;IACnC,MAAM;IACN,MAAM;KACJ,SAAS,MAAM;KACf,UAAU,MAAM;KAChB,QAAQ,MAAM;KACd,UAAU,MAAM;KAChB;KACA,MAAM;KACP,CAAC,KAAK,KAAK;IACb,EAAE,EACJ;WACM,OAAO;GAGd,OAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,4BAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAG2B,CACnE,EACF;;GAGN"}
@@ -0,0 +1,6 @@
1
+ import { loadCLITools } from "./cli.mjs";
2
+ import { loadAPITools } from "./api.mjs";
3
+ import { loadInstallSkillsTool } from "./installSkills.mjs";
4
+ import { loadDocsTools } from "./docs.mjs";
5
+
6
+ export { loadAPITools, loadCLITools, loadDocsTools, loadInstallSkillsTool };
@@ -1 +1 @@
1
- {"version":3,"file":"installSkills.mjs","names":[],"sources":["../../../src/tools/installSkills.ts"],"sourcesContent":["import * as readline from 'node:readline';\nimport {\n installSkills,\n PLATFORMS,\n SKILLS,\n type Skill,\n} from '@intlayer/chokidar/cli';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport z from 'zod';\n\nexport const loadInstallSkillsTool = (server: McpServer): void => {\n server.registerTool(\n 'intlayer-install-skills',\n {\n title: 'Install Intlayer Skills',\n description:\n 'Install Intlayer documentation and skills to the project to assist AI agents. Ask the user for the platform (Cursor, VSCode, OpenCode, Claude, etc.) and which skills they want to install before calling this tool.',\n inputSchema: {\n platform: z\n .enum(PLATFORMS)\n .describe('The platform to install skills for'),\n skills: z.array(z.enum(SKILLS)).describe('List of skills to install'),\n projectRoot: z\n .string()\n .optional()\n .describe(\n 'Root directory of the project. Defaults to current directory.'\n ),\n },\n },\n\n async ({ platform, skills, projectRoot }) => {\n try {\n const root = projectRoot || process.cwd();\n const message = await installSkills(root, platform, skills);\n\n return {\n content: [\n {\n type: 'text',\n text: message,\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: `Failed to install skills: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n};\n\nexport const runInstallSkillsCLI = async (): Promise<void> => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const question = (query: string): Promise<string> =>\n new Promise((resolve) => rl.question(query, resolve));\n\n try {\n console.log('Install Intlayer Skills');\n console.log('-----------------------');\n\n const platformInput = await question(\n 'Which platform are you using? (Cursor, Windsurf, Trae, OpenCode, GitHub, Claude, VSCode, Cline, RooCode, etc. or \"Other\"): '\n );\n\n // we only accept a single platform here, not an array like the main CLI\n const platform =\n PLATFORMS.find(\n (platform) =>\n platform.toLowerCase() === platformInput.trim().toLowerCase()\n ) || ('Other' as const);\n\n console.log(`Selected platform: ${platform}`);\n\n console.log('\\nAvailable skills:');\n\n SKILLS.forEach((skill, i) => {\n console.log(`${i + 1}. ${skill}`);\n });\n\n const skillsInput = await question(\n '\\nWhich skills do you want to install? (comma separated numbers, e.g. 1,2,3 or \"all\"): '\n );\n\n let selectedSkills: Skill[] = [];\n if (skillsInput.trim().toLowerCase() === 'all') {\n selectedSkills = [...SKILLS];\n } else {\n const indices = skillsInput\n .split(',')\n .map((skill) => parseInt(skill.trim(), 10) - 1)\n .filter(\n (skill) => !Number.isNaN(skill) && skill >= 0 && skill < SKILLS.length\n );\n selectedSkills = indices.map((i) => SKILLS[i] as any);\n }\n\n if (selectedSkills.length === 0) {\n console.log('No valid skills selected. Exiting.');\n rl.close();\n return;\n }\n\n console.log(`Installing skills: ${selectedSkills.join(', ')}...`);\n const result = await installSkills(process.cwd(), platform, selectedSkills);\n console.log(result);\n } catch (error) {\n console.error('Error:', error);\n } finally {\n rl.close();\n }\n};\n"],"mappings":";;;;;AAUA,MAAa,yBAAyB,WAA4B;CAChE,OAAO,aACL,2BACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,UAAU,EACP,KAAK,UAAU,CACf,SAAS,qCAAqC;GACjD,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,CAAC,SAAS,4BAA4B;GACrE,aAAa,EACV,QAAQ,CACR,UAAU,CACV,SACC,gEACD;GACJ;EACF,EAED,OAAO,EAAE,UAAU,QAAQ,kBAAkB;EAC3C,IAAI;GAIF,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,MANU,cADT,eAAe,QAAQ,KAAK,EACC,UAAU,OAAO;IAOtD,CACF,EACF;WACM,OAAO;GACd,OAAO;IACL,SAAS,CACP;KACE,MAAM;KACN,MAAM,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;KAC1F,CACF;IACD,SAAS;IACV;;GAGN;;AAGH,MAAa,sBAAsB,YAA2B;CAC5D,MAAM,KAAK,SAAS,gBAAgB;EAClC,OAAO,QAAQ;EACf,QAAQ,QAAQ;EACjB,CAAC;CAEF,MAAM,YAAY,UAChB,IAAI,SAAS,YAAY,GAAG,SAAS,OAAO,QAAQ,CAAC;CAEvD,IAAI;EACF,QAAQ,IAAI,0BAA0B;EACtC,QAAQ,IAAI,0BAA0B;EAEtC,MAAM,gBAAgB,MAAM,SAC1B,gIACD;EAGD,MAAM,WACJ,UAAU,MACP,aACC,SAAS,aAAa,KAAK,cAAc,MAAM,CAAC,aAAa,CAChE,IAAK;EAER,QAAQ,IAAI,sBAAsB,WAAW;EAE7C,QAAQ,IAAI,sBAAsB;EAElC,OAAO,SAAS,OAAO,MAAM;GAC3B,QAAQ,IAAI,GAAG,IAAI,EAAE,IAAI,QAAQ;IACjC;EAEF,MAAM,cAAc,MAAM,SACxB,4FACD;EAED,IAAI,iBAA0B,EAAE;EAChC,IAAI,YAAY,MAAM,CAAC,aAAa,KAAK,OACvC,iBAAiB,CAAC,GAAG,OAAO;OAQ5B,iBANgB,YACb,MAAM,IAAI,CACV,KAAK,UAAU,SAAS,MAAM,MAAM,EAAE,GAAG,GAAG,EAAE,CAC9C,QACE,UAAU,CAAC,OAAO,MAAM,MAAM,IAAI,SAAS,KAAK,QAAQ,OAAO,OAE5C,CAAC,KAAK,MAAM,OAAO,GAAU;EAGvD,IAAI,eAAe,WAAW,GAAG;GAC/B,QAAQ,IAAI,qCAAqC;GACjD,GAAG,OAAO;GACV;;EAGF,QAAQ,IAAI,sBAAsB,eAAe,KAAK,KAAK,CAAC,KAAK;EACjE,MAAM,SAAS,MAAM,cAAc,QAAQ,KAAK,EAAE,UAAU,eAAe;EAC3E,QAAQ,IAAI,OAAO;UACZ,OAAO;EACd,QAAQ,MAAM,UAAU,MAAM;WACtB;EACR,GAAG,OAAO"}
1
+ {"version":3,"file":"installSkills.mjs","names":[],"sources":["../../../src/tools/installSkills.ts"],"sourcesContent":["import * as readline from 'node:readline';\nimport {\n installSkills,\n PLATFORMS,\n SKILLS,\n type Skill,\n} from '@intlayer/chokidar/cli';\nimport z from 'zod';\nimport type { McpServer } from './docs';\n\nexport const loadInstallSkillsTool = (server: McpServer): void => {\n server.registerTool(\n 'intlayer-install-skills',\n {\n title: 'Install Intlayer Skills',\n description:\n 'Install Intlayer documentation and skills to the project to assist AI agents. Ask the user for the platform (Cursor, VSCode, OpenCode, Claude, etc.) and which skills they want to install before calling this tool.',\n inputSchema: {\n platform: z\n .enum(PLATFORMS)\n .describe('The platform to install skills for'),\n skills: z.array(z.enum(SKILLS)).describe('List of skills to install'),\n projectRoot: z\n .string()\n .optional()\n .describe(\n 'Root directory of the project. Defaults to current directory.'\n ),\n },\n },\n\n async ({ platform, skills, projectRoot }) => {\n try {\n const root = projectRoot || process.cwd();\n const message = await installSkills(root, platform, skills);\n\n return {\n content: [\n {\n type: 'text',\n text: message,\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: `Failed to install skills: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n};\n\nexport const runInstallSkillsCLI = async (): Promise<void> => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const question = (query: string): Promise<string> =>\n new Promise((resolve) => rl.question(query, resolve));\n\n try {\n console.log('Install Intlayer Skills');\n console.log('-----------------------');\n\n const platformInput = await question(\n 'Which platform are you using? (Cursor, Windsurf, Trae, OpenCode, GitHub, Claude, VSCode, Cline, RooCode, etc. or \"Other\"): '\n );\n\n // we only accept a single platform here, not an array like the main CLI\n const platform =\n PLATFORMS.find(\n (platform) =>\n platform.toLowerCase() === platformInput.trim().toLowerCase()\n ) || ('Other' as const);\n\n console.log(`Selected platform: ${platform}`);\n\n console.log('\\nAvailable skills:');\n\n SKILLS.forEach((skill, i) => {\n console.log(`${i + 1}. ${skill}`);\n });\n\n const skillsInput = await question(\n '\\nWhich skills do you want to install? (comma separated numbers, e.g. 1,2,3 or \"all\"): '\n );\n\n let selectedSkills: Skill[] = [];\n if (skillsInput.trim().toLowerCase() === 'all') {\n selectedSkills = [...SKILLS];\n } else {\n const indices = skillsInput\n .split(',')\n .map((skill) => parseInt(skill.trim(), 10) - 1)\n .filter(\n (skill) => !Number.isNaN(skill) && skill >= 0 && skill < SKILLS.length\n );\n selectedSkills = indices.map((i) => SKILLS[i] as any);\n }\n\n if (selectedSkills.length === 0) {\n console.log('No valid skills selected. Exiting.');\n rl.close();\n return;\n }\n\n console.log(`Installing skills: ${selectedSkills.join(', ')}...`);\n const result = await installSkills(process.cwd(), platform, selectedSkills);\n console.log(result);\n } catch (error) {\n console.error('Error:', error);\n } finally {\n rl.close();\n }\n};\n"],"mappings":";;;;;AAUA,MAAa,yBAAyB,WAA4B;CAChE,OAAO,aACL,2BACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,UAAU,EACP,KAAK,UAAU,CACf,SAAS,qCAAqC;GACjD,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,CAAC,SAAS,4BAA4B;GACrE,aAAa,EACV,QAAQ,CACR,UAAU,CACV,SACC,gEACD;GACJ;EACF,EAED,OAAO,EAAE,UAAU,QAAQ,kBAAkB;EAC3C,IAAI;GAIF,OAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,MANU,cADT,eAAe,QAAQ,KAAK,EACC,UAAU,OAAO;IAOtD,CACF,EACF;WACM,OAAO;GACd,OAAO;IACL,SAAS,CACP;KACE,MAAM;KACN,MAAM,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;KAC1F,CACF;IACD,SAAS;IACV;;GAGN;;AAGH,MAAa,sBAAsB,YAA2B;CAC5D,MAAM,KAAK,SAAS,gBAAgB;EAClC,OAAO,QAAQ;EACf,QAAQ,QAAQ;EACjB,CAAC;CAEF,MAAM,YAAY,UAChB,IAAI,SAAS,YAAY,GAAG,SAAS,OAAO,QAAQ,CAAC;CAEvD,IAAI;EACF,QAAQ,IAAI,0BAA0B;EACtC,QAAQ,IAAI,0BAA0B;EAEtC,MAAM,gBAAgB,MAAM,SAC1B,gIACD;EAGD,MAAM,WACJ,UAAU,MACP,aACC,SAAS,aAAa,KAAK,cAAc,MAAM,CAAC,aAAa,CAChE,IAAK;EAER,QAAQ,IAAI,sBAAsB,WAAW;EAE7C,QAAQ,IAAI,sBAAsB;EAElC,OAAO,SAAS,OAAO,MAAM;GAC3B,QAAQ,IAAI,GAAG,IAAI,EAAE,IAAI,QAAQ;IACjC;EAEF,MAAM,cAAc,MAAM,SACxB,4FACD;EAED,IAAI,iBAA0B,EAAE;EAChC,IAAI,YAAY,MAAM,CAAC,aAAa,KAAK,OACvC,iBAAiB,CAAC,GAAG,OAAO;OAQ5B,iBANgB,YACb,MAAM,IAAI,CACV,KAAK,UAAU,SAAS,MAAM,MAAM,EAAE,GAAG,GAAG,EAAE,CAC9C,QACE,UAAU,CAAC,OAAO,MAAM,MAAM,IAAI,SAAS,KAAK,QAAQ,OAAO,OAE5C,CAAC,KAAK,MAAM,OAAO,GAAU;EAGvD,IAAI,eAAe,WAAW,GAAG;GAC/B,QAAQ,IAAI,qCAAqC;GACjD,GAAG,OAAO;GACV;;EAGF,QAAQ,IAAI,sBAAsB,eAAe,KAAK,KAAK,CAAC,KAAK;EACjE,MAAM,SAAS,MAAM,cAAc,QAAQ,KAAK,EAAE,UAAU,eAAe;EAC3E,QAAQ,IAAI,OAAO;UACZ,OAAO;EACd,QAAQ,MAAM,UAAU,MAAM;WACtB;EACR,GAAG,OAAO"}
@@ -1,5 +1,11 @@
1
+ import { MCPClient } from "@ai-sdk/mcp";
2
+
1
3
  //#region src/client/client.d.ts
2
4
  declare const dirname: string;
5
+ declare const loadMCPTools: (serverURL: string) => Promise<{
6
+ client: MCPClient;
7
+ tools: Record<string, any>;
8
+ }>;
3
9
  //#endregion
4
- export { dirname };
10
+ export { type MCPClient, dirname, loadMCPTools };
5
11
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","names":[],"sources":["../../../src/client/client.ts"],"mappings":";cAIa,OAAA"}
1
+ {"version":3,"file":"client.d.ts","names":[],"sources":["../../../src/client/client.ts"],"mappings":";;;cAOa,OAAA;AAAA,cAIA,YAAA,GACX,SAAA,aACC,OAAA;EAAU,MAAA,EAAQ,SAAA;EAAW,KAAA,EAAO,MAAA;AAAA"}
@@ -1,11 +1,35 @@
1
- import { McpServer } from "/Users/aymericpineau/Documents/intlayer_/node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js";
2
-
3
1
  //#region src/server/server.d.ts
4
2
  declare const dirname: string;
3
+ type ToolResult = {
4
+ content: {
5
+ type: string;
6
+ text: string;
7
+ }[];
8
+ isError?: boolean;
9
+ };
10
+ interface McpTransport {
11
+ start(server: McpServer): Promise<void>;
12
+ }
13
+ declare class McpServer {
14
+ private readonly _tools;
15
+ private readonly _info;
16
+ constructor(info: {
17
+ name: string;
18
+ version: string;
19
+ });
20
+ registerTool(name: string, config: {
21
+ title?: string;
22
+ description?: string;
23
+ inputSchema?: Record<string, any>;
24
+ annotations?: Record<string, any>;
25
+ }, handler: (params: any) => Promise<ToolResult>): void;
26
+ handleMessage(message: any): Promise<any>;
27
+ connect(transport: McpTransport): Promise<void>;
28
+ }
5
29
  type LoadServer = (options: {
6
30
  isLocal: boolean;
7
31
  }) => McpServer;
8
32
  declare const loadServer: LoadServer;
9
33
  //#endregion
10
- export { dirname, loadServer };
34
+ export { McpServer, McpTransport, dirname, loadServer };
11
35
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","names":[],"sources":["../../../src/server/server.ts"],"mappings":";;;cAUa,OAAA;AAAA,KAQR,UAAA,IAAc,OAAA;EAAW,OAAA;AAAA,MAAuB,SAAA;AAAA,cAExC,UAAA,EAAY,UAAA"}
1
+ {"version":3,"file":"server.d.ts","names":[],"sources":["../../../src/server/server.ts"],"mappings":";cAUa,OAAA;AAAA,KAQR,UAAA;EACH,OAAA;IAAW,IAAA;IAAc,IAAA;EAAA;EACzB,OAAA;AAAA;AAAA,UAWe,YAAA;EACf,KAAA,CAAM,MAAA,EAAQ,SAAA,GAAY,OAAA;AAAA;AAAA,cAGf,SAAA;EAAA,iBACM,MAAA;EAAA,iBACA,KAAA;EAEjB,WAAA,CAAY,IAAA;IAAQ,IAAA;IAAc,OAAA;EAAA;EAIlC,YAAA,CACE,IAAA,UACA,MAAA;IACE,KAAA;IACA,WAAA;IACA,WAAA,GAAc,MAAA;IACd,WAAA,GAAc,MAAA;EAAA,GAEhB,OAAA,GAAU,MAAA,UAAgB,OAAA,CAAQ,UAAA;EAkBpC,aAAA,CAAoB,OAAA,QAAe,OAAA;EAwEnC,OAAA,CAAc,SAAA,EAAW,YAAA,GAAe,OAAA;AAAA;AAAA,KAKrC,UAAA,IAAc,OAAA;EAAW,OAAA;AAAA,MAAuB,SAAA;AAAA,cAExC,UAAA,EAAY,UAAA"}
@@ -1,4 +1,4 @@
1
- import { McpServer } from "/Users/aymericpineau/Documents/intlayer_/node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js";
1
+ import { McpServer } from "./docs.js";
2
2
 
3
3
  //#region src/tools/api.d.ts
4
4
  type LoadAPITools = (server: McpServer) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","names":[],"sources":["../../../src/tools/api.ts"],"mappings":";;;KAKK,YAAA,IAAgB,MAAA,EAAQ,SAAA;AAAA,cA6DhB,YAAA,EAAc,YAAA"}
1
+ {"version":3,"file":"api.d.ts","names":[],"sources":["../../../src/tools/api.ts"],"mappings":";;;KAKK,YAAA,IAAgB,MAAA,EAAQ,SAAA;AAAA,cAkEhB,YAAA,EAAc,YAAA"}
@@ -1,4 +1,4 @@
1
- import { McpServer } from "/Users/aymericpineau/Documents/intlayer_/node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js";
1
+ import { McpServer } from "./docs.js";
2
2
 
3
3
  //#region src/tools/cli.d.ts
4
4
  type LoadCLITools = (server: McpServer) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","names":[],"sources":["../../../src/tools/cli.ts"],"mappings":";;;KAiBK,YAAA,IAAgB,MAAA,EAAQ,SAAA,KAAc,OAAA;AAAA,cAE9B,YAAA,EAAc,YAAA"}
1
+ {"version":3,"file":"cli.d.ts","names":[],"sources":["../../../src/tools/cli.ts"],"mappings":";;;KAoEK,YAAA,IAAgB,MAAA,EAAQ,SAAA,KAAc,OAAA;AAAA,cAE9B,YAAA,EAAc,YAAA"}
@@ -1,8 +1,16 @@
1
- import { McpServer } from "/Users/aymericpineau/Documents/intlayer_/node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js";
2
-
3
1
  //#region src/tools/docs.d.ts
2
+ type ToolResult = {
3
+ content: {
4
+ type: string;
5
+ text: string;
6
+ }[];
7
+ isError?: boolean;
8
+ };
9
+ type McpServer = {
10
+ registerTool(name: string, config: any, handler: (params: any) => Promise<ToolResult>): void;
11
+ };
4
12
  type LoadDocsTools = (server: McpServer) => Promise<void>;
5
13
  declare const loadDocsTools: LoadDocsTools;
6
14
  //#endregion
7
- export { loadDocsTools };
15
+ export { McpServer, ToolResult, loadDocsTools };
8
16
  //# sourceMappingURL=docs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"docs.d.ts","names":[],"sources":["../../../src/tools/docs.ts"],"mappings":";;;KAWK,aAAA,IAAiB,MAAA,EAAQ,SAAA,KAAc,OAAA;AAAA,cAE/B,aAAA,EAAe,aAAA"}
1
+ {"version":3,"file":"docs.d.ts","names":[],"sources":["../../../src/tools/docs.ts"],"mappings":";KAUY,UAAA;EACV,OAAA;IAAW,IAAA;IAAc,IAAA;EAAA;EACzB,OAAA;AAAA;AAAA,KAEU,SAAA;EACV,YAAA,CACE,IAAA,UACA,MAAA,OACA,OAAA,GAAU,MAAA,UAAgB,OAAA,CAAQ,UAAA;AAAA;AAAA,KAIjC,aAAA,IAAiB,MAAA,EAAQ,SAAA,KAAc,OAAA;AAAA,cAE/B,aAAA,EAAe,aAAA"}
@@ -0,0 +1,5 @@
1
+ import { loadDocsTools } from "./docs.js";
2
+ import { loadAPITools } from "./api.js";
3
+ import { loadCLITools } from "./cli.js";
4
+ import { loadInstallSkillsTool } from "./installSkills.js";
5
+ export { loadAPITools, loadCLITools, loadDocsTools, loadInstallSkillsTool };
@@ -1,4 +1,4 @@
1
- import { McpServer } from "/Users/aymericpineau/Documents/intlayer_/node_modules/.bun/@modelcontextprotocol+sdk@1.29.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js";
1
+ import { McpServer } from "./docs.js";
2
2
 
3
3
  //#region src/tools/installSkills.d.ts
4
4
  declare const loadInstallSkillsTool: (server: McpServer) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/mcp",
3
- "version": "8.9.4-canary.0",
3
+ "version": "8.9.5",
4
4
  "private": false,
5
5
  "description": "Intlayer MCP server. Handle MCP to help IDE to use Intlayer. It build, fill, pull, push, dictionaries",
6
6
  "keywords": [
@@ -43,6 +43,16 @@
43
43
  "require": "./dist/esm/server/sse.mjs",
44
44
  "import": "./dist/esm/server/sse.mjs"
45
45
  },
46
+ "./client": {
47
+ "types": "./dist/types/client/client.d.ts",
48
+ "require": "./dist/esm/client/client.mjs",
49
+ "import": "./dist/esm/client/client.mjs"
50
+ },
51
+ "./tools": {
52
+ "types": "./dist/types/tools/index.d.ts",
53
+ "require": "./dist/esm/tools/index.mjs",
54
+ "import": "./dist/esm/tools/index.mjs"
55
+ },
46
56
  "./package.json": "./package.json"
47
57
  },
48
58
  "main": "dist/esm/server/stdio.mjs",
@@ -56,6 +66,12 @@
56
66
  "sse": [
57
67
  "./dist/types/server/sse.d.ts"
58
68
  ],
69
+ "client": [
70
+ "./dist/types/client/client.d.ts"
71
+ ],
72
+ "tools": [
73
+ "./dist/types/tools/index.d.ts"
74
+ ],
59
75
  "package.json": [
60
76
  "./package.json"
61
77
  ]
@@ -93,28 +109,27 @@
93
109
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
94
110
  },
95
111
  "dependencies": {
96
- "@ai-sdk/mcp": "^1.0.41",
97
- "@intlayer/api": "8.9.4-canary.0",
98
- "@intlayer/chokidar": "8.9.4-canary.0",
99
- "@intlayer/cli": "8.9.4-canary.0",
100
- "@intlayer/config": "8.9.4-canary.0",
101
- "@intlayer/docs": "8.9.4-canary.0",
102
- "@intlayer/types": "8.9.4-canary.0",
112
+ "@intlayer/api": "8.9.5",
113
+ "@intlayer/chokidar": "8.9.5",
114
+ "@intlayer/cli": "8.9.5",
115
+ "@intlayer/config": "8.9.5",
116
+ "@intlayer/docs": "8.9.5",
117
+ "@intlayer/types": "8.9.5",
103
118
  "dotenv": "17.4.2",
104
119
  "express": "5.2.1",
105
120
  "zod": "4.4.3"
106
121
  },
107
122
  "devDependencies": {
108
- "@intlayer/types": "8.9.4-canary.0",
123
+ "@intlayer/types": "8.9.5",
109
124
  "@types/express": "5.0.6",
110
- "@types/node": "25.6.2",
125
+ "@types/node": "25.7.0",
111
126
  "@utils/ts-config": "1.0.4",
112
127
  "@utils/ts-config-types": "1.0.4",
113
128
  "@utils/tsdown-config": "1.0.4",
114
129
  "rimraf": "6.1.3",
115
130
  "tsdown": "0.22.00",
116
131
  "typescript": "6.0.3",
117
- "vitest": "4.1.5"
132
+ "vitest": "4.1.6"
118
133
  },
119
134
  "engines": {
120
135
  "node": ">=14.18"