@agiflowai/one-mcp 0.2.0

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.
@@ -0,0 +1,1277 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ let __modelcontextprotocol_sdk_server_index_js = require("@modelcontextprotocol/sdk/server/index.js");
25
+ let __modelcontextprotocol_sdk_types_js = require("@modelcontextprotocol/sdk/types.js");
26
+ let node_fs_promises = require("node:fs/promises");
27
+ let node_fs = require("node:fs");
28
+ let js_yaml = require("js-yaml");
29
+ js_yaml = __toESM(js_yaml);
30
+ let zod = require("zod");
31
+ let __modelcontextprotocol_sdk_client_index_js = require("@modelcontextprotocol/sdk/client/index.js");
32
+ let __modelcontextprotocol_sdk_client_stdio_js = require("@modelcontextprotocol/sdk/client/stdio.js");
33
+ let __modelcontextprotocol_sdk_client_sse_js = require("@modelcontextprotocol/sdk/client/sse.js");
34
+ let __modelcontextprotocol_sdk_server_stdio_js = require("@modelcontextprotocol/sdk/server/stdio.js");
35
+ let __modelcontextprotocol_sdk_server_sse_js = require("@modelcontextprotocol/sdk/server/sse.js");
36
+ let express = require("express");
37
+ express = __toESM(express);
38
+ let node_crypto = require("node:crypto");
39
+ let __modelcontextprotocol_sdk_server_streamableHttp_js = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
40
+
41
+ //#region src/utils/mcpConfigSchema.ts
42
+ /**
43
+ * mcpConfigSchema Utilities
44
+ *
45
+ * DESIGN PATTERNS:
46
+ * - Schema-based validation using Zod
47
+ * - Pure functions with no side effects
48
+ * - Type inference from schemas
49
+ * - Transformation from Claude Code format to internal format
50
+ *
51
+ * CODING STANDARDS:
52
+ * - Export individual functions and schemas
53
+ * - Use descriptive function names with verbs
54
+ * - Add JSDoc comments for complex logic
55
+ * - Keep functions small and focused
56
+ *
57
+ * AVOID:
58
+ * - Side effects (mutating external state)
59
+ * - Stateful logic (use services for state)
60
+ * - Loosely typed configs (use Zod for runtime safety)
61
+ */
62
+ /**
63
+ * Interpolate environment variables in a string
64
+ * Supports ${VAR_NAME} syntax
65
+ *
66
+ * This function replaces environment variable placeholders with their actual values.
67
+ * If an environment variable is not defined, the placeholder is kept as-is and a warning is logged.
68
+ *
69
+ * Examples:
70
+ * - "${HOME}/data" → "/Users/username/data"
71
+ * - "Bearer ${API_KEY}" → "Bearer sk-abc123xyz"
72
+ * - "${DATABASE_URL}/api" → "postgres://localhost:5432/mydb/api"
73
+ *
74
+ * Supported locations for environment variable interpolation:
75
+ * - Stdio config: command, args, env values
76
+ * - HTTP/SSE config: url, header values
77
+ *
78
+ * @param value - String that may contain environment variable references
79
+ * @returns String with environment variables replaced
80
+ */
81
+ function interpolateEnvVars(value) {
82
+ return value.replace(/\$\{([^}]+)\}/g, (_, varName) => {
83
+ const envValue = process.env[varName];
84
+ if (envValue === void 0) {
85
+ console.warn(`Environment variable ${varName} is not defined, keeping placeholder`);
86
+ return `\${${varName}}`;
87
+ }
88
+ return envValue;
89
+ });
90
+ }
91
+ /**
92
+ * Recursively interpolate environment variables in an object
93
+ *
94
+ * @param obj - Object that may contain environment variable references
95
+ * @returns Object with environment variables replaced
96
+ */
97
+ function interpolateEnvVarsInObject(obj) {
98
+ if (typeof obj === "string") return interpolateEnvVars(obj);
99
+ if (Array.isArray(obj)) return obj.map((item) => interpolateEnvVarsInObject(item));
100
+ if (obj !== null && typeof obj === "object") {
101
+ const result = {};
102
+ for (const [key, value] of Object.entries(obj)) result[key] = interpolateEnvVarsInObject(value);
103
+ return result;
104
+ }
105
+ return obj;
106
+ }
107
+ /**
108
+ * Claude Code / Claude Desktop standard MCP config format
109
+ * This is the format users write in their config files
110
+ */
111
+ const AdditionalConfigSchema = zod.z.object({
112
+ instruction: zod.z.string().optional(),
113
+ toolBlacklist: zod.z.array(zod.z.string()).optional(),
114
+ omitToolDescription: zod.z.boolean().optional()
115
+ }).optional();
116
+ const ClaudeCodeStdioServerSchema = zod.z.object({
117
+ command: zod.z.string(),
118
+ args: zod.z.array(zod.z.string()).optional(),
119
+ env: zod.z.record(zod.z.string(), zod.z.string()).optional(),
120
+ disabled: zod.z.boolean().optional(),
121
+ instruction: zod.z.string().optional(),
122
+ config: AdditionalConfigSchema
123
+ });
124
+ const ClaudeCodeHttpServerSchema = zod.z.object({
125
+ url: zod.z.string().url(),
126
+ headers: zod.z.record(zod.z.string(), zod.z.string()).optional(),
127
+ type: zod.z.enum(["http", "sse"]).optional(),
128
+ disabled: zod.z.boolean().optional(),
129
+ instruction: zod.z.string().optional(),
130
+ config: AdditionalConfigSchema
131
+ });
132
+ const ClaudeCodeServerConfigSchema = zod.z.union([ClaudeCodeStdioServerSchema, ClaudeCodeHttpServerSchema]);
133
+ /**
134
+ * Full Claude Code MCP configuration schema
135
+ */
136
+ const ClaudeCodeMcpConfigSchema = zod.z.object({ mcpServers: zod.z.record(zod.z.string(), ClaudeCodeServerConfigSchema) });
137
+ /**
138
+ * Internal MCP config format
139
+ * This is the normalized format used internally by the proxy
140
+ */
141
+ const McpStdioConfigSchema = zod.z.object({
142
+ command: zod.z.string(),
143
+ args: zod.z.array(zod.z.string()).optional(),
144
+ env: zod.z.record(zod.z.string(), zod.z.string()).optional()
145
+ });
146
+ const McpHttpConfigSchema = zod.z.object({
147
+ url: zod.z.string().url(),
148
+ headers: zod.z.record(zod.z.string(), zod.z.string()).optional()
149
+ });
150
+ const McpSseConfigSchema = zod.z.object({
151
+ url: zod.z.string().url(),
152
+ headers: zod.z.record(zod.z.string(), zod.z.string()).optional()
153
+ });
154
+ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
155
+ zod.z.object({
156
+ name: zod.z.string(),
157
+ instruction: zod.z.string().optional(),
158
+ toolBlacklist: zod.z.array(zod.z.string()).optional(),
159
+ omitToolDescription: zod.z.boolean().optional(),
160
+ transport: zod.z.literal("stdio"),
161
+ config: McpStdioConfigSchema
162
+ }),
163
+ zod.z.object({
164
+ name: zod.z.string(),
165
+ instruction: zod.z.string().optional(),
166
+ toolBlacklist: zod.z.array(zod.z.string()).optional(),
167
+ omitToolDescription: zod.z.boolean().optional(),
168
+ transport: zod.z.literal("http"),
169
+ config: McpHttpConfigSchema
170
+ }),
171
+ zod.z.object({
172
+ name: zod.z.string(),
173
+ instruction: zod.z.string().optional(),
174
+ toolBlacklist: zod.z.array(zod.z.string()).optional(),
175
+ omitToolDescription: zod.z.boolean().optional(),
176
+ transport: zod.z.literal("sse"),
177
+ config: McpSseConfigSchema
178
+ })
179
+ ]);
180
+ /**
181
+ * Full internal MCP configuration schema
182
+ */
183
+ const InternalMcpConfigSchema = zod.z.object({ mcpServers: zod.z.record(zod.z.string(), McpServerConfigSchema) });
184
+ /**
185
+ * Transform Claude Code config to internal format
186
+ * Converts standard Claude Code MCP configuration to normalized internal format
187
+ *
188
+ * @param claudeConfig - Claude Code format configuration
189
+ * @returns Internal format configuration
190
+ */
191
+ function transformClaudeCodeConfig(claudeConfig) {
192
+ const transformedServers = {};
193
+ for (const [serverName, serverConfig] of Object.entries(claudeConfig.mcpServers)) {
194
+ if ("disabled" in serverConfig && serverConfig.disabled === true) continue;
195
+ if ("command" in serverConfig) {
196
+ const stdioConfig = serverConfig;
197
+ const interpolatedCommand = interpolateEnvVars(stdioConfig.command);
198
+ const interpolatedArgs = stdioConfig.args?.map((arg) => interpolateEnvVars(arg));
199
+ const interpolatedEnv = stdioConfig.env ? interpolateEnvVarsInObject(stdioConfig.env) : void 0;
200
+ transformedServers[serverName] = {
201
+ name: serverName,
202
+ instruction: stdioConfig.instruction || stdioConfig.config?.instruction,
203
+ toolBlacklist: stdioConfig.config?.toolBlacklist,
204
+ omitToolDescription: stdioConfig.config?.omitToolDescription,
205
+ transport: "stdio",
206
+ config: {
207
+ command: interpolatedCommand,
208
+ args: interpolatedArgs,
209
+ env: interpolatedEnv
210
+ }
211
+ };
212
+ } else if ("url" in serverConfig) {
213
+ const httpConfig = serverConfig;
214
+ const transport = httpConfig.type === "sse" ? "sse" : "http";
215
+ const interpolatedUrl = interpolateEnvVars(httpConfig.url);
216
+ const interpolatedHeaders = httpConfig.headers ? interpolateEnvVarsInObject(httpConfig.headers) : void 0;
217
+ transformedServers[serverName] = {
218
+ name: serverName,
219
+ instruction: httpConfig.instruction || httpConfig.config?.instruction,
220
+ toolBlacklist: httpConfig.config?.toolBlacklist,
221
+ omitToolDescription: httpConfig.config?.omitToolDescription,
222
+ transport,
223
+ config: {
224
+ url: interpolatedUrl,
225
+ headers: interpolatedHeaders
226
+ }
227
+ };
228
+ }
229
+ }
230
+ return { mcpServers: transformedServers };
231
+ }
232
+ /**
233
+ * Parse and validate MCP config from raw JSON
234
+ * Validates against Claude Code format, transforms to internal format, and validates result
235
+ *
236
+ * @param rawConfig - Raw JSON configuration object
237
+ * @returns Validated and transformed internal configuration
238
+ * @throws ZodError if validation fails
239
+ */
240
+ function parseMcpConfig(rawConfig) {
241
+ const internalConfig = transformClaudeCodeConfig(ClaudeCodeMcpConfigSchema.parse(rawConfig));
242
+ return InternalMcpConfigSchema.parse(internalConfig);
243
+ }
244
+
245
+ //#endregion
246
+ //#region src/services/ConfigFetcherService.ts
247
+ /**
248
+ * ConfigFetcherService
249
+ *
250
+ * DESIGN PATTERNS:
251
+ * - Service pattern for business logic encapsulation
252
+ * - Single responsibility principle
253
+ * - Caching pattern for performance optimization
254
+ *
255
+ * CODING STANDARDS:
256
+ * - Use async/await for asynchronous operations
257
+ * - Throw descriptive errors for error cases
258
+ * - Keep methods focused and well-named
259
+ * - Document complex logic with comments
260
+ *
261
+ * AVOID:
262
+ * - Mixing concerns (keep focused on single domain)
263
+ * - Direct tool implementation (services should be tool-agnostic)
264
+ */
265
+ /**
266
+ * Service for fetching and caching MCP server configurations from local file
267
+ */
268
+ var ConfigFetcherService = class {
269
+ configFilePath;
270
+ cacheTtlMs;
271
+ cachedConfig = null;
272
+ lastFetchTime = 0;
273
+ constructor(options) {
274
+ this.configFilePath = options.configFilePath;
275
+ this.cacheTtlMs = options.cacheTtlMs || 6e4;
276
+ if (!this.configFilePath) throw new Error("configFilePath must be provided");
277
+ }
278
+ /**
279
+ * Fetch MCP configuration from local file with caching
280
+ * @param forceRefresh - Force reload from source, bypassing cache
281
+ */
282
+ async fetchConfiguration(forceRefresh = false) {
283
+ const now = Date.now();
284
+ if (!forceRefresh && this.cachedConfig && now - this.lastFetchTime < this.cacheTtlMs) return this.cachedConfig;
285
+ const config = await this.loadFromFile();
286
+ if (!config.mcpServers || typeof config.mcpServers !== "object") throw new Error("Invalid MCP configuration: missing or invalid mcpServers");
287
+ this.cachedConfig = config;
288
+ this.lastFetchTime = now;
289
+ return config;
290
+ }
291
+ /**
292
+ * Load configuration from a local file (supports JSON and YAML)
293
+ */
294
+ async loadFromFile() {
295
+ if (!this.configFilePath) throw new Error("No config file path provided");
296
+ if (!(0, node_fs.existsSync)(this.configFilePath)) throw new Error(`Config file not found: ${this.configFilePath}`);
297
+ try {
298
+ const content = await (0, node_fs_promises.readFile)(this.configFilePath, "utf-8");
299
+ let rawConfig;
300
+ if (this.configFilePath.endsWith(".yaml") || this.configFilePath.endsWith(".yml")) rawConfig = js_yaml.default.load(content);
301
+ else rawConfig = JSON.parse(content);
302
+ return parseMcpConfig(rawConfig);
303
+ } catch (error) {
304
+ if (error instanceof Error) throw new Error(`Failed to load config file: ${error.message}`);
305
+ throw new Error("Failed to load config file: Unknown error");
306
+ }
307
+ }
308
+ /**
309
+ * Clear the cached configuration
310
+ */
311
+ clearCache() {
312
+ this.cachedConfig = null;
313
+ this.lastFetchTime = 0;
314
+ }
315
+ /**
316
+ * Check if cache is valid
317
+ */
318
+ isCacheValid() {
319
+ const now = Date.now();
320
+ return this.cachedConfig !== null && now - this.lastFetchTime < this.cacheTtlMs;
321
+ }
322
+ };
323
+
324
+ //#endregion
325
+ //#region src/services/McpClientManagerService.ts
326
+ /**
327
+ * MCP Client wrapper for managing individual server connections
328
+ */
329
+ var McpClient = class {
330
+ serverName;
331
+ serverInstruction;
332
+ toolBlacklist;
333
+ omitToolDescription;
334
+ transport;
335
+ client;
336
+ childProcess;
337
+ connected = false;
338
+ constructor(serverName, transport, client, config) {
339
+ this.serverName = serverName;
340
+ this.serverInstruction = config.instruction;
341
+ this.toolBlacklist = config.toolBlacklist;
342
+ this.omitToolDescription = config.omitToolDescription;
343
+ this.transport = transport;
344
+ this.client = client;
345
+ }
346
+ setChildProcess(process$1) {
347
+ this.childProcess = process$1;
348
+ }
349
+ setConnected(connected) {
350
+ this.connected = connected;
351
+ }
352
+ async listTools() {
353
+ if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
354
+ return (await this.client.listTools()).tools;
355
+ }
356
+ async listResources() {
357
+ if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
358
+ return (await this.client.listResources()).resources;
359
+ }
360
+ async listPrompts() {
361
+ if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
362
+ return (await this.client.listPrompts()).prompts;
363
+ }
364
+ async callTool(name, args) {
365
+ if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
366
+ return await this.client.callTool({
367
+ name,
368
+ arguments: args
369
+ });
370
+ }
371
+ async readResource(uri) {
372
+ if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
373
+ return await this.client.readResource({ uri });
374
+ }
375
+ async getPrompt(name, args) {
376
+ if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
377
+ return await this.client.getPrompt({
378
+ name,
379
+ arguments: args
380
+ });
381
+ }
382
+ async close() {
383
+ if (this.childProcess) this.childProcess.kill();
384
+ await this.client.close();
385
+ this.connected = false;
386
+ }
387
+ };
388
+ /**
389
+ * Service for managing MCP client connections to remote servers
390
+ */
391
+ var McpClientManagerService = class {
392
+ clients = /* @__PURE__ */ new Map();
393
+ constructor() {
394
+ process.on("exit", () => {
395
+ this.cleanupOnExit();
396
+ });
397
+ process.on("SIGINT", () => {
398
+ this.cleanupOnExit();
399
+ process.exit(0);
400
+ });
401
+ process.on("SIGTERM", () => {
402
+ this.cleanupOnExit();
403
+ process.exit(0);
404
+ });
405
+ }
406
+ /**
407
+ * Cleanup all resources on exit (child processes)
408
+ */
409
+ cleanupOnExit() {
410
+ for (const [serverName, client] of this.clients) try {
411
+ const childProcess = client["childProcess"];
412
+ if (childProcess && !childProcess.killed) {
413
+ console.error(`Killing stdio MCP server: ${serverName} (PID: ${childProcess.pid})`);
414
+ childProcess.kill("SIGTERM");
415
+ setTimeout(() => {
416
+ if (!childProcess.killed) {
417
+ console.error(`Force killing stdio MCP server: ${serverName} (PID: ${childProcess.pid})`);
418
+ childProcess.kill("SIGKILL");
419
+ }
420
+ }, 1e3);
421
+ }
422
+ } catch (error) {
423
+ console.error(`Failed to kill child process for ${serverName}:`, error);
424
+ }
425
+ }
426
+ /**
427
+ * Connect to an MCP server based on its configuration with timeout
428
+ */
429
+ async connectToServer(serverName, config, timeoutMs = 1e4) {
430
+ if (this.clients.has(serverName)) throw new Error(`Client for ${serverName} is already connected`);
431
+ const client = new __modelcontextprotocol_sdk_client_index_js.Client({
432
+ name: `@agiflowai/one-mcp-client`,
433
+ version: "0.1.0"
434
+ }, { capabilities: {} });
435
+ const mcpClient = new McpClient(serverName, config.transport, client, {
436
+ instruction: config.instruction,
437
+ toolBlacklist: config.toolBlacklist,
438
+ omitToolDescription: config.omitToolDescription
439
+ });
440
+ try {
441
+ await Promise.race([this.performConnection(mcpClient, config), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`Connection timeout after ${timeoutMs}ms`)), timeoutMs))]);
442
+ mcpClient.setConnected(true);
443
+ if (!mcpClient.serverInstruction) try {
444
+ const serverInstruction = mcpClient["client"].getInstructions();
445
+ if (serverInstruction) mcpClient.serverInstruction = serverInstruction;
446
+ } catch (error) {
447
+ console.error(`Failed to get server instruction from ${serverName}:`, error);
448
+ }
449
+ this.clients.set(serverName, mcpClient);
450
+ } catch (error) {
451
+ await mcpClient.close();
452
+ throw error;
453
+ }
454
+ }
455
+ /**
456
+ * Perform the actual connection to MCP server
457
+ */
458
+ async performConnection(mcpClient, config) {
459
+ if (config.transport === "stdio") await this.connectStdioClient(mcpClient, config.config);
460
+ else if (config.transport === "sse") await this.connectSseClient(mcpClient, config.config);
461
+ else throw new Error(`Unsupported transport type: ${config.transport}`);
462
+ }
463
+ async connectStdioClient(mcpClient, config) {
464
+ const transport = new __modelcontextprotocol_sdk_client_stdio_js.StdioClientTransport({
465
+ command: config.command,
466
+ args: config.args,
467
+ env: config.env
468
+ });
469
+ await mcpClient["client"].connect(transport);
470
+ const childProcess = transport["_process"];
471
+ if (childProcess) mcpClient.setChildProcess(childProcess);
472
+ }
473
+ async connectSseClient(mcpClient, config) {
474
+ const transport = new __modelcontextprotocol_sdk_client_sse_js.SSEClientTransport(new URL(config.url));
475
+ await mcpClient["client"].connect(transport);
476
+ }
477
+ /**
478
+ * Get a connected client by server name
479
+ */
480
+ getClient(serverName) {
481
+ return this.clients.get(serverName);
482
+ }
483
+ /**
484
+ * Get all connected clients
485
+ */
486
+ getAllClients() {
487
+ return Array.from(this.clients.values());
488
+ }
489
+ /**
490
+ * Disconnect from a specific server
491
+ */
492
+ async disconnectServer(serverName) {
493
+ const client = this.clients.get(serverName);
494
+ if (client) {
495
+ await client.close();
496
+ this.clients.delete(serverName);
497
+ }
498
+ }
499
+ /**
500
+ * Disconnect from all servers
501
+ */
502
+ async disconnectAll() {
503
+ const disconnectPromises = Array.from(this.clients.values()).map((client) => client.close());
504
+ await Promise.all(disconnectPromises);
505
+ this.clients.clear();
506
+ }
507
+ /**
508
+ * Check if a server is connected
509
+ */
510
+ isConnected(serverName) {
511
+ return this.clients.has(serverName);
512
+ }
513
+ };
514
+
515
+ //#endregion
516
+ //#region src/tools/DescribeToolsTool.ts
517
+ var DescribeToolsTool = class DescribeToolsTool {
518
+ static TOOL_NAME = "describe_tools";
519
+ clientManager;
520
+ constructor(clientManager) {
521
+ this.clientManager = clientManager;
522
+ }
523
+ async getDefinition() {
524
+ const clients = this.clientManager.getAllClients();
525
+ const serverDescriptions = await Promise.all(clients.map(async (client) => {
526
+ try {
527
+ const tools = await client.listTools();
528
+ const blacklist = new Set(client.toolBlacklist || []);
529
+ const filteredTools = tools.filter((t) => !blacklist.has(t.name));
530
+ const toolList = client.omitToolDescription ? filteredTools.map((t) => t.name).join(", ") : filteredTools.map((t) => `${t.name}: ${t.description || "No description"}`).join("\n");
531
+ const instructionLine = client.serverInstruction ? `\n- Description: ${client.serverInstruction}` : "";
532
+ return `\n\n### Server: ${client.serverName}${instructionLine}\n- Available tools:${toolList ? "\n" + toolList : ""}`;
533
+ } catch (error) {
534
+ console.error(`Failed to list tools from ${client.serverName}:`, error);
535
+ const instructionLine = client.serverInstruction ? `\n- Description: ${client.serverInstruction}` : "";
536
+ return `\n\n**Server: ${client.serverName}**${instructionLine}\n`;
537
+ }
538
+ }));
539
+ return {
540
+ name: DescribeToolsTool.TOOL_NAME,
541
+ description: `Learn how to use multiple MCP tools before using them. Below are supported tools and capabilities.
542
+
543
+ ## Available MCP Servers:${serverDescriptions.join("")}
544
+
545
+ ## Usage:
546
+ You MUST call this tool with a list of tool names to learn how to use them properly before use_tool; this includes:
547
+ - Arguments schema needed to pass to the tool use
548
+ - Description about each tool
549
+
550
+ This tool is optimized for batch queries - you can request multiple tools at once for better performance.`,
551
+ inputSchema: {
552
+ type: "object",
553
+ properties: {
554
+ toolNames: {
555
+ type: "array",
556
+ items: { type: "string" },
557
+ description: "List of tool names to get detailed information about",
558
+ minItems: 1
559
+ },
560
+ serverName: {
561
+ type: "string",
562
+ description: "Optional server name to search within. If not specified, searches all servers."
563
+ }
564
+ },
565
+ required: ["toolNames"],
566
+ additionalProperties: false
567
+ }
568
+ };
569
+ }
570
+ async execute(input) {
571
+ try {
572
+ const { toolNames, serverName } = input;
573
+ const clients = this.clientManager.getAllClients();
574
+ if (!toolNames || toolNames.length === 0) return {
575
+ content: [{
576
+ type: "text",
577
+ text: "No tool names provided. Please specify at least one tool name."
578
+ }],
579
+ isError: true
580
+ };
581
+ if (serverName) {
582
+ const client = this.clientManager.getClient(serverName);
583
+ if (!client) return {
584
+ content: [{
585
+ type: "text",
586
+ text: `Server "${serverName}" not found. Available servers: ${clients.map((c) => c.serverName).join(", ")}`
587
+ }],
588
+ isError: true
589
+ };
590
+ const tools = await client.listTools();
591
+ const blacklist = new Set(client.toolBlacklist || []);
592
+ const filteredTools = tools.filter((t) => !blacklist.has(t.name));
593
+ const foundTools$1 = [];
594
+ const notFoundTools$1 = [];
595
+ for (const toolName of toolNames) {
596
+ if (blacklist.has(toolName)) {
597
+ notFoundTools$1.push(toolName);
598
+ continue;
599
+ }
600
+ const tool = filteredTools.find((t) => t.name === toolName);
601
+ if (tool) foundTools$1.push({
602
+ server: serverName,
603
+ tool: {
604
+ name: tool.name,
605
+ description: tool.description,
606
+ inputSchema: tool.inputSchema
607
+ }
608
+ });
609
+ else notFoundTools$1.push(toolName);
610
+ }
611
+ if (foundTools$1.length === 0) return {
612
+ content: [{
613
+ type: "text",
614
+ text: `None of the requested tools found on server "${serverName}".\nRequested: ${toolNames.join(", ")}\nAvailable tools: ${tools.map((t) => t.name).join(", ")}`
615
+ }],
616
+ isError: true
617
+ };
618
+ const result$1 = { tools: foundTools$1 };
619
+ if (notFoundTools$1.length > 0) {
620
+ result$1.notFound = notFoundTools$1;
621
+ result$1.warning = `Some tools were not found on server "${serverName}": ${notFoundTools$1.join(", ")}`;
622
+ }
623
+ return { content: [{
624
+ type: "text",
625
+ text: JSON.stringify(result$1, null, 2)
626
+ }] };
627
+ }
628
+ const foundTools = [];
629
+ const notFoundTools = [...toolNames];
630
+ const toolMatches = /* @__PURE__ */ new Map();
631
+ const results = await Promise.all(clients.map(async (client) => {
632
+ try {
633
+ const tools = await client.listTools();
634
+ const blacklist = new Set(client.toolBlacklist || []);
635
+ const filteredTools = tools.filter((t) => !blacklist.has(t.name));
636
+ const matches = [];
637
+ for (const toolName of toolNames) {
638
+ if (blacklist.has(toolName)) continue;
639
+ const tool = filteredTools.find((t) => t.name === toolName);
640
+ if (tool) matches.push({
641
+ toolName,
642
+ server: client.serverName,
643
+ tool
644
+ });
645
+ }
646
+ return matches;
647
+ } catch (error) {
648
+ console.error(`Failed to list tools from ${client.serverName}:`, error);
649
+ return [];
650
+ }
651
+ }));
652
+ for (const matches of results) for (const match of matches) {
653
+ if (!toolMatches.has(match.toolName)) toolMatches.set(match.toolName, []);
654
+ toolMatches.get(match.toolName).push({
655
+ server: match.server,
656
+ tool: match.tool
657
+ });
658
+ }
659
+ const ambiguousTools = [];
660
+ for (const toolName of toolNames) {
661
+ const matches = toolMatches.get(toolName);
662
+ if (!matches || matches.length === 0) continue;
663
+ if (matches.length === 1) {
664
+ const match = matches[0];
665
+ foundTools.push({
666
+ server: match.server,
667
+ tool: {
668
+ name: match.tool.name,
669
+ description: match.tool.description,
670
+ inputSchema: match.tool.inputSchema
671
+ }
672
+ });
673
+ const idx = notFoundTools.indexOf(toolName);
674
+ if (idx > -1) notFoundTools.splice(idx, 1);
675
+ } else {
676
+ ambiguousTools.push({
677
+ toolName,
678
+ servers: matches.map((m) => m.server)
679
+ });
680
+ const idx = notFoundTools.indexOf(toolName);
681
+ if (idx > -1) notFoundTools.splice(idx, 1);
682
+ }
683
+ }
684
+ if (foundTools.length === 0 && ambiguousTools.length === 0) return {
685
+ content: [{
686
+ type: "text",
687
+ text: `None of the requested tools found on any connected server.\nRequested: ${toolNames.join(", ")}\nUse describe_tools without arguments to see available servers.`
688
+ }],
689
+ isError: true
690
+ };
691
+ const result = { tools: foundTools };
692
+ if (notFoundTools.length > 0) result.notFound = notFoundTools;
693
+ if (ambiguousTools.length > 0) result.ambiguous = ambiguousTools.map((item) => ({
694
+ toolName: item.toolName,
695
+ servers: item.servers,
696
+ message: `Tool "${item.toolName}" found on multiple servers: ${item.servers.join(", ")}. Please specify serverName to disambiguate.`
697
+ }));
698
+ const warnings = [];
699
+ if (notFoundTools.length > 0) warnings.push(`Tools not found: ${notFoundTools.join(", ")}`);
700
+ if (ambiguousTools.length > 0) warnings.push(`Ambiguous tools (specify serverName): ${ambiguousTools.map((t) => t.toolName).join(", ")}`);
701
+ if (warnings.length > 0) result.warnings = warnings;
702
+ return { content: [{
703
+ type: "text",
704
+ text: JSON.stringify(result, null, 2)
705
+ }] };
706
+ } catch (error) {
707
+ return {
708
+ content: [{
709
+ type: "text",
710
+ text: `Error describing tools: ${error instanceof Error ? error.message : "Unknown error"}`
711
+ }],
712
+ isError: true
713
+ };
714
+ }
715
+ }
716
+ };
717
+
718
+ //#endregion
719
+ //#region src/tools/UseToolTool.ts
720
+ var UseToolTool = class UseToolTool {
721
+ static TOOL_NAME = "use_tool";
722
+ clientManager;
723
+ constructor(clientManager) {
724
+ this.clientManager = clientManager;
725
+ }
726
+ getDefinition() {
727
+ return {
728
+ name: UseToolTool.TOOL_NAME,
729
+ description: `Execute an MCP tool with provided arguments. You MUST call describe_tools first to discover the tool's correct arguments. Then to use tool:
730
+ - Provide toolName and toolArgs based on the schema
731
+ - If multiple servers provide the same tool, specify serverName
732
+ `,
733
+ inputSchema: {
734
+ type: "object",
735
+ properties: {
736
+ toolName: {
737
+ type: "string",
738
+ description: "Name of the tool to execute"
739
+ },
740
+ toolArgs: {
741
+ type: "object",
742
+ description: "Arguments to pass to the tool, as discovered from describe_tools"
743
+ },
744
+ serverName: {
745
+ type: "string",
746
+ description: "Optional server name to disambiguate when multiple servers have the same tool"
747
+ }
748
+ },
749
+ required: ["toolName"],
750
+ additionalProperties: false
751
+ }
752
+ };
753
+ }
754
+ async execute(input) {
755
+ try {
756
+ const { toolName, toolArgs = {}, serverName } = input;
757
+ const clients = this.clientManager.getAllClients();
758
+ if (serverName) {
759
+ const client$1 = this.clientManager.getClient(serverName);
760
+ if (!client$1) return {
761
+ content: [{
762
+ type: "text",
763
+ text: `Server "${serverName}" not found. Available servers: ${clients.map((c) => c.serverName).join(", ")}`
764
+ }],
765
+ isError: true
766
+ };
767
+ if (client$1.toolBlacklist && client$1.toolBlacklist.includes(toolName)) return {
768
+ content: [{
769
+ type: "text",
770
+ text: `Tool "${toolName}" is blacklisted on server "${serverName}" and cannot be executed.`
771
+ }],
772
+ isError: true
773
+ };
774
+ try {
775
+ return await client$1.callTool(toolName, toolArgs);
776
+ } catch (error) {
777
+ return {
778
+ content: [{
779
+ type: "text",
780
+ text: `Failed to call tool "${toolName}" on server "${serverName}": ${error instanceof Error ? error.message : "Unknown error"}`
781
+ }],
782
+ isError: true
783
+ };
784
+ }
785
+ }
786
+ const matchingServers = [];
787
+ const results = await Promise.all(clients.map(async (client$1) => {
788
+ try {
789
+ if (client$1.toolBlacklist && client$1.toolBlacklist.includes(toolName)) return null;
790
+ if ((await client$1.listTools()).some((t) => t.name === toolName)) return client$1.serverName;
791
+ } catch (error) {
792
+ console.error(`Failed to list tools from ${client$1.serverName}:`, error);
793
+ }
794
+ return null;
795
+ }));
796
+ matchingServers.push(...results.filter((r) => r !== null));
797
+ if (matchingServers.length === 0) return {
798
+ content: [{
799
+ type: "text",
800
+ text: `Tool "${toolName}" not found on any connected server. Use describe_tools to see available tools.`
801
+ }],
802
+ isError: true
803
+ };
804
+ if (matchingServers.length > 1) return {
805
+ content: [{
806
+ type: "text",
807
+ text: `Multiple servers provide tool "${toolName}". Please specify serverName. Available servers: ${matchingServers.join(", ")}`
808
+ }],
809
+ isError: true
810
+ };
811
+ const targetServerName = matchingServers[0];
812
+ const client = this.clientManager.getClient(targetServerName);
813
+ if (!client) return {
814
+ content: [{
815
+ type: "text",
816
+ text: `Internal error: Server "${targetServerName}" was found but is not connected`
817
+ }],
818
+ isError: true
819
+ };
820
+ try {
821
+ return await client.callTool(toolName, toolArgs);
822
+ } catch (error) {
823
+ return {
824
+ content: [{
825
+ type: "text",
826
+ text: `Failed to call tool "${toolName}": ${error instanceof Error ? error.message : "Unknown error"}`
827
+ }],
828
+ isError: true
829
+ };
830
+ }
831
+ } catch (error) {
832
+ return {
833
+ content: [{
834
+ type: "text",
835
+ text: `Error executing tool: ${error instanceof Error ? error.message : "Unknown error"}`
836
+ }],
837
+ isError: true
838
+ };
839
+ }
840
+ }
841
+ };
842
+
843
+ //#endregion
844
+ //#region src/server/index.ts
845
+ /**
846
+ * MCP Server Setup
847
+ *
848
+ * DESIGN PATTERNS:
849
+ * - Factory pattern for server creation
850
+ * - Tool registration pattern
851
+ * - Dependency injection for services
852
+ *
853
+ * CODING STANDARDS:
854
+ * - Register all tools, resources, and prompts here
855
+ * - Keep server setup modular and extensible
856
+ * - Import tools from ../tools/ and register them in the handlers
857
+ */
858
+ async function createServer(options) {
859
+ const server = new __modelcontextprotocol_sdk_server_index_js.Server({
860
+ name: "@agiflowai/one-mcp",
861
+ version: "0.1.0"
862
+ }, { capabilities: { tools: {} } });
863
+ const clientManager = new McpClientManagerService();
864
+ if (options?.configFilePath) try {
865
+ const config = await new ConfigFetcherService({ configFilePath: options.configFilePath }).fetchConfiguration(options.noCache || false);
866
+ const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
867
+ try {
868
+ await clientManager.connectToServer(serverName, serverConfig);
869
+ console.error(`Connected to MCP server: ${serverName}`);
870
+ } catch (error) {
871
+ console.error(`Failed to connect to ${serverName}:`, error);
872
+ }
873
+ });
874
+ await Promise.all(connectionPromises);
875
+ } catch (error) {
876
+ console.error("Failed to load MCP configuration:", error);
877
+ }
878
+ const describeTools = new DescribeToolsTool(clientManager);
879
+ const useTool = new UseToolTool(clientManager);
880
+ server.setRequestHandler(__modelcontextprotocol_sdk_types_js.ListToolsRequestSchema, async () => ({ tools: [await describeTools.getDefinition(), useTool.getDefinition()] }));
881
+ server.setRequestHandler(__modelcontextprotocol_sdk_types_js.CallToolRequestSchema, async (request) => {
882
+ const { name, arguments: args } = request.params;
883
+ if (name === DescribeToolsTool.TOOL_NAME) return await describeTools.execute(args);
884
+ if (name === UseToolTool.TOOL_NAME) return await useTool.execute(args);
885
+ throw new Error(`Unknown tool: ${name}`);
886
+ });
887
+ return server;
888
+ }
889
+
890
+ //#endregion
891
+ //#region src/transports/stdio.ts
892
+ /**
893
+ * Stdio transport handler for MCP server
894
+ * Used for command-line and direct integrations
895
+ */
896
+ var StdioTransportHandler = class {
897
+ server;
898
+ transport = null;
899
+ constructor(server) {
900
+ this.server = server;
901
+ }
902
+ async start() {
903
+ this.transport = new __modelcontextprotocol_sdk_server_stdio_js.StdioServerTransport();
904
+ await this.server.connect(this.transport);
905
+ console.error("@agiflowai/one-mcp MCP server started on stdio");
906
+ }
907
+ async stop() {
908
+ if (this.transport) {
909
+ await this.transport.close();
910
+ this.transport = null;
911
+ }
912
+ }
913
+ };
914
+
915
+ //#endregion
916
+ //#region src/transports/sse.ts
917
+ /**
918
+ * Session manager for SSE transports
919
+ */
920
+ var SseSessionManager = class {
921
+ sessions = /* @__PURE__ */ new Map();
922
+ getSession(sessionId) {
923
+ return this.sessions.get(sessionId)?.transport;
924
+ }
925
+ setSession(sessionId, transport, server) {
926
+ this.sessions.set(sessionId, {
927
+ transport,
928
+ server
929
+ });
930
+ }
931
+ deleteSession(sessionId) {
932
+ const session = this.sessions.get(sessionId);
933
+ if (session) session.server.close();
934
+ this.sessions.delete(sessionId);
935
+ }
936
+ hasSession(sessionId) {
937
+ return this.sessions.has(sessionId);
938
+ }
939
+ clear() {
940
+ for (const session of this.sessions.values()) session.server.close();
941
+ this.sessions.clear();
942
+ }
943
+ };
944
+ /**
945
+ * SSE (Server-Sent Events) transport handler
946
+ * Legacy transport for backwards compatibility (protocol version 2024-11-05)
947
+ * Uses separate endpoints: /sse for SSE stream (GET) and /messages for client messages (POST)
948
+ */
949
+ var SseTransportHandler = class {
950
+ serverFactory;
951
+ app;
952
+ server = null;
953
+ sessionManager;
954
+ config;
955
+ constructor(serverFactory, config) {
956
+ this.serverFactory = typeof serverFactory === "function" ? serverFactory : () => serverFactory;
957
+ this.app = (0, express.default)();
958
+ this.sessionManager = new SseSessionManager();
959
+ this.config = {
960
+ mode: config.mode,
961
+ port: config.port ?? 3e3,
962
+ host: config.host ?? "localhost"
963
+ };
964
+ this.setupMiddleware();
965
+ this.setupRoutes();
966
+ }
967
+ setupMiddleware() {
968
+ this.app.use(express.default.json());
969
+ }
970
+ setupRoutes() {
971
+ this.app.get("/sse", async (req, res) => {
972
+ await this.handleSseConnection(req, res);
973
+ });
974
+ this.app.post("/messages", async (req, res) => {
975
+ await this.handlePostMessage(req, res);
976
+ });
977
+ this.app.get("/health", (_req, res) => {
978
+ res.json({
979
+ status: "ok",
980
+ transport: "sse"
981
+ });
982
+ });
983
+ }
984
+ async handleSseConnection(_req, res) {
985
+ try {
986
+ const mcpServer = this.serverFactory();
987
+ const transport = new __modelcontextprotocol_sdk_server_sse_js.SSEServerTransport("/messages", res);
988
+ this.sessionManager.setSession(transport.sessionId, transport, mcpServer);
989
+ res.on("close", () => {
990
+ this.sessionManager.deleteSession(transport.sessionId);
991
+ });
992
+ await mcpServer.connect(transport);
993
+ console.error(`SSE session established: ${transport.sessionId}`);
994
+ } catch (error) {
995
+ console.error("Error handling SSE connection:", error);
996
+ if (!res.headersSent) res.status(500).send("Internal Server Error");
997
+ }
998
+ }
999
+ async handlePostMessage(req, res) {
1000
+ const sessionId = req.query.sessionId;
1001
+ if (!sessionId) {
1002
+ res.status(400).send("Missing sessionId query parameter");
1003
+ return;
1004
+ }
1005
+ const transport = this.sessionManager.getSession(sessionId);
1006
+ if (!transport) {
1007
+ res.status(404).send("No transport found for sessionId");
1008
+ return;
1009
+ }
1010
+ try {
1011
+ await transport.handlePostMessage(req, res, req.body);
1012
+ } catch (error) {
1013
+ console.error("Error handling post message:", error);
1014
+ if (!res.headersSent) res.status(500).send("Internal Server Error");
1015
+ }
1016
+ }
1017
+ async start() {
1018
+ return new Promise((resolve, reject) => {
1019
+ try {
1020
+ this.server = this.app.listen(this.config.port, this.config.host, () => {
1021
+ console.error(`@agiflowai/one-mcp MCP server started with SSE transport on http://${this.config.host}:${this.config.port}`);
1022
+ console.error(`SSE endpoint: http://${this.config.host}:${this.config.port}/sse`);
1023
+ console.error(`Messages endpoint: http://${this.config.host}:${this.config.port}/messages`);
1024
+ console.error(`Health check: http://${this.config.host}:${this.config.port}/health`);
1025
+ resolve();
1026
+ });
1027
+ this.server.on("error", (error) => {
1028
+ reject(error);
1029
+ });
1030
+ } catch (error) {
1031
+ reject(error);
1032
+ }
1033
+ });
1034
+ }
1035
+ async stop() {
1036
+ return new Promise((resolve, reject) => {
1037
+ if (this.server) {
1038
+ this.sessionManager.clear();
1039
+ this.server.close((err) => {
1040
+ if (err) reject(err);
1041
+ else {
1042
+ this.server = null;
1043
+ resolve();
1044
+ }
1045
+ });
1046
+ } else resolve();
1047
+ });
1048
+ }
1049
+ getPort() {
1050
+ return this.config.port;
1051
+ }
1052
+ getHost() {
1053
+ return this.config.host;
1054
+ }
1055
+ };
1056
+
1057
+ //#endregion
1058
+ //#region src/transports/http.ts
1059
+ /**
1060
+ * HTTP Transport Handler
1061
+ *
1062
+ * DESIGN PATTERNS:
1063
+ * - Transport handler pattern implementing TransportHandler interface
1064
+ * - Session management for stateful connections
1065
+ * - Streamable HTTP protocol (2025-03-26) with resumability support
1066
+ * - Factory pattern for creating MCP server instances per session
1067
+ *
1068
+ * CODING STANDARDS:
1069
+ * - Use async/await for all asynchronous operations
1070
+ * - Implement proper session lifecycle management
1071
+ * - Handle errors gracefully with appropriate HTTP status codes
1072
+ * - Provide health check endpoint for monitoring
1073
+ * - Clean up resources on shutdown
1074
+ *
1075
+ * AVOID:
1076
+ * - Sharing MCP server instances across sessions (use factory pattern)
1077
+ * - Forgetting to clean up sessions on disconnect
1078
+ * - Missing error handling for request processing
1079
+ * - Hardcoded configuration (use TransportConfig)
1080
+ */
1081
+ /**
1082
+ * HTTP session manager
1083
+ */
1084
+ var HttpFullSessionManager = class {
1085
+ sessions = /* @__PURE__ */ new Map();
1086
+ getSession(sessionId) {
1087
+ return this.sessions.get(sessionId);
1088
+ }
1089
+ setSession(sessionId, transport, server) {
1090
+ this.sessions.set(sessionId, {
1091
+ transport,
1092
+ server
1093
+ });
1094
+ }
1095
+ deleteSession(sessionId) {
1096
+ const session = this.sessions.get(sessionId);
1097
+ if (session) session.server.close();
1098
+ this.sessions.delete(sessionId);
1099
+ }
1100
+ hasSession(sessionId) {
1101
+ return this.sessions.has(sessionId);
1102
+ }
1103
+ clear() {
1104
+ for (const session of this.sessions.values()) session.server.close();
1105
+ this.sessions.clear();
1106
+ }
1107
+ };
1108
+ /**
1109
+ * HTTP transport handler using Streamable HTTP (protocol version 2025-03-26)
1110
+ * Provides stateful session management with resumability support
1111
+ */
1112
+ var HttpTransportHandler = class {
1113
+ serverFactory;
1114
+ app;
1115
+ server = null;
1116
+ sessionManager;
1117
+ config;
1118
+ constructor(serverFactory, config) {
1119
+ this.serverFactory = typeof serverFactory === "function" ? serverFactory : () => serverFactory;
1120
+ this.app = (0, express.default)();
1121
+ this.sessionManager = new HttpFullSessionManager();
1122
+ this.config = {
1123
+ mode: config.mode,
1124
+ port: config.port ?? 3e3,
1125
+ host: config.host ?? "localhost"
1126
+ };
1127
+ this.setupMiddleware();
1128
+ this.setupRoutes();
1129
+ }
1130
+ setupMiddleware() {
1131
+ this.app.use(express.default.json());
1132
+ }
1133
+ setupRoutes() {
1134
+ this.app.post("/mcp", async (req, res) => {
1135
+ await this.handlePostRequest(req, res);
1136
+ });
1137
+ this.app.get("/mcp", async (req, res) => {
1138
+ await this.handleGetRequest(req, res);
1139
+ });
1140
+ this.app.delete("/mcp", async (req, res) => {
1141
+ await this.handleDeleteRequest(req, res);
1142
+ });
1143
+ this.app.get("/health", (_req, res) => {
1144
+ res.json({
1145
+ status: "ok",
1146
+ transport: "http"
1147
+ });
1148
+ });
1149
+ }
1150
+ async handlePostRequest(req, res) {
1151
+ const sessionId = req.headers["mcp-session-id"];
1152
+ let transport;
1153
+ if (sessionId && this.sessionManager.hasSession(sessionId)) transport = this.sessionManager.getSession(sessionId).transport;
1154
+ else if (!sessionId && (0, __modelcontextprotocol_sdk_types_js.isInitializeRequest)(req.body)) {
1155
+ const mcpServer = this.serverFactory();
1156
+ transport = new __modelcontextprotocol_sdk_server_streamableHttp_js.StreamableHTTPServerTransport({
1157
+ sessionIdGenerator: () => (0, node_crypto.randomUUID)(),
1158
+ enableJsonResponse: true,
1159
+ onsessioninitialized: (sessionId$1) => {
1160
+ this.sessionManager.setSession(sessionId$1, transport, mcpServer);
1161
+ }
1162
+ });
1163
+ transport.onclose = () => {
1164
+ if (transport.sessionId) this.sessionManager.deleteSession(transport.sessionId);
1165
+ };
1166
+ await mcpServer.connect(transport);
1167
+ } else {
1168
+ res.status(400).json({
1169
+ jsonrpc: "2.0",
1170
+ error: {
1171
+ code: -32e3,
1172
+ message: "Bad Request: No valid session ID provided"
1173
+ },
1174
+ id: null
1175
+ });
1176
+ return;
1177
+ }
1178
+ await transport.handleRequest(req, res, req.body);
1179
+ }
1180
+ async handleGetRequest(req, res) {
1181
+ const sessionId = req.headers["mcp-session-id"];
1182
+ if (!sessionId || !this.sessionManager.hasSession(sessionId)) {
1183
+ res.status(400).send("Invalid or missing session ID");
1184
+ return;
1185
+ }
1186
+ await this.sessionManager.getSession(sessionId).transport.handleRequest(req, res);
1187
+ }
1188
+ async handleDeleteRequest(req, res) {
1189
+ const sessionId = req.headers["mcp-session-id"];
1190
+ if (!sessionId || !this.sessionManager.hasSession(sessionId)) {
1191
+ res.status(400).send("Invalid or missing session ID");
1192
+ return;
1193
+ }
1194
+ await this.sessionManager.getSession(sessionId).transport.handleRequest(req, res);
1195
+ this.sessionManager.deleteSession(sessionId);
1196
+ }
1197
+ async start() {
1198
+ return new Promise((resolve, reject) => {
1199
+ try {
1200
+ this.server = this.app.listen(this.config.port, this.config.host, () => {
1201
+ console.error(`@agiflowai/one-mcp MCP server started on http://${this.config.host}:${this.config.port}/mcp`);
1202
+ console.error(`Health check: http://${this.config.host}:${this.config.port}/health`);
1203
+ resolve();
1204
+ });
1205
+ this.server.on("error", (error) => {
1206
+ reject(error);
1207
+ });
1208
+ } catch (error) {
1209
+ reject(error);
1210
+ }
1211
+ });
1212
+ }
1213
+ async stop() {
1214
+ return new Promise((resolve, reject) => {
1215
+ if (this.server) {
1216
+ this.sessionManager.clear();
1217
+ this.server.close((err) => {
1218
+ if (err) reject(err);
1219
+ else {
1220
+ this.server = null;
1221
+ resolve();
1222
+ }
1223
+ });
1224
+ } else resolve();
1225
+ });
1226
+ }
1227
+ getPort() {
1228
+ return this.config.port;
1229
+ }
1230
+ getHost() {
1231
+ return this.config.host;
1232
+ }
1233
+ };
1234
+
1235
+ //#endregion
1236
+ Object.defineProperty(exports, 'ConfigFetcherService', {
1237
+ enumerable: true,
1238
+ get: function () {
1239
+ return ConfigFetcherService;
1240
+ }
1241
+ });
1242
+ Object.defineProperty(exports, 'HttpTransportHandler', {
1243
+ enumerable: true,
1244
+ get: function () {
1245
+ return HttpTransportHandler;
1246
+ }
1247
+ });
1248
+ Object.defineProperty(exports, 'McpClientManagerService', {
1249
+ enumerable: true,
1250
+ get: function () {
1251
+ return McpClientManagerService;
1252
+ }
1253
+ });
1254
+ Object.defineProperty(exports, 'SseTransportHandler', {
1255
+ enumerable: true,
1256
+ get: function () {
1257
+ return SseTransportHandler;
1258
+ }
1259
+ });
1260
+ Object.defineProperty(exports, 'StdioTransportHandler', {
1261
+ enumerable: true,
1262
+ get: function () {
1263
+ return StdioTransportHandler;
1264
+ }
1265
+ });
1266
+ Object.defineProperty(exports, '__toESM', {
1267
+ enumerable: true,
1268
+ get: function () {
1269
+ return __toESM;
1270
+ }
1271
+ });
1272
+ Object.defineProperty(exports, 'createServer', {
1273
+ enumerable: true,
1274
+ get: function () {
1275
+ return createServer;
1276
+ }
1277
+ });