@intlayer/mcp 8.9.3 → 8.9.4
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/esm/client/client.mjs +13 -9
- package/dist/esm/client/client.mjs.map +1 -1
- package/dist/esm/client/sse.mjs +17 -50
- package/dist/esm/client/sse.mjs.map +1 -1
- package/dist/esm/server/server.mjs +115 -4
- package/dist/esm/server/server.mjs.map +1 -1
- package/dist/esm/server/sse.mjs +33 -20
- package/dist/esm/server/sse.mjs.map +1 -1
- package/dist/esm/server/stdio.mjs +35 -3
- package/dist/esm/server/stdio.mjs.map +1 -1
- package/dist/esm/tools/api.mjs +340 -0
- package/dist/esm/tools/api.mjs.map +1 -0
- package/dist/esm/tools/cli.mjs +37 -46
- package/dist/esm/tools/cli.mjs.map +1 -1
- package/dist/esm/tools/docs.mjs +1 -1
- package/dist/esm/tools/docs.mjs.map +1 -1
- package/dist/esm/tools/index.mjs +6 -0
- package/dist/esm/tools/installSkills.mjs +2 -2
- package/dist/esm/tools/installSkills.mjs.map +1 -1
- package/dist/types/client/client.d.ts +6 -4
- package/dist/types/client/client.d.ts.map +1 -1
- package/dist/types/server/server.d.ts +27 -3
- package/dist/types/server/server.d.ts.map +1 -1
- package/dist/types/tools/api.d.ts +8 -0
- package/dist/types/tools/api.d.ts.map +1 -0
- package/dist/types/tools/cli.d.ts +1 -1
- package/dist/types/tools/cli.d.ts.map +1 -1
- package/dist/types/tools/docs.d.ts +11 -3
- package/dist/types/tools/docs.d.ts.map +1 -1
- package/dist/types/tools/index.d.ts +5 -0
- package/dist/types/tools/installSkills.d.ts +1 -1
- package/package.json +25 -11
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
import { dirname as dirname$1
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
1
|
+
import { dirname as dirname$1 } from "node:path";
|
|
3
2
|
import { fileURLToPath } from "node:url";
|
|
4
3
|
import { isESModule } from "@intlayer/config/utils";
|
|
5
|
-
import {
|
|
4
|
+
import { createMCPClient } from "/Users/aymericpineau/Documents/intlayer_/node_modules/.bun/@ai-sdk+mcp@1.0.41+68a1e3a0c4588df3/node_modules/@ai-sdk/mcp/dist/index.mjs";
|
|
6
5
|
|
|
7
6
|
//#region src/client/client.ts
|
|
8
7
|
const dirname = isESModule ? dirname$1(fileURLToPath(import.meta.url)) : __dirname;
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
});
|
|
8
|
+
const loadMCPTools = async (serverURL) => {
|
|
9
|
+
const client = await createMCPClient({ transport: {
|
|
10
|
+
type: "http",
|
|
11
|
+
url: serverURL
|
|
12
|
+
} });
|
|
13
|
+
return {
|
|
14
|
+
client,
|
|
15
|
+
tools: await client.tools()
|
|
16
|
+
};
|
|
17
|
+
};
|
|
14
18
|
|
|
15
19
|
//#endregion
|
|
16
|
-
export { dirname,
|
|
20
|
+
export { dirname, loadMCPTools };
|
|
17
21
|
//# sourceMappingURL=client.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":["pathDirname"],"sources":["../../../src/client/client.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"client.mjs","names":["pathDirname"],"sources":["../../../src/client/client.ts"],"sourcesContent":["import { dirname as pathDirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createMCPClient, type MCPClient } from '@ai-sdk/mcp';\nimport { isESModule } from '@intlayer/config/utils';\n\nexport type { MCPClient };\n\nexport const dirname: string = isESModule\n ? pathDirname(fileURLToPath(import.meta.url))\n : __dirname;\n\nexport const loadMCPTools = async (\n serverURL: string\n): Promise<{ client: MCPClient; tools: Record<string, any> }> => {\n const client = await createMCPClient({\n transport: { type: 'http', url: serverURL },\n });\n const tools = await client.tools();\n return { client, tools };\n};\n"],"mappings":";;;;;;AAOA,MAAa,UAAkB,aAC3BA,UAAY,cAAc,OAAO,KAAK,IAAI,CAAC,GAC3C;AAEJ,MAAa,eAAe,OAC1B,cAC+D;CAC/D,MAAM,SAAS,MAAM,gBAAgB,EACnC,WAAW;EAAE,MAAM;EAAQ,KAAK;EAAW,EAC5C,CAAC;CAEF,OAAO;EAAE;EAAQ,aADG,OAAO,OAAO;EACV"}
|
package/dist/esm/client/sse.mjs
CHANGED
|
@@ -1,59 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { URL } from "node:url";
|
|
3
|
-
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
1
|
+
import { createMCPClient } from "/Users/aymericpineau/Documents/intlayer_/node_modules/.bun/@ai-sdk+mcp@1.0.41+68a1e3a0c4588df3/node_modules/@ai-sdk/mcp/dist/index.mjs";
|
|
4
2
|
|
|
5
3
|
//#region src/client/sse.ts
|
|
6
|
-
var SSEClient = class {
|
|
7
|
-
client;
|
|
8
|
-
transport = null;
|
|
9
|
-
isCompleted = false;
|
|
10
|
-
constructor() {
|
|
11
|
-
this.client = loadClient();
|
|
12
|
-
}
|
|
13
|
-
async connectToServer() {
|
|
14
|
-
const mcpServerURL = process.env.MCP_SERVER_URL ?? "http://localhost:3000/";
|
|
15
|
-
const url = new URL(mcpServerURL);
|
|
16
|
-
try {
|
|
17
|
-
console.info(`Connecting to server - ${mcpServerURL}`);
|
|
18
|
-
this.transport = new StreamableHTTPClientTransport(url);
|
|
19
|
-
await this.client.connect(this.transport);
|
|
20
|
-
console.info("Connected to MCP server");
|
|
21
|
-
this.setUpTransport();
|
|
22
|
-
} catch (e) {
|
|
23
|
-
console.error("Failed to connect to MCP server: ", e);
|
|
24
|
-
throw e;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
setUpTransport() {
|
|
28
|
-
if (this.transport === null) return;
|
|
29
|
-
this.transport.onclose = () => {
|
|
30
|
-
console.info("Transport closed.");
|
|
31
|
-
this.isCompleted = true;
|
|
32
|
-
};
|
|
33
|
-
this.transport.onerror = async (error) => {
|
|
34
|
-
console.error("Transport error: ", error);
|
|
35
|
-
await this.cleanup();
|
|
36
|
-
};
|
|
37
|
-
this.transport.onmessage = (message) => {
|
|
38
|
-
console.info("Message received: ", message);
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
async waitForCompletion() {
|
|
42
|
-
while (!this.isCompleted) await new Promise((resolve) => setTimeout(resolve, 100));
|
|
43
|
-
}
|
|
44
|
-
async cleanup() {
|
|
45
|
-
if (this.transport) await this.client.close();
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
4
|
const main = async () => {
|
|
49
|
-
const
|
|
5
|
+
const mcpServerURL = process.env.MCP_SERVER_URL ?? "http://localhost:3000/";
|
|
6
|
+
console.info(`Connecting to server - ${mcpServerURL}`);
|
|
7
|
+
let mcpClient;
|
|
50
8
|
try {
|
|
51
|
-
await
|
|
52
|
-
|
|
9
|
+
mcpClient = await createMCPClient({ transport: {
|
|
10
|
+
type: "http",
|
|
11
|
+
url: mcpServerURL
|
|
12
|
+
} });
|
|
13
|
+
console.info("Connected to MCP server");
|
|
14
|
+
await new Promise((resolve) => {
|
|
15
|
+
process.once("SIGINT", resolve);
|
|
16
|
+
process.once("SIGTERM", resolve);
|
|
17
|
+
});
|
|
53
18
|
} catch (error) {
|
|
54
|
-
console.error(error);
|
|
19
|
+
console.error("Failed to connect to MCP server: ", error);
|
|
20
|
+
throw error;
|
|
55
21
|
} finally {
|
|
56
|
-
await
|
|
22
|
+
await mcpClient?.close();
|
|
23
|
+
console.info("Connection closed.");
|
|
57
24
|
}
|
|
58
25
|
};
|
|
59
26
|
main();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.mjs","names":[],"sources":["../../../src/client/sse.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"sse.mjs","names":[],"sources":["../../../src/client/sse.ts"],"sourcesContent":["import { createMCPClient, type MCPClient } from '@ai-sdk/mcp';\n\nconst main = async () => {\n const mcpServerURL = process.env.MCP_SERVER_URL ?? 'http://localhost:3000/';\n\n console.info(`Connecting to server - ${mcpServerURL}`);\n\n let mcpClient: MCPClient | undefined;\n try {\n mcpClient = await createMCPClient({\n transport: {\n type: 'http',\n url: mcpServerURL,\n },\n });\n console.info('Connected to MCP server');\n\n await new Promise<void>((resolve) => {\n process.once('SIGINT', resolve);\n process.once('SIGTERM', resolve);\n });\n } catch (error) {\n console.error('Failed to connect to MCP server: ', error);\n throw error;\n } finally {\n await mcpClient?.close();\n console.info('Connection closed.');\n }\n};\n\nmain();\n"],"mappings":";;;AAEA,MAAM,OAAO,YAAY;CACvB,MAAM,eAAe,QAAQ,IAAI,kBAAkB;CAEnD,QAAQ,KAAK,0BAA0B,eAAe;CAEtD,IAAI;CACJ,IAAI;EACF,YAAY,MAAM,gBAAgB,EAChC,WAAW;GACT,MAAM;GACN,KAAK;GACN,EACF,CAAC;EACF,QAAQ,KAAK,0BAA0B;EAEvC,MAAM,IAAI,SAAe,YAAY;GACnC,QAAQ,KAAK,UAAU,QAAQ;GAC/B,QAAQ,KAAK,WAAW,QAAQ;IAChC;UACK,OAAO;EACd,QAAQ,MAAM,qCAAqC,MAAM;EACzD,MAAM;WACE;EACR,MAAM,WAAW,OAAO;EACxB,QAAQ,KAAK,qBAAqB;;;AAItC,MAAM"}
|
|
@@ -1,15 +1,121 @@
|
|
|
1
|
+
import { loadAPITools } from "../tools/api.mjs";
|
|
1
2
|
import { loadCLITools } from "../tools/cli.mjs";
|
|
2
|
-
import { loadInstallSkillsTool } from "../tools/installSkills.mjs";
|
|
3
3
|
import { loadDocsTools } from "../tools/docs.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { loadInstallSkillsTool } from "../tools/installSkills.mjs";
|
|
5
5
|
import { readFileSync } from "node:fs";
|
|
6
|
+
import { dirname as dirname$1, resolve } from "node:path";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
7
8
|
import { isESModule } from "@intlayer/config/utils";
|
|
8
|
-
import
|
|
9
|
+
import z from "zod";
|
|
9
10
|
|
|
10
11
|
//#region src/server/server.ts
|
|
11
12
|
const dirname = isESModule ? dirname$1(fileURLToPath(import.meta.url)) : __dirname;
|
|
12
13
|
const packageJson = JSON.parse(readFileSync(resolve(dirname, "../../../package.json"), "utf8"));
|
|
14
|
+
var McpServer = class {
|
|
15
|
+
_tools = /* @__PURE__ */ new Map();
|
|
16
|
+
_info;
|
|
17
|
+
constructor(info) {
|
|
18
|
+
this._info = info;
|
|
19
|
+
}
|
|
20
|
+
registerTool(name, config, handler) {
|
|
21
|
+
const shape = config.inputSchema ?? {};
|
|
22
|
+
let inputSchema;
|
|
23
|
+
try {
|
|
24
|
+
inputSchema = z.toJSONSchema(z.object(shape));
|
|
25
|
+
} catch {
|
|
26
|
+
inputSchema = {
|
|
27
|
+
type: "object",
|
|
28
|
+
properties: {}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
this._tools.set(name, {
|
|
32
|
+
name,
|
|
33
|
+
description: config.description,
|
|
34
|
+
annotations: config.annotations,
|
|
35
|
+
inputSchema,
|
|
36
|
+
handler
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async handleMessage(message) {
|
|
40
|
+
const { id, method, params } = message;
|
|
41
|
+
const isNotification = id === void 0;
|
|
42
|
+
switch (method) {
|
|
43
|
+
case "initialize": return {
|
|
44
|
+
jsonrpc: "2.0",
|
|
45
|
+
id,
|
|
46
|
+
result: {
|
|
47
|
+
protocolVersion: "2024-11-05",
|
|
48
|
+
capabilities: { tools: {} },
|
|
49
|
+
serverInfo: this._info
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
case "tools/list": return {
|
|
53
|
+
jsonrpc: "2.0",
|
|
54
|
+
id,
|
|
55
|
+
result: { tools: Array.from(this._tools.values()).map((t) => ({
|
|
56
|
+
name: t.name,
|
|
57
|
+
description: t.description,
|
|
58
|
+
inputSchema: t.inputSchema,
|
|
59
|
+
...t.annotations && { annotations: t.annotations }
|
|
60
|
+
})) }
|
|
61
|
+
};
|
|
62
|
+
case "tools/call": {
|
|
63
|
+
const { name, arguments: args } = params ?? {};
|
|
64
|
+
const tool = this._tools.get(name);
|
|
65
|
+
if (!tool) {
|
|
66
|
+
if (isNotification) return null;
|
|
67
|
+
return {
|
|
68
|
+
jsonrpc: "2.0",
|
|
69
|
+
id,
|
|
70
|
+
error: {
|
|
71
|
+
code: -32601,
|
|
72
|
+
message: `Tool not found: ${name}`
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const result = await tool.handler(args ?? {});
|
|
78
|
+
if (isNotification) return null;
|
|
79
|
+
return {
|
|
80
|
+
jsonrpc: "2.0",
|
|
81
|
+
id,
|
|
82
|
+
result
|
|
83
|
+
};
|
|
84
|
+
} catch (error) {
|
|
85
|
+
if (isNotification) return null;
|
|
86
|
+
return {
|
|
87
|
+
jsonrpc: "2.0",
|
|
88
|
+
id,
|
|
89
|
+
error: {
|
|
90
|
+
code: -32e3,
|
|
91
|
+
message: error instanceof Error ? error.message : String(error)
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
case "ping":
|
|
97
|
+
if (isNotification) return null;
|
|
98
|
+
return {
|
|
99
|
+
jsonrpc: "2.0",
|
|
100
|
+
id,
|
|
101
|
+
result: {}
|
|
102
|
+
};
|
|
103
|
+
default:
|
|
104
|
+
if (isNotification) return null;
|
|
105
|
+
return {
|
|
106
|
+
jsonrpc: "2.0",
|
|
107
|
+
id,
|
|
108
|
+
error: {
|
|
109
|
+
code: -32601,
|
|
110
|
+
message: `Method not found: ${method}`
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async connect(transport) {
|
|
116
|
+
await transport.start(this);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
13
119
|
const loadServer = ({ isLocal }) => {
|
|
14
120
|
const server = new McpServer({
|
|
15
121
|
name: "intlayer",
|
|
@@ -26,9 +132,14 @@ const loadServer = ({ isLocal }) => {
|
|
|
26
132
|
} catch (error) {
|
|
27
133
|
console.error("Error loading docs tools:", error);
|
|
28
134
|
}
|
|
135
|
+
try {
|
|
136
|
+
loadAPITools(server);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error("Error loading API tools:", error);
|
|
139
|
+
}
|
|
29
140
|
return server;
|
|
30
141
|
};
|
|
31
142
|
|
|
32
143
|
//#endregion
|
|
33
|
-
export { dirname, loadServer };
|
|
144
|
+
export { McpServer, dirname, loadServer };
|
|
34
145
|
//# sourceMappingURL=server.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":["pathDirname"],"sources":["../../../src/server/server.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { dirname as pathDirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { isESModule } from '@intlayer/config/utils';\nimport {
|
|
1
|
+
{"version":3,"file":"server.mjs","names":["pathDirname"],"sources":["../../../src/server/server.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { dirname as pathDirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { isESModule } from '@intlayer/config/utils';\nimport z from 'zod';\nimport { loadAPITools } from '../tools/api';\nimport { loadCLITools } from '../tools/cli';\nimport { loadDocsTools } from '../tools/docs';\nimport { loadInstallSkillsTool } from '../tools/installSkills';\n\nexport const dirname: string = isESModule\n ? pathDirname(fileURLToPath(import.meta.url))\n : __dirname;\n\nconst packageJson: Record<string, any> = JSON.parse(\n readFileSync(resolve(dirname, '../../../package.json'), 'utf8')\n);\n\ntype ToolResult = {\n content: { type: string; text: string }[];\n isError?: boolean;\n};\n\ntype StoredTool = {\n name: string;\n description?: string;\n annotations?: Record<string, any>;\n inputSchema: Record<string, any>;\n handler: (params: any) => Promise<ToolResult>;\n};\n\nexport interface McpTransport {\n start(server: McpServer): Promise<void>;\n}\n\nexport class McpServer {\n private readonly _tools = new Map<string, StoredTool>();\n private readonly _info: { name: string; version: string };\n\n constructor(info: { name: string; version: string }) {\n this._info = info;\n }\n\n registerTool(\n name: string,\n config: {\n title?: string;\n description?: string;\n inputSchema?: Record<string, any>;\n annotations?: Record<string, any>;\n },\n handler: (params: any) => Promise<ToolResult>\n ): void {\n const shape = config.inputSchema ?? {};\n let inputSchema: Record<string, any>;\n try {\n inputSchema = z.toJSONSchema(z.object(shape)) as Record<string, any>;\n } catch {\n inputSchema = { type: 'object', properties: {} };\n }\n this._tools.set(name, {\n name,\n description: config.description,\n annotations: config.annotations,\n inputSchema,\n handler,\n });\n }\n\n async handleMessage(message: any): Promise<any> {\n const { id, method, params } = message;\n const isNotification = id === undefined;\n\n switch (method) {\n case 'initialize':\n return {\n jsonrpc: '2.0',\n id,\n result: {\n protocolVersion: '2024-11-05',\n capabilities: { tools: {} },\n serverInfo: this._info,\n },\n };\n\n case 'tools/list':\n return {\n jsonrpc: '2.0',\n id,\n result: {\n tools: Array.from(this._tools.values()).map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n ...(t.annotations && { annotations: t.annotations }),\n })),\n },\n };\n\n case 'tools/call': {\n const { name, arguments: args } = params ?? {};\n const tool = this._tools.get(name);\n if (!tool) {\n if (isNotification) return null;\n return {\n jsonrpc: '2.0',\n id,\n error: { code: -32601, message: `Tool not found: ${name}` },\n };\n }\n try {\n const result = await tool.handler(args ?? {});\n if (isNotification) return null;\n return { jsonrpc: '2.0', id, result };\n } catch (error) {\n if (isNotification) return null;\n return {\n jsonrpc: '2.0',\n id,\n error: {\n code: -32000,\n message: error instanceof Error ? error.message : String(error),\n },\n };\n }\n }\n\n case 'ping':\n if (isNotification) return null;\n return { jsonrpc: '2.0', id, result: {} };\n\n default:\n if (isNotification) return null;\n return {\n jsonrpc: '2.0',\n id,\n error: { code: -32601, message: `Method not found: ${method}` },\n };\n }\n }\n\n async connect(transport: McpTransport): Promise<void> {\n await transport.start(this);\n }\n}\n\ntype LoadServer = (options: { isLocal: boolean }) => McpServer;\n\nexport const loadServer: LoadServer = ({ isLocal }) => {\n const server = new McpServer({\n name: 'intlayer',\n version: packageJson.version,\n });\n\n if (isLocal) {\n try {\n loadCLITools(server);\n loadInstallSkillsTool(server);\n } catch (error) {\n console.error('Error loading CLI tools:', error);\n }\n }\n\n try {\n loadDocsTools(server);\n } catch (error) {\n console.error('Error loading docs tools:', error);\n }\n\n try {\n loadAPITools(server);\n } catch (error) {\n console.error('Error loading API tools:', error);\n }\n\n return server;\n};\n"],"mappings":";;;;;;;;;;;AAUA,MAAa,UAAkB,aAC3BA,UAAY,cAAc,OAAO,KAAK,IAAI,CAAC,GAC3C;AAEJ,MAAM,cAAmC,KAAK,MAC5C,aAAa,QAAQ,SAAS,wBAAwB,EAAE,OAAO,CAChE;AAmBD,IAAa,YAAb,MAAuB;CACrB,AAAiB,yBAAS,IAAI,KAAyB;CACvD,AAAiB;CAEjB,YAAY,MAAyC;EACnD,KAAK,QAAQ;;CAGf,aACE,MACA,QAMA,SACM;EACN,MAAM,QAAQ,OAAO,eAAe,EAAE;EACtC,IAAI;EACJ,IAAI;GACF,cAAc,EAAE,aAAa,EAAE,OAAO,MAAM,CAAC;UACvC;GACN,cAAc;IAAE,MAAM;IAAU,YAAY,EAAE;IAAE;;EAElD,KAAK,OAAO,IAAI,MAAM;GACpB;GACA,aAAa,OAAO;GACpB,aAAa,OAAO;GACpB;GACA;GACD,CAAC;;CAGJ,MAAM,cAAc,SAA4B;EAC9C,MAAM,EAAE,IAAI,QAAQ,WAAW;EAC/B,MAAM,iBAAiB,OAAO;EAE9B,QAAQ,QAAR;GACE,KAAK,cACH,OAAO;IACL,SAAS;IACT;IACA,QAAQ;KACN,iBAAiB;KACjB,cAAc,EAAE,OAAO,EAAE,EAAE;KAC3B,YAAY,KAAK;KAClB;IACF;GAEH,KAAK,cACH,OAAO;IACL,SAAS;IACT;IACA,QAAQ,EACN,OAAO,MAAM,KAAK,KAAK,OAAO,QAAQ,CAAC,CAAC,KAAK,OAAO;KAClD,MAAM,EAAE;KACR,aAAa,EAAE;KACf,aAAa,EAAE;KACf,GAAI,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa;KACpD,EAAE,EACJ;IACF;GAEH,KAAK,cAAc;IACjB,MAAM,EAAE,MAAM,WAAW,SAAS,UAAU,EAAE;IAC9C,MAAM,OAAO,KAAK,OAAO,IAAI,KAAK;IAClC,IAAI,CAAC,MAAM;KACT,IAAI,gBAAgB,OAAO;KAC3B,OAAO;MACL,SAAS;MACT;MACA,OAAO;OAAE,MAAM;OAAQ,SAAS,mBAAmB;OAAQ;MAC5D;;IAEH,IAAI;KACF,MAAM,SAAS,MAAM,KAAK,QAAQ,QAAQ,EAAE,CAAC;KAC7C,IAAI,gBAAgB,OAAO;KAC3B,OAAO;MAAE,SAAS;MAAO;MAAI;MAAQ;aAC9B,OAAO;KACd,IAAI,gBAAgB,OAAO;KAC3B,OAAO;MACL,SAAS;MACT;MACA,OAAO;OACL,MAAM;OACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;OAChE;MACF;;;GAIL,KAAK;IACH,IAAI,gBAAgB,OAAO;IAC3B,OAAO;KAAE,SAAS;KAAO;KAAI,QAAQ,EAAE;KAAE;GAE3C;IACE,IAAI,gBAAgB,OAAO;IAC3B,OAAO;KACL,SAAS;KACT;KACA,OAAO;MAAE,MAAM;MAAQ,SAAS,qBAAqB;MAAU;KAChE;;;CAIP,MAAM,QAAQ,WAAwC;EACpD,MAAM,UAAU,MAAM,KAAK;;;AAM/B,MAAa,cAA0B,EAAE,cAAc;CACrD,MAAM,SAAS,IAAI,UAAU;EAC3B,MAAM;EACN,SAAS,YAAY;EACtB,CAAC;CAEF,IAAI,SACF,IAAI;EACF,aAAa,OAAO;EACpB,sBAAsB,OAAO;UACtB,OAAO;EACd,QAAQ,MAAM,4BAA4B,MAAM;;CAIpD,IAAI;EACF,cAAc,OAAO;UACd,OAAO;EACd,QAAQ,MAAM,6BAA6B,MAAM;;CAGnD,IAAI;EACF,aAAa,OAAO;UACb,OAAO;EACd,QAAQ,MAAM,4BAA4B,MAAM;;CAGlD,OAAO"}
|
package/dist/esm/server/sse.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { loadServer } from "./server.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
|
-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
5
4
|
import dotenv from "dotenv";
|
|
6
5
|
import express from "express";
|
|
7
6
|
|
|
@@ -19,7 +18,7 @@ dotenv.config({
|
|
|
19
18
|
});
|
|
20
19
|
app.use((req, res, next) => {
|
|
21
20
|
res.header("Access-Control-Allow-Origin", "*");
|
|
22
|
-
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
21
|
+
res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
|
23
22
|
res.header("Access-Control-Allow-Headers", "Content-Type, mcp-session-id");
|
|
24
23
|
if (req.method === "OPTIONS") {
|
|
25
24
|
res.sendStatus(200);
|
|
@@ -29,40 +28,54 @@ app.use((req, res, next) => {
|
|
|
29
28
|
});
|
|
30
29
|
app.use(express.json());
|
|
31
30
|
const router = express.Router();
|
|
32
|
-
const
|
|
31
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
33
32
|
router.post("/", async (req, res) => {
|
|
34
33
|
const sessionId = req.headers["mcp-session-id"];
|
|
35
|
-
let
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
let server;
|
|
35
|
+
let currentSessionId;
|
|
36
|
+
if (sessionId && sessions.has(sessionId)) {
|
|
37
|
+
server = sessions.get(sessionId);
|
|
38
|
+
currentSessionId = sessionId;
|
|
39
|
+
} else if (!sessionId) {
|
|
40
|
+
currentSessionId = randomUUID();
|
|
41
|
+
server = loadServer({ isLocal: false });
|
|
42
|
+
sessions.set(currentSessionId, server);
|
|
43
|
+
res.setHeader("mcp-session-id", currentSessionId);
|
|
43
44
|
} else {
|
|
44
45
|
res.status(400).send({ messages: "Bad session id." });
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
try {
|
|
49
|
+
const response = await server.handleMessage(req.body);
|
|
50
|
+
if (response !== null && response !== void 0) res.json(response);
|
|
51
|
+
else res.status(202).end();
|
|
52
|
+
} catch (error) {
|
|
53
|
+
res.status(500).json({
|
|
54
|
+
jsonrpc: "2.0",
|
|
55
|
+
id: req.body?.id ?? null,
|
|
56
|
+
error: {
|
|
57
|
+
code: -32e3,
|
|
58
|
+
message: "Internal server error"
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
50
62
|
});
|
|
51
|
-
router.get("/",
|
|
63
|
+
router.get("/", (req, res) => {
|
|
52
64
|
const sessionId = req.headers["mcp-session-id"];
|
|
53
|
-
if (!sessionId || !
|
|
65
|
+
if (!sessionId || !sessions.has(sessionId)) {
|
|
54
66
|
res.status(400).send({ messages: "Bad session id." });
|
|
55
67
|
return;
|
|
56
68
|
}
|
|
57
|
-
|
|
69
|
+
res.status(200).end();
|
|
58
70
|
});
|
|
59
|
-
router.delete("/",
|
|
71
|
+
router.delete("/", (req, res) => {
|
|
60
72
|
const sessionId = req.headers["mcp-session-id"];
|
|
61
|
-
if (!sessionId || !
|
|
73
|
+
if (!sessionId || !sessions.has(sessionId)) {
|
|
62
74
|
res.status(400).send({ messages: "Bad session id." });
|
|
63
75
|
return;
|
|
64
76
|
}
|
|
65
|
-
|
|
77
|
+
sessions.delete(sessionId);
|
|
78
|
+
res.status(200).end();
|
|
66
79
|
});
|
|
67
80
|
app.use("/", router);
|
|
68
81
|
app.use("/health", (_req, res) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.mjs","names":[],"sources":["../../../src/server/sse.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { randomUUID } from 'node:crypto';\nimport
|
|
1
|
+
{"version":3,"file":"sse.mjs","names":[],"sources":["../../../src/server/sse.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { randomUUID } from 'node:crypto';\nimport dotenv from 'dotenv';\nimport express, { type Request, type Response } from 'express';\nimport { loadServer, type McpServer } from './server';\n\nconst app = express();\nconst env = app.get('env');\n\ndotenv.config({\n path: [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env'],\n quiet: true,\n});\n\napp.use((req, res, next) => {\n res.header('Access-Control-Allow-Origin', '*');\n res.header('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Content-Type, mcp-session-id');\n if (req.method === 'OPTIONS') {\n res.sendStatus(200);\n return;\n }\n next();\n});\n\napp.use(express.json());\nconst router = express.Router();\n\nconst sessions = new Map<string, McpServer>();\n\nrouter.post('/', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n let server: McpServer;\n let currentSessionId: string;\n\n if (sessionId && sessions.has(sessionId)) {\n server = sessions.get(sessionId)!;\n currentSessionId = sessionId;\n } else if (!sessionId) {\n currentSessionId = randomUUID();\n server = loadServer({ isLocal: false });\n sessions.set(currentSessionId, server);\n res.setHeader('mcp-session-id', currentSessionId);\n } else {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n\n try {\n const response = await server.handleMessage(req.body);\n if (response !== null && response !== undefined) {\n res.json(response);\n } else {\n res.status(202).end();\n }\n } catch (error) {\n res.status(500).json({\n jsonrpc: '2.0',\n id: req.body?.id ?? null,\n error: { code: -32000, message: 'Internal server error' },\n });\n }\n});\n\nrouter.get('/', (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n if (!sessionId || !sessions.has(sessionId)) {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n res.status(200).end();\n});\n\nrouter.delete('/', (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n if (!sessionId || !sessions.has(sessionId)) {\n res.status(400).send({ messages: 'Bad session id.' });\n return;\n }\n sessions.delete(sessionId);\n res.status(200).end();\n});\n\napp.use('/', router);\napp.use('/health', (_req: Request, res: Response) => {\n res.send('OK');\n});\n\nconst PORT = process.env.PORT ?? 3000;\napp.listen(PORT, () => {\n console.info(`MCP Streamable HTTP Server listening on port ${PORT}`);\n});\n"],"mappings":";;;;;;;AAOA,MAAM,MAAM,SAAS;AACrB,MAAM,MAAM,IAAI,IAAI,MAAM;AAE1B,OAAO,OAAO;CACZ,MAAM;EAAC,QAAQ,IAAI;EAAS,QAAQ;EAAO;EAAc;EAAO;CAChE,OAAO;CACR,CAAC;AAEF,IAAI,KAAK,KAAK,KAAK,SAAS;CAC1B,IAAI,OAAO,+BAA+B,IAAI;CAC9C,IAAI,OAAO,gCAAgC,6BAA6B;CACxE,IAAI,OAAO,gCAAgC,+BAA+B;CAC1E,IAAI,IAAI,WAAW,WAAW;EAC5B,IAAI,WAAW,IAAI;EACnB;;CAEF,MAAM;EACN;AAEF,IAAI,IAAI,QAAQ,MAAM,CAAC;AACvB,MAAM,SAAS,QAAQ,QAAQ;AAE/B,MAAM,2BAAW,IAAI,KAAwB;AAE7C,OAAO,KAAK,KAAK,OAAO,KAAc,QAAkB;CACtD,MAAM,YAAY,IAAI,QAAQ;CAE9B,IAAI;CACJ,IAAI;CAEJ,IAAI,aAAa,SAAS,IAAI,UAAU,EAAE;EACxC,SAAS,SAAS,IAAI,UAAU;EAChC,mBAAmB;QACd,IAAI,CAAC,WAAW;EACrB,mBAAmB,YAAY;EAC/B,SAAS,WAAW,EAAE,SAAS,OAAO,CAAC;EACvC,SAAS,IAAI,kBAAkB,OAAO;EACtC,IAAI,UAAU,kBAAkB,iBAAiB;QAC5C;EACL,IAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;EACrD;;CAGF,IAAI;EACF,MAAM,WAAW,MAAM,OAAO,cAAc,IAAI,KAAK;EACrD,IAAI,aAAa,QAAQ,aAAa,QACpC,IAAI,KAAK,SAAS;OAElB,IAAI,OAAO,IAAI,CAAC,KAAK;UAEhB,OAAO;EACd,IAAI,OAAO,IAAI,CAAC,KAAK;GACnB,SAAS;GACT,IAAI,IAAI,MAAM,MAAM;GACpB,OAAO;IAAE,MAAM;IAAQ,SAAS;IAAyB;GAC1D,CAAC;;EAEJ;AAEF,OAAO,IAAI,MAAM,KAAc,QAAkB;CAC/C,MAAM,YAAY,IAAI,QAAQ;CAC9B,IAAI,CAAC,aAAa,CAAC,SAAS,IAAI,UAAU,EAAE;EAC1C,IAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;EACrD;;CAEF,IAAI,OAAO,IAAI,CAAC,KAAK;EACrB;AAEF,OAAO,OAAO,MAAM,KAAc,QAAkB;CAClD,MAAM,YAAY,IAAI,QAAQ;CAC9B,IAAI,CAAC,aAAa,CAAC,SAAS,IAAI,UAAU,EAAE;EAC1C,IAAI,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,mBAAmB,CAAC;EACrD;;CAEF,SAAS,OAAO,UAAU;CAC1B,IAAI,OAAO,IAAI,CAAC,KAAK;EACrB;AAEF,IAAI,IAAI,KAAK,OAAO;AACpB,IAAI,IAAI,YAAY,MAAe,QAAkB;CACnD,IAAI,KAAK,KAAK;EACd;AAEF,MAAM,OAAO,QAAQ,IAAI,QAAQ;AACjC,IAAI,OAAO,YAAY;CACrB,QAAQ,KAAK,gDAAgD,OAAO;EACpE"}
|
|
@@ -1,13 +1,45 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { loadServer } from "./server.mjs";
|
|
3
|
-
import
|
|
3
|
+
import * as readline from "node:readline";
|
|
4
4
|
|
|
5
5
|
//#region src/server/stdio.ts
|
|
6
|
+
var StdioTransport = class {
|
|
7
|
+
async start(server) {
|
|
8
|
+
const rl = readline.createInterface({
|
|
9
|
+
input: process.stdin,
|
|
10
|
+
terminal: false
|
|
11
|
+
});
|
|
12
|
+
const send = (message) => {
|
|
13
|
+
process.stdout.write(`${JSON.stringify(message)}\n`);
|
|
14
|
+
};
|
|
15
|
+
rl.on("line", async (line) => {
|
|
16
|
+
const trimmed = line.trim();
|
|
17
|
+
if (!trimmed) return;
|
|
18
|
+
try {
|
|
19
|
+
const message = JSON.parse(trimmed);
|
|
20
|
+
const response = await server.handleMessage(message);
|
|
21
|
+
if (response !== null && response !== void 0) send(response);
|
|
22
|
+
} catch {
|
|
23
|
+
send({
|
|
24
|
+
jsonrpc: "2.0",
|
|
25
|
+
id: null,
|
|
26
|
+
error: {
|
|
27
|
+
code: -32700,
|
|
28
|
+
message: "Parse error"
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
console.error("Intlayer MCP Server running on stdio");
|
|
34
|
+
await new Promise((resolve) => {
|
|
35
|
+
rl.on("close", resolve);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
};
|
|
6
39
|
const server = loadServer({ isLocal: true });
|
|
7
40
|
const main = async () => {
|
|
8
|
-
const transport = new
|
|
41
|
+
const transport = new StdioTransport();
|
|
9
42
|
await server.connect(transport);
|
|
10
|
-
console.error("Intlayer MCP Server running on stdio");
|
|
11
43
|
};
|
|
12
44
|
main().catch((error) => {
|
|
13
45
|
console.error("Fatal error in main():", error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.mjs","names":[],"sources":["../../../src/server/stdio.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport
|
|
1
|
+
{"version":3,"file":"stdio.mjs","names":[],"sources":["../../../src/server/stdio.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as readline from 'node:readline';\nimport { loadServer, type McpServer, type McpTransport } from './server';\n\nclass StdioTransport implements McpTransport {\n async start(server: McpServer): Promise<void> {\n const rl = readline.createInterface({\n input: process.stdin,\n terminal: false,\n });\n\n const send = (message: any) => {\n process.stdout.write(`${JSON.stringify(message)}\\n`);\n };\n\n rl.on('line', async (line) => {\n const trimmed = line.trim();\n if (!trimmed) return;\n try {\n const message = JSON.parse(trimmed);\n const response = await server.handleMessage(message);\n if (response !== null && response !== undefined) {\n send(response);\n }\n } catch {\n send({\n jsonrpc: '2.0',\n id: null,\n error: { code: -32700, message: 'Parse error' },\n });\n }\n });\n\n console.error('Intlayer MCP Server running on stdio');\n\n await new Promise<void>((resolve) => {\n rl.on('close', resolve);\n });\n }\n}\n\nconst server = loadServer({ isLocal: true });\n\nconst main = async () => {\n const transport = new StdioTransport();\n await server.connect(transport);\n};\n\nmain().catch((error) => {\n console.error('Fatal error in main():', error);\n process.exit(1);\n});\n"],"mappings":";;;;;AAKA,IAAM,iBAAN,MAA6C;CAC3C,MAAM,MAAM,QAAkC;EAC5C,MAAM,KAAK,SAAS,gBAAgB;GAClC,OAAO,QAAQ;GACf,UAAU;GACX,CAAC;EAEF,MAAM,QAAQ,YAAiB;GAC7B,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,QAAQ,CAAC,IAAI;;EAGtD,GAAG,GAAG,QAAQ,OAAO,SAAS;GAC5B,MAAM,UAAU,KAAK,MAAM;GAC3B,IAAI,CAAC,SAAS;GACd,IAAI;IACF,MAAM,UAAU,KAAK,MAAM,QAAQ;IACnC,MAAM,WAAW,MAAM,OAAO,cAAc,QAAQ;IACpD,IAAI,aAAa,QAAQ,aAAa,QACpC,KAAK,SAAS;WAEV;IACN,KAAK;KACH,SAAS;KACT,IAAI;KACJ,OAAO;MAAE,MAAM;MAAQ,SAAS;MAAe;KAChD,CAAC;;IAEJ;EAEF,QAAQ,MAAM,uCAAuC;EAErD,MAAM,IAAI,SAAe,YAAY;GACnC,GAAG,GAAG,SAAS,QAAQ;IACvB;;;AAIN,MAAM,SAAS,WAAW,EAAE,SAAS,MAAM,CAAC;AAE5C,MAAM,OAAO,YAAY;CACvB,MAAM,YAAY,IAAI,gBAAgB;CACtC,MAAM,OAAO,QAAQ,UAAU;;AAGjC,MAAM,CAAC,OAAO,UAAU;CACtB,QAAQ,MAAM,0BAA0B,MAAM;CAC9C,QAAQ,KAAK,EAAE;EACf"}
|