lua-cli 3.1.0-alpha.4 → 3.1.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.
Files changed (97) hide show
  1. package/dist/api/cdn.api.service.d.ts +18 -0
  2. package/dist/api/cdn.api.service.js +43 -0
  3. package/dist/api/custom.data.api.service.d.ts +4 -3
  4. package/dist/api/custom.data.api.service.js +4 -3
  5. package/dist/api/developer.api.service.d.ts +54 -1
  6. package/dist/api/developer.api.service.js +89 -0
  7. package/dist/api/job.api.service.d.ts +10 -0
  8. package/dist/api/job.api.service.js +14 -0
  9. package/dist/api/lazy-instances.d.ts +8 -0
  10. package/dist/api/lazy-instances.js +16 -0
  11. package/dist/api/postprocessor.api.service.d.ts +3 -6
  12. package/dist/api/postprocessor.api.service.js +2 -3
  13. package/dist/api-exports.d.ts +74 -6
  14. package/dist/api-exports.js +87 -7
  15. package/dist/cli/command-definitions.js +34 -7
  16. package/dist/commands/admin.js +1 -1
  17. package/dist/commands/channels.js +1 -1
  18. package/dist/commands/compile.js +23 -4
  19. package/dist/commands/evals.d.ts +8 -0
  20. package/dist/commands/evals.js +41 -0
  21. package/dist/commands/index.d.ts +2 -0
  22. package/dist/commands/index.js +2 -0
  23. package/dist/commands/init.d.ts +10 -1
  24. package/dist/commands/init.js +13 -3
  25. package/dist/commands/mcp.d.ts +18 -0
  26. package/dist/commands/mcp.js +393 -0
  27. package/dist/commands/push.js +172 -14
  28. package/dist/common/data.entry.instance.d.ts +1 -1
  29. package/dist/common/data.entry.instance.js +4 -4
  30. package/dist/common/job.instance.d.ts +24 -0
  31. package/dist/common/job.instance.js +38 -0
  32. package/dist/config/constants.d.ts +1 -0
  33. package/dist/config/constants.js +1 -0
  34. package/dist/index.js +1 -0
  35. package/dist/interfaces/cdn.d.ts +24 -0
  36. package/dist/interfaces/cdn.js +5 -0
  37. package/dist/interfaces/compile.d.ts +1 -0
  38. package/dist/interfaces/custom.data.d.ts +3 -3
  39. package/dist/interfaces/index.d.ts +1 -0
  40. package/dist/interfaces/mcp.d.ts +64 -0
  41. package/dist/interfaces/mcp.js +5 -0
  42. package/dist/types/api-contracts.d.ts +36 -14
  43. package/dist/types/compile.types.d.ts +5 -0
  44. package/dist/types/index.d.ts +2 -2
  45. package/dist/types/index.js +3 -1
  46. package/dist/types/skill.d.ts +120 -13
  47. package/dist/types/skill.js +95 -5
  48. package/dist/utils/bundling.d.ts +4 -11
  49. package/dist/utils/bundling.js +19 -27
  50. package/dist/utils/compile.d.ts +17 -8
  51. package/dist/utils/compile.js +71 -37
  52. package/dist/utils/deployment.js +13 -6
  53. package/dist/utils/dev-api.js +1 -2
  54. package/dist/utils/dev-server.js +1 -1
  55. package/dist/utils/files.d.ts +8 -1
  56. package/dist/utils/files.js +13 -2
  57. package/dist/utils/init-helpers.d.ts +3 -1
  58. package/dist/utils/init-helpers.js +7 -2
  59. package/dist/utils/mcp-server-management.d.ts +23 -0
  60. package/dist/utils/mcp-server-management.js +212 -0
  61. package/dist/utils/sandbox.d.ts +4 -2
  62. package/dist/utils/sandbox.js +22 -3
  63. package/dist/web/app.css +1505 -14
  64. package/dist/web/app.js +79 -64
  65. package/package.json +2 -6
  66. package/template/QUICKSTART.md +57 -761
  67. package/template/README.md +80 -906
  68. package/template/examples/README.md +106 -0
  69. package/template/{src → examples}/jobs/AbandonedBasketProcessorJob.ts +67 -11
  70. package/template/{src → examples}/postprocessors/modifyResponse.ts +3 -3
  71. package/template/{src → examples}/skills/tools/GameScoreTrackerTool.ts +11 -15
  72. package/template/{src → examples}/skills/tools/OrderTool.ts +25 -0
  73. package/template/examples/skills/tools/PremiumFeatureTool.ts +98 -0
  74. package/template/{src → examples}/skills/tools/UserDataTool.ts +34 -0
  75. package/template/examples/webhooks/FileUploadWebhook.ts +86 -0
  76. package/template/package-lock.json +7895 -0
  77. package/template/package.json +1 -1
  78. package/template/src/index.ts +40 -22
  79. /package/template/{src → examples}/jobs/DailyCleanupJob.ts +0 -0
  80. /package/template/{src → examples}/jobs/DataMigrationJob.ts +0 -0
  81. /package/template/{src → examples}/jobs/HealthCheckJob.ts +0 -0
  82. /package/template/{src → examples}/preprocessors/messageMatching.ts +0 -0
  83. /package/template/{src → examples}/services/ApiService.ts +0 -0
  84. /package/template/{src → examples}/services/GetWeather.ts +0 -0
  85. /package/template/{src → examples}/skills/basket.skill.ts +0 -0
  86. /package/template/{src → examples}/skills/product.skill.ts +0 -0
  87. /package/template/{src → examples}/skills/tools/BasketTool.ts +0 -0
  88. /package/template/{src → examples}/skills/tools/CreateInlineJob.ts +0 -0
  89. /package/template/{src → examples}/skills/tools/CreatePostTool.ts +0 -0
  90. /package/template/{src → examples}/skills/tools/CustomDataTool.ts +0 -0
  91. /package/template/{src → examples}/skills/tools/GetWeatherTool.ts +0 -0
  92. /package/template/{src → examples}/skills/tools/PaymentTool.ts +0 -0
  93. /package/template/{src → examples}/skills/tools/ProductsTool.ts +0 -0
  94. /package/template/{src → examples}/skills/tools/SmartBasketTool.ts +0 -0
  95. /package/template/{src → examples}/skills/user.skill.ts +0 -0
  96. /package/template/{src → examples}/webhooks/PaymentWebhook.ts +0 -0
  97. /package/template/{src → examples}/webhooks/UserEventWebhook.ts +0 -0
