@agimon-ai/mcp-proxy 0.7.3 → 0.8.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.
- package/dist/cli.cjs +49 -67
- package/dist/cli.mjs +34 -52
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +5 -5
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +2 -3
- package/dist/{src-Y-cyyxaw.mjs → src-Dorvm5bM.mjs} +201 -313
- package/dist/{src-Dp2m9_I_.cjs → src-dZuRf3Wt.cjs} +389 -506
- package/package.json +18 -18
package/dist/cli.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_src = require(
|
|
2
|
+
const require_src = require("./src-dZuRf3Wt.cjs");
|
|
3
3
|
let node_fs = require("node:fs");
|
|
4
4
|
let node_fs_promises = require("node:fs/promises");
|
|
5
5
|
let js_yaml = require("js-yaml");
|
|
@@ -10,17 +10,14 @@ node_path = require_src.__toESM(node_path);
|
|
|
10
10
|
let node_child_process = require("node:child_process");
|
|
11
11
|
let liquidjs = require("liquidjs");
|
|
12
12
|
let commander = require("commander");
|
|
13
|
-
let
|
|
14
|
-
let
|
|
13
|
+
let _agimon_ai_foundation_port_registry = require("@agimon-ai/foundation-port-registry");
|
|
14
|
+
let _agimon_ai_foundation_process_registry = require("@agimon-ai/foundation-process-registry");
|
|
15
15
|
let node_url = require("node:url");
|
|
16
|
-
|
|
17
16
|
//#region src/templates/mcp-config.json?raw
|
|
18
17
|
var mcp_config_default = "{\n \"_comment\": \"MCP Server Configuration - Use ${VAR_NAME} syntax for environment variable interpolation\",\n \"_instructions\": \"config.instruction: Server's default instruction | instruction: User override (takes precedence)\",\n \"mcpServers\": {\n \"example-server\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/mcp-server/build/index.js\"],\n \"env\": {\n \"LOG_LEVEL\": \"info\",\n \"_comment\": \"You can use environment variable interpolation:\",\n \"_example_DATABASE_URL\": \"${DATABASE_URL}\",\n \"_example_API_KEY\": \"${MY_API_KEY}\"\n },\n \"config\": {\n \"instruction\": \"Use this server for...\"\n },\n \"_instruction_override\": \"Optional user override - takes precedence over config.instruction\"\n }\n }\n}\n";
|
|
19
|
-
|
|
20
18
|
//#endregion
|
|
21
19
|
//#region src/templates/mcp-config.yaml.liquid?raw
|
|
22
20
|
var mcp_config_yaml_default = "# MCP Server Configuration\n# This file configures the MCP servers that mcp-proxy will connect to\n#\n# Environment Variable Interpolation:\n# Use ${VAR_NAME} syntax to reference environment variables\n# Example: ${HOME}, ${API_KEY}, ${DATABASE_URL}\n#\n# Instructions:\n# - config.instruction: Server's default instruction (from server documentation)\n# - instruction: User override (optional, takes precedence over config.instruction)\n# - config.toolBlacklist: Array of tool names to hide/block from this server\n# - config.omitToolDescription: Boolean to show only tool names without descriptions (saves tokens)\n\n# Remote Configuration Sources (OPTIONAL)\n# Fetch and merge configurations from remote URLs\n# Remote configs are merged with local configs based on merge strategy\n#\n# SECURITY: SSRF Protection is ENABLED by default\n# - Only HTTPS URLs are allowed (set security.enforceHttps: false to allow HTTP)\n# - Private IPs and localhost are blocked (set security.allowPrivateIPs: true for internal networks)\n# - Blocked ranges: 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16\nremoteConfigs:\n # Example 1: Basic remote config with default security\n # - url: ${AGIFLOW_URL}/api/v1/mcp-configs\n # headers:\n # Authorization: Bearer ${AGIFLOW_API_KEY}\n # mergeStrategy: local-priority # Options: local-priority (default), remote-priority, merge-deep\n #\n # Example 2: Remote config with custom security settings (for internal networks)\n # - url: ${INTERNAL_URL}/mcp-configs\n # headers:\n # Authorization: Bearer ${INTERNAL_TOKEN}\n # security:\n # allowPrivateIPs: true # Allow internal IPs (default: false)\n # enforceHttps: false # Allow HTTP (default: true, HTTPS only)\n # mergeStrategy: local-priority\n #\n # Example 3: Remote config with additional validation (OPTIONAL)\n # - url: ${AGIFLOW_URL}/api/v1/mcp-configs\n # headers:\n # Authorization: Bearer ${AGIFLOW_API_KEY}\n # X-API-Key: ${AGIFLOW_API_KEY}\n # security:\n # enforceHttps: true # Require HTTPS (default: true)\n # allowPrivateIPs: false # Block private IPs (default: false)\n # validation: # OPTIONAL: Additional regex validation on top of security checks\n # url: ^https://.*\\.agiflow\\.io/.* # OPTIONAL: Regex pattern to validate URL format\n # headers: # OPTIONAL: Regex patterns to validate header values\n # Authorization: ^Bearer [A-Za-z0-9_-]+$\n # X-API-Key: ^[A-Za-z0-9_-]{32,}$\n # mergeStrategy: local-priority\n\nmcpServers:\n{%- if mcpServers %}{% for server in mcpServers %}\n {{ server.name }}:\n command: {{ server.command }}\n args:{% for arg in server.args %}\n - '{{ arg }}'{% endfor %}\n # env:\n # LOG_LEVEL: info\n # # API_KEY: ${MY_API_KEY}\n # config:\n # instruction: Use this server for...\n # # toolBlacklist:\n # # - tool_to_block\n # # omitToolDescription: true\n{% endfor %}\n # Example MCP server using SSE transport\n # remote-server:\n # url: https://example.com/mcp\n # type: sse\n # headers:\n # Authorization: Bearer ${API_KEY}\n # config:\n # instruction: This server provides tools for...\n{% else %}\n # Example MCP server using stdio transport\n example-server:\n command: node\n args:\n - /path/to/mcp-server/build/index.js\n env:\n # Environment variables for the MCP server\n LOG_LEVEL: info\n # You can use environment variable interpolation:\n # DATABASE_URL: ${DATABASE_URL}\n # API_KEY: ${MY_API_KEY}\n config:\n # Server's default instruction (from server documentation)\n instruction: Use this server for...\n # Optional: Block specific tools from being listed or executed\n # toolBlacklist:\n # - dangerous_tool_name\n # - another_blocked_tool\n # Optional: Omit tool descriptions to save tokens (default: false)\n # omitToolDescription: true\n # instruction: Optional user override - takes precedence over config.instruction\n\n # Example MCP server using SSE transport with environment variables\n # remote-server:\n # url: https://example.com/mcp\n # type: sse\n # headers:\n # # Use ${VAR_NAME} to interpolate environment variables\n # Authorization: Bearer ${API_KEY}\n # config:\n # instruction: This server provides tools for...\n # # Optional: Block specific tools from being listed or executed\n # # toolBlacklist:\n # # - tool_to_block\n # # Optional: Omit tool descriptions to save tokens (default: false)\n # # omitToolDescription: true\n # # instruction: Optional user override\n{% endif %}\n";
|
|
23
|
-
|
|
24
21
|
//#endregion
|
|
25
22
|
//#region src/utils/output.ts
|
|
26
23
|
function writeLine(message = "") {
|
|
@@ -44,7 +41,6 @@ const print = {
|
|
|
44
41
|
item: (message) => writeLine(`- ${message}`),
|
|
45
42
|
indent: (message) => writeLine(` ${message}`)
|
|
46
43
|
};
|
|
47
|
-
|
|
48
44
|
//#endregion
|
|
49
45
|
//#region src/commands/init.ts
|
|
50
46
|
/**
|
|
@@ -114,7 +110,6 @@ const initCommand = new commander.Command("init").description("Initialize MCP co
|
|
|
114
110
|
process.exit(1);
|
|
115
111
|
}
|
|
116
112
|
});
|
|
117
|
-
|
|
118
113
|
//#endregion
|
|
119
114
|
//#region src/commands/prestart-http.ts
|
|
120
115
|
/**
|
|
@@ -142,7 +137,7 @@ function resolveWorkspaceRoot(startPath = process.env.PROJECT_PATH || process.cw
|
|
|
142
137
|
}
|
|
143
138
|
const PROCESS_REGISTRY_SERVICE_HTTP$1 = "mcp-proxy-http";
|
|
144
139
|
async function findExistingHealthyRuntime(workspaceRoot) {
|
|
145
|
-
const match = (await new
|
|
140
|
+
const match = (await new _agimon_ai_foundation_process_registry.ProcessRegistryService(process.env.PROCESS_REGISTRY_PATH).listProcesses({
|
|
146
141
|
repositoryPath: workspaceRoot,
|
|
147
142
|
serviceName: PROCESS_REGISTRY_SERVICE_HTTP$1
|
|
148
143
|
}))[0];
|
|
@@ -163,14 +158,14 @@ async function findExistingHealthyRuntime(workspaceRoot) {
|
|
|
163
158
|
return null;
|
|
164
159
|
}
|
|
165
160
|
function buildCliCandidates() {
|
|
166
|
-
const __filename
|
|
167
|
-
const __dirname
|
|
161
|
+
const __filename = (0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href);
|
|
162
|
+
const __dirname = node_path.default.dirname(__filename);
|
|
168
163
|
const distCandidates = [
|
|
169
|
-
node_path.default.resolve(__dirname
|
|
170
|
-
node_path.default.resolve(__dirname
|
|
171
|
-
node_path.default.resolve(__dirname
|
|
164
|
+
node_path.default.resolve(__dirname, "cli.mjs"),
|
|
165
|
+
node_path.default.resolve(__dirname, "..", "dist", "cli.mjs"),
|
|
166
|
+
node_path.default.resolve(__dirname, "..", "..", "dist", "cli.mjs")
|
|
172
167
|
];
|
|
173
|
-
const srcCandidates = [node_path.default.resolve(__dirname
|
|
168
|
+
const srcCandidates = [node_path.default.resolve(__dirname, "..", "cli.ts"), node_path.default.resolve(__dirname, "..", "..", "src", "cli.ts")];
|
|
174
169
|
for (const candidate of distCandidates) if ((0, node_fs.existsSync)(candidate)) return {
|
|
175
170
|
command: process.execPath,
|
|
176
171
|
args: [candidate]
|
|
@@ -198,7 +193,7 @@ async function waitForFile(filePath, timeoutMs) {
|
|
|
198
193
|
await (0, node_fs_promises.access)(filePath);
|
|
199
194
|
return;
|
|
200
195
|
} catch {}
|
|
201
|
-
await new Promise((resolve
|
|
196
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
202
197
|
}
|
|
203
198
|
throw new Error(`Timed out waiting for runtime state file: ${filePath}`);
|
|
204
199
|
}
|
|
@@ -220,7 +215,7 @@ async function waitForHealthyRuntime(serverId, timeoutMs) {
|
|
|
220
215
|
}
|
|
221
216
|
} catch {}
|
|
222
217
|
}
|
|
223
|
-
await new Promise((resolve
|
|
218
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
224
219
|
}
|
|
225
220
|
throw new Error(`Timed out waiting for HTTP runtime '${serverId}' to become healthy`);
|
|
226
221
|
}
|
|
@@ -266,7 +261,7 @@ async function prestartHttpRuntime(options) {
|
|
|
266
261
|
...process.env,
|
|
267
262
|
...registryPath ? {
|
|
268
263
|
PORT_REGISTRY_PATH: registryPath,
|
|
269
|
-
PROCESS_REGISTRY_PATH: (0,
|
|
264
|
+
PROCESS_REGISTRY_PATH: (0, _agimon_ai_foundation_process_registry.resolveSiblingRegistryPath)(registryPath, "processes.json")
|
|
270
265
|
} : {}
|
|
271
266
|
};
|
|
272
267
|
const child = spawnBackgroundRuntime([
|
|
@@ -316,7 +311,6 @@ const prestartHttpCommand = new commander.Command("prestart-http").description("
|
|
|
316
311
|
throw new Error(`Failed to prestart HTTP runtime '${options.id || "generated-server-id"}': ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
317
312
|
}
|
|
318
313
|
});
|
|
319
|
-
|
|
320
314
|
//#endregion
|
|
321
315
|
//#region src/commands/mcp-serve.ts
|
|
322
316
|
/**
|
|
@@ -490,7 +484,7 @@ function createRuntimeRecord(serverId, config, port, shutdownToken, configPath)
|
|
|
490
484
|
};
|
|
491
485
|
}
|
|
492
486
|
function createPortRegistryService() {
|
|
493
|
-
return new
|
|
487
|
+
return new _agimon_ai_foundation_port_registry.PortRegistryService(process.env.PORT_REGISTRY_PATH);
|
|
494
488
|
}
|
|
495
489
|
function getRegistryEnvironment() {
|
|
496
490
|
return process.env.NODE_ENV ?? "development";
|
|
@@ -498,7 +492,7 @@ function getRegistryEnvironment() {
|
|
|
498
492
|
async function createPortRegistryLease(serviceName, host, preferredPort, serverId, transport, configPath, portRange = preferredPort !== void 0 ? {
|
|
499
493
|
min: preferredPort,
|
|
500
494
|
max: preferredPort
|
|
501
|
-
} :
|
|
495
|
+
} : _agimon_ai_foundation_port_registry.DEFAULT_PORT_RANGE) {
|
|
502
496
|
const portRegistry = createPortRegistryService();
|
|
503
497
|
const result = await portRegistry.reservePort({
|
|
504
498
|
repositoryPath: getRegistryRepositoryPath(),
|
|
@@ -630,14 +624,14 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
630
624
|
const portRange = requestedPort !== void 0 ? {
|
|
631
625
|
min: requestedPort,
|
|
632
626
|
max: requestedPort
|
|
633
|
-
} :
|
|
627
|
+
} : _agimon_ai_foundation_port_registry.DEFAULT_PORT_RANGE;
|
|
634
628
|
const portLease = await createPortRegistryLease(PORT_REGISTRY_SERVICE_HTTP, config.host ?? DEFAULT_HOST, requestedPort, runtimeServerId, TRANSPORT_TYPE_HTTP, resolvedConfigPath, portRange);
|
|
635
629
|
const runtimePort = portLease.port;
|
|
636
630
|
const runtimeConfig = {
|
|
637
631
|
...config,
|
|
638
632
|
port: runtimePort
|
|
639
633
|
};
|
|
640
|
-
const processLease = await (0,
|
|
634
|
+
const processLease = await (0, _agimon_ai_foundation_process_registry.createProcessLease)({
|
|
641
635
|
repositoryPath: getRegistryRepositoryPath(),
|
|
642
636
|
serviceName: PROCESS_REGISTRY_SERVICE_HTTP,
|
|
643
637
|
serviceType: PROCESS_REGISTRY_SERVICE_TYPE,
|
|
@@ -707,7 +701,7 @@ async function startSseTransport(serverOptions, config) {
|
|
|
707
701
|
const portRange = requestedPort !== void 0 ? {
|
|
708
702
|
min: requestedPort,
|
|
709
703
|
max: requestedPort
|
|
710
|
-
} :
|
|
704
|
+
} : _agimon_ai_foundation_port_registry.DEFAULT_PORT_RANGE;
|
|
711
705
|
const portLease = await createPortRegistryLease("mcp-proxy-sse", config.host ?? DEFAULT_HOST, requestedPort, serverOptions.serverId ?? require_src.generateServerId(), TRANSPORT_TYPE_SSE, void 0, portRange);
|
|
712
706
|
const resolvedConfig = {
|
|
713
707
|
...config,
|
|
@@ -830,7 +824,6 @@ const mcpServeCommand = new commander.Command("mcp-serve").description("Start MC
|
|
|
830
824
|
process.exit(1);
|
|
831
825
|
}
|
|
832
826
|
});
|
|
833
|
-
|
|
834
827
|
//#endregion
|
|
835
828
|
//#region src/commands/bootstrap.ts
|
|
836
829
|
function toErrorMessage$8(error) {
|
|
@@ -920,7 +913,6 @@ async function withConnectedCommandContext(options, run) {
|
|
|
920
913
|
if (config.proxy?.port) return await withProxiedContext(container, config, configFilePath, options, run);
|
|
921
914
|
return await withDirectContext(container, config, configFilePath, options, run);
|
|
922
915
|
}
|
|
923
|
-
|
|
924
916
|
//#endregion
|
|
925
917
|
//#region src/commands/list-tools.ts
|
|
926
918
|
/**
|
|
@@ -991,7 +983,6 @@ const searchToolsCommand = new commander.Command("search-tools").description("Se
|
|
|
991
983
|
process.exit(1);
|
|
992
984
|
}
|
|
993
985
|
});
|
|
994
|
-
|
|
995
986
|
//#endregion
|
|
996
987
|
//#region src/commands/describe-tools.ts
|
|
997
988
|
/**
|
|
@@ -1132,7 +1123,6 @@ const describeToolsCommand = new commander.Command("describe-tools").description
|
|
|
1132
1123
|
process.exit(1);
|
|
1133
1124
|
}
|
|
1134
1125
|
});
|
|
1135
|
-
|
|
1136
1126
|
//#endregion
|
|
1137
1127
|
//#region src/commands/use-tool.ts
|
|
1138
1128
|
/**
|
|
@@ -1174,34 +1164,34 @@ const useToolCommand = new commander.Command("use-tool").description("Execute an
|
|
|
1174
1164
|
await withConnectedCommandContext(options, async ({ container, config, clientManager }) => {
|
|
1175
1165
|
const clients = clientManager.getAllClients();
|
|
1176
1166
|
if (options.server) {
|
|
1177
|
-
const client
|
|
1178
|
-
if (!client
|
|
1167
|
+
const client = clientManager.getClient(options.server);
|
|
1168
|
+
if (!client) throw new Error(`Server "${options.server}" not found`);
|
|
1179
1169
|
if (!options.json) console.error(`Executing ${toolName} on ${options.server}...`);
|
|
1180
|
-
const requestOptions
|
|
1181
|
-
const result
|
|
1182
|
-
if (options.json) console.log(JSON.stringify(result
|
|
1170
|
+
const requestOptions = options.timeout ? { timeout: options.timeout } : void 0;
|
|
1171
|
+
const result = await client.callTool(toolName, toolArgs, requestOptions);
|
|
1172
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
1183
1173
|
else {
|
|
1184
1174
|
console.log("\nResult:");
|
|
1185
|
-
if (result
|
|
1175
|
+
if (result.content) for (const content of result.content) if (content.type === "text") console.log(content.text);
|
|
1186
1176
|
else console.log(JSON.stringify(content, null, 2));
|
|
1187
|
-
if (result
|
|
1177
|
+
if (result.isError) {
|
|
1188
1178
|
console.error("\n⚠️ Tool execution returned an error");
|
|
1189
1179
|
process.exit(1);
|
|
1190
1180
|
}
|
|
1191
1181
|
}
|
|
1192
1182
|
return;
|
|
1193
1183
|
}
|
|
1194
|
-
const searchResults = await Promise.all(clients.map(async (client
|
|
1184
|
+
const searchResults = await Promise.all(clients.map(async (client) => {
|
|
1195
1185
|
try {
|
|
1196
|
-
const hasTool = (await client
|
|
1186
|
+
const hasTool = (await client.listTools()).some((t) => t.name === toolName);
|
|
1197
1187
|
return {
|
|
1198
|
-
serverName: client
|
|
1188
|
+
serverName: client.serverName,
|
|
1199
1189
|
hasTool,
|
|
1200
1190
|
error: null
|
|
1201
1191
|
};
|
|
1202
1192
|
} catch (error) {
|
|
1203
1193
|
return {
|
|
1204
|
-
serverName: client
|
|
1194
|
+
serverName: client.serverName,
|
|
1205
1195
|
hasTool: false,
|
|
1206
1196
|
error
|
|
1207
1197
|
};
|
|
@@ -1223,11 +1213,11 @@ const useToolCommand = new commander.Command("use-tool").description("Execute an
|
|
|
1223
1213
|
const skillName = toolName.startsWith("skill__") ? toolName.slice(7) : toolName;
|
|
1224
1214
|
const skill = await skillService.getSkill(skillName);
|
|
1225
1215
|
if (skill) {
|
|
1226
|
-
const result
|
|
1216
|
+
const result = { content: [{
|
|
1227
1217
|
type: "text",
|
|
1228
1218
|
text: skill.content
|
|
1229
1219
|
}] };
|
|
1230
|
-
if (options.json) console.log(JSON.stringify(result
|
|
1220
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
1231
1221
|
else {
|
|
1232
1222
|
console.log("\nSkill content:");
|
|
1233
1223
|
console.log(skill.content);
|
|
@@ -1262,7 +1252,6 @@ const useToolCommand = new commander.Command("use-tool").description("Execute an
|
|
|
1262
1252
|
process.exit(1);
|
|
1263
1253
|
}
|
|
1264
1254
|
});
|
|
1265
|
-
|
|
1266
1255
|
//#endregion
|
|
1267
1256
|
//#region src/commands/list-resources.ts
|
|
1268
1257
|
/**
|
|
@@ -1333,7 +1322,6 @@ const listResourcesCommand = new commander.Command("list-resources").description
|
|
|
1333
1322
|
process.exit(1);
|
|
1334
1323
|
}
|
|
1335
1324
|
});
|
|
1336
|
-
|
|
1337
1325
|
//#endregion
|
|
1338
1326
|
//#region src/commands/read-resource.ts
|
|
1339
1327
|
/**
|
|
@@ -1368,26 +1356,26 @@ const readResourceCommand = new commander.Command("read-resource").description("
|
|
|
1368
1356
|
await withConnectedCommandContext(options, async ({ clientManager }) => {
|
|
1369
1357
|
const clients = clientManager.getAllClients();
|
|
1370
1358
|
if (options.server) {
|
|
1371
|
-
const client
|
|
1372
|
-
if (!client
|
|
1359
|
+
const client = clientManager.getClient(options.server);
|
|
1360
|
+
if (!client) throw new Error(`Server "${options.server}" not found`);
|
|
1373
1361
|
if (!options.json) console.error(`Reading ${uri} from ${options.server}...`);
|
|
1374
|
-
const result
|
|
1375
|
-
if (options.json) console.log(JSON.stringify(result
|
|
1376
|
-
else for (const content of result
|
|
1362
|
+
const result = await client.readResource(uri);
|
|
1363
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
1364
|
+
else for (const content of result.contents) if ("text" in content) console.log(content.text);
|
|
1377
1365
|
else console.log(JSON.stringify(content, null, 2));
|
|
1378
1366
|
return;
|
|
1379
1367
|
}
|
|
1380
|
-
const searchResults = await Promise.all(clients.map(async (client
|
|
1368
|
+
const searchResults = await Promise.all(clients.map(async (client) => {
|
|
1381
1369
|
try {
|
|
1382
|
-
const hasResource = (await client
|
|
1370
|
+
const hasResource = (await client.listResources()).some((r) => r.uri === uri);
|
|
1383
1371
|
return {
|
|
1384
|
-
serverName: client
|
|
1372
|
+
serverName: client.serverName,
|
|
1385
1373
|
hasResource,
|
|
1386
1374
|
error: null
|
|
1387
1375
|
};
|
|
1388
1376
|
} catch (error) {
|
|
1389
1377
|
return {
|
|
1390
|
-
serverName: client
|
|
1378
|
+
serverName: client.serverName,
|
|
1391
1379
|
hasResource: false,
|
|
1392
1380
|
error
|
|
1393
1381
|
};
|
|
@@ -1417,7 +1405,6 @@ const readResourceCommand = new commander.Command("read-resource").description("
|
|
|
1417
1405
|
process.exit(1);
|
|
1418
1406
|
}
|
|
1419
1407
|
});
|
|
1420
|
-
|
|
1421
1408
|
//#endregion
|
|
1422
1409
|
//#region src/commands/list-prompts.ts
|
|
1423
1410
|
function toErrorMessage$2(error) {
|
|
@@ -1458,7 +1445,6 @@ const listPromptsCommand = new commander.Command("list-prompts").description("Li
|
|
|
1458
1445
|
process.exit(1);
|
|
1459
1446
|
}
|
|
1460
1447
|
});
|
|
1461
|
-
|
|
1462
1448
|
//#endregion
|
|
1463
1449
|
//#region src/commands/get-prompt.ts
|
|
1464
1450
|
function toErrorMessage$1(error) {
|
|
@@ -1475,11 +1461,11 @@ const getPromptCommand = new commander.Command("get-prompt").description("Get a
|
|
|
1475
1461
|
await withConnectedCommandContext(options, async ({ clientManager }) => {
|
|
1476
1462
|
const clients = clientManager.getAllClients();
|
|
1477
1463
|
if (options.server) {
|
|
1478
|
-
const client
|
|
1479
|
-
if (!client
|
|
1480
|
-
const prompt
|
|
1481
|
-
if (options.json) console.log(JSON.stringify(prompt
|
|
1482
|
-
else for (const message of prompt
|
|
1464
|
+
const client = clientManager.getClient(options.server);
|
|
1465
|
+
if (!client) throw new Error(`Server "${options.server}" not found`);
|
|
1466
|
+
const prompt = await client.getPrompt(promptName, promptArgs);
|
|
1467
|
+
if (options.json) console.log(JSON.stringify(prompt, null, 2));
|
|
1468
|
+
else for (const message of prompt.messages) {
|
|
1483
1469
|
const content = message.content;
|
|
1484
1470
|
if (typeof content === "object" && content && "text" in content) console.log(content.text);
|
|
1485
1471
|
else console.log(JSON.stringify(message, null, 2));
|
|
@@ -1487,11 +1473,11 @@ const getPromptCommand = new commander.Command("get-prompt").description("Get a
|
|
|
1487
1473
|
return;
|
|
1488
1474
|
}
|
|
1489
1475
|
const matchingServers = [];
|
|
1490
|
-
await Promise.all(clients.map(async (client
|
|
1476
|
+
await Promise.all(clients.map(async (client) => {
|
|
1491
1477
|
try {
|
|
1492
|
-
if ((await client
|
|
1478
|
+
if ((await client.listPrompts()).some((prompt) => prompt.name === promptName)) matchingServers.push(client.serverName);
|
|
1493
1479
|
} catch (error) {
|
|
1494
|
-
if (!options.json) console.error(`Failed to list prompts from ${client
|
|
1480
|
+
if (!options.json) console.error(`Failed to list prompts from ${client.serverName}: ${toErrorMessage$1(error)}`);
|
|
1495
1481
|
}
|
|
1496
1482
|
}));
|
|
1497
1483
|
if (matchingServers.length === 0) throw new Error(`Prompt "${promptName}" not found on any connected server`);
|
|
@@ -1511,7 +1497,6 @@ const getPromptCommand = new commander.Command("get-prompt").description("Get a
|
|
|
1511
1497
|
process.exit(1);
|
|
1512
1498
|
}
|
|
1513
1499
|
});
|
|
1514
|
-
|
|
1515
1500
|
//#endregion
|
|
1516
1501
|
//#region src/commands/prefetch.ts
|
|
1517
1502
|
/**
|
|
@@ -1638,7 +1623,6 @@ const prefetchCommand = new commander.Command("prefetch").description("Pre-downl
|
|
|
1638
1623
|
process.exit(1);
|
|
1639
1624
|
}
|
|
1640
1625
|
});
|
|
1641
|
-
|
|
1642
1626
|
//#endregion
|
|
1643
1627
|
//#region src/commands/stop.ts
|
|
1644
1628
|
/**
|
|
@@ -1684,7 +1668,6 @@ const stopCommand = new commander.Command("stop").description("Stop a running HT
|
|
|
1684
1668
|
process.exit(1);
|
|
1685
1669
|
}
|
|
1686
1670
|
});
|
|
1687
|
-
|
|
1688
1671
|
//#endregion
|
|
1689
1672
|
//#region src/cli.ts
|
|
1690
1673
|
/**
|
|
@@ -1734,5 +1717,4 @@ main().catch((error) => {
|
|
|
1734
1717
|
console.error(`Fatal error: ${error instanceof Error ? error.message : error}`);
|
|
1735
1718
|
process.exit(1);
|
|
1736
1719
|
});
|
|
1737
|
-
|
|
1738
|
-
//#endregion
|
|
1720
|
+
//#endregion
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as DefinitionsCacheService, D as version, T as findConfigFile, b as RuntimeStateService, d as StdioHttpTransportHandler, f as StdioTransportHandler, m as HttpTransportHandler, n as createServer, o as createProxyIoCContainer, p as SseTransportHandler, r as createSessionServer, t as TRANSPORT_MODE, u as initializeSharedServices, w as generateServerId, y as StopServerService } from "./src-
|
|
2
|
+
import { C as DefinitionsCacheService, D as version, T as findConfigFile, b as RuntimeStateService, d as StdioHttpTransportHandler, f as StdioTransportHandler, m as HttpTransportHandler, n as createServer, o as createProxyIoCContainer, p as SseTransportHandler, r as createSessionServer, t as TRANSPORT_MODE, u as initializeSharedServices, w as generateServerId, y as StopServerService } from "./src-Dorvm5bM.mjs";
|
|
3
3
|
import { constants, existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { access, writeFile } from "node:fs/promises";
|
|
5
5
|
import yaml from "js-yaml";
|
|
@@ -11,14 +11,11 @@ import { Command } from "commander";
|
|
|
11
11
|
import { DEFAULT_PORT_RANGE, PortRegistryService } from "@agimon-ai/foundation-port-registry";
|
|
12
12
|
import { ProcessRegistryService, createProcessLease, resolveSiblingRegistryPath } from "@agimon-ai/foundation-process-registry";
|
|
13
13
|
import { fileURLToPath } from "node:url";
|
|
14
|
-
|
|
15
14
|
//#region src/templates/mcp-config.json?raw
|
|
16
15
|
var mcp_config_default = "{\n \"_comment\": \"MCP Server Configuration - Use ${VAR_NAME} syntax for environment variable interpolation\",\n \"_instructions\": \"config.instruction: Server's default instruction | instruction: User override (takes precedence)\",\n \"mcpServers\": {\n \"example-server\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/mcp-server/build/index.js\"],\n \"env\": {\n \"LOG_LEVEL\": \"info\",\n \"_comment\": \"You can use environment variable interpolation:\",\n \"_example_DATABASE_URL\": \"${DATABASE_URL}\",\n \"_example_API_KEY\": \"${MY_API_KEY}\"\n },\n \"config\": {\n \"instruction\": \"Use this server for...\"\n },\n \"_instruction_override\": \"Optional user override - takes precedence over config.instruction\"\n }\n }\n}\n";
|
|
17
|
-
|
|
18
16
|
//#endregion
|
|
19
17
|
//#region src/templates/mcp-config.yaml.liquid?raw
|
|
20
18
|
var mcp_config_yaml_default = "# MCP Server Configuration\n# This file configures the MCP servers that mcp-proxy will connect to\n#\n# Environment Variable Interpolation:\n# Use ${VAR_NAME} syntax to reference environment variables\n# Example: ${HOME}, ${API_KEY}, ${DATABASE_URL}\n#\n# Instructions:\n# - config.instruction: Server's default instruction (from server documentation)\n# - instruction: User override (optional, takes precedence over config.instruction)\n# - config.toolBlacklist: Array of tool names to hide/block from this server\n# - config.omitToolDescription: Boolean to show only tool names without descriptions (saves tokens)\n\n# Remote Configuration Sources (OPTIONAL)\n# Fetch and merge configurations from remote URLs\n# Remote configs are merged with local configs based on merge strategy\n#\n# SECURITY: SSRF Protection is ENABLED by default\n# - Only HTTPS URLs are allowed (set security.enforceHttps: false to allow HTTP)\n# - Private IPs and localhost are blocked (set security.allowPrivateIPs: true for internal networks)\n# - Blocked ranges: 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16\nremoteConfigs:\n # Example 1: Basic remote config with default security\n # - url: ${AGIFLOW_URL}/api/v1/mcp-configs\n # headers:\n # Authorization: Bearer ${AGIFLOW_API_KEY}\n # mergeStrategy: local-priority # Options: local-priority (default), remote-priority, merge-deep\n #\n # Example 2: Remote config with custom security settings (for internal networks)\n # - url: ${INTERNAL_URL}/mcp-configs\n # headers:\n # Authorization: Bearer ${INTERNAL_TOKEN}\n # security:\n # allowPrivateIPs: true # Allow internal IPs (default: false)\n # enforceHttps: false # Allow HTTP (default: true, HTTPS only)\n # mergeStrategy: local-priority\n #\n # Example 3: Remote config with additional validation (OPTIONAL)\n # - url: ${AGIFLOW_URL}/api/v1/mcp-configs\n # headers:\n # Authorization: Bearer ${AGIFLOW_API_KEY}\n # X-API-Key: ${AGIFLOW_API_KEY}\n # security:\n # enforceHttps: true # Require HTTPS (default: true)\n # allowPrivateIPs: false # Block private IPs (default: false)\n # validation: # OPTIONAL: Additional regex validation on top of security checks\n # url: ^https://.*\\.agiflow\\.io/.* # OPTIONAL: Regex pattern to validate URL format\n # headers: # OPTIONAL: Regex patterns to validate header values\n # Authorization: ^Bearer [A-Za-z0-9_-]+$\n # X-API-Key: ^[A-Za-z0-9_-]{32,}$\n # mergeStrategy: local-priority\n\nmcpServers:\n{%- if mcpServers %}{% for server in mcpServers %}\n {{ server.name }}:\n command: {{ server.command }}\n args:{% for arg in server.args %}\n - '{{ arg }}'{% endfor %}\n # env:\n # LOG_LEVEL: info\n # # API_KEY: ${MY_API_KEY}\n # config:\n # instruction: Use this server for...\n # # toolBlacklist:\n # # - tool_to_block\n # # omitToolDescription: true\n{% endfor %}\n # Example MCP server using SSE transport\n # remote-server:\n # url: https://example.com/mcp\n # type: sse\n # headers:\n # Authorization: Bearer ${API_KEY}\n # config:\n # instruction: This server provides tools for...\n{% else %}\n # Example MCP server using stdio transport\n example-server:\n command: node\n args:\n - /path/to/mcp-server/build/index.js\n env:\n # Environment variables for the MCP server\n LOG_LEVEL: info\n # You can use environment variable interpolation:\n # DATABASE_URL: ${DATABASE_URL}\n # API_KEY: ${MY_API_KEY}\n config:\n # Server's default instruction (from server documentation)\n instruction: Use this server for...\n # Optional: Block specific tools from being listed or executed\n # toolBlacklist:\n # - dangerous_tool_name\n # - another_blocked_tool\n # Optional: Omit tool descriptions to save tokens (default: false)\n # omitToolDescription: true\n # instruction: Optional user override - takes precedence over config.instruction\n\n # Example MCP server using SSE transport with environment variables\n # remote-server:\n # url: https://example.com/mcp\n # type: sse\n # headers:\n # # Use ${VAR_NAME} to interpolate environment variables\n # Authorization: Bearer ${API_KEY}\n # config:\n # instruction: This server provides tools for...\n # # Optional: Block specific tools from being listed or executed\n # # toolBlacklist:\n # # - tool_to_block\n # # Optional: Omit tool descriptions to save tokens (default: false)\n # # omitToolDescription: true\n # # instruction: Optional user override\n{% endif %}\n";
|
|
21
|
-
|
|
22
19
|
//#endregion
|
|
23
20
|
//#region src/utils/output.ts
|
|
24
21
|
function writeLine(message = "") {
|
|
@@ -42,7 +39,6 @@ const print = {
|
|
|
42
39
|
item: (message) => writeLine(`- ${message}`),
|
|
43
40
|
indent: (message) => writeLine(` ${message}`)
|
|
44
41
|
};
|
|
45
|
-
|
|
46
42
|
//#endregion
|
|
47
43
|
//#region src/commands/init.ts
|
|
48
44
|
/**
|
|
@@ -112,7 +108,6 @@ const initCommand = new Command("init").description("Initialize MCP configuratio
|
|
|
112
108
|
process.exit(1);
|
|
113
109
|
}
|
|
114
110
|
});
|
|
115
|
-
|
|
116
111
|
//#endregion
|
|
117
112
|
//#region src/commands/prestart-http.ts
|
|
118
113
|
/**
|
|
@@ -196,7 +191,7 @@ async function waitForFile(filePath, timeoutMs) {
|
|
|
196
191
|
await access(filePath);
|
|
197
192
|
return;
|
|
198
193
|
} catch {}
|
|
199
|
-
await new Promise((resolve
|
|
194
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
200
195
|
}
|
|
201
196
|
throw new Error(`Timed out waiting for runtime state file: ${filePath}`);
|
|
202
197
|
}
|
|
@@ -218,7 +213,7 @@ async function waitForHealthyRuntime(serverId, timeoutMs) {
|
|
|
218
213
|
}
|
|
219
214
|
} catch {}
|
|
220
215
|
}
|
|
221
|
-
await new Promise((resolve
|
|
216
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
222
217
|
}
|
|
223
218
|
throw new Error(`Timed out waiting for HTTP runtime '${serverId}' to become healthy`);
|
|
224
219
|
}
|
|
@@ -314,7 +309,6 @@ const prestartHttpCommand = new Command("prestart-http").description("Start an m
|
|
|
314
309
|
throw new Error(`Failed to prestart HTTP runtime '${options.id || "generated-server-id"}': ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
315
310
|
}
|
|
316
311
|
});
|
|
317
|
-
|
|
318
312
|
//#endregion
|
|
319
313
|
//#region src/commands/mcp-serve.ts
|
|
320
314
|
/**
|
|
@@ -828,7 +822,6 @@ const mcpServeCommand = new Command("mcp-serve").description("Start MCP server w
|
|
|
828
822
|
process.exit(1);
|
|
829
823
|
}
|
|
830
824
|
});
|
|
831
|
-
|
|
832
825
|
//#endregion
|
|
833
826
|
//#region src/commands/bootstrap.ts
|
|
834
827
|
function toErrorMessage$8(error) {
|
|
@@ -918,7 +911,6 @@ async function withConnectedCommandContext(options, run) {
|
|
|
918
911
|
if (config.proxy?.port) return await withProxiedContext(container, config, configFilePath, options, run);
|
|
919
912
|
return await withDirectContext(container, config, configFilePath, options, run);
|
|
920
913
|
}
|
|
921
|
-
|
|
922
914
|
//#endregion
|
|
923
915
|
//#region src/commands/list-tools.ts
|
|
924
916
|
/**
|
|
@@ -989,7 +981,6 @@ const searchToolsCommand = new Command("search-tools").description("Search proxi
|
|
|
989
981
|
process.exit(1);
|
|
990
982
|
}
|
|
991
983
|
});
|
|
992
|
-
|
|
993
984
|
//#endregion
|
|
994
985
|
//#region src/commands/describe-tools.ts
|
|
995
986
|
/**
|
|
@@ -1130,7 +1121,6 @@ const describeToolsCommand = new Command("describe-tools").description("Describe
|
|
|
1130
1121
|
process.exit(1);
|
|
1131
1122
|
}
|
|
1132
1123
|
});
|
|
1133
|
-
|
|
1134
1124
|
//#endregion
|
|
1135
1125
|
//#region src/commands/use-tool.ts
|
|
1136
1126
|
/**
|
|
@@ -1172,34 +1162,34 @@ const useToolCommand = new Command("use-tool").description("Execute an MCP tool
|
|
|
1172
1162
|
await withConnectedCommandContext(options, async ({ container, config, clientManager }) => {
|
|
1173
1163
|
const clients = clientManager.getAllClients();
|
|
1174
1164
|
if (options.server) {
|
|
1175
|
-
const client
|
|
1176
|
-
if (!client
|
|
1165
|
+
const client = clientManager.getClient(options.server);
|
|
1166
|
+
if (!client) throw new Error(`Server "${options.server}" not found`);
|
|
1177
1167
|
if (!options.json) console.error(`Executing ${toolName} on ${options.server}...`);
|
|
1178
|
-
const requestOptions
|
|
1179
|
-
const result
|
|
1180
|
-
if (options.json) console.log(JSON.stringify(result
|
|
1168
|
+
const requestOptions = options.timeout ? { timeout: options.timeout } : void 0;
|
|
1169
|
+
const result = await client.callTool(toolName, toolArgs, requestOptions);
|
|
1170
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
1181
1171
|
else {
|
|
1182
1172
|
console.log("\nResult:");
|
|
1183
|
-
if (result
|
|
1173
|
+
if (result.content) for (const content of result.content) if (content.type === "text") console.log(content.text);
|
|
1184
1174
|
else console.log(JSON.stringify(content, null, 2));
|
|
1185
|
-
if (result
|
|
1175
|
+
if (result.isError) {
|
|
1186
1176
|
console.error("\n⚠️ Tool execution returned an error");
|
|
1187
1177
|
process.exit(1);
|
|
1188
1178
|
}
|
|
1189
1179
|
}
|
|
1190
1180
|
return;
|
|
1191
1181
|
}
|
|
1192
|
-
const searchResults = await Promise.all(clients.map(async (client
|
|
1182
|
+
const searchResults = await Promise.all(clients.map(async (client) => {
|
|
1193
1183
|
try {
|
|
1194
|
-
const hasTool = (await client
|
|
1184
|
+
const hasTool = (await client.listTools()).some((t) => t.name === toolName);
|
|
1195
1185
|
return {
|
|
1196
|
-
serverName: client
|
|
1186
|
+
serverName: client.serverName,
|
|
1197
1187
|
hasTool,
|
|
1198
1188
|
error: null
|
|
1199
1189
|
};
|
|
1200
1190
|
} catch (error) {
|
|
1201
1191
|
return {
|
|
1202
|
-
serverName: client
|
|
1192
|
+
serverName: client.serverName,
|
|
1203
1193
|
hasTool: false,
|
|
1204
1194
|
error
|
|
1205
1195
|
};
|
|
@@ -1221,11 +1211,11 @@ const useToolCommand = new Command("use-tool").description("Execute an MCP tool
|
|
|
1221
1211
|
const skillName = toolName.startsWith("skill__") ? toolName.slice(7) : toolName;
|
|
1222
1212
|
const skill = await skillService.getSkill(skillName);
|
|
1223
1213
|
if (skill) {
|
|
1224
|
-
const result
|
|
1214
|
+
const result = { content: [{
|
|
1225
1215
|
type: "text",
|
|
1226
1216
|
text: skill.content
|
|
1227
1217
|
}] };
|
|
1228
|
-
if (options.json) console.log(JSON.stringify(result
|
|
1218
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
1229
1219
|
else {
|
|
1230
1220
|
console.log("\nSkill content:");
|
|
1231
1221
|
console.log(skill.content);
|
|
@@ -1260,7 +1250,6 @@ const useToolCommand = new Command("use-tool").description("Execute an MCP tool
|
|
|
1260
1250
|
process.exit(1);
|
|
1261
1251
|
}
|
|
1262
1252
|
});
|
|
1263
|
-
|
|
1264
1253
|
//#endregion
|
|
1265
1254
|
//#region src/commands/list-resources.ts
|
|
1266
1255
|
/**
|
|
@@ -1331,7 +1320,6 @@ const listResourcesCommand = new Command("list-resources").description("List all
|
|
|
1331
1320
|
process.exit(1);
|
|
1332
1321
|
}
|
|
1333
1322
|
});
|
|
1334
|
-
|
|
1335
1323
|
//#endregion
|
|
1336
1324
|
//#region src/commands/read-resource.ts
|
|
1337
1325
|
/**
|
|
@@ -1366,26 +1354,26 @@ const readResourceCommand = new Command("read-resource").description("Read a res
|
|
|
1366
1354
|
await withConnectedCommandContext(options, async ({ clientManager }) => {
|
|
1367
1355
|
const clients = clientManager.getAllClients();
|
|
1368
1356
|
if (options.server) {
|
|
1369
|
-
const client
|
|
1370
|
-
if (!client
|
|
1357
|
+
const client = clientManager.getClient(options.server);
|
|
1358
|
+
if (!client) throw new Error(`Server "${options.server}" not found`);
|
|
1371
1359
|
if (!options.json) console.error(`Reading ${uri} from ${options.server}...`);
|
|
1372
|
-
const result
|
|
1373
|
-
if (options.json) console.log(JSON.stringify(result
|
|
1374
|
-
else for (const content of result
|
|
1360
|
+
const result = await client.readResource(uri);
|
|
1361
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
1362
|
+
else for (const content of result.contents) if ("text" in content) console.log(content.text);
|
|
1375
1363
|
else console.log(JSON.stringify(content, null, 2));
|
|
1376
1364
|
return;
|
|
1377
1365
|
}
|
|
1378
|
-
const searchResults = await Promise.all(clients.map(async (client
|
|
1366
|
+
const searchResults = await Promise.all(clients.map(async (client) => {
|
|
1379
1367
|
try {
|
|
1380
|
-
const hasResource = (await client
|
|
1368
|
+
const hasResource = (await client.listResources()).some((r) => r.uri === uri);
|
|
1381
1369
|
return {
|
|
1382
|
-
serverName: client
|
|
1370
|
+
serverName: client.serverName,
|
|
1383
1371
|
hasResource,
|
|
1384
1372
|
error: null
|
|
1385
1373
|
};
|
|
1386
1374
|
} catch (error) {
|
|
1387
1375
|
return {
|
|
1388
|
-
serverName: client
|
|
1376
|
+
serverName: client.serverName,
|
|
1389
1377
|
hasResource: false,
|
|
1390
1378
|
error
|
|
1391
1379
|
};
|
|
@@ -1415,7 +1403,6 @@ const readResourceCommand = new Command("read-resource").description("Read a res
|
|
|
1415
1403
|
process.exit(1);
|
|
1416
1404
|
}
|
|
1417
1405
|
});
|
|
1418
|
-
|
|
1419
1406
|
//#endregion
|
|
1420
1407
|
//#region src/commands/list-prompts.ts
|
|
1421
1408
|
function toErrorMessage$2(error) {
|
|
@@ -1456,7 +1443,6 @@ const listPromptsCommand = new Command("list-prompts").description("List all ava
|
|
|
1456
1443
|
process.exit(1);
|
|
1457
1444
|
}
|
|
1458
1445
|
});
|
|
1459
|
-
|
|
1460
1446
|
//#endregion
|
|
1461
1447
|
//#region src/commands/get-prompt.ts
|
|
1462
1448
|
function toErrorMessage$1(error) {
|
|
@@ -1473,11 +1459,11 @@ const getPromptCommand = new Command("get-prompt").description("Get a prompt by
|
|
|
1473
1459
|
await withConnectedCommandContext(options, async ({ clientManager }) => {
|
|
1474
1460
|
const clients = clientManager.getAllClients();
|
|
1475
1461
|
if (options.server) {
|
|
1476
|
-
const client
|
|
1477
|
-
if (!client
|
|
1478
|
-
const prompt
|
|
1479
|
-
if (options.json) console.log(JSON.stringify(prompt
|
|
1480
|
-
else for (const message of prompt
|
|
1462
|
+
const client = clientManager.getClient(options.server);
|
|
1463
|
+
if (!client) throw new Error(`Server "${options.server}" not found`);
|
|
1464
|
+
const prompt = await client.getPrompt(promptName, promptArgs);
|
|
1465
|
+
if (options.json) console.log(JSON.stringify(prompt, null, 2));
|
|
1466
|
+
else for (const message of prompt.messages) {
|
|
1481
1467
|
const content = message.content;
|
|
1482
1468
|
if (typeof content === "object" && content && "text" in content) console.log(content.text);
|
|
1483
1469
|
else console.log(JSON.stringify(message, null, 2));
|
|
@@ -1485,11 +1471,11 @@ const getPromptCommand = new Command("get-prompt").description("Get a prompt by
|
|
|
1485
1471
|
return;
|
|
1486
1472
|
}
|
|
1487
1473
|
const matchingServers = [];
|
|
1488
|
-
await Promise.all(clients.map(async (client
|
|
1474
|
+
await Promise.all(clients.map(async (client) => {
|
|
1489
1475
|
try {
|
|
1490
|
-
if ((await client
|
|
1476
|
+
if ((await client.listPrompts()).some((prompt) => prompt.name === promptName)) matchingServers.push(client.serverName);
|
|
1491
1477
|
} catch (error) {
|
|
1492
|
-
if (!options.json) console.error(`Failed to list prompts from ${client
|
|
1478
|
+
if (!options.json) console.error(`Failed to list prompts from ${client.serverName}: ${toErrorMessage$1(error)}`);
|
|
1493
1479
|
}
|
|
1494
1480
|
}));
|
|
1495
1481
|
if (matchingServers.length === 0) throw new Error(`Prompt "${promptName}" not found on any connected server`);
|
|
@@ -1509,7 +1495,6 @@ const getPromptCommand = new Command("get-prompt").description("Get a prompt by
|
|
|
1509
1495
|
process.exit(1);
|
|
1510
1496
|
}
|
|
1511
1497
|
});
|
|
1512
|
-
|
|
1513
1498
|
//#endregion
|
|
1514
1499
|
//#region src/commands/prefetch.ts
|
|
1515
1500
|
/**
|
|
@@ -1636,7 +1621,6 @@ const prefetchCommand = new Command("prefetch").description("Pre-download packag
|
|
|
1636
1621
|
process.exit(1);
|
|
1637
1622
|
}
|
|
1638
1623
|
});
|
|
1639
|
-
|
|
1640
1624
|
//#endregion
|
|
1641
1625
|
//#region src/commands/stop.ts
|
|
1642
1626
|
/**
|
|
@@ -1682,7 +1666,6 @@ const stopCommand = new Command("stop").description("Stop a running HTTP mcp-pro
|
|
|
1682
1666
|
process.exit(1);
|
|
1683
1667
|
}
|
|
1684
1668
|
});
|
|
1685
|
-
|
|
1686
1669
|
//#endregion
|
|
1687
1670
|
//#region src/cli.ts
|
|
1688
1671
|
/**
|
|
@@ -1732,6 +1715,5 @@ main().catch((error) => {
|
|
|
1732
1715
|
console.error(`Fatal error: ${error instanceof Error ? error.message : error}`);
|
|
1733
1716
|
process.exit(1);
|
|
1734
1717
|
});
|
|
1735
|
-
|
|
1736
1718
|
//#endregion
|
|
1737
|
-
export {
|
|
1719
|
+
export {};
|