@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 +6 -4
- package/dist/cli.mjs +6 -4
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.mts +6 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-Dn6vMZIk.mjs → src-DPIjPYdS.mjs} +94 -15
- package/dist/{src-BRqEdbha.cjs → src-hm1dRqUF.cjs} +94 -15
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_src = require('./src-
|
|
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
|
|
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
|
|
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-
|
|
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
|
|
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
|
|
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
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
|
|
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
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1470
|
-
|
|
1471
|
-
|
|
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
|
|
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
|
|
1481
|
-
|
|
1482
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1499
|
-
|
|
1500
|
-
|
|
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
|
|
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
|
|
1510
|
-
|
|
1511
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
2878
|
+
var version = "0.3.17";
|
|
2800
2879
|
|
|
2801
2880
|
//#endregion
|
|
2802
2881
|
//#region src/server/index.ts
|