@@ -0,0 +1,393 @@
1
+ /**
2
+ * MCP Command
3
+ * Manages Model Context Protocol (MCP) servers for agents
4
+ */
5
+ import { loadApiKey, checkApiKey } from '../services/auth.js';
6
+ import { readSkillConfig } from '../utils/files.js';
7
+ import { withErrorHandling, writeProgress, writeSuccess, writeInfo } from '../utils/cli.js';
8
+ import { BASE_URLS } from '../config/constants.js';
9
+ import { safePrompt } from '../utils/prompt-handler.js';
10
+ import { validateConfig, validateAgentConfig, } from '../utils/dev-helpers.js';
11
+ import DeveloperApi from '../api/developer.api.service.js';
12
+ /**
13
+ * Main MCP command - manages MCP servers
14
+ *
15
+ * Subcommands:
16
+ * - lua mcp list - List all MCP servers
17
+ * - lua mcp activate - Activate an MCP server
18
+ * - lua mcp deactivate - Deactivate an MCP server
19
+ * - lua mcp delete - Delete an MCP server
20
+ *
21
+ * @param action - Optional action ('list', 'activate', 'deactivate', 'delete')
22
+ * @param serverName - Optional server name for actions
23
+ * @returns Promise that resolves when command completes
24
+ */
25
+ export async function mcpCommand(action, serverName) {
26
+ return withErrorHandling(async () => {
27
+ // Step 1: Load configuration
28
+ const config = readSkillConfig();
29
+ validateConfig(config);
30
+ validateAgentConfig(config);
31
+ const agentId = config.agent.agentId;
32
+ // Step 2: Authenticate
33
+ const apiKey = await loadApiKey();
34
+ if (!apiKey) {
35
+ console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
36
+ process.exit(1);
37
+ }
38
+ await checkApiKey(apiKey);
39
+ writeProgress("✅ Authenticated");
40
+ const developerApi = new DeveloperApi(BASE_URLS.API, apiKey, agentId);
41
+ const context = {
42
+ agentId,
43
+ apiKey,
44
+ developerApi,
45
+ };
46
+ // Step 3: Handle action or show interactive menu
47
+ if (action) {
48
+ const normalizedAction = action.toLowerCase();
49
+ switch (normalizedAction) {
50
+ case 'list':
51
+ case 'ls':
52
+ await listMCPServers(context);
53
+ break;
54
+ case 'activate':
55
+ case 'enable':
56
+ await activateMCPServer(context, serverName);
57
+ break;
58
+ case 'deactivate':
59
+ case 'disable':
60
+ await deactivateMCPServer(context, serverName);
61
+ break;
62
+ case 'delete':
63
+ case 'rm':
64
+ await deleteMCPServer(context, serverName);
65
+ break;
66
+ default:
67
+ console.error(`❌ Unknown action: "${action}"`);
68
+ showUsage();
69
+ process.exit(1);
70
+ }
71
+ }
72
+ else {
73
+ // Interactive mode
74
+ await interactiveMCPManagement(context);
75
+ }
76
+ }, "mcp");
77
+ }
78
+ /**
79
+ * Show usage information
80
+ */
81
+ function showUsage() {
82
+ console.log('\nUsage:');
83
+ console.log(' lua mcp - Interactive MCP server management');
84
+ console.log(' lua mcp list - List all MCP servers');
85
+ console.log(' lua mcp activate [name] - Activate an MCP server');
86
+ console.log(' lua mcp deactivate [name] - Deactivate an MCP server');
87
+ console.log(' lua mcp delete [name] - Delete an MCP server');
88
+ console.log('\nAliases:');
89
+ console.log(' list → ls');
90
+ console.log(' activate → enable');
91
+ console.log(' deactivate → disable');
92
+ console.log(' delete → rm');
93
+ }
94
+ /**
95
+ * Interactive MCP management
96
+ */
97
+ async function interactiveMCPManagement(context) {
98
+ let continueManaging = true;
99
+ while (continueManaging) {
100
+ console.log("\n" + "=".repeat(60));
101
+ console.log("🔌 MCP Server Management");
102
+ console.log("=".repeat(60) + "\n");
103
+ const actionAnswer = await safePrompt([
104
+ {
105
+ type: 'list',
106
+ name: 'action',
107
+ message: 'What would you like to do?',
108
+ choices: [
109
+ { name: '📋 List MCP servers', value: 'list' },
110
+ { name: '✅ Activate a server', value: 'activate' },
111
+ { name: '⏸️ Deactivate a server', value: 'deactivate' },
112
+ { name: '🗑️ Delete a server', value: 'delete' },
113
+ { name: '❌ Exit', value: 'exit' }
114
+ ]
115
+ }
116
+ ]);
117
+ if (!actionAnswer)
118
+ return;
119
+ const { action } = actionAnswer;
120
+ switch (action) {
121
+ case 'list':
122
+ await listMCPServers(context);
123
+ break;
124
+ case 'activate':
125
+ await activateMCPServer(context);
126
+ break;
127
+ case 'deactivate':
128
+ await deactivateMCPServer(context);
129
+ break;
130
+ case 'delete':
131
+ await deleteMCPServer(context);
132
+ break;
133
+ case 'exit':
134
+ continueManaging = false;
135
+ console.log("\n👋 Goodbye!\n");
136
+ break;
137
+ }
138
+ }
139
+ }
140
+ /**
141
+ * List all MCP servers
142
+ */
143
+ async function listMCPServers(context) {
144
+ writeProgress("🔄 Loading MCP servers...");
145
+ try {
146
+ const result = await context.developerApi.getMCPServers();
147
+ if (!result.success) {
148
+ console.error(`\n❌ Failed to load MCP servers: ${result.error?.message}\n`);
149
+ return;
150
+ }
151
+ const servers = result.data || [];
152
+ console.log("\n" + "=".repeat(60));
153
+ console.log("🔌 MCP Servers");
154
+ console.log("=".repeat(60) + "\n");
155
+ if (servers.length === 0) {
156
+ console.log("ℹ️ No MCP servers found.");
157
+ console.log("💡 Define MCP servers in your LuaAgent configuration and run 'lua push all'.\n");
158
+ return;
159
+ }
160
+ // Separate active and inactive servers
161
+ const activeServers = servers.filter((s) => s.active);
162
+ const inactiveServers = servers.filter((s) => !s.active);
163
+ if (activeServers.length > 0) {
164
+ console.log("✅ Active Servers:\n");
165
+ activeServers.forEach((server) => {
166
+ printServerInfo(server);
167
+ });
168
+ }
169
+ if (inactiveServers.length > 0) {
170
+ if (activeServers.length > 0)
171
+ console.log("─".repeat(40) + "\n");
172
+ console.log("⏸️ Inactive Servers:\n");
173
+ inactiveServers.forEach((server) => {
174
+ printServerInfo(server);
175
+ });
176
+ }
177
+ console.log("=".repeat(60) + "\n");
178
+ }
179
+ catch (error) {
180
+ console.error('\n❌ Error loading MCP servers:', error.message);
181
+ }
182
+ }
183
+ /**
184
+ * Print server information
185
+ */
186
+ function printServerInfo(server) {
187
+ const statusIcon = server.active ? '🟢' : '⚪';
188
+ console.log(`${statusIcon} ${server.name}`);
189
+ console.log(` Transport: ${server.transport}`);
190
+ if (server.transport === 'stdio') {
191
+ console.log(` Command: ${server.command} ${(server.args || []).join(' ')}`);
192
+ }
193
+ else {
194
+ console.log(` URL: ${server.url}`);
195
+ }
196
+ console.log(` ID: ${server.id}`);
197
+ console.log();
198
+ }
199
+ /**
200
+ * Activate an MCP server
201
+ */
202
+ async function activateMCPServer(context, serverName) {
203
+ try {
204
+ // Get all servers
205
+ const result = await context.developerApi.getMCPServers();
206
+ if (!result.success) {
207
+ console.error(`\n❌ Failed to load MCP servers: ${result.error?.message}\n`);
208
+ return;
209
+ }
210
+ const servers = result.data || [];
211
+ const inactiveServers = servers.filter((s) => !s.active);
212
+ if (inactiveServers.length === 0) {
213
+ console.log("\nℹ️ All MCP servers are already active.\n");
214
+ return;
215
+ }
216
+ let serverToActivate;
217
+ if (serverName) {
218
+ // Find by name
219
+ const server = inactiveServers.find((s) => s.name.toLowerCase() === serverName.toLowerCase());
220
+ if (!server) {
221
+ console.error(`\n❌ Inactive MCP server "${serverName}" not found.\n`);
222
+ console.log("Available inactive servers:");
223
+ inactiveServers.forEach((s) => console.log(` - ${s.name}`));
224
+ return;
225
+ }
226
+ serverToActivate = server;
227
+ }
228
+ else {
229
+ // Prompt for selection
230
+ const answer = await safePrompt([
231
+ {
232
+ type: 'list',
233
+ name: 'server',
234
+ message: 'Select an MCP server to activate:',
235
+ choices: inactiveServers.map((s) => ({
236
+ name: `${s.name} (${s.transport})`,
237
+ value: s
238
+ }))
239
+ }
240
+ ]);
241
+ if (!answer)
242
+ return;
243
+ serverToActivate = answer.server;
244
+ }
245
+ writeProgress(`🔄 Activating ${serverToActivate.name}...`);
246
+ const activateResult = await context.developerApi.activateMCPServer(serverToActivate.id);
247
+ if (activateResult.success) {
248
+ writeSuccess(`\n✅ MCP server "${serverToActivate.name}" activated successfully!\n`);
249
+ writeInfo("💡 The server's tools are now available to your agent.");
250
+ }
251
+ else {
252
+ console.error(`\n❌ Failed to activate: ${activateResult.error?.message}\n`);
253
+ }
254
+ }
255
+ catch (error) {
256
+ console.error('\n❌ Error activating MCP server:', error.message);
257
+ }
258
+ }
259
+ /**
260
+ * Deactivate an MCP server
261
+ */
262
+ async function deactivateMCPServer(context, serverName) {
263
+ try {
264
+ // Get all servers
265
+ const result = await context.developerApi.getMCPServers();
266
+ if (!result.success) {
267
+ console.error(`\n❌ Failed to load MCP servers: ${result.error?.message}\n`);
268
+ return;
269
+ }
270
+ const servers = result.data || [];
271
+ const activeServers = servers.filter((s) => s.active);
272
+ if (activeServers.length === 0) {
273
+ console.log("\nℹ️ No active MCP servers to deactivate.\n");
274
+ return;
275
+ }
276
+ let serverToDeactivate;
277
+ if (serverName) {
278
+ // Find by name
279
+ const server = activeServers.find((s) => s.name.toLowerCase() === serverName.toLowerCase());
280
+ if (!server) {
281
+ console.error(`\n❌ Active MCP server "${serverName}" not found.\n`);
282
+ console.log("Available active servers:");
283
+ activeServers.forEach((s) => console.log(` - ${s.name}`));
284
+ return;
285
+ }
286
+ serverToDeactivate = server;
287
+ }
288
+ else {
289
+ // Prompt for selection
290
+ const answer = await safePrompt([
291
+ {
292
+ type: 'list',
293
+ name: 'server',
294
+ message: 'Select an MCP server to deactivate:',
295
+ choices: activeServers.map((s) => ({
296
+ name: `${s.name} (${s.transport})`,
297
+ value: s
298
+ }))
299
+ }
300
+ ]);
301
+ if (!answer)
302
+ return;
303
+ serverToDeactivate = answer.server;
304
+ }
305
+ writeProgress(`🔄 Deactivating ${serverToDeactivate.name}...`);
306
+ const deactivateResult = await context.developerApi.deactivateMCPServer(serverToDeactivate.id);
307
+ if (deactivateResult.success) {
308
+ writeSuccess(`\n✅ MCP server "${serverToDeactivate.name}" deactivated successfully!\n`);
309
+ writeInfo("💡 The server's tools are no longer available to your agent.");
310
+ }
311
+ else {
312
+ console.error(`\n❌ Failed to deactivate: ${deactivateResult.error?.message}\n`);
313
+ }
314
+ }
315
+ catch (error) {
316
+ console.error('\n❌ Error deactivating MCP server:', error.message);
317
+ }
318
+ }
319
+ /**
320
+ * Delete an MCP server
321
+ */
322
+ async function deleteMCPServer(context, serverName) {
323
+ try {
324
+ // Get all servers
325
+ const result = await context.developerApi.getMCPServers();
326
+ if (!result.success) {
327
+ console.error(`\n❌ Failed to load MCP servers: ${result.error?.message}\n`);
328
+ return;
329
+ }
330
+ const servers = result.data || [];
331
+ if (servers.length === 0) {
332
+ console.log("\nℹ️ No MCP servers to delete.\n");
333
+ return;
334
+ }
335
+ let serverToDelete;
336
+ if (serverName) {
337
+ // Find by name
338
+ const server = servers.find((s) => s.name.toLowerCase() === serverName.toLowerCase());
339
+ if (!server) {
340
+ console.error(`\n❌ MCP server "${serverName}" not found.\n`);
341
+ console.log("Available servers:");
342
+ servers.forEach((s) => console.log(` - ${s.name}`));
343
+ return;
344
+ }
345
+ serverToDelete = server;
346
+ }
347
+ else {
348
+ // Prompt for selection
349
+ const answer = await safePrompt([
350
+ {
351
+ type: 'list',
352
+ name: 'server',
353
+ message: 'Select an MCP server to delete:',
354
+ choices: servers.map((s) => ({
355
+ name: `${s.name} (${s.transport}) ${s.active ? '🟢' : '⚪'}`,
356
+ value: s
357
+ }))
358
+ }
359
+ ]);
360
+ if (!answer)
361
+ return;
362
+ serverToDelete = answer.server;
363
+ }
364
+ // Confirm deletion
365
+ console.log(`\n⚠️ You are about to delete MCP server: ${serverToDelete.name}`);
366
+ if (serverToDelete.active) {
367
+ console.log("⚠️ WARNING: This server is currently ACTIVE!");
368
+ }
369
+ const confirmAnswer = await safePrompt([
370
+ {
371
+ type: 'confirm',
372
+ name: 'confirm',
373
+ message: 'Are you sure you want to delete this MCP server?',
374
+ default: false
375
+ }
376
+ ]);
377
+ if (!confirmAnswer || !confirmAnswer.confirm) {
378
+ console.log("\n❌ Deletion cancelled.\n");
379
+ return;
380
+ }
381
+ writeProgress(`🔄 Deleting ${serverToDelete.name}...`);
382
+ const deleteResult = await context.developerApi.deleteMCPServer(serverToDelete.id);
383
+ if (deleteResult.success) {
384
+ writeSuccess(`\n✅ MCP server "${serverToDelete.name}" deleted successfully!\n`);
385
+ }
386
+ else {
387
+ console.error(`\n❌ Failed to delete: ${deleteResult.error?.message}\n`);
388
+ }
389
+ }
390
+ catch (error) {
391
+ console.error('\n❌ Error deleting MCP server:', error.message);
392
+ }
393
+ }
@@ -16,6 +16,7 @@ import { fetchVersions, publishVersion, } from '../utils/deploy-api.js';
16
16
  import { BASE_URLS } from '../config/constants.js';
