@alisaitteke/temporal-mcp 0.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.
- package/README.md +225 -0
- package/bin/temporal-mcp.js +5 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2254 -0
- package/dist/index.js.map +1 -0
- package/mcp.json +13 -0
- package/package.json +49 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2254 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
|
|
7
|
+
// src/client.ts
|
|
8
|
+
var TemporalError = class extends Error {
|
|
9
|
+
constructor(status, message, details) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.status = status;
|
|
12
|
+
this.details = details;
|
|
13
|
+
this.name = "TemporalError";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
var TemporalClient = class {
|
|
17
|
+
baseUrl;
|
|
18
|
+
defaultNamespace;
|
|
19
|
+
headers;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.baseUrl = config.address.replace(/\/$/, "");
|
|
22
|
+
this.defaultNamespace = config.defaultNamespace;
|
|
23
|
+
this.headers = {
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
Accept: "application/json",
|
|
26
|
+
...config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** Resolves namespace: uses provided value or falls back to the configured default. */
|
|
30
|
+
ns(namespace) {
|
|
31
|
+
return namespace ?? this.defaultNamespace;
|
|
32
|
+
}
|
|
33
|
+
// ─── Core HTTP helpers ────────────────────────────────────────────────────
|
|
34
|
+
async get(path, params) {
|
|
35
|
+
const url = this.buildUrl(path, params);
|
|
36
|
+
const res = await fetch(url, { headers: this.headers });
|
|
37
|
+
return this.parseResponse(res);
|
|
38
|
+
}
|
|
39
|
+
async post(path, body) {
|
|
40
|
+
const url = this.buildUrl(path);
|
|
41
|
+
const res = await fetch(url, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: this.headers,
|
|
44
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
45
|
+
});
|
|
46
|
+
return this.parseResponse(res);
|
|
47
|
+
}
|
|
48
|
+
async delete(path, body) {
|
|
49
|
+
const url = this.buildUrl(path);
|
|
50
|
+
const res = await fetch(url, {
|
|
51
|
+
method: "DELETE",
|
|
52
|
+
headers: this.headers,
|
|
53
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
54
|
+
});
|
|
55
|
+
return this.parseResponse(res);
|
|
56
|
+
}
|
|
57
|
+
// ─── Private helpers ──────────────────────────────────────────────────────
|
|
58
|
+
buildUrl(path, params) {
|
|
59
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
60
|
+
if (params) {
|
|
61
|
+
for (const [key, value] of Object.entries(params)) {
|
|
62
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
63
|
+
url.searchParams.set(key, String(value));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return url.toString();
|
|
68
|
+
}
|
|
69
|
+
async parseResponse(res) {
|
|
70
|
+
const text = await res.text();
|
|
71
|
+
if (!res.ok) {
|
|
72
|
+
let message = `HTTP ${res.status}: ${res.statusText}`;
|
|
73
|
+
let details;
|
|
74
|
+
try {
|
|
75
|
+
const err = JSON.parse(text);
|
|
76
|
+
message = err.message ?? message;
|
|
77
|
+
details = err.details;
|
|
78
|
+
} catch {
|
|
79
|
+
if (text) message = text;
|
|
80
|
+
}
|
|
81
|
+
throw new TemporalError(res.status, message, details);
|
|
82
|
+
}
|
|
83
|
+
if (!text) return {};
|
|
84
|
+
try {
|
|
85
|
+
return JSON.parse(text);
|
|
86
|
+
} catch {
|
|
87
|
+
throw new TemporalError(200, `Failed to parse response body: ${text}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
function createClientFromEnv() {
|
|
92
|
+
const address = process.env.TEMPORAL_ADDRESS;
|
|
93
|
+
if (!address) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
"TEMPORAL_ADDRESS environment variable is required (e.g. http://localhost:8080)"
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
return new TemporalClient({
|
|
99
|
+
address,
|
|
100
|
+
defaultNamespace: process.env.TEMPORAL_NAMESPACE ?? "default",
|
|
101
|
+
apiKey: process.env.TEMPORAL_API_KEY
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
var clusterToolDefinitions = [
|
|
105
|
+
{
|
|
106
|
+
name: "get_cluster_info",
|
|
107
|
+
description: "Get Temporal cluster information including server version, supported features, and system info. Use this first to verify connectivity and check what capabilities are available.",
|
|
108
|
+
inputSchema: {
|
|
109
|
+
type: "object",
|
|
110
|
+
properties: {},
|
|
111
|
+
required: []
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
];
|
|
115
|
+
var getClusterInfoSchema = z.object({});
|
|
116
|
+
async function handleGetClusterInfo(_args, client) {
|
|
117
|
+
const [clusterInfo, systemInfo] = await Promise.all([
|
|
118
|
+
client.get("/api/v1/cluster-info"),
|
|
119
|
+
client.get("/api/v1/system-info")
|
|
120
|
+
]);
|
|
121
|
+
const lines = [
|
|
122
|
+
"# Temporal Cluster Info",
|
|
123
|
+
"",
|
|
124
|
+
"## Cluster"
|
|
125
|
+
];
|
|
126
|
+
if (clusterInfo.clusterId) lines.push(`- Cluster ID: ${clusterInfo.clusterId}`);
|
|
127
|
+
if (clusterInfo.serverVersion) lines.push(`- Server Version: ${clusterInfo.serverVersion}`);
|
|
128
|
+
if (clusterInfo.clusterName) lines.push(`- Cluster Name: ${clusterInfo.clusterName}`);
|
|
129
|
+
if (clusterInfo.historyShardCount) lines.push(`- History Shard Count: ${clusterInfo.historyShardCount}`);
|
|
130
|
+
lines.push("", "## System");
|
|
131
|
+
const caps = systemInfo.capabilities;
|
|
132
|
+
if (caps) {
|
|
133
|
+
const enabledCaps = Object.entries(caps).filter(([, v]) => v === true).map(([k]) => k);
|
|
134
|
+
if (enabledCaps.length > 0) {
|
|
135
|
+
lines.push("Enabled capabilities:");
|
|
136
|
+
enabledCaps.forEach((c) => lines.push(` - ${c}`));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (systemInfo.serverVersion) lines.push(`- Server Version: ${systemInfo.serverVersion}`);
|
|
140
|
+
return {
|
|
141
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
142
|
+
structuredContent: {
|
|
143
|
+
clusterId: clusterInfo.clusterId,
|
|
144
|
+
clusterName: clusterInfo.clusterName,
|
|
145
|
+
serverVersion: clusterInfo.serverVersion ?? systemInfo.serverVersion,
|
|
146
|
+
historyShardCount: clusterInfo.historyShardCount,
|
|
147
|
+
capabilities: caps ? Object.keys(caps).filter((k) => caps[k] === true) : []
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
var namespaceToolDefinitions = [
|
|
152
|
+
{
|
|
153
|
+
name: "list_namespaces",
|
|
154
|
+
description: "List all Temporal namespaces in the cluster.",
|
|
155
|
+
inputSchema: {
|
|
156
|
+
type: "object",
|
|
157
|
+
properties: {
|
|
158
|
+
page_size: {
|
|
159
|
+
type: "number",
|
|
160
|
+
description: "Maximum number of namespaces to return (default 100)."
|
|
161
|
+
},
|
|
162
|
+
next_page_token: {
|
|
163
|
+
type: "string",
|
|
164
|
+
description: "Pagination token from a previous list_namespaces call."
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
required: []
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: "describe_namespace",
|
|
172
|
+
description: "Get detailed configuration and status for a specific namespace.",
|
|
173
|
+
inputSchema: {
|
|
174
|
+
type: "object",
|
|
175
|
+
properties: {
|
|
176
|
+
namespace: {
|
|
177
|
+
type: "string",
|
|
178
|
+
description: 'Namespace name (e.g. "default", "my-team").'
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
required: ["namespace"]
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
];
|
|
185
|
+
var listNamespacesSchema = z.object({
|
|
186
|
+
page_size: z.number().optional().describe("Maximum number of namespaces to return"),
|
|
187
|
+
next_page_token: z.string().optional().describe("Pagination cursor from previous call")
|
|
188
|
+
});
|
|
189
|
+
var describeNamespaceSchema = z.object({
|
|
190
|
+
namespace: z.string().describe("Namespace name")
|
|
191
|
+
});
|
|
192
|
+
async function handleListNamespaces(args, client) {
|
|
193
|
+
const data = await client.get("/api/v1/namespaces", {
|
|
194
|
+
pageSize: args.page_size,
|
|
195
|
+
nextPageToken: args.next_page_token
|
|
196
|
+
});
|
|
197
|
+
const namespaces = data.namespaces ?? [];
|
|
198
|
+
const lines = [`# Namespaces (${namespaces.length})`, ""];
|
|
199
|
+
for (const ns of namespaces) {
|
|
200
|
+
const info = ns.namespaceInfo;
|
|
201
|
+
const config = ns.config;
|
|
202
|
+
lines.push(`## ${info?.name ?? "unknown"}`);
|
|
203
|
+
if (info?.state) lines.push(`- State: ${info.state}`);
|
|
204
|
+
if (info?.description) lines.push(`- Description: ${info.description}`);
|
|
205
|
+
if (info?.ownerEmail) lines.push(`- Owner: ${info.ownerEmail}`);
|
|
206
|
+
if (config?.workflowExecutionRetentionPeriod)
|
|
207
|
+
lines.push(`- Retention: ${config.workflowExecutionRetentionPeriod}`);
|
|
208
|
+
lines.push("");
|
|
209
|
+
}
|
|
210
|
+
if (data.nextPageToken) {
|
|
211
|
+
lines.push(`*Next page token: ${data.nextPageToken}*`);
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
215
|
+
structuredContent: {
|
|
216
|
+
namespaces: namespaces.map((ns) => {
|
|
217
|
+
const info = ns.namespaceInfo;
|
|
218
|
+
const config = ns.config;
|
|
219
|
+
return {
|
|
220
|
+
name: info?.name,
|
|
221
|
+
state: info?.state,
|
|
222
|
+
description: info?.description,
|
|
223
|
+
ownerEmail: info?.ownerEmail,
|
|
224
|
+
retention: config?.workflowExecutionRetentionPeriod
|
|
225
|
+
};
|
|
226
|
+
}),
|
|
227
|
+
nextPageToken: data.nextPageToken
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
async function handleDescribeNamespace(args, client) {
|
|
232
|
+
const ns = args.namespace ?? client.ns();
|
|
233
|
+
const data = await client.get(`/api/v1/namespaces/${encodeURIComponent(ns)}`);
|
|
234
|
+
const info = data.namespaceInfo;
|
|
235
|
+
const config = data.config;
|
|
236
|
+
const repConfig = data.replicationConfig;
|
|
237
|
+
const lines = [`# Namespace: ${info?.name ?? ns}`, ""];
|
|
238
|
+
if (info?.state) lines.push(`- State: ${info.state}`);
|
|
239
|
+
if (info?.description) lines.push(`- Description: ${info.description}`);
|
|
240
|
+
if (info?.ownerEmail) lines.push(`- Owner Email: ${info.ownerEmail}`);
|
|
241
|
+
if (config?.workflowExecutionRetentionPeriod)
|
|
242
|
+
lines.push(`- Workflow Retention: ${config.workflowExecutionRetentionPeriod}`);
|
|
243
|
+
if (repConfig?.activeClusterName)
|
|
244
|
+
lines.push(`- Active Cluster: ${repConfig.activeClusterName}`);
|
|
245
|
+
const clusters = repConfig?.clusters;
|
|
246
|
+
if (clusters?.length) {
|
|
247
|
+
lines.push(`- Clusters: ${clusters.map((c) => c.clusterName).join(", ")}`);
|
|
248
|
+
}
|
|
249
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
250
|
+
}
|
|
251
|
+
var workflowToolDefinitions = [
|
|
252
|
+
{
|
|
253
|
+
name: "count_workflows",
|
|
254
|
+
description: "Count workflow executions matching an optional visibility query. Useful for dashboards and health checks.",
|
|
255
|
+
inputSchema: {
|
|
256
|
+
type: "object",
|
|
257
|
+
properties: {
|
|
258
|
+
namespace: { type: "string", description: "Target namespace." },
|
|
259
|
+
query: {
|
|
260
|
+
type: "string",
|
|
261
|
+
description: `Visibility query filter (e.g. "ExecutionStatus='Running'"). Leave empty to count all.`
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
required: []
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: "pause_workflow",
|
|
269
|
+
description: "Pause a running workflow execution. The workflow will stop scheduling new tasks until unpaused.",
|
|
270
|
+
inputSchema: {
|
|
271
|
+
type: "object",
|
|
272
|
+
properties: {
|
|
273
|
+
namespace: { type: "string", description: "Namespace containing the workflow." },
|
|
274
|
+
workflow_id: { type: "string", description: "Workflow ID to pause." },
|
|
275
|
+
run_id: { type: "string", description: "Specific run ID (optional)." },
|
|
276
|
+
reason: { type: "string", description: "Human-readable reason for pausing." }
|
|
277
|
+
},
|
|
278
|
+
required: ["workflow_id"]
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
name: "unpause_workflow",
|
|
283
|
+
description: "Resume a previously paused workflow execution.",
|
|
284
|
+
inputSchema: {
|
|
285
|
+
type: "object",
|
|
286
|
+
properties: {
|
|
287
|
+
namespace: { type: "string", description: "Namespace containing the workflow." },
|
|
288
|
+
workflow_id: { type: "string", description: "Workflow ID to unpause." },
|
|
289
|
+
run_id: { type: "string", description: "Specific run ID (optional)." }
|
|
290
|
+
},
|
|
291
|
+
required: ["workflow_id"]
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: "signal_with_start_workflow",
|
|
296
|
+
description: "Start a workflow and send a signal atomically. If the workflow is already running, only the signal is sent. Ideal for event-driven patterns.",
|
|
297
|
+
inputSchema: {
|
|
298
|
+
type: "object",
|
|
299
|
+
properties: {
|
|
300
|
+
namespace: { type: "string", description: "Target namespace." },
|
|
301
|
+
workflow_id: { type: "string", description: "Workflow ID to start or signal." },
|
|
302
|
+
workflow_type: { type: "string", description: "Workflow type to start if not already running." },
|
|
303
|
+
task_queue: { type: "string", description: "Task queue for the workflow." },
|
|
304
|
+
signal_name: { type: "string", description: "Signal name to send." },
|
|
305
|
+
signal_input: { description: "Signal payload. Will be JSON-encoded." },
|
|
306
|
+
workflow_input: { description: "Workflow start input (used only if starting fresh)." }
|
|
307
|
+
},
|
|
308
|
+
required: ["workflow_id", "workflow_type", "task_queue", "signal_name"]
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: "list_workflows",
|
|
313
|
+
description: "List or search workflow executions in a namespace. Supports Temporal's query syntax (e.g. `WorkflowType='OrderWorkflow' AND ExecutionStatus='Running'`). Returns status, type, start time, and IDs.",
|
|
314
|
+
inputSchema: {
|
|
315
|
+
type: "object",
|
|
316
|
+
properties: {
|
|
317
|
+
namespace: {
|
|
318
|
+
type: "string",
|
|
319
|
+
description: "Namespace to query. Defaults to the configured TEMPORAL_NAMESPACE."
|
|
320
|
+
},
|
|
321
|
+
query: {
|
|
322
|
+
type: "string",
|
|
323
|
+
description: "Temporal visibility query (SQL-like filter). Leave empty to list all workflows."
|
|
324
|
+
},
|
|
325
|
+
page_size: {
|
|
326
|
+
type: "number",
|
|
327
|
+
description: "Maximum number of results (default 20, max 1000)."
|
|
328
|
+
},
|
|
329
|
+
next_page_token: {
|
|
330
|
+
type: "string",
|
|
331
|
+
description: "Pagination cursor from a previous list_workflows call."
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
required: []
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
name: "describe_workflow",
|
|
339
|
+
description: "Get full details for a specific workflow execution: status, workflow type, task queue, start/close time, memo, and search attributes.",
|
|
340
|
+
inputSchema: {
|
|
341
|
+
type: "object",
|
|
342
|
+
properties: {
|
|
343
|
+
namespace: { type: "string", description: "Namespace containing the workflow." },
|
|
344
|
+
workflow_id: { type: "string", description: "Workflow ID to describe." },
|
|
345
|
+
run_id: {
|
|
346
|
+
type: "string",
|
|
347
|
+
description: "Specific run ID. Omit to get the latest run."
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
required: ["workflow_id"]
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
name: "start_workflow",
|
|
355
|
+
description: "Start a new workflow execution. Returns the run ID of the newly started workflow.",
|
|
356
|
+
inputSchema: {
|
|
357
|
+
type: "object",
|
|
358
|
+
properties: {
|
|
359
|
+
namespace: { type: "string", description: "Target namespace." },
|
|
360
|
+
workflow_id: {
|
|
361
|
+
type: "string",
|
|
362
|
+
description: "Unique workflow ID. If a workflow with this ID already exists, behavior depends on the ID reuse policy."
|
|
363
|
+
},
|
|
364
|
+
workflow_type: {
|
|
365
|
+
type: "string",
|
|
366
|
+
description: "Registered workflow type / function name."
|
|
367
|
+
},
|
|
368
|
+
task_queue: {
|
|
369
|
+
type: "string",
|
|
370
|
+
description: "Task queue name where workers are polling."
|
|
371
|
+
},
|
|
372
|
+
input: {
|
|
373
|
+
description: "Workflow input payload. Will be JSON-encoded."
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
required: ["workflow_id", "workflow_type", "task_queue"]
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
name: "signal_workflow",
|
|
381
|
+
description: "Send a signal to a running workflow execution.",
|
|
382
|
+
inputSchema: {
|
|
383
|
+
type: "object",
|
|
384
|
+
properties: {
|
|
385
|
+
namespace: { type: "string", description: "Namespace containing the workflow." },
|
|
386
|
+
workflow_id: { type: "string", description: "Target workflow ID." },
|
|
387
|
+
run_id: { type: "string", description: "Specific run ID (optional, targets latest if omitted)." },
|
|
388
|
+
signal_name: { type: "string", description: "Signal name as registered in the workflow." },
|
|
389
|
+
input: { description: "Signal payload. Will be JSON-encoded." }
|
|
390
|
+
},
|
|
391
|
+
required: ["workflow_id", "signal_name"]
|
|
392
|
+
}
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
name: "query_workflow",
|
|
396
|
+
description: "Query a workflow's current state using a registered query handler.",
|
|
397
|
+
inputSchema: {
|
|
398
|
+
type: "object",
|
|
399
|
+
properties: {
|
|
400
|
+
namespace: { type: "string", description: "Namespace containing the workflow." },
|
|
401
|
+
workflow_id: { type: "string", description: "Target workflow ID." },
|
|
402
|
+
run_id: { type: "string", description: "Specific run ID (optional)." },
|
|
403
|
+
query_type: {
|
|
404
|
+
type: "string",
|
|
405
|
+
description: 'Query type name as registered in the workflow (e.g. "getStatus", "__stack_trace").'
|
|
406
|
+
},
|
|
407
|
+
query_args: { description: "Optional query arguments. Will be JSON-encoded." }
|
|
408
|
+
},
|
|
409
|
+
required: ["workflow_id", "query_type"]
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
name: "cancel_workflow",
|
|
414
|
+
description: "Request graceful cancellation of a workflow execution. The workflow will receive a CancellationRequested event and can clean up before stopping.",
|
|
415
|
+
inputSchema: {
|
|
416
|
+
type: "object",
|
|
417
|
+
properties: {
|
|
418
|
+
namespace: { type: "string", description: "Namespace containing the workflow." },
|
|
419
|
+
workflow_id: { type: "string", description: "Workflow ID to cancel." },
|
|
420
|
+
run_id: { type: "string", description: "Specific run ID (optional)." },
|
|
421
|
+
reason: { type: "string", description: "Human-readable reason for cancellation." }
|
|
422
|
+
},
|
|
423
|
+
required: ["workflow_id"]
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
name: "terminate_workflow",
|
|
428
|
+
description: "Force-terminate a workflow execution immediately without cleanup. Prefer cancel_workflow when possible.",
|
|
429
|
+
inputSchema: {
|
|
430
|
+
type: "object",
|
|
431
|
+
properties: {
|
|
432
|
+
namespace: { type: "string", description: "Namespace containing the workflow." },
|
|
433
|
+
workflow_id: { type: "string", description: "Workflow ID to terminate." },
|
|
434
|
+
run_id: { type: "string", description: "Specific run ID (optional)." },
|
|
435
|
+
reason: {
|
|
436
|
+
type: "string",
|
|
437
|
+
description: "Reason for termination (stored in workflow history)."
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
required: ["workflow_id"]
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
];
|
|
444
|
+
var countWorkflowsSchema = z.object({
|
|
445
|
+
namespace: z.string().optional(),
|
|
446
|
+
query: z.string().optional()
|
|
447
|
+
});
|
|
448
|
+
var pauseWorkflowSchema = z.object({
|
|
449
|
+
namespace: z.string().optional(),
|
|
450
|
+
workflow_id: z.string(),
|
|
451
|
+
run_id: z.string().optional(),
|
|
452
|
+
reason: z.string().optional()
|
|
453
|
+
});
|
|
454
|
+
var unpauseWorkflowSchema = z.object({
|
|
455
|
+
namespace: z.string().optional(),
|
|
456
|
+
workflow_id: z.string(),
|
|
457
|
+
run_id: z.string().optional()
|
|
458
|
+
});
|
|
459
|
+
var signalWithStartWorkflowSchema = z.object({
|
|
460
|
+
namespace: z.string().optional(),
|
|
461
|
+
workflow_id: z.string(),
|
|
462
|
+
workflow_type: z.string(),
|
|
463
|
+
task_queue: z.string(),
|
|
464
|
+
signal_name: z.string(),
|
|
465
|
+
signal_input: z.unknown().optional(),
|
|
466
|
+
workflow_input: z.unknown().optional()
|
|
467
|
+
});
|
|
468
|
+
var listWorkflowsSchema = z.object({
|
|
469
|
+
namespace: z.string().optional(),
|
|
470
|
+
query: z.string().optional(),
|
|
471
|
+
page_size: z.number().optional(),
|
|
472
|
+
next_page_token: z.string().optional()
|
|
473
|
+
});
|
|
474
|
+
var describeWorkflowSchema = z.object({
|
|
475
|
+
namespace: z.string().optional(),
|
|
476
|
+
workflow_id: z.string(),
|
|
477
|
+
run_id: z.string().optional()
|
|
478
|
+
});
|
|
479
|
+
var startWorkflowSchema = z.object({
|
|
480
|
+
namespace: z.string().optional(),
|
|
481
|
+
workflow_id: z.string(),
|
|
482
|
+
workflow_type: z.string(),
|
|
483
|
+
task_queue: z.string(),
|
|
484
|
+
input: z.unknown().optional()
|
|
485
|
+
});
|
|
486
|
+
var signalWorkflowSchema = z.object({
|
|
487
|
+
namespace: z.string().optional(),
|
|
488
|
+
workflow_id: z.string(),
|
|
489
|
+
run_id: z.string().optional(),
|
|
490
|
+
signal_name: z.string(),
|
|
491
|
+
input: z.unknown().optional()
|
|
492
|
+
});
|
|
493
|
+
var queryWorkflowSchema = z.object({
|
|
494
|
+
namespace: z.string().optional(),
|
|
495
|
+
workflow_id: z.string(),
|
|
496
|
+
run_id: z.string().optional(),
|
|
497
|
+
query_type: z.string(),
|
|
498
|
+
query_args: z.unknown().optional()
|
|
499
|
+
});
|
|
500
|
+
var cancelWorkflowSchema = z.object({
|
|
501
|
+
namespace: z.string().optional(),
|
|
502
|
+
workflow_id: z.string(),
|
|
503
|
+
run_id: z.string().optional(),
|
|
504
|
+
reason: z.string().optional()
|
|
505
|
+
});
|
|
506
|
+
var terminateWorkflowSchema = z.object({
|
|
507
|
+
namespace: z.string().optional(),
|
|
508
|
+
workflow_id: z.string(),
|
|
509
|
+
run_id: z.string().optional(),
|
|
510
|
+
reason: z.string().optional()
|
|
511
|
+
});
|
|
512
|
+
function fmtTime(t) {
|
|
513
|
+
if (!t) return "N/A";
|
|
514
|
+
if (typeof t === "string") return new Date(t).toISOString();
|
|
515
|
+
if (typeof t === "object") {
|
|
516
|
+
const obj = t;
|
|
517
|
+
if (obj.seconds) return new Date(Number(obj.seconds) * 1e3).toISOString();
|
|
518
|
+
}
|
|
519
|
+
return String(t);
|
|
520
|
+
}
|
|
521
|
+
function extractStatus(exec) {
|
|
522
|
+
const statusCode = exec.status;
|
|
523
|
+
if (!statusCode) return "Unknown";
|
|
524
|
+
const statusMap = {
|
|
525
|
+
"1": "Running",
|
|
526
|
+
"2": "Completed",
|
|
527
|
+
"3": "Failed",
|
|
528
|
+
"4": "Cancelled",
|
|
529
|
+
"5": "Terminated",
|
|
530
|
+
"6": "ContinuedAsNew",
|
|
531
|
+
"7": "TimedOut",
|
|
532
|
+
WORKFLOW_EXECUTION_STATUS_RUNNING: "Running",
|
|
533
|
+
WORKFLOW_EXECUTION_STATUS_COMPLETED: "Completed",
|
|
534
|
+
WORKFLOW_EXECUTION_STATUS_FAILED: "Failed",
|
|
535
|
+
WORKFLOW_EXECUTION_STATUS_CANCELED: "Cancelled",
|
|
536
|
+
WORKFLOW_EXECUTION_STATUS_TERMINATED: "Terminated",
|
|
537
|
+
WORKFLOW_EXECUTION_STATUS_CONTINUED_AS_NEW: "ContinuedAsNew",
|
|
538
|
+
WORKFLOW_EXECUTION_STATUS_TIMED_OUT: "TimedOut"
|
|
539
|
+
};
|
|
540
|
+
return statusMap[String(statusCode)] ?? String(statusCode);
|
|
541
|
+
}
|
|
542
|
+
async function handleListWorkflows(args, client) {
|
|
543
|
+
const ns = client.ns(args.namespace);
|
|
544
|
+
const data = await client.get(
|
|
545
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflows`,
|
|
546
|
+
{
|
|
547
|
+
query: args.query,
|
|
548
|
+
pageSize: args.page_size ?? 20,
|
|
549
|
+
nextPageToken: args.next_page_token
|
|
550
|
+
}
|
|
551
|
+
);
|
|
552
|
+
const executions = data.executions ?? [];
|
|
553
|
+
const lines = [
|
|
554
|
+
`# Workflows in "${ns}" (${executions.length} returned)`,
|
|
555
|
+
""
|
|
556
|
+
];
|
|
557
|
+
for (const exec of executions) {
|
|
558
|
+
const execution = exec.execution;
|
|
559
|
+
const type = exec.type;
|
|
560
|
+
lines.push(`## ${execution?.workflowId ?? "unknown"}`);
|
|
561
|
+
lines.push(`- Run ID: ${execution?.runId ?? "N/A"}`);
|
|
562
|
+
lines.push(`- Type: ${type?.name ?? "N/A"}`);
|
|
563
|
+
lines.push(`- Status: ${extractStatus(exec)}`);
|
|
564
|
+
lines.push(`- Started: ${fmtTime(exec.startTime)}`);
|
|
565
|
+
if (exec.closeTime) lines.push(`- Closed: ${fmtTime(exec.closeTime)}`);
|
|
566
|
+
if (exec.taskQueue) {
|
|
567
|
+
const tq = exec.taskQueue;
|
|
568
|
+
lines.push(`- Task Queue: ${tq.name ?? exec.taskQueue}`);
|
|
569
|
+
}
|
|
570
|
+
lines.push("");
|
|
571
|
+
}
|
|
572
|
+
if (data.nextPageToken) {
|
|
573
|
+
lines.push(`*Next page token: ${data.nextPageToken}*`);
|
|
574
|
+
}
|
|
575
|
+
return {
|
|
576
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
577
|
+
structuredContent: {
|
|
578
|
+
namespace: ns,
|
|
579
|
+
count: executions.length,
|
|
580
|
+
workflows: executions.map((exec) => {
|
|
581
|
+
const execution = exec.execution;
|
|
582
|
+
const type = exec.type;
|
|
583
|
+
return {
|
|
584
|
+
workflowId: execution?.workflowId,
|
|
585
|
+
runId: execution?.runId,
|
|
586
|
+
type: type?.name,
|
|
587
|
+
status: extractStatus(exec),
|
|
588
|
+
startTime: exec.startTime,
|
|
589
|
+
closeTime: exec.closeTime
|
|
590
|
+
};
|
|
591
|
+
}),
|
|
592
|
+
nextPageToken: data.nextPageToken
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
async function handleDescribeWorkflow(args, client) {
|
|
597
|
+
const ns = client.ns(args.namespace);
|
|
598
|
+
const params = {};
|
|
599
|
+
if (args.run_id) params["execution.runId"] = args.run_id;
|
|
600
|
+
const data = await client.get(
|
|
601
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflows/${encodeURIComponent(args.workflow_id)}`,
|
|
602
|
+
params
|
|
603
|
+
);
|
|
604
|
+
const execInfo = data.workflowExecutionInfo;
|
|
605
|
+
const execution = execInfo?.execution;
|
|
606
|
+
const type = execInfo?.type;
|
|
607
|
+
const pendingActs = data.pendingActivities;
|
|
608
|
+
const pendingChildren = data.pendingChildren;
|
|
609
|
+
const lines = [
|
|
610
|
+
`# Workflow: ${execution?.workflowId ?? args.workflow_id}`,
|
|
611
|
+
""
|
|
612
|
+
];
|
|
613
|
+
if (execution?.runId) lines.push(`- Run ID: ${execution.runId}`);
|
|
614
|
+
if (type?.name) lines.push(`- Type: ${type.name}`);
|
|
615
|
+
if (execInfo) lines.push(`- Status: ${extractStatus(execInfo)}`);
|
|
616
|
+
if (execInfo?.startTime) lines.push(`- Started: ${fmtTime(execInfo.startTime)}`);
|
|
617
|
+
if (execInfo?.closeTime) lines.push(`- Closed: ${fmtTime(execInfo.closeTime)}`);
|
|
618
|
+
if (execInfo?.taskQueue) {
|
|
619
|
+
const tq = execInfo.taskQueue;
|
|
620
|
+
lines.push(`- Task Queue: ${tq.name ?? execInfo.taskQueue}`);
|
|
621
|
+
}
|
|
622
|
+
if (execInfo?.historyLength) lines.push(`- History Events: ${execInfo.historyLength}`);
|
|
623
|
+
if (pendingActs?.length) {
|
|
624
|
+
lines.push("", `## Pending Activities (${pendingActs.length})`);
|
|
625
|
+
for (const act of pendingActs) {
|
|
626
|
+
const a = act;
|
|
627
|
+
lines.push(`- ${a.activityId}: ${a.activityType?.name ?? "unknown"} [${a.state ?? ""}]`);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
if (pendingChildren?.length) {
|
|
631
|
+
lines.push("", `## Pending Child Workflows (${pendingChildren.length})`);
|
|
632
|
+
for (const child of pendingChildren) {
|
|
633
|
+
const c = child;
|
|
634
|
+
lines.push(`- ${c.workflowId}: ${c.workflowTypeName ?? "unknown"}`);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
return {
|
|
638
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
639
|
+
structuredContent: {
|
|
640
|
+
workflowId: execution?.workflowId,
|
|
641
|
+
runId: execution?.runId,
|
|
642
|
+
type: type?.name,
|
|
643
|
+
status: execInfo ? extractStatus(execInfo) : void 0,
|
|
644
|
+
startTime: execInfo?.startTime,
|
|
645
|
+
closeTime: execInfo?.closeTime,
|
|
646
|
+
taskQueue: (() => {
|
|
647
|
+
const tq = execInfo?.taskQueue;
|
|
648
|
+
return tq?.name ?? execInfo?.taskQueue;
|
|
649
|
+
})(),
|
|
650
|
+
historyLength: execInfo?.historyLength,
|
|
651
|
+
pendingActivities: pendingActs?.length ?? 0,
|
|
652
|
+
pendingChildren: pendingChildren?.length ?? 0
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
function encodePayload(value) {
|
|
657
|
+
const json = JSON.stringify(value);
|
|
658
|
+
const b64 = Buffer.from(json).toString("base64");
|
|
659
|
+
return {
|
|
660
|
+
metadata: { encoding: Buffer.from("json/plain").toString("base64") },
|
|
661
|
+
data: b64
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
async function handleStartWorkflow(args, client) {
|
|
665
|
+
const ns = client.ns(args.namespace);
|
|
666
|
+
const body = {
|
|
667
|
+
workflowType: { name: args.workflow_type },
|
|
668
|
+
taskQueue: { name: args.task_queue }
|
|
669
|
+
};
|
|
670
|
+
if (args.input !== void 0) {
|
|
671
|
+
body.input = { payloads: [encodePayload(args.input)] };
|
|
672
|
+
}
|
|
673
|
+
const data = await client.post(
|
|
674
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflows/${encodeURIComponent(args.workflow_id)}`,
|
|
675
|
+
body
|
|
676
|
+
);
|
|
677
|
+
const lines = [
|
|
678
|
+
`# Workflow Started`,
|
|
679
|
+
`- Workflow ID: ${args.workflow_id}`,
|
|
680
|
+
`- Run ID: ${data.runId ?? "N/A"}`,
|
|
681
|
+
`- Started: ${data.started !== void 0 ? data.started : "yes"}`
|
|
682
|
+
];
|
|
683
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
684
|
+
}
|
|
685
|
+
async function handleSignalWorkflow(args, client) {
|
|
686
|
+
const ns = client.ns(args.namespace);
|
|
687
|
+
const body = {};
|
|
688
|
+
if (args.run_id) body["workflowExecution"] = { workflowId: args.workflow_id, runId: args.run_id };
|
|
689
|
+
if (args.input !== void 0) body.input = { payloads: [encodePayload(args.input)] };
|
|
690
|
+
await client.post(
|
|
691
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflows/${encodeURIComponent(args.workflow_id)}/signal/${encodeURIComponent(args.signal_name)}`,
|
|
692
|
+
body
|
|
693
|
+
);
|
|
694
|
+
return {
|
|
695
|
+
content: [{
|
|
696
|
+
type: "text",
|
|
697
|
+
text: `Signal "${args.signal_name}" sent to workflow "${args.workflow_id}" successfully.`
|
|
698
|
+
}]
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
async function handleQueryWorkflow(args, client) {
|
|
702
|
+
const ns = client.ns(args.namespace);
|
|
703
|
+
const body = {};
|
|
704
|
+
if (args.run_id) body.execution = { workflowId: args.workflow_id, runId: args.run_id };
|
|
705
|
+
if (args.query_args !== void 0) body.query = { queryArgs: { payloads: [encodePayload(args.query_args)] } };
|
|
706
|
+
const data = await client.post(
|
|
707
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflows/${encodeURIComponent(args.workflow_id)}/query/${encodeURIComponent(args.query_type)}`,
|
|
708
|
+
body
|
|
709
|
+
);
|
|
710
|
+
const result = data.queryResult;
|
|
711
|
+
const payloads = result?.payloads;
|
|
712
|
+
let resultText = JSON.stringify(data, null, 2);
|
|
713
|
+
if (payloads?.length) {
|
|
714
|
+
try {
|
|
715
|
+
const payload = payloads[0];
|
|
716
|
+
if (payload.data) {
|
|
717
|
+
const decoded = Buffer.from(payload.data, "base64").toString("utf-8");
|
|
718
|
+
resultText = decoded;
|
|
719
|
+
}
|
|
720
|
+
} catch {
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
const lines = [
|
|
724
|
+
`# Query Result: ${args.query_type}`,
|
|
725
|
+
`Workflow: ${args.workflow_id}`,
|
|
726
|
+
"",
|
|
727
|
+
"```json",
|
|
728
|
+
resultText,
|
|
729
|
+
"```"
|
|
730
|
+
];
|
|
731
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
732
|
+
}
|
|
733
|
+
async function handleCancelWorkflow(args, client) {
|
|
734
|
+
const ns = client.ns(args.namespace);
|
|
735
|
+
const body = {};
|
|
736
|
+
if (args.run_id) body.workflowExecution = { workflowId: args.workflow_id, runId: args.run_id };
|
|
737
|
+
if (args.reason) body.reason = args.reason;
|
|
738
|
+
await client.post(
|
|
739
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflows/${encodeURIComponent(args.workflow_id)}/cancel`,
|
|
740
|
+
body
|
|
741
|
+
);
|
|
742
|
+
return {
|
|
743
|
+
content: [{
|
|
744
|
+
type: "text",
|
|
745
|
+
text: `Cancellation requested for workflow "${args.workflow_id}"${args.reason ? ` (reason: ${args.reason})` : ""}.`
|
|
746
|
+
}]
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
async function handleTerminateWorkflow(args, client) {
|
|
750
|
+
const ns = client.ns(args.namespace);
|
|
751
|
+
const body = {};
|
|
752
|
+
if (args.run_id) body.workflowExecution = { workflowId: args.workflow_id, runId: args.run_id };
|
|
753
|
+
if (args.reason) body.reason = args.reason;
|
|
754
|
+
await client.post(
|
|
755
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflows/${encodeURIComponent(args.workflow_id)}/terminate`,
|
|
756
|
+
body
|
|
757
|
+
);
|
|
758
|
+
return {
|
|
759
|
+
content: [{
|
|
760
|
+
type: "text",
|
|
761
|
+
text: `Workflow "${args.workflow_id}" terminated${args.reason ? ` (reason: ${args.reason})` : ""}.`
|
|
762
|
+
}]
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
async function handleCountWorkflows(args, client) {
|
|
766
|
+
const ns = client.ns(args.namespace);
|
|
767
|
+
const data = await client.get(
|
|
768
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflow-count`,
|
|
769
|
+
{ query: args.query }
|
|
770
|
+
);
|
|
771
|
+
const count = data.count ?? 0;
|
|
772
|
+
const groups = data.groups;
|
|
773
|
+
const lines = [
|
|
774
|
+
`# Workflow Count in "${ns}"`,
|
|
775
|
+
"",
|
|
776
|
+
`Total: **${count}**`
|
|
777
|
+
];
|
|
778
|
+
if (groups?.length) {
|
|
779
|
+
lines.push("", "## Breakdown");
|
|
780
|
+
for (const g of groups) {
|
|
781
|
+
const groupValues = g.groupValues;
|
|
782
|
+
const label = groupValues?.map((v) => v.data ?? v).join(", ") ?? JSON.stringify(g);
|
|
783
|
+
lines.push(`- ${label}: ${g.count}`);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return {
|
|
787
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
788
|
+
structuredContent: {
|
|
789
|
+
namespace: ns,
|
|
790
|
+
count: Number(count),
|
|
791
|
+
query: args.query ?? null,
|
|
792
|
+
groups: groups?.map((g) => ({
|
|
793
|
+
count: g.count,
|
|
794
|
+
groupValues: g.groupValues
|
|
795
|
+
})) ?? []
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
async function handlePauseWorkflow(args, client) {
|
|
800
|
+
const ns = client.ns(args.namespace);
|
|
801
|
+
const body = {};
|
|
802
|
+
if (args.run_id) body.workflowExecution = { workflowId: args.workflow_id, runId: args.run_id };
|
|
803
|
+
if (args.reason) body.reason = args.reason;
|
|
804
|
+
await client.post(
|
|
805
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflows/${encodeURIComponent(args.workflow_id)}/pause`,
|
|
806
|
+
body
|
|
807
|
+
);
|
|
808
|
+
return {
|
|
809
|
+
content: [{
|
|
810
|
+
type: "text",
|
|
811
|
+
text: `Workflow "${args.workflow_id}" paused${args.reason ? ` (reason: ${args.reason})` : ""}.`
|
|
812
|
+
}]
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
async function handleUnpauseWorkflow(args, client) {
|
|
816
|
+
const ns = client.ns(args.namespace);
|
|
817
|
+
const body = {};
|
|
818
|
+
if (args.run_id) body.workflowExecution = { workflowId: args.workflow_id, runId: args.run_id };
|
|
819
|
+
await client.post(
|
|
820
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflows/${encodeURIComponent(args.workflow_id)}/unpause`,
|
|
821
|
+
body
|
|
822
|
+
);
|
|
823
|
+
return {
|
|
824
|
+
content: [{ type: "text", text: `Workflow "${args.workflow_id}" unpaused.` }]
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
async function handleSignalWithStartWorkflow(args, client) {
|
|
828
|
+
const ns = client.ns(args.namespace);
|
|
829
|
+
const body = {
|
|
830
|
+
workflowType: { name: args.workflow_type },
|
|
831
|
+
taskQueue: { name: args.task_queue },
|
|
832
|
+
signalName: args.signal_name
|
|
833
|
+
};
|
|
834
|
+
if (args.signal_input !== void 0) body.signalInput = { payloads: [encodePayload(args.signal_input)] };
|
|
835
|
+
if (args.workflow_input !== void 0) body.input = { payloads: [encodePayload(args.workflow_input)] };
|
|
836
|
+
const data = await client.post(
|
|
837
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflows/${encodeURIComponent(args.workflow_id)}/signal-with-start/${encodeURIComponent(args.signal_name)}`,
|
|
838
|
+
body
|
|
839
|
+
);
|
|
840
|
+
return {
|
|
841
|
+
content: [{
|
|
842
|
+
type: "text",
|
|
843
|
+
text: [
|
|
844
|
+
`# signal_with_start: "${args.workflow_id}"`,
|
|
845
|
+
`- Signal: ${args.signal_name}`,
|
|
846
|
+
`- Run ID: ${data.runId ?? "N/A"}`,
|
|
847
|
+
`- Started: ${data.started !== void 0 ? data.started : "yes (or already running)"}`
|
|
848
|
+
].join("\n")
|
|
849
|
+
}]
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
var historyToolDefinitions = [
|
|
853
|
+
{
|
|
854
|
+
name: "get_workflow_history",
|
|
855
|
+
description: "Get the event history of a workflow execution. Useful for debugging failures, understanding execution flow, and auditing. Returns a human-readable summary of history events.",
|
|
856
|
+
inputSchema: {
|
|
857
|
+
type: "object",
|
|
858
|
+
properties: {
|
|
859
|
+
namespace: { type: "string", description: "Namespace containing the workflow." },
|
|
860
|
+
workflow_id: { type: "string", description: "Workflow ID." },
|
|
861
|
+
run_id: { type: "string", description: "Specific run ID (optional, uses latest run if omitted)." },
|
|
862
|
+
reverse: {
|
|
863
|
+
type: "boolean",
|
|
864
|
+
description: "If true, return history in reverse chronological order (most recent first). Useful for checking the latest events of a long-running workflow."
|
|
865
|
+
},
|
|
866
|
+
page_size: {
|
|
867
|
+
type: "number",
|
|
868
|
+
description: "Maximum number of history events to return (default 50)."
|
|
869
|
+
},
|
|
870
|
+
next_page_token: {
|
|
871
|
+
type: "string",
|
|
872
|
+
description: "Pagination cursor from a previous get_workflow_history call."
|
|
873
|
+
}
|
|
874
|
+
},
|
|
875
|
+
required: ["workflow_id"]
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
];
|
|
879
|
+
var getWorkflowHistorySchema = z.object({
|
|
880
|
+
namespace: z.string().optional(),
|
|
881
|
+
workflow_id: z.string(),
|
|
882
|
+
run_id: z.string().optional(),
|
|
883
|
+
reverse: z.boolean().optional(),
|
|
884
|
+
page_size: z.number().optional(),
|
|
885
|
+
next_page_token: z.string().optional()
|
|
886
|
+
});
|
|
887
|
+
var EVENT_TYPE_LABELS = {
|
|
888
|
+
EVENT_TYPE_WORKFLOW_EXECUTION_STARTED: "WorkflowExecutionStarted",
|
|
889
|
+
EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED: "WorkflowExecutionCompleted",
|
|
890
|
+
EVENT_TYPE_WORKFLOW_EXECUTION_FAILED: "WorkflowExecutionFailed",
|
|
891
|
+
EVENT_TYPE_WORKFLOW_EXECUTION_TIMED_OUT: "WorkflowExecutionTimedOut",
|
|
892
|
+
EVENT_TYPE_WORKFLOW_EXECUTION_CANCELED: "WorkflowExecutionCanceled",
|
|
893
|
+
EVENT_TYPE_WORKFLOW_EXECUTION_TERMINATED: "WorkflowExecutionTerminated",
|
|
894
|
+
EVENT_TYPE_WORKFLOW_EXECUTION_CONTINUED_AS_NEW: "WorkflowExecutionContinuedAsNew",
|
|
895
|
+
EVENT_TYPE_WORKFLOW_TASK_SCHEDULED: "WorkflowTaskScheduled",
|
|
896
|
+
EVENT_TYPE_WORKFLOW_TASK_STARTED: "WorkflowTaskStarted",
|
|
897
|
+
EVENT_TYPE_WORKFLOW_TASK_COMPLETED: "WorkflowTaskCompleted",
|
|
898
|
+
EVENT_TYPE_WORKFLOW_TASK_FAILED: "WorkflowTaskFailed",
|
|
899
|
+
EVENT_TYPE_WORKFLOW_TASK_TIMED_OUT: "WorkflowTaskTimedOut",
|
|
900
|
+
EVENT_TYPE_ACTIVITY_TASK_SCHEDULED: "ActivityTaskScheduled",
|
|
901
|
+
EVENT_TYPE_ACTIVITY_TASK_STARTED: "ActivityTaskStarted",
|
|
902
|
+
EVENT_TYPE_ACTIVITY_TASK_COMPLETED: "ActivityTaskCompleted",
|
|
903
|
+
EVENT_TYPE_ACTIVITY_TASK_FAILED: "ActivityTaskFailed",
|
|
904
|
+
EVENT_TYPE_ACTIVITY_TASK_TIMED_OUT: "ActivityTaskTimedOut",
|
|
905
|
+
EVENT_TYPE_ACTIVITY_TASK_CANCEL_REQUESTED: "ActivityTaskCancelRequested",
|
|
906
|
+
EVENT_TYPE_ACTIVITY_TASK_CANCELED: "ActivityTaskCanceled",
|
|
907
|
+
EVENT_TYPE_TIMER_STARTED: "TimerStarted",
|
|
908
|
+
EVENT_TYPE_TIMER_FIRED: "TimerFired",
|
|
909
|
+
EVENT_TYPE_TIMER_CANCELED: "TimerCanceled",
|
|
910
|
+
EVENT_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED: "SignalExternalWorkflowInitiated",
|
|
911
|
+
EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED: "WorkflowExecutionSignaled",
|
|
912
|
+
EVENT_TYPE_START_CHILD_WORKFLOW_EXECUTION_INITIATED: "StartChildWorkflowInitiated",
|
|
913
|
+
EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_STARTED: "ChildWorkflowStarted",
|
|
914
|
+
EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_COMPLETED: "ChildWorkflowCompleted",
|
|
915
|
+
EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_FAILED: "ChildWorkflowFailed",
|
|
916
|
+
EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_CANCELED: "ChildWorkflowCanceled",
|
|
917
|
+
EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_TERMINATED: "ChildWorkflowTerminated",
|
|
918
|
+
EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_TIMED_OUT: "ChildWorkflowTimedOut"
|
|
919
|
+
};
|
|
920
|
+
function labelEvent(eventType) {
|
|
921
|
+
return EVENT_TYPE_LABELS[eventType] ?? eventType.replace(/^EVENT_TYPE_/, "");
|
|
922
|
+
}
|
|
923
|
+
function eventDetail(event) {
|
|
924
|
+
const type = event.eventType;
|
|
925
|
+
if (!type) return "";
|
|
926
|
+
if (type === "EVENT_TYPE_ACTIVITY_TASK_SCHEDULED") {
|
|
927
|
+
const attr = event.activityTaskScheduledEventAttributes;
|
|
928
|
+
const actType = attr?.activityType;
|
|
929
|
+
if (actType?.name) return ` \u2192 ${actType.name}`;
|
|
930
|
+
if (attr?.activityId) return ` id=${attr.activityId}`;
|
|
931
|
+
}
|
|
932
|
+
if (type === "EVENT_TYPE_ACTIVITY_TASK_FAILED") {
|
|
933
|
+
const attr = event.activityTaskFailedEventAttributes;
|
|
934
|
+
const failure = attr?.failure;
|
|
935
|
+
if (failure?.message) return ` \u2717 ${failure.message}`;
|
|
936
|
+
}
|
|
937
|
+
if (type === "EVENT_TYPE_WORKFLOW_EXECUTION_FAILED") {
|
|
938
|
+
const attr = event.workflowExecutionFailedEventAttributes;
|
|
939
|
+
const failure = attr?.failure;
|
|
940
|
+
if (failure?.message) return ` \u2717 ${failure.message}`;
|
|
941
|
+
}
|
|
942
|
+
if (type === "EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED") {
|
|
943
|
+
const attr = event.workflowExecutionSignaledEventAttributes;
|
|
944
|
+
if (attr?.signalName) return ` "${attr.signalName}"`;
|
|
945
|
+
}
|
|
946
|
+
if (type === "EVENT_TYPE_TIMER_STARTED") {
|
|
947
|
+
const attr = event.timerStartedEventAttributes;
|
|
948
|
+
if (attr?.startToFireTimeout) return ` timeout=${attr.startToFireTimeout}`;
|
|
949
|
+
}
|
|
950
|
+
return "";
|
|
951
|
+
}
|
|
952
|
+
function fmtTime2(t) {
|
|
953
|
+
if (!t) return "";
|
|
954
|
+
if (typeof t === "string") return new Date(t).toISOString();
|
|
955
|
+
if (typeof t === "object") {
|
|
956
|
+
const obj = t;
|
|
957
|
+
if (obj.seconds) return new Date(Number(obj.seconds) * 1e3).toISOString();
|
|
958
|
+
}
|
|
959
|
+
return String(t);
|
|
960
|
+
}
|
|
961
|
+
async function handleGetWorkflowHistory(args, client) {
|
|
962
|
+
const ns = client.ns(args.namespace);
|
|
963
|
+
const endpoint = args.reverse ? `/api/v1/namespaces/${encodeURIComponent(ns)}/workflows/${encodeURIComponent(args.workflow_id)}/history-reverse` : `/api/v1/namespaces/${encodeURIComponent(ns)}/workflows/${encodeURIComponent(args.workflow_id)}/history`;
|
|
964
|
+
const params = {
|
|
965
|
+
pageSize: args.page_size ?? 50,
|
|
966
|
+
nextPageToken: args.next_page_token
|
|
967
|
+
};
|
|
968
|
+
if (args.run_id) params["execution.runId"] = args.run_id;
|
|
969
|
+
const data = await client.get(endpoint, params);
|
|
970
|
+
const history = data.history;
|
|
971
|
+
const events = history?.events ?? data.events ?? [];
|
|
972
|
+
const lines = [
|
|
973
|
+
`# Workflow History: ${args.workflow_id}`,
|
|
974
|
+
`${args.reverse ? "(reversed)" : ""} ${events.length} events returned`,
|
|
975
|
+
""
|
|
976
|
+
];
|
|
977
|
+
for (const event of events) {
|
|
978
|
+
const eventId = event.eventId ?? "?";
|
|
979
|
+
const eventType = String(event.eventType ?? "");
|
|
980
|
+
const time = fmtTime2(event.eventTime);
|
|
981
|
+
const detail = eventDetail(event);
|
|
982
|
+
lines.push(`${String(eventId).padStart(4)} ${labelEvent(eventType)}${detail} [${time}]`);
|
|
983
|
+
}
|
|
984
|
+
if (data.nextPageToken) {
|
|
985
|
+
lines.push("", `*Next page token: ${data.nextPageToken}*`);
|
|
986
|
+
}
|
|
987
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
988
|
+
}
|
|
989
|
+
var scheduleToolDefinitions = [
|
|
990
|
+
{
|
|
991
|
+
name: "list_schedules",
|
|
992
|
+
description: "List all schedules in a namespace.",
|
|
993
|
+
inputSchema: {
|
|
994
|
+
type: "object",
|
|
995
|
+
properties: {
|
|
996
|
+
namespace: { type: "string", description: "Target namespace." },
|
|
997
|
+
page_size: { type: "number", description: "Max results (default 20)." },
|
|
998
|
+
next_page_token: { type: "string", description: "Pagination cursor." }
|
|
999
|
+
},
|
|
1000
|
+
required: []
|
|
1001
|
+
}
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
name: "describe_schedule",
|
|
1005
|
+
description: "Get full details of a specific schedule including spec, actions, state, and upcoming run times.",
|
|
1006
|
+
inputSchema: {
|
|
1007
|
+
type: "object",
|
|
1008
|
+
properties: {
|
|
1009
|
+
namespace: { type: "string", description: "Namespace containing the schedule." },
|
|
1010
|
+
schedule_id: { type: "string", description: "Schedule ID." }
|
|
1011
|
+
},
|
|
1012
|
+
required: ["schedule_id"]
|
|
1013
|
+
}
|
|
1014
|
+
},
|
|
1015
|
+
{
|
|
1016
|
+
name: "create_schedule",
|
|
1017
|
+
description: "Create a new schedule that starts a workflow on a recurring basis. The schedule_spec uses cron-style spec or interval.",
|
|
1018
|
+
inputSchema: {
|
|
1019
|
+
type: "object",
|
|
1020
|
+
properties: {
|
|
1021
|
+
namespace: { type: "string", description: "Target namespace." },
|
|
1022
|
+
schedule_id: { type: "string", description: "Unique schedule ID." },
|
|
1023
|
+
cron_expression: {
|
|
1024
|
+
type: "string",
|
|
1025
|
+
description: 'Cron expression (e.g. "0 * * * *" for every hour). Use this OR interval_seconds.'
|
|
1026
|
+
},
|
|
1027
|
+
interval_seconds: {
|
|
1028
|
+
type: "number",
|
|
1029
|
+
description: "Run interval in seconds (e.g. 3600 for every hour). Use this OR cron_expression."
|
|
1030
|
+
},
|
|
1031
|
+
workflow_type: { type: "string", description: "Workflow type to start on each trigger." },
|
|
1032
|
+
workflow_id_prefix: {
|
|
1033
|
+
type: "string",
|
|
1034
|
+
description: "Prefix for workflow IDs (schedule ID used if omitted)."
|
|
1035
|
+
},
|
|
1036
|
+
task_queue: { type: "string", description: "Task queue for the triggered workflows." },
|
|
1037
|
+
input: { description: "Input payload for triggered workflows." },
|
|
1038
|
+
paused: { type: "boolean", description: "Create the schedule in a paused state (default false)." },
|
|
1039
|
+
notes: { type: "string", description: "Human-readable notes." }
|
|
1040
|
+
},
|
|
1041
|
+
required: ["schedule_id", "workflow_type", "task_queue"]
|
|
1042
|
+
}
|
|
1043
|
+
},
|
|
1044
|
+
{
|
|
1045
|
+
name: "delete_schedule",
|
|
1046
|
+
description: "Delete a schedule. This does not affect any workflow executions already started by the schedule.",
|
|
1047
|
+
inputSchema: {
|
|
1048
|
+
type: "object",
|
|
1049
|
+
properties: {
|
|
1050
|
+
namespace: { type: "string", description: "Namespace containing the schedule." },
|
|
1051
|
+
schedule_id: { type: "string", description: "Schedule ID to delete." }
|
|
1052
|
+
},
|
|
1053
|
+
required: ["schedule_id"]
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
];
|
|
1057
|
+
var listSchedulesSchema = z.object({
|
|
1058
|
+
namespace: z.string().optional(),
|
|
1059
|
+
page_size: z.number().optional(),
|
|
1060
|
+
next_page_token: z.string().optional()
|
|
1061
|
+
});
|
|
1062
|
+
var describeScheduleSchema = z.object({
|
|
1063
|
+
namespace: z.string().optional(),
|
|
1064
|
+
schedule_id: z.string()
|
|
1065
|
+
});
|
|
1066
|
+
var createScheduleSchema = z.object({
|
|
1067
|
+
namespace: z.string().optional(),
|
|
1068
|
+
schedule_id: z.string(),
|
|
1069
|
+
cron_expression: z.string().optional(),
|
|
1070
|
+
interval_seconds: z.number().optional(),
|
|
1071
|
+
workflow_type: z.string(),
|
|
1072
|
+
workflow_id_prefix: z.string().optional(),
|
|
1073
|
+
task_queue: z.string(),
|
|
1074
|
+
input: z.unknown().optional(),
|
|
1075
|
+
paused: z.boolean().optional(),
|
|
1076
|
+
notes: z.string().optional()
|
|
1077
|
+
});
|
|
1078
|
+
var deleteScheduleSchema = z.object({
|
|
1079
|
+
namespace: z.string().optional(),
|
|
1080
|
+
schedule_id: z.string()
|
|
1081
|
+
});
|
|
1082
|
+
async function handleListSchedules(args, client) {
|
|
1083
|
+
const ns = client.ns(args.namespace);
|
|
1084
|
+
const data = await client.get(
|
|
1085
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/schedules`,
|
|
1086
|
+
{ pageSize: args.page_size ?? 20, nextPageToken: args.next_page_token }
|
|
1087
|
+
);
|
|
1088
|
+
const schedules = data.schedules ?? [];
|
|
1089
|
+
const lines = [`# Schedules in "${ns}" (${schedules.length} returned)`, ""];
|
|
1090
|
+
for (const s of schedules) {
|
|
1091
|
+
const info = s.info;
|
|
1092
|
+
lines.push(`## ${s.scheduleId ?? "unknown"}`);
|
|
1093
|
+
if (info?.workflowType) {
|
|
1094
|
+
const wt = info.workflowType;
|
|
1095
|
+
lines.push(`- Workflow Type: ${wt.name ?? info.workflowType}`);
|
|
1096
|
+
}
|
|
1097
|
+
const state = s.state;
|
|
1098
|
+
if (state?.paused !== void 0) lines.push(`- Paused: ${state.paused}`);
|
|
1099
|
+
if (info?.recentActions) {
|
|
1100
|
+
const recent = info.recentActions;
|
|
1101
|
+
lines.push(`- Recent Actions: ${recent.length}`);
|
|
1102
|
+
}
|
|
1103
|
+
if (info?.futureActionTimes) {
|
|
1104
|
+
const times = info.futureActionTimes;
|
|
1105
|
+
if (times.length > 0) lines.push(`- Next Run: ${times[0]}`);
|
|
1106
|
+
}
|
|
1107
|
+
lines.push("");
|
|
1108
|
+
}
|
|
1109
|
+
if (data.nextPageToken) lines.push(`*Next page token: ${data.nextPageToken}*`);
|
|
1110
|
+
return {
|
|
1111
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
1112
|
+
structuredContent: {
|
|
1113
|
+
namespace: ns,
|
|
1114
|
+
schedules: schedules.map((s) => {
|
|
1115
|
+
const info = s.info;
|
|
1116
|
+
const state = s.state;
|
|
1117
|
+
const wt = info?.workflowType;
|
|
1118
|
+
const future = info?.futureActionTimes;
|
|
1119
|
+
return {
|
|
1120
|
+
scheduleId: s.scheduleId,
|
|
1121
|
+
workflowType: wt?.name ?? info?.workflowType,
|
|
1122
|
+
paused: state?.paused,
|
|
1123
|
+
nextRun: future?.[0] ?? null
|
|
1124
|
+
};
|
|
1125
|
+
}),
|
|
1126
|
+
nextPageToken: data.nextPageToken
|
|
1127
|
+
}
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
async function handleDescribeSchedule(args, client) {
|
|
1131
|
+
const ns = client.ns(args.namespace);
|
|
1132
|
+
const data = await client.get(
|
|
1133
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/schedules/${encodeURIComponent(args.schedule_id)}`
|
|
1134
|
+
);
|
|
1135
|
+
const schedule = data.schedule;
|
|
1136
|
+
const spec = schedule?.spec;
|
|
1137
|
+
const action = schedule?.action;
|
|
1138
|
+
const state = schedule?.state;
|
|
1139
|
+
const info = data.info;
|
|
1140
|
+
const lines = [`# Schedule: ${args.schedule_id}`, ""];
|
|
1141
|
+
if (state?.paused !== void 0) lines.push(`- Paused: ${state.paused}`);
|
|
1142
|
+
if (state?.notes) lines.push(`- Notes: ${state.notes}`);
|
|
1143
|
+
if (spec) {
|
|
1144
|
+
lines.push("", "## Spec");
|
|
1145
|
+
const cronStrings = spec.cronString;
|
|
1146
|
+
if (cronStrings?.length) lines.push(`- Cron: ${cronStrings.join(", ")}`);
|
|
1147
|
+
const intervals = spec.interval;
|
|
1148
|
+
if (intervals?.length) {
|
|
1149
|
+
intervals.forEach((iv) => {
|
|
1150
|
+
const i = iv;
|
|
1151
|
+
lines.push(`- Interval: ${i.interval ?? JSON.stringify(i)}`);
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
if (action) {
|
|
1156
|
+
lines.push("", "## Action");
|
|
1157
|
+
const startWorkflow = action.startWorkflow;
|
|
1158
|
+
if (startWorkflow) {
|
|
1159
|
+
const wt = startWorkflow.workflowType;
|
|
1160
|
+
if (wt?.name) lines.push(`- Workflow Type: ${wt.name}`);
|
|
1161
|
+
const tq = startWorkflow.taskQueue;
|
|
1162
|
+
if (tq?.name) lines.push(`- Task Queue: ${tq.name}`);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
if (info) {
|
|
1166
|
+
const future = info.futureActionTimes;
|
|
1167
|
+
if (future?.length) {
|
|
1168
|
+
lines.push("", "## Upcoming Runs");
|
|
1169
|
+
future.slice(0, 5).forEach((t) => lines.push(`- ${t}`));
|
|
1170
|
+
}
|
|
1171
|
+
const recent = info.recentActions;
|
|
1172
|
+
if (recent?.length) {
|
|
1173
|
+
lines.push("", `## Recent Actions (${recent.length})`);
|
|
1174
|
+
recent.slice(0, 5).forEach((a) => {
|
|
1175
|
+
lines.push(`- ${a.scheduleTime ?? JSON.stringify(a)}`);
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1180
|
+
}
|
|
1181
|
+
function encodePayload2(value) {
|
|
1182
|
+
return {
|
|
1183
|
+
metadata: { encoding: Buffer.from("json/plain").toString("base64") },
|
|
1184
|
+
data: Buffer.from(JSON.stringify(value)).toString("base64")
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
async function handleCreateSchedule(args, client) {
|
|
1188
|
+
const ns = client.ns(args.namespace);
|
|
1189
|
+
const spec = {};
|
|
1190
|
+
if (args.cron_expression) spec.cronString = [args.cron_expression];
|
|
1191
|
+
if (args.interval_seconds) spec.interval = [{ interval: `${args.interval_seconds}s` }];
|
|
1192
|
+
const startWorkflow = {
|
|
1193
|
+
workflowType: { name: args.workflow_type },
|
|
1194
|
+
taskQueue: { name: args.task_queue },
|
|
1195
|
+
workflowId: `${args.workflow_id_prefix ?? args.schedule_id}-${Date.now()}`
|
|
1196
|
+
};
|
|
1197
|
+
if (args.input !== void 0) {
|
|
1198
|
+
startWorkflow.input = { payloads: [encodePayload2(args.input)] };
|
|
1199
|
+
}
|
|
1200
|
+
const body = {
|
|
1201
|
+
schedule: {
|
|
1202
|
+
spec,
|
|
1203
|
+
action: { startWorkflow },
|
|
1204
|
+
state: {
|
|
1205
|
+
paused: args.paused ?? false,
|
|
1206
|
+
notes: args.notes ?? ""
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
};
|
|
1210
|
+
await client.post(
|
|
1211
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/schedules/${encodeURIComponent(args.schedule_id)}`,
|
|
1212
|
+
body
|
|
1213
|
+
);
|
|
1214
|
+
return {
|
|
1215
|
+
content: [{
|
|
1216
|
+
type: "text",
|
|
1217
|
+
text: `Schedule "${args.schedule_id}" created in namespace "${ns}". Workflow type: ${args.workflow_type}, Task queue: ${args.task_queue}.`
|
|
1218
|
+
}]
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
async function handleDeleteSchedule(args, client) {
|
|
1222
|
+
const ns = client.ns(args.namespace);
|
|
1223
|
+
await client.delete(
|
|
1224
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/schedules/${encodeURIComponent(args.schedule_id)}`
|
|
1225
|
+
);
|
|
1226
|
+
return {
|
|
1227
|
+
content: [{
|
|
1228
|
+
type: "text",
|
|
1229
|
+
text: `Schedule "${args.schedule_id}" deleted from namespace "${ns}".`
|
|
1230
|
+
}]
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
var taskQueueToolDefinitions = [
|
|
1234
|
+
{
|
|
1235
|
+
name: "describe_task_queue",
|
|
1236
|
+
description: "Get task queue information: active pollers, backlog, and task queue type. Useful for diagnosing worker connectivity issues.",
|
|
1237
|
+
inputSchema: {
|
|
1238
|
+
type: "object",
|
|
1239
|
+
properties: {
|
|
1240
|
+
namespace: { type: "string", description: "Target namespace." },
|
|
1241
|
+
task_queue: { type: "string", description: "Task queue name." },
|
|
1242
|
+
task_queue_type: {
|
|
1243
|
+
type: "string",
|
|
1244
|
+
enum: ["WORKFLOW", "ACTIVITY"],
|
|
1245
|
+
description: "Task queue type. Defaults to WORKFLOW."
|
|
1246
|
+
}
|
|
1247
|
+
},
|
|
1248
|
+
required: ["task_queue"]
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
];
|
|
1252
|
+
var describeTaskQueueSchema = z.object({
|
|
1253
|
+
namespace: z.string().optional(),
|
|
1254
|
+
task_queue: z.string(),
|
|
1255
|
+
task_queue_type: z.enum(["WORKFLOW", "ACTIVITY"]).optional()
|
|
1256
|
+
});
|
|
1257
|
+
async function handleDescribeTaskQueue(args, client) {
|
|
1258
|
+
const ns = client.ns(args.namespace);
|
|
1259
|
+
const data = await client.get(
|
|
1260
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/task-queues/${encodeURIComponent(args.task_queue)}`,
|
|
1261
|
+
{ taskQueueType: args.task_queue_type ?? "WORKFLOW" }
|
|
1262
|
+
);
|
|
1263
|
+
const lines = [`# Task Queue: ${args.task_queue}`, ""];
|
|
1264
|
+
const pollers = data.pollers ?? [];
|
|
1265
|
+
lines.push(`- Active Pollers: ${pollers.length}`);
|
|
1266
|
+
if (pollers.length > 0) {
|
|
1267
|
+
lines.push("", "## Pollers");
|
|
1268
|
+
for (const poller of pollers) {
|
|
1269
|
+
lines.push(`- Identity: ${poller.identity ?? "unknown"}`);
|
|
1270
|
+
if (poller.lastAccessTime) lines.push(` Last Access: ${poller.lastAccessTime}`);
|
|
1271
|
+
if (poller.ratePerSecond !== void 0) lines.push(` Rate: ${poller.ratePerSecond} tasks/s`);
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
const taskIdBlock = data.taskIdBlock;
|
|
1275
|
+
if (taskIdBlock) {
|
|
1276
|
+
lines.push("", "## Task ID Block");
|
|
1277
|
+
if (taskIdBlock.startId !== void 0) lines.push(`- Start ID: ${taskIdBlock.startId}`);
|
|
1278
|
+
if (taskIdBlock.endId !== void 0) lines.push(`- End ID: ${taskIdBlock.endId}`);
|
|
1279
|
+
}
|
|
1280
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1281
|
+
}
|
|
1282
|
+
var searchAttributeToolDefinitions = [
|
|
1283
|
+
{
|
|
1284
|
+
name: "list_search_attributes",
|
|
1285
|
+
description: "List all custom and system search attributes for a namespace. Search attributes are used in workflow visibility queries.",
|
|
1286
|
+
inputSchema: {
|
|
1287
|
+
type: "object",
|
|
1288
|
+
properties: {
|
|
1289
|
+
namespace: {
|
|
1290
|
+
type: "string",
|
|
1291
|
+
description: "Target namespace. Defaults to TEMPORAL_NAMESPACE."
|
|
1292
|
+
}
|
|
1293
|
+
},
|
|
1294
|
+
required: []
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
];
|
|
1298
|
+
var listSearchAttributesSchema = z.object({
|
|
1299
|
+
namespace: z.string().optional()
|
|
1300
|
+
});
|
|
1301
|
+
var VALUE_TYPE_LABELS = {
|
|
1302
|
+
INDEXED_VALUE_TYPE_TEXT: "Text",
|
|
1303
|
+
INDEXED_VALUE_TYPE_KEYWORD: "Keyword",
|
|
1304
|
+
INDEXED_VALUE_TYPE_INT: "Int",
|
|
1305
|
+
INDEXED_VALUE_TYPE_DOUBLE: "Double",
|
|
1306
|
+
INDEXED_VALUE_TYPE_BOOL: "Bool",
|
|
1307
|
+
INDEXED_VALUE_TYPE_DATETIME: "Datetime",
|
|
1308
|
+
INDEXED_VALUE_TYPE_KEYWORD_LIST: "KeywordList",
|
|
1309
|
+
"1": "Text",
|
|
1310
|
+
"2": "Keyword",
|
|
1311
|
+
"3": "Int",
|
|
1312
|
+
"4": "Double",
|
|
1313
|
+
"5": "Bool",
|
|
1314
|
+
"6": "Datetime",
|
|
1315
|
+
"7": "KeywordList"
|
|
1316
|
+
};
|
|
1317
|
+
function labelType(t) {
|
|
1318
|
+
return VALUE_TYPE_LABELS[t] ?? t;
|
|
1319
|
+
}
|
|
1320
|
+
async function handleListSearchAttributes(args, client) {
|
|
1321
|
+
const ns = client.ns(args.namespace);
|
|
1322
|
+
const data = await client.get(
|
|
1323
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/search-attributes`
|
|
1324
|
+
);
|
|
1325
|
+
const custom = data.customAttributes;
|
|
1326
|
+
const system = data.systemAttributes;
|
|
1327
|
+
const lines = [`# Search Attributes in "${ns}"`, ""];
|
|
1328
|
+
if (custom && Object.keys(custom).length > 0) {
|
|
1329
|
+
lines.push("## Custom Attributes");
|
|
1330
|
+
for (const [name, type] of Object.entries(custom)) {
|
|
1331
|
+
lines.push(`- ${name}: ${labelType(type)}`);
|
|
1332
|
+
}
|
|
1333
|
+
lines.push("");
|
|
1334
|
+
}
|
|
1335
|
+
if (system && Object.keys(system).length > 0) {
|
|
1336
|
+
lines.push("## System Attributes");
|
|
1337
|
+
for (const [name, type] of Object.entries(system)) {
|
|
1338
|
+
lines.push(`- ${name}: ${labelType(type)}`);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
if ((!custom || Object.keys(custom).length === 0) && (!system || Object.keys(system).length === 0)) {
|
|
1342
|
+
lines.push("No search attributes found.");
|
|
1343
|
+
}
|
|
1344
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1345
|
+
}
|
|
1346
|
+
var activityToolDefinitions = [
|
|
1347
|
+
{
|
|
1348
|
+
name: "list_activities",
|
|
1349
|
+
description: "List activity executions in a namespace. Use the query parameter to filter by workflow ID, activity type, status, etc.",
|
|
1350
|
+
inputSchema: {
|
|
1351
|
+
type: "object",
|
|
1352
|
+
properties: {
|
|
1353
|
+
namespace: { type: "string", description: "Target namespace." },
|
|
1354
|
+
query: {
|
|
1355
|
+
type: "string",
|
|
1356
|
+
description: `Visibility query filter (e.g. "WorkflowId='my-workflow' AND ActivityType='SendEmail'").`
|
|
1357
|
+
},
|
|
1358
|
+
page_size: { type: "number", description: "Max results (default 20)." },
|
|
1359
|
+
next_page_token: { type: "string", description: "Pagination cursor." }
|
|
1360
|
+
},
|
|
1361
|
+
required: []
|
|
1362
|
+
}
|
|
1363
|
+
},
|
|
1364
|
+
{
|
|
1365
|
+
name: "describe_activity",
|
|
1366
|
+
description: "Get details of a specific activity execution: type, status, schedule/start time, heartbeat, and failure info.",
|
|
1367
|
+
inputSchema: {
|
|
1368
|
+
type: "object",
|
|
1369
|
+
properties: {
|
|
1370
|
+
namespace: { type: "string", description: "Namespace containing the activity." },
|
|
1371
|
+
activity_id: { type: "string", description: "Activity ID." }
|
|
1372
|
+
},
|
|
1373
|
+
required: ["activity_id"]
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
];
|
|
1377
|
+
var listActivitiesSchema = z.object({
|
|
1378
|
+
namespace: z.string().optional(),
|
|
1379
|
+
query: z.string().optional(),
|
|
1380
|
+
page_size: z.number().optional(),
|
|
1381
|
+
next_page_token: z.string().optional()
|
|
1382
|
+
});
|
|
1383
|
+
var describeActivitySchema = z.object({
|
|
1384
|
+
namespace: z.string().optional(),
|
|
1385
|
+
activity_id: z.string()
|
|
1386
|
+
});
|
|
1387
|
+
function fmtTime3(t) {
|
|
1388
|
+
if (!t) return "N/A";
|
|
1389
|
+
if (typeof t === "string") return new Date(t).toISOString();
|
|
1390
|
+
if (typeof t === "object") {
|
|
1391
|
+
const o = t;
|
|
1392
|
+
if (o.seconds) return new Date(Number(o.seconds) * 1e3).toISOString();
|
|
1393
|
+
}
|
|
1394
|
+
return String(t);
|
|
1395
|
+
}
|
|
1396
|
+
async function handleListActivities(args, client) {
|
|
1397
|
+
const ns = client.ns(args.namespace);
|
|
1398
|
+
const data = await client.get(
|
|
1399
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/activities`,
|
|
1400
|
+
{ query: args.query, pageSize: args.page_size ?? 20, nextPageToken: args.next_page_token }
|
|
1401
|
+
);
|
|
1402
|
+
const activities = data.activityExecutions ?? [];
|
|
1403
|
+
const lines = [`# Activities in "${ns}" (${activities.length} returned)`, ""];
|
|
1404
|
+
for (const act of activities) {
|
|
1405
|
+
const actType = act.activityType;
|
|
1406
|
+
const exec = act.execution;
|
|
1407
|
+
lines.push(`## ${act.activityId ?? "unknown"}`);
|
|
1408
|
+
if (actType?.name) lines.push(`- Type: ${actType.name}`);
|
|
1409
|
+
if (exec?.workflowId) lines.push(`- Workflow: ${exec.workflowId}`);
|
|
1410
|
+
if (act.state) lines.push(`- State: ${act.state}`);
|
|
1411
|
+
if (act.scheduleTime) lines.push(`- Scheduled: ${fmtTime3(act.scheduleTime)}`);
|
|
1412
|
+
if (act.startTime) lines.push(`- Started: ${fmtTime3(act.startTime)}`);
|
|
1413
|
+
lines.push("");
|
|
1414
|
+
}
|
|
1415
|
+
if (data.nextPageToken) lines.push(`*Next page token: ${data.nextPageToken}*`);
|
|
1416
|
+
return {
|
|
1417
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
1418
|
+
structuredContent: {
|
|
1419
|
+
namespace: ns,
|
|
1420
|
+
activities: activities.map((act) => {
|
|
1421
|
+
const actType = act.activityType;
|
|
1422
|
+
const exec = act.execution;
|
|
1423
|
+
return {
|
|
1424
|
+
activityId: act.activityId,
|
|
1425
|
+
type: actType?.name,
|
|
1426
|
+
workflowId: exec?.workflowId,
|
|
1427
|
+
state: act.state,
|
|
1428
|
+
scheduleTime: act.scheduleTime,
|
|
1429
|
+
startTime: act.startTime
|
|
1430
|
+
};
|
|
1431
|
+
}),
|
|
1432
|
+
nextPageToken: data.nextPageToken
|
|
1433
|
+
}
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
async function handleDescribeActivity(args, client) {
|
|
1437
|
+
const ns = client.ns(args.namespace);
|
|
1438
|
+
const data = await client.get(
|
|
1439
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/activities/${encodeURIComponent(args.activity_id)}`
|
|
1440
|
+
);
|
|
1441
|
+
const actType = data.activityType;
|
|
1442
|
+
const exec = data.execution;
|
|
1443
|
+
const failure = data.failure;
|
|
1444
|
+
const heartbeat = data.lastHeartbeatDetails;
|
|
1445
|
+
const lines = [`# Activity: ${args.activity_id}`, ""];
|
|
1446
|
+
if (actType?.name) lines.push(`- Type: ${actType.name}`);
|
|
1447
|
+
if (exec?.workflowId) lines.push(`- Workflow: ${exec.workflowId}`);
|
|
1448
|
+
if (exec?.runId) lines.push(`- Run ID: ${exec.runId}`);
|
|
1449
|
+
if (data.state) lines.push(`- State: ${data.state}`);
|
|
1450
|
+
if (data.scheduleTime) lines.push(`- Scheduled: ${fmtTime3(data.scheduleTime)}`);
|
|
1451
|
+
if (data.startTime) lines.push(`- Started: ${fmtTime3(data.startTime)}`);
|
|
1452
|
+
if (data.attempt !== void 0) lines.push(`- Attempt: ${data.attempt}`);
|
|
1453
|
+
if (data.maxAttempts !== void 0) lines.push(`- Max Attempts: ${data.maxAttempts}`);
|
|
1454
|
+
if (heartbeat) lines.push(`- Last Heartbeat: ${JSON.stringify(heartbeat)}`);
|
|
1455
|
+
if (failure?.message) {
|
|
1456
|
+
lines.push("", "## Failure");
|
|
1457
|
+
lines.push(`- Message: ${failure.message}`);
|
|
1458
|
+
if (failure.applicationFailureInfo) {
|
|
1459
|
+
const info = failure.applicationFailureInfo;
|
|
1460
|
+
if (info.type) lines.push(`- Failure Type: ${info.type}`);
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1464
|
+
}
|
|
1465
|
+
var batchOperationToolDefinitions = [
|
|
1466
|
+
{
|
|
1467
|
+
name: "list_batch_operations",
|
|
1468
|
+
description: "List batch operations (bulk workflow signal/cancel/terminate/delete jobs) in a namespace.",
|
|
1469
|
+
inputSchema: {
|
|
1470
|
+
type: "object",
|
|
1471
|
+
properties: {
|
|
1472
|
+
namespace: { type: "string", description: "Target namespace." },
|
|
1473
|
+
page_size: { type: "number", description: "Max results (default 20)." },
|
|
1474
|
+
next_page_token: { type: "string", description: "Pagination cursor." }
|
|
1475
|
+
},
|
|
1476
|
+
required: []
|
|
1477
|
+
}
|
|
1478
|
+
},
|
|
1479
|
+
{
|
|
1480
|
+
name: "describe_batch_operation",
|
|
1481
|
+
description: "Get details of a batch operation: type, state, progress, and error info.",
|
|
1482
|
+
inputSchema: {
|
|
1483
|
+
type: "object",
|
|
1484
|
+
properties: {
|
|
1485
|
+
namespace: { type: "string", description: "Namespace containing the batch operation." },
|
|
1486
|
+
job_id: { type: "string", description: "Batch operation job ID." }
|
|
1487
|
+
},
|
|
1488
|
+
required: ["job_id"]
|
|
1489
|
+
}
|
|
1490
|
+
},
|
|
1491
|
+
{
|
|
1492
|
+
name: "stop_batch_operation",
|
|
1493
|
+
description: "Stop a running batch operation. The operation will not be rolled back.",
|
|
1494
|
+
inputSchema: {
|
|
1495
|
+
type: "object",
|
|
1496
|
+
properties: {
|
|
1497
|
+
namespace: { type: "string", description: "Namespace containing the batch operation." },
|
|
1498
|
+
job_id: { type: "string", description: "Batch operation job ID to stop." },
|
|
1499
|
+
reason: { type: "string", description: "Reason for stopping the operation." }
|
|
1500
|
+
},
|
|
1501
|
+
required: ["job_id"]
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
];
|
|
1505
|
+
var listBatchOperationsSchema = z.object({
|
|
1506
|
+
namespace: z.string().optional(),
|
|
1507
|
+
page_size: z.number().optional(),
|
|
1508
|
+
next_page_token: z.string().optional()
|
|
1509
|
+
});
|
|
1510
|
+
var describeBatchOperationSchema = z.object({
|
|
1511
|
+
namespace: z.string().optional(),
|
|
1512
|
+
job_id: z.string()
|
|
1513
|
+
});
|
|
1514
|
+
var stopBatchOperationSchema = z.object({
|
|
1515
|
+
namespace: z.string().optional(),
|
|
1516
|
+
job_id: z.string(),
|
|
1517
|
+
reason: z.string().optional()
|
|
1518
|
+
});
|
|
1519
|
+
async function handleListBatchOperations(args, client) {
|
|
1520
|
+
const ns = client.ns(args.namespace);
|
|
1521
|
+
const data = await client.get(
|
|
1522
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/batch-operations`,
|
|
1523
|
+
{ pageSize: args.page_size ?? 20, nextPageToken: args.next_page_token }
|
|
1524
|
+
);
|
|
1525
|
+
const ops = data.operationInfo ?? [];
|
|
1526
|
+
const lines = [`# Batch Operations in "${ns}" (${ops.length} returned)`, ""];
|
|
1527
|
+
for (const op of ops) {
|
|
1528
|
+
lines.push(`## ${op.jobId ?? "unknown"}`);
|
|
1529
|
+
if (op.operationType) lines.push(`- Type: ${op.operationType}`);
|
|
1530
|
+
if (op.state) lines.push(`- State: ${op.state}`);
|
|
1531
|
+
if (op.startTime) lines.push(`- Started: ${op.startTime}`);
|
|
1532
|
+
if (op.closeTime) lines.push(`- Closed: ${op.closeTime}`);
|
|
1533
|
+
lines.push("");
|
|
1534
|
+
}
|
|
1535
|
+
if (data.nextPageToken) lines.push(`*Next page token: ${data.nextPageToken}*`);
|
|
1536
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1537
|
+
}
|
|
1538
|
+
async function handleDescribeBatchOperation(args, client) {
|
|
1539
|
+
const ns = client.ns(args.namespace);
|
|
1540
|
+
const data = await client.get(
|
|
1541
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/batch-operations/${encodeURIComponent(args.job_id)}`
|
|
1542
|
+
);
|
|
1543
|
+
const lines = [`# Batch Operation: ${args.job_id}`, ""];
|
|
1544
|
+
if (data.operationType) lines.push(`- Type: ${data.operationType}`);
|
|
1545
|
+
if (data.state) lines.push(`- State: ${data.state}`);
|
|
1546
|
+
if (data.startTime) lines.push(`- Started: ${data.startTime}`);
|
|
1547
|
+
if (data.closeTime) lines.push(`- Closed: ${data.closeTime}`);
|
|
1548
|
+
if (data.totalOperationCount !== void 0) lines.push(`- Total: ${data.totalOperationCount}`);
|
|
1549
|
+
if (data.completeOperationCount !== void 0) lines.push(`- Completed: ${data.completeOperationCount}`);
|
|
1550
|
+
if (data.failureOperationCount !== void 0) lines.push(`- Failed: ${data.failureOperationCount}`);
|
|
1551
|
+
const reason = data.reason;
|
|
1552
|
+
if (reason) lines.push(`- Reason: ${reason}`);
|
|
1553
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1554
|
+
}
|
|
1555
|
+
async function handleStopBatchOperation(args, client) {
|
|
1556
|
+
const ns = client.ns(args.namespace);
|
|
1557
|
+
await client.post(
|
|
1558
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/batch-operations/${encodeURIComponent(args.job_id)}/stop`,
|
|
1559
|
+
{ reason: args.reason ?? "" }
|
|
1560
|
+
);
|
|
1561
|
+
return {
|
|
1562
|
+
content: [{
|
|
1563
|
+
type: "text",
|
|
1564
|
+
text: `Batch operation "${args.job_id}" stopped${args.reason ? ` (reason: ${args.reason})` : ""}.`
|
|
1565
|
+
}]
|
|
1566
|
+
};
|
|
1567
|
+
}
|
|
1568
|
+
var workerDeploymentToolDefinitions = [
|
|
1569
|
+
{
|
|
1570
|
+
name: "list_worker_deployments",
|
|
1571
|
+
description: "List worker deployments in a namespace. Worker deployments track versioned worker releases.",
|
|
1572
|
+
inputSchema: {
|
|
1573
|
+
type: "object",
|
|
1574
|
+
properties: {
|
|
1575
|
+
namespace: { type: "string", description: "Target namespace." },
|
|
1576
|
+
page_size: { type: "number", description: "Max results (default 20)." },
|
|
1577
|
+
next_page_token: { type: "string", description: "Pagination cursor." }
|
|
1578
|
+
},
|
|
1579
|
+
required: []
|
|
1580
|
+
}
|
|
1581
|
+
},
|
|
1582
|
+
{
|
|
1583
|
+
name: "describe_worker_deployment",
|
|
1584
|
+
description: "Get details of a worker deployment: current version, ramping version, routing config, and version summaries.",
|
|
1585
|
+
inputSchema: {
|
|
1586
|
+
type: "object",
|
|
1587
|
+
properties: {
|
|
1588
|
+
namespace: { type: "string", description: "Namespace containing the deployment." },
|
|
1589
|
+
deployment_name: { type: "string", description: "Deployment name." }
|
|
1590
|
+
},
|
|
1591
|
+
required: ["deployment_name"]
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
];
|
|
1595
|
+
var listWorkerDeploymentsSchema = z.object({
|
|
1596
|
+
namespace: z.string().optional(),
|
|
1597
|
+
page_size: z.number().optional(),
|
|
1598
|
+
next_page_token: z.string().optional()
|
|
1599
|
+
});
|
|
1600
|
+
var describeWorkerDeploymentSchema = z.object({
|
|
1601
|
+
namespace: z.string().optional(),
|
|
1602
|
+
deployment_name: z.string()
|
|
1603
|
+
});
|
|
1604
|
+
async function handleListWorkerDeployments(args, client) {
|
|
1605
|
+
const ns = client.ns(args.namespace);
|
|
1606
|
+
const data = await client.get(
|
|
1607
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/worker-deployments`,
|
|
1608
|
+
{ pageSize: args.page_size ?? 20, nextPageToken: args.next_page_token }
|
|
1609
|
+
);
|
|
1610
|
+
const deployments = data.deployments ?? [];
|
|
1611
|
+
const lines = [`# Worker Deployments in "${ns}" (${deployments.length} returned)`, ""];
|
|
1612
|
+
for (const dep of deployments) {
|
|
1613
|
+
const info = dep.deploymentInfo;
|
|
1614
|
+
const name = info?.name ?? dep.name;
|
|
1615
|
+
lines.push(`## ${name ?? "unknown"}`);
|
|
1616
|
+
if (info?.createTime) lines.push(`- Created: ${info.createTime}`);
|
|
1617
|
+
const currentVersion = info?.currentVersion;
|
|
1618
|
+
if (currentVersion?.version) lines.push(`- Current Version: ${currentVersion.version}`);
|
|
1619
|
+
const rampingVersion = info?.rampingVersion;
|
|
1620
|
+
if (rampingVersion?.version) lines.push(`- Ramping Version: ${rampingVersion.version}`);
|
|
1621
|
+
lines.push("");
|
|
1622
|
+
}
|
|
1623
|
+
if (data.nextPageToken) lines.push(`*Next page token: ${data.nextPageToken}*`);
|
|
1624
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1625
|
+
}
|
|
1626
|
+
async function handleDescribeWorkerDeployment(args, client) {
|
|
1627
|
+
const ns = client.ns(args.namespace);
|
|
1628
|
+
const data = await client.get(
|
|
1629
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/worker-deployments/${encodeURIComponent(args.deployment_name)}`
|
|
1630
|
+
);
|
|
1631
|
+
const dep = data.deploymentInfo;
|
|
1632
|
+
const lines = [`# Worker Deployment: ${args.deployment_name}`, ""];
|
|
1633
|
+
if (dep?.createTime) lines.push(`- Created: ${dep.createTime}`);
|
|
1634
|
+
if (dep?.lastModifierIdentity) lines.push(`- Last Modified By: ${dep.lastModifierIdentity}`);
|
|
1635
|
+
const currentVersion = dep?.currentVersion;
|
|
1636
|
+
if (currentVersion) {
|
|
1637
|
+
lines.push("", "## Current Version");
|
|
1638
|
+
if (currentVersion.version) lines.push(`- Version: ${currentVersion.version}`);
|
|
1639
|
+
if (currentVersion.becameCurrentTime) lines.push(`- Became Current: ${currentVersion.becameCurrentTime}`);
|
|
1640
|
+
}
|
|
1641
|
+
const rampingVersion = dep?.rampingVersion;
|
|
1642
|
+
if (rampingVersion) {
|
|
1643
|
+
lines.push("", "## Ramping Version");
|
|
1644
|
+
if (rampingVersion.version) lines.push(`- Version: ${rampingVersion.version}`);
|
|
1645
|
+
if (rampingVersion.rampPercentage !== void 0) lines.push(`- Ramp: ${rampingVersion.rampPercentage}%`);
|
|
1646
|
+
}
|
|
1647
|
+
const versionSummaries = dep?.versionSummaries;
|
|
1648
|
+
if (versionSummaries?.length) {
|
|
1649
|
+
lines.push("", `## Version History (${versionSummaries.length})`);
|
|
1650
|
+
for (const v of versionSummaries) {
|
|
1651
|
+
lines.push(`- ${v.version}: drained=${v.drainageStatus ?? "N/A"}`);
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1655
|
+
}
|
|
1656
|
+
var nexusEndpointToolDefinitions = [
|
|
1657
|
+
{
|
|
1658
|
+
name: "list_nexus_endpoints",
|
|
1659
|
+
description: "List all Nexus endpoints registered in the cluster. Nexus endpoints connect Temporal namespaces to external services.",
|
|
1660
|
+
inputSchema: {
|
|
1661
|
+
type: "object",
|
|
1662
|
+
properties: {
|
|
1663
|
+
page_size: { type: "number", description: "Max results (default 20)." },
|
|
1664
|
+
next_page_token: { type: "string", description: "Pagination cursor." }
|
|
1665
|
+
},
|
|
1666
|
+
required: []
|
|
1667
|
+
}
|
|
1668
|
+
},
|
|
1669
|
+
{
|
|
1670
|
+
name: "get_nexus_endpoint",
|
|
1671
|
+
description: "Get details of a specific Nexus endpoint by ID.",
|
|
1672
|
+
inputSchema: {
|
|
1673
|
+
type: "object",
|
|
1674
|
+
properties: {
|
|
1675
|
+
id: { type: "string", description: "Nexus endpoint ID." }
|
|
1676
|
+
},
|
|
1677
|
+
required: ["id"]
|
|
1678
|
+
}
|
|
1679
|
+
},
|
|
1680
|
+
{
|
|
1681
|
+
name: "create_nexus_endpoint",
|
|
1682
|
+
description: "Create a new Nexus endpoint that routes to a target namespace and task queue.",
|
|
1683
|
+
inputSchema: {
|
|
1684
|
+
type: "object",
|
|
1685
|
+
properties: {
|
|
1686
|
+
name: { type: "string", description: "Unique endpoint name." },
|
|
1687
|
+
target_namespace: { type: "string", description: "Target Temporal namespace." },
|
|
1688
|
+
target_task_queue: { type: "string", description: "Target task queue in the target namespace." },
|
|
1689
|
+
description: { type: "string", description: "Human-readable description." }
|
|
1690
|
+
},
|
|
1691
|
+
required: ["name", "target_namespace", "target_task_queue"]
|
|
1692
|
+
}
|
|
1693
|
+
},
|
|
1694
|
+
{
|
|
1695
|
+
name: "delete_nexus_endpoint",
|
|
1696
|
+
description: "Delete a Nexus endpoint by ID.",
|
|
1697
|
+
inputSchema: {
|
|
1698
|
+
type: "object",
|
|
1699
|
+
properties: {
|
|
1700
|
+
id: { type: "string", description: "Nexus endpoint ID to delete." },
|
|
1701
|
+
version: { type: "string", description: "Current version for optimistic concurrency (required)." }
|
|
1702
|
+
},
|
|
1703
|
+
required: ["id", "version"]
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
];
|
|
1707
|
+
var listNexusEndpointsSchema = z.object({
|
|
1708
|
+
page_size: z.number().optional(),
|
|
1709
|
+
next_page_token: z.string().optional()
|
|
1710
|
+
});
|
|
1711
|
+
var getNexusEndpointSchema = z.object({
|
|
1712
|
+
id: z.string()
|
|
1713
|
+
});
|
|
1714
|
+
var createNexusEndpointSchema = z.object({
|
|
1715
|
+
name: z.string(),
|
|
1716
|
+
target_namespace: z.string(),
|
|
1717
|
+
target_task_queue: z.string(),
|
|
1718
|
+
description: z.string().optional()
|
|
1719
|
+
});
|
|
1720
|
+
var deleteNexusEndpointSchema = z.object({
|
|
1721
|
+
id: z.string(),
|
|
1722
|
+
version: z.string()
|
|
1723
|
+
});
|
|
1724
|
+
function formatEndpoint(ep) {
|
|
1725
|
+
const lines = [];
|
|
1726
|
+
const spec = ep.spec;
|
|
1727
|
+
const target = spec?.target;
|
|
1728
|
+
const worker = target?.worker;
|
|
1729
|
+
lines.push(`- ID: ${ep.id}`);
|
|
1730
|
+
if (spec?.name) lines.push(`- Name: ${spec.name}`);
|
|
1731
|
+
if (ep.createdTime) lines.push(`- Created: ${ep.createdTime}`);
|
|
1732
|
+
if (ep.lastModifiedTime) lines.push(`- Last Modified: ${ep.lastModifiedTime}`);
|
|
1733
|
+
if (worker?.namespace) lines.push(`- Target Namespace: ${worker.namespace}`);
|
|
1734
|
+
if (worker?.taskQueue) lines.push(`- Target Task Queue: ${worker.taskQueue}`);
|
|
1735
|
+
return lines;
|
|
1736
|
+
}
|
|
1737
|
+
async function handleListNexusEndpoints(args, client) {
|
|
1738
|
+
const data = await client.get(
|
|
1739
|
+
"/api/v1/nexus/endpoints",
|
|
1740
|
+
{ pageSize: args.page_size ?? 20, nextPageToken: args.next_page_token }
|
|
1741
|
+
);
|
|
1742
|
+
const endpoints = data.endpoints ?? [];
|
|
1743
|
+
const lines = [`# Nexus Endpoints (${endpoints.length} returned)`, ""];
|
|
1744
|
+
for (const ep of endpoints) {
|
|
1745
|
+
const spec = ep.spec;
|
|
1746
|
+
lines.push(`## ${spec?.name ?? ep.id ?? "unknown"}`);
|
|
1747
|
+
lines.push(...formatEndpoint(ep));
|
|
1748
|
+
lines.push("");
|
|
1749
|
+
}
|
|
1750
|
+
if (data.nextPageToken) lines.push(`*Next page token: ${data.nextPageToken}*`);
|
|
1751
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1752
|
+
}
|
|
1753
|
+
async function handleGetNexusEndpoint(args, client) {
|
|
1754
|
+
const data = await client.get(
|
|
1755
|
+
`/api/v1/nexus/endpoints/${encodeURIComponent(args.id)}`
|
|
1756
|
+
);
|
|
1757
|
+
const ep = data.endpoint ?? data;
|
|
1758
|
+
const spec = ep.spec;
|
|
1759
|
+
const lines = [`# Nexus Endpoint: ${spec?.name ?? args.id}`, ""];
|
|
1760
|
+
lines.push(...formatEndpoint(ep));
|
|
1761
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1762
|
+
}
|
|
1763
|
+
async function handleCreateNexusEndpoint(args, client) {
|
|
1764
|
+
const body = {
|
|
1765
|
+
spec: {
|
|
1766
|
+
name: args.name,
|
|
1767
|
+
description: args.description ? { value: args.description } : void 0,
|
|
1768
|
+
target: {
|
|
1769
|
+
worker: {
|
|
1770
|
+
namespace: args.target_namespace,
|
|
1771
|
+
taskQueue: args.target_task_queue
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
};
|
|
1776
|
+
const data = await client.post("/api/v1/nexus/endpoints", body);
|
|
1777
|
+
const ep = data.endpoint ?? data;
|
|
1778
|
+
return {
|
|
1779
|
+
content: [{
|
|
1780
|
+
type: "text",
|
|
1781
|
+
text: `Nexus endpoint "${args.name}" created. ID: ${ep.id ?? "N/A"}, Target: ${args.target_namespace}/${args.target_task_queue}`
|
|
1782
|
+
}]
|
|
1783
|
+
};
|
|
1784
|
+
}
|
|
1785
|
+
async function handleDeleteNexusEndpoint(args, client) {
|
|
1786
|
+
await client.delete(
|
|
1787
|
+
`/api/v1/nexus/endpoints/${encodeURIComponent(args.id)}`,
|
|
1788
|
+
{ version: args.version }
|
|
1789
|
+
);
|
|
1790
|
+
return {
|
|
1791
|
+
content: [{ type: "text", text: `Nexus endpoint "${args.id}" deleted.` }]
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
var workflowRuleToolDefinitions = [
|
|
1795
|
+
{
|
|
1796
|
+
name: "list_workflow_rules",
|
|
1797
|
+
description: "List workflow rules in a namespace. Workflow rules automatically perform actions (terminate, pause, etc.) on matching workflows.",
|
|
1798
|
+
inputSchema: {
|
|
1799
|
+
type: "object",
|
|
1800
|
+
properties: {
|
|
1801
|
+
namespace: { type: "string", description: "Target namespace." }
|
|
1802
|
+
},
|
|
1803
|
+
required: []
|
|
1804
|
+
}
|
|
1805
|
+
},
|
|
1806
|
+
{
|
|
1807
|
+
name: "describe_workflow_rule",
|
|
1808
|
+
description: "Get details of a specific workflow rule: spec, action, and status.",
|
|
1809
|
+
inputSchema: {
|
|
1810
|
+
type: "object",
|
|
1811
|
+
properties: {
|
|
1812
|
+
namespace: { type: "string", description: "Namespace containing the rule." },
|
|
1813
|
+
rule_id: { type: "string", description: "Workflow rule ID." }
|
|
1814
|
+
},
|
|
1815
|
+
required: ["rule_id"]
|
|
1816
|
+
}
|
|
1817
|
+
},
|
|
1818
|
+
{
|
|
1819
|
+
name: "create_workflow_rule",
|
|
1820
|
+
description: "Create a workflow rule that automatically acts on workflows matching a visibility query. Supported actions: TERMINATE, PAUSE.",
|
|
1821
|
+
inputSchema: {
|
|
1822
|
+
type: "object",
|
|
1823
|
+
properties: {
|
|
1824
|
+
namespace: { type: "string", description: "Target namespace." },
|
|
1825
|
+
rule_id: { type: "string", description: "Unique rule ID." },
|
|
1826
|
+
query: {
|
|
1827
|
+
type: "string",
|
|
1828
|
+
description: `Visibility query to match workflows (e.g. "WorkflowType='OldJob' AND ExecutionStatus='Running'").`
|
|
1829
|
+
},
|
|
1830
|
+
action: {
|
|
1831
|
+
type: "string",
|
|
1832
|
+
enum: ["TERMINATE", "PAUSE"],
|
|
1833
|
+
description: "Action to perform on matching workflows."
|
|
1834
|
+
},
|
|
1835
|
+
description: { type: "string", description: "Human-readable description of the rule." }
|
|
1836
|
+
},
|
|
1837
|
+
required: ["rule_id", "query", "action"]
|
|
1838
|
+
}
|
|
1839
|
+
},
|
|
1840
|
+
{
|
|
1841
|
+
name: "delete_workflow_rule",
|
|
1842
|
+
description: "Delete a workflow rule. Workflows already acted on are not affected.",
|
|
1843
|
+
inputSchema: {
|
|
1844
|
+
type: "object",
|
|
1845
|
+
properties: {
|
|
1846
|
+
namespace: { type: "string", description: "Namespace containing the rule." },
|
|
1847
|
+
rule_id: { type: "string", description: "Rule ID to delete." }
|
|
1848
|
+
},
|
|
1849
|
+
required: ["rule_id"]
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
];
|
|
1853
|
+
var listWorkflowRulesSchema = z.object({
|
|
1854
|
+
namespace: z.string().optional()
|
|
1855
|
+
});
|
|
1856
|
+
var describeWorkflowRuleSchema = z.object({
|
|
1857
|
+
namespace: z.string().optional(),
|
|
1858
|
+
rule_id: z.string()
|
|
1859
|
+
});
|
|
1860
|
+
var createWorkflowRuleSchema = z.object({
|
|
1861
|
+
namespace: z.string().optional(),
|
|
1862
|
+
rule_id: z.string(),
|
|
1863
|
+
query: z.string(),
|
|
1864
|
+
action: z.enum(["TERMINATE", "PAUSE"]),
|
|
1865
|
+
description: z.string().optional()
|
|
1866
|
+
});
|
|
1867
|
+
var deleteWorkflowRuleSchema = z.object({
|
|
1868
|
+
namespace: z.string().optional(),
|
|
1869
|
+
rule_id: z.string()
|
|
1870
|
+
});
|
|
1871
|
+
function formatRule(rule) {
|
|
1872
|
+
const lines = [];
|
|
1873
|
+
const spec = rule.spec;
|
|
1874
|
+
if (rule.id) lines.push(`- ID: ${rule.id}`);
|
|
1875
|
+
if (spec?.visibilityQuery) lines.push(`- Query: ${spec.visibilityQuery}`);
|
|
1876
|
+
const action = spec?.action;
|
|
1877
|
+
if (action) {
|
|
1878
|
+
if (action.terminateWorkflow !== void 0) lines.push("- Action: TERMINATE");
|
|
1879
|
+
else if (action.pauseWorkflow !== void 0) lines.push("- Action: PAUSE");
|
|
1880
|
+
else lines.push(`- Action: ${JSON.stringify(action)}`);
|
|
1881
|
+
}
|
|
1882
|
+
if (spec?.description) lines.push(`- Description: ${spec.description}`);
|
|
1883
|
+
if (rule.createTime) lines.push(`- Created: ${rule.createTime}`);
|
|
1884
|
+
return lines;
|
|
1885
|
+
}
|
|
1886
|
+
async function handleListWorkflowRules(args, client) {
|
|
1887
|
+
const ns = client.ns(args.namespace);
|
|
1888
|
+
const data = await client.get(
|
|
1889
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflow-rules`
|
|
1890
|
+
);
|
|
1891
|
+
const rules = data.workflowRules ?? [];
|
|
1892
|
+
const lines = [`# Workflow Rules in "${ns}" (${rules.length} found)`, ""];
|
|
1893
|
+
for (const rule of rules) {
|
|
1894
|
+
const spec = rule.spec;
|
|
1895
|
+
lines.push(`## ${rule.id ?? "unknown"}${spec?.description ? ` \u2014 ${spec.description}` : ""}`);
|
|
1896
|
+
lines.push(...formatRule(rule));
|
|
1897
|
+
lines.push("");
|
|
1898
|
+
}
|
|
1899
|
+
if (rules.length === 0) lines.push("No workflow rules found.");
|
|
1900
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1901
|
+
}
|
|
1902
|
+
async function handleDescribeWorkflowRule(args, client) {
|
|
1903
|
+
const ns = client.ns(args.namespace);
|
|
1904
|
+
const data = await client.get(
|
|
1905
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflow-rules/${encodeURIComponent(args.rule_id)}`
|
|
1906
|
+
);
|
|
1907
|
+
const rule = data.workflowRule ?? data;
|
|
1908
|
+
const spec = rule.spec;
|
|
1909
|
+
const lines = [`# Workflow Rule: ${rule.id ?? args.rule_id}${spec?.description ? ` \u2014 ${spec.description}` : ""}`, ""];
|
|
1910
|
+
lines.push(...formatRule(rule));
|
|
1911
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1912
|
+
}
|
|
1913
|
+
async function handleCreateWorkflowRule(args, client) {
|
|
1914
|
+
const ns = client.ns(args.namespace);
|
|
1915
|
+
const action = args.action === "TERMINATE" ? { terminateWorkflow: {} } : { pauseWorkflow: {} };
|
|
1916
|
+
const body = {
|
|
1917
|
+
workflowRule: {
|
|
1918
|
+
id: args.rule_id,
|
|
1919
|
+
spec: {
|
|
1920
|
+
visibilityQuery: args.query,
|
|
1921
|
+
action,
|
|
1922
|
+
description: args.description ?? ""
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
};
|
|
1926
|
+
await client.post(
|
|
1927
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflow-rules`,
|
|
1928
|
+
body
|
|
1929
|
+
);
|
|
1930
|
+
return {
|
|
1931
|
+
content: [{
|
|
1932
|
+
type: "text",
|
|
1933
|
+
text: `Workflow rule "${args.rule_id}" created in "${ns}". Action: ${args.action}, Query: ${args.query}`
|
|
1934
|
+
}]
|
|
1935
|
+
};
|
|
1936
|
+
}
|
|
1937
|
+
async function handleDeleteWorkflowRule(args, client) {
|
|
1938
|
+
const ns = client.ns(args.namespace);
|
|
1939
|
+
await client.delete(
|
|
1940
|
+
`/api/v1/namespaces/${encodeURIComponent(ns)}/workflow-rules/${encodeURIComponent(args.rule_id)}`
|
|
1941
|
+
);
|
|
1942
|
+
return {
|
|
1943
|
+
content: [{ type: "text", text: `Workflow rule "${args.rule_id}" deleted from namespace "${ns}".` }]
|
|
1944
|
+
};
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1947
|
+
// src/index.ts
|
|
1948
|
+
var ESSENTIAL_TOOLS = /* @__PURE__ */ new Set([
|
|
1949
|
+
"get_cluster_info",
|
|
1950
|
+
"list_namespaces",
|
|
1951
|
+
"describe_namespace",
|
|
1952
|
+
"list_workflows",
|
|
1953
|
+
"describe_workflow",
|
|
1954
|
+
"start_workflow",
|
|
1955
|
+
"signal_workflow",
|
|
1956
|
+
"query_workflow",
|
|
1957
|
+
"cancel_workflow",
|
|
1958
|
+
"terminate_workflow",
|
|
1959
|
+
"get_workflow_history"
|
|
1960
|
+
]);
|
|
1961
|
+
var STANDARD_TOOLS = /* @__PURE__ */ new Set([
|
|
1962
|
+
...ESSENTIAL_TOOLS,
|
|
1963
|
+
"count_workflows",
|
|
1964
|
+
"pause_workflow",
|
|
1965
|
+
"unpause_workflow",
|
|
1966
|
+
"signal_with_start_workflow",
|
|
1967
|
+
"list_schedules",
|
|
1968
|
+
"describe_schedule",
|
|
1969
|
+
"create_schedule",
|
|
1970
|
+
"delete_schedule",
|
|
1971
|
+
"list_activities",
|
|
1972
|
+
"describe_activity",
|
|
1973
|
+
"describe_task_queue",
|
|
1974
|
+
"list_search_attributes"
|
|
1975
|
+
]);
|
|
1976
|
+
function resolveToolTier() {
|
|
1977
|
+
const val = (process.env.TEMPORAL_TOOLS ?? "essential").toLowerCase();
|
|
1978
|
+
if (val === "all") return "all";
|
|
1979
|
+
if (val === "standard") return "standard";
|
|
1980
|
+
return "essential";
|
|
1981
|
+
}
|
|
1982
|
+
async function runTool(fn) {
|
|
1983
|
+
try {
|
|
1984
|
+
return await fn();
|
|
1985
|
+
} catch (err) {
|
|
1986
|
+
let message;
|
|
1987
|
+
if (err instanceof TemporalError) {
|
|
1988
|
+
message = `Temporal API error ${err.status}: ${err.message}`;
|
|
1989
|
+
} else if (err instanceof Error) {
|
|
1990
|
+
message = err.message;
|
|
1991
|
+
} else {
|
|
1992
|
+
message = String(err);
|
|
1993
|
+
}
|
|
1994
|
+
return {
|
|
1995
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1996
|
+
isError: true
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
function parseArgs(schema, args) {
|
|
2001
|
+
const result = schema.safeParse(args);
|
|
2002
|
+
if (!result.success) {
|
|
2003
|
+
return {
|
|
2004
|
+
ok: false,
|
|
2005
|
+
error: {
|
|
2006
|
+
content: [{ type: "text", text: `Invalid arguments: ${result.error.message}` }],
|
|
2007
|
+
isError: true
|
|
2008
|
+
}
|
|
2009
|
+
};
|
|
2010
|
+
}
|
|
2011
|
+
return { ok: true, data: result.data };
|
|
2012
|
+
}
|
|
2013
|
+
async function main() {
|
|
2014
|
+
const client = createClientFromEnv();
|
|
2015
|
+
const server = new Server(
|
|
2016
|
+
{ name: "temporal-mcp", version: "0.1.0" },
|
|
2017
|
+
{ capabilities: { tools: {} } }
|
|
2018
|
+
);
|
|
2019
|
+
const tier = resolveToolTier();
|
|
2020
|
+
const allToolDefs = [
|
|
2021
|
+
// Phase 1
|
|
2022
|
+
...clusterToolDefinitions,
|
|
2023
|
+
...namespaceToolDefinitions,
|
|
2024
|
+
...workflowToolDefinitions,
|
|
2025
|
+
...historyToolDefinitions,
|
|
2026
|
+
...scheduleToolDefinitions,
|
|
2027
|
+
...taskQueueToolDefinitions,
|
|
2028
|
+
...searchAttributeToolDefinitions,
|
|
2029
|
+
// Phase 2
|
|
2030
|
+
...activityToolDefinitions,
|
|
2031
|
+
...batchOperationToolDefinitions,
|
|
2032
|
+
...workerDeploymentToolDefinitions,
|
|
2033
|
+
...nexusEndpointToolDefinitions,
|
|
2034
|
+
...workflowRuleToolDefinitions
|
|
2035
|
+
];
|
|
2036
|
+
const tools = tier === "all" ? allToolDefs : allToolDefs.filter(
|
|
2037
|
+
(t) => tier === "standard" ? STANDARD_TOOLS.has(t.name) : ESSENTIAL_TOOLS.has(t.name)
|
|
2038
|
+
);
|
|
2039
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
|
|
2040
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
2041
|
+
const { name, arguments: args } = request.params;
|
|
2042
|
+
switch (name) {
|
|
2043
|
+
// ── Cluster ──────────────────────────────────────────────────────────
|
|
2044
|
+
case "get_cluster_info": {
|
|
2045
|
+
const parsed = parseArgs(getClusterInfoSchema, args);
|
|
2046
|
+
if (!parsed.ok) return parsed.error;
|
|
2047
|
+
return runTool(() => handleGetClusterInfo(parsed.data, client));
|
|
2048
|
+
}
|
|
2049
|
+
// ── Namespaces ───────────────────────────────────────────────────────
|
|
2050
|
+
case "list_namespaces": {
|
|
2051
|
+
const parsed = parseArgs(listNamespacesSchema, args);
|
|
2052
|
+
if (!parsed.ok) return parsed.error;
|
|
2053
|
+
return runTool(() => handleListNamespaces(parsed.data, client));
|
|
2054
|
+
}
|
|
2055
|
+
case "describe_namespace": {
|
|
2056
|
+
const parsed = parseArgs(describeNamespaceSchema, args);
|
|
2057
|
+
if (!parsed.ok) return parsed.error;
|
|
2058
|
+
return runTool(() => handleDescribeNamespace(parsed.data, client));
|
|
2059
|
+
}
|
|
2060
|
+
// ── Workflows ────────────────────────────────────────────────────────
|
|
2061
|
+
case "list_workflows": {
|
|
2062
|
+
const parsed = parseArgs(listWorkflowsSchema, args);
|
|
2063
|
+
if (!parsed.ok) return parsed.error;
|
|
2064
|
+
return runTool(() => handleListWorkflows(parsed.data, client));
|
|
2065
|
+
}
|
|
2066
|
+
case "describe_workflow": {
|
|
2067
|
+
const parsed = parseArgs(describeWorkflowSchema, args);
|
|
2068
|
+
if (!parsed.ok) return parsed.error;
|
|
2069
|
+
return runTool(() => handleDescribeWorkflow(parsed.data, client));
|
|
2070
|
+
}
|
|
2071
|
+
case "start_workflow": {
|
|
2072
|
+
const parsed = parseArgs(startWorkflowSchema, args);
|
|
2073
|
+
if (!parsed.ok) return parsed.error;
|
|
2074
|
+
return runTool(() => handleStartWorkflow(parsed.data, client));
|
|
2075
|
+
}
|
|
2076
|
+
case "signal_workflow": {
|
|
2077
|
+
const parsed = parseArgs(signalWorkflowSchema, args);
|
|
2078
|
+
if (!parsed.ok) return parsed.error;
|
|
2079
|
+
return runTool(() => handleSignalWorkflow(parsed.data, client));
|
|
2080
|
+
}
|
|
2081
|
+
case "query_workflow": {
|
|
2082
|
+
const parsed = parseArgs(queryWorkflowSchema, args);
|
|
2083
|
+
if (!parsed.ok) return parsed.error;
|
|
2084
|
+
return runTool(() => handleQueryWorkflow(parsed.data, client));
|
|
2085
|
+
}
|
|
2086
|
+
case "cancel_workflow": {
|
|
2087
|
+
const parsed = parseArgs(cancelWorkflowSchema, args);
|
|
2088
|
+
if (!parsed.ok) return parsed.error;
|
|
2089
|
+
return runTool(() => handleCancelWorkflow(parsed.data, client));
|
|
2090
|
+
}
|
|
2091
|
+
case "terminate_workflow": {
|
|
2092
|
+
const parsed = parseArgs(terminateWorkflowSchema, args);
|
|
2093
|
+
if (!parsed.ok) return parsed.error;
|
|
2094
|
+
return runTool(() => handleTerminateWorkflow(parsed.data, client));
|
|
2095
|
+
}
|
|
2096
|
+
// ── Workflow control (pause / unpause / count / signal-with-start) ───
|
|
2097
|
+
case "count_workflows": {
|
|
2098
|
+
const parsed = parseArgs(countWorkflowsSchema, args);
|
|
2099
|
+
if (!parsed.ok) return parsed.error;
|
|
2100
|
+
return runTool(() => handleCountWorkflows(parsed.data, client));
|
|
2101
|
+
}
|
|
2102
|
+
case "pause_workflow": {
|
|
2103
|
+
const parsed = parseArgs(pauseWorkflowSchema, args);
|
|
2104
|
+
if (!parsed.ok) return parsed.error;
|
|
2105
|
+
return runTool(() => handlePauseWorkflow(parsed.data, client));
|
|
2106
|
+
}
|
|
2107
|
+
case "unpause_workflow": {
|
|
2108
|
+
const parsed = parseArgs(unpauseWorkflowSchema, args);
|
|
2109
|
+
if (!parsed.ok) return parsed.error;
|
|
2110
|
+
return runTool(() => handleUnpauseWorkflow(parsed.data, client));
|
|
2111
|
+
}
|
|
2112
|
+
case "signal_with_start_workflow": {
|
|
2113
|
+
const parsed = parseArgs(signalWithStartWorkflowSchema, args);
|
|
2114
|
+
if (!parsed.ok) return parsed.error;
|
|
2115
|
+
return runTool(() => handleSignalWithStartWorkflow(parsed.data, client));
|
|
2116
|
+
}
|
|
2117
|
+
// ── Workflow History ─────────────────────────────────────────────────
|
|
2118
|
+
case "get_workflow_history": {
|
|
2119
|
+
const parsed = parseArgs(getWorkflowHistorySchema, args);
|
|
2120
|
+
if (!parsed.ok) return parsed.error;
|
|
2121
|
+
return runTool(() => handleGetWorkflowHistory(parsed.data, client));
|
|
2122
|
+
}
|
|
2123
|
+
// ── Schedules ────────────────────────────────────────────────────────
|
|
2124
|
+
case "list_schedules": {
|
|
2125
|
+
const parsed = parseArgs(listSchedulesSchema, args);
|
|
2126
|
+
if (!parsed.ok) return parsed.error;
|
|
2127
|
+
return runTool(() => handleListSchedules(parsed.data, client));
|
|
2128
|
+
}
|
|
2129
|
+
case "describe_schedule": {
|
|
2130
|
+
const parsed = parseArgs(describeScheduleSchema, args);
|
|
2131
|
+
if (!parsed.ok) return parsed.error;
|
|
2132
|
+
return runTool(() => handleDescribeSchedule(parsed.data, client));
|
|
2133
|
+
}
|
|
2134
|
+
case "create_schedule": {
|
|
2135
|
+
const parsed = parseArgs(createScheduleSchema, args);
|
|
2136
|
+
if (!parsed.ok) return parsed.error;
|
|
2137
|
+
return runTool(() => handleCreateSchedule(parsed.data, client));
|
|
2138
|
+
}
|
|
2139
|
+
case "delete_schedule": {
|
|
2140
|
+
const parsed = parseArgs(deleteScheduleSchema, args);
|
|
2141
|
+
if (!parsed.ok) return parsed.error;
|
|
2142
|
+
return runTool(() => handleDeleteSchedule(parsed.data, client));
|
|
2143
|
+
}
|
|
2144
|
+
// ── Task Queues ──────────────────────────────────────────────────────
|
|
2145
|
+
case "describe_task_queue": {
|
|
2146
|
+
const parsed = parseArgs(describeTaskQueueSchema, args);
|
|
2147
|
+
if (!parsed.ok) return parsed.error;
|
|
2148
|
+
return runTool(() => handleDescribeTaskQueue(parsed.data, client));
|
|
2149
|
+
}
|
|
2150
|
+
// ── Search Attributes ────────────────────────────────────────────────
|
|
2151
|
+
case "list_search_attributes": {
|
|
2152
|
+
const parsed = parseArgs(listSearchAttributesSchema, args);
|
|
2153
|
+
if (!parsed.ok) return parsed.error;
|
|
2154
|
+
return runTool(() => handleListSearchAttributes(parsed.data, client));
|
|
2155
|
+
}
|
|
2156
|
+
// ── Activities ───────────────────────────────────────────────────────
|
|
2157
|
+
case "list_activities": {
|
|
2158
|
+
const parsed = parseArgs(listActivitiesSchema, args);
|
|
2159
|
+
if (!parsed.ok) return parsed.error;
|
|
2160
|
+
return runTool(() => handleListActivities(parsed.data, client));
|
|
2161
|
+
}
|
|
2162
|
+
case "describe_activity": {
|
|
2163
|
+
const parsed = parseArgs(describeActivitySchema, args);
|
|
2164
|
+
if (!parsed.ok) return parsed.error;
|
|
2165
|
+
return runTool(() => handleDescribeActivity(parsed.data, client));
|
|
2166
|
+
}
|
|
2167
|
+
// ── Batch Operations ─────────────────────────────────────────────────
|
|
2168
|
+
case "list_batch_operations": {
|
|
2169
|
+
const parsed = parseArgs(listBatchOperationsSchema, args);
|
|
2170
|
+
if (!parsed.ok) return parsed.error;
|
|
2171
|
+
return runTool(() => handleListBatchOperations(parsed.data, client));
|
|
2172
|
+
}
|
|
2173
|
+
case "describe_batch_operation": {
|
|
2174
|
+
const parsed = parseArgs(describeBatchOperationSchema, args);
|
|
2175
|
+
if (!parsed.ok) return parsed.error;
|
|
2176
|
+
return runTool(() => handleDescribeBatchOperation(parsed.data, client));
|
|
2177
|
+
}
|
|
2178
|
+
case "stop_batch_operation": {
|
|
2179
|
+
const parsed = parseArgs(stopBatchOperationSchema, args);
|
|
2180
|
+
if (!parsed.ok) return parsed.error;
|
|
2181
|
+
return runTool(() => handleStopBatchOperation(parsed.data, client));
|
|
2182
|
+
}
|
|
2183
|
+
// ── Worker Deployments ───────────────────────────────────────────────
|
|
2184
|
+
case "list_worker_deployments": {
|
|
2185
|
+
const parsed = parseArgs(listWorkerDeploymentsSchema, args);
|
|
2186
|
+
if (!parsed.ok) return parsed.error;
|
|
2187
|
+
return runTool(() => handleListWorkerDeployments(parsed.data, client));
|
|
2188
|
+
}
|
|
2189
|
+
case "describe_worker_deployment": {
|
|
2190
|
+
const parsed = parseArgs(describeWorkerDeploymentSchema, args);
|
|
2191
|
+
if (!parsed.ok) return parsed.error;
|
|
2192
|
+
return runTool(() => handleDescribeWorkerDeployment(parsed.data, client));
|
|
2193
|
+
}
|
|
2194
|
+
// ── Nexus Endpoints ──────────────────────────────────────────────────
|
|
2195
|
+
case "list_nexus_endpoints": {
|
|
2196
|
+
const parsed = parseArgs(listNexusEndpointsSchema, args);
|
|
2197
|
+
if (!parsed.ok) return parsed.error;
|
|
2198
|
+
return runTool(() => handleListNexusEndpoints(parsed.data, client));
|
|
2199
|
+
}
|
|
2200
|
+
case "get_nexus_endpoint": {
|
|
2201
|
+
const parsed = parseArgs(getNexusEndpointSchema, args);
|
|
2202
|
+
if (!parsed.ok) return parsed.error;
|
|
2203
|
+
return runTool(() => handleGetNexusEndpoint(parsed.data, client));
|
|
2204
|
+
}
|
|
2205
|
+
case "create_nexus_endpoint": {
|
|
2206
|
+
const parsed = parseArgs(createNexusEndpointSchema, args);
|
|
2207
|
+
if (!parsed.ok) return parsed.error;
|
|
2208
|
+
return runTool(() => handleCreateNexusEndpoint(parsed.data, client));
|
|
2209
|
+
}
|
|
2210
|
+
case "delete_nexus_endpoint": {
|
|
2211
|
+
const parsed = parseArgs(deleteNexusEndpointSchema, args);
|
|
2212
|
+
if (!parsed.ok) return parsed.error;
|
|
2213
|
+
return runTool(() => handleDeleteNexusEndpoint(parsed.data, client));
|
|
2214
|
+
}
|
|
2215
|
+
// ── Workflow Rules ───────────────────────────────────────────────────
|
|
2216
|
+
case "list_workflow_rules": {
|
|
2217
|
+
const parsed = parseArgs(listWorkflowRulesSchema, args);
|
|
2218
|
+
if (!parsed.ok) return parsed.error;
|
|
2219
|
+
return runTool(() => handleListWorkflowRules(parsed.data, client));
|
|
2220
|
+
}
|
|
2221
|
+
case "describe_workflow_rule": {
|
|
2222
|
+
const parsed = parseArgs(describeWorkflowRuleSchema, args);
|
|
2223
|
+
if (!parsed.ok) return parsed.error;
|
|
2224
|
+
return runTool(() => handleDescribeWorkflowRule(parsed.data, client));
|
|
2225
|
+
}
|
|
2226
|
+
case "create_workflow_rule": {
|
|
2227
|
+
const parsed = parseArgs(createWorkflowRuleSchema, args);
|
|
2228
|
+
if (!parsed.ok) return parsed.error;
|
|
2229
|
+
return runTool(() => handleCreateWorkflowRule(parsed.data, client));
|
|
2230
|
+
}
|
|
2231
|
+
case "delete_workflow_rule": {
|
|
2232
|
+
const parsed = parseArgs(deleteWorkflowRuleSchema, args);
|
|
2233
|
+
if (!parsed.ok) return parsed.error;
|
|
2234
|
+
return runTool(() => handleDeleteWorkflowRule(parsed.data, client));
|
|
2235
|
+
}
|
|
2236
|
+
default:
|
|
2237
|
+
return {
|
|
2238
|
+
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
|
2239
|
+
isError: true
|
|
2240
|
+
};
|
|
2241
|
+
}
|
|
2242
|
+
});
|
|
2243
|
+
const transport = new StdioServerTransport();
|
|
2244
|
+
await server.connect(transport);
|
|
2245
|
+
process.stderr.write(`Temporal MCP server started (tools: ${tier}, ${tools.length} loaded)
|
|
2246
|
+
`);
|
|
2247
|
+
}
|
|
2248
|
+
main().catch((err) => {
|
|
2249
|
+
process.stderr.write(`Fatal error: ${err instanceof Error ? err.message : String(err)}
|
|
2250
|
+
`);
|
|
2251
|
+
process.exit(1);
|
|
2252
|
+
});
|
|
2253
|
+
//# sourceMappingURL=index.js.map
|
|
2254
|
+
//# sourceMappingURL=index.js.map
|