@agiflowai/one-mcp 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +500 -0
- package/dist/cli.cjs +497 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +498 -0
- package/dist/http-B1EDyxR_.mjs +1211 -0
- package/dist/http-B5WVqLzz.cjs +1277 -0
- package/dist/index.cjs +6 -0
- package/dist/index.d.cts +172 -0
- package/dist/index.d.mts +172 -0
- package/dist/index.mjs +3 -0
- package/package.json +57 -0
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { a as McpClientManagerService, i as createServer, n as SseTransportHandler, o as ConfigFetcherService, r as StdioTransportHandler, t as HttpTransportHandler } from "./http-B1EDyxR_.mjs";
|
|
3
|
+
import { writeFile } from "node:fs/promises";
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { resolve } from "node:path";
|
|
6
|
+
import { log } from "@agiflowai/aicode-utils";
|
|
7
|
+
|
|
8
|
+
//#region src/types/index.ts
|
|
9
|
+
/**
|
|
10
|
+
* Transport mode types
|
|
11
|
+
*/
|
|
12
|
+
let TransportMode = /* @__PURE__ */ function(TransportMode$1) {
|
|
13
|
+
TransportMode$1["STDIO"] = "stdio";
|
|
14
|
+
TransportMode$1["HTTP"] = "http";
|
|
15
|
+
TransportMode$1["SSE"] = "sse";
|
|
16
|
+
return TransportMode$1;
|
|
17
|
+
}({});
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/commands/mcp-serve.ts
|
|
21
|
+
/**
|
|
22
|
+
* MCP Serve Command
|
|
23
|
+
*
|
|
24
|
+
* DESIGN PATTERNS:
|
|
25
|
+
* - Command pattern with Commander for CLI argument parsing
|
|
26
|
+
* - Transport abstraction pattern for flexible deployment (stdio, HTTP, SSE)
|
|
27
|
+
* - Factory pattern for creating transport handlers
|
|
28
|
+
* - Graceful shutdown pattern with signal handling
|
|
29
|
+
*
|
|
30
|
+
* CODING STANDARDS:
|
|
31
|
+
* - Use async/await for asynchronous operations
|
|
32
|
+
* - Implement proper error handling with try-catch blocks
|
|
33
|
+
* - Handle process signals for graceful shutdown
|
|
34
|
+
* - Provide clear CLI options and help messages
|
|
35
|
+
*
|
|
36
|
+
* AVOID:
|
|
37
|
+
* - Hardcoded configuration values (use CLI options or environment variables)
|
|
38
|
+
* - Missing error handling for transport startup
|
|
39
|
+
* - Not cleaning up resources on shutdown
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Start MCP server with given transport handler
|
|
43
|
+
*/
|
|
44
|
+
async function startServer(handler) {
|
|
45
|
+
await handler.start();
|
|
46
|
+
const shutdown = async (signal) => {
|
|
47
|
+
console.error(`\nReceived ${signal}, shutting down gracefully...`);
|
|
48
|
+
try {
|
|
49
|
+
await handler.stop();
|
|
50
|
+
process.exit(0);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error("Error during shutdown:", error);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
57
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* MCP Serve command
|
|
61
|
+
*/
|
|
62
|
+
const mcpServeCommand = new Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", "Transport type: stdio, http, or sse", "stdio").option("-p, --port <port>", "Port to listen on (http/sse only)", (val) => parseInt(val, 10), 3e3).option("--host <host>", "Host to bind to (http/sse only)", "localhost").option("-c, --config <path>", "Path to MCP server configuration file").option("--no-cache", "Force reload configuration from source, bypassing cache").action(async (options) => {
|
|
63
|
+
try {
|
|
64
|
+
const transportType = options.type.toLowerCase();
|
|
65
|
+
const serverOptions = {
|
|
66
|
+
configFilePath: options.config,
|
|
67
|
+
noCache: options.cache === false
|
|
68
|
+
};
|
|
69
|
+
if (transportType === "stdio") await startServer(new StdioTransportHandler(await createServer(serverOptions)));
|
|
70
|
+
else if (transportType === "http") await startServer(new HttpTransportHandler(await createServer(serverOptions), {
|
|
71
|
+
mode: TransportMode.HTTP,
|
|
72
|
+
port: options.port || Number(process.env.MCP_PORT) || 3e3,
|
|
73
|
+
host: options.host || process.env.MCP_HOST || "localhost"
|
|
74
|
+
}));
|
|
75
|
+
else if (transportType === "sse") await startServer(new SseTransportHandler(await createServer(serverOptions), {
|
|
76
|
+
mode: TransportMode.SSE,
|
|
77
|
+
port: options.port || Number(process.env.MCP_PORT) || 3e3,
|
|
78
|
+
host: options.host || process.env.MCP_HOST || "localhost"
|
|
79
|
+
}));
|
|
80
|
+
else {
|
|
81
|
+
console.error(`Unknown transport type: ${transportType}. Use: stdio, http, or sse`);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error("Failed to start MCP server:", error);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/commands/list-tools.ts
|
|
92
|
+
/**
|
|
93
|
+
* List Tools Command
|
|
94
|
+
*
|
|
95
|
+
* DESIGN PATTERNS:
|
|
96
|
+
* - Command pattern with Commander for CLI argument parsing
|
|
97
|
+
* - Async/await pattern for asynchronous operations
|
|
98
|
+
* - Error handling pattern with try-catch and proper exit codes
|
|
99
|
+
*
|
|
100
|
+
* CODING STANDARDS:
|
|
101
|
+
* - Use async action handlers for asynchronous operations
|
|
102
|
+
* - Provide clear option descriptions and default values
|
|
103
|
+
* - Handle errors gracefully with process.exit()
|
|
104
|
+
* - Log progress and errors to console
|
|
105
|
+
* - Use Commander's .option() and .argument() for inputs
|
|
106
|
+
*
|
|
107
|
+
* AVOID:
|
|
108
|
+
* - Synchronous blocking operations in action handlers
|
|
109
|
+
* - Missing error handling (always use try-catch)
|
|
110
|
+
* - Hardcoded values (use options or environment variables)
|
|
111
|
+
* - Not exiting with appropriate exit codes on errors
|
|
112
|
+
*/
|
|
113
|
+
/**
|
|
114
|
+
* List all available tools from connected MCP servers
|
|
115
|
+
*/
|
|
116
|
+
const listToolsCommand = new Command("list-tools").description("List all available tools from connected MCP servers").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Filter by server name").option("-j, --json", "Output as JSON", false).action(async (options) => {
|
|
117
|
+
try {
|
|
118
|
+
if (!options.config) {
|
|
119
|
+
console.error("Error: --config is required");
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
const config = await new ConfigFetcherService({ configFilePath: options.config }).fetchConfiguration();
|
|
123
|
+
const clientManager = new McpClientManagerService();
|
|
124
|
+
const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
|
|
125
|
+
try {
|
|
126
|
+
await clientManager.connectToServer(serverName, serverConfig);
|
|
127
|
+
if (!options.json) console.error(`✓ Connected to ${serverName}`);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
if (!options.json) console.error(`✗ Failed to connect to ${serverName}:`, error);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
await Promise.all(connectionPromises);
|
|
133
|
+
const clients = options.server ? [clientManager.getClient(options.server)].filter((c) => c !== void 0) : clientManager.getAllClients();
|
|
134
|
+
if (clients.length === 0) {
|
|
135
|
+
console.error("No MCP servers connected");
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
const toolsByServer = {};
|
|
139
|
+
for (const client of clients) try {
|
|
140
|
+
const tools = await client.listTools();
|
|
141
|
+
const blacklist = new Set(client.toolBlacklist || []);
|
|
142
|
+
const filteredTools = tools.filter((t) => !blacklist.has(t.name));
|
|
143
|
+
toolsByServer[client.serverName] = filteredTools;
|
|
144
|
+
} catch (error) {
|
|
145
|
+
if (!options.json) console.error(`Failed to list tools from ${client.serverName}:`, error);
|
|
146
|
+
toolsByServer[client.serverName] = [];
|
|
147
|
+
}
|
|
148
|
+
if (options.json) console.log(JSON.stringify(toolsByServer, null, 2));
|
|
149
|
+
else for (const [serverName, tools] of Object.entries(toolsByServer)) {
|
|
150
|
+
const omitDescription = clients.find((c) => c.serverName === serverName)?.omitToolDescription || false;
|
|
151
|
+
console.log(`\n${serverName}:`);
|
|
152
|
+
if (tools.length === 0) console.log(" No tools available");
|
|
153
|
+
else if (omitDescription) {
|
|
154
|
+
const toolNames = tools.map((t) => t.name).join(", ");
|
|
155
|
+
console.log(` ${toolNames}`);
|
|
156
|
+
} else for (const tool of tools) console.log(` - ${tool.name}: ${tool.description || "No description"}`);
|
|
157
|
+
}
|
|
158
|
+
await clientManager.disconnectAll();
|
|
159
|
+
} catch (error) {
|
|
160
|
+
console.error("Error executing list-tools:", error);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/commands/describe-tools.ts
|
|
167
|
+
/**
|
|
168
|
+
* Describe Tools Command
|
|
169
|
+
*
|
|
170
|
+
* DESIGN PATTERNS:
|
|
171
|
+
* - Command pattern with Commander for CLI argument parsing
|
|
172
|
+
* - Async/await pattern for asynchronous operations
|
|
173
|
+
* - Error handling pattern with try-catch and proper exit codes
|
|
174
|
+
*
|
|
175
|
+
* CODING STANDARDS:
|
|
176
|
+
* - Use async action handlers for asynchronous operations
|
|
177
|
+
* - Provide clear option descriptions and default values
|
|
178
|
+
* - Handle errors gracefully with process.exit()
|
|
179
|
+
* - Log progress and errors to console
|
|
180
|
+
* - Use Commander's .option() and .argument() for inputs
|
|
181
|
+
*
|
|
182
|
+
* AVOID:
|
|
183
|
+
* - Synchronous blocking operations in action handlers
|
|
184
|
+
* - Missing error handling (always use try-catch)
|
|
185
|
+
* - Hardcoded values (use options or environment variables)
|
|
186
|
+
* - Not exiting with appropriate exit codes on errors
|
|
187
|
+
*/
|
|
188
|
+
/**
|
|
189
|
+
* Describe specific MCP tools
|
|
190
|
+
*/
|
|
191
|
+
const describeToolsCommand = new Command("describe-tools").description("Describe specific MCP tools").argument("<toolNames...>", "Tool names to describe").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Filter by server name").option("-j, --json", "Output as JSON", false).action(async (toolNames, options) => {
|
|
192
|
+
try {
|
|
193
|
+
if (!options.config) {
|
|
194
|
+
console.error("Error: --config is required");
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
const config = await new ConfigFetcherService({ configFilePath: options.config }).fetchConfiguration();
|
|
198
|
+
const clientManager = new McpClientManagerService();
|
|
199
|
+
const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
|
|
200
|
+
try {
|
|
201
|
+
await clientManager.connectToServer(serverName, serverConfig);
|
|
202
|
+
if (!options.json) console.error(`✓ Connected to ${serverName}`);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
if (!options.json) console.error(`✗ Failed to connect to ${serverName}:`, error);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
await Promise.all(connectionPromises);
|
|
208
|
+
const clients = clientManager.getAllClients();
|
|
209
|
+
if (clients.length === 0) {
|
|
210
|
+
console.error("No MCP servers connected");
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
|
213
|
+
const foundTools = [];
|
|
214
|
+
const notFoundTools = [...toolNames];
|
|
215
|
+
for (const client of clients) {
|
|
216
|
+
if (options.server && client.serverName !== options.server) continue;
|
|
217
|
+
try {
|
|
218
|
+
const tools = await client.listTools();
|
|
219
|
+
for (const toolName of toolNames) {
|
|
220
|
+
const tool = tools.find((t) => t.name === toolName);
|
|
221
|
+
if (tool) {
|
|
222
|
+
foundTools.push({
|
|
223
|
+
server: client.serverName,
|
|
224
|
+
name: tool.name,
|
|
225
|
+
description: tool.description,
|
|
226
|
+
inputSchema: tool.inputSchema
|
|
227
|
+
});
|
|
228
|
+
const idx = notFoundTools.indexOf(toolName);
|
|
229
|
+
if (idx > -1) notFoundTools.splice(idx, 1);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
} catch (error) {
|
|
233
|
+
if (!options.json) console.error(`Failed to list tools from ${client.serverName}:`, error);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (options.json) {
|
|
237
|
+
const result = { tools: foundTools };
|
|
238
|
+
if (notFoundTools.length > 0) result.notFound = notFoundTools;
|
|
239
|
+
console.log(JSON.stringify(result, null, 2));
|
|
240
|
+
} else {
|
|
241
|
+
if (foundTools.length > 0) {
|
|
242
|
+
console.log("\nFound tools:\n");
|
|
243
|
+
for (const tool of foundTools) {
|
|
244
|
+
console.log(`Server: ${tool.server}`);
|
|
245
|
+
console.log(`Tool: ${tool.name}`);
|
|
246
|
+
console.log(`Description: ${tool.description || "No description"}`);
|
|
247
|
+
console.log(`Input Schema:`);
|
|
248
|
+
console.log(JSON.stringify(tool.inputSchema, null, 2));
|
|
249
|
+
console.log("");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (notFoundTools.length > 0) console.error(`\nTools not found: ${notFoundTools.join(", ")}`);
|
|
253
|
+
if (foundTools.length === 0) {
|
|
254
|
+
console.error("No tools found");
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
await clientManager.disconnectAll();
|
|
259
|
+
} catch (error) {
|
|
260
|
+
console.error("Error executing describe-tools:", error);
|
|
261
|
+
process.exit(1);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
//#endregion
|
|
266
|
+
//#region src/commands/use-tool.ts
|
|
267
|
+
/**
|
|
268
|
+
* Use Tool Command
|
|
269
|
+
*
|
|
270
|
+
* DESIGN PATTERNS:
|
|
271
|
+
* - Command pattern with Commander for CLI argument parsing
|
|
272
|
+
* - Async/await pattern for asynchronous operations
|
|
273
|
+
* - Error handling pattern with try-catch and proper exit codes
|
|
274
|
+
*
|
|
275
|
+
* CODING STANDARDS:
|
|
276
|
+
* - Use async action handlers for asynchronous operations
|
|
277
|
+
* - Provide clear option descriptions and default values
|
|
278
|
+
* - Handle errors gracefully with process.exit()
|
|
279
|
+
* - Log progress and errors to console
|
|
280
|
+
* - Use Commander's .option() and .argument() for inputs
|
|
281
|
+
*
|
|
282
|
+
* AVOID:
|
|
283
|
+
* - Synchronous blocking operations in action handlers
|
|
284
|
+
* - Missing error handling (always use try-catch)
|
|
285
|
+
* - Hardcoded values (use options or environment variables)
|
|
286
|
+
* - Not exiting with appropriate exit codes on errors
|
|
287
|
+
*/
|
|
288
|
+
/**
|
|
289
|
+
* Execute an MCP tool with arguments
|
|
290
|
+
*/
|
|
291
|
+
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) => {
|
|
292
|
+
try {
|
|
293
|
+
if (!options.config) {
|
|
294
|
+
console.error("Error: --config is required");
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
let toolArgs = {};
|
|
298
|
+
try {
|
|
299
|
+
toolArgs = JSON.parse(options.args);
|
|
300
|
+
} catch (error) {
|
|
301
|
+
console.error("Error: Invalid JSON in --args");
|
|
302
|
+
process.exit(1);
|
|
303
|
+
}
|
|
304
|
+
const config = await new ConfigFetcherService({ configFilePath: options.config }).fetchConfiguration();
|
|
305
|
+
const clientManager = new McpClientManagerService();
|
|
306
|
+
const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
|
|
307
|
+
try {
|
|
308
|
+
await clientManager.connectToServer(serverName, serverConfig);
|
|
309
|
+
if (!options.json) console.error(`✓ Connected to ${serverName}`);
|
|
310
|
+
} catch (error) {
|
|
311
|
+
if (!options.json) console.error(`✗ Failed to connect to ${serverName}:`, error);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
await Promise.all(connectionPromises);
|
|
315
|
+
const clients = clientManager.getAllClients();
|
|
316
|
+
if (clients.length === 0) {
|
|
317
|
+
console.error("No MCP servers connected");
|
|
318
|
+
process.exit(1);
|
|
319
|
+
}
|
|
320
|
+
if (options.server) {
|
|
321
|
+
const client$1 = clientManager.getClient(options.server);
|
|
322
|
+
if (!client$1) {
|
|
323
|
+
console.error(`Server "${options.server}" not found`);
|
|
324
|
+
process.exit(1);
|
|
325
|
+
}
|
|
326
|
+
try {
|
|
327
|
+
if (!options.json) console.error(`Executing ${toolName} on ${options.server}...`);
|
|
328
|
+
const result = await client$1.callTool(toolName, toolArgs);
|
|
329
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
330
|
+
else {
|
|
331
|
+
console.log("\nResult:");
|
|
332
|
+
if (result.content) for (const content of result.content) if (content.type === "text") console.log(content.text);
|
|
333
|
+
else console.log(JSON.stringify(content, null, 2));
|
|
334
|
+
if (result.isError) {
|
|
335
|
+
console.error("\n⚠️ Tool execution returned an error");
|
|
336
|
+
process.exit(1);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
await clientManager.disconnectAll();
|
|
340
|
+
return;
|
|
341
|
+
} catch (error) {
|
|
342
|
+
console.error(`Failed to execute tool "${toolName}":`, error);
|
|
343
|
+
await clientManager.disconnectAll();
|
|
344
|
+
process.exit(1);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
const matchingServers = [];
|
|
348
|
+
for (const client$1 of clients) try {
|
|
349
|
+
if ((await client$1.listTools()).some((t) => t.name === toolName)) matchingServers.push(client$1.serverName);
|
|
350
|
+
} catch (error) {
|
|
351
|
+
if (!options.json) console.error(`Failed to list tools from ${client$1.serverName}:`, error);
|
|
352
|
+
}
|
|
353
|
+
if (matchingServers.length === 0) {
|
|
354
|
+
console.error(`Tool "${toolName}" not found on any connected server`);
|
|
355
|
+
await clientManager.disconnectAll();
|
|
356
|
+
process.exit(1);
|
|
357
|
+
}
|
|
358
|
+
if (matchingServers.length > 1) {
|
|
359
|
+
console.error(`Tool "${toolName}" found on multiple servers: ${matchingServers.join(", ")}`);
|
|
360
|
+
console.error("Please specify --server to disambiguate");
|
|
361
|
+
await clientManager.disconnectAll();
|
|
362
|
+
process.exit(1);
|
|
363
|
+
}
|
|
364
|
+
const targetServer = matchingServers[0];
|
|
365
|
+
const client = clientManager.getClient(targetServer);
|
|
366
|
+
if (!client) {
|
|
367
|
+
console.error(`Internal error: Server "${targetServer}" not connected`);
|
|
368
|
+
await clientManager.disconnectAll();
|
|
369
|
+
process.exit(1);
|
|
370
|
+
}
|
|
371
|
+
try {
|
|
372
|
+
if (!options.json) console.error(`Executing ${toolName} on ${targetServer}...`);
|
|
373
|
+
const result = await client.callTool(toolName, toolArgs);
|
|
374
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
375
|
+
else {
|
|
376
|
+
console.log("\nResult:");
|
|
377
|
+
if (result.content) for (const content of result.content) if (content.type === "text") console.log(content.text);
|
|
378
|
+
else console.log(JSON.stringify(content, null, 2));
|
|
379
|
+
if (result.isError) {
|
|
380
|
+
console.error("\n⚠️ Tool execution returned an error");
|
|
381
|
+
await clientManager.disconnectAll();
|
|
382
|
+
process.exit(1);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
await clientManager.disconnectAll();
|
|
386
|
+
} catch (error) {
|
|
387
|
+
console.error(`Failed to execute tool "${toolName}":`, error);
|
|
388
|
+
await clientManager.disconnectAll();
|
|
389
|
+
process.exit(1);
|
|
390
|
+
}
|
|
391
|
+
} catch (error) {
|
|
392
|
+
console.error("Error executing use-tool:", error);
|
|
393
|
+
process.exit(1);
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
//#endregion
|
|
398
|
+
//#region src/templates/mcp-config.yaml?raw
|
|
399
|
+
var mcp_config_default = "# MCP Server Configuration\n# This file configures the MCP servers that one-mcp 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\nmcpServers:\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";
|
|
400
|
+
|
|
401
|
+
//#endregion
|
|
402
|
+
//#region src/templates/mcp-config.json?raw
|
|
403
|
+
var mcp_config_default$1 = "{\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\": [\n \"/path/to/mcp-server/build/index.js\"\n ],\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";
|
|
404
|
+
|
|
405
|
+
//#endregion
|
|
406
|
+
//#region src/commands/init.ts
|
|
407
|
+
/**
|
|
408
|
+
* Init Command
|
|
409
|
+
*
|
|
410
|
+
* DESIGN PATTERNS:
|
|
411
|
+
* - Command pattern with Commander for CLI argument parsing
|
|
412
|
+
* - Async/await pattern for asynchronous operations
|
|
413
|
+
* - Error handling pattern with try-catch and proper exit codes
|
|
414
|
+
*
|
|
415
|
+
* CODING STANDARDS:
|
|
416
|
+
* - Use async action handlers for asynchronous operations
|
|
417
|
+
* - Provide clear option descriptions and default values
|
|
418
|
+
* - Handle errors gracefully with process.exit()
|
|
419
|
+
* - Log progress and errors to console
|
|
420
|
+
* - Use Commander's .option() and .argument() for inputs
|
|
421
|
+
*
|
|
422
|
+
* AVOID:
|
|
423
|
+
* - Synchronous blocking operations in action handlers
|
|
424
|
+
* - Missing error handling (always use try-catch)
|
|
425
|
+
* - Hardcoded values (use options or environment variables)
|
|
426
|
+
* - Not exiting with appropriate exit codes on errors
|
|
427
|
+
*/
|
|
428
|
+
/**
|
|
429
|
+
* Initialize MCP configuration file
|
|
430
|
+
*/
|
|
431
|
+
const initCommand = new Command("init").description("Initialize MCP configuration file").option("-o, --output <path>", "Output file path", "mcp-config.yaml").option("--json", "Generate JSON config instead of YAML", false).option("-f, --force", "Overwrite existing config file", false).action(async (options) => {
|
|
432
|
+
try {
|
|
433
|
+
const outputPath = resolve(options.output);
|
|
434
|
+
const template = !options.json && (outputPath.endsWith(".yaml") || outputPath.endsWith(".yml")) ? mcp_config_default : mcp_config_default$1;
|
|
435
|
+
try {
|
|
436
|
+
await writeFile(outputPath, template, {
|
|
437
|
+
encoding: "utf-8",
|
|
438
|
+
flag: options.force ? "w" : "wx"
|
|
439
|
+
});
|
|
440
|
+
} catch (error) {
|
|
441
|
+
if (error && typeof error === "object" && "code" in error && error.code === "EEXIST") {
|
|
442
|
+
log.error(`Config file already exists: ${outputPath}`);
|
|
443
|
+
log.info("Use --force to overwrite");
|
|
444
|
+
process.exit(1);
|
|
445
|
+
}
|
|
446
|
+
throw error;
|
|
447
|
+
}
|
|
448
|
+
log.info(`MCP configuration file created: ${outputPath}`);
|
|
449
|
+
log.info("Next steps:");
|
|
450
|
+
log.info("1. Edit the configuration file to add your MCP servers");
|
|
451
|
+
log.info(`2. Run: one-mcp mcp-serve --config ${outputPath}`);
|
|
452
|
+
} catch (error) {
|
|
453
|
+
log.error("Error executing init:", error instanceof Error ? error.message : String(error));
|
|
454
|
+
process.exit(1);
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
//#endregion
|
|
459
|
+
//#region package.json
|
|
460
|
+
var version = "0.1.0";
|
|
461
|
+
|
|
462
|
+
//#endregion
|
|
463
|
+
//#region src/cli.ts
|
|
464
|
+
/**
|
|
465
|
+
* MCP Server Entry Point
|
|
466
|
+
*
|
|
467
|
+
* DESIGN PATTERNS:
|
|
468
|
+
* - CLI pattern with Commander for argument parsing
|
|
469
|
+
* - Command pattern for organizing CLI commands
|
|
470
|
+
* - Transport abstraction for multiple communication methods
|
|
471
|
+
*
|
|
472
|
+
* CODING STANDARDS:
|
|
473
|
+
* - Use async/await for asynchronous operations
|
|
474
|
+
* - Handle errors gracefully with try-catch
|
|
475
|
+
* - Log important events for debugging
|
|
476
|
+
* - Register all commands in main entry point
|
|
477
|
+
*
|
|
478
|
+
* AVOID:
|
|
479
|
+
* - Hardcoding command logic in index.ts (use separate command files)
|
|
480
|
+
* - Missing error handling for command execution
|
|
481
|
+
*/
|
|
482
|
+
/**
|
|
483
|
+
* Main entry point
|
|
484
|
+
*/
|
|
485
|
+
async function main() {
|
|
486
|
+
const program = new Command();
|
|
487
|
+
program.name("one-mcp").description("One MCP server package").version(version);
|
|
488
|
+
program.addCommand(initCommand);
|
|
489
|
+
program.addCommand(mcpServeCommand);
|
|
490
|
+
program.addCommand(listToolsCommand);
|
|
491
|
+
program.addCommand(describeToolsCommand);
|
|
492
|
+
program.addCommand(useToolCommand);
|
|
493
|
+
await program.parseAsync(process.argv);
|
|
494
|
+
}
|
|
495
|
+
main();
|
|
496
|
+
|
|
497
|
+
//#endregion
|
|
498
|
+
export { };
|