17
17
  import PreProcessorApi from '../api/preprocessor.api.service.js';
18
18
  import PostProcessorApi from '../api/postprocessor.api.service.js';
19
+ import DeveloperApi from '../api/developer.api.service.js';
19
20
  /**
20
21
  * Main push command - pushes a skill or persona version to the server.
21
22
  *
@@ -57,8 +58,8 @@ export async function pushCommand(type, cmdObj) {
57
58
  // Step 1: Check if type was provided as argument
58
59
  if (type) {
59
60
  // Validate the provided type
60
- if (type !== 'skill' && type !== 'persona' && type !== 'webhook' && type !== 'job' && type !== 'preprocessor' && type !== 'postprocessor') {
61
- console.error(`❌ Invalid type: "${type}". Must be "skill", "persona", "webhook", "job", "preprocessor", "postprocessor", or "all".`);
61
+ if (type !== 'skill' && type !== 'persona' && type !== 'webhook' && type !== 'job' && type !== 'preprocessor' && type !== 'postprocessor' && type !== 'mcp') {
62
+ console.error(`❌ Invalid type: "${type}". Must be "skill", "persona", "webhook", "job", "preprocessor", "postprocessor", "mcp", or "all".`);
62
63
  console.log('\nUsage:');
63
64
  console.log(' lua push - Interactive selection');
64
65
  console.log(' lua push skill - Push a skill directly');
@@ -67,6 +68,7 @@ export async function pushCommand(type, cmdObj) {
67
68
  console.log(' lua push job - Push a job directly');
68
69
  console.log(' lua push preprocessor - Push a preprocessor directly');
69
70
  console.log(' lua push postprocessor - Push a postprocessor directly');
71
+ console.log(' lua push mcp - Push an MCP server directly');
70
72
  console.log(' lua push all --force - Push all components without prompts');
71
73
  process.exit(1);
72
74
  }
@@ -85,6 +87,7 @@ export async function pushCommand(type, cmdObj) {
85
87
  { name: '⏰ Job', value: 'job' },
86
88
  { name: '📥 PreProcessor', value: 'preprocessor' },
87
89
  { name: '📤 PostProcessor', value: 'postprocessor' },
90
+ { name: '🔌 MCP Server', value: 'mcp' },
88
91
  { name: '🌙 Persona', value: 'persona' }
89
92
  ]
90
93
  }
@@ -111,6 +114,9 @@ export async function pushCommand(type, cmdObj) {
111
114
  else if (selectedType === 'postprocessor') {
112
115
  await pushPostProcessorVersion();
113
116
  }
117
+ else if (selectedType === 'mcp') {
118
+ await pushMCPServerVersion();
119
+ }
114
120
  else {
115
121
  await pushPersonaVersion();
116
122
  }
@@ -133,8 +139,9 @@ export async function pushCommand(type, cmdObj) {
133
139
  */
134
140
  async function pushSkillVersion() {
135
141
  // Step 1: Validate configuration
136
- const config = readSkillConfig();
137
- validatePushConfig(config);
142
+ const yamlConfig = readSkillConfig();
143
+ validatePushConfig(yamlConfig);
144
+ const config = yamlConfig;
138
145
  // Step 2: Get available skills and prompt for selection
139
146
  const availableSkills = getAvailableSkills(config);
140
147
  if (availableSkills.length === 0) {
@@ -912,8 +919,7 @@ async function pushPostProcessorVersion() {
912
919
  description: bundledData.description || selected.description,
913
920
  postprocessorId: selected.postprocessorId,
914
921
  code: bundledData.code,
915
- executeFunction: bundledData.executeFunction,
916
- async: Boolean(bundledData.async ?? false) // Ensure boolean type
922
+ executeFunction: bundledData.executeFunction
917
923
  };
918
924
  writeProgress(`\n🚀 Pushing ${selected.name} v${confirmedVersion}...`);
919
925
  const api = new PostProcessorApi(BASE_URLS.API, apiKey, config.agent.agentId);
@@ -1001,6 +1007,120 @@ function updateProcessorVersionInYaml(processorType, processorName, newVersion)
1001
1007
  console.warn('⚠️ Could not update processor version in YAML:', error);
1002
1008
  }
1003
1009
  }
1010
+ /**
1011
+ * Push MCP Server to the server
1012
+ */
1013
+ async function pushMCPServerVersion() {
1014
+ try {
1015
+ // Step 1: Run compilation
1016
+ writeProgress("📦 Compiling project...");
1017
+ await compileCommand();
1018
+ writeSuccess("✅ Compilation complete");
1019
+ // Step 2: Authenticate
1020
+ const apiKey = await loadApiKey();
1021
+ if (!apiKey) {
1022
+ console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
1023
+ process.exit(1);
1024
+ }
1025
+ await checkApiKey(apiKey);
1026
+ writeSuccess("✅ Authentication verified");
1027
+ // Step 3: Read configuration
1028
+ const config = readSkillConfig();
1029
+ if (!config?.agent?.agentId) {
1030
+ console.error("❌ No agent ID found in lua.skill.yaml. Please run 'lua init' first.");
1031
+ process.exit(1);
1032
+ }
1033
+ const mcpServers = config.mcpServers || [];
1034
+ if (mcpServers.length === 0) {
1035
+ console.error("❌ No MCP servers found in lua.skill.yaml.");
1036
+ console.log("💡 Make sure you have defined MCP servers in your LuaAgent configuration.");
1037
+ process.exit(1);
1038
+ }
1039
+ // Step 4: Load bundled MCP server data first (has full config)
1040
+ const bundledServersPath = path.join(process.cwd(), 'dist', 'mcp-servers.json');
1041
+ let bundledServers = [];
1042
+ if (fs.existsSync(bundledServersPath)) {
1043
+ bundledServers = JSON.parse(fs.readFileSync(bundledServersPath, 'utf8'));
1044
+ }
1045
+ else {
1046
+ console.error('❌ Bundled MCP server data not found.');
1047
+ console.log("💡 Please ensure your MCP servers are properly compiled.");
1048
+ process.exit(1);
1049
+ }
1050
+ // Step 5: Select MCP server to push (use bundled data for display, YAML for ID tracking)
1051
+ const serverAnswer = await safePrompt([
1052
+ {
1053
+ type: 'list',
1054
+ name: 'selectedServer',
1055
+ message: 'Select an MCP server to push:',
1056
+ choices: bundledServers.map((server) => {
1057
+ const yamlEntry = mcpServers.find((s) => s.name === server.name);
1058
+ return {
1059
+ name: `${server.name} (${server.transport})`,
1060
+ value: { ...server, mcpServerId: yamlEntry?.mcpServerId }
1061
+ };
1062
+ })
1063
+ }
1064
+ ]);
1065
+ if (!serverAnswer) {
1066
+ console.log("Push cancelled.");
1067
+ return;
1068
+ }
1069
+ const selectedServer = serverAnswer.selectedServer;
1070
+ const bundledServerData = selectedServer;
1071
+ // Step 6: Prepare server data for push
1072
+ const serverData = {
1073
+ name: bundledServerData.name,
1074
+ transport: bundledServerData.transport,
1075
+ timeout: bundledServerData.timeout,
1076
+ ...(bundledServerData.transport === 'stdio' ? {
1077
+ command: bundledServerData.command,
1078
+ args: bundledServerData.args,
1079
+ env: bundledServerData.env
1080
+ } : {
1081
+ url: bundledServerData.url,
1082
+ headers: bundledServerData.headers
1083
+ })
1084
+ };
1085
+ // Step 7: Push to server (upsert)
1086
+ writeProgress(`\n🚀 Pushing MCP server "${selectedServer.name}" to server...`);
1087
+ const developerApi = new DeveloperApi(BASE_URLS.API, apiKey, config.agent.agentId);
1088
+ const result = await developerApi.upsertMCPServer(serverData);
1089
+ if (result.success && result.data) {
1090
+ writeSuccess(`\n✅ MCP server "${selectedServer.name}" pushed successfully\n`);
1091
+ // Ask if user wants to activate now
1092
+ const activateAnswer = await safePrompt([
1093
+ {
1094
+ type: 'confirm',
1095
+ name: 'activateNow',
1096
+ message: 'Would you like to activate this MCP server now?',
1097
+ default: false
1098
+ }
1099
+ ]);
1100
+ if (activateAnswer && activateAnswer.activateNow) {
1101
+ writeProgress("🔄 Activating MCP server...");
1102
+ const activateResult = await developerApi.activateMCPServer(result.data.id);
1103
+ if (activateResult.success) {
1104
+ writeSuccess(`\n✅ MCP server "${selectedServer.name}" activated successfully\n`);
1105
+ writeInfo("💡 The server's tools are now available to your agent.");
1106
+ }
1107
+ else {
1108
+ console.error(`❌ Failed to activate: ${activateResult.error?.message}`);
1109
+ }
1110
+ }
1111
+ else {
1112
+ writeInfo("💡 You can activate this server later using: lua mcp activate");
1113
+ }
1114
+ }
1115
+ else {
1116
+ console.error(`❌ Failed to push: ${result.error?.message}`);
1117
+ }
1118
+ }
1119
+ catch (error) {
1120
+ console.error('❌ Error pushing MCP server:', error);
1121
+ process.exit(1);
1122
+ }
1123
+ }
1004
1124
  /**
1005
1125
  * Deploy a version immediately after pushing
1006
1126
  */
@@ -1189,7 +1309,7 @@ async function pushAllCommand(options) {
1189
1309
  const pushData = {
1190
1310
  name: webhookConfig.name,
1191
1311
  version: newVersion,
1192
- description: webhookData.description || webhookConfig.description || '',
1312
+ description: webhookData.description || '',
1193
1313
  webhookId: webhookConfig.webhookId,
1194
1314
  querySchema: webhookData.querySchema,
1195
1315
  headerSchema: webhookData.headerSchema,
@@ -1249,14 +1369,14 @@ async function pushAllCommand(options) {
1249
1369
  const pushData = {
1250
1370
  name: jobConfig.name,
1251
1371
  version: newVersion,
1252
- description: jobData.description || jobConfig.description || '',
1372
+ description: jobData.description || '',
1253
1373
  jobId: jobConfig.jobId,
1254
1374
  schedule: jobData.schedule || jobConfig.schedule,
1255
1375
  timeout: jobData.timeout,
1256
1376
  retry: jobData.retry,
1257
1377
  code: jobData.code,
1258
1378
  executeFunction: jobData.executeFunction,
1259
- metadata: jobData.metadata || jobConfig.metadata
1379
+ metadata: jobData.metadata
1260
1380
  };
1261
1381
  // Push version using fetch
1262
1382
  const response = await fetch(`${BASE_URLS.API}/developer/jobs/${agentId}/${jobConfig.jobId}/version`, {
@@ -1313,7 +1433,7 @@ async function pushAllCommand(options) {
1313
1433
  const versionData = {
1314
1434
  name: processorConfig.name,
1315
1435
  version: newVersion,
1316
- description: processorData.description || processorConfig.description || '',
1436
+ description: processorData.description || '',
1317
1437
  preprocessorId: preprocessorId,
1318
1438
  code: processorData.code,
1319
1439
  executeFunction: processorData.executeFunction,
@@ -1367,11 +1487,10 @@ async function pushAllCommand(options) {
1367
1487
  const versionData = {
1368
1488
  name: processorConfig.name,
1369
1489
  version: newVersion,
1370
- description: processorData.description || processorConfig.description || '',
1490
+ description: processorData.description || '',
1371
1491
  postprocessorId: postprocessorId,
1372
1492
  code: processorData.code,
1373
- executeFunction: processorData.executeFunction,
1374
- async: Boolean(processorData.async ?? false)
1493
+ executeFunction: processorData.executeFunction
1375
1494
  };
1376
1495
  // Push version
1377
1496
  const result = await postprocessorService.pushPostProcessor(postprocessorId, versionData);
@@ -1392,7 +1511,46 @@ async function pushAllCommand(options) {
1392
1511
  }
1393
1512
  }
1394
1513
  }
1395
- // Step 9: Deploy all components if autoDeploy is enabled
1514
+ // Step 9: Push MCP server configurations
1515
+ const mcpServersJsonPath = path.join(process.cwd(), 'dist', 'mcp-servers.json');
1516
+ if (fs.existsSync(mcpServersJsonPath)) {
1517
+ const mcpServers = JSON.parse(fs.readFileSync(mcpServersJsonPath, 'utf8'));
1518
+ if (mcpServers.length > 0) {
1519
+ writeProgress(`\n🔌 Pushing ${mcpServers.length} MCP server(s)...`);
1520
+ try {
1521
+ const DeveloperApi = (await import('../api/developer.api.service.js')).default;
1522
+ const developerApi = new DeveloperApi(BASE_URLS.API, apiKey, agentId);
1523
+ for (const serverConfig of mcpServers) {
1524
+ try {
1525
+ // Upsert the MCP server (create or update by name)
1526
+ const result = await developerApi.upsertMCPServer(serverConfig);
1527
+ if (result.success && result.data) {
1528
+ const mcpServerId = result.data.id;
1529
+ const isActive = result.data.active;
1530
+ writeSuccess(` ✅ ${serverConfig.name} (${serverConfig.transport}) - ${isActive ? 'active' : 'inactive'}`);
1531
+ // Auto-activate if autoDeploy is enabled
1532
+ if (options.autoDeploy && !isActive) {
1533
+ const activateResult = await developerApi.activateMCPServer(mcpServerId);
1534
+ if (activateResult.success) {
1535
+ writeSuccess(` 🔌 Auto-activated`);
1536
+ }
1537
+ }
1538
+ }
1539
+ else {
1540
+ console.error(` ❌ Failed to push ${serverConfig.name}:`, result.error?.message);
1541
+ }
1542
+ }
1543
+ catch (error) {
1544
+ console.error(` ❌ Failed to push ${serverConfig.name}:`, error.message);
1545
+ }
1546
+ }
1547
+ }
1548
+ catch (error) {
1549
+ console.error(` ❌ Failed to push MCP servers:`, error.message);
1550
+ }
1551
+ }
1552
+ }
1553
+ // Step 10: Deploy all components if autoDeploy is enabled
1396
1554
  if (options.autoDeploy && (toDeploySkills.length > 0 || toDeployWebhooks.length > 0 || toDeployJobs.length > 0 || toDeployPreprocessors.length > 0 || toDeployPostprocessors.length > 0)) {
1397
1555
  writeProgress('\n🚀 Deploying all pushed versions to production...');
1398
1556
  writeInfo('⏱️ Waiting for server to process versions (5 seconds)...\n');
@@ -32,7 +32,7 @@ export default class DataEntryInstance {
32
32
  * @returns Promise resolving to the updated data
33
33
  * @throws Error if the update fails
34
34
  */
35
- update(data: Record<string, any>, searchText?: string): Promise<any>;
35
+ update(data: Record<string, any>, searchText?: string): Promise<Record<string, any>>;
36
36
  /**
37
37
  * Deletes the custom data entry
38
38
  * @returns Promise resolving to true if deletion was successful