@intlayer/mcp 8.7.6-canary.0 → 8.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { dirname as dirname$1, resolve } from "node:path";
2
- import { fileURLToPath } from "node:url";
3
2
  import { readFileSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
4
  import { isESModule } from "@intlayer/config/utils";
5
5
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
6
6
 
@@ -2,8 +2,8 @@ import { loadCLITools } from "../tools/cli.mjs";
2
2
  import { loadInstallSkillsTool } from "../tools/installSkills.mjs";
3
3
  import { loadDocsTools } from "../tools/docs.mjs";
4
4
  import { dirname as dirname$1, resolve } from "node:path";
5
- import { fileURLToPath } from "node:url";
6
5
  import { readFileSync } from "node:fs";
6
+ import { fileURLToPath } from "node:url";
7
7
  import { isESModule } from "@intlayer/config/utils";
8
8
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
9
 
@@ -1 +1 @@
1
- {"version":3,"file":"sse.mjs","names":[],"sources":["../../../src/server/sse.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { randomUUID } from 'node:crypto';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport dotenv from 'dotenv';\nimport express, { type Request, type Response } from 'express';\nimport { loadServer } from './server';\n\nconst app = express();\nconst env = app.get('env');\n\ndotenv.config({\n path: [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env'],\n quiet: true,\n});\n\napp.use((req, res, next) => {\n res.header('Access-Control-Allow-Origin', '*');\n res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Content-Type, mcp-session-id');\n if (req.method === 'OPTIONS') {\n res.sendStatus(200);\n return;\n }\n next();\n});\n\napp.use(express.json());\nconst router = express.Router();\n\nconst transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};\n\nrouter.post('/', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n let transport: StreamableHTTPServerTransport;\n\n if (sessionId && transports[sessionId]) {\n transport = transports[sessionId];\n } else if (!sessionId) {\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n });\n transport.onclose = () => {\n if (transport.sessionId) {\n delete transports[transport.sessionId];\n }\n };\n const server = loadServer({ isLocal: false });\n await server.connect(transport);\n } else {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n\n await transport.handleRequest(req, res, req.body);\n\n const newSessionId = transport.sessionId;\n if (newSessionId && !transports[newSessionId]) {\n transports[newSessionId] = transport;\n }\n});\n\nrouter.get('/', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n\n await transports[sessionId].handleRequest(req, res);\n});\n\nrouter.delete('/', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n\n await transports[sessionId].handleRequest(req, res);\n});\n\napp.use('/', router);\napp.use('/health', (_req: Request, res: Response) => {\n res.send('OK');\n});\n\nconst PORT = process.env.PORT ?? 3000;\napp.listen(PORT, () => {\n console.info(`MCP Streamable HTTP Server listening on port ${PORT}`);\n});\n"],"mappings":";;;;;;;;AAQA,MAAM,MAAM,SAAS;AACrB,MAAM,MAAM,IAAI,IAAI,MAAM;AAE1B,OAAO,OAAO;CACZ,MAAM;EAAC,QAAQ,IAAI;EAAS,QAAQ;EAAO;EAAc;EAAO;CAChE,OAAO;CACR,CAAC;AAEF,IAAI,KAAK,KAAK,KAAK,SAAS;AAC1B,KAAI,OAAO,+BAA+B,IAAI;AAC9C,KAAI,OAAO,gCAAgC,qBAAqB;AAChE,KAAI,OAAO,gCAAgC,+BAA+B;AAC1E,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,aAAqE,EAAE;AAE7E,OAAO,KAAK,KAAK,OAAO,KAAc,QAAkB;CACtD,MAAM,YAAY,IAAI,QAAQ;CAE9B,IAAI;AAEJ,KAAI,aAAa,WAAW,WAC1B,aAAY,WAAW;UACd,CAAC,WAAW;AACrB,cAAY,IAAI,8BAA8B,EAC5C,0BAA0B,YAAY,EACvC,CAAC;AACF,YAAU,gBAAgB;AACxB,OAAI,UAAU,UACZ,QAAO,WAAW,UAAU;;AAIhC,QADe,WAAW,EAAE,SAAS,OAAO,CAAC,CAChC,QAAQ,UAAU;QAC1B;AACL,MAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;AACrD;;AAGF,OAAM,UAAU,cAAc,KAAK,KAAK,IAAI,KAAK;CAEjD,MAAM,eAAe,UAAU;AAC/B,KAAI,gBAAgB,CAAC,WAAW,cAC9B,YAAW,gBAAgB;EAE7B;AAEF,OAAO,IAAI,KAAK,OAAO,KAAc,QAAkB;CACrD,MAAM,YAAY,IAAI,QAAQ;AAE9B,KAAI,CAAC,aAAa,CAAC,WAAW,YAAY;AACxC,MAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;AACrD;;AAGF,OAAM,WAAW,WAAW,cAAc,KAAK,IAAI;EACnD;AAEF,OAAO,OAAO,KAAK,OAAO,KAAc,QAAkB;CACxD,MAAM,YAAY,IAAI,QAAQ;AAE9B,KAAI,CAAC,aAAa,CAAC,WAAW,YAAY;AACxC,MAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;AACrD;;AAGF,OAAM,WAAW,WAAW,cAAc,KAAK,IAAI;EACnD;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
+ {"version":3,"file":"sse.mjs","names":[],"sources":["../../../src/server/sse.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { randomUUID } from 'node:crypto';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport dotenv from 'dotenv';\nimport express, { type Request, type Response } from 'express';\nimport { loadServer } from './server';\n\nconst app = express();\nconst env = app.get('env');\n\ndotenv.config({\n path: [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env'],\n quiet: true,\n});\n\napp.use((req, res, next) => {\n res.header('Access-Control-Allow-Origin', '*');\n res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Content-Type, mcp-session-id');\n if (req.method === 'OPTIONS') {\n res.sendStatus(200);\n return;\n }\n next();\n});\n\napp.use(express.json());\nconst router = express.Router();\n\nconst transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};\n\nrouter.post('/', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n let transport: StreamableHTTPServerTransport;\n\n if (sessionId && transports[sessionId]) {\n transport = transports[sessionId];\n } else if (!sessionId) {\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n });\n transport.onclose = () => {\n if (transport.sessionId) {\n delete transports[transport.sessionId];\n }\n };\n const server = loadServer({ isLocal: false });\n await server.connect(transport);\n } else {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n\n await transport.handleRequest(req, res, req.body);\n\n const newSessionId = transport.sessionId;\n if (newSessionId && !transports[newSessionId]) {\n transports[newSessionId] = transport;\n }\n});\n\nrouter.get('/', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n\n await transports[sessionId].handleRequest(req, res);\n});\n\nrouter.delete('/', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n if (!sessionId || !transports[sessionId]) {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n\n await transports[sessionId].handleRequest(req, res);\n});\n\napp.use('/', router);\napp.use('/health', (_req: Request, res: Response) => {\n res.send('OK');\n});\n\nconst PORT = process.env.PORT ?? 3000;\napp.listen(PORT, () => {\n console.info(`MCP Streamable HTTP Server listening on port ${PORT}`);\n});\n"],"mappings":";;;;;;;;AAQA,MAAM,MAAM,SAAS;AACrB,MAAM,MAAM,IAAI,IAAI,MAAM;AAE1B,OAAO,OAAO;CACZ,MAAM;EAAC,QAAQ,IAAI;EAAS,QAAQ;EAAO;EAAc;EAAO;CAChE,OAAO;CACR,CAAC;AAEF,IAAI,KAAK,KAAK,KAAK,SAAS;AAC1B,KAAI,OAAO,+BAA+B,IAAI;AAC9C,KAAI,OAAO,gCAAgC,qBAAqB;AAChE,KAAI,OAAO,gCAAgC,+BAA+B;AAC1E,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,aAAqE,EAAE;AAE7E,OAAO,KAAK,KAAK,OAAO,KAAc,QAAkB;CACtD,MAAM,YAAY,IAAI,QAAQ;CAE9B,IAAI;AAEJ,KAAI,aAAa,WAAW,WAC1B,aAAY,WAAW;UACd,CAAC,WAAW;AACrB,cAAY,IAAI,8BAA8B,EAC5C,0BAA0B,YAAY,EACvC,CAAC;AACF,YAAU,gBAAgB;AACxB,OAAI,UAAU,UACZ,QAAO,WAAW,UAAU;;AAIhC,QADe,WAAW,EAAE,SAAS,OAAO,CAChC,CAAC,QAAQ,UAAU;QAC1B;AACL,MAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;AACrD;;AAGF,OAAM,UAAU,cAAc,KAAK,KAAK,IAAI,KAAK;CAEjD,MAAM,eAAe,UAAU;AAC/B,KAAI,gBAAgB,CAAC,WAAW,cAC9B,YAAW,gBAAgB;EAE7B;AAEF,OAAO,IAAI,KAAK,OAAO,KAAc,QAAkB;CACrD,MAAM,YAAY,IAAI,QAAQ;AAE9B,KAAI,CAAC,aAAa,CAAC,WAAW,YAAY;AACxC,MAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;AACrD;;AAGF,OAAM,WAAW,WAAW,cAAc,KAAK,IAAI;EACnD;AAEF,OAAO,OAAO,KAAK,OAAO,KAAc,QAAkB;CACxD,MAAM,YAAY,IAAI,QAAQ;AAE9B,KAAI,CAAC,aAAa,CAAC,WAAW,YAAY;AACxC,MAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;AACrD;;AAGF,OAAM,WAAW,WAAW,cAAc,KAAK,IAAI;EACnD;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 +1 @@
1
- {"version":3,"file":"docs.mjs","names":[],"sources":["../../../src/tools/docs.ts"],"sourcesContent":["import { getSearchAPI } from '@intlayer/api';\nimport type { DocKey } from '@intlayer/docs';\nimport {\n getDoc,\n getDocBySlug,\n getDocMetadataRecord,\n getDocsKeys,\n} from '@intlayer/docs';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport z from 'zod';\n\ntype LoadDocsTools = (server: McpServer) => Promise<void>;\n\nexport const loadDocsTools: LoadDocsTools = async (server) => {\n const docsKeys = getDocsKeys();\n\n server.registerTool(\n 'get-doc-list',\n {\n title: 'Get Doc List',\n description:\n 'Get the list of docs names and their metadata to get more details about what doc to retrieve',\n inputSchema: {},\n annotations: {\n readOnlyHint: true,\n },\n },\n async () => {\n try {\n const docsMetadataRecord = await getDocMetadataRecord();\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(docsMetadataRecord, null, 2),\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Get doc list failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'get-doc',\n {\n title: 'Get Doc by Key',\n description:\n 'Get a doc by his key. Example: `./docs/en/getting-started.md`. List all docs metadata first to get more details about what doc key to retrieve.',\n inputSchema: {\n docKey: z.enum(docsKeys as [string, ...string[]]),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ docKey }) => {\n try {\n const doc = await getDoc(docKey as DocKey);\n return {\n content: [{ type: 'text', text: doc }],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [{ type: 'text', text: `Get doc failed: ${errorMessage}` }],\n };\n }\n }\n );\n\n server.registerTool(\n 'get-doc-by-slug',\n {\n title: 'Get Doc by Slug',\n description:\n 'Get an array of docs by their slugs. If not slug is provided, return all docs (1.2Mb). List all docs metadata first to get more details about what doc to retrieve.',\n inputSchema: {\n slug: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe(\n 'Slug of the docs. If not provided, return all docs. If not provided, return all docs.'\n ),\n strict: z\n .boolean()\n .optional()\n .describe(\n 'Strict mode - only return docs that match all slugs, by excluding additional slugs'\n ),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ slug, strict }) => {\n try {\n const doc = await getDocBySlug(slug ?? [], undefined, strict);\n return {\n content: doc.map((d) => ({ type: 'text', text: d })),\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Get doc by slug failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'fetch-doc-chunks',\n {\n title: 'Fetch Doc Chunks',\n description:\n 'Fetch related doc chunks using keywords or questions. This tool will return the most relevant chunks of documentation based on the input query.',\n inputSchema: {\n query: z.string().describe('The keywords or question to search for'),\n limit: z\n .number()\n .optional()\n .describe('The number of chunks to retrieve (default: 10)'),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ query, limit }) => {\n try {\n const { searchDoc } = getSearchAPI();\n const response = await searchDoc({\n input: query,\n limit: limit?.toString(),\n returnContent: 'true',\n });\n\n if (!response.data || !Array.isArray(response.data)) {\n return {\n content: [{ type: 'text', text: 'No relevant chunks found.' }],\n };\n }\n\n const chunks = response.data;\n\n return {\n content: chunks.map((chunk: any) => ({\n type: 'text',\n text: [\n `File: ${chunk.fileKey}`,\n `Title: ${chunk.docName}`,\n `URL: ${chunk.docUrl}`,\n `Chunk: ${chunk.chunkNumber}`,\n `Content:`,\n chunk.content,\n ].join('\\n'),\n })),\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Fetch doc chunks failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n};\n"],"mappings":";;;;;AAaA,MAAa,gBAA+B,OAAO,WAAW;CAC5D,MAAM,WAAW,aAAa;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"}
1
+ {"version":3,"file":"docs.mjs","names":[],"sources":["../../../src/tools/docs.ts"],"sourcesContent":["import { getSearchAPI } from '@intlayer/api';\nimport type { DocKey } from '@intlayer/docs';\nimport {\n getDoc,\n getDocBySlug,\n getDocMetadataRecord,\n getDocsKeys,\n} from '@intlayer/docs';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport z from 'zod';\n\ntype LoadDocsTools = (server: McpServer) => Promise<void>;\n\nexport const loadDocsTools: LoadDocsTools = async (server) => {\n const docsKeys = getDocsKeys();\n\n server.registerTool(\n 'get-doc-list',\n {\n title: 'Get Doc List',\n description:\n 'Get the list of docs names and their metadata to get more details about what doc to retrieve',\n inputSchema: {},\n annotations: {\n readOnlyHint: true,\n },\n },\n async () => {\n try {\n const docsMetadataRecord = await getDocMetadataRecord();\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(docsMetadataRecord, null, 2),\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Get doc list failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'get-doc',\n {\n title: 'Get Doc by Key',\n description:\n 'Get a doc by his key. Example: `./docs/en/getting-started.md`. List all docs metadata first to get more details about what doc key to retrieve.',\n inputSchema: {\n docKey: z.enum(docsKeys as [string, ...string[]]),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ docKey }) => {\n try {\n const doc = await getDoc(docKey as DocKey);\n return {\n content: [{ type: 'text', text: doc }],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [{ type: 'text', text: `Get doc failed: ${errorMessage}` }],\n };\n }\n }\n );\n\n server.registerTool(\n 'get-doc-by-slug',\n {\n title: 'Get Doc by Slug',\n description:\n 'Get an array of docs by their slugs. If not slug is provided, return all docs (1.2Mb). List all docs metadata first to get more details about what doc to retrieve.',\n inputSchema: {\n slug: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .describe(\n 'Slug of the docs. If not provided, return all docs. If not provided, return all docs.'\n ),\n strict: z\n .boolean()\n .optional()\n .describe(\n 'Strict mode - only return docs that match all slugs, by excluding additional slugs'\n ),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ slug, strict }) => {\n try {\n const doc = await getDocBySlug(slug ?? [], undefined, strict);\n return {\n content: doc.map((d) => ({ type: 'text', text: d })),\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Get doc by slug failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n\n server.registerTool(\n 'fetch-doc-chunks',\n {\n title: 'Fetch Doc Chunks',\n description:\n 'Fetch related doc chunks using keywords or questions. This tool will return the most relevant chunks of documentation based on the input query.',\n inputSchema: {\n query: z.string().describe('The keywords or question to search for'),\n limit: z\n .number()\n .optional()\n .describe('The number of chunks to retrieve (default: 10)'),\n },\n annotations: {\n readOnlyHint: true,\n },\n },\n async ({ query, limit }) => {\n try {\n const { searchDoc } = getSearchAPI();\n const response = await searchDoc({\n input: query,\n limit: limit?.toString(),\n returnContent: 'true',\n });\n\n if (!response.data || !Array.isArray(response.data)) {\n return {\n content: [{ type: 'text', text: 'No relevant chunks found.' }],\n };\n }\n\n const chunks = response.data;\n\n return {\n content: chunks.map((chunk: any) => ({\n type: 'text',\n text: [\n `File: ${chunk.fileKey}`,\n `Title: ${chunk.docName}`,\n `URL: ${chunk.docUrl}`,\n `Chunk: ${chunk.chunkNumber}`,\n `Content:`,\n chunk.content,\n ].join('\\n'),\n })),\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'An unknown error occurred';\n return {\n content: [\n { type: 'text', text: `Fetch doc chunks failed: ${errorMessage}` },\n ],\n };\n }\n }\n );\n};\n"],"mappings":";;;;;AAaA,MAAa,gBAA+B,OAAO,WAAW;CAC5D,MAAM,WAAW,aAAa;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,MAAM,MAFhB,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,UAAS,MAFO,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"}
@@ -1 +1 @@
1
- {"version":3,"file":"installSkills.mjs","names":[],"sources":["../../../src/tools/installSkills.ts"],"sourcesContent":["import * as readline from 'node:readline';\nimport {\n installSkills,\n PLATFORMS,\n SKILLS,\n type Skill,\n} from '@intlayer/chokidar/cli';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport z from 'zod';\n\nexport const loadInstallSkillsTool = (server: McpServer): void => {\n server.registerTool(\n 'intlayer-install-skills',\n {\n title: 'Install Intlayer Skills',\n description:\n 'Install Intlayer documentation and skills to the project to assist AI agents. Ask the user for the platform (Cursor, VSCode, OpenCode, Claude, etc.) and which skills they want to install before calling this tool.',\n inputSchema: {\n platform: z\n .enum(PLATFORMS)\n .describe('The platform to install skills for'),\n skills: z.array(z.enum(SKILLS)).describe('List of skills to install'),\n projectRoot: z\n .string()\n .optional()\n .describe(\n 'Root directory of the project. Defaults to current directory.'\n ),\n },\n },\n\n async ({ platform, skills, projectRoot }) => {\n try {\n const root = projectRoot || process.cwd();\n const message = await installSkills(root, platform, skills);\n\n return {\n content: [\n {\n type: 'text',\n text: message,\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: `Failed to install skills: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n};\n\nexport const runInstallSkillsCLI = async (): Promise<void> => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const question = (query: string): Promise<string> =>\n new Promise((resolve) => rl.question(query, resolve));\n\n try {\n console.log('Install Intlayer Skills');\n console.log('-----------------------');\n\n const platformInput = await question(\n 'Which platform are you using? (Cursor, Windsurf, Trae, OpenCode, GitHub, Claude, VSCode, Cline, RooCode, etc. or \"Other\"): '\n );\n\n // we only accept a single platform here, not an array like the main CLI\n const platform =\n PLATFORMS.find(\n (platform) =>\n platform.toLowerCase() === platformInput.trim().toLowerCase()\n ) || ('Other' as const);\n\n console.log(`Selected platform: ${platform}`);\n\n console.log('\\nAvailable skills:');\n\n SKILLS.forEach((skill, i) => {\n console.log(`${i + 1}. ${skill}`);\n });\n\n const skillsInput = await question(\n '\\nWhich skills do you want to install? (comma separated numbers, e.g. 1,2,3 or \"all\"): '\n );\n\n let selectedSkills: Skill[] = [];\n if (skillsInput.trim().toLowerCase() === 'all') {\n selectedSkills = [...SKILLS];\n } else {\n const indices = skillsInput\n .split(',')\n .map((skill) => parseInt(skill.trim(), 10) - 1)\n .filter(\n (skill) => !Number.isNaN(skill) && skill >= 0 && skill < SKILLS.length\n );\n selectedSkills = indices.map((i) => SKILLS[i] as any);\n }\n\n if (selectedSkills.length === 0) {\n console.log('No valid skills selected. Exiting.');\n rl.close();\n return;\n }\n\n console.log(`Installing skills: ${selectedSkills.join(', ')}...`);\n const result = await installSkills(process.cwd(), platform, selectedSkills);\n console.log(result);\n } catch (error) {\n console.error('Error:', error);\n } finally {\n rl.close();\n }\n};\n"],"mappings":";;;;;AAUA,MAAa,yBAAyB,WAA4B;AAChE,QAAO,aACL,2BACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,UAAU,EACP,KAAK,UAAU,CACf,SAAS,qCAAqC;GACjD,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,CAAC,SAAS,4BAA4B;GACrE,aAAa,EACV,QAAQ,CACR,UAAU,CACV,SACC,gEACD;GACJ;EACF,EAED,OAAO,EAAE,UAAU,QAAQ,kBAAkB;AAC3C,MAAI;AAIF,UAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MANU,MAAM,cADT,eAAe,QAAQ,KAAK,EACC,UAAU,OAAO;IAOtD,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,gIACD;EAGD,MAAM,WACJ,UAAU,MACP,aACC,SAAS,aAAa,KAAK,cAAc,MAAM,CAAC,aAAa,CAChE,IAAK;AAER,UAAQ,IAAI,sBAAsB,WAAW;AAE7C,UAAQ,IAAI,sBAAsB;AAElC,SAAO,SAAS,OAAO,MAAM;AAC3B,WAAQ,IAAI,GAAG,IAAI,EAAE,IAAI,QAAQ;IACjC;EAEF,MAAM,cAAc,MAAM,SACxB,4FACD;EAED,IAAI,iBAA0B,EAAE;AAChC,MAAI,YAAY,MAAM,CAAC,aAAa,KAAK,MACvC,kBAAiB,CAAC,GAAG,OAAO;MAQ5B,kBANgB,YACb,MAAM,IAAI,CACV,KAAK,UAAU,SAAS,MAAM,MAAM,EAAE,GAAG,GAAG,EAAE,CAC9C,QACE,UAAU,CAAC,OAAO,MAAM,MAAM,IAAI,SAAS,KAAK,QAAQ,OAAO,OACjE,CACsB,KAAK,MAAM,OAAO,GAAU;AAGvD,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
+ {"version":3,"file":"installSkills.mjs","names":[],"sources":["../../../src/tools/installSkills.ts"],"sourcesContent":["import * as readline from 'node:readline';\nimport {\n installSkills,\n PLATFORMS,\n SKILLS,\n type Skill,\n} from '@intlayer/chokidar/cli';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport z from 'zod';\n\nexport const loadInstallSkillsTool = (server: McpServer): void => {\n server.registerTool(\n 'intlayer-install-skills',\n {\n title: 'Install Intlayer Skills',\n description:\n 'Install Intlayer documentation and skills to the project to assist AI agents. Ask the user for the platform (Cursor, VSCode, OpenCode, Claude, etc.) and which skills they want to install before calling this tool.',\n inputSchema: {\n platform: z\n .enum(PLATFORMS)\n .describe('The platform to install skills for'),\n skills: z.array(z.enum(SKILLS)).describe('List of skills to install'),\n projectRoot: z\n .string()\n .optional()\n .describe(\n 'Root directory of the project. Defaults to current directory.'\n ),\n },\n },\n\n async ({ platform, skills, projectRoot }) => {\n try {\n const root = projectRoot || process.cwd();\n const message = await installSkills(root, platform, skills);\n\n return {\n content: [\n {\n type: 'text',\n text: message,\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: `Failed to install skills: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n};\n\nexport const runInstallSkillsCLI = async (): Promise<void> => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const question = (query: string): Promise<string> =>\n new Promise((resolve) => rl.question(query, resolve));\n\n try {\n console.log('Install Intlayer Skills');\n console.log('-----------------------');\n\n const platformInput = await question(\n 'Which platform are you using? (Cursor, Windsurf, Trae, OpenCode, GitHub, Claude, VSCode, Cline, RooCode, etc. or \"Other\"): '\n );\n\n // we only accept a single platform here, not an array like the main CLI\n const platform =\n PLATFORMS.find(\n (platform) =>\n platform.toLowerCase() === platformInput.trim().toLowerCase()\n ) || ('Other' as const);\n\n console.log(`Selected platform: ${platform}`);\n\n console.log('\\nAvailable skills:');\n\n SKILLS.forEach((skill, i) => {\n console.log(`${i + 1}. ${skill}`);\n });\n\n const skillsInput = await question(\n '\\nWhich skills do you want to install? (comma separated numbers, e.g. 1,2,3 or \"all\"): '\n );\n\n let selectedSkills: Skill[] = [];\n if (skillsInput.trim().toLowerCase() === 'all') {\n selectedSkills = [...SKILLS];\n } else {\n const indices = skillsInput\n .split(',')\n .map((skill) => parseInt(skill.trim(), 10) - 1)\n .filter(\n (skill) => !Number.isNaN(skill) && skill >= 0 && skill < SKILLS.length\n );\n selectedSkills = indices.map((i) => SKILLS[i] as any);\n }\n\n if (selectedSkills.length === 0) {\n console.log('No valid skills selected. Exiting.');\n rl.close();\n return;\n }\n\n console.log(`Installing skills: ${selectedSkills.join(', ')}...`);\n const result = await installSkills(process.cwd(), platform, selectedSkills);\n console.log(result);\n } catch (error) {\n console.error('Error:', error);\n } finally {\n rl.close();\n }\n};\n"],"mappings":";;;;;AAUA,MAAa,yBAAyB,WAA4B;AAChE,QAAO,aACL,2BACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,UAAU,EACP,KAAK,UAAU,CACf,SAAS,qCAAqC;GACjD,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,CAAC,SAAS,4BAA4B;GACrE,aAAa,EACV,QAAQ,CACR,UAAU,CACV,SACC,gEACD;GACJ;EACF,EAED,OAAO,EAAE,UAAU,QAAQ,kBAAkB;AAC3C,MAAI;AAIF,UAAO,EACL,SAAS,CACP;IACE,MAAM;IACN,MAAM,MANU,cADT,eAAe,QAAQ,KAAK,EACC,UAAU,OAAO;IAOtD,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,gIACD;EAGD,MAAM,WACJ,UAAU,MACP,aACC,SAAS,aAAa,KAAK,cAAc,MAAM,CAAC,aAAa,CAChE,IAAK;AAER,UAAQ,IAAI,sBAAsB,WAAW;AAE7C,UAAQ,IAAI,sBAAsB;AAElC,SAAO,SAAS,OAAO,MAAM;AAC3B,WAAQ,IAAI,GAAG,IAAI,EAAE,IAAI,QAAQ;IACjC;EAEF,MAAM,cAAc,MAAM,SACxB,4FACD;EAED,IAAI,iBAA0B,EAAE;AAChC,MAAI,YAAY,MAAM,CAAC,aAAa,KAAK,MACvC,kBAAiB,CAAC,GAAG,OAAO;MAQ5B,kBANgB,YACb,MAAM,IAAI,CACV,KAAK,UAAU,SAAS,MAAM,MAAM,EAAE,GAAG,GAAG,EAAE,CAC9C,QACE,UAAU,CAAC,OAAO,MAAM,MAAM,IAAI,SAAS,KAAK,QAAQ,OAAO,OAE5C,CAAC,KAAK,MAAM,OAAO,GAAU;AAGvD,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/mcp",
3
- "version": "8.7.6-canary.0",
3
+ "version": "8.7.7",
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": [
@@ -93,19 +93,19 @@
93
93
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
94
94
  },
95
95
  "dependencies": {
96
- "@intlayer/api": "8.7.6-canary.0",
97
- "@intlayer/chokidar": "8.7.6-canary.0",
98
- "@intlayer/cli": "8.7.6-canary.0",
99
- "@intlayer/config": "8.7.6-canary.0",
100
- "@intlayer/docs": "8.7.6-canary.0",
101
- "@intlayer/types": "8.7.6-canary.0",
96
+ "@intlayer/api": "8.7.7",
97
+ "@intlayer/chokidar": "8.7.7",
98
+ "@intlayer/cli": "8.7.7",
99
+ "@intlayer/config": "8.7.7",
100
+ "@intlayer/docs": "8.7.7",
101
+ "@intlayer/types": "8.7.7",
102
102
  "@modelcontextprotocol/sdk": "1.29.0",
103
103
  "dotenv": "17.4.2",
104
104
  "express": "5.2.1",
105
105
  "zod": "4.3.6"
106
106
  },
107
107
  "devDependencies": {
108
- "@intlayer/types": "8.7.6-canary.0",
108
+ "@intlayer/types": "8.7.7",
109
109
  "@modelcontextprotocol/inspector": "0.21.2",
110
110
  "@types/express": "5.0.6",
111
111
  "@types/node": "25.6.0",
@@ -113,9 +113,9 @@
113
113
  "@utils/ts-config-types": "1.0.4",
114
114
  "@utils/tsdown-config": "1.0.4",
115
115
  "rimraf": "6.1.3",
116
- "tsdown": "0.21.9",
116
+ "tsdown": "0.21.10",
117
117
  "typescript": "6.0.3",
118
- "vitest": "4.1.4"
118
+ "vitest": "4.1.5"
119
119
  },
120
120
  "engines": {
121
121
  "node": ">=14.18"