@letta-ai/letta-code 0.32.11 → 0.32.13
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/channels-slack.js +135 -54
- package/dist/channels-slack.js.map +3 -3
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/types/agent/message.d.ts.map +1 -1
- package/dist/types/agent/subagents/manager.d.ts.map +1 -1
- package/dist/types/agent/subagents/subagent-process.d.ts +23 -0
- package/dist/types/agent/subagents/subagent-process.d.ts.map +1 -0
- package/dist/types/backend/api/metadata.d.ts +12 -0
- package/dist/types/backend/api/metadata.d.ts.map +1 -1
- package/dist/types/channels/slack/status-controller.d.ts +2 -0
- package/dist/types/channels/slack/status-controller.d.ts.map +1 -1
- package/dist/types/cli/helpers/error-formatter.d.ts.map +1 -1
- package/dist/types/cli/helpers/stream-processor.d.ts +2 -0
- package/dist/types/cli/helpers/stream-processor.d.ts.map +1 -1
- package/dist/types/telemetry/index.d.ts +16 -1
- package/dist/types/telemetry/index.d.ts.map +1 -1
- package/dist/types/tools/impl/process_manager.d.ts +2 -0
- package/dist/types/tools/impl/process_manager.d.ts.map +1 -1
- package/dist/types/tools/impl/task-stop.d.ts.map +1 -1
- package/dist/types/tools/impl/task.d.ts.map +1 -1
- package/dist/types/utils/cloud-api-shutdown.d.ts +17 -0
- package/dist/types/utils/cloud-api-shutdown.d.ts.map +1 -0
- package/dist/types/websocket/listener/constants.d.ts +1 -0
- package/dist/types/websocket/listener/constants.d.ts.map +1 -1
- package/letta.js +2 -2
- package/package.json +1 -1
- package/scripts/build-pypi.py +172 -0
- package/scripts/isolated-unit-tests.json +5 -0
- package/scripts/smoke-pypi.py +236 -0
- package/scripts/source-file-size-baseline.json +1 -1
- package/scripts/stage-pypi-deps.mjs +90 -0
- package/skills/finding-agents/SKILL.md +6 -2
- package/skills/letta-guide/SKILL.md +21 -2
- package/skills/self-configuration/SKILL.md +11 -1
- package/skills/converting-mcps-to-skills/SKILL.md +0 -202
- package/skills/converting-mcps-to-skills/references/skill-templates.md +0 -141
- package/skills/converting-mcps-to-skills/scripts/mcp-http.ts +0 -980
- package/skills/converting-mcps-to-skills/scripts/mcp-stdio.ts +0 -494
|
@@ -1,494 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env npx tsx
|
|
2
|
-
/**
|
|
3
|
-
* MCP stdio Client - Connect to any MCP server over stdio
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* npx tsx mcp-stdio.ts "<command>" <action> [args]
|
|
7
|
-
*
|
|
8
|
-
* Commands:
|
|
9
|
-
* list-tools List available tools
|
|
10
|
-
* list-resources List available resources
|
|
11
|
-
* info <tool> Show tool schema
|
|
12
|
-
* call <tool> '<json>' Call a tool with JSON arguments
|
|
13
|
-
*
|
|
14
|
-
* Options:
|
|
15
|
-
* --env "KEY=VALUE" Set environment variable (can be repeated)
|
|
16
|
-
* --cwd <path> Set working directory for server
|
|
17
|
-
*
|
|
18
|
-
* Examples:
|
|
19
|
-
* npx tsx mcp-stdio.ts "node server.js" list-tools
|
|
20
|
-
* npx tsx mcp-stdio.ts "npx -y @modelcontextprotocol/server-filesystem ." list-tools
|
|
21
|
-
* npx tsx mcp-stdio.ts "python server.py" call my_tool '{"arg":"value"}'
|
|
22
|
-
* npx tsx mcp-stdio.ts "node server.js" --env "API_KEY=xxx" list-tools
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import { type ChildProcessWithoutNullStreams, spawn } from "node:child_process";
|
|
26
|
-
|
|
27
|
-
interface JsonRpcRequest {
|
|
28
|
-
jsonrpc: "2.0";
|
|
29
|
-
method: string;
|
|
30
|
-
params?: object;
|
|
31
|
-
id: number;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
interface JsonRpcNotification {
|
|
35
|
-
jsonrpc: "2.0";
|
|
36
|
-
method: string;
|
|
37
|
-
params?: object;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
interface JsonRpcResponse {
|
|
41
|
-
jsonrpc: "2.0";
|
|
42
|
-
result?: unknown;
|
|
43
|
-
error?: {
|
|
44
|
-
code: number;
|
|
45
|
-
message: string;
|
|
46
|
-
data?: unknown;
|
|
47
|
-
};
|
|
48
|
-
id: number;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
interface ParsedArgs {
|
|
52
|
-
serverCommand: string;
|
|
53
|
-
action: string;
|
|
54
|
-
actionArgs: string[];
|
|
55
|
-
env: Record<string, string>;
|
|
56
|
-
cwd?: string;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function parseArgs(): ParsedArgs {
|
|
60
|
-
const args = process.argv.slice(2);
|
|
61
|
-
const env: Record<string, string> = {};
|
|
62
|
-
let cwd: string | undefined;
|
|
63
|
-
let serverCommand = "";
|
|
64
|
-
let action = "";
|
|
65
|
-
const actionArgs: string[] = [];
|
|
66
|
-
|
|
67
|
-
let i = 0;
|
|
68
|
-
while (i < args.length) {
|
|
69
|
-
const arg = args[i];
|
|
70
|
-
if (!arg) {
|
|
71
|
-
i++;
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (arg === "--env" || arg === "-e") {
|
|
76
|
-
const envValue = args[++i];
|
|
77
|
-
if (envValue) {
|
|
78
|
-
const eqIndex = envValue.indexOf("=");
|
|
79
|
-
if (eqIndex > 0) {
|
|
80
|
-
const key = envValue.slice(0, eqIndex);
|
|
81
|
-
const value = envValue.slice(eqIndex + 1);
|
|
82
|
-
env[key] = value;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
} else if (arg === "--cwd") {
|
|
86
|
-
cwd = args[++i];
|
|
87
|
-
} else if (arg === "--help" || arg === "-h") {
|
|
88
|
-
printUsage();
|
|
89
|
-
process.exit(0);
|
|
90
|
-
} else if (!serverCommand) {
|
|
91
|
-
serverCommand = arg;
|
|
92
|
-
} else if (!action) {
|
|
93
|
-
action = arg;
|
|
94
|
-
} else {
|
|
95
|
-
actionArgs.push(arg);
|
|
96
|
-
}
|
|
97
|
-
i++;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return { serverCommand, action, actionArgs, env, cwd };
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function parseCommand(commandStr: string): { command: string; args: string[] } {
|
|
104
|
-
// Simple parsing - split on spaces, respecting quotes.
|
|
105
|
-
const parts: string[] = [];
|
|
106
|
-
let current = "";
|
|
107
|
-
let inQuote = false;
|
|
108
|
-
let quoteChar = "";
|
|
109
|
-
|
|
110
|
-
for (const char of commandStr) {
|
|
111
|
-
if ((char === '"' || char === "'") && !inQuote) {
|
|
112
|
-
inQuote = true;
|
|
113
|
-
quoteChar = char;
|
|
114
|
-
} else if (char === quoteChar && inQuote) {
|
|
115
|
-
inQuote = false;
|
|
116
|
-
quoteChar = "";
|
|
117
|
-
} else if (char === " " && !inQuote) {
|
|
118
|
-
if (current) {
|
|
119
|
-
parts.push(current);
|
|
120
|
-
current = "";
|
|
121
|
-
}
|
|
122
|
-
} else {
|
|
123
|
-
current += char;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (current) {
|
|
127
|
-
parts.push(current);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return {
|
|
131
|
-
command: parts[0] || "",
|
|
132
|
-
args: parts.slice(1),
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
let serverProcess: ChildProcessWithoutNullStreams | null = null;
|
|
137
|
-
let stdoutBuffer = "";
|
|
138
|
-
let nextRequestId = 1;
|
|
139
|
-
const pendingRequests = new Map<
|
|
140
|
-
number,
|
|
141
|
-
{
|
|
142
|
-
resolve: (response: JsonRpcResponse) => void;
|
|
143
|
-
reject: (error: Error) => void;
|
|
144
|
-
}
|
|
145
|
-
>();
|
|
146
|
-
|
|
147
|
-
function handleStdout(chunk: Buffer): void {
|
|
148
|
-
stdoutBuffer += chunk.toString("utf8");
|
|
149
|
-
|
|
150
|
-
while (true) {
|
|
151
|
-
const newlineIndex = stdoutBuffer.indexOf("\n");
|
|
152
|
-
if (newlineIndex === -1) {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const line = stdoutBuffer.slice(0, newlineIndex).trim();
|
|
157
|
-
stdoutBuffer = stdoutBuffer.slice(newlineIndex + 1);
|
|
158
|
-
|
|
159
|
-
if (!line) {
|
|
160
|
-
continue;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
let message: unknown;
|
|
164
|
-
try {
|
|
165
|
-
message = JSON.parse(line);
|
|
166
|
-
} catch {
|
|
167
|
-
process.stderr.write(`[server stdout] ${line}\n`);
|
|
168
|
-
continue;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (
|
|
172
|
-
typeof message !== "object" ||
|
|
173
|
-
message === null ||
|
|
174
|
-
!("id" in message) ||
|
|
175
|
-
typeof message.id !== "number"
|
|
176
|
-
) {
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const pending = pendingRequests.get(message.id);
|
|
181
|
-
if (!pending) {
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
pendingRequests.delete(message.id);
|
|
186
|
-
pending.resolve(message as JsonRpcResponse);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function rejectPendingRequests(error: Error): void {
|
|
191
|
-
for (const pending of pendingRequests.values()) {
|
|
192
|
-
pending.reject(error);
|
|
193
|
-
}
|
|
194
|
-
pendingRequests.clear();
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
async function connect(
|
|
198
|
-
serverCommand: string,
|
|
199
|
-
env: Record<string, string>,
|
|
200
|
-
cwd?: string,
|
|
201
|
-
): Promise<void> {
|
|
202
|
-
const { command, args } = parseCommand(serverCommand);
|
|
203
|
-
|
|
204
|
-
if (!command) {
|
|
205
|
-
throw new Error("No command specified");
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Merge with process.env.
|
|
209
|
-
const mergedEnv: Record<string, string> = {};
|
|
210
|
-
for (const [key, value] of Object.entries(process.env)) {
|
|
211
|
-
if (value !== undefined) {
|
|
212
|
-
mergedEnv[key] = value;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
Object.assign(mergedEnv, env);
|
|
216
|
-
|
|
217
|
-
serverProcess = spawn(command, args, {
|
|
218
|
-
cwd,
|
|
219
|
-
env: mergedEnv,
|
|
220
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
serverProcess.stdout.on("data", handleStdout);
|
|
224
|
-
serverProcess.stderr.on("data", (chunk: Buffer) => {
|
|
225
|
-
process.stderr.write(`[server] ${chunk.toString()}`);
|
|
226
|
-
});
|
|
227
|
-
serverProcess.on("error", (error) => {
|
|
228
|
-
rejectPendingRequests(error);
|
|
229
|
-
});
|
|
230
|
-
serverProcess.on("exit", (code, signal) => {
|
|
231
|
-
rejectPendingRequests(
|
|
232
|
-
new Error(`MCP server exited with code ${code} signal ${signal}`),
|
|
233
|
-
);
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
const initializeResponse = await sendRequest("initialize", {
|
|
237
|
-
protocolVersion: "2024-11-05",
|
|
238
|
-
capabilities: {},
|
|
239
|
-
clientInfo: {
|
|
240
|
-
name: "mcp-stdio-cli",
|
|
241
|
-
version: "1.0.0",
|
|
242
|
-
},
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
if (initializeResponse.error) {
|
|
246
|
-
throw new Error(
|
|
247
|
-
`Initialization failed: ${initializeResponse.error.message}`,
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
sendNotification("notifications/initialized", {});
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function sendMessage(message: JsonRpcRequest | JsonRpcNotification): void {
|
|
255
|
-
if (!serverProcess) {
|
|
256
|
-
throw new Error("MCP server is not connected");
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
serverProcess.stdin.write(`${JSON.stringify(message)}\n`);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
function sendNotification(method: string, params?: object): void {
|
|
263
|
-
sendMessage({ jsonrpc: "2.0", method, params });
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
function sendRequest(
|
|
267
|
-
method: string,
|
|
268
|
-
params?: object,
|
|
269
|
-
): Promise<JsonRpcResponse> {
|
|
270
|
-
const id = nextRequestId++;
|
|
271
|
-
const request: JsonRpcRequest = { jsonrpc: "2.0", method, params, id };
|
|
272
|
-
|
|
273
|
-
return new Promise((resolve, reject) => {
|
|
274
|
-
pendingRequests.set(id, { resolve, reject });
|
|
275
|
-
sendMessage(request);
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
async function cleanup(): Promise<void> {
|
|
280
|
-
if (serverProcess && !serverProcess.killed) {
|
|
281
|
-
serverProcess.kill();
|
|
282
|
-
}
|
|
283
|
-
serverProcess = null;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
async function listTools(): Promise<void> {
|
|
287
|
-
const response = await sendRequest("tools/list");
|
|
288
|
-
|
|
289
|
-
if (response.error) {
|
|
290
|
-
console.error("Error:", response.error.message);
|
|
291
|
-
process.exit(1);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const result = response.result as {
|
|
295
|
-
tools: Array<{ name: string; description?: string; inputSchema: object }>;
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
console.log("Available tools:\n");
|
|
299
|
-
for (const tool of result.tools) {
|
|
300
|
-
console.log(` ${tool.name}`);
|
|
301
|
-
if (tool.description) {
|
|
302
|
-
console.log(` ${tool.description}\n`);
|
|
303
|
-
} else {
|
|
304
|
-
console.log();
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
console.log(`\nTotal: ${result.tools.length} tools`);
|
|
309
|
-
console.log("\nUse 'call <tool> <json-args>' to invoke a tool");
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
async function listResources(): Promise<void> {
|
|
313
|
-
const response = await sendRequest("resources/list");
|
|
314
|
-
|
|
315
|
-
if (response.error) {
|
|
316
|
-
console.error("Error:", response.error.message);
|
|
317
|
-
process.exit(1);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
const result = response.result as {
|
|
321
|
-
resources: Array<{ uri: string; name: string; description?: string }>;
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
if (!result.resources || result.resources.length === 0) {
|
|
325
|
-
console.log("No resources available.");
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
console.log("Available resources:\n");
|
|
330
|
-
for (const resource of result.resources) {
|
|
331
|
-
console.log(` ${resource.uri}`);
|
|
332
|
-
console.log(` ${resource.name}`);
|
|
333
|
-
if (resource.description) {
|
|
334
|
-
console.log(` ${resource.description}`);
|
|
335
|
-
}
|
|
336
|
-
console.log();
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
async function getToolSchema(toolName: string): Promise<void> {
|
|
341
|
-
const response = await sendRequest("tools/list");
|
|
342
|
-
|
|
343
|
-
if (response.error) {
|
|
344
|
-
console.error("Error:", response.error.message);
|
|
345
|
-
process.exit(1);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
const result = response.result as {
|
|
349
|
-
tools: Array<{ name: string; description?: string; inputSchema: object }>;
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
const tool = result.tools.find((t) => t.name === toolName);
|
|
353
|
-
if (!tool) {
|
|
354
|
-
console.error(`Tool not found: ${toolName}`);
|
|
355
|
-
console.error(
|
|
356
|
-
`Available tools: ${result.tools.map((t) => t.name).join(", ")}`,
|
|
357
|
-
);
|
|
358
|
-
process.exit(1);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
console.log(`Tool: ${tool.name}\n`);
|
|
362
|
-
if (tool.description) {
|
|
363
|
-
console.log(`Description: ${tool.description}\n`);
|
|
364
|
-
}
|
|
365
|
-
console.log("Input Schema:");
|
|
366
|
-
console.log(JSON.stringify(tool.inputSchema, null, 2));
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
async function callTool(toolName: string, argsJson: string): Promise<void> {
|
|
370
|
-
let args: Record<string, unknown>;
|
|
371
|
-
try {
|
|
372
|
-
args = JSON.parse(argsJson || "{}");
|
|
373
|
-
} catch {
|
|
374
|
-
console.error(`Invalid JSON: ${argsJson}`);
|
|
375
|
-
process.exit(1);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
const response = await sendRequest("tools/call", {
|
|
379
|
-
name: toolName,
|
|
380
|
-
arguments: args,
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
if (response.error) {
|
|
384
|
-
console.error("Error:", response.error.message);
|
|
385
|
-
if (response.error.data) {
|
|
386
|
-
console.error("Details:", JSON.stringify(response.error.data, null, 2));
|
|
387
|
-
}
|
|
388
|
-
process.exit(1);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
console.log(JSON.stringify(response.result, null, 2));
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
function printUsage(): void {
|
|
395
|
-
console.log(`MCP stdio Client - Connect to any MCP server over stdio
|
|
396
|
-
|
|
397
|
-
Usage: npx tsx mcp-stdio.ts "<command>" [options] <action> [args]
|
|
398
|
-
|
|
399
|
-
Actions:
|
|
400
|
-
list-tools List available tools with descriptions
|
|
401
|
-
list-resources List available resources
|
|
402
|
-
info <tool> Show tool schema/parameters
|
|
403
|
-
call <tool> '<json>' Call a tool with JSON arguments
|
|
404
|
-
|
|
405
|
-
Options:
|
|
406
|
-
--env, -e "KEY=VALUE" Set environment variable (repeatable)
|
|
407
|
-
--cwd <path> Set working directory for server
|
|
408
|
-
--help, -h Show this help
|
|
409
|
-
|
|
410
|
-
Examples:
|
|
411
|
-
# List tools from filesystem server
|
|
412
|
-
npx tsx mcp-stdio.ts "npx -y @modelcontextprotocol/server-filesystem ." list-tools
|
|
413
|
-
|
|
414
|
-
# With environment variable
|
|
415
|
-
npx tsx mcp-stdio.ts "node server.js" --env "API_KEY=xxx" list-tools
|
|
416
|
-
|
|
417
|
-
# Call a tool
|
|
418
|
-
npx tsx mcp-stdio.ts "python server.py" call read_file '{"path":"./README.md"}'
|
|
419
|
-
`);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
async function main(): Promise<void> {
|
|
423
|
-
const { serverCommand, action, actionArgs, env, cwd } = parseArgs();
|
|
424
|
-
|
|
425
|
-
if (!serverCommand) {
|
|
426
|
-
console.error("Error: Server command is required\n");
|
|
427
|
-
printUsage();
|
|
428
|
-
process.exit(1);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
if (!action) {
|
|
432
|
-
console.error("Error: Action is required\n");
|
|
433
|
-
printUsage();
|
|
434
|
-
process.exit(1);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
process.on("SIGINT", async () => {
|
|
438
|
-
await cleanup();
|
|
439
|
-
process.exit(0);
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
process.on("SIGTERM", async () => {
|
|
443
|
-
await cleanup();
|
|
444
|
-
process.exit(0);
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
try {
|
|
448
|
-
await connect(serverCommand, env, cwd);
|
|
449
|
-
|
|
450
|
-
switch (action) {
|
|
451
|
-
case "list-tools":
|
|
452
|
-
await listTools();
|
|
453
|
-
break;
|
|
454
|
-
|
|
455
|
-
case "list-resources":
|
|
456
|
-
await listResources();
|
|
457
|
-
break;
|
|
458
|
-
|
|
459
|
-
case "info": {
|
|
460
|
-
const [toolName] = actionArgs;
|
|
461
|
-
if (!toolName) {
|
|
462
|
-
console.error("Error: Tool name required");
|
|
463
|
-
console.error("Usage: info <tool>");
|
|
464
|
-
process.exit(1);
|
|
465
|
-
}
|
|
466
|
-
await getToolSchema(toolName);
|
|
467
|
-
break;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
case "call": {
|
|
471
|
-
const [toolName, argsJson] = actionArgs;
|
|
472
|
-
if (!toolName) {
|
|
473
|
-
console.error("Error: Tool name required");
|
|
474
|
-
console.error("Usage: call <tool> '<json-args>'");
|
|
475
|
-
process.exit(1);
|
|
476
|
-
}
|
|
477
|
-
await callTool(toolName, argsJson || "{}");
|
|
478
|
-
break;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
default:
|
|
482
|
-
console.error(`Unknown action: ${action}\n`);
|
|
483
|
-
printUsage();
|
|
484
|
-
process.exit(1);
|
|
485
|
-
}
|
|
486
|
-
} catch (error) {
|
|
487
|
-
console.error("Error:", error instanceof Error ? error.message : error);
|
|
488
|
-
process.exit(1);
|
|
489
|
-
} finally {
|
|
490
|
-
await cleanup();
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
main();
|