@intlayer/mcp 8.0.4 → 8.0.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.
- package/dist/cjs/_virtual/{rolldown_runtime.cjs → _rolldown/runtime.cjs} +1 -1
- package/dist/cjs/client/client.cjs +2 -1
- package/dist/cjs/client/client.cjs.map +1 -1
- package/dist/cjs/client/sse.cjs +1 -1
- package/dist/cjs/server/server.cjs +5 -3
- package/dist/cjs/server/server.cjs.map +1 -1
- package/dist/cjs/server/sse.cjs +36 -75
- package/dist/cjs/server/sse.cjs.map +1 -1
- package/dist/cjs/server/stdio.cjs +1 -1
- package/dist/cjs/tools/cli.cjs +3 -2
- package/dist/cjs/tools/cli.cjs.map +1 -1
- package/dist/cjs/tools/docs.cjs +43 -3
- package/dist/cjs/tools/docs.cjs.map +1 -1
- package/dist/cjs/tools/installSkills.cjs +87 -0
- package/dist/cjs/tools/installSkills.cjs.map +1 -0
- package/dist/esm/server/server.mjs +3 -2
- package/dist/esm/server/server.mjs.map +1 -1
- package/dist/esm/server/sse.mjs +33 -72
- package/dist/esm/server/sse.mjs.map +1 -1
- package/dist/esm/tools/docs.mjs +40 -1
- package/dist/esm/tools/docs.mjs.map +1 -1
- package/dist/esm/tools/installSkills.mjs +82 -0
- package/dist/esm/tools/installSkills.mjs.map +1 -0
- package/dist/types/server/server.d.ts.map +1 -1
- package/dist/types/tools/docs.d.ts.map +1 -1
- package/dist/types/tools/installSkills.d.ts +8 -0
- package/dist/types/tools/installSkills.d.ts.map +1 -0
- package/package.json +11 -10
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
2
3
|
let node_fs = require("node:fs");
|
|
3
4
|
let node_path = require("node:path");
|
|
4
5
|
let node_url = require("node:url");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.cjs","names":["isESModule","Client"],"sources":["../../../src/client/client.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';\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\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 LoadClient = () => Client;\n\nexport const loadClient: LoadClient = () =>\n new Client({\n name: `mcp-client-for-intlayer-mcp-server`,\n version: packageJson.version,\n });\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.cjs","names":["isESModule","Client"],"sources":["../../../src/client/client.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';\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\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 LoadClient = () => Client;\n\nexport const loadClient: LoadClient = () =>\n new Client({\n name: `mcp-client-for-intlayer-mcp-server`,\n version: packageJson.version,\n });\n"],"mappings":";;;;;;;;;AAMA,MAAa,UAAkBA,+HACe,CAAC,GAC3C;AAEJ,MAAM,cAAmC,KAAK,uDACvB,SAAS,wBAAwB,EAAE,OAAO,CAChE;AAID,MAAa,mBACX,IAAIC,iDAAO;CACT,MAAM;CACN,SAAS,YAAY;CACtB,CAAC"}
|
package/dist/cjs/client/sse.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
2
2
|
const require_client_client = require('./client.cjs');
|
|
3
3
|
let node_url = require("node:url");
|
|
4
4
|
let _modelcontextprotocol_sdk_client_sse_js = require("@modelcontextprotocol/sdk/client/sse.js");
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
2
3
|
const require_tools_cli = require('../tools/cli.cjs');
|
|
3
4
|
const require_tools_docs = require('../tools/docs.cjs');
|
|
5
|
+
const require_tools_installSkills = require('../tools/installSkills.cjs');
|
|
4
6
|
let node_fs = require("node:fs");
|
|
5
7
|
let node_path = require("node:path");
|
|
6
8
|
let node_url = require("node:url");
|
|
@@ -13,11 +15,11 @@ const packageJson = JSON.parse((0, node_fs.readFileSync)((0, node_path.resolve)(
|
|
|
13
15
|
const loadServer = ({ isLocal }) => {
|
|
14
16
|
const server = new _modelcontextprotocol_sdk_server_mcp_js.McpServer({
|
|
15
17
|
name: "intlayer",
|
|
16
|
-
version: packageJson.version
|
|
17
|
-
capabilities: { resources: {} }
|
|
18
|
+
version: packageJson.version
|
|
18
19
|
});
|
|
19
20
|
if (isLocal) try {
|
|
20
21
|
require_tools_cli.loadCLITools(server);
|
|
22
|
+
require_tools_installSkills.loadInstallSkillsTool(server);
|
|
21
23
|
} catch (error) {
|
|
22
24
|
console.error("Error loading CLI tools:", error);
|
|
23
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.cjs","names":["isESModule","McpServer"],"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';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { loadCLITools } from '../tools/cli';\nimport { loadDocsTools } from '../tools/docs';\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
|
|
1
|
+
{"version":3,"file":"server.cjs","names":["isESModule","McpServer"],"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';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\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 return server;\n};\n"],"mappings":";;;;;;;;;;;;AASA,MAAa,UAAkBA,+HACe,CAAC,GAC3C;AAEJ,MAAM,cAAmC,KAAK,uDACvB,SAAS,wBAAwB,EAAE,OAAO,CAChE;AAID,MAAa,cAA0B,EAAE,cAAc;CACrD,MAAM,SAAS,IAAIC,kDAAU;EAC3B,MAAM;EACN,SAAS,YAAY;EACtB,CAAC;AAEF,KAAI,QACF,KAAI;AACF,iCAAa,OAAO;AACpB,oDAAsB,OAAO;UACtB,OAAO;AACd,UAAQ,MAAM,4BAA4B,MAAM;;AAIpD,KAAI;AACF,mCAAc,OAAO;UACd,OAAO;AACd,UAAQ,MAAM,6BAA6B,MAAM;;AAGnD,QAAO"}
|
package/dist/cjs/server/sse.cjs
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const
|
|
2
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
3
3
|
const require_server_server = require('./server.cjs');
|
|
4
|
-
let
|
|
4
|
+
let _modelcontextprotocol_sdk_server_streamableHttp_js = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
5
5
|
let dotenv = require("dotenv");
|
|
6
|
-
dotenv =
|
|
6
|
+
dotenv = require_runtime.__toESM(dotenv);
|
|
7
7
|
let express = require("express");
|
|
8
|
-
express =
|
|
8
|
+
express = require_runtime.__toESM(express);
|
|
9
9
|
|
|
10
10
|
//#region src/server/sse.ts
|
|
11
|
-
/******* Server Set Up ************/
|
|
12
11
|
const server = require_server_server.loadServer({ isLocal: false });
|
|
13
|
-
/******* Express App Set Up *******/
|
|
14
12
|
const app = (0, express.default)();
|
|
15
13
|
const env = app.get("env");
|
|
16
|
-
dotenv.default.config({
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
dotenv.default.config({
|
|
15
|
+
path: [
|
|
16
|
+
`.env.${env}.local`,
|
|
17
|
+
`.env.${env}`,
|
|
18
|
+
".env.local",
|
|
19
|
+
".env"
|
|
20
|
+
],
|
|
21
|
+
quiet: true
|
|
22
|
+
});
|
|
22
23
|
app.use((req, res, next) => {
|
|
23
24
|
res.header("Access-Control-Allow-Origin", "*");
|
|
24
25
|
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
@@ -31,72 +32,32 @@ app.use((req, res, next) => {
|
|
|
31
32
|
});
|
|
32
33
|
app.use(express.default.json());
|
|
33
34
|
const router = express.default.Router();
|
|
35
|
+
const sessionIdGenerator = () => Math.random().toString(36).slice(2);
|
|
34
36
|
const transports = {};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
res.
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
const transport = transports[sessionId];
|
|
44
|
-
if (!transport) {
|
|
45
|
-
res.status(400).send({ messages: "No transport found for sessionId." });
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
await transport.handlePostMessage(req, res, req.body);
|
|
49
|
-
});
|
|
50
|
-
router.get("/", async (_req, res) => {
|
|
51
|
-
console.info("connection request received");
|
|
52
|
-
const transport = new _modelcontextprotocol_sdk_server_sse_js.SSEServerTransport(POST_ENDPOINT, res);
|
|
53
|
-
console.info("new transport created with session id: ", transport.sessionId);
|
|
54
|
-
transports[transport.sessionId] = transport;
|
|
55
|
-
console.info(`${Object.keys(transports).length} sessions active`);
|
|
56
|
-
res.on("close", () => {
|
|
57
|
-
console.info("SSE connection closed");
|
|
58
|
-
delete transports[transport.sessionId];
|
|
59
|
-
});
|
|
60
|
-
await server.connect(transport);
|
|
61
|
-
await sendMessages(transport);
|
|
62
|
-
});
|
|
63
|
-
const sendMessages = async (transport) => {
|
|
64
|
-
try {
|
|
65
|
-
await transport.send({
|
|
66
|
-
jsonrpc: "2.0",
|
|
67
|
-
method: "sse/connection",
|
|
68
|
-
params: { message: "Stream started" }
|
|
37
|
+
router.all("/", async (req, res) => {
|
|
38
|
+
if (req.method === "GET") {
|
|
39
|
+
const sessionId = sessionIdGenerator();
|
|
40
|
+
const transport = new _modelcontextprotocol_sdk_server_streamableHttp_js.StreamableHTTPServerTransport({ sessionIdGenerator: () => sessionId });
|
|
41
|
+
transports[sessionId] = transport;
|
|
42
|
+
res.on("close", () => {
|
|
43
|
+
delete transports[sessionId];
|
|
69
44
|
});
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
await transport.send({
|
|
85
|
-
jsonrpc: "2.0",
|
|
86
|
-
method: "sse/complete",
|
|
87
|
-
params: { message: "Stream completed" }
|
|
88
|
-
});
|
|
89
|
-
console.info("Stream completed");
|
|
90
|
-
}
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error("Error sending message:", error);
|
|
93
|
-
clearInterval(interval);
|
|
94
|
-
}
|
|
95
|
-
}, 1e3);
|
|
96
|
-
} catch (error) {
|
|
97
|
-
console.error("Error in startSending:", error);
|
|
45
|
+
await server.connect(transport);
|
|
46
|
+
await transport.handleRequest(req, res);
|
|
47
|
+
} else if (req.method === "POST") {
|
|
48
|
+
const sessionId = req.query.sessionId;
|
|
49
|
+
if (typeof sessionId !== "string") {
|
|
50
|
+
res.status(400).send({ messages: "Bad session id." });
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const transport = transports[sessionId];
|
|
54
|
+
if (!transport) {
|
|
55
|
+
res.status(400).send({ messages: "No transport found for sessionId." });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
await transport.handleRequest(req, res, req.body);
|
|
98
59
|
}
|
|
99
|
-
};
|
|
60
|
+
});
|
|
100
61
|
app.use("/", router);
|
|
101
62
|
app.use("/health", (_req, res) => {
|
|
102
63
|
res.send("OK");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.cjs","names":["loadServer","
|
|
1
|
+
{"version":3,"file":"sse.cjs","names":["loadServer","StreamableHTTPServerTransport"],"sources":["../../../src/server/sse.ts"],"sourcesContent":["#!/usr/bin/env node\n\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 server = loadServer({ isLocal: false });\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');\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 sessionIdGenerator = () => Math.random().toString(36).slice(2);\nconst transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};\n\nrouter.all('/', async (req: Request, res: Response) => {\n if (req.method === 'GET') {\n const sessionId = sessionIdGenerator();\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => sessionId,\n });\n transports[sessionId] = transport;\n res.on('close', () => {\n delete transports[sessionId];\n });\n await server.connect(transport);\n await transport.handleRequest(req, res);\n } else if (req.method === 'POST') {\n const sessionId = req.query.sessionId;\n if (typeof sessionId !== 'string') {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n const transport = transports[sessionId];\n if (!transport) {\n res.status(400).send({ messages: 'No transport found for sessionId.' });\n return;\n }\n await transport.handleRequest(req, res, req.body);\n }\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,SAASA,iCAAW,EAAE,SAAS,OAAO,CAAC;AAC7C,MAAM,4BAAe;AACrB,MAAM,MAAM,IAAI,IAAI,MAAM;AAE1B,eAAO,OAAO;CACZ,MAAM;EAAC,QAAQ,IAAI;EAAS,QAAQ;EAAO;EAAc;EAAO;CAChE,OAAO;CACR,CAAC;AAEF,IAAI,KAAK,KAAK,KAAK,SAAS;AAC1B,KAAI,OAAO,+BAA+B,IAAI;AAC9C,KAAI,OAAO,gCAAgC,qBAAqB;AAChE,KAAI,OAAO,gCAAgC,eAAe;AAC1D,KAAI,IAAI,WAAW,WAAW;AAC5B,MAAI,WAAW,IAAI;AACnB;;AAEF,OAAM;EACN;AAEF,IAAI,IAAI,gBAAQ,MAAM,CAAC;AACvB,MAAM,SAAS,gBAAQ,QAAQ;AAE/B,MAAM,2BAA2B,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE;AACpE,MAAM,aAAqE,EAAE;AAE7E,OAAO,IAAI,KAAK,OAAO,KAAc,QAAkB;AACrD,KAAI,IAAI,WAAW,OAAO;EACxB,MAAM,YAAY,oBAAoB;EACtC,MAAM,YAAY,IAAIC,iFAA8B,EAClD,0BAA0B,WAC3B,CAAC;AACF,aAAW,aAAa;AACxB,MAAI,GAAG,eAAe;AACpB,UAAO,WAAW;IAClB;AACF,QAAM,OAAO,QAAQ,UAAU;AAC/B,QAAM,UAAU,cAAc,KAAK,IAAI;YAC9B,IAAI,WAAW,QAAQ;EAChC,MAAM,YAAY,IAAI,MAAM;AAC5B,MAAI,OAAO,cAAc,UAAU;AACjC,OAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;AACrD;;EAEF,MAAM,YAAY,WAAW;AAC7B,MAAI,CAAC,WAAW;AACd,OAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,qCAAqC,CAAC;AACvE;;AAEF,QAAM,UAAU,cAAc,KAAK,KAAK,IAAI,KAAK;;EAEnD;AAEF,IAAI,IAAI,KAAK,OAAO;AACpB,IAAI,IAAI,YAAY,MAAe,QAAkB;AACnD,KAAI,KAAK,KAAK;EACd;AAEF,MAAM,OAAO,QAAQ,IAAI,QAAQ;AACjC,IAAI,OAAO,YAAY;AACrB,SAAQ,KAAK,gDAAgD,OAAO;EACpE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const
|
|
2
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
3
3
|
const require_server_server = require('./server.cjs');
|
|
4
4
|
let _modelcontextprotocol_sdk_server_stdio_js = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
5
5
|
|
package/dist/cjs/tools/cli.cjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
2
3
|
let node_path = require("node:path");
|
|
3
4
|
let _intlayer_chokidar = require("@intlayer/chokidar");
|
|
4
5
|
let _intlayer_cli = require("@intlayer/cli");
|
|
5
6
|
let _intlayer_types = require("@intlayer/types");
|
|
6
7
|
let zod_v3 = require("zod/v3");
|
|
7
|
-
zod_v3 =
|
|
8
|
+
zod_v3 = require_runtime.__toESM(zod_v3);
|
|
8
9
|
|
|
9
10
|
//#region src/tools/cli.ts
|
|
10
11
|
const loadCLITools = async (server) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.cjs","names":["z","Locales"],"sources":["../../../src/tools/cli.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport { listProjects } from '@intlayer/chokidar';\nimport {\n build,\n fill,\n init,\n listContentDeclarationRows,\n listMissingTranslations,\n pull,\n push,\n transform,\n} from '@intlayer/cli';\nimport { Locales, type LogConfig } from '@intlayer/types';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport z from 'zod/v3';\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(Locales.ALL_LOCALES)\n .optional()\n .describe('Source locale'),\n outputLocales: z\n .union([\n z.nativeEnum(Locales.ALL_LOCALES),\n z.array(z.nativeEnum(Locales.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-transform',\n {\n title: 'Transform Component',\n description:\n 'Transform an existing component to use Intlayer. Trigger this action to transform an existing component to be multilingual. If the component does not exist, create a normal React component including text in JSX, and then trigger this tool to transform it.',\n inputSchema: {\n file: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('List of files to transform'),\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 transform({\n files: Array.isArray(props.file)\n ? props.file\n : props.file\n ? [props.file]\n : undefined,\n outputContentDeclarations: props.outputContentDeclarations,\n configOptions: props.configOptions,\n });\n\n return {\n content: [\n {\n type: 'text',\n text: 'Transform 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: `Transform 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.cjs","names":["z","Locales"],"sources":["../../../src/tools/cli.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport { listProjects } from '@intlayer/chokidar';\nimport {\n build,\n fill,\n init,\n listContentDeclarationRows,\n listMissingTranslations,\n pull,\n push,\n transform,\n} from '@intlayer/cli';\nimport { Locales, type LogConfig } from '@intlayer/types';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport z from 'zod/v3';\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(Locales.ALL_LOCALES)\n .optional()\n .describe('Source locale'),\n outputLocales: z\n .union([\n z.nativeEnum(Locales.ALL_LOCALES),\n z.array(z.nativeEnum(Locales.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-transform',\n {\n title: 'Transform Component',\n description:\n 'Transform an existing component to use Intlayer. Trigger this action to transform an existing component to be multilingual. If the component does not exist, create a normal React component including text in JSX, and then trigger this tool to transform it.',\n inputSchema: {\n file: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe('List of files to transform'),\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 transform({\n files: Array.isArray(props.file)\n ? props.file\n : props.file\n ? [props.file]\n : undefined,\n outputContentDeclarations: props.outputContentDeclarations,\n configOptions: props.configOptions,\n });\n\n return {\n content: [\n {\n type: 'text',\n text: 'Transform 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: `Transform 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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"}
|
package/dist/cjs/tools/docs.cjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
2
3
|
let zod_v3 = require("zod/v3");
|
|
3
|
-
zod_v3 =
|
|
4
|
+
zod_v3 = require_runtime.__toESM(zod_v3);
|
|
5
|
+
let _intlayer_api = require("@intlayer/api");
|
|
4
6
|
let _intlayer_docs = require("@intlayer/docs");
|
|
5
7
|
|
|
6
8
|
//#region src/tools/docs.ts
|
|
@@ -53,7 +55,7 @@ const loadDocsTools = async (server) => {
|
|
|
53
55
|
annotations: { readOnlyHint: true }
|
|
54
56
|
}, async ({ slug, strict }) => {
|
|
55
57
|
try {
|
|
56
|
-
return { content: (await (0, _intlayer_docs.getDocBySlug)(slug, void 0, strict)).map((d) => ({
|
|
58
|
+
return { content: (await (0, _intlayer_docs.getDocBySlug)(slug ?? [], void 0, strict)).map((d) => ({
|
|
57
59
|
type: "text",
|
|
58
60
|
text: d
|
|
59
61
|
})) };
|
|
@@ -64,6 +66,44 @@ const loadDocsTools = async (server) => {
|
|
|
64
66
|
}] };
|
|
65
67
|
}
|
|
66
68
|
});
|
|
69
|
+
server.registerTool("fetch-doc-chunks", {
|
|
70
|
+
title: "Fetch Doc Chunks",
|
|
71
|
+
description: "Fetch related doc chunks using keywords or questions. This tool will return the most relevant chunks of documentation based on the input query.",
|
|
72
|
+
inputSchema: {
|
|
73
|
+
query: zod_v3.default.string().describe("The keywords or question to search for"),
|
|
74
|
+
limit: zod_v3.default.number().optional().describe("The number of chunks to retrieve (default: 10)")
|
|
75
|
+
},
|
|
76
|
+
annotations: { readOnlyHint: true }
|
|
77
|
+
}, async ({ query, limit }) => {
|
|
78
|
+
try {
|
|
79
|
+
const { searchDoc } = (0, _intlayer_api.getSearchAPI)();
|
|
80
|
+
const response = await searchDoc({
|
|
81
|
+
input: query,
|
|
82
|
+
limit: limit?.toString(),
|
|
83
|
+
returnContent: "true"
|
|
84
|
+
});
|
|
85
|
+
if (!response.data || !Array.isArray(response.data)) return { content: [{
|
|
86
|
+
type: "text",
|
|
87
|
+
text: "No relevant chunks found."
|
|
88
|
+
}] };
|
|
89
|
+
return { content: response.data.map((chunk) => ({
|
|
90
|
+
type: "text",
|
|
91
|
+
text: [
|
|
92
|
+
`File: ${chunk.fileKey}`,
|
|
93
|
+
`Title: ${chunk.docName}`,
|
|
94
|
+
`URL: ${chunk.docUrl}`,
|
|
95
|
+
`Chunk: ${chunk.chunkNumber}`,
|
|
96
|
+
`Content:`,
|
|
97
|
+
chunk.content
|
|
98
|
+
].join("\n")
|
|
99
|
+
})) };
|
|
100
|
+
} catch (error) {
|
|
101
|
+
return { content: [{
|
|
102
|
+
type: "text",
|
|
103
|
+
text: `Fetch doc chunks failed: ${error instanceof Error ? error.message : "An unknown error occurred"}`
|
|
104
|
+
}] };
|
|
105
|
+
}
|
|
106
|
+
});
|
|
67
107
|
};
|
|
68
108
|
|
|
69
109
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.cjs","names":["z"],"sources":["../../../src/tools/docs.ts"],"sourcesContent":["import 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/v3';\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"],"mappings":"
|
|
1
|
+
{"version":3,"file":"docs.cjs","names":["z"],"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/v3';\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,4CAAwB;AAE9B,QAAO,aACL,gBACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EAAE;EACf,aAAa,EACX,cAAc,MACf;EACF,EACD,YAAY;AACV,MAAI;GACF,MAAM,qBAAqB,gDAA4B;AAEvD,UAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,KAAK,UAAU,oBAAoB,MAAM,EAAE;IAClD,CACF,EACF;WACM,OAAO;AAGd,UAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,wBAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAGuB,CAC/D,EACF;;GAGN;AAED,QAAO,aACL,WACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,QAAQA,eAAE,KAAK,SAAkC,EAClD;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,EAAE,aAAa;AACpB,MAAI;AAEF,UAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAFhB,iCAAa,OAAiB;IAEH,CAAC,EACvC;WACM,OAAO;AAGd,UAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,mBAFhC,iBAAiB,QAAQ,MAAM,UAAU;IAE0B,CAAC,EACrE;;GAGN;AAED,QAAO,aACL,mBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,MAAMA,eACH,MAAM,CAACA,eAAE,QAAQ,EAAEA,eAAE,MAAMA,eAAE,QAAQ,CAAC,CAAC,CAAC,CACxC,UAAU,CACV,SACC,wFACD;GACH,QAAQA,eACL,SAAS,CACT,UAAU,CACV,SACC,qFACD;GACJ;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,EAAE,MAAM,aAAa;AAC1B,MAAI;AAEF,UAAO,EACL,UAFU,uCAAmB,QAAQ,EAAE,EAAE,QAAW,OAAO,EAE9C,KAAK,OAAO;IAAE,MAAM;IAAQ,MAAM;IAAG,EAAE,EACrD;WACM,OAAO;AAGd,UAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,2BAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAG0B,CAClE,EACF;;GAGN;AAED,QAAO,aACL,oBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,OAAOA,eAAE,QAAQ,CAAC,SAAS,yCAAyC;GACpE,OAAOA,eACJ,QAAQ,CACR,UAAU,CACV,SAAS,iDAAiD;GAC9D;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,EAAE,OAAO,YAAY;AAC1B,MAAI;GACF,MAAM,EAAE,+CAA4B;GACpC,MAAM,WAAW,MAAM,UAAU;IAC/B,OAAO;IACP,OAAO,OAAO,UAAU;IACxB,eAAe;IAChB,CAAC;AAEF,OAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,QAAQ,SAAS,KAAK,CACjD,QAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM;IAA6B,CAAC,EAC/D;AAKH,UAAO,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;AAGd,UAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,4BAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAG2B,CACnE,EACF;;GAGN"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
let _intlayer_chokidar = require("@intlayer/chokidar");
|
|
4
|
+
let node_readline = require("node:readline");
|
|
5
|
+
node_readline = require_runtime.__toESM(node_readline);
|
|
6
|
+
let zod = require("zod");
|
|
7
|
+
zod = require_runtime.__toESM(zod);
|
|
8
|
+
|
|
9
|
+
//#region src/tools/installSkills.ts
|
|
10
|
+
const loadInstallSkillsTool = (server) => {
|
|
11
|
+
server.registerTool("intlayer-install-skills", {
|
|
12
|
+
title: "Install Intlayer Skills",
|
|
13
|
+
description: "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.",
|
|
14
|
+
inputSchema: {
|
|
15
|
+
platform: zod.default.enum([
|
|
16
|
+
"Cursor",
|
|
17
|
+
"VSCode",
|
|
18
|
+
"OpenCode",
|
|
19
|
+
"Claude",
|
|
20
|
+
"Other"
|
|
21
|
+
]).describe("The platform to install skills for"),
|
|
22
|
+
skills: zod.default.array(zod.default.enum(_intlayer_chokidar.SKILLS)).describe("List of skills to install"),
|
|
23
|
+
projectRoot: zod.default.string().optional().describe("Root directory of the project. Defaults to current directory.")
|
|
24
|
+
}
|
|
25
|
+
}, async ({ platform, skills, projectRoot }) => {
|
|
26
|
+
try {
|
|
27
|
+
return { content: [{
|
|
28
|
+
type: "text",
|
|
29
|
+
text: await (0, _intlayer_chokidar.installSkills)(projectRoot || process.cwd(), platform, skills)
|
|
30
|
+
}] };
|
|
31
|
+
} catch (error) {
|
|
32
|
+
return {
|
|
33
|
+
content: [{
|
|
34
|
+
type: "text",
|
|
35
|
+
text: `Failed to install skills: ${error instanceof Error ? error.message : String(error)}`
|
|
36
|
+
}],
|
|
37
|
+
isError: true
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
const runInstallSkillsCLI = async () => {
|
|
43
|
+
const rl = node_readline.createInterface({
|
|
44
|
+
input: process.stdin,
|
|
45
|
+
output: process.stdout
|
|
46
|
+
});
|
|
47
|
+
const question = (query) => new Promise((resolve) => rl.question(query, resolve));
|
|
48
|
+
try {
|
|
49
|
+
console.log("Install Intlayer Skills");
|
|
50
|
+
console.log("-----------------------");
|
|
51
|
+
const platformInput = await question("Which platform are you using? (Cursor, VSCode, OpenCode, Claude, Other): ");
|
|
52
|
+
const platform = [
|
|
53
|
+
"Cursor",
|
|
54
|
+
"VSCode",
|
|
55
|
+
"OpenCode",
|
|
56
|
+
"Claude",
|
|
57
|
+
"Other"
|
|
58
|
+
].find((p) => p.toLowerCase() === platformInput.trim().toLowerCase()) || "Other";
|
|
59
|
+
console.log(`Selected platform: ${platform}`);
|
|
60
|
+
const availableSkills = _intlayer_chokidar.SKILLS;
|
|
61
|
+
console.log("\nAvailable skills:");
|
|
62
|
+
availableSkills.forEach((s, i) => {
|
|
63
|
+
console.log(`${i + 1}. ${s}`);
|
|
64
|
+
});
|
|
65
|
+
const skillsInput = await question("\nWhich skills do you want to install? (comma separated numbers, e.g. 1,2,3 or \"all\"): ");
|
|
66
|
+
let selectedSkills = [];
|
|
67
|
+
if (skillsInput.trim().toLowerCase() === "all") selectedSkills = [...availableSkills];
|
|
68
|
+
else selectedSkills = skillsInput.split(",").map((s) => parseInt(s.trim()) - 1).filter((i) => !isNaN(i) && i >= 0 && i < availableSkills.length).map((i) => availableSkills[i]);
|
|
69
|
+
if (selectedSkills.length === 0) {
|
|
70
|
+
console.log("No valid skills selected. Exiting.");
|
|
71
|
+
rl.close();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
console.log(`Installing skills: ${selectedSkills.join(", ")}...`);
|
|
75
|
+
const result = await (0, _intlayer_chokidar.installSkills)(process.cwd(), platform, selectedSkills);
|
|
76
|
+
console.log(result);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error("Error:", error);
|
|
79
|
+
} finally {
|
|
80
|
+
rl.close();
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
exports.loadInstallSkillsTool = loadInstallSkillsTool;
|
|
86
|
+
exports.runInstallSkillsCLI = runInstallSkillsCLI;
|
|
87
|
+
//# sourceMappingURL=installSkills.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installSkills.cjs","names":["z","SKILLS","readline"],"sources":["../../../src/tools/installSkills.ts"],"sourcesContent":["import * as readline from 'node:readline';\nimport { installSkills, SKILLS, type Skill } from '@intlayer/chokidar';\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(['Cursor', 'VSCode', 'OpenCode', 'Claude', 'Other'])\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 async ({ platform, skills, projectRoot }) => {\n try {\n const root = projectRoot || process.cwd();\n const message = await installSkills(\n root,\n platform as any,\n skills as any\n );\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, VSCode, OpenCode, Claude, Other): '\n );\n const platform = (['Cursor', 'VSCode', 'OpenCode', 'Claude', 'Other'].find(\n (p) => p.toLowerCase() === platformInput.trim().toLowerCase()\n ) || 'Other') as 'Cursor' | 'VSCode' | 'OpenCode' | 'Claude' | 'Other';\n\n console.log(`Selected platform: ${platform}`);\n\n const availableSkills = SKILLS;\n console.log('\\nAvailable skills:');\n availableSkills.forEach((s, i) => {\n console.log(`${i + 1}. ${s}`);\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 = [...availableSkills];\n } else {\n const indices = skillsInput\n .split(',')\n .map((s) => parseInt(s.trim()) - 1)\n .filter((i) => !isNaN(i) && i >= 0 && i < availableSkills.length);\n selectedSkills = indices.map((i) => availableSkills[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":";;;;;;;;;AAKA,MAAa,yBAAyB,WAA4B;AAChE,QAAO,aACL,2BACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,UAAUA,YACP,KAAK;IAAC;IAAU;IAAU;IAAY;IAAU;IAAQ,CAAC,CACzD,SAAS,qCAAqC;GACjD,QAAQA,YAAE,MAAMA,YAAE,KAAKC,0BAAO,CAAC,CAAC,SAAS,4BAA4B;GACrE,aAAaD,YACV,QAAQ,CACR,UAAU,CACV,SACC,gEACD;GACJ;EACF,EACD,OAAO,EAAE,UAAU,QAAQ,kBAAkB;AAC3C,MAAI;AAQF,UAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAVU,4CADH,eAAe,QAAQ,KAAK,EAGvC,UACA,OACD;IAOI,CACF,EACF;WACM,OAAO;AACd,UAAO;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,KAAKE,cAAS,gBAAgB;EAClC,OAAO,QAAQ;EACf,QAAQ,QAAQ;EACjB,CAAC;CAEF,MAAM,YAAY,UAChB,IAAI,SAAS,YAAY,GAAG,SAAS,OAAO,QAAQ,CAAC;AAEvD,KAAI;AACF,UAAQ,IAAI,0BAA0B;AACtC,UAAQ,IAAI,0BAA0B;EAEtC,MAAM,gBAAgB,MAAM,SAC1B,4EACD;EACD,MAAM,WAAY;GAAC;GAAU;GAAU;GAAY;GAAU;GAAQ,CAAC,MACnE,MAAM,EAAE,aAAa,KAAK,cAAc,MAAM,CAAC,aAAa,CAC9D,IAAI;AAEL,UAAQ,IAAI,sBAAsB,WAAW;EAE7C,MAAM,kBAAkBD;AACxB,UAAQ,IAAI,sBAAsB;AAClC,kBAAgB,SAAS,GAAG,MAAM;AAChC,WAAQ,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI;IAC7B;EAEF,MAAM,cAAc,MAAM,SACxB,4FACD;EAED,IAAI,iBAA0B,EAAE;AAChC,MAAI,YAAY,MAAM,CAAC,aAAa,KAAK,MACvC,kBAAiB,CAAC,GAAG,gBAAgB;MAMrC,kBAJgB,YACb,MAAM,IAAI,CACV,KAAK,MAAM,SAAS,EAAE,MAAM,CAAC,GAAG,EAAE,CAClC,QAAQ,MAAM,CAAC,MAAM,EAAE,IAAI,KAAK,KAAK,IAAI,gBAAgB,OAAO,CAC1C,KAAK,MAAM,gBAAgB,GAAU;AAGhE,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAQ,IAAI,qCAAqC;AACjD,MAAG,OAAO;AACV;;AAGF,UAAQ,IAAI,sBAAsB,eAAe,KAAK,KAAK,CAAC,KAAK;EACjE,MAAM,SAAS,4CAAoB,QAAQ,KAAK,EAAE,UAAU,eAAe;AAC3E,UAAQ,IAAI,OAAO;UACZ,OAAO;AACd,UAAQ,MAAM,UAAU,MAAM;WACtB;AACR,KAAG,OAAO"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { loadCLITools } from "../tools/cli.mjs";
|
|
2
2
|
import { loadDocsTools } from "../tools/docs.mjs";
|
|
3
|
+
import { loadInstallSkillsTool } from "../tools/installSkills.mjs";
|
|
3
4
|
import { readFileSync } from "node:fs";
|
|
4
5
|
import { dirname as dirname$1, resolve } from "node:path";
|
|
5
6
|
import { fileURLToPath } from "node:url";
|
|
@@ -12,11 +13,11 @@ const packageJson = JSON.parse(readFileSync(resolve(dirname, "../../../package.j
|
|
|
12
13
|
const loadServer = ({ isLocal }) => {
|
|
13
14
|
const server = new McpServer({
|
|
14
15
|
name: "intlayer",
|
|
15
|
-
version: packageJson.version
|
|
16
|
-
capabilities: { resources: {} }
|
|
16
|
+
version: packageJson.version
|
|
17
17
|
});
|
|
18
18
|
if (isLocal) try {
|
|
19
19
|
loadCLITools(server);
|
|
20
|
+
loadInstallSkillsTool(server);
|
|
20
21
|
} catch (error) {
|
|
21
22
|
console.error("Error loading CLI tools:", error);
|
|
22
23
|
}
|
|
@@ -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';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { loadCLITools } from '../tools/cli';\nimport { loadDocsTools } from '../tools/docs';\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
|
|
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';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\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 return server;\n};\n"],"mappings":";;;;;;;;;;AASA,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;AAEF,KAAI,QACF,KAAI;AACF,eAAa,OAAO;AACpB,wBAAsB,OAAO;UACtB,OAAO;AACd,UAAQ,MAAM,4BAA4B,MAAM;;AAIpD,KAAI;AACF,gBAAc,OAAO;UACd,OAAO;AACd,UAAQ,MAAM,6BAA6B,MAAM;;AAGnD,QAAO"}
|
package/dist/esm/server/sse.mjs
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { loadServer } from "./server.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
4
|
import dotenv from "dotenv";
|
|
5
5
|
import express from "express";
|
|
6
6
|
|
|
7
7
|
//#region src/server/sse.ts
|
|
8
|
-
/******* Server Set Up ************/
|
|
9
8
|
const server = loadServer({ isLocal: false });
|
|
10
|
-
/******* Express App Set Up *******/
|
|
11
9
|
const app = express();
|
|
12
10
|
const env = app.get("env");
|
|
13
|
-
dotenv.config({
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
dotenv.config({
|
|
12
|
+
path: [
|
|
13
|
+
`.env.${env}.local`,
|
|
14
|
+
`.env.${env}`,
|
|
15
|
+
".env.local",
|
|
16
|
+
".env"
|
|
17
|
+
],
|
|
18
|
+
quiet: true
|
|
19
|
+
});
|
|
19
20
|
app.use((req, res, next) => {
|
|
20
21
|
res.header("Access-Control-Allow-Origin", "*");
|
|
21
22
|
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
@@ -28,72 +29,32 @@ app.use((req, res, next) => {
|
|
|
28
29
|
});
|
|
29
30
|
app.use(express.json());
|
|
30
31
|
const router = express.Router();
|
|
32
|
+
const sessionIdGenerator = () => Math.random().toString(36).slice(2);
|
|
31
33
|
const transports = {};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
res.
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
const transport = transports[sessionId];
|
|
41
|
-
if (!transport) {
|
|
42
|
-
res.status(400).send({ messages: "No transport found for sessionId." });
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
await transport.handlePostMessage(req, res, req.body);
|
|
46
|
-
});
|
|
47
|
-
router.get("/", async (_req, res) => {
|
|
48
|
-
console.info("connection request received");
|
|
49
|
-
const transport = new SSEServerTransport(POST_ENDPOINT, res);
|
|
50
|
-
console.info("new transport created with session id: ", transport.sessionId);
|
|
51
|
-
transports[transport.sessionId] = transport;
|
|
52
|
-
console.info(`${Object.keys(transports).length} sessions active`);
|
|
53
|
-
res.on("close", () => {
|
|
54
|
-
console.info("SSE connection closed");
|
|
55
|
-
delete transports[transport.sessionId];
|
|
56
|
-
});
|
|
57
|
-
await server.connect(transport);
|
|
58
|
-
await sendMessages(transport);
|
|
59
|
-
});
|
|
60
|
-
const sendMessages = async (transport) => {
|
|
61
|
-
try {
|
|
62
|
-
await transport.send({
|
|
63
|
-
jsonrpc: "2.0",
|
|
64
|
-
method: "sse/connection",
|
|
65
|
-
params: { message: "Stream started" }
|
|
34
|
+
router.all("/", async (req, res) => {
|
|
35
|
+
if (req.method === "GET") {
|
|
36
|
+
const sessionId = sessionIdGenerator();
|
|
37
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => sessionId });
|
|
38
|
+
transports[sessionId] = transport;
|
|
39
|
+
res.on("close", () => {
|
|
40
|
+
delete transports[sessionId];
|
|
66
41
|
});
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
await transport.send({
|
|
82
|
-
jsonrpc: "2.0",
|
|
83
|
-
method: "sse/complete",
|
|
84
|
-
params: { message: "Stream completed" }
|
|
85
|
-
});
|
|
86
|
-
console.info("Stream completed");
|
|
87
|
-
}
|
|
88
|
-
} catch (error) {
|
|
89
|
-
console.error("Error sending message:", error);
|
|
90
|
-
clearInterval(interval);
|
|
91
|
-
}
|
|
92
|
-
}, 1e3);
|
|
93
|
-
} catch (error) {
|
|
94
|
-
console.error("Error in startSending:", error);
|
|
42
|
+
await server.connect(transport);
|
|
43
|
+
await transport.handleRequest(req, res);
|
|
44
|
+
} else if (req.method === "POST") {
|
|
45
|
+
const sessionId = req.query.sessionId;
|
|
46
|
+
if (typeof sessionId !== "string") {
|
|
47
|
+
res.status(400).send({ messages: "Bad session id." });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const transport = transports[sessionId];
|
|
51
|
+
if (!transport) {
|
|
52
|
+
res.status(400).send({ messages: "No transport found for sessionId." });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
await transport.handleRequest(req, res, req.body);
|
|
95
56
|
}
|
|
96
|
-
};
|
|
57
|
+
});
|
|
97
58
|
app.use("/", router);
|
|
98
59
|
app.use("/health", (_req, res) => {
|
|
99
60
|
res.send("OK");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.mjs","names":[],"sources":["../../../src/server/sse.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {
|
|
1
|
+
{"version":3,"file":"sse.mjs","names":[],"sources":["../../../src/server/sse.ts"],"sourcesContent":["#!/usr/bin/env node\n\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 server = loadServer({ isLocal: false });\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');\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 sessionIdGenerator = () => Math.random().toString(36).slice(2);\nconst transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};\n\nrouter.all('/', async (req: Request, res: Response) => {\n if (req.method === 'GET') {\n const sessionId = sessionIdGenerator();\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => sessionId,\n });\n transports[sessionId] = transport;\n res.on('close', () => {\n delete transports[sessionId];\n });\n await server.connect(transport);\n await transport.handleRequest(req, res);\n } else if (req.method === 'POST') {\n const sessionId = req.query.sessionId;\n if (typeof sessionId !== 'string') {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n const transport = transports[sessionId];\n if (!transport) {\n res.status(400).send({ messages: 'No transport found for sessionId.' });\n return;\n }\n await transport.handleRequest(req, res, req.body);\n }\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,SAAS,WAAW,EAAE,SAAS,OAAO,CAAC;AAC7C,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;AAC1B,KAAI,OAAO,+BAA+B,IAAI;AAC9C,KAAI,OAAO,gCAAgC,qBAAqB;AAChE,KAAI,OAAO,gCAAgC,eAAe;AAC1D,KAAI,IAAI,WAAW,WAAW;AAC5B,MAAI,WAAW,IAAI;AACnB;;AAEF,OAAM;EACN;AAEF,IAAI,IAAI,QAAQ,MAAM,CAAC;AACvB,MAAM,SAAS,QAAQ,QAAQ;AAE/B,MAAM,2BAA2B,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE;AACpE,MAAM,aAAqE,EAAE;AAE7E,OAAO,IAAI,KAAK,OAAO,KAAc,QAAkB;AACrD,KAAI,IAAI,WAAW,OAAO;EACxB,MAAM,YAAY,oBAAoB;EACtC,MAAM,YAAY,IAAI,8BAA8B,EAClD,0BAA0B,WAC3B,CAAC;AACF,aAAW,aAAa;AACxB,MAAI,GAAG,eAAe;AACpB,UAAO,WAAW;IAClB;AACF,QAAM,OAAO,QAAQ,UAAU;AAC/B,QAAM,UAAU,cAAc,KAAK,IAAI;YAC9B,IAAI,WAAW,QAAQ;EAChC,MAAM,YAAY,IAAI,MAAM;AAC5B,MAAI,OAAO,cAAc,UAAU;AACjC,OAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;AACrD;;EAEF,MAAM,YAAY,WAAW;AAC7B,MAAI,CAAC,WAAW;AACd,OAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,qCAAqC,CAAC;AACvE;;AAEF,QAAM,UAAU,cAAc,KAAK,KAAK,IAAI,KAAK;;EAEnD;AAEF,IAAI,IAAI,KAAK,OAAO;AACpB,IAAI,IAAI,YAAY,MAAe,QAAkB;AACnD,KAAI,KAAK,KAAK;EACd;AAEF,MAAM,OAAO,QAAQ,IAAI,QAAQ;AACjC,IAAI,OAAO,YAAY;AACrB,SAAQ,KAAK,gDAAgD,OAAO;EACpE"}
|
package/dist/esm/tools/docs.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import z from "zod/v3";
|
|
2
|
+
import { getSearchAPI } from "@intlayer/api";
|
|
2
3
|
import { getDoc, getDocBySlug, getDocMetadataRecord, getDocsKeys } from "@intlayer/docs";
|
|
3
4
|
|
|
4
5
|
//#region src/tools/docs.ts
|
|
@@ -51,7 +52,7 @@ const loadDocsTools = async (server) => {
|
|
|
51
52
|
annotations: { readOnlyHint: true }
|
|
52
53
|
}, async ({ slug, strict }) => {
|
|
53
54
|
try {
|
|
54
|
-
return { content: (await getDocBySlug(slug, void 0, strict)).map((d) => ({
|
|
55
|
+
return { content: (await getDocBySlug(slug ?? [], void 0, strict)).map((d) => ({
|
|
55
56
|
type: "text",
|
|
56
57
|
text: d
|
|
57
58
|
})) };
|
|
@@ -62,6 +63,44 @@ const loadDocsTools = async (server) => {
|
|
|
62
63
|
}] };
|
|
63
64
|
}
|
|
64
65
|
});
|
|
66
|
+
server.registerTool("fetch-doc-chunks", {
|
|
67
|
+
title: "Fetch Doc Chunks",
|
|
68
|
+
description: "Fetch related doc chunks using keywords or questions. This tool will return the most relevant chunks of documentation based on the input query.",
|
|
69
|
+
inputSchema: {
|
|
70
|
+
query: z.string().describe("The keywords or question to search for"),
|
|
71
|
+
limit: z.number().optional().describe("The number of chunks to retrieve (default: 10)")
|
|
72
|
+
},
|
|
73
|
+
annotations: { readOnlyHint: true }
|
|
74
|
+
}, async ({ query, limit }) => {
|
|
75
|
+
try {
|
|
76
|
+
const { searchDoc } = getSearchAPI();
|
|
77
|
+
const response = await searchDoc({
|
|
78
|
+
input: query,
|
|
79
|
+
limit: limit?.toString(),
|
|
80
|
+
returnContent: "true"
|
|
81
|
+
});
|
|
82
|
+
if (!response.data || !Array.isArray(response.data)) return { content: [{
|
|
83
|
+
type: "text",
|
|
84
|
+
text: "No relevant chunks found."
|
|
85
|
+
}] };
|
|
86
|
+
return { content: response.data.map((chunk) => ({
|
|
87
|
+
type: "text",
|
|
88
|
+
text: [
|
|
89
|
+
`File: ${chunk.fileKey}`,
|
|
90
|
+
`Title: ${chunk.docName}`,
|
|
91
|
+
`URL: ${chunk.docUrl}`,
|
|
92
|
+
`Chunk: ${chunk.chunkNumber}`,
|
|
93
|
+
`Content:`,
|
|
94
|
+
chunk.content
|
|
95
|
+
].join("\n")
|
|
96
|
+
})) };
|
|
97
|
+
} catch (error) {
|
|
98
|
+
return { content: [{
|
|
99
|
+
type: "text",
|
|
100
|
+
text: `Fetch doc chunks failed: ${error instanceof Error ? error.message : "An unknown error occurred"}`
|
|
101
|
+
}] };
|
|
102
|
+
}
|
|
103
|
+
});
|
|
65
104
|
};
|
|
66
105
|
|
|
67
106
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.mjs","names":[],"sources":["../../../src/tools/docs.ts"],"sourcesContent":["import 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/v3';\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"],"mappings":"
|
|
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/v3';\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;AAE9B,QAAO,aACL,gBACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EAAE;EACf,aAAa,EACX,cAAc,MACf;EACF,EACD,YAAY;AACV,MAAI;GACF,MAAM,qBAAqB,MAAM,sBAAsB;AAEvD,UAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,KAAK,UAAU,oBAAoB,MAAM,EAAE;IAClD,CACF,EACF;WACM,OAAO;AAGd,UAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,wBAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAGuB,CAC/D,EACF;;GAGN;AAED,QAAO,aACL,WACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,QAAQ,EAAE,KAAK,SAAkC,EAClD;EACD,aAAa,EACX,cAAc,MACf;EACF,EACD,OAAO,EAAE,aAAa;AACpB,MAAI;AAEF,UAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAFhB,MAAM,OAAO,OAAiB;IAEH,CAAC,EACvC;WACM,OAAO;AAGd,UAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,mBAFhC,iBAAiB,QAAQ,MAAM,UAAU;IAE0B,CAAC,EACrE;;GAGN;AAED,QAAO,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;AAC1B,MAAI;AAEF,UAAO,EACL,UAFU,MAAM,aAAa,QAAQ,EAAE,EAAE,QAAW,OAAO,EAE9C,KAAK,OAAO;IAAE,MAAM;IAAQ,MAAM;IAAG,EAAE,EACrD;WACM,OAAO;AAGd,UAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,2BAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAG0B,CAClE,EACF;;GAGN;AAED,QAAO,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;AAC1B,MAAI;GACF,MAAM,EAAE,cAAc,cAAc;GACpC,MAAM,WAAW,MAAM,UAAU;IAC/B,OAAO;IACP,OAAO,OAAO,UAAU;IACxB,eAAe;IAChB,CAAC;AAEF,OAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,QAAQ,SAAS,KAAK,CACjD,QAAO,EACL,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM;IAA6B,CAAC,EAC/D;AAKH,UAAO,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;AAGd,UAAO,EACL,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,4BAHxB,iBAAiB,QAAQ,MAAM,UAAU;IAG2B,CACnE,EACF;;GAGN"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { SKILLS, installSkills } from "@intlayer/chokidar";
|
|
2
|
+
import * as readline from "node:readline";
|
|
3
|
+
import z from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/tools/installSkills.ts
|
|
6
|
+
const loadInstallSkillsTool = (server) => {
|
|
7
|
+
server.registerTool("intlayer-install-skills", {
|
|
8
|
+
title: "Install Intlayer Skills",
|
|
9
|
+
description: "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.",
|
|
10
|
+
inputSchema: {
|
|
11
|
+
platform: z.enum([
|
|
12
|
+
"Cursor",
|
|
13
|
+
"VSCode",
|
|
14
|
+
"OpenCode",
|
|
15
|
+
"Claude",
|
|
16
|
+
"Other"
|
|
17
|
+
]).describe("The platform to install skills for"),
|
|
18
|
+
skills: z.array(z.enum(SKILLS)).describe("List of skills to install"),
|
|
19
|
+
projectRoot: z.string().optional().describe("Root directory of the project. Defaults to current directory.")
|
|
20
|
+
}
|
|
21
|
+
}, async ({ platform, skills, projectRoot }) => {
|
|
22
|
+
try {
|
|
23
|
+
return { content: [{
|
|
24
|
+
type: "text",
|
|
25
|
+
text: await installSkills(projectRoot || process.cwd(), platform, skills)
|
|
26
|
+
}] };
|
|
27
|
+
} catch (error) {
|
|
28
|
+
return {
|
|
29
|
+
content: [{
|
|
30
|
+
type: "text",
|
|
31
|
+
text: `Failed to install skills: ${error instanceof Error ? error.message : String(error)}`
|
|
32
|
+
}],
|
|
33
|
+
isError: true
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
const runInstallSkillsCLI = async () => {
|
|
39
|
+
const rl = readline.createInterface({
|
|
40
|
+
input: process.stdin,
|
|
41
|
+
output: process.stdout
|
|
42
|
+
});
|
|
43
|
+
const question = (query) => new Promise((resolve) => rl.question(query, resolve));
|
|
44
|
+
try {
|
|
45
|
+
console.log("Install Intlayer Skills");
|
|
46
|
+
console.log("-----------------------");
|
|
47
|
+
const platformInput = await question("Which platform are you using? (Cursor, VSCode, OpenCode, Claude, Other): ");
|
|
48
|
+
const platform = [
|
|
49
|
+
"Cursor",
|
|
50
|
+
"VSCode",
|
|
51
|
+
"OpenCode",
|
|
52
|
+
"Claude",
|
|
53
|
+
"Other"
|
|
54
|
+
].find((p) => p.toLowerCase() === platformInput.trim().toLowerCase()) || "Other";
|
|
55
|
+
console.log(`Selected platform: ${platform}`);
|
|
56
|
+
const availableSkills = SKILLS;
|
|
57
|
+
console.log("\nAvailable skills:");
|
|
58
|
+
availableSkills.forEach((s, i) => {
|
|
59
|
+
console.log(`${i + 1}. ${s}`);
|
|
60
|
+
});
|
|
61
|
+
const skillsInput = await question("\nWhich skills do you want to install? (comma separated numbers, e.g. 1,2,3 or \"all\"): ");
|
|
62
|
+
let selectedSkills = [];
|
|
63
|
+
if (skillsInput.trim().toLowerCase() === "all") selectedSkills = [...availableSkills];
|
|
64
|
+
else selectedSkills = skillsInput.split(",").map((s) => parseInt(s.trim()) - 1).filter((i) => !isNaN(i) && i >= 0 && i < availableSkills.length).map((i) => availableSkills[i]);
|
|
65
|
+
if (selectedSkills.length === 0) {
|
|
66
|
+
console.log("No valid skills selected. Exiting.");
|
|
67
|
+
rl.close();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
console.log(`Installing skills: ${selectedSkills.join(", ")}...`);
|
|
71
|
+
const result = await installSkills(process.cwd(), platform, selectedSkills);
|
|
72
|
+
console.log(result);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error("Error:", error);
|
|
75
|
+
} finally {
|
|
76
|
+
rl.close();
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
81
|
+
export { loadInstallSkillsTool, runInstallSkillsCLI };
|
|
82
|
+
//# sourceMappingURL=installSkills.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installSkills.mjs","names":[],"sources":["../../../src/tools/installSkills.ts"],"sourcesContent":["import * as readline from 'node:readline';\nimport { installSkills, SKILLS, type Skill } from '@intlayer/chokidar';\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(['Cursor', 'VSCode', 'OpenCode', 'Claude', 'Other'])\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 async ({ platform, skills, projectRoot }) => {\n try {\n const root = projectRoot || process.cwd();\n const message = await installSkills(\n root,\n platform as any,\n skills as any\n );\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, VSCode, OpenCode, Claude, Other): '\n );\n const platform = (['Cursor', 'VSCode', 'OpenCode', 'Claude', 'Other'].find(\n (p) => p.toLowerCase() === platformInput.trim().toLowerCase()\n ) || 'Other') as 'Cursor' | 'VSCode' | 'OpenCode' | 'Claude' | 'Other';\n\n console.log(`Selected platform: ${platform}`);\n\n const availableSkills = SKILLS;\n console.log('\\nAvailable skills:');\n availableSkills.forEach((s, i) => {\n console.log(`${i + 1}. ${s}`);\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 = [...availableSkills];\n } else {\n const indices = skillsInput\n .split(',')\n .map((s) => parseInt(s.trim()) - 1)\n .filter((i) => !isNaN(i) && i >= 0 && i < availableSkills.length);\n selectedSkills = indices.map((i) => availableSkills[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":";;;;;AAKA,MAAa,yBAAyB,WAA4B;AAChE,QAAO,aACL,2BACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,UAAU,EACP,KAAK;IAAC;IAAU;IAAU;IAAY;IAAU;IAAQ,CAAC,CACzD,SAAS,qCAAqC;GACjD,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,CAAC,SAAS,4BAA4B;GACrE,aAAa,EACV,QAAQ,CACR,UAAU,CACV,SACC,gEACD;GACJ;EACF,EACD,OAAO,EAAE,UAAU,QAAQ,kBAAkB;AAC3C,MAAI;AAQF,UAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAVU,MAAM,cADT,eAAe,QAAQ,KAAK,EAGvC,UACA,OACD;IAOI,CACF,EACF;WACM,OAAO;AACd,UAAO;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;AAEvD,KAAI;AACF,UAAQ,IAAI,0BAA0B;AACtC,UAAQ,IAAI,0BAA0B;EAEtC,MAAM,gBAAgB,MAAM,SAC1B,4EACD;EACD,MAAM,WAAY;GAAC;GAAU;GAAU;GAAY;GAAU;GAAQ,CAAC,MACnE,MAAM,EAAE,aAAa,KAAK,cAAc,MAAM,CAAC,aAAa,CAC9D,IAAI;AAEL,UAAQ,IAAI,sBAAsB,WAAW;EAE7C,MAAM,kBAAkB;AACxB,UAAQ,IAAI,sBAAsB;AAClC,kBAAgB,SAAS,GAAG,MAAM;AAChC,WAAQ,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI;IAC7B;EAEF,MAAM,cAAc,MAAM,SACxB,4FACD;EAED,IAAI,iBAA0B,EAAE;AAChC,MAAI,YAAY,MAAM,CAAC,aAAa,KAAK,MACvC,kBAAiB,CAAC,GAAG,gBAAgB;MAMrC,kBAJgB,YACb,MAAM,IAAI,CACV,KAAK,MAAM,SAAS,EAAE,MAAM,CAAC,GAAG,EAAE,CAClC,QAAQ,MAAM,CAAC,MAAM,EAAE,IAAI,KAAK,KAAK,IAAI,gBAAgB,OAAO,CAC1C,KAAK,MAAM,gBAAgB,GAAU;AAGhE,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAQ,IAAI,qCAAqC;AACjD,MAAG,OAAO;AACV;;AAGF,UAAQ,IAAI,sBAAsB,eAAe,KAAK,KAAK,CAAC,KAAK;EACjE,MAAM,SAAS,MAAM,cAAc,QAAQ,KAAK,EAAE,UAAU,eAAe;AAC3E,UAAQ,IAAI,OAAO;UACZ,OAAO;AACd,UAAQ,MAAM,UAAU,MAAM;WACtB;AACR,KAAG,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","names":[],"sources":["../../../src/server/server.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"server.d.ts","names":[],"sources":["../../../src/server/server.ts"],"mappings":";;;cASa,OAAA;AAAA,KAQR,UAAA,IAAc,OAAA;EAAW,OAAA;AAAA,MAAuB,SAAA;AAAA,cAExC,UAAA,EAAY,UAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.d.ts","names":[],"sources":["../../../src/tools/docs.ts"],"mappings":";;;
|
|
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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
|
|
3
|
+
//#region src/tools/installSkills.d.ts
|
|
4
|
+
declare const loadInstallSkillsTool: (server: McpServer) => void;
|
|
5
|
+
declare const runInstallSkillsCLI: () => Promise<void>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { loadInstallSkillsTool, runInstallSkillsCLI };
|
|
8
|
+
//# sourceMappingURL=installSkills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installSkills.d.ts","names":[],"sources":["../../../src/tools/installSkills.ts"],"mappings":";;;cAKa,qBAAA,GAAyB,MAAA,EAAQ,SAAA;AAAA,cAoDjC,mBAAA,QAAgC,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/mcp",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.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": [
|
|
@@ -96,26 +96,27 @@
|
|
|
96
96
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
97
97
|
},
|
|
98
98
|
"dependencies": {
|
|
99
|
-
"@intlayer/
|
|
100
|
-
"@intlayer/
|
|
101
|
-
"@intlayer/
|
|
102
|
-
"@intlayer/
|
|
103
|
-
"@intlayer/
|
|
99
|
+
"@intlayer/api": "8.0.5",
|
|
100
|
+
"@intlayer/chokidar": "8.0.5",
|
|
101
|
+
"@intlayer/cli": "8.0.5",
|
|
102
|
+
"@intlayer/config": "8.0.5",
|
|
103
|
+
"@intlayer/docs": "8.0.5",
|
|
104
|
+
"@intlayer/types": "8.0.5",
|
|
104
105
|
"@modelcontextprotocol/sdk": "1.25.3",
|
|
105
|
-
"dotenv": "
|
|
106
|
+
"dotenv": "17.2.4",
|
|
106
107
|
"express": "5.2.1",
|
|
107
108
|
"zod": "4.3.6"
|
|
108
109
|
},
|
|
109
110
|
"devDependencies": {
|
|
110
|
-
"@intlayer/types": "8.0.
|
|
111
|
+
"@intlayer/types": "8.0.5",
|
|
111
112
|
"@modelcontextprotocol/inspector": "0.19.0",
|
|
112
113
|
"@types/express": "5.0.6",
|
|
113
|
-
"@types/node": "25.
|
|
114
|
+
"@types/node": "25.2.2",
|
|
114
115
|
"@utils/ts-config": "1.0.4",
|
|
115
116
|
"@utils/ts-config-types": "1.0.4",
|
|
116
117
|
"@utils/tsdown-config": "1.0.4",
|
|
117
118
|
"rimraf": "6.1.2",
|
|
118
|
-
"tsdown": "0.20.
|
|
119
|
+
"tsdown": "0.20.3",
|
|
119
120
|
"typescript": "5.9.3",
|
|
120
121
|
"vitest": "4.0.18"
|
|
121
122
|
},
|