sequentum-mcp 1.0.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/CHANGELOG.md +47 -0
- package/LICENSE +21 -0
- package/README.md +191 -0
- package/dist/api-client.d.ts +185 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +476 -0
- package/dist/api-client.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1172 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +417 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +91 -0
- package/dist/types.js.map +1 -0
- package/docs/tool-reference.md +782 -0
- package/docs/troubleshooting.md +313 -0
- package/package.json +63 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1172 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Sequentum MCP Server
|
|
4
|
+
*
|
|
5
|
+
* A Model Context Protocol (MCP) server that enables AI assistants to interact
|
|
6
|
+
* with the Sequentum web scraping platform.
|
|
7
|
+
*
|
|
8
|
+
* Environment Variables:
|
|
9
|
+
* SEQUENTUM_API_URL - The base URL of the Sequentum API (required)
|
|
10
|
+
* SEQUENTUM_API_KEY - Your API key (required, format: sk-...)
|
|
11
|
+
*/
|
|
12
|
+
import { createRequire } from "module";
|
|
13
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
14
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
15
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
16
|
+
import { SequentumApiClient } from "./api-client.js";
|
|
17
|
+
// Import version from package.json
|
|
18
|
+
const require = createRequire(import.meta.url);
|
|
19
|
+
const { version } = require("../package.json");
|
|
20
|
+
// Configuration from environment variables
|
|
21
|
+
const DEFAULT_API_URL = "https://dashboard.sequentum.com";
|
|
22
|
+
const API_BASE_URL = process.env.SEQUENTUM_API_URL || DEFAULT_API_URL;
|
|
23
|
+
const API_KEY = process.env.SEQUENTUM_API_KEY;
|
|
24
|
+
const DEBUG = process.env.DEBUG === '1';
|
|
25
|
+
// Debug: Log environment configuration (only when DEBUG=1)
|
|
26
|
+
if (DEBUG) {
|
|
27
|
+
console.error(`[DEBUG] API_BASE_URL = ${API_BASE_URL}${!process.env.SEQUENTUM_API_URL ? ' (default)' : ''}`);
|
|
28
|
+
}
|
|
29
|
+
if (!API_KEY) {
|
|
30
|
+
console.error("Error: SEQUENTUM_API_KEY environment variable is required");
|
|
31
|
+
console.error("Please set your API key (format: sk-...)");
|
|
32
|
+
console.error("\nExample:");
|
|
33
|
+
console.error(' export SEQUENTUM_API_KEY="sk-your-api-key-here"');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
const client = new SequentumApiClient(API_BASE_URL, API_KEY);
|
|
37
|
+
// ==========================================
|
|
38
|
+
// Input Validation Helpers
|
|
39
|
+
// ==========================================
|
|
40
|
+
function validateNumber(args, field, required = true) {
|
|
41
|
+
const value = args[field];
|
|
42
|
+
if (value === undefined || value === null) {
|
|
43
|
+
if (required) {
|
|
44
|
+
throw new Error(`Missing required parameter: ${field}`);
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
49
|
+
throw new Error(`Invalid parameter '${field}': expected a number, got ${typeof value}`);
|
|
50
|
+
}
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
function validateString(args, field, required = true) {
|
|
54
|
+
const value = args[field];
|
|
55
|
+
if (value === undefined || value === null) {
|
|
56
|
+
if (required) {
|
|
57
|
+
throw new Error(`Missing required parameter: ${field}`);
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
if (typeof value !== "string") {
|
|
62
|
+
throw new Error(`Invalid parameter '${field}': expected a string, got ${typeof value}`);
|
|
63
|
+
}
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
function validateBoolean(args, field, required = true) {
|
|
67
|
+
const value = args[field];
|
|
68
|
+
if (value === undefined || value === null) {
|
|
69
|
+
if (required) {
|
|
70
|
+
throw new Error(`Missing required parameter: ${field}`);
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
if (typeof value !== "boolean") {
|
|
75
|
+
throw new Error(`Invalid parameter '${field}': expected a boolean, got ${typeof value}`);
|
|
76
|
+
}
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
// ==========================================
|
|
80
|
+
// Response Helpers
|
|
81
|
+
// ==========================================
|
|
82
|
+
/**
|
|
83
|
+
* Map RunStatus numeric value to human-readable string
|
|
84
|
+
*/
|
|
85
|
+
function getRunStatusLabel(status) {
|
|
86
|
+
const statusMap = {
|
|
87
|
+
0: "Invalid",
|
|
88
|
+
1: "Running",
|
|
89
|
+
2: "Exporting",
|
|
90
|
+
3: "Starting",
|
|
91
|
+
4: "Queuing",
|
|
92
|
+
5: "Stopping",
|
|
93
|
+
6: "Failure",
|
|
94
|
+
7: "Failed",
|
|
95
|
+
8: "Stopped",
|
|
96
|
+
9: "Completed",
|
|
97
|
+
10: "Success",
|
|
98
|
+
11: "Skipped",
|
|
99
|
+
12: "Waiting",
|
|
100
|
+
};
|
|
101
|
+
if (status === undefined || status === null) {
|
|
102
|
+
return "Never Run";
|
|
103
|
+
}
|
|
104
|
+
return statusMap[status] ?? `Unknown (${status})`;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Transform agent list to summary format for display
|
|
108
|
+
*/
|
|
109
|
+
function summarizeAgents(agents) {
|
|
110
|
+
return agents.map((a) => ({
|
|
111
|
+
id: a.id,
|
|
112
|
+
name: a.name,
|
|
113
|
+
description: a.description,
|
|
114
|
+
status: getRunStatusLabel(a.status),
|
|
115
|
+
configType: a.configType,
|
|
116
|
+
version: a.version,
|
|
117
|
+
lastActivity: a.lastActivity,
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
// ==========================================
|
|
121
|
+
// Tool Definitions
|
|
122
|
+
// ==========================================
|
|
123
|
+
const tools = [
|
|
124
|
+
// Agent Tools
|
|
125
|
+
{
|
|
126
|
+
name: "list_agents",
|
|
127
|
+
description: "List web scraping agents with IDs, names, status, and configuration. " +
|
|
128
|
+
"USE THIS FIRST to discover available agents before running or managing them. " +
|
|
129
|
+
"Answers: 'What agents do I have?', 'Show me my scrapers', 'List all completed agents'. " +
|
|
130
|
+
"Returns: Array of agent summaries with id, name, status (last run status), configType, version, lastActivity. " +
|
|
131
|
+
"Pagination always applied (defaults: pageIndex=1, recordsPerPage=50). " +
|
|
132
|
+
"TIP: Use 'search' param to find agents by name, or 'status' to filter by last run status (Completed, Failed, etc.).",
|
|
133
|
+
inputSchema: {
|
|
134
|
+
type: "object",
|
|
135
|
+
properties: {
|
|
136
|
+
status: {
|
|
137
|
+
type: "number",
|
|
138
|
+
enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
|
139
|
+
description: "Filter by last run status: 0=Invalid, 1=Running, 2=Exporting, 3=Starting, 4=Queuing, 5=Stopping, 6=Failure, 7=Failed, 8=Stopped, 9=Completed, 10=Success, 11=Skipped, 12=Waiting. Agents that never ran have null status.",
|
|
140
|
+
},
|
|
141
|
+
spaceId: {
|
|
142
|
+
type: "number",
|
|
143
|
+
description: "Filter by space ID. Use list_spaces first to find space IDs.",
|
|
144
|
+
},
|
|
145
|
+
search: {
|
|
146
|
+
type: "string",
|
|
147
|
+
description: "Search by agent name (case-insensitive partial match). Example: 'amazon' finds 'Amazon Product Scraper'.",
|
|
148
|
+
},
|
|
149
|
+
configType: {
|
|
150
|
+
type: "string",
|
|
151
|
+
enum: ["Agent", "Command", "Api", "Shared"],
|
|
152
|
+
description: "Filter by type. 'Agent' = web scrapers, 'Command' = data inputs, 'Api' = API configs, 'Shared' = reusable components.",
|
|
153
|
+
},
|
|
154
|
+
sortColumn: {
|
|
155
|
+
type: "string",
|
|
156
|
+
enum: ["name", "lastActivity", "created", "updated", "status", "configType"],
|
|
157
|
+
description: "Column to sort by. 'lastActivity' shows recently run agents first (with sortOrder=1).",
|
|
158
|
+
},
|
|
159
|
+
sortOrder: {
|
|
160
|
+
type: "string",
|
|
161
|
+
enum: ["asc", "desc"],
|
|
162
|
+
description: "Sort direction. 'desc' = newest/Z first (descending), 'asc' = oldest/A first (ascending, default).",
|
|
163
|
+
},
|
|
164
|
+
pageIndex: {
|
|
165
|
+
type: "number",
|
|
166
|
+
description: "Page number (1-based). Defaults to 1. Use with recordsPerPage to paginate large result sets.",
|
|
167
|
+
},
|
|
168
|
+
recordsPerPage: {
|
|
169
|
+
type: "number",
|
|
170
|
+
description: "Results per page. Defaults to 50. Max recommended: 100.",
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
required: [],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: "get_agent",
|
|
178
|
+
description: "Get detailed information about a specific agent including its configuration, input parameters, and documentation. " +
|
|
179
|
+
"USE AFTER list_agents or search_agents when you need full details for a specific agent. " +
|
|
180
|
+
"Answers: 'Tell me about agent X', 'What parameters does this agent need?', 'Show agent configuration'. " +
|
|
181
|
+
"Returns: Full agent details including inputParameters (what inputs the agent accepts), description, documentation, startUrl. " +
|
|
182
|
+
"REQUIRED: You must have the agentId first (get it from list_agents or search_agents).",
|
|
183
|
+
inputSchema: {
|
|
184
|
+
type: "object",
|
|
185
|
+
properties: {
|
|
186
|
+
agentId: { type: "number", description: "The unique ID of the agent. Get this from list_agents or search_agents." },
|
|
187
|
+
},
|
|
188
|
+
required: ["agentId"],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: "search_agents",
|
|
193
|
+
description: "Search for agents by name or description (case-insensitive partial match). " +
|
|
194
|
+
"FASTER than list_agents when user mentions a specific agent name. " +
|
|
195
|
+
"Answers: 'Find the Amazon scraper', 'Which agent handles product data?', 'Search for pricing agents'. " +
|
|
196
|
+
"Returns: Matching agents with id, name, status, configType. " +
|
|
197
|
+
"TIP: Prefer this over list_agents when user mentions an agent by name.",
|
|
198
|
+
inputSchema: {
|
|
199
|
+
type: "object",
|
|
200
|
+
properties: {
|
|
201
|
+
query: { type: "string", description: "Search term to match against agent names and descriptions. Case-insensitive." },
|
|
202
|
+
maxRecords: { type: "number", description: "Maximum results to return. Default: 50, Max: 1000." },
|
|
203
|
+
},
|
|
204
|
+
required: ["query"],
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
// Run Tools
|
|
208
|
+
{
|
|
209
|
+
name: "get_agent_runs",
|
|
210
|
+
description: "Get execution history for an agent showing past runs with status, timing, and records extracted. " +
|
|
211
|
+
"Answers: 'When did agent X last run?', 'Show run history', 'How many records were extracted?', 'Did the agent fail?'. " +
|
|
212
|
+
"Returns: Array of runs with id, status (Running/Completed/Failed/etc), startTime, endTime, recordsExtracted, recordsExported, errorMessage. " +
|
|
213
|
+
"TIP: Check the most recent run's status to see if agent is currently running or recently completed. " +
|
|
214
|
+
"NEXT STEP: Use get_run_files to see output files from a completed run.",
|
|
215
|
+
inputSchema: {
|
|
216
|
+
type: "object",
|
|
217
|
+
properties: {
|
|
218
|
+
agentId: { type: "number", description: "The unique ID of the agent. Get this from list_agents or search_agents." },
|
|
219
|
+
maxRecords: { type: "number", description: "Maximum number of runs to return. Default: 50. Use smaller values for faster response." },
|
|
220
|
+
},
|
|
221
|
+
required: ["agentId"],
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: "get_run_status",
|
|
226
|
+
description: "Get the current status of a specific run. FASTER than get_agent_runs when you only need one run's status. " +
|
|
227
|
+
"Answers: 'Is run 123 still running?', 'Did that run complete?', 'Check run status'. " +
|
|
228
|
+
"Returns: Single run with status, timing, records extracted. " +
|
|
229
|
+
"USE AFTER start_agent to monitor a run you just started. " +
|
|
230
|
+
"Status values: Running, Completed, Failed, CompletedWithErrors, Stopped, Queued.",
|
|
231
|
+
inputSchema: {
|
|
232
|
+
type: "object",
|
|
233
|
+
properties: {
|
|
234
|
+
agentId: { type: "number", description: "The unique ID of the agent." },
|
|
235
|
+
runId: { type: "number", description: "The run ID returned by start_agent or found in get_agent_runs." },
|
|
236
|
+
},
|
|
237
|
+
required: ["agentId", "runId"],
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: "start_agent",
|
|
242
|
+
description: "Start a web scraping agent execution. Two modes available: " +
|
|
243
|
+
"(1) ASYNC (default): Returns immediately with runId - use get_run_status to monitor progress. " +
|
|
244
|
+
"(2) SYNC: Set isRunSynchronously=true to wait and get scraped data directly (best for quick agents <60s). " +
|
|
245
|
+
"Answers: 'Run agent X', 'Start the scraper', 'Execute the Amazon agent', 'Scrape this website'. " +
|
|
246
|
+
"Returns: In async mode: {runId, status}. In sync mode: Scraped data directly as JSON/text. " +
|
|
247
|
+
"REQUIRED: Get agentId first using list_agents or search_agents. " +
|
|
248
|
+
"TIP: Use get_agent first to check what inputParameters the agent accepts before running.",
|
|
249
|
+
inputSchema: {
|
|
250
|
+
type: "object",
|
|
251
|
+
properties: {
|
|
252
|
+
agentId: { type: "number", description: "The unique ID of the agent to run. Get this from list_agents or search_agents." },
|
|
253
|
+
inputParameters: { type: "string", description: "JSON string of input parameters. Check agent's inputParameters with get_agent to see what's accepted. Example: '{\"url\": \"https://example.com\"}'" },
|
|
254
|
+
isRunSynchronously: { type: "boolean", description: "If true, wait for completion and return scraped data. If false (default), return immediately with runId. Use true only for quick agents." },
|
|
255
|
+
timeout: { type: "number", description: "Timeout in seconds for synchronous runs. Only used when isRunSynchronously=true. Default: 60." },
|
|
256
|
+
parallelism: { type: "number", description: "Number of parallel instances. Default: 1. Cannot be >1 when isRunSynchronously=true." },
|
|
257
|
+
},
|
|
258
|
+
required: ["agentId"],
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: "stop_agent",
|
|
263
|
+
description: "Stop a running agent execution immediately. Use to cancel runs that are taking too long or no longer needed. " +
|
|
264
|
+
"Answers: 'Stop that run', 'Cancel the scraper', 'Abort agent X', 'Kill the running job'. " +
|
|
265
|
+
"REQUIRED: You need both agentId and runId. Get runId from start_agent response or get_agent_runs.",
|
|
266
|
+
inputSchema: {
|
|
267
|
+
type: "object",
|
|
268
|
+
properties: {
|
|
269
|
+
agentId: { type: "number", description: "The unique ID of the agent." },
|
|
270
|
+
runId: { type: "number", description: "The run ID to stop. Get this from start_agent response or get_agent_runs." },
|
|
271
|
+
},
|
|
272
|
+
required: ["agentId", "runId"],
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
// File Tools
|
|
276
|
+
{
|
|
277
|
+
name: "get_run_files",
|
|
278
|
+
description: "List all output files generated by a completed run. Files contain scraped data in formats like CSV, JSON, Excel. " +
|
|
279
|
+
"Answers: 'What files did the run produce?', 'Show output files', 'Where is the scraped data?', 'Download results'. " +
|
|
280
|
+
"Returns: Array of files with id, name, fileType, fileSize, created. " +
|
|
281
|
+
"USE AFTER a run completes (status=Completed) to see available downloads. " +
|
|
282
|
+
"NEXT STEP: Use get_file_download_url with a fileId to get the actual download link.",
|
|
283
|
+
inputSchema: {
|
|
284
|
+
type: "object",
|
|
285
|
+
properties: {
|
|
286
|
+
agentId: { type: "number", description: "The unique ID of the agent." },
|
|
287
|
+
runId: { type: "number", description: "The run ID. Get this from get_agent_runs or start_agent response." },
|
|
288
|
+
},
|
|
289
|
+
required: ["agentId", "runId"],
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
name: "get_file_download_url",
|
|
294
|
+
description: "Get a temporary download URL for a specific output file. The URL expires after a short time. " +
|
|
295
|
+
"Answers: 'Download the CSV file', 'Get the output data', 'Give me the file link'. " +
|
|
296
|
+
"Returns: Temporary URL that can be used to download the file directly. " +
|
|
297
|
+
"REQUIRED: Get fileId first from get_run_files. " +
|
|
298
|
+
"TIP: Share the URL with the user so they can download the file.",
|
|
299
|
+
inputSchema: {
|
|
300
|
+
type: "object",
|
|
301
|
+
properties: {
|
|
302
|
+
agentId: { type: "number", description: "The unique ID of the agent." },
|
|
303
|
+
runId: { type: "number", description: "The run ID." },
|
|
304
|
+
fileId: { type: "number", description: "The file ID from get_run_files response." },
|
|
305
|
+
},
|
|
306
|
+
required: ["agentId", "runId", "fileId"],
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
// Version Tools
|
|
310
|
+
{
|
|
311
|
+
name: "get_agent_versions",
|
|
312
|
+
description: "List all saved versions of an agent's configuration. Use for reviewing change history or finding a version to restore. " +
|
|
313
|
+
"Answers: 'Show agent version history', 'What changes were made?', 'List previous versions'. " +
|
|
314
|
+
"Returns: Array of versions with version number, userName (who made the change), created date, comments, fileSize. " +
|
|
315
|
+
"NEXT STEP: Use restore_agent_version to roll back to a previous version if needed.",
|
|
316
|
+
inputSchema: {
|
|
317
|
+
type: "object",
|
|
318
|
+
properties: {
|
|
319
|
+
agentId: { type: "number", description: "The unique ID of the agent." },
|
|
320
|
+
},
|
|
321
|
+
required: ["agentId"],
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
name: "restore_agent_version",
|
|
326
|
+
description: "Restore an agent to a previous version. This creates a NEW version based on the restored configuration. " +
|
|
327
|
+
"Answers: 'Roll back agent to version X', 'Undo agent changes', 'Restore previous configuration'. " +
|
|
328
|
+
"WARNING: This modifies the agent. Use get_agent_versions first to find the correct version number. " +
|
|
329
|
+
"REQUIRED: Provide a reason in 'comments' explaining why the restore is needed.",
|
|
330
|
+
inputSchema: {
|
|
331
|
+
type: "object",
|
|
332
|
+
properties: {
|
|
333
|
+
agentId: { type: "number", description: "The unique ID of the agent." },
|
|
334
|
+
versionNumber: { type: "number", description: "The version number to restore to. Get this from get_agent_versions." },
|
|
335
|
+
comments: { type: "string", description: "Explanation for why this version is being restored. Will be recorded in version history." },
|
|
336
|
+
},
|
|
337
|
+
required: ["agentId", "versionNumber", "comments"],
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
// Schedule Tools
|
|
341
|
+
{
|
|
342
|
+
name: "list_agent_schedules",
|
|
343
|
+
description: "List all scheduled tasks for a specific agent. Shows when the agent is configured to run automatically. " +
|
|
344
|
+
"Answers: 'When does this agent run?', 'Show schedules for agent X', 'Is this agent scheduled?'. " +
|
|
345
|
+
"Returns: Array of schedules with id, name, cronExpression/schedule, nextRunTime, isEnabled, timezone. " +
|
|
346
|
+
"TIP: Check isEnabled to see if the schedule is active.",
|
|
347
|
+
inputSchema: {
|
|
348
|
+
type: "object",
|
|
349
|
+
properties: {
|
|
350
|
+
agentId: { type: "number", description: "The unique ID of the agent." },
|
|
351
|
+
},
|
|
352
|
+
required: ["agentId"],
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
name: "create_agent_schedule",
|
|
357
|
+
description: "Create a schedule for an agent. Use scheduleType: 1=RunOnce, 2=RunEvery, 3=CRON. " +
|
|
358
|
+
"RunOnce: requires startTime (ISO 8601 UTC, >=1min in future). " +
|
|
359
|
+
"RunEvery: uses runEveryCount + runEveryPeriod (0=min,1=hr,2=day,3=wk,4=mo); optional startTime for first run. " +
|
|
360
|
+
"CRON: uses cronExpression ('min hr day mo wkday'). " +
|
|
361
|
+
"TIP: Specify timezone for local time.",
|
|
362
|
+
inputSchema: {
|
|
363
|
+
type: "object",
|
|
364
|
+
properties: {
|
|
365
|
+
agentId: { type: "number", description: "Agent ID to schedule." },
|
|
366
|
+
name: { type: "string", description: "Schedule name." },
|
|
367
|
+
scheduleType: {
|
|
368
|
+
type: "number",
|
|
369
|
+
enum: [1, 2, 3],
|
|
370
|
+
description: "1=RunOnce, 2=RunEvery, 3=CRON (default)."
|
|
371
|
+
},
|
|
372
|
+
startTime: { type: "string", description: "ISO 8601 UTC datetime. Required for RunOnce (>=1min future). Optional for RunEvery (first run time). Not used for CRON." },
|
|
373
|
+
cronExpression: { type: "string", description: "For CRON: 'min hr day mo wkday'. Example: '0 9 * * 1,4' = Mon/Thu 9am." },
|
|
374
|
+
runEveryCount: { type: "number", description: "For RunEvery: interval count." },
|
|
375
|
+
runEveryPeriod: {
|
|
376
|
+
type: "number",
|
|
377
|
+
enum: [0, 1, 2, 3, 4],
|
|
378
|
+
description: "For RunEvery: 0=min, 1=hr, 2=day, 3=wk, 4=mo."
|
|
379
|
+
},
|
|
380
|
+
timezone: { type: "string", description: "Timezone (e.g., 'America/New_York'). Default: UTC." },
|
|
381
|
+
inputParameters: { type: "string", description: "JSON input parameters for runs." },
|
|
382
|
+
isEnabled: { type: "boolean", description: "Active schedule. Default: true." },
|
|
383
|
+
parallelism: { type: "number", description: "Parallel instances. Default: 1." },
|
|
384
|
+
},
|
|
385
|
+
required: ["agentId", "name"],
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
name: "delete_agent_schedule",
|
|
390
|
+
description: "Remove a schedule from an agent. The agent will no longer run automatically on this schedule. " +
|
|
391
|
+
"Answers: 'Stop the scheduled runs', 'Remove the Monday schedule', 'Delete schedule X'. " +
|
|
392
|
+
"WARNING: This permanently deletes the schedule. Use list_agent_schedules first to find the scheduleId.",
|
|
393
|
+
inputSchema: {
|
|
394
|
+
type: "object",
|
|
395
|
+
properties: {
|
|
396
|
+
agentId: { type: "number", description: "The unique ID of the agent." },
|
|
397
|
+
scheduleId: { type: "number", description: "The schedule ID to delete. Get this from list_agent_schedules." },
|
|
398
|
+
},
|
|
399
|
+
required: ["agentId", "scheduleId"],
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
name: "get_scheduled_runs",
|
|
404
|
+
description: "Get all upcoming scheduled runs across all agents in a date range. Shows what will run and when. " +
|
|
405
|
+
"Answers: 'What runs this week?', 'Show upcoming schedules', 'What agents are scheduled tomorrow?'. " +
|
|
406
|
+
"Returns: Array of upcoming runs with scheduleId, agentId, agentName, scheduleName, nextRunTime, isEnabled. " +
|
|
407
|
+
"TIP: If no dates provided, defaults to the next 7 days.",
|
|
408
|
+
inputSchema: {
|
|
409
|
+
type: "object",
|
|
410
|
+
properties: {
|
|
411
|
+
startDate: { type: "string", description: "Start date in ISO 8601 format. Example: '2026-01-16'. Defaults to today." },
|
|
412
|
+
endDate: { type: "string", description: "End date in ISO 8601 format. Example: '2026-01-23'. Defaults to 7 days from start." },
|
|
413
|
+
},
|
|
414
|
+
required: [],
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
// Billing/Credits Tools
|
|
418
|
+
{
|
|
419
|
+
name: "get_credits_balance",
|
|
420
|
+
description: "Get the current available credits balance for the organization. " +
|
|
421
|
+
"Answers: 'How many credits do I have?', 'What's my balance?', 'Check credits'. " +
|
|
422
|
+
"Returns: availableCredits, organizationId, retrievedAt timestamp.",
|
|
423
|
+
inputSchema: { type: "object", properties: {}, required: [] },
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
name: "get_spending_summary",
|
|
427
|
+
description: "Get a summary of credits spent in a date range. " +
|
|
428
|
+
"Answers: 'How much have I spent?', 'What's my usage this week?', 'Show spending for January'. " +
|
|
429
|
+
"Returns: totalSpent, startDate, endDate, currentBalance. " +
|
|
430
|
+
"TIP: If no dates provided, returns spending for the current period.",
|
|
431
|
+
inputSchema: {
|
|
432
|
+
type: "object",
|
|
433
|
+
properties: {
|
|
434
|
+
startDate: { type: "string", description: "Start date in ISO 8601 format. Example: '2026-01-01'." },
|
|
435
|
+
endDate: { type: "string", description: "End date in ISO 8601 format. Example: '2026-01-31'." },
|
|
436
|
+
},
|
|
437
|
+
required: [],
|
|
438
|
+
},
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
name: "get_credit_history",
|
|
442
|
+
description: "Get the transaction history of credits (additions from purchases, deductions from usage). " +
|
|
443
|
+
"Answers: 'Show credit history', 'What were my credit transactions?', 'When were credits added?'. " +
|
|
444
|
+
"Returns: Array of transactions with transactionType, amount, balance, created date, message.",
|
|
445
|
+
inputSchema: {
|
|
446
|
+
type: "object",
|
|
447
|
+
properties: {
|
|
448
|
+
pageIndex: { type: "number", description: "Page number (1-based). Default: 1." },
|
|
449
|
+
recordsPerPage: { type: "number", description: "Records per page. Default: 50, Max: 100." },
|
|
450
|
+
},
|
|
451
|
+
required: [],
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
// Space Tools
|
|
455
|
+
{
|
|
456
|
+
name: "list_spaces",
|
|
457
|
+
description: "List all accessible spaces (folders for organizing agents into groups). " +
|
|
458
|
+
"Answers: 'What spaces do I have?', 'Show my folders', 'List agent groups'. " +
|
|
459
|
+
"Returns: Array of spaces with id, name, description. " +
|
|
460
|
+
"USE THIS to find spaceId before using get_space_agents or filtering list_agents by space.",
|
|
461
|
+
inputSchema: { type: "object", properties: {}, required: [] },
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
name: "get_space",
|
|
465
|
+
description: "Get details of a specific space including its description and settings. " +
|
|
466
|
+
"Answers: 'Tell me about space X', 'Show space details'. " +
|
|
467
|
+
"Returns: Space details with id, name, description, organizationId, created/updated dates.",
|
|
468
|
+
inputSchema: {
|
|
469
|
+
type: "object",
|
|
470
|
+
properties: {
|
|
471
|
+
spaceId: { type: "number", description: "The unique ID of the space. Get this from list_spaces." },
|
|
472
|
+
},
|
|
473
|
+
required: ["spaceId"],
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
name: "get_space_agents",
|
|
478
|
+
description: "List all agents that belong to a specific space. " +
|
|
479
|
+
"Answers: 'What agents are in space X?', 'Show agents in the Production folder'. " +
|
|
480
|
+
"Returns: Array of agents in the space with id, name, status, configType, lastActivity. " +
|
|
481
|
+
"ALTERNATIVE: You can also use list_agents with spaceId filter.",
|
|
482
|
+
inputSchema: {
|
|
483
|
+
type: "object",
|
|
484
|
+
properties: {
|
|
485
|
+
spaceId: { type: "number", description: "The unique ID of the space. Get this from list_spaces or search_space_by_name." },
|
|
486
|
+
},
|
|
487
|
+
required: ["spaceId"],
|
|
488
|
+
},
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
name: "search_space_by_name",
|
|
492
|
+
description: "Find a space by its name. Use when user mentions a space by name instead of ID. " +
|
|
493
|
+
"Answers: 'Find the Production space', 'Get the Bot Blocking folder'. " +
|
|
494
|
+
"Returns: Matching space with id, name, description. " +
|
|
495
|
+
"NEXT STEP: Use the returned spaceId with get_space_agents or run_space_agents.",
|
|
496
|
+
inputSchema: {
|
|
497
|
+
type: "object",
|
|
498
|
+
properties: {
|
|
499
|
+
name: { type: "string", description: "The space name to search for. Case-insensitive." },
|
|
500
|
+
},
|
|
501
|
+
required: ["name"],
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
name: "run_space_agents",
|
|
506
|
+
description: "Start ALL agents in a space at once (batch operation). Useful for running a group of related agents together. " +
|
|
507
|
+
"Answers: 'Run all agents in space X', 'Execute the Production folder', 'Start all scrapers in Bot Blocking'. " +
|
|
508
|
+
"Returns: Summary with totalAgents, agentsStarted, agentsFailed, and individual results. " +
|
|
509
|
+
"WARNING: This starts multiple agents. Use get_space_agents first to see what will run.",
|
|
510
|
+
inputSchema: {
|
|
511
|
+
type: "object",
|
|
512
|
+
properties: {
|
|
513
|
+
spaceId: { type: "number", description: "The unique ID of the space. Get this from list_spaces or search_space_by_name." },
|
|
514
|
+
inputParameters: { type: "string", description: "Optional JSON string of input parameters to pass to ALL agents in the space." },
|
|
515
|
+
},
|
|
516
|
+
required: ["spaceId"],
|
|
517
|
+
},
|
|
518
|
+
},
|
|
519
|
+
// Analytics Tools
|
|
520
|
+
{
|
|
521
|
+
name: "get_runs_summary",
|
|
522
|
+
description: "Get aggregate statistics about agent runs in a date range: counts of completed, failed, running, etc. " +
|
|
523
|
+
"Answers: 'How many agents ran yesterday?', 'What failed last week?', 'Show run statistics', 'Give me a summary of runs'. " +
|
|
524
|
+
"Returns: totalRuns, completedRuns, failedRuns, completedWithErrorsRuns, runningRuns, queuedRuns, stoppedRuns. " +
|
|
525
|
+
"TIP: Set includeDetails=true to get details of which specific agents failed and why. " +
|
|
526
|
+
"TIP: Use status filter to focus on specific outcomes (e.g., 'Failed' to see only failures).",
|
|
527
|
+
inputSchema: {
|
|
528
|
+
type: "object",
|
|
529
|
+
properties: {
|
|
530
|
+
startDate: { type: "string", description: "Start date in ISO 8601 format. Example: '2026-01-15'. Defaults to today if not specified." },
|
|
531
|
+
endDate: { type: "string", description: "End date in ISO 8601 format. Example: '2026-01-16'. Defaults to today if not specified." },
|
|
532
|
+
status: { type: "string", description: "Filter by run status: 'Failed', 'Completed', 'CompletedWithErrors', 'Running'. Only shows runs with this status." },
|
|
533
|
+
includeDetails: { type: "boolean", description: "If true, includes failedRunDetails array with specific agent names and error messages. Default: true." },
|
|
534
|
+
},
|
|
535
|
+
required: [],
|
|
536
|
+
},
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
name: "get_records_summary",
|
|
540
|
+
description: "Get a summary of how many records were extracted and exported by agents in a date range. " +
|
|
541
|
+
"Answers: 'How many records were scraped?', 'What was the output yesterday?', 'Show extraction statistics'. " +
|
|
542
|
+
"Returns: totalRecordsExtracted, totalRecordsExported, totalErrors, totalPageLoads, runCount. " +
|
|
543
|
+
"TIP: Use agentId filter to see statistics for a specific agent only.",
|
|
544
|
+
inputSchema: {
|
|
545
|
+
type: "object",
|
|
546
|
+
properties: {
|
|
547
|
+
startDate: { type: "string", description: "Start date in ISO 8601 format. Example: '2026-01-15'." },
|
|
548
|
+
endDate: { type: "string", description: "End date in ISO 8601 format. Example: '2026-01-16'." },
|
|
549
|
+
agentId: { type: "number", description: "Optional: Filter to show records for a specific agent only." },
|
|
550
|
+
},
|
|
551
|
+
required: [],
|
|
552
|
+
},
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
name: "get_run_diagnostics",
|
|
556
|
+
description: "Get detailed diagnostics for a specific run, including error messages, possible causes, and suggested fixes. " +
|
|
557
|
+
"Answers: 'Why did run X fail?', 'Show error details for this run', 'Debug run 123'. " +
|
|
558
|
+
"Returns: errorMessage, possibleCauses (array), suggestedActions (array), run timing and stats. " +
|
|
559
|
+
"USE THIS when you have a specific runId. Use get_latest_failure if you just want the most recent failure.",
|
|
560
|
+
inputSchema: {
|
|
561
|
+
type: "object",
|
|
562
|
+
properties: {
|
|
563
|
+
agentId: { type: "number", description: "The unique ID of the agent." },
|
|
564
|
+
runId: { type: "number", description: "The run ID to diagnose. Get this from get_agent_runs." },
|
|
565
|
+
},
|
|
566
|
+
required: ["agentId", "runId"],
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
name: "get_latest_failure",
|
|
571
|
+
description: "Get diagnostics for the most recent failed run of an agent. Includes error analysis and suggested fixes. " +
|
|
572
|
+
"Answers: 'Why did my agent fail?', 'What went wrong?', 'Debug agent X', 'Show the last error'. " +
|
|
573
|
+
"Returns: errorMessage, possibleCauses, suggestedActions, run timing and stats. " +
|
|
574
|
+
"USE THIS instead of get_run_diagnostics when user asks about failure without specifying a run ID. " +
|
|
575
|
+
"SHORTCUT: This is faster than calling get_agent_runs + filtering for Failed + get_run_diagnostics.",
|
|
576
|
+
inputSchema: {
|
|
577
|
+
type: "object",
|
|
578
|
+
properties: {
|
|
579
|
+
agentId: { type: "number", description: "The unique ID of the agent. Get this from list_agents or search_agents." },
|
|
580
|
+
},
|
|
581
|
+
required: ["agentId"],
|
|
582
|
+
},
|
|
583
|
+
},
|
|
584
|
+
];
|
|
585
|
+
// ==========================================
|
|
586
|
+
// Server Setup
|
|
587
|
+
// ==========================================
|
|
588
|
+
const server = new Server({
|
|
589
|
+
name: "sequentum-mcp-server",
|
|
590
|
+
version,
|
|
591
|
+
}, {
|
|
592
|
+
capabilities: {
|
|
593
|
+
tools: {},
|
|
594
|
+
},
|
|
595
|
+
});
|
|
596
|
+
// ==========================================
|
|
597
|
+
// Request Handlers
|
|
598
|
+
// ==========================================
|
|
599
|
+
// Handle tool listing
|
|
600
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
601
|
+
tools,
|
|
602
|
+
}));
|
|
603
|
+
// Handle tool execution
|
|
604
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
605
|
+
const { name, arguments: args } = request.params;
|
|
606
|
+
if (DEBUG) {
|
|
607
|
+
console.error(`[DEBUG] Tool called: ${name}`);
|
|
608
|
+
console.error(`[DEBUG] Args: ${JSON.stringify(args)}`);
|
|
609
|
+
}
|
|
610
|
+
try {
|
|
611
|
+
switch (name) {
|
|
612
|
+
// Agent Tools
|
|
613
|
+
case "list_agents": {
|
|
614
|
+
const params = args;
|
|
615
|
+
const statusNum = validateNumber(params, "status", false);
|
|
616
|
+
const spaceId = validateNumber(params, "spaceId", false);
|
|
617
|
+
const search = validateString(params, "search", false);
|
|
618
|
+
const configTypeStr = validateString(params, "configType", false);
|
|
619
|
+
const sortColumn = validateString(params, "sortColumn", false);
|
|
620
|
+
const sortOrderStr = validateString(params, "sortOrder", false);
|
|
621
|
+
const pageIndex = validateNumber(params, "pageIndex", false);
|
|
622
|
+
const recordsPerPage = validateNumber(params, "recordsPerPage", false);
|
|
623
|
+
// Build filters object - ALWAYS include pagination to ensure resource-efficient API calls
|
|
624
|
+
const filters = {
|
|
625
|
+
// Always enforce pagination with defaults (pageIndex is 1-based per API spec)
|
|
626
|
+
pageIndex: pageIndex ?? 1,
|
|
627
|
+
recordsPerPage: recordsPerPage ?? 50,
|
|
628
|
+
};
|
|
629
|
+
// Add other optional filters
|
|
630
|
+
// Status is now the RunStatus enum value (1=Running, 7=Failed, 9=Completed, etc.)
|
|
631
|
+
if (statusNum !== undefined) {
|
|
632
|
+
filters.status = statusNum;
|
|
633
|
+
}
|
|
634
|
+
if (spaceId !== undefined) {
|
|
635
|
+
filters.spaceId = spaceId;
|
|
636
|
+
}
|
|
637
|
+
if (search) {
|
|
638
|
+
filters.search = search;
|
|
639
|
+
}
|
|
640
|
+
if (configTypeStr) {
|
|
641
|
+
filters.configType = configTypeStr;
|
|
642
|
+
}
|
|
643
|
+
if (sortColumn) {
|
|
644
|
+
filters.sortColumn = sortColumn;
|
|
645
|
+
}
|
|
646
|
+
if (sortOrderStr) {
|
|
647
|
+
// Convert "asc"/"desc" to 0/1 as the API expects
|
|
648
|
+
filters.sortOrder = sortOrderStr === "desc" ? 1 : 0;
|
|
649
|
+
}
|
|
650
|
+
if (DEBUG) {
|
|
651
|
+
console.error(`[DEBUG] Calling getAllAgents with filters: ${JSON.stringify(filters)}`);
|
|
652
|
+
}
|
|
653
|
+
const response = await client.getAllAgents(filters);
|
|
654
|
+
if (DEBUG) {
|
|
655
|
+
console.error(`[DEBUG] Response type: ${typeof response}, isArray: ${Array.isArray(response)}`);
|
|
656
|
+
}
|
|
657
|
+
// Check if response is paginated (has 'data', 'items', 'records', or 'agents' property) or plain array
|
|
658
|
+
let agents;
|
|
659
|
+
let paginationInfo = null;
|
|
660
|
+
if (Array.isArray(response)) {
|
|
661
|
+
agents = response;
|
|
662
|
+
}
|
|
663
|
+
else if (response && typeof response === 'object') {
|
|
664
|
+
// Try common property names for paginated responses
|
|
665
|
+
const possibleDataProps = ['data', 'items', 'records', 'agents', 'results'];
|
|
666
|
+
const dataKey = possibleDataProps.find(key => key in response && Array.isArray(response[key]));
|
|
667
|
+
if (dataKey) {
|
|
668
|
+
agents = response[dataKey];
|
|
669
|
+
paginationInfo = {
|
|
670
|
+
totalCount: response.totalCount ?? response.total ?? response.count,
|
|
671
|
+
pageIndex: response.pageIndex ?? response.page,
|
|
672
|
+
recordsPerPage: response.recordsPerPage ?? response.pageSize ?? response.limit,
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
else {
|
|
676
|
+
// Unknown structure - return raw response
|
|
677
|
+
if (DEBUG) {
|
|
678
|
+
console.error(`[DEBUG] Unknown response structure: ${JSON.stringify(response).substring(0, 500)}`);
|
|
679
|
+
}
|
|
680
|
+
return {
|
|
681
|
+
content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
else {
|
|
686
|
+
throw new Error(`Unexpected response type: ${typeof response}`);
|
|
687
|
+
}
|
|
688
|
+
if (DEBUG) {
|
|
689
|
+
console.error(`[DEBUG] getAllAgents returned ${agents.length} agents`);
|
|
690
|
+
}
|
|
691
|
+
const summary = summarizeAgents(agents);
|
|
692
|
+
// Include pagination info if available
|
|
693
|
+
const result = paginationInfo ? {
|
|
694
|
+
agents: summary,
|
|
695
|
+
pagination: paginationInfo,
|
|
696
|
+
} : summary;
|
|
697
|
+
return {
|
|
698
|
+
content: [
|
|
699
|
+
{
|
|
700
|
+
type: "text",
|
|
701
|
+
text: JSON.stringify(result, null, 2),
|
|
702
|
+
},
|
|
703
|
+
],
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
case "get_agent": {
|
|
707
|
+
const params = args;
|
|
708
|
+
const agentId = validateNumber(params, "agentId");
|
|
709
|
+
const agent = await client.getAgent(agentId);
|
|
710
|
+
return {
|
|
711
|
+
content: [
|
|
712
|
+
{
|
|
713
|
+
type: "text",
|
|
714
|
+
text: JSON.stringify(agent, null, 2),
|
|
715
|
+
},
|
|
716
|
+
],
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
case "search_agents": {
|
|
720
|
+
const params = args;
|
|
721
|
+
const query = validateString(params, "query");
|
|
722
|
+
if (!query.trim()) {
|
|
723
|
+
throw new Error("Search query cannot be empty");
|
|
724
|
+
}
|
|
725
|
+
const maxRecords = validateNumber(params, "maxRecords", false);
|
|
726
|
+
const agents = await client.searchAgents(query, maxRecords);
|
|
727
|
+
return {
|
|
728
|
+
content: [
|
|
729
|
+
{
|
|
730
|
+
type: "text",
|
|
731
|
+
text: JSON.stringify(summarizeAgents(agents), null, 2),
|
|
732
|
+
},
|
|
733
|
+
],
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
// Run Tools
|
|
737
|
+
case "get_agent_runs": {
|
|
738
|
+
const params = args;
|
|
739
|
+
const agentId = validateNumber(params, "agentId");
|
|
740
|
+
const maxRecords = validateNumber(params, "maxRecords", false);
|
|
741
|
+
const runs = await client.getAgentRuns(agentId, maxRecords);
|
|
742
|
+
return {
|
|
743
|
+
content: [
|
|
744
|
+
{
|
|
745
|
+
type: "text",
|
|
746
|
+
text: JSON.stringify(runs, null, 2),
|
|
747
|
+
},
|
|
748
|
+
],
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
case "get_run_status": {
|
|
752
|
+
const params = args;
|
|
753
|
+
const agentId = validateNumber(params, "agentId");
|
|
754
|
+
const runId = validateNumber(params, "runId");
|
|
755
|
+
const status = await client.getRunStatus(agentId, runId);
|
|
756
|
+
return {
|
|
757
|
+
content: [
|
|
758
|
+
{
|
|
759
|
+
type: "text",
|
|
760
|
+
text: JSON.stringify(status, null, 2),
|
|
761
|
+
},
|
|
762
|
+
],
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
case "start_agent": {
|
|
766
|
+
const params = args;
|
|
767
|
+
const agentId = validateNumber(params, "agentId");
|
|
768
|
+
const inputParameters = validateString(params, "inputParameters", false);
|
|
769
|
+
const isRunSynchronously = validateBoolean(params, "isRunSynchronously", false);
|
|
770
|
+
const timeout = validateNumber(params, "timeout", false);
|
|
771
|
+
const parallelism = validateNumber(params, "parallelism", false);
|
|
772
|
+
const result = await client.startAgent(agentId, {
|
|
773
|
+
inputParameters,
|
|
774
|
+
isRunSynchronously: isRunSynchronously ?? false,
|
|
775
|
+
timeout: timeout ?? 60,
|
|
776
|
+
parallelism: parallelism ?? 1,
|
|
777
|
+
});
|
|
778
|
+
if (typeof result === "string") {
|
|
779
|
+
// Synchronous run returned data directly
|
|
780
|
+
return {
|
|
781
|
+
content: [
|
|
782
|
+
{
|
|
783
|
+
type: "text",
|
|
784
|
+
text: result,
|
|
785
|
+
},
|
|
786
|
+
],
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
else {
|
|
790
|
+
// Asynchronous run returned run info
|
|
791
|
+
return {
|
|
792
|
+
content: [
|
|
793
|
+
{
|
|
794
|
+
type: "text",
|
|
795
|
+
text: `Agent started successfully.\n\n${JSON.stringify(result, null, 2)}`,
|
|
796
|
+
},
|
|
797
|
+
],
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
case "stop_agent": {
|
|
802
|
+
const params = args;
|
|
803
|
+
const agentId = validateNumber(params, "agentId");
|
|
804
|
+
const runId = validateNumber(params, "runId");
|
|
805
|
+
await client.stopAgent(agentId, runId);
|
|
806
|
+
return {
|
|
807
|
+
content: [
|
|
808
|
+
{
|
|
809
|
+
type: "text",
|
|
810
|
+
text: `Successfully stopped run ${runId} for agent ${agentId}`,
|
|
811
|
+
},
|
|
812
|
+
],
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
// File Tools
|
|
816
|
+
case "get_run_files": {
|
|
817
|
+
const params = args;
|
|
818
|
+
const agentId = validateNumber(params, "agentId");
|
|
819
|
+
const runId = validateNumber(params, "runId");
|
|
820
|
+
const files = await client.getRunFiles(agentId, runId);
|
|
821
|
+
if (files.length === 0) {
|
|
822
|
+
return {
|
|
823
|
+
content: [
|
|
824
|
+
{
|
|
825
|
+
type: "text",
|
|
826
|
+
text: "No files found for this run.",
|
|
827
|
+
},
|
|
828
|
+
],
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
const summary = files.map((f) => ({
|
|
832
|
+
id: f.id,
|
|
833
|
+
name: f.name,
|
|
834
|
+
fileType: f.fileType,
|
|
835
|
+
fileSize: `${((f.fileSize ?? 0) / 1024).toFixed(2)} KB`,
|
|
836
|
+
created: f.created,
|
|
837
|
+
}));
|
|
838
|
+
return {
|
|
839
|
+
content: [
|
|
840
|
+
{
|
|
841
|
+
type: "text",
|
|
842
|
+
text: JSON.stringify(summary, null, 2),
|
|
843
|
+
},
|
|
844
|
+
],
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
case "get_file_download_url": {
|
|
848
|
+
const params = args;
|
|
849
|
+
const agentId = validateNumber(params, "agentId");
|
|
850
|
+
const runId = validateNumber(params, "runId");
|
|
851
|
+
const fileId = validateNumber(params, "fileId");
|
|
852
|
+
const result = await client.downloadRunFile(agentId, runId, fileId);
|
|
853
|
+
return {
|
|
854
|
+
content: [
|
|
855
|
+
{
|
|
856
|
+
type: "text",
|
|
857
|
+
text: `Download URL:\n${result.redirectUrl}\n\nNote: This URL is temporary and will expire.`,
|
|
858
|
+
},
|
|
859
|
+
],
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
// Version Tools
|
|
863
|
+
case "get_agent_versions": {
|
|
864
|
+
const params = args;
|
|
865
|
+
const agentId = validateNumber(params, "agentId");
|
|
866
|
+
const versions = await client.getAgentVersions(agentId);
|
|
867
|
+
return {
|
|
868
|
+
content: [
|
|
869
|
+
{
|
|
870
|
+
type: "text",
|
|
871
|
+
text: JSON.stringify(versions, null, 2),
|
|
872
|
+
},
|
|
873
|
+
],
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
case "restore_agent_version": {
|
|
877
|
+
const params = args;
|
|
878
|
+
const agentId = validateNumber(params, "agentId");
|
|
879
|
+
const versionNumber = validateNumber(params, "versionNumber");
|
|
880
|
+
const comments = validateString(params, "comments");
|
|
881
|
+
await client.restoreAgentVersion(agentId, versionNumber, comments);
|
|
882
|
+
return {
|
|
883
|
+
content: [
|
|
884
|
+
{
|
|
885
|
+
type: "text",
|
|
886
|
+
text: `Successfully restored agent ${agentId} to version ${versionNumber}.\n\nA new version has been created based on version ${versionNumber}.`,
|
|
887
|
+
},
|
|
888
|
+
],
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
// Schedule Tools
|
|
892
|
+
case "list_agent_schedules": {
|
|
893
|
+
const params = args;
|
|
894
|
+
const agentId = validateNumber(params, "agentId");
|
|
895
|
+
const schedules = await client.getAgentSchedules(agentId);
|
|
896
|
+
return {
|
|
897
|
+
content: [
|
|
898
|
+
{
|
|
899
|
+
type: "text",
|
|
900
|
+
text: JSON.stringify(schedules, null, 2),
|
|
901
|
+
},
|
|
902
|
+
],
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
case "create_agent_schedule": {
|
|
906
|
+
const params = args;
|
|
907
|
+
const agentId = validateNumber(params, "agentId");
|
|
908
|
+
const name = validateString(params, "name");
|
|
909
|
+
const scheduleType = validateNumber(params, "scheduleType", false);
|
|
910
|
+
const startTime = validateString(params, "startTime", false);
|
|
911
|
+
const cronExpression = validateString(params, "cronExpression", false);
|
|
912
|
+
const runEveryCount = validateNumber(params, "runEveryCount", false);
|
|
913
|
+
const runEveryPeriod = validateNumber(params, "runEveryPeriod", false);
|
|
914
|
+
const timezone = validateString(params, "timezone", false);
|
|
915
|
+
const inputParameters = validateString(params, "inputParameters", false);
|
|
916
|
+
const isEnabled = validateBoolean(params, "isEnabled", false);
|
|
917
|
+
const parallelism = validateNumber(params, "parallelism", false);
|
|
918
|
+
// Validate schedule type specific parameters
|
|
919
|
+
const effectiveScheduleType = scheduleType ?? 3; // Default to CRON
|
|
920
|
+
if (effectiveScheduleType === 1 && !startTime) {
|
|
921
|
+
throw new Error("startTime is required when scheduleType is 1 (RunOnce)");
|
|
922
|
+
}
|
|
923
|
+
if (effectiveScheduleType === 2 && (runEveryCount === undefined || runEveryPeriod === undefined)) {
|
|
924
|
+
throw new Error("runEveryCount and runEveryPeriod are required when scheduleType is 2 (RunEvery)");
|
|
925
|
+
}
|
|
926
|
+
if (effectiveScheduleType === 3 && !cronExpression) {
|
|
927
|
+
throw new Error("cronExpression is required when scheduleType is 3 (CRON)");
|
|
928
|
+
}
|
|
929
|
+
const schedule = await client.createAgentSchedule(agentId, {
|
|
930
|
+
name,
|
|
931
|
+
scheduleType: effectiveScheduleType,
|
|
932
|
+
startTime,
|
|
933
|
+
cronExpression,
|
|
934
|
+
runEveryCount,
|
|
935
|
+
runEveryPeriod,
|
|
936
|
+
timezone,
|
|
937
|
+
inputParameters,
|
|
938
|
+
isEnabled: isEnabled ?? true,
|
|
939
|
+
parallelism: parallelism ?? 1,
|
|
940
|
+
});
|
|
941
|
+
return {
|
|
942
|
+
content: [
|
|
943
|
+
{
|
|
944
|
+
type: "text",
|
|
945
|
+
text: `Schedule created successfully.\n\n${JSON.stringify(schedule, null, 2)}`,
|
|
946
|
+
},
|
|
947
|
+
],
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
case "delete_agent_schedule": {
|
|
951
|
+
const params = args;
|
|
952
|
+
const agentId = validateNumber(params, "agentId");
|
|
953
|
+
const scheduleId = validateNumber(params, "scheduleId");
|
|
954
|
+
await client.deleteAgentSchedule(agentId, scheduleId);
|
|
955
|
+
return {
|
|
956
|
+
content: [
|
|
957
|
+
{
|
|
958
|
+
type: "text",
|
|
959
|
+
text: `Successfully deleted schedule ${scheduleId} from agent ${agentId}`,
|
|
960
|
+
},
|
|
961
|
+
],
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
case "get_scheduled_runs": {
|
|
965
|
+
const params = args;
|
|
966
|
+
const startDate = validateString(params, "startDate", false);
|
|
967
|
+
const endDate = validateString(params, "endDate", false);
|
|
968
|
+
const schedules = await client.getUpcomingSchedules(startDate, endDate);
|
|
969
|
+
return {
|
|
970
|
+
content: [
|
|
971
|
+
{
|
|
972
|
+
type: "text",
|
|
973
|
+
text: JSON.stringify(schedules, null, 2),
|
|
974
|
+
},
|
|
975
|
+
],
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
// Billing/Credits Tools
|
|
979
|
+
case "get_credits_balance": {
|
|
980
|
+
const balance = await client.getCreditsBalance();
|
|
981
|
+
return {
|
|
982
|
+
content: [
|
|
983
|
+
{
|
|
984
|
+
type: "text",
|
|
985
|
+
text: JSON.stringify(balance, null, 2),
|
|
986
|
+
},
|
|
987
|
+
],
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
case "get_spending_summary": {
|
|
991
|
+
const params = args;
|
|
992
|
+
const startDate = validateString(params, "startDate", false);
|
|
993
|
+
const endDate = validateString(params, "endDate", false);
|
|
994
|
+
const spending = await client.getSpendingSummary(startDate, endDate);
|
|
995
|
+
return {
|
|
996
|
+
content: [
|
|
997
|
+
{
|
|
998
|
+
type: "text",
|
|
999
|
+
text: JSON.stringify(spending, null, 2),
|
|
1000
|
+
},
|
|
1001
|
+
],
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
case "get_credit_history": {
|
|
1005
|
+
const params = args;
|
|
1006
|
+
const pageIndex = validateNumber(params, "pageIndex", false);
|
|
1007
|
+
const recordsPerPage = validateNumber(params, "recordsPerPage", false);
|
|
1008
|
+
const history = await client.getCreditHistory(pageIndex, recordsPerPage);
|
|
1009
|
+
return {
|
|
1010
|
+
content: [
|
|
1011
|
+
{
|
|
1012
|
+
type: "text",
|
|
1013
|
+
text: JSON.stringify(history, null, 2),
|
|
1014
|
+
},
|
|
1015
|
+
],
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
// Space Tools
|
|
1019
|
+
case "list_spaces": {
|
|
1020
|
+
const spaces = await client.getAllSpaces();
|
|
1021
|
+
return {
|
|
1022
|
+
content: [
|
|
1023
|
+
{
|
|
1024
|
+
type: "text",
|
|
1025
|
+
text: JSON.stringify(spaces, null, 2),
|
|
1026
|
+
},
|
|
1027
|
+
],
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
case "get_space": {
|
|
1031
|
+
const params = args;
|
|
1032
|
+
const spaceId = validateNumber(params, "spaceId");
|
|
1033
|
+
const space = await client.getSpace(spaceId);
|
|
1034
|
+
return {
|
|
1035
|
+
content: [
|
|
1036
|
+
{
|
|
1037
|
+
type: "text",
|
|
1038
|
+
text: JSON.stringify(space, null, 2),
|
|
1039
|
+
},
|
|
1040
|
+
],
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
case "get_space_agents": {
|
|
1044
|
+
const params = args;
|
|
1045
|
+
const spaceId = validateNumber(params, "spaceId");
|
|
1046
|
+
const agents = await client.getSpaceAgents(spaceId);
|
|
1047
|
+
return {
|
|
1048
|
+
content: [
|
|
1049
|
+
{
|
|
1050
|
+
type: "text",
|
|
1051
|
+
text: JSON.stringify(agents, null, 2),
|
|
1052
|
+
},
|
|
1053
|
+
],
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
case "search_space_by_name": {
|
|
1057
|
+
const params = args;
|
|
1058
|
+
const name = validateString(params, "name");
|
|
1059
|
+
const space = await client.searchSpaceByName(name);
|
|
1060
|
+
return {
|
|
1061
|
+
content: [
|
|
1062
|
+
{
|
|
1063
|
+
type: "text",
|
|
1064
|
+
text: JSON.stringify(space, null, 2),
|
|
1065
|
+
},
|
|
1066
|
+
],
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
case "run_space_agents": {
|
|
1070
|
+
const params = args;
|
|
1071
|
+
const spaceId = validateNumber(params, "spaceId");
|
|
1072
|
+
const inputParameters = validateString(params, "inputParameters", false);
|
|
1073
|
+
const result = await client.runSpaceAgents(spaceId, inputParameters);
|
|
1074
|
+
return {
|
|
1075
|
+
content: [
|
|
1076
|
+
{
|
|
1077
|
+
type: "text",
|
|
1078
|
+
text: `Started agents in space.\n\n${JSON.stringify(result, null, 2)}`,
|
|
1079
|
+
},
|
|
1080
|
+
],
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
// Analytics Tools
|
|
1084
|
+
case "get_runs_summary": {
|
|
1085
|
+
const params = args;
|
|
1086
|
+
const startDate = validateString(params, "startDate", false);
|
|
1087
|
+
const endDate = validateString(params, "endDate", false);
|
|
1088
|
+
const status = validateString(params, "status", false);
|
|
1089
|
+
const includeDetails = validateBoolean(params, "includeDetails", false);
|
|
1090
|
+
const summary = await client.getRunsSummary(startDate, endDate, status, includeDetails);
|
|
1091
|
+
return {
|
|
1092
|
+
content: [
|
|
1093
|
+
{
|
|
1094
|
+
type: "text",
|
|
1095
|
+
text: JSON.stringify(summary, null, 2),
|
|
1096
|
+
},
|
|
1097
|
+
],
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
case "get_records_summary": {
|
|
1101
|
+
const params = args;
|
|
1102
|
+
const startDate = validateString(params, "startDate", false);
|
|
1103
|
+
const endDate = validateString(params, "endDate", false);
|
|
1104
|
+
const agentId = validateNumber(params, "agentId", false);
|
|
1105
|
+
const summary = await client.getRecordsSummary(startDate, endDate, agentId);
|
|
1106
|
+
return {
|
|
1107
|
+
content: [
|
|
1108
|
+
{
|
|
1109
|
+
type: "text",
|
|
1110
|
+
text: JSON.stringify(summary, null, 2),
|
|
1111
|
+
},
|
|
1112
|
+
],
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
case "get_run_diagnostics": {
|
|
1116
|
+
const params = args;
|
|
1117
|
+
const agentId = validateNumber(params, "agentId");
|
|
1118
|
+
const runId = validateNumber(params, "runId");
|
|
1119
|
+
const diagnostics = await client.getRunDiagnostics(agentId, runId);
|
|
1120
|
+
return {
|
|
1121
|
+
content: [
|
|
1122
|
+
{
|
|
1123
|
+
type: "text",
|
|
1124
|
+
text: JSON.stringify(diagnostics, null, 2),
|
|
1125
|
+
},
|
|
1126
|
+
],
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
case "get_latest_failure": {
|
|
1130
|
+
const params = args;
|
|
1131
|
+
const agentId = validateNumber(params, "agentId");
|
|
1132
|
+
const diagnostics = await client.getLatestFailure(agentId);
|
|
1133
|
+
return {
|
|
1134
|
+
content: [
|
|
1135
|
+
{
|
|
1136
|
+
type: "text",
|
|
1137
|
+
text: JSON.stringify(diagnostics, null, 2),
|
|
1138
|
+
},
|
|
1139
|
+
],
|
|
1140
|
+
};
|
|
1141
|
+
}
|
|
1142
|
+
default:
|
|
1143
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
catch (error) {
|
|
1147
|
+
const errorMessage = error instanceof Error ? error.message : "An unknown error occurred";
|
|
1148
|
+
return {
|
|
1149
|
+
content: [
|
|
1150
|
+
{
|
|
1151
|
+
type: "text",
|
|
1152
|
+
text: `Error: ${errorMessage}`,
|
|
1153
|
+
},
|
|
1154
|
+
],
|
|
1155
|
+
isError: true,
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
});
|
|
1159
|
+
// ==========================================
|
|
1160
|
+
// Main Entry Point
|
|
1161
|
+
// ==========================================
|
|
1162
|
+
async function main() {
|
|
1163
|
+
const transport = new StdioServerTransport();
|
|
1164
|
+
await server.connect(transport);
|
|
1165
|
+
console.error("Sequentum MCP Server running on stdio");
|
|
1166
|
+
console.error(`Connected to: ${API_BASE_URL}`);
|
|
1167
|
+
}
|
|
1168
|
+
main().catch((error) => {
|
|
1169
|
+
console.error("Fatal error starting server:", error);
|
|
1170
|
+
process.exit(1);
|
|
1171
|
+
});
|
|
1172
|
+
//# sourceMappingURL=index.js.map
|