@agiflowai/one-mcp 0.3.16 → 0.3.18

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/cli.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_src = require('./src-BRqEdbha.cjs');
2
+ const require_src = require('./src-hm1dRqUF.cjs');
3
3
  let node_fs_promises = require("node:fs/promises");
4
4
  let node_fs = require("node:fs");
5
5
  let node_crypto = require("node:crypto");
@@ -1132,7 +1132,7 @@ const describeToolsCommand = new commander.Command("describe-tools").description
1132
1132
  /**
1133
1133
  * Execute an MCP tool with arguments
1134
1134
  */
1135
- const useToolCommand = new commander.Command("use-tool").description("Execute an MCP tool with arguments").argument("<toolName>", "Tool name to execute").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Server name (required if tool exists on multiple servers)").option("-a, --args <json>", "Tool arguments as JSON string", "{}").option("-j, --json", "Output as JSON", false).action(async (toolName, options) => {
1135
+ const useToolCommand = new commander.Command("use-tool").description("Execute an MCP tool with arguments").argument("<toolName>", "Tool name to execute").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Server name (required if tool exists on multiple servers)").option("-a, --args <json>", "Tool arguments as JSON string", "{}").option("-t, --timeout <ms>", "Request timeout in milliseconds for tool execution (default: 60000)", parseInt).option("-j, --json", "Output as JSON", false).action(async (toolName, options) => {
1136
1136
  try {
1137
1137
  const configFilePath = options.config || require_src.findConfigFile();
1138
1138
  if (!configFilePath) {
@@ -1170,7 +1170,8 @@ const useToolCommand = new commander.Command("use-tool").description("Execute an
1170
1170
  }
1171
1171
  try {
1172
1172
  if (!options.json) console.error(`Executing ${toolName} on ${options.server}...`);
1173
- const result = await client$1.callTool(toolName, toolArgs);
1173
+ const requestOptions = options.timeout ? { timeout: options.timeout } : void 0;
1174
+ const result = await client$1.callTool(toolName, toolArgs, requestOptions);
1174
1175
  if (options.json) console.log(JSON.stringify(result, null, 2));
1175
1176
  else {
1176
1177
  console.log("\nResult:");
@@ -1255,7 +1256,8 @@ const useToolCommand = new commander.Command("use-tool").description("Execute an
1255
1256
  }
1256
1257
  try {
1257
1258
  if (!options.json) console.error(`Executing ${toolName} on ${targetServer}...`);
1258
- const result = await client.callTool(toolName, toolArgs);
1259
+ const requestOpts = options.timeout ? { timeout: options.timeout } : void 0;
1260
+ const result = await client.callTool(toolName, toolArgs, requestOpts);
1259
1261
  if (options.json) console.log(JSON.stringify(result, null, 2));
1260
1262
  else {
1261
1263
  console.log("\nResult:");
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { _ as DefinitionsCacheService, a as SseTransportHandler, b as ConfigFetcherService, c as createServer, d as version, g as McpClientManagerService, h as SkillService, i as StdioTransportHandler, l as createSessionServer, n as RuntimeStateService, o as HttpTransportHandler, p as SearchListToolsTool, r as StdioHttpTransportHandler, s as TRANSPORT_MODE, t as StopServerService, u as initializeSharedServices, v as generateServerId, y as findConfigFile } from "./src-Dn6vMZIk.mjs";
2
+ import { _ as DefinitionsCacheService, a as SseTransportHandler, b as ConfigFetcherService, c as createServer, d as version, g as McpClientManagerService, h as SkillService, i as StdioTransportHandler, l as createSessionServer, n as RuntimeStateService, o as HttpTransportHandler, p as SearchListToolsTool, r as StdioHttpTransportHandler, s as TRANSPORT_MODE, t as StopServerService, u as initializeSharedServices, v as generateServerId, y as findConfigFile } from "./src-DPIjPYdS.mjs";
3
3
  import { access, writeFile } from "node:fs/promises";
4
4
  import { constants } from "node:fs";
5
5
  import { randomUUID } from "node:crypto";
@@ -1132,7 +1132,7 @@ const describeToolsCommand = new Command("describe-tools").description("Describe
1132
1132
  /**
1133
1133
  * Execute an MCP tool with arguments
1134
1134
  */
1135
- const useToolCommand = new Command("use-tool").description("Execute an MCP tool with arguments").argument("<toolName>", "Tool name to execute").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Server name (required if tool exists on multiple servers)").option("-a, --args <json>", "Tool arguments as JSON string", "{}").option("-j, --json", "Output as JSON", false).action(async (toolName, options) => {
1135
+ const useToolCommand = new Command("use-tool").description("Execute an MCP tool with arguments").argument("<toolName>", "Tool name to execute").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Server name (required if tool exists on multiple servers)").option("-a, --args <json>", "Tool arguments as JSON string", "{}").option("-t, --timeout <ms>", "Request timeout in milliseconds for tool execution (default: 60000)", parseInt).option("-j, --json", "Output as JSON", false).action(async (toolName, options) => {
1136
1136
  try {
1137
1137
  const configFilePath = options.config || findConfigFile();
1138
1138
  if (!configFilePath) {
@@ -1170,7 +1170,8 @@ const useToolCommand = new Command("use-tool").description("Execute an MCP tool
1170
1170
  }
1171
1171
  try {
1172
1172
  if (!options.json) console.error(`Executing ${toolName} on ${options.server}...`);
1173
- const result = await client$1.callTool(toolName, toolArgs);
1173
+ const requestOptions = options.timeout ? { timeout: options.timeout } : void 0;
1174
+ const result = await client$1.callTool(toolName, toolArgs, requestOptions);
1174
1175
  if (options.json) console.log(JSON.stringify(result, null, 2));
1175
1176
  else {
1176
1177
  console.log("\nResult:");
@@ -1255,7 +1256,8 @@ const useToolCommand = new Command("use-tool").description("Execute an MCP tool
1255
1256
  }
1256
1257
  try {
1257
1258
  if (!options.json) console.error(`Executing ${toolName} on ${targetServer}...`);
1258
- const result = await client.callTool(toolName, toolArgs);
1259
+ const requestOpts = options.timeout ? { timeout: options.timeout } : void 0;
1260
+ const result = await client.callTool(toolName, toolArgs, requestOpts);
1259
1261
  if (options.json) console.log(JSON.stringify(result, null, 2));
1260
1262
  else {
1261
1263
  console.log("\nResult:");
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_src = require('./src-BRqEdbha.cjs');
1
+ const require_src = require('./src-hm1dRqUF.cjs');
2
2
 
3
3
  exports.ConfigFetcherService = require_src.ConfigFetcherService;
4
4
  exports.DefinitionsCacheService = require_src.DefinitionsCacheService;
package/dist/index.d.cts CHANGED
@@ -221,6 +221,8 @@ interface McpServerConfig {
221
221
  transport: McpServerTransportType;
222
222
  config: McpServerTransportConfig;
223
223
  timeout?: number;
224
+ /** Optional per-request timeout in milliseconds for tool calls (default: 60000 from MCP SDK) */
225
+ requestTimeout?: number;
224
226
  disabled?: boolean;
225
227
  }
226
228
  /**
@@ -322,7 +324,9 @@ interface McpClientConnection {
322
324
  /** List available prompts from the server */
323
325
  listPrompts(): Promise<McpPromptInfo[]>;
324
326
  /** Call a tool with the given name and arguments */
325
- callTool(name: string, args: Record<string, unknown>): Promise<CallToolResult>;
327
+ callTool(name: string, args: Record<string, unknown>, options?: {
328
+ timeout?: number;
329
+ }): Promise<CallToolResult>;
326
330
  /** Read a resource by URI */
327
331
  readResource(uri: string): Promise<ReadResourceResult>;
328
332
  /** Get a prompt by name with optional arguments */
@@ -552,6 +556,7 @@ declare class McpClientManagerService {
552
556
  connectToServer(serverName: string, config: McpServerConfig): Promise<void>;
553
557
  registerServerConfigs(configs: Record<string, McpServerConfig>): void;
554
558
  getKnownServerNames(): string[];
559
+ getServerRequestTimeout(serverName: string): number | undefined;
555
560
  ensureConnected(serverName: string): Promise<McpClientConnection>;
556
561
  private createConnection;
557
562
  /**
package/dist/index.d.mts CHANGED
@@ -222,6 +222,8 @@ interface McpServerConfig {
222
222
  transport: McpServerTransportType;
223
223
  config: McpServerTransportConfig;
224
224
  timeout?: number;
225
+ /** Optional per-request timeout in milliseconds for tool calls (default: 60000 from MCP SDK) */
226
+ requestTimeout?: number;
225
227
  disabled?: boolean;
226
228
  }
227
229
  /**
@@ -323,7 +325,9 @@ interface McpClientConnection {
323
325
  /** List available prompts from the server */
324
326
  listPrompts(): Promise<McpPromptInfo[]>;
325
327
  /** Call a tool with the given name and arguments */
326
- callTool(name: string, args: Record<string, unknown>): Promise<CallToolResult>;
328
+ callTool(name: string, args: Record<string, unknown>, options?: {
329
+ timeout?: number;
330
+ }): Promise<CallToolResult>;
327
331
  /** Read a resource by URI */
328
332
  readResource(uri: string): Promise<ReadResourceResult>;
329
333
  /** Get a prompt by name with optional arguments */
@@ -553,6 +557,7 @@ declare class McpClientManagerService {
553
557
  connectToServer(serverName: string, config: McpServerConfig): Promise<void>;
554
558
  registerServerConfigs(configs: Record<string, McpServerConfig>): void;
555
559
  getKnownServerNames(): string[];
560
+ getServerRequestTimeout(serverName: string): number | undefined;
556
561
  ensureConnected(serverName: string): Promise<McpClientConnection>;
557
562
  private createConnection;
558
563
  /**
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { _ as DefinitionsCacheService, a as SseTransportHandler, b as ConfigFetcherService, c as createServer, f as UseToolTool, g as McpClientManagerService, h as SkillService, i as StdioTransportHandler, l as createSessionServer, m as DescribeToolsTool, n as RuntimeStateService, o as HttpTransportHandler, p as SearchListToolsTool, r as StdioHttpTransportHandler, s as TRANSPORT_MODE, t as StopServerService, u as initializeSharedServices, v as generateServerId, y as findConfigFile } from "./src-Dn6vMZIk.mjs";
1
+ import { _ as DefinitionsCacheService, a as SseTransportHandler, b as ConfigFetcherService, c as createServer, f as UseToolTool, g as McpClientManagerService, h as SkillService, i as StdioTransportHandler, l as createSessionServer, m as DescribeToolsTool, n as RuntimeStateService, o as HttpTransportHandler, p as SearchListToolsTool, r as StdioHttpTransportHandler, s as TRANSPORT_MODE, t as StopServerService, u as initializeSharedServices, v as generateServerId, y as findConfigFile } from "./src-DPIjPYdS.mjs";
2
2
 
3
3
  export { ConfigFetcherService, DefinitionsCacheService, DescribeToolsTool, HttpTransportHandler, McpClientManagerService, RuntimeStateService, SearchListToolsTool, SkillService, SseTransportHandler, StdioHttpTransportHandler, StdioTransportHandler, StopServerService, TRANSPORT_MODE, UseToolTool, createServer, createSessionServer, findConfigFile, generateServerId, initializeSharedServices };
@@ -8,8 +8,8 @@ import { createHash, randomBytes, randomUUID } from "node:crypto";
8
8
  import { dirname, isAbsolute, join, resolve } from "node:path";
9
9
  import { homedir, tmpdir } from "node:os";
10
10
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
11
- import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
12
11
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
12
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
13
13
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
14
14
  import { Liquid } from "liquidjs";
15
15
  import { once } from "node:events";
@@ -205,6 +205,7 @@ const ClaudeCodeStdioServerSchema = z.object({
205
205
  disabled: z.boolean().optional(),
206
206
  instruction: z.string().optional(),
207
207
  timeout: z.number().positive().optional(),
208
+ requestTimeout: z.number().positive().optional(),
208
209
  config: AdditionalConfigSchema
209
210
  });
210
211
  const ClaudeCodeHttpServerSchema = z.object({
@@ -214,6 +215,7 @@ const ClaudeCodeHttpServerSchema = z.object({
214
215
  disabled: z.boolean().optional(),
215
216
  instruction: z.string().optional(),
216
217
  timeout: z.number().positive().optional(),
218
+ requestTimeout: z.number().positive().optional(),
217
219
  config: AdditionalConfigSchema
218
220
  });
219
221
  const ClaudeCodeServerConfigSchema = z.union([ClaudeCodeStdioServerSchema, ClaudeCodeHttpServerSchema]);
@@ -286,6 +288,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
286
288
  omitToolDescription: z.boolean().optional(),
287
289
  prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
288
290
  timeout: z.number().positive().optional(),
291
+ requestTimeout: z.number().positive().optional(),
289
292
  transport: z.literal("stdio"),
290
293
  config: McpStdioConfigSchema
291
294
  }),
@@ -296,6 +299,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
296
299
  omitToolDescription: z.boolean().optional(),
297
300
  prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
298
301
  timeout: z.number().positive().optional(),
302
+ requestTimeout: z.number().positive().optional(),
299
303
  transport: z.literal("http"),
300
304
  config: McpHttpConfigSchema
301
305
  }),
@@ -306,6 +310,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
306
310
  omitToolDescription: z.boolean().optional(),
307
311
  prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
308
312
  timeout: z.number().positive().optional(),
313
+ requestTimeout: z.number().positive().optional(),
309
314
  transport: z.literal("sse"),
310
315
  config: McpSseConfigSchema
311
316
  })
@@ -341,6 +346,7 @@ function transformClaudeCodeConfig(claudeConfig) {
341
346
  omitToolDescription: stdioConfig.config?.omitToolDescription,
342
347
  prompts: stdioConfig.config?.prompts,
343
348
  timeout: stdioConfig.timeout,
349
+ requestTimeout: stdioConfig.requestTimeout,
344
350
  transport: "stdio",
345
351
  config: {
346
352
  command: interpolatedCommand,
@@ -360,6 +366,7 @@ function transformClaudeCodeConfig(claudeConfig) {
360
366
  omitToolDescription: httpConfig.config?.omitToolDescription,
361
367
  prompts: httpConfig.config?.prompts,
362
368
  timeout: httpConfig.timeout,
369
+ requestTimeout: httpConfig.requestTimeout,
363
370
  transport,
364
371
  config: {
365
372
  url: interpolatedUrl,
@@ -1424,6 +1431,14 @@ var DefinitionsCacheService = class {
1424
1431
  /** Default connection timeout in milliseconds (30 seconds) */
1425
1432
  const DEFAULT_CONNECTION_TIMEOUT_MS = 3e4;
1426
1433
  /**
1434
+ * Checks if an error is a session-related error from an HTTP backend
1435
+ * (e.g., downstream server restarted and no longer recognizes the session ID).
1436
+ */
1437
+ function isSessionError(error) {
1438
+ const message = error instanceof Error ? error.message : String(error);
1439
+ return message.includes("unknown session") || message.includes("Session not found");
1440
+ }
1441
+ /**
1427
1442
  * MCP Client wrapper for managing individual server connections
1428
1443
  * This is an internal class used by McpClientManagerService
1429
1444
  */
@@ -1437,6 +1452,7 @@ var McpClient = class {
1437
1452
  client;
1438
1453
  childProcess;
1439
1454
  connected = false;
1455
+ reconnectFn;
1440
1456
  constructor(serverName, transport, client, config) {
1441
1457
  this.serverName = serverName;
1442
1458
  this.serverInstruction = config.instruction;
@@ -1452,34 +1468,77 @@ var McpClient = class {
1452
1468
  setConnected(connected) {
1453
1469
  this.connected = connected;
1454
1470
  }
1471
+ /**
1472
+ * Sets a reconnection function that creates a fresh Client and transport.
1473
+ * Called automatically by withSessionRetry when a session error is detected
1474
+ * (e.g., downstream HTTP server restarted and the old session ID is invalid).
1475
+ */
1476
+ setReconnectFn(fn) {
1477
+ this.reconnectFn = fn;
1478
+ }
1479
+ /**
1480
+ * Wraps an operation with automatic retry on session errors.
1481
+ * If the operation fails with a session error (e.g., downstream server restarted),
1482
+ * reconnects and retries once.
1483
+ */
1484
+ async withSessionRetry(operation) {
1485
+ try {
1486
+ return await operation();
1487
+ } catch (error) {
1488
+ if (!this.reconnectFn || !isSessionError(error)) throw error;
1489
+ console.error(`Session error for ${this.serverName}, reconnecting: ${error instanceof Error ? error.message : String(error)}`);
1490
+ try {
1491
+ await this.client.close();
1492
+ } catch (closeError) {
1493
+ console.error(`Failed to close stale client for ${this.serverName}:`, closeError);
1494
+ }
1495
+ const result = await this.reconnectFn();
1496
+ this.client = result.client;
1497
+ if (result.childProcess) this.childProcess = result.childProcess;
1498
+ return await operation();
1499
+ }
1500
+ }
1455
1501
  async listTools() {
1456
1502
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1457
- return (await this.client.listTools()).tools;
1503
+ return this.withSessionRetry(async () => {
1504
+ return (await this.client.listTools()).tools;
1505
+ });
1458
1506
  }
1459
1507
  async listResources() {
1460
1508
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1461
- return (await this.client.listResources()).resources;
1509
+ return this.withSessionRetry(async () => {
1510
+ return (await this.client.listResources()).resources;
1511
+ });
1462
1512
  }
1463
1513
  async listPrompts() {
1464
1514
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1465
- return (await this.client.listPrompts()).prompts;
1515
+ return this.withSessionRetry(async () => {
1516
+ return (await this.client.listPrompts()).prompts;
1517
+ });
1466
1518
  }
1467
- async callTool(name, args) {
1519
+ async callTool(name, args, options) {
1468
1520
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1469
- return await this.client.callTool({
1470
- name,
1471
- arguments: args
1521
+ return this.withSessionRetry(async () => {
1522
+ const requestOptions = options?.timeout ? { timeout: options.timeout } : void 0;
1523
+ return await this.client.callTool({
1524
+ name,
1525
+ arguments: args
1526
+ }, void 0, requestOptions);
1472
1527
  });
1473
1528
  }
1474
1529
  async readResource(uri) {
1475
1530
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1476
- return await this.client.readResource({ uri });
1531
+ return this.withSessionRetry(async () => {
1532
+ return await this.client.readResource({ uri });
1533
+ });
1477
1534
  }
1478
1535
  async getPrompt(name, args) {
1479
1536
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1480
- return await this.client.getPrompt({
1481
- name,
1482
- arguments: args
1537
+ return this.withSessionRetry(async () => {
1538
+ return await this.client.getPrompt({
1539
+ name,
1540
+ arguments: args
1541
+ });
1483
1542
  });
1484
1543
  }
1485
1544
  async close() {
@@ -1530,6 +1589,9 @@ var McpClientManagerService = class {
1530
1589
  getKnownServerNames() {
1531
1590
  return Array.from(this.serverConfigs.keys());
1532
1591
  }
1592
+ getServerRequestTimeout(serverName) {
1593
+ return this.serverConfigs.get(serverName)?.requestTimeout;
1594
+ }
1533
1595
  async ensureConnected(serverName) {
1534
1596
  const existingClient = this.clients.get(serverName);
1535
1597
  if (existingClient) return existingClient;
@@ -1560,6 +1622,20 @@ var McpClientManagerService = class {
1560
1622
  try {
1561
1623
  await Promise.race([this.performConnection(mcpClient, config), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`Connection timeout after ${timeoutMs}ms`)), timeoutMs))]);
1562
1624
  mcpClient.setConnected(true);
1625
+ if (config.transport === "http" || config.transport === "sse") mcpClient.setReconnectFn(async () => {
1626
+ try {
1627
+ const newClient = new Client({
1628
+ name: "@agiflowai/one-mcp-client",
1629
+ version: "0.1.0"
1630
+ }, { capabilities: {} });
1631
+ const newMcpClient = new McpClient(serverName, config.transport, newClient, {});
1632
+ await this.performConnection(newMcpClient, config);
1633
+ return { client: newClient };
1634
+ } catch (error) {
1635
+ console.error(`Failed to reconnect to ${serverName}:`, error);
1636
+ throw error;
1637
+ }
1638
+ });
1563
1639
  if (!mcpClient.serverInstruction) try {
1564
1640
  const serverInstruction = mcpClient["client"].getInstructions();
1565
1641
  if (serverInstruction) mcpClient.serverInstruction = serverInstruction;
@@ -2708,7 +2784,8 @@ IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverI
2708
2784
  }],
2709
2785
  isError: true
2710
2786
  };
2711
- return await client.callTool(actualToolName, toolArgs);
2787
+ const reqTimeout = this.clientManager.getServerRequestTimeout(serverName);
2788
+ return await client.callTool(actualToolName, toolArgs, reqTimeout ? { timeout: reqTimeout } : void 0);
2712
2789
  } catch (error) {
2713
2790
  return {
2714
2791
  content: [{
@@ -2743,7 +2820,9 @@ IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverI
2743
2820
  };
2744
2821
  try {
2745
2822
  const targetServerName = matchingServers[0];
2746
- return await (await this.clientManager.ensureConnected(targetServerName)).callTool(actualToolName, toolArgs);
2823
+ const client = await this.clientManager.ensureConnected(targetServerName);
2824
+ const targetReqTimeout = this.clientManager.getServerRequestTimeout(targetServerName);
2825
+ return await client.callTool(actualToolName, toolArgs, targetReqTimeout ? { timeout: targetReqTimeout } : void 0);
2747
2826
  } catch (error) {
2748
2827
  return {
2749
2828
  content: [{
@@ -2767,7 +2846,7 @@ IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverI
2767
2846
 
2768
2847
  //#endregion
2769
2848
  //#region package.json
2770
- var version = "0.3.15";
2849
+ var version = "0.3.17";
2771
2850
 
2772
2851
  //#endregion
2773
2852
  //#region src/server/index.ts
@@ -36,8 +36,8 @@ let node_crypto = require("node:crypto");
36
36
  let node_path = require("node:path");
37
37
  let node_os = require("node:os");
38
38
  let __modelcontextprotocol_sdk_client_index_js = require("@modelcontextprotocol/sdk/client/index.js");
39
- let __modelcontextprotocol_sdk_client_stdio_js = require("@modelcontextprotocol/sdk/client/stdio.js");
40
39
  let __modelcontextprotocol_sdk_client_sse_js = require("@modelcontextprotocol/sdk/client/sse.js");
40
+ let __modelcontextprotocol_sdk_client_stdio_js = require("@modelcontextprotocol/sdk/client/stdio.js");
41
41
  let __modelcontextprotocol_sdk_client_streamableHttp_js = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
42
42
  let liquidjs = require("liquidjs");
43
43
  let node_events = require("node:events");
@@ -234,6 +234,7 @@ const ClaudeCodeStdioServerSchema = zod.z.object({
234
234
  disabled: zod.z.boolean().optional(),
235
235
  instruction: zod.z.string().optional(),
236
236
  timeout: zod.z.number().positive().optional(),
237
+ requestTimeout: zod.z.number().positive().optional(),
237
238
  config: AdditionalConfigSchema
238
239
  });
239
240
  const ClaudeCodeHttpServerSchema = zod.z.object({
@@ -243,6 +244,7 @@ const ClaudeCodeHttpServerSchema = zod.z.object({
243
244
  disabled: zod.z.boolean().optional(),
244
245
  instruction: zod.z.string().optional(),
245
246
  timeout: zod.z.number().positive().optional(),
247
+ requestTimeout: zod.z.number().positive().optional(),
246
248
  config: AdditionalConfigSchema
247
249
  });
248
250
  const ClaudeCodeServerConfigSchema = zod.z.union([ClaudeCodeStdioServerSchema, ClaudeCodeHttpServerSchema]);
@@ -315,6 +317,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
315
317
  omitToolDescription: zod.z.boolean().optional(),
316
318
  prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
317
319
  timeout: zod.z.number().positive().optional(),
320
+ requestTimeout: zod.z.number().positive().optional(),
318
321
  transport: zod.z.literal("stdio"),
319
322
  config: McpStdioConfigSchema
320
323
  }),
@@ -325,6 +328,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
325
328
  omitToolDescription: zod.z.boolean().optional(),
326
329
  prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
327
330
  timeout: zod.z.number().positive().optional(),
331
+ requestTimeout: zod.z.number().positive().optional(),
328
332
  transport: zod.z.literal("http"),
329
333
  config: McpHttpConfigSchema
330
334
  }),
@@ -335,6 +339,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
335
339
  omitToolDescription: zod.z.boolean().optional(),
336
340
  prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
337
341
  timeout: zod.z.number().positive().optional(),
342
+ requestTimeout: zod.z.number().positive().optional(),
338
343
  transport: zod.z.literal("sse"),
339
344
  config: McpSseConfigSchema
340
345
  })
@@ -370,6 +375,7 @@ function transformClaudeCodeConfig(claudeConfig) {
370
375
  omitToolDescription: stdioConfig.config?.omitToolDescription,
371
376
  prompts: stdioConfig.config?.prompts,
372
377
  timeout: stdioConfig.timeout,
378
+ requestTimeout: stdioConfig.requestTimeout,
373
379
  transport: "stdio",
374
380
  config: {
375
381
  command: interpolatedCommand,
@@ -389,6 +395,7 @@ function transformClaudeCodeConfig(claudeConfig) {
389
395
  omitToolDescription: httpConfig.config?.omitToolDescription,
390
396
  prompts: httpConfig.config?.prompts,
391
397
  timeout: httpConfig.timeout,
398
+ requestTimeout: httpConfig.requestTimeout,
392
399
  transport,
393
400
  config: {
394
401
  url: interpolatedUrl,
@@ -1453,6 +1460,14 @@ var DefinitionsCacheService = class {
1453
1460
  /** Default connection timeout in milliseconds (30 seconds) */
1454
1461
  const DEFAULT_CONNECTION_TIMEOUT_MS = 3e4;
1455
1462
  /**
1463
+ * Checks if an error is a session-related error from an HTTP backend
1464
+ * (e.g., downstream server restarted and no longer recognizes the session ID).
1465
+ */
1466
+ function isSessionError(error) {
1467
+ const message = error instanceof Error ? error.message : String(error);
1468
+ return message.includes("unknown session") || message.includes("Session not found");
1469
+ }
1470
+ /**
1456
1471
  * MCP Client wrapper for managing individual server connections
1457
1472
  * This is an internal class used by McpClientManagerService
1458
1473
  */
@@ -1466,6 +1481,7 @@ var McpClient = class {
1466
1481
  client;
1467
1482
  childProcess;
1468
1483
  connected = false;
1484
+ reconnectFn;
1469
1485
  constructor(serverName, transport, client, config) {
1470
1486
  this.serverName = serverName;
1471
1487
  this.serverInstruction = config.instruction;
@@ -1481,34 +1497,77 @@ var McpClient = class {
1481
1497
  setConnected(connected) {
1482
1498
  this.connected = connected;
1483
1499
  }
1500
+ /**
1501
+ * Sets a reconnection function that creates a fresh Client and transport.
1502
+ * Called automatically by withSessionRetry when a session error is detected
1503
+ * (e.g., downstream HTTP server restarted and the old session ID is invalid).
1504
+ */
1505
+ setReconnectFn(fn) {
1506
+ this.reconnectFn = fn;
1507
+ }
1508
+ /**
1509
+ * Wraps an operation with automatic retry on session errors.
1510
+ * If the operation fails with a session error (e.g., downstream server restarted),
1511
+ * reconnects and retries once.
1512
+ */
1513
+ async withSessionRetry(operation) {
1514
+ try {
1515
+ return await operation();
1516
+ } catch (error) {
1517
+ if (!this.reconnectFn || !isSessionError(error)) throw error;
1518
+ console.error(`Session error for ${this.serverName}, reconnecting: ${error instanceof Error ? error.message : String(error)}`);
1519
+ try {
1520
+ await this.client.close();
1521
+ } catch (closeError) {
1522
+ console.error(`Failed to close stale client for ${this.serverName}:`, closeError);
1523
+ }
1524
+ const result = await this.reconnectFn();
1525
+ this.client = result.client;
1526
+ if (result.childProcess) this.childProcess = result.childProcess;
1527
+ return await operation();
1528
+ }
1529
+ }
1484
1530
  async listTools() {
1485
1531
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1486
- return (await this.client.listTools()).tools;
1532
+ return this.withSessionRetry(async () => {
1533
+ return (await this.client.listTools()).tools;
1534
+ });
1487
1535
  }
1488
1536
  async listResources() {
1489
1537
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1490
- return (await this.client.listResources()).resources;
1538
+ return this.withSessionRetry(async () => {
1539
+ return (await this.client.listResources()).resources;
1540
+ });
1491
1541
  }
1492
1542
  async listPrompts() {
1493
1543
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1494
- return (await this.client.listPrompts()).prompts;
1544
+ return this.withSessionRetry(async () => {
1545
+ return (await this.client.listPrompts()).prompts;
1546
+ });
1495
1547
  }
1496
- async callTool(name, args) {
1548
+ async callTool(name, args, options) {
1497
1549
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1498
- return await this.client.callTool({
1499
- name,
1500
- arguments: args
1550
+ return this.withSessionRetry(async () => {
1551
+ const requestOptions = options?.timeout ? { timeout: options.timeout } : void 0;
1552
+ return await this.client.callTool({
1553
+ name,
1554
+ arguments: args
1555
+ }, void 0, requestOptions);
1501
1556
  });
1502
1557
  }
1503
1558
  async readResource(uri) {
1504
1559
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1505
- return await this.client.readResource({ uri });
1560
+ return this.withSessionRetry(async () => {
1561
+ return await this.client.readResource({ uri });
1562
+ });
1506
1563
  }
1507
1564
  async getPrompt(name, args) {
1508
1565
  if (!this.connected) throw new Error(`Client for ${this.serverName} is not connected`);
1509
- return await this.client.getPrompt({
1510
- name,
1511
- arguments: args
1566
+ return this.withSessionRetry(async () => {
1567
+ return await this.client.getPrompt({
1568
+ name,
1569
+ arguments: args
1570
+ });
1512
1571
  });
1513
1572
  }
1514
1573
  async close() {
@@ -1559,6 +1618,9 @@ var McpClientManagerService = class {
1559
1618
  getKnownServerNames() {
1560
1619
  return Array.from(this.serverConfigs.keys());
1561
1620
  }
1621
+ getServerRequestTimeout(serverName) {
1622
+ return this.serverConfigs.get(serverName)?.requestTimeout;
1623
+ }
1562
1624
  async ensureConnected(serverName) {
1563
1625
  const existingClient = this.clients.get(serverName);
1564
1626
  if (existingClient) return existingClient;
@@ -1589,6 +1651,20 @@ var McpClientManagerService = class {
1589
1651
  try {
1590
1652
  await Promise.race([this.performConnection(mcpClient, config), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`Connection timeout after ${timeoutMs}ms`)), timeoutMs))]);
1591
1653
  mcpClient.setConnected(true);
1654
+ if (config.transport === "http" || config.transport === "sse") mcpClient.setReconnectFn(async () => {
1655
+ try {
1656
+ const newClient = new __modelcontextprotocol_sdk_client_index_js.Client({
1657
+ name: "@agiflowai/one-mcp-client",
1658
+ version: "0.1.0"
1659
+ }, { capabilities: {} });
1660
+ const newMcpClient = new McpClient(serverName, config.transport, newClient, {});
1661
+ await this.performConnection(newMcpClient, config);
1662
+ return { client: newClient };
1663
+ } catch (error) {
1664
+ console.error(`Failed to reconnect to ${serverName}:`, error);
1665
+ throw error;
1666
+ }
1667
+ });
1592
1668
  if (!mcpClient.serverInstruction) try {
1593
1669
  const serverInstruction = mcpClient["client"].getInstructions();
1594
1670
  if (serverInstruction) mcpClient.serverInstruction = serverInstruction;
@@ -2737,7 +2813,8 @@ IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverI
2737
2813
  }],
2738
2814
  isError: true
2739
2815
  };
2740
- return await client.callTool(actualToolName, toolArgs);
2816
+ const reqTimeout = this.clientManager.getServerRequestTimeout(serverName);
2817
+ return await client.callTool(actualToolName, toolArgs, reqTimeout ? { timeout: reqTimeout } : void 0);
2741
2818
  } catch (error) {
2742
2819
  return {
2743
2820
  content: [{
@@ -2772,7 +2849,9 @@ IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverI
2772
2849
  };
2773
2850
  try {
2774
2851
  const targetServerName = matchingServers[0];
2775
- return await (await this.clientManager.ensureConnected(targetServerName)).callTool(actualToolName, toolArgs);
2852
+ const client = await this.clientManager.ensureConnected(targetServerName);
2853
+ const targetReqTimeout = this.clientManager.getServerRequestTimeout(targetServerName);
2854
+ return await client.callTool(actualToolName, toolArgs, targetReqTimeout ? { timeout: targetReqTimeout } : void 0);
2776
2855
  } catch (error) {
2777
2856
  return {
2778
2857
  content: [{
@@ -2796,7 +2875,7 @@ IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverI
2796
2875
 
2797
2876
  //#endregion
2798
2877
  //#region package.json
2799
- var version = "0.3.15";
2878
+ var version = "0.3.17";
2800
2879
 
2801
2880
  //#endregion
2802
2881
  //#region src/server/index.ts
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agiflowai/one-mcp",
3
3
  "description": "One MCP server package",
4
- "version": "0.3.16",
4
+ "version": "0.3.18",
5
5
  "license": "AGPL-3.0",
6
6
  "keywords": [
7
7
  "mcp",