@burdenoff/mcp-libs 2026.902.1 → 2026.908.2

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.
@@ -0,0 +1,2158 @@
1
+ 'use strict';
2
+
3
+ var zod = require('zod');
4
+ require('graphql-request');
5
+ require('cross-fetch');
6
+ require('@modelcontextprotocol/sdk/server/mcp.js');
7
+ require('@modelcontextprotocol/sdk/types.js');
8
+
9
+ // src/modules/fluidgrids/tools/credentials.ts
10
+
11
+ // src/core/errors.ts
12
+ var McpInternalError = class extends Error {
13
+ cause;
14
+ constructor(message, cause) {
15
+ super(message);
16
+ this.name = "McpInternalError";
17
+ this.cause = cause;
18
+ }
19
+ };
20
+
21
+ // src/core/tool-name.ts
22
+ var MAX_TOOL_NAME_LENGTH = 63;
23
+ function assertSafeName(name, kind) {
24
+ if (name.length > MAX_TOOL_NAME_LENGTH) {
25
+ throw new McpInternalError(
26
+ `Tool name '${name}' exceeds ${MAX_TOOL_NAME_LENGTH} characters (some MCP clients truncate at 64).`
27
+ );
28
+ }
29
+ return name;
30
+ }
31
+ function mcpToolName(productName, ...parts) {
32
+ if (!productName) {
33
+ throw new McpInternalError("mcpToolName: productName is required");
34
+ }
35
+ const name = [productName, ...parts].filter(Boolean).join("_");
36
+ return assertSafeName(name);
37
+ }
38
+ function mcpResourceUri(productName, ...parts) {
39
+ if (!productName) {
40
+ throw new McpInternalError("mcpResourceUri: productName is required");
41
+ }
42
+ return `${productName}://${parts.filter(Boolean).join("/")}`;
43
+ }
44
+ function mcpPromptName(productName, ...parts) {
45
+ if (!productName) {
46
+ throw new McpInternalError("mcpPromptName: productName is required");
47
+ }
48
+ return [productName, ...parts].filter(Boolean).join("-");
49
+ }
50
+
51
+ // src/core/result.ts
52
+ function jsonResult(data, structured) {
53
+ const result = {
54
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
55
+ };
56
+ return result;
57
+ }
58
+ function errorResult(message, hint) {
59
+ const text = hint ? `${message}
60
+
61
+ Hint: ${hint}` : message;
62
+ return { content: [{ type: "text", text }], isError: true };
63
+ }
64
+
65
+ // src/modules/fluidgrids/operations.ts
66
+ var LIST_WORKFLOWS = `
67
+ query ListWorkflows($input: ListWorkflowDefinitionsInput!) {
68
+ workflowDefinitions(input: $input) {
69
+ items {
70
+ id
71
+ workflowKey
72
+ name
73
+ description
74
+ version
75
+ status
76
+ category
77
+ tags
78
+ isActive
79
+ totalVersions
80
+ createdAt
81
+ updatedAt
82
+ }
83
+ total
84
+ hasMore
85
+ }
86
+ }
87
+ `;
88
+ var GET_WORKFLOW = `
89
+ query GetWorkflow($id: ID, $workflowKey: String, $version: String) {
90
+ workflowDefinition(id: $id, workflowKey: $workflowKey, version: $version) {
91
+ id
92
+ workflowKey
93
+ name
94
+ description
95
+ version
96
+ status
97
+ category
98
+ tags
99
+ icon
100
+ isActive
101
+ totalVersions
102
+ definitionJson
103
+ createdAt
104
+ updatedAt
105
+ }
106
+ }
107
+ `;
108
+ var GET_WORKFLOW_VERSIONS = `
109
+ query GetWorkflowVersions($workflowKey: String!) {
110
+ workflowVersions(workflowKey: $workflowKey) {
111
+ id
112
+ workflowKey
113
+ name
114
+ description
115
+ version
116
+ status
117
+ category
118
+ tags
119
+ icon
120
+ isActive
121
+ totalVersions
122
+ createdAt
123
+ updatedAt
124
+ }
125
+ }
126
+ `;
127
+ var LIST_RUNS = `
128
+ query ListRuns($input: ListWorkflowRunsInput!) {
129
+ workflowRuns(input: $input) {
130
+ items {
131
+ id
132
+ workflowId
133
+ workflowKey
134
+ version
135
+ status
136
+ startedAt
137
+ completedAt
138
+ duration
139
+ triggeredById
140
+ errorMessage
141
+ errorType
142
+ progress
143
+ totalNodes
144
+ completedNodes
145
+ failedNodes
146
+ }
147
+ total
148
+ hasMore
149
+ }
150
+ }
151
+ `;
152
+ var GET_RUN = `
153
+ query GetRun($id: ID!) {
154
+ workflowRun(id: $id) {
155
+ id
156
+ workflowId
157
+ workflowKey
158
+ version
159
+ status
160
+ startedAt
161
+ completedAt
162
+ duration
163
+ triggeredById
164
+ triggerData
165
+ triggerNodeId
166
+ errorMessage
167
+ errorType
168
+ progress
169
+ totalNodes
170
+ completedNodes
171
+ failedNodes
172
+ skippedNodes
173
+ nodeStates {
174
+ nodeId
175
+ nodeType
176
+ status
177
+ error
178
+ output
179
+ }
180
+ }
181
+ }
182
+ `;
183
+ var GET_RUN_LOGS = `
184
+ query GetRunLogs(
185
+ $runId: ID!
186
+ $nodeId: String
187
+ $minLevel: RunLogLevel
188
+ $limit: Int
189
+ $after: String
190
+ $search: String
191
+ $includeChildRuns: Boolean
192
+ ) {
193
+ workflowRunLogs(
194
+ runId: $runId
195
+ nodeId: $nodeId
196
+ minLevel: $minLevel
197
+ limit: $limit
198
+ after: $after
199
+ search: $search
200
+ includeChildRuns: $includeChildRuns
201
+ ) {
202
+ lines {
203
+ id
204
+ runId
205
+ nodeId
206
+ level
207
+ message
208
+ timestamp
209
+ data
210
+ attempt
211
+ phase
212
+ stream
213
+ truncated
214
+ }
215
+ hasMore
216
+ nextCursor
217
+ limitReached
218
+ }
219
+ }
220
+ `;
221
+ var LIST_NODES = `
222
+ query ListNodes(
223
+ $nodeType: String
224
+ $publishType: PublishType
225
+ $status: NodeConfigStatus
226
+ $pagination: WorkflowPaginationInput
227
+ ) {
228
+ nodeEndpointConfigs(
229
+ nodeType: $nodeType
230
+ publishType: $publishType
231
+ status: $status
232
+ pagination: $pagination
233
+ ) {
234
+ configs {
235
+ id
236
+ nodeType
237
+ nodeVersion
238
+ name
239
+ description
240
+ category
241
+ icon
242
+ logo
243
+ keywords
244
+ kind
245
+ author
246
+ publishType
247
+ status
248
+ isLatest
249
+ endpointUrl
250
+ operations
251
+ supportsAdapterMode
252
+ adapterOutputType
253
+ createdAt
254
+ updatedAt
255
+ }
256
+ pagination {
257
+ total
258
+ limit
259
+ offset
260
+ hasMore
261
+ }
262
+ }
263
+ }
264
+ `;
265
+ var GET_NODE = `
266
+ query GetNode($nodeType: String!, $nodeVersion: String!) {
267
+ nodeEndpointConfig(nodeType: $nodeType, nodeVersion: $nodeVersion) {
268
+ id
269
+ nodeType
270
+ nodeVersion
271
+ name
272
+ description
273
+ category
274
+ icon
275
+ logo
276
+ keywords
277
+ kind
278
+ author
279
+ publishType
280
+ status
281
+ isLatest
282
+ endpointUrl
283
+ operations
284
+ supportsAdapterMode
285
+ adapterOutputType
286
+ createdAt
287
+ updatedAt
288
+ healthCheckUrl
289
+ nodeAdapters
290
+ }
291
+ }
292
+ `;
293
+ var LIST_CREDENTIALS = `
294
+ query ListCredentials($filter: ConnectionFilterInput, $pagination: IntegrationsPaginationInput) {
295
+ getConnections(filter: $filter, pagination: $pagination) {
296
+ items {
297
+ id
298
+ name
299
+ description
300
+ status
301
+ providerId
302
+ provider {
303
+ id
304
+ key
305
+ name
306
+ category
307
+ authType
308
+ icon
309
+ }
310
+ credentialSource
311
+ externalAccountId
312
+ externalAccountName
313
+ externalAccountEmail
314
+ grantedScopes
315
+ lastUsedAt
316
+ lastHealthCheck
317
+ errorMessage
318
+ createdAt
319
+ updatedAt
320
+ }
321
+ total
322
+ hasMore
323
+ }
324
+ }
325
+ `;
326
+ var GET_CREDENTIAL = `
327
+ query GetCredential($id: ID!) {
328
+ getConnection(id: $id) {
329
+ id
330
+ name
331
+ description
332
+ status
333
+ providerId
334
+ provider {
335
+ id
336
+ key
337
+ name
338
+ description
339
+ category
340
+ authType
341
+ configSchema
342
+ availableScopes
343
+ defaultScopes
344
+ icon
345
+ docsUrl
346
+ }
347
+ config
348
+ metadata
349
+ credentialSource
350
+ externalAccountId
351
+ externalAccountName
352
+ externalAccountEmail
353
+ grantedScopes
354
+ lastUsedAt
355
+ lastHealthCheck
356
+ errorMessage
357
+ workspaceId
358
+ createdAt
359
+ updatedAt
360
+ }
361
+ }
362
+ `;
363
+ var LIST_CREDENTIAL_TYPES = `
364
+ query ListCredentialTypes($filter: ProviderFilterInput, $pagination: IntegrationsPaginationInput) {
365
+ getProviders(filter: $filter, pagination: $pagination) {
366
+ items {
367
+ id
368
+ key
369
+ name
370
+ description
371
+ category
372
+ authType
373
+ configSchema
374
+ availableScopes
375
+ defaultScopes
376
+ icon
377
+ docsUrl
378
+ isBuiltIn
379
+ isEnabled
380
+ connectionCount
381
+ }
382
+ total
383
+ hasMore
384
+ }
385
+ }
386
+ `;
387
+ var LIST_WEBHOOKS = `
388
+ query ListWebhooks($status: EventStatus, $workflowKey: String) {
389
+ eventRegistrations(status: $status, workflowKey: $workflowKey) {
390
+ id
391
+ name
392
+ description
393
+ workflowKey
394
+ triggerNodeId
395
+ eventSource
396
+ eventType
397
+ status
398
+ isActive
399
+ webhookUrl
400
+ webhookToken
401
+ validationMethod
402
+ signatureHeader
403
+ apiKeyHeader
404
+ payloadMapping
405
+ config
406
+ tags
407
+ totalTriggers
408
+ successfulTriggers
409
+ failedTriggers
410
+ lastTriggeredAt
411
+ createdAt
412
+ updatedAt
413
+ }
414
+ }
415
+ `;
416
+ var GET_WEBHOOK = `
417
+ query GetWebhook($id: ID!) {
418
+ eventRegistration(id: $id) {
419
+ id
420
+ name
421
+ description
422
+ workflowKey
423
+ triggerNodeId
424
+ eventSource
425
+ eventType
426
+ status
427
+ isActive
428
+ webhookUrl
429
+ webhookToken
430
+ validationMethod
431
+ signatureHeader
432
+ apiKeyHeader
433
+ payloadMapping
434
+ config
435
+ tags
436
+ totalTriggers
437
+ successfulTriggers
438
+ failedTriggers
439
+ lastTriggeredAt
440
+ createdAt
441
+ updatedAt
442
+ projectId
443
+ workspaceId
444
+ createdById
445
+ }
446
+ }
447
+ `;
448
+ var LIST_SCHEDULED_JOBS = `
449
+ query ListScheduledJobs($enabled: Boolean, $workflowKey: String, $pagination: WorkflowPaginationInput) {
450
+ workflowScheduledJobs(enabled: $enabled, workflowKey: $workflowKey, pagination: $pagination) {
451
+ jobs {
452
+ id
453
+ name
454
+ workflowKey
455
+ version
456
+ schedule
457
+ enabled
458
+ nextRun
459
+ lastRun
460
+ config
461
+ createdAt
462
+ updatedAt
463
+ }
464
+ pagination {
465
+ total
466
+ limit
467
+ offset
468
+ hasMore
469
+ }
470
+ }
471
+ }
472
+ `;
473
+ var GET_SCHEDULED_JOB = `
474
+ query GetScheduledJob($jobId: ID!) {
475
+ workflowScheduledJob(jobId: $jobId) {
476
+ id
477
+ name
478
+ workflowKey
479
+ version
480
+ schedule
481
+ enabled
482
+ nextRun
483
+ lastRun
484
+ config
485
+ createdAt
486
+ updatedAt
487
+ workspaceId
488
+ }
489
+ }
490
+ `;
491
+ var GET_DASHBOARD_SUMMARY = `
492
+ query DashboardSummary($projectId: String) {
493
+ dashboardSummary(projectId: $projectId) {
494
+ userId
495
+ username
496
+ workflowsCount
497
+ activeWorkflowsCount
498
+ archivedWorkflowsCount
499
+ runsCountTotal
500
+ runsCompletedCount
501
+ runsFailedCount
502
+ runsCancelledCount
503
+ runsPendingCount
504
+ runsRunningCount
505
+ runsWaitingCount
506
+ runsCompletedLast24h
507
+ runsFailedLast24h
508
+ runsCompletedLast7d
509
+ runsFailedLast7d
510
+ runsCompletedLast30d
511
+ runsFailedLast30d
512
+ totalNodesExecutedCount
513
+ workflowSuccessRate
514
+ avgWorkflowExecutionTimeSeconds
515
+ avgNodeExecutionTimeSeconds
516
+ recentRuns {
517
+ id
518
+ workflowKey
519
+ version
520
+ status
521
+ startedAt
522
+ completedAt
523
+ duration
524
+ }
525
+ recentWorkflows {
526
+ workflowKey
527
+ name
528
+ version
529
+ updatedAt
530
+ }
531
+ nodeUsageStats {
532
+ nodeType
533
+ totalExecutions
534
+ successCount
535
+ failureCount
536
+ avgExecutionTime
537
+ }
538
+ }
539
+ }
540
+ `;
541
+ var GET_USAGE_METRICS = `
542
+ query GetUsageMetrics($input: UsageQueryInput!) {
543
+ usageMetrics(input: $input) {
544
+ period
545
+ workflowMetrics {
546
+ totalRuns
547
+ successfulRuns
548
+ failedRuns
549
+ cancelledRuns
550
+ totalDurationSeconds
551
+ averageDurationSeconds
552
+ minDurationSeconds
553
+ maxDurationSeconds
554
+ medianDurationSeconds
555
+ }
556
+ nodeMetrics {
557
+ totalNodes
558
+ successfulNodes
559
+ failedNodes
560
+ skippedNodes
561
+ totalDurationSeconds
562
+ averageDurationSeconds
563
+ nodeTypeBreakdown
564
+ }
565
+ }
566
+ }
567
+ `;
568
+ var SEARCH = `
569
+ query Search($input: SearchRequestInput!) {
570
+ search(input: $input) {
571
+ query
572
+ results
573
+ entityCounts
574
+ totalResults
575
+ metadata
576
+ }
577
+ }
578
+ `;
579
+ var SEARCH_BY_ENTITY_TYPE = `
580
+ query SearchByEntityType($entityType: String!, $query: String!, $filters: SearchFilterInput, $limit: Int, $offset: Int) {
581
+ searchByEntityType(entityType: $entityType, query: $query, filters: $filters, limit: $limit, offset: $offset) {
582
+ query
583
+ results
584
+ entityCounts
585
+ totalResults
586
+ metadata
587
+ }
588
+ }
589
+ `;
590
+ var GET_SYSTEM_CONFIG = `
591
+ query GetSystemConfig {
592
+ systemConfig {
593
+ version
594
+ revision
595
+ environment
596
+ deploymentType
597
+ hostname
598
+ hostIp
599
+ }
600
+ }
601
+ `;
602
+ var CREATE_WORKFLOW = `
603
+ mutation CreateWorkflow($input: CreateWorkflowDefinitionInput!) {
604
+ createWorkflowDefinition(input: $input) {
605
+ id
606
+ workflowKey
607
+ name
608
+ description
609
+ version
610
+ status
611
+ category
612
+ tags
613
+ icon
614
+ isActive
615
+ totalVersions
616
+ createdAt
617
+ updatedAt
618
+ }
619
+ }
620
+ `;
621
+ var UPDATE_WORKFLOW = `
622
+ mutation UpdateWorkflow($id: ID!, $input: UpdateWorkflowDefinitionInput!) {
623
+ updateWorkflowDefinition(id: $id, input: $input) {
624
+ id
625
+ workflowKey
626
+ name
627
+ description
628
+ version
629
+ status
630
+ category
631
+ tags
632
+ icon
633
+ isActive
634
+ totalVersions
635
+ createdAt
636
+ updatedAt
637
+ }
638
+ }
639
+ `;
640
+ var DELETE_WORKFLOW = `
641
+ mutation DeleteWorkflow($workflowKey: String!, $version: String) {
642
+ deleteWorkflowDefinition(workflowKey: $workflowKey, version: $version)
643
+ }
644
+ `;
645
+ var TRIGGER_WORKFLOW = `
646
+ mutation TriggerWorkflow($input: TriggerWorkflowInput!) {
647
+ triggerWorkflow(input: $input) {
648
+ runId
649
+ status
650
+ workflowKey
651
+ version
652
+ triggerNodeId
653
+ }
654
+ }
655
+ `;
656
+ var PUBLISH_WORKFLOW = `
657
+ mutation PublishWorkflow($id: ID!) {
658
+ publishWorkflow(id: $id) {
659
+ id
660
+ workflowKey
661
+ name
662
+ description
663
+ version
664
+ status
665
+ category
666
+ tags
667
+ icon
668
+ isActive
669
+ totalVersions
670
+ createdAt
671
+ updatedAt
672
+ }
673
+ }
674
+ `;
675
+ var ACTIVATE_WORKFLOW = `
676
+ mutation ActivateWorkflow($id: ID!) {
677
+ activateWorkflowDefinition(id: $id) {
678
+ id
679
+ workflowKey
680
+ name
681
+ description
682
+ version
683
+ status
684
+ category
685
+ tags
686
+ icon
687
+ isActive
688
+ totalVersions
689
+ createdAt
690
+ updatedAt
691
+ }
692
+ }
693
+ `;
694
+ var DEACTIVATE_WORKFLOW = `
695
+ mutation DeactivateWorkflow($id: ID!) {
696
+ deactivateWorkflowDefinition(id: $id) {
697
+ id
698
+ workflowKey
699
+ name
700
+ description
701
+ version
702
+ status
703
+ category
704
+ tags
705
+ icon
706
+ isActive
707
+ totalVersions
708
+ createdAt
709
+ updatedAt
710
+ }
711
+ }
712
+ `;
713
+ var DUPLICATE_WORKFLOW = `
714
+ mutation DuplicateWorkflow($workflowKey: String!, $version: String!, $input: DuplicateWorkflowInput!) {
715
+ duplicateWorkflow(workflowKey: $workflowKey, version: $version, input: $input) {
716
+ success
717
+ message
718
+ workflow {
719
+ id
720
+ workflowKey
721
+ name
722
+ description
723
+ version
724
+ status
725
+ category
726
+ tags
727
+ icon
728
+ isActive
729
+ totalVersions
730
+ createdAt
731
+ updatedAt
732
+ }
733
+ }
734
+ }
735
+ `;
736
+ var ARCHIVE_WORKFLOW = `
737
+ mutation ArchiveWorkflow($id: ID!) {
738
+ archiveWorkflow(id: $id) {
739
+ id
740
+ status
741
+ }
742
+ }
743
+ `;
744
+ var CANCEL_RUN = `
745
+ mutation CancelRun($id: ID!) {
746
+ cancelWorkflowRun(id: $id) {
747
+ id
748
+ status
749
+ completedAt
750
+ errorMessage
751
+ }
752
+ }
753
+ `;
754
+ var PAUSE_RUN = `
755
+ mutation PauseRun($id: ID!) {
756
+ pauseWorkflowRun(id: $id) {
757
+ id
758
+ status
759
+ completedAt
760
+ errorMessage
761
+ }
762
+ }
763
+ `;
764
+ var RESUME_RUN = `
765
+ mutation ResumeRun($id: ID!, $payload: JSON) {
766
+ resumeWorkflowRun(id: $id, payload: $payload) {
767
+ success
768
+ message
769
+ resumedFromNodeId
770
+ run {
771
+ id
772
+ status
773
+ completedAt
774
+ errorMessage
775
+ }
776
+ }
777
+ }
778
+ `;
779
+ var RETRY_RUN = `
780
+ mutation RetryNode($id: ID!, $nodeId: String!) {
781
+ retryNode(id: $id, nodeId: $nodeId) {
782
+ id
783
+ nodeId
784
+ nodeType
785
+ status
786
+ error
787
+ attemptCount
788
+ }
789
+ }
790
+ `;
791
+ var CREATE_CREDENTIAL = `
792
+ mutation CreateCredential($input: CreateConnectionInput!) {
793
+ createConnection(input: $input) {
794
+ id
795
+ name
796
+ description
797
+ status
798
+ providerId
799
+ provider {
800
+ id
801
+ key
802
+ name
803
+ authType
804
+ }
805
+ credentialSource
806
+ createdAt
807
+ }
808
+ }
809
+ `;
810
+ var AUTHENTICATE_CREDENTIAL_API_KEY = `
811
+ mutation AuthenticateCredentialApiKey($input: ApiKeyAuthInput!) {
812
+ authenticateWithApiKey(input: $input) {
813
+ id
814
+ name
815
+ status
816
+ grantedScopes
817
+ externalAccountName
818
+ errorMessage
819
+ updatedAt
820
+ }
821
+ }
822
+ `;
823
+ var AUTHENTICATE_CREDENTIAL_BASIC = `
824
+ mutation AuthenticateCredentialBasic($input: BasicAuthInput!) {
825
+ authenticateWithBasicAuth(input: $input) {
826
+ id
827
+ name
828
+ status
829
+ grantedScopes
830
+ externalAccountName
831
+ errorMessage
832
+ updatedAt
833
+ }
834
+ }
835
+ `;
836
+ var UPDATE_CREDENTIAL = `
837
+ mutation UpdateCredential($id: ID!, $input: UpdateConnectionInput!) {
838
+ updateConnection(id: $id, input: $input) {
839
+ id
840
+ name
841
+ description
842
+ status
843
+ config
844
+ updatedAt
845
+ }
846
+ }
847
+ `;
848
+ var DELETE_CREDENTIAL = `
849
+ mutation DeleteCredential($id: ID!, $deleteVaultSecret: Boolean) {
850
+ deleteConnection(id: $id, deleteVaultSecret: $deleteVaultSecret)
851
+ }
852
+ `;
853
+ var TEST_CREDENTIAL = `
854
+ mutation TestCredential($connectionId: ID!) {
855
+ testConnection(connectionId: $connectionId) {
856
+ success
857
+ message
858
+ latencyMs
859
+ }
860
+ }
861
+ `;
862
+ var CREATE_WEBHOOK = `
863
+ mutation CreateWebhook($input: CreateEventRegistrationInput!) {
864
+ createEventRegistration(input: $input) {
865
+ id
866
+ name
867
+ workflowKey
868
+ triggerNodeId
869
+ isActive
870
+ status
871
+ webhookUrl
872
+ webhookToken
873
+ updatedAt
874
+ createdAt
875
+ }
876
+ }
877
+ `;
878
+ var UPDATE_WEBHOOK = `
879
+ mutation UpdateWebhook($id: ID!, $input: UpdateEventRegistrationInput!) {
880
+ updateEventRegistration(id: $id, input: $input) {
881
+ id
882
+ name
883
+ workflowKey
884
+ triggerNodeId
885
+ isActive
886
+ status
887
+ webhookUrl
888
+ webhookToken
889
+ updatedAt
890
+ }
891
+ }
892
+ `;
893
+ var DELETE_WEBHOOK = `
894
+ mutation DeleteWebhook($id: ID!) {
895
+ deleteEventRegistration(id: $id)
896
+ }
897
+ `;
898
+ var TOGGLE_WEBHOOK = `
899
+ mutation ToggleWebhook($id: ID!, $isActive: Boolean!) {
900
+ toggleEventRegistration(id: $id, isActive: $isActive) {
901
+ id
902
+ name
903
+ workflowKey
904
+ triggerNodeId
905
+ isActive
906
+ status
907
+ webhookUrl
908
+ webhookToken
909
+ updatedAt
910
+ }
911
+ }
912
+ `;
913
+ var CREATE_SCHEDULED_JOB = `
914
+ mutation CreateScheduledJob($input: ScheduledJobInput!) {
915
+ createWorkflowScheduledJob(input: $input) {
916
+ success
917
+ message
918
+ job {
919
+ id
920
+ name
921
+ workflowKey
922
+ version
923
+ schedule
924
+ enabled
925
+ nextRun
926
+ lastRun
927
+ config
928
+ createdAt
929
+ updatedAt
930
+ }
931
+ }
932
+ }
933
+ `;
934
+ var UPDATE_SCHEDULED_JOB = `
935
+ mutation UpdateScheduledJob($jobId: ID!, $input: WorkflowUpdateScheduledJobInput!) {
936
+ updateWorkflowScheduledJob(jobId: $jobId, input: $input) {
937
+ success
938
+ message
939
+ job {
940
+ id
941
+ name
942
+ workflowKey
943
+ version
944
+ schedule
945
+ enabled
946
+ nextRun
947
+ lastRun
948
+ config
949
+ createdAt
950
+ updatedAt
951
+ }
952
+ }
953
+ }
954
+ `;
955
+ var DELETE_SCHEDULED_JOB = `
956
+ mutation DeleteScheduledJob($jobId: ID!) {
957
+ deleteWorkflowScheduledJob(jobId: $jobId) {
958
+ success
959
+ message
960
+ }
961
+ }
962
+ `;
963
+
964
+ // src/modules/fluidgrids/tools/helpers.ts
965
+ function isClientErrorShape(error) {
966
+ return typeof error === "object" && error !== null && "response" in error && "request" in error;
967
+ }
968
+ function safeErrorMessage(error) {
969
+ if (isClientErrorShape(error)) {
970
+ const errors = error.response?.errors;
971
+ if (Array.isArray(errors) && errors.length > 0) {
972
+ const joined = errors.map((e) => e?.message).filter((m) => typeof m === "string" && m.length > 0).join("; ");
973
+ if (joined) return joined;
974
+ }
975
+ const status = error.response?.status;
976
+ return status === void 0 ? "GraphQL request failed" : `GraphQL error (status ${status})`;
977
+ }
978
+ return error instanceof Error ? error.message : String(error);
979
+ }
980
+ async function runTool(ctx, label, run) {
981
+ try {
982
+ return await run();
983
+ } catch (error) {
984
+ const message = safeErrorMessage(error);
985
+ ctx.logger.error(`fluidgrids ${label} failed`, { error: message });
986
+ return errorResult(`Failed (${label}): ${message}`);
987
+ }
988
+ }
989
+ function definedInput(obj) {
990
+ const out = {};
991
+ for (const [key, value] of Object.entries(obj)) {
992
+ if (value !== void 0) out[key] = value;
993
+ }
994
+ return out;
995
+ }
996
+ function workflowPagination(limit, offset) {
997
+ if (limit === void 0 && offset === void 0) return void 0;
998
+ return definedInput({ limit, offset });
999
+ }
1000
+
1001
+ // src/modules/fluidgrids/tools/credentials.ts
1002
+ function pagination(limit, offset) {
1003
+ if (limit === void 0 && offset === void 0) return void 0;
1004
+ return definedInput({ limit, offset });
1005
+ }
1006
+ function registerCredentialTools(server, ctx, track) {
1007
+ server.registerTool(
1008
+ track(mcpToolName(ctx.productName, "credentials_list")),
1009
+ {
1010
+ title: "List Credentials",
1011
+ description: "List stored connections (credentials) available to workflows.",
1012
+ annotations: { readOnlyHint: true },
1013
+ inputSchema: {
1014
+ providerId: zod.z.string().optional().describe("Filter by provider ID"),
1015
+ name: zod.z.string().optional().describe("Filter by name"),
1016
+ limit: zod.z.number().optional().describe("Max results"),
1017
+ offset: zod.z.number().optional().describe("Offset for pagination")
1018
+ }
1019
+ },
1020
+ async ({ providerId, name, limit, offset }) => runTool(ctx, "credentials_list", async () => {
1021
+ const filter = definedInput({ providerId, name });
1022
+ const data = await ctx.gql.workspace.request(
1023
+ LIST_CREDENTIALS,
1024
+ {
1025
+ filter: Object.keys(filter).length > 0 ? filter : void 0,
1026
+ pagination: pagination(limit, offset)
1027
+ }
1028
+ );
1029
+ return jsonResult(data.getConnections);
1030
+ })
1031
+ );
1032
+ server.registerTool(
1033
+ track(mcpToolName(ctx.productName, "credentials_get")),
1034
+ {
1035
+ title: "Get Credential",
1036
+ description: "Get one connection by ID. Secret material is never returned.",
1037
+ annotations: { readOnlyHint: true },
1038
+ inputSchema: { id: zod.z.string().describe("Connection ID") }
1039
+ },
1040
+ async ({ id }) => runTool(ctx, "credentials_get", async () => {
1041
+ const data = await ctx.gql.workspace.request(GET_CREDENTIAL, {
1042
+ id
1043
+ });
1044
+ return jsonResult(data.getConnection);
1045
+ })
1046
+ );
1047
+ server.registerTool(
1048
+ track(mcpToolName(ctx.productName, "credentials_list_types")),
1049
+ {
1050
+ title: "List Credential Types",
1051
+ description: "List the providers a connection can be created against.",
1052
+ annotations: { readOnlyHint: true },
1053
+ inputSchema: {
1054
+ name: zod.z.string().optional().describe("Filter by provider name"),
1055
+ limit: zod.z.number().optional().describe("Max results"),
1056
+ offset: zod.z.number().optional().describe("Offset for pagination")
1057
+ }
1058
+ },
1059
+ async ({ name, limit, offset }) => runTool(ctx, "credentials_list_types", async () => {
1060
+ const filter = definedInput({ name });
1061
+ const data = await ctx.gql.workspace.request(
1062
+ LIST_CREDENTIAL_TYPES,
1063
+ {
1064
+ filter: Object.keys(filter).length > 0 ? filter : void 0,
1065
+ pagination: pagination(limit, offset)
1066
+ }
1067
+ );
1068
+ return jsonResult(data.getProviders);
1069
+ })
1070
+ );
1071
+ server.registerTool(
1072
+ track(mcpToolName(ctx.productName, "credentials_create")),
1073
+ {
1074
+ title: "Create Credential",
1075
+ description: "Create a connection against a provider. Secrets go to the vault; pass a reference, never a raw secret in config.",
1076
+ inputSchema: {
1077
+ name: zod.z.string().describe("Connection name"),
1078
+ providerId: zod.z.string().describe("Provider ID"),
1079
+ description: zod.z.string().optional().describe("Description"),
1080
+ config: zod.z.unknown().optional().describe("Non-secret provider config as JSON"),
1081
+ context: zod.z.unknown().optional().describe("Context JSON"),
1082
+ vaultId: zod.z.string().optional().describe("Vault to store secret material in"),
1083
+ credentialSecretId: zod.z.string().optional().describe("Existing vault secret reference"),
1084
+ managedSecretName: zod.z.string().optional().describe("Managed secret name")
1085
+ }
1086
+ },
1087
+ async (args) => runTool(ctx, "credentials_create", async () => {
1088
+ const data = await ctx.gql.workspace.request(
1089
+ CREATE_CREDENTIAL,
1090
+ { input: definedInput({ ...args }) }
1091
+ );
1092
+ return jsonResult(data.createConnection);
1093
+ })
1094
+ );
1095
+ server.registerTool(
1096
+ track(mcpToolName(ctx.productName, "credentials_update")),
1097
+ {
1098
+ title: "Update Credential",
1099
+ description: "Update a connection\u2019s name, description or non-secret config.",
1100
+ inputSchema: {
1101
+ id: zod.z.string().describe("Connection ID"),
1102
+ name: zod.z.string().optional().describe("Name"),
1103
+ description: zod.z.string().optional().describe("Description"),
1104
+ config: zod.z.unknown().optional().describe("Non-secret provider config as JSON")
1105
+ }
1106
+ },
1107
+ async ({ id, ...input }) => runTool(ctx, "credentials_update", async () => {
1108
+ const data = await ctx.gql.workspace.request(
1109
+ UPDATE_CREDENTIAL,
1110
+ { id, input: definedInput(input) }
1111
+ );
1112
+ return jsonResult(data.updateConnection);
1113
+ })
1114
+ );
1115
+ server.registerTool(
1116
+ track(mcpToolName(ctx.productName, "credentials_delete")),
1117
+ {
1118
+ title: "Delete Credential",
1119
+ description: "Delete a connection. Set deleteVaultSecret to also destroy the stored secret \u2014 that is irreversible.",
1120
+ annotations: { destructiveHint: true },
1121
+ inputSchema: {
1122
+ id: zod.z.string().describe("Connection ID"),
1123
+ deleteVaultSecret: zod.z.boolean().optional().describe("Also delete the vault secret")
1124
+ }
1125
+ },
1126
+ async ({ id, deleteVaultSecret }) => runTool(ctx, "credentials_delete", async () => {
1127
+ const data = await ctx.gql.workspace.request(
1128
+ DELETE_CREDENTIAL,
1129
+ { id, deleteVaultSecret }
1130
+ );
1131
+ return jsonResult(data.deleteConnection);
1132
+ })
1133
+ );
1134
+ server.registerTool(
1135
+ track(mcpToolName(ctx.productName, "credentials_test")),
1136
+ {
1137
+ title: "Test Credential",
1138
+ description: "Verify a connection can authenticate against its provider.",
1139
+ annotations: { readOnlyHint: true },
1140
+ inputSchema: { connectionId: zod.z.string().describe("Connection ID") }
1141
+ },
1142
+ async ({ connectionId }) => runTool(ctx, "credentials_test", async () => {
1143
+ const data = await ctx.gql.workspace.request(TEST_CREDENTIAL, {
1144
+ connectionId
1145
+ });
1146
+ return jsonResult(data.testConnection);
1147
+ })
1148
+ );
1149
+ server.registerTool(
1150
+ track(mcpToolName(ctx.productName, "credentials_auth_api_key")),
1151
+ {
1152
+ title: "Authenticate Credential (API key)",
1153
+ description: "Attach an API key to a connection via the API-key auth flow.",
1154
+ inputSchema: {
1155
+ connectionId: zod.z.string().describe("Connection ID"),
1156
+ apiKey: zod.z.string().describe("API key to store")
1157
+ }
1158
+ },
1159
+ async ({ connectionId, apiKey }) => runTool(ctx, "credentials_auth_api_key", async () => {
1160
+ const data = await ctx.gql.workspace.request(
1161
+ AUTHENTICATE_CREDENTIAL_API_KEY,
1162
+ { input: { connectionId, apiKey } }
1163
+ );
1164
+ return jsonResult(data.authenticateWithApiKey);
1165
+ })
1166
+ );
1167
+ server.registerTool(
1168
+ track(mcpToolName(ctx.productName, "credentials_auth_basic")),
1169
+ {
1170
+ title: "Authenticate Credential (basic)",
1171
+ description: "Attach basic-auth credentials to a connection.",
1172
+ inputSchema: {
1173
+ connectionId: zod.z.string().describe("Connection ID"),
1174
+ username: zod.z.string().describe("Username"),
1175
+ password: zod.z.string().describe("Password")
1176
+ }
1177
+ },
1178
+ async ({ connectionId, username, password }) => runTool(ctx, "credentials_auth_basic", async () => {
1179
+ const data = await ctx.gql.workspace.request(
1180
+ AUTHENTICATE_CREDENTIAL_BASIC,
1181
+ { input: { connectionId, username, password } }
1182
+ );
1183
+ return jsonResult(data.authenticateWithBasicAuth);
1184
+ })
1185
+ );
1186
+ }
1187
+ function registerInsightTools(server, ctx, track) {
1188
+ server.registerTool(
1189
+ track(mcpToolName(ctx.productName, "dashboard_summary")),
1190
+ {
1191
+ title: "Dashboard Summary",
1192
+ description: "Workflow, run and failure counters for the current workspace.",
1193
+ annotations: { readOnlyHint: true },
1194
+ inputSchema: { projectId: zod.z.string().optional().describe("Scope to one project") }
1195
+ },
1196
+ async ({ projectId }) => runTool(ctx, "dashboard_summary", async () => {
1197
+ const data = await ctx.gql.workspace.request(
1198
+ GET_DASHBOARD_SUMMARY,
1199
+ { projectId }
1200
+ );
1201
+ return jsonResult(data.dashboardSummary);
1202
+ })
1203
+ );
1204
+ server.registerTool(
1205
+ track(mcpToolName(ctx.productName, "usage_metrics")),
1206
+ {
1207
+ title: "Usage Metrics",
1208
+ description: "Usage metrics over a date range \u2014 run minutes and execution counts.",
1209
+ annotations: { readOnlyHint: true },
1210
+ inputSchema: {
1211
+ startDate: zod.z.string().describe("ISO 8601 start of the range"),
1212
+ endDate: zod.z.string().describe("ISO 8601 end of the range"),
1213
+ userId: zod.z.string().optional().describe("Scope to one user"),
1214
+ contextFilter: zod.z.unknown().optional().describe("Context filter as JSON")
1215
+ }
1216
+ },
1217
+ async (args) => runTool(ctx, "usage_metrics", async () => {
1218
+ const data = await ctx.gql.workspace.request(GET_USAGE_METRICS, {
1219
+ input: definedInput({ ...args })
1220
+ });
1221
+ return jsonResult(data.usageMetrics);
1222
+ })
1223
+ );
1224
+ server.registerTool(
1225
+ track(mcpToolName(ctx.productName, "search")),
1226
+ {
1227
+ title: "Search",
1228
+ description: "Search across FluidGrids entities. Narrow with entityTypes when you know it.",
1229
+ annotations: { readOnlyHint: true },
1230
+ inputSchema: {
1231
+ query: zod.z.string().describe("Search query"),
1232
+ entityTypes: zod.z.array(zod.z.string()).optional().describe("Restrict to these entity types"),
1233
+ filters: zod.z.unknown().optional().describe("Additional filters as JSON"),
1234
+ highlight: zod.z.boolean().optional().describe("Return highlighted snippets"),
1235
+ limit: zod.z.number().optional().describe("Max results"),
1236
+ offset: zod.z.number().optional().describe("Offset for pagination")
1237
+ }
1238
+ },
1239
+ async (args) => runTool(ctx, "search", async () => {
1240
+ const data = await ctx.gql.workspace.request(SEARCH, {
1241
+ input: definedInput({ ...args })
1242
+ });
1243
+ return jsonResult(data.search);
1244
+ })
1245
+ );
1246
+ server.registerTool(
1247
+ track(mcpToolName(ctx.productName, "search_by_entity_type")),
1248
+ {
1249
+ title: "Search By Entity Type",
1250
+ description: "Search within a single entity type.",
1251
+ annotations: { readOnlyHint: true },
1252
+ inputSchema: {
1253
+ entityType: zod.z.string().describe("Entity type to search"),
1254
+ query: zod.z.string().describe("Search query"),
1255
+ filters: zod.z.unknown().optional().describe("Additional filters as JSON"),
1256
+ limit: zod.z.number().optional().describe("Max results"),
1257
+ offset: zod.z.number().optional().describe("Offset for pagination")
1258
+ }
1259
+ },
1260
+ async (args) => runTool(ctx, "search_by_entity_type", async () => {
1261
+ const data = await ctx.gql.workspace.request(
1262
+ SEARCH_BY_ENTITY_TYPE,
1263
+ definedInput({ ...args })
1264
+ );
1265
+ return jsonResult(data.searchByEntityType);
1266
+ })
1267
+ );
1268
+ server.registerTool(
1269
+ track(mcpToolName(ctx.productName, "system_config")),
1270
+ {
1271
+ title: "System Config",
1272
+ description: "Read the workflow engine\u2019s effective system configuration.",
1273
+ annotations: { readOnlyHint: true },
1274
+ inputSchema: {}
1275
+ },
1276
+ async () => runTool(ctx, "system_config", async () => {
1277
+ const data = await ctx.gql.workspace.request(GET_SYSTEM_CONFIG);
1278
+ return jsonResult(data.systemConfig);
1279
+ })
1280
+ );
1281
+ }
1282
+ var PublishTypeEnum = zod.z.enum(["BUILTIN", "CUSTOM", "STORE"]);
1283
+ var NodeConfigStatusEnum = zod.z.enum(["AVAILABLE", "DEPRECATED", "DISABLED"]);
1284
+ function registerNodeTools(server, ctx, track) {
1285
+ server.registerTool(
1286
+ track(mcpToolName(ctx.productName, "nodes_list")),
1287
+ {
1288
+ title: "List Nodes",
1289
+ description: "List the node types available to build workflows with, from the node endpoint config registry.",
1290
+ annotations: { readOnlyHint: true },
1291
+ inputSchema: {
1292
+ nodeType: zod.z.string().optional().describe("Filter by node type"),
1293
+ publishType: PublishTypeEnum.optional().describe("BUILTIN, CUSTOM or STORE"),
1294
+ status: NodeConfigStatusEnum.optional().describe("Filter by availability"),
1295
+ limit: zod.z.number().optional().describe("Max results"),
1296
+ offset: zod.z.number().optional().describe("Offset for pagination")
1297
+ }
1298
+ },
1299
+ async ({ nodeType, publishType, status, limit, offset }) => runTool(ctx, "nodes_list", async () => {
1300
+ const data = await ctx.gql.workspace.request(LIST_NODES, {
1301
+ nodeType,
1302
+ publishType,
1303
+ status,
1304
+ pagination: workflowPagination(limit, offset)
1305
+ });
1306
+ return jsonResult(data.nodeEndpointConfigs);
1307
+ })
1308
+ );
1309
+ server.registerTool(
1310
+ track(mcpToolName(ctx.productName, "nodes_get")),
1311
+ {
1312
+ title: "Get Node",
1313
+ description: "Get one node type at a specific version, including its input fields and operations.",
1314
+ annotations: { readOnlyHint: true },
1315
+ inputSchema: {
1316
+ nodeType: zod.z.string().describe("Node type identifier"),
1317
+ nodeVersion: zod.z.string().describe("Node version")
1318
+ }
1319
+ },
1320
+ async ({ nodeType, nodeVersion }) => runTool(ctx, "nodes_get", async () => {
1321
+ const data = await ctx.gql.workspace.request(GET_NODE, {
1322
+ nodeType,
1323
+ nodeVersion
1324
+ });
1325
+ return jsonResult(data.nodeEndpointConfig);
1326
+ })
1327
+ );
1328
+ }
1329
+ var RunStatusEnum = zod.z.enum([
1330
+ "CANCELLED",
1331
+ "COMPLETED",
1332
+ "FAILED",
1333
+ "PENDING",
1334
+ "RUNNING",
1335
+ "TERMINATED",
1336
+ "WAITING"
1337
+ ]);
1338
+ var RunLogLevelEnum = zod.z.enum(["DEBUG", "ERROR", "INFO", "WARN"]);
1339
+ function registerRunTools(server, ctx, track) {
1340
+ server.registerTool(
1341
+ track(mcpToolName(ctx.productName, "runs_list")),
1342
+ {
1343
+ title: "List Runs",
1344
+ description: "List workflow runs, optionally filtered by workflowKey and status.",
1345
+ annotations: { readOnlyHint: true },
1346
+ inputSchema: {
1347
+ workflowKey: zod.z.string().optional().describe("Filter by workflow key"),
1348
+ status: RunStatusEnum.optional().describe("Filter by run status"),
1349
+ limit: zod.z.number().optional().describe("Max results (default 10)"),
1350
+ offset: zod.z.number().optional().describe("Offset for pagination (default 0)")
1351
+ }
1352
+ },
1353
+ async ({ workflowKey, status, limit, offset }) => runTool(ctx, "runs_list", async () => {
1354
+ const data = await ctx.gql.workspace.request(LIST_RUNS, {
1355
+ input: definedInput({ workflowKey, status, limit, offset })
1356
+ });
1357
+ return jsonResult(data.workflowRuns);
1358
+ })
1359
+ );
1360
+ server.registerTool(
1361
+ track(mcpToolName(ctx.productName, "runs_get")),
1362
+ {
1363
+ title: "Get Run",
1364
+ description: "Get one workflow run, including per-node state. Poll this to follow a run to a terminal status.",
1365
+ annotations: { readOnlyHint: true },
1366
+ inputSchema: { id: zod.z.string().describe("Run ID") }
1367
+ },
1368
+ async ({ id }) => runTool(ctx, "runs_get", async () => {
1369
+ const data = await ctx.gql.workspace.request(GET_RUN, { id });
1370
+ return jsonResult(data.workflowRun);
1371
+ })
1372
+ );
1373
+ server.registerTool(
1374
+ track(mcpToolName(ctx.productName, "runs_logs")),
1375
+ {
1376
+ title: "Get Run Logs",
1377
+ description: "Read a run log, newest page first. Keyset paginated: pass the previous page cursor as `after`.",
1378
+ annotations: { readOnlyHint: true },
1379
+ inputSchema: {
1380
+ runId: zod.z.string().describe("Run ID"),
1381
+ nodeId: zod.z.string().optional().describe("Restrict to one node"),
1382
+ minLevel: RunLogLevelEnum.optional().describe("Minimum log level"),
1383
+ limit: zod.z.number().optional().describe("Max log lines"),
1384
+ after: zod.z.string().optional().describe("Keyset cursor from a previous page"),
1385
+ search: zod.z.string().optional().describe("Substring filter"),
1386
+ includeChildRuns: zod.z.boolean().optional().describe("Include logs from child runs")
1387
+ }
1388
+ },
1389
+ async (args) => runTool(ctx, "runs_logs", async () => {
1390
+ const data = await ctx.gql.workspace.request(
1391
+ GET_RUN_LOGS,
1392
+ definedInput({ ...args })
1393
+ );
1394
+ return jsonResult(data.workflowRunLogs);
1395
+ })
1396
+ );
1397
+ server.registerTool(
1398
+ track(mcpToolName(ctx.productName, "runs_cancel")),
1399
+ {
1400
+ title: "Cancel Run",
1401
+ description: "Cancel an in-flight run. Terminal runs cannot be cancelled.",
1402
+ annotations: { destructiveHint: true },
1403
+ inputSchema: { id: zod.z.string().describe("Run ID") }
1404
+ },
1405
+ async ({ id }) => runTool(ctx, "runs_cancel", async () => {
1406
+ const data = await ctx.gql.workspace.request(CANCEL_RUN, {
1407
+ id
1408
+ });
1409
+ return jsonResult(data.cancelWorkflowRun);
1410
+ })
1411
+ );
1412
+ server.registerTool(
1413
+ track(mcpToolName(ctx.productName, "runs_pause")),
1414
+ {
1415
+ title: "Pause Run",
1416
+ description: "Pause a running workflow run.",
1417
+ inputSchema: { id: zod.z.string().describe("Run ID") }
1418
+ },
1419
+ async ({ id }) => runTool(ctx, "runs_pause", async () => {
1420
+ const data = await ctx.gql.workspace.request(PAUSE_RUN, {
1421
+ id
1422
+ });
1423
+ return jsonResult(data.pauseWorkflowRun);
1424
+ })
1425
+ );
1426
+ server.registerTool(
1427
+ track(mcpToolName(ctx.productName, "runs_resume")),
1428
+ {
1429
+ title: "Resume Run",
1430
+ description: "Resume a paused or waiting run. `payload` supplies the data a Wait node is blocked on.",
1431
+ inputSchema: {
1432
+ id: zod.z.string().describe("Run ID"),
1433
+ payload: zod.z.unknown().optional().describe("Payload to resume with")
1434
+ }
1435
+ },
1436
+ async ({ id, payload }) => runTool(ctx, "runs_resume", async () => {
1437
+ const data = await ctx.gql.workspace.request(RESUME_RUN, {
1438
+ id,
1439
+ payload
1440
+ });
1441
+ return jsonResult(data.resumeWorkflowRun);
1442
+ })
1443
+ );
1444
+ server.registerTool(
1445
+ track(mcpToolName(ctx.productName, "runs_retry_node")),
1446
+ {
1447
+ title: "Retry Node",
1448
+ description: "Re-execute one failed node within a run, continuing from there.",
1449
+ inputSchema: {
1450
+ id: zod.z.string().describe("Run ID"),
1451
+ nodeId: zod.z.string().describe("Node ID to retry")
1452
+ }
1453
+ },
1454
+ async ({ id, nodeId }) => runTool(ctx, "runs_retry_node", async () => {
1455
+ const data = await ctx.gql.workspace.request(RETRY_RUN, {
1456
+ id,
1457
+ nodeId
1458
+ });
1459
+ return jsonResult(data.retryNode);
1460
+ })
1461
+ );
1462
+ }
1463
+ function registerScheduledJobTools(server, ctx, track) {
1464
+ server.registerTool(
1465
+ track(mcpToolName(ctx.productName, "scheduled_jobs_list")),
1466
+ {
1467
+ title: "List Scheduled Jobs",
1468
+ description: "List schedules that trigger workflows on a cron or interval.",
1469
+ annotations: { readOnlyHint: true },
1470
+ inputSchema: {
1471
+ enabled: zod.z.boolean().optional().describe("Filter by enabled state"),
1472
+ workflowKey: zod.z.string().optional().describe("Filter by workflow key"),
1473
+ limit: zod.z.number().optional().describe("Max results"),
1474
+ offset: zod.z.number().optional().describe("Offset for pagination")
1475
+ }
1476
+ },
1477
+ async ({ enabled, workflowKey, limit, offset }) => runTool(ctx, "scheduled_jobs_list", async () => {
1478
+ const data = await ctx.gql.workspace.request(
1479
+ LIST_SCHEDULED_JOBS,
1480
+ { enabled, workflowKey, pagination: workflowPagination(limit, offset) }
1481
+ );
1482
+ return jsonResult(data.workflowScheduledJobs);
1483
+ })
1484
+ );
1485
+ server.registerTool(
1486
+ track(mcpToolName(ctx.productName, "scheduled_jobs_get")),
1487
+ {
1488
+ title: "Get Scheduled Job",
1489
+ description: "Get one scheduled job by ID.",
1490
+ annotations: { readOnlyHint: true },
1491
+ inputSchema: { jobId: zod.z.string().describe("Scheduled job ID") }
1492
+ },
1493
+ async ({ jobId }) => runTool(ctx, "scheduled_jobs_get", async () => {
1494
+ const data = await ctx.gql.workspace.request(
1495
+ GET_SCHEDULED_JOB,
1496
+ { jobId }
1497
+ );
1498
+ return jsonResult(data.workflowScheduledJob);
1499
+ })
1500
+ );
1501
+ server.registerTool(
1502
+ track(mcpToolName(ctx.productName, "scheduled_jobs_create")),
1503
+ {
1504
+ title: "Create Scheduled Job",
1505
+ description: "Schedule a workflow. `schedule` is the cron or interval expression the scheduler service evaluates.",
1506
+ inputSchema: {
1507
+ name: zod.z.string().describe("Job name"),
1508
+ workflowKey: zod.z.string().describe("Workflow key to run"),
1509
+ version: zod.z.string().describe("Workflow version"),
1510
+ schedule: zod.z.string().describe("Cron or interval expression"),
1511
+ enabled: zod.z.boolean().optional().describe("Start enabled (default true)"),
1512
+ config: zod.z.unknown().optional().describe("Job config as JSON")
1513
+ }
1514
+ },
1515
+ async (args) => runTool(ctx, "scheduled_jobs_create", async () => {
1516
+ const data = await ctx.gql.workspace.request(
1517
+ CREATE_SCHEDULED_JOB,
1518
+ { input: definedInput({ ...args }) }
1519
+ );
1520
+ return jsonResult(data.createWorkflowScheduledJob);
1521
+ })
1522
+ );
1523
+ server.registerTool(
1524
+ track(mcpToolName(ctx.productName, "scheduled_jobs_update")),
1525
+ {
1526
+ title: "Update Scheduled Job",
1527
+ description: "Update a scheduled job\u2019s name, schedule, config or enabled state.",
1528
+ inputSchema: {
1529
+ jobId: zod.z.string().describe("Scheduled job ID"),
1530
+ name: zod.z.string().optional().describe("Name"),
1531
+ schedule: zod.z.string().optional().describe("Cron or interval expression"),
1532
+ enabled: zod.z.boolean().optional().describe("Enabled state"),
1533
+ config: zod.z.unknown().optional().describe("Job config as JSON")
1534
+ }
1535
+ },
1536
+ async ({ jobId, ...input }) => runTool(ctx, "scheduled_jobs_update", async () => {
1537
+ const data = await ctx.gql.workspace.request(
1538
+ UPDATE_SCHEDULED_JOB,
1539
+ { jobId, input: definedInput(input) }
1540
+ );
1541
+ return jsonResult(data.updateWorkflowScheduledJob);
1542
+ })
1543
+ );
1544
+ server.registerTool(
1545
+ track(mcpToolName(ctx.productName, "scheduled_jobs_delete")),
1546
+ {
1547
+ title: "Delete Scheduled Job",
1548
+ description: "Delete a scheduled job permanently.",
1549
+ annotations: { destructiveHint: true },
1550
+ inputSchema: { jobId: zod.z.string().describe("Scheduled job ID") }
1551
+ },
1552
+ async ({ jobId }) => runTool(ctx, "scheduled_jobs_delete", async () => {
1553
+ const data = await ctx.gql.workspace.request(
1554
+ DELETE_SCHEDULED_JOB,
1555
+ { jobId }
1556
+ );
1557
+ return jsonResult(data.deleteWorkflowScheduledJob);
1558
+ })
1559
+ );
1560
+ }
1561
+ var EventStatusEnum = zod.z.enum(["ACTIVE", "ARCHIVED", "DISABLED", "PAUSED"]);
1562
+ function registerWebhookTools(server, ctx, track) {
1563
+ server.registerTool(
1564
+ track(mcpToolName(ctx.productName, "webhooks_list")),
1565
+ {
1566
+ title: "List Webhooks",
1567
+ description: "List event registrations (webhooks) that can trigger workflows.",
1568
+ annotations: { readOnlyHint: true },
1569
+ inputSchema: {
1570
+ status: EventStatusEnum.optional().describe("Filter by status"),
1571
+ workflowKey: zod.z.string().optional().describe("Filter by workflow key")
1572
+ }
1573
+ },
1574
+ async ({ status, workflowKey }) => runTool(ctx, "webhooks_list", async () => {
1575
+ const data = await ctx.gql.workspace.request(
1576
+ LIST_WEBHOOKS,
1577
+ { status, workflowKey }
1578
+ );
1579
+ return jsonResult(data.eventRegistrations);
1580
+ })
1581
+ );
1582
+ server.registerTool(
1583
+ track(mcpToolName(ctx.productName, "webhooks_get")),
1584
+ {
1585
+ title: "Get Webhook",
1586
+ description: "Get one event registration by ID.",
1587
+ annotations: { readOnlyHint: true },
1588
+ inputSchema: { id: zod.z.string().describe("Event registration ID") }
1589
+ },
1590
+ async ({ id }) => runTool(ctx, "webhooks_get", async () => {
1591
+ const data = await ctx.gql.workspace.request(GET_WEBHOOK, {
1592
+ id
1593
+ });
1594
+ return jsonResult(data.eventRegistration);
1595
+ })
1596
+ );
1597
+ server.registerTool(
1598
+ track(mcpToolName(ctx.productName, "webhooks_create")),
1599
+ {
1600
+ title: "Create Webhook",
1601
+ description: "Register an event source that triggers a workflow. triggerNodeId names the trigger node the event enters at.",
1602
+ inputSchema: {
1603
+ name: zod.z.string().describe("Registration name"),
1604
+ workflowKey: zod.z.string().describe("Workflow key to trigger"),
1605
+ triggerNodeId: zod.z.string().describe("Trigger node ID"),
1606
+ eventSource: zod.z.string().optional().describe("Event source identifier"),
1607
+ eventType: zod.z.string().optional().describe("Event type"),
1608
+ description: zod.z.string().optional().describe("Description"),
1609
+ config: zod.z.unknown().optional().describe("Source-specific config as JSON"),
1610
+ payloadMapping: zod.z.unknown().optional().describe("Payload mapping as JSON"),
1611
+ validationMethod: zod.z.string().optional().describe("Signature validation method"),
1612
+ signatureHeader: zod.z.string().optional().describe("Header carrying the signature"),
1613
+ apiKeyHeader: zod.z.string().optional().describe("Header carrying the API key"),
1614
+ secretToken: zod.z.string().optional().describe("Shared secret for validation"),
1615
+ projectId: zod.z.string().optional().describe("Owning project ID"),
1616
+ tags: zod.z.array(zod.z.string()).optional().describe("Tags")
1617
+ }
1618
+ },
1619
+ async (args) => runTool(ctx, "webhooks_create", async () => {
1620
+ const data = await ctx.gql.workspace.request(
1621
+ CREATE_WEBHOOK,
1622
+ { input: definedInput({ ...args }) }
1623
+ );
1624
+ return jsonResult(data.createEventRegistration);
1625
+ })
1626
+ );
1627
+ server.registerTool(
1628
+ track(mcpToolName(ctx.productName, "webhooks_update")),
1629
+ {
1630
+ title: "Update Webhook",
1631
+ description: "Update an event registration.",
1632
+ inputSchema: {
1633
+ id: zod.z.string().describe("Event registration ID"),
1634
+ name: zod.z.string().optional().describe("Name"),
1635
+ description: zod.z.string().optional().describe("Description"),
1636
+ status: EventStatusEnum.optional().describe("Status"),
1637
+ isActive: zod.z.boolean().optional().describe("Active flag"),
1638
+ config: zod.z.unknown().optional().describe("Config as JSON"),
1639
+ payloadMapping: zod.z.unknown().optional().describe("Payload mapping as JSON"),
1640
+ validationMethod: zod.z.string().optional().describe("Signature validation method"),
1641
+ secretToken: zod.z.string().optional().describe("Shared secret"),
1642
+ tags: zod.z.array(zod.z.string()).optional().describe("Tags")
1643
+ }
1644
+ },
1645
+ async ({ id, ...input }) => runTool(ctx, "webhooks_update", async () => {
1646
+ const data = await ctx.gql.workspace.request(
1647
+ UPDATE_WEBHOOK,
1648
+ { id, input: definedInput(input) }
1649
+ );
1650
+ return jsonResult(data.updateEventRegistration);
1651
+ })
1652
+ );
1653
+ server.registerTool(
1654
+ track(mcpToolName(ctx.productName, "webhooks_toggle")),
1655
+ {
1656
+ title: "Toggle Webhook",
1657
+ description: "Enable or disable an event registration without deleting it.",
1658
+ inputSchema: {
1659
+ id: zod.z.string().describe("Event registration ID"),
1660
+ isActive: zod.z.boolean().describe("True to enable, false to disable")
1661
+ }
1662
+ },
1663
+ async ({ id, isActive }) => runTool(ctx, "webhooks_toggle", async () => {
1664
+ const data = await ctx.gql.workspace.request(
1665
+ TOGGLE_WEBHOOK,
1666
+ { id, isActive }
1667
+ );
1668
+ return jsonResult(data.toggleEventRegistration);
1669
+ })
1670
+ );
1671
+ server.registerTool(
1672
+ track(mcpToolName(ctx.productName, "webhooks_delete")),
1673
+ {
1674
+ title: "Delete Webhook",
1675
+ description: "Delete an event registration permanently.",
1676
+ annotations: { destructiveHint: true },
1677
+ inputSchema: { id: zod.z.string().describe("Event registration ID") }
1678
+ },
1679
+ async ({ id }) => runTool(ctx, "webhooks_delete", async () => {
1680
+ const data = await ctx.gql.workspace.request(
1681
+ DELETE_WEBHOOK,
1682
+ { id }
1683
+ );
1684
+ return jsonResult(data.deleteEventRegistration);
1685
+ })
1686
+ );
1687
+ }
1688
+ var WorkflowStatusEnum = zod.z.enum(["ACTIVE", "ARCHIVED", "DEPRECATED", "DRAFT"]);
1689
+ function registerWorkflowTools(server, ctx, track) {
1690
+ server.registerTool(
1691
+ track(mcpToolName(ctx.productName, "workflows_list")),
1692
+ {
1693
+ title: "List Workflows",
1694
+ description: "List FluidGrids workflow definitions with optional filters and pagination. Use latestOnly to collapse a workflowKey to its newest version.",
1695
+ annotations: { readOnlyHint: true },
1696
+ inputSchema: {
1697
+ status: WorkflowStatusEnum.optional().describe("Filter by workflow status"),
1698
+ category: zod.z.string().optional().describe("Filter by category"),
1699
+ tags: zod.z.array(zod.z.string()).optional().describe("Filter by tags"),
1700
+ latestOnly: zod.z.boolean().optional().describe("Return only the latest version per workflowKey"),
1701
+ limit: zod.z.number().optional().describe("Max results (default 10)"),
1702
+ offset: zod.z.number().optional().describe("Offset for pagination (default 0)")
1703
+ }
1704
+ },
1705
+ async ({ status, category, tags, latestOnly, limit, offset }) => runTool(ctx, "workflows_list", async () => {
1706
+ const data = await ctx.gql.workspace.request(
1707
+ LIST_WORKFLOWS,
1708
+ { input: definedInput({ status, category, tags, latestOnly, limit, offset }) }
1709
+ );
1710
+ return jsonResult(data.workflowDefinitions);
1711
+ })
1712
+ );
1713
+ server.registerTool(
1714
+ track(mcpToolName(ctx.productName, "workflows_get")),
1715
+ {
1716
+ title: "Get Workflow",
1717
+ description: "Get a single workflow definition by id, or by workflowKey (optionally pinned to a version). Without a version the executable version is resolved.",
1718
+ annotations: { readOnlyHint: true },
1719
+ inputSchema: {
1720
+ id: zod.z.string().optional().describe("Workflow definition ID"),
1721
+ workflowKey: zod.z.string().optional().describe("Workflow key (alternative to id)"),
1722
+ version: zod.z.string().optional().describe("Pin to a specific version")
1723
+ }
1724
+ },
1725
+ async ({ id, workflowKey, version }) => runTool(ctx, "workflows_get", async () => {
1726
+ const data = await ctx.gql.workspace.request(
1727
+ GET_WORKFLOW,
1728
+ {
1729
+ id,
1730
+ workflowKey,
1731
+ version
1732
+ }
1733
+ );
1734
+ return jsonResult(data.workflowDefinition);
1735
+ })
1736
+ );
1737
+ server.registerTool(
1738
+ track(mcpToolName(ctx.productName, "workflows_versions")),
1739
+ {
1740
+ title: "List Workflow Versions",
1741
+ description: "List every stored version of one workflowKey.",
1742
+ annotations: { readOnlyHint: true },
1743
+ inputSchema: { workflowKey: zod.z.string().describe("Workflow key") }
1744
+ },
1745
+ async ({ workflowKey }) => runTool(ctx, "workflows_versions", async () => {
1746
+ const data = await ctx.gql.workspace.request(
1747
+ GET_WORKFLOW_VERSIONS,
1748
+ { workflowKey }
1749
+ );
1750
+ return jsonResult(data.workflowVersions);
1751
+ })
1752
+ );
1753
+ server.registerTool(
1754
+ track(mcpToolName(ctx.productName, "workflows_create")),
1755
+ {
1756
+ title: "Create Workflow",
1757
+ description: "Create a workflow definition. definitionJson is the node/edge graph; workflowKey plus version identify it.",
1758
+ inputSchema: {
1759
+ workflowKey: zod.z.string().describe("Stable key identifying the workflow"),
1760
+ name: zod.z.string().describe("Human-readable name"),
1761
+ version: zod.z.string().describe('Version string, e.g. "1.0.0"'),
1762
+ definitionJson: zod.z.unknown().describe("Workflow graph (nodes + edges) as JSON"),
1763
+ description: zod.z.string().optional().describe("Description"),
1764
+ category: zod.z.string().optional().describe("Category"),
1765
+ icon: zod.z.string().optional().describe("Icon identifier"),
1766
+ alias: zod.z.string().optional().describe("Alias"),
1767
+ projectId: zod.z.string().optional().describe("Owning project ID"),
1768
+ context: zod.z.unknown().optional().describe("Context JSON"),
1769
+ tags: zod.z.array(zod.z.string()).optional().describe("Tags")
1770
+ }
1771
+ },
1772
+ async (args) => runTool(ctx, "workflows_create", async () => {
1773
+ const data = await ctx.gql.workspace.request(
1774
+ CREATE_WORKFLOW,
1775
+ { input: definedInput({ ...args }) }
1776
+ );
1777
+ return jsonResult(data.createWorkflowDefinition);
1778
+ })
1779
+ );
1780
+ server.registerTool(
1781
+ track(mcpToolName(ctx.productName, "workflows_update")),
1782
+ {
1783
+ title: "Update Workflow",
1784
+ description: "Update a workflow definition by id. Saving a change to a published workflow forks a new version rather than mutating the active one.",
1785
+ inputSchema: {
1786
+ id: zod.z.string().describe("Workflow definition ID"),
1787
+ name: zod.z.string().optional().describe("Name"),
1788
+ description: zod.z.string().optional().describe("Description"),
1789
+ definitionJson: zod.z.unknown().optional().describe("Workflow graph as JSON"),
1790
+ category: zod.z.string().optional().describe("Category"),
1791
+ icon: zod.z.string().optional().describe("Icon identifier"),
1792
+ alias: zod.z.string().optional().describe("Alias"),
1793
+ context: zod.z.unknown().optional().describe("Context JSON"),
1794
+ tags: zod.z.array(zod.z.string()).optional().describe("Tags"),
1795
+ version: zod.z.string().optional().describe("Version")
1796
+ }
1797
+ },
1798
+ async ({ id, ...input }) => runTool(ctx, "workflows_update", async () => {
1799
+ const data = await ctx.gql.workspace.request(
1800
+ UPDATE_WORKFLOW,
1801
+ { id, input: definedInput(input) }
1802
+ );
1803
+ return jsonResult(data.updateWorkflowDefinition);
1804
+ })
1805
+ );
1806
+ server.registerTool(
1807
+ track(mcpToolName(ctx.productName, "workflows_delete")),
1808
+ {
1809
+ title: "Delete Workflow",
1810
+ description: "Delete a workflow by key. Without a version every version of that key is deleted.",
1811
+ annotations: { destructiveHint: true },
1812
+ inputSchema: {
1813
+ workflowKey: zod.z.string().describe("Workflow key"),
1814
+ version: zod.z.string().optional().describe("Delete only this version")
1815
+ }
1816
+ },
1817
+ async ({ workflowKey, version }) => runTool(ctx, "workflows_delete", async () => {
1818
+ const data = await ctx.gql.workspace.request(
1819
+ DELETE_WORKFLOW,
1820
+ { workflowKey, version }
1821
+ );
1822
+ return jsonResult(data.deleteWorkflowDefinition);
1823
+ })
1824
+ );
1825
+ server.registerTool(
1826
+ track(mcpToolName(ctx.productName, "workflows_trigger")),
1827
+ {
1828
+ title: "Trigger Workflow",
1829
+ description: "Start a workflow run. triggerNodeId names the trigger node to start from; stopAtNodeId runs only up to a node (step debugging).",
1830
+ inputSchema: {
1831
+ workflowKey: zod.z.string().describe("Workflow key"),
1832
+ version: zod.z.string().describe("Workflow version"),
1833
+ triggerNodeId: zod.z.string().describe("ID of the trigger node to start from"),
1834
+ triggerData: zod.z.unknown().optional().describe("Payload passed to the trigger node"),
1835
+ context: zod.z.unknown().optional().describe("Run context JSON"),
1836
+ stopAtNodeId: zod.z.string().optional().describe("Stop after this node and mark the run COMPLETED")
1837
+ }
1838
+ },
1839
+ async (args) => runTool(ctx, "workflows_trigger", async () => {
1840
+ const data = await ctx.gql.workspace.request(
1841
+ TRIGGER_WORKFLOW,
1842
+ { input: definedInput({ ...args }) }
1843
+ );
1844
+ return jsonResult(data.triggerWorkflow);
1845
+ })
1846
+ );
1847
+ server.registerTool(
1848
+ track(mcpToolName(ctx.productName, "workflows_publish")),
1849
+ {
1850
+ title: "Publish Workflow",
1851
+ description: "Publish a workflow definition, making that version the executable one.",
1852
+ inputSchema: { id: zod.z.string().describe("Workflow definition ID") }
1853
+ },
1854
+ async ({ id }) => runTool(ctx, "workflows_publish", async () => {
1855
+ const data = await ctx.gql.workspace.request(
1856
+ PUBLISH_WORKFLOW,
1857
+ { id }
1858
+ );
1859
+ return jsonResult(data.publishWorkflow);
1860
+ })
1861
+ );
1862
+ server.registerTool(
1863
+ track(mcpToolName(ctx.productName, "workflows_activate")),
1864
+ {
1865
+ title: "Activate Workflow",
1866
+ description: "Activate a workflow definition. Exactly one version per workflowKey may be ACTIVE.",
1867
+ inputSchema: { id: zod.z.string().describe("Workflow definition ID") }
1868
+ },
1869
+ async ({ id }) => runTool(ctx, "workflows_activate", async () => {
1870
+ const data = await ctx.gql.workspace.request(
1871
+ ACTIVATE_WORKFLOW,
1872
+ { id }
1873
+ );
1874
+ return jsonResult(data.activateWorkflowDefinition);
1875
+ })
1876
+ );
1877
+ server.registerTool(
1878
+ track(mcpToolName(ctx.productName, "workflows_deactivate")),
1879
+ {
1880
+ title: "Deactivate Workflow",
1881
+ description: "Deactivate a workflow definition so no version of the key is executable.",
1882
+ inputSchema: { id: zod.z.string().describe("Workflow definition ID") }
1883
+ },
1884
+ async ({ id }) => runTool(ctx, "workflows_deactivate", async () => {
1885
+ const data = await ctx.gql.workspace.request(
1886
+ DEACTIVATE_WORKFLOW,
1887
+ { id }
1888
+ );
1889
+ return jsonResult(data.deactivateWorkflowDefinition);
1890
+ })
1891
+ );
1892
+ server.registerTool(
1893
+ track(mcpToolName(ctx.productName, "workflows_duplicate")),
1894
+ {
1895
+ title: "Duplicate Workflow",
1896
+ description: "Copy an existing workflow version to a new workflowKey.",
1897
+ inputSchema: {
1898
+ workflowKey: zod.z.string().describe("Source workflow key"),
1899
+ version: zod.z.string().describe("Source version"),
1900
+ newWorkflowKey: zod.z.string().describe("Key for the copy"),
1901
+ newVersion: zod.z.string().optional().describe("Version for the copy")
1902
+ }
1903
+ },
1904
+ async ({ workflowKey, version, newWorkflowKey, newVersion }) => runTool(ctx, "workflows_duplicate", async () => {
1905
+ const data = await ctx.gql.workspace.request(
1906
+ DUPLICATE_WORKFLOW,
1907
+ { workflowKey, version, input: definedInput({ newWorkflowKey, newVersion }) }
1908
+ );
1909
+ return jsonResult(data.duplicateWorkflow);
1910
+ })
1911
+ );
1912
+ server.registerTool(
1913
+ track(mcpToolName(ctx.productName, "workflows_archive")),
1914
+ {
1915
+ title: "Archive Workflow",
1916
+ description: "Archive a workflow definition. Reversible: archived workflows still list.",
1917
+ annotations: { destructiveHint: true },
1918
+ inputSchema: { id: zod.z.string().describe("Workflow definition ID") }
1919
+ },
1920
+ async ({ id }) => runTool(ctx, "workflows_archive", async () => {
1921
+ const data = await ctx.gql.workspace.request(
1922
+ ARCHIVE_WORKFLOW,
1923
+ { id }
1924
+ );
1925
+ return jsonResult(data.archiveWorkflow);
1926
+ })
1927
+ );
1928
+ }
1929
+ function registerFluidgridsPrompts(server, ctx, track) {
1930
+ const p = ctx.productName;
1931
+ const buildName = track(mcpPromptName(p, "build-workflow"));
1932
+ const debugName = track(mcpPromptName(p, "debug-run"));
1933
+ server.registerPrompt(
1934
+ buildName,
1935
+ {
1936
+ title: "Build a Workflow",
1937
+ description: "Guide for authoring a FluidGrids workflow end to end: pick nodes, create the definition, publish a version, then trigger it and confirm the run completes.",
1938
+ argsSchema: {
1939
+ goal: zod.z.string().optional().describe("What the workflow should do"),
1940
+ workflowKey: zod.z.string().optional().describe("Workflow key to use")
1941
+ }
1942
+ },
1943
+ ({ goal, workflowKey }) => {
1944
+ ctx.logger.debug(`Prompt ${buildName} called`, { goal, workflowKey });
1945
+ const goalNote = goal ? `The workflow should: ${goal}` : "Ask the user what the workflow should do before building anything.";
1946
+ const keyNote = workflowKey ? `Use the workflowKey "${workflowKey}".` : "Choose a stable, descriptive workflowKey and confirm it with the user.";
1947
+ return {
1948
+ messages: [
1949
+ {
1950
+ role: "user",
1951
+ content: {
1952
+ type: "text",
1953
+ text: `Build a FluidGrids workflow.
1954
+
1955
+ ${goalNote}
1956
+ ${keyNote}
1957
+
1958
+ Follow this order and stop if a step fails:
1959
+
1960
+ 1. \`${p}_nodes_list\` \u2014 find the node types you need. Use \`${p}_nodes_get\` to read a
1961
+ node's input fields before wiring it; do not guess field names.
1962
+ 2. \`${p}_workflows_create\` \u2014 build \`definitionJson\` as a graph of nodes and edges.
1963
+ Exactly one trigger node. Note its node id: triggering needs it.
1964
+ 3. \`${p}_workflows_publish\` then \`${p}_workflows_activate\` \u2014 only an active version
1965
+ is executable, and only one version per key may be ACTIVE.
1966
+ 4. \`${p}_workflows_trigger\` \u2014 pass \`triggerNodeId\` and any \`triggerData\`.
1967
+ 5. \`${p}_runs_get\` \u2014 poll until status is terminal (COMPLETED, FAILED, CANCELLED or
1968
+ TERMINATED). Statuses are UPPERCASE.
1969
+ 6. If it did not complete, run \`${p}_debug-run\` on the run id.
1970
+
1971
+ If the workflow needs credentials, create them with \`${p}_credentials_create\` and
1972
+ verify with \`${p}_credentials_test\` BEFORE triggering \u2014 a missing connection fails
1973
+ the run at the node, not at save time.`
1974
+ }
1975
+ }
1976
+ ]
1977
+ };
1978
+ }
1979
+ );
1980
+ server.registerPrompt(
1981
+ debugName,
1982
+ {
1983
+ title: "Debug a Run",
1984
+ description: "Guide for diagnosing a FluidGrids run that failed or stalled: read node state, read the log, then retry the failing node or fix the definition.",
1985
+ argsSchema: { runId: zod.z.string().optional().describe("Run ID to diagnose") }
1986
+ },
1987
+ ({ runId }) => {
1988
+ ctx.logger.debug(`Prompt ${debugName} called`, { runId });
1989
+ const runNote = runId ? `Diagnose run "${runId}".` : `Ask for the run id, or find it with \`${p}_runs_list\` filtered to status FAILED.`;
1990
+ return {
1991
+ messages: [
1992
+ {
1993
+ role: "user",
1994
+ content: {
1995
+ type: "text",
1996
+ text: `Diagnose a FluidGrids run.
1997
+
1998
+ ${runNote}
1999
+
2000
+ 1. \`${p}_runs_get\` \u2014 read the run and its per-node state. Identify the FIRST node that
2001
+ did not succeed; later failures are usually consequences of it.
2002
+ 2. \`${p}_runs_logs\` \u2014 read that node's log with \`nodeId\` set, \`minLevel\` ERROR first,
2003
+ then widen to WARN/INFO if the error alone is not conclusive.
2004
+ 3. Classify before acting:
2005
+ - credential/auth error -> \`${p}_credentials_test\` the connection the node uses
2006
+ - bad input -> compare against \`${p}_nodes_get\` input fields for that node type
2007
+ - transient/upstream -> \`${p}_runs_retry_node\` is appropriate
2008
+ - wrong graph -> fix \`definitionJson\` via \`${p}_workflows_update\` (this forks a new
2009
+ version), then publish, activate and trigger again
2010
+ 4. Only retry once you know which class it is. Retrying a bad definition just
2011
+ reproduces the failure.
2012
+
2013
+ A run stuck in WAITING is not failed \u2014 it is blocked on a Wait node. Resume it with
2014
+ \`${p}_runs_resume\` and the payload it expects.`
2015
+ }
2016
+ }
2017
+ ]
2018
+ };
2019
+ }
2020
+ );
2021
+ }
2022
+
2023
+ // src/modules/fluidgrids/resources.ts
2024
+ function registerFluidgridsResources(server, ctx, track) {
2025
+ const schemaUri = track(mcpResourceUri(ctx.productName, "schema"));
2026
+ const nodesUri = track(mcpResourceUri(ctx.productName, "nodes"));
2027
+ server.registerResource(
2028
+ "fluidgrids-schema",
2029
+ schemaUri,
2030
+ {
2031
+ title: "FluidGrids Domain Schema",
2032
+ description: "Overview of the FluidGrids workflow-automation domain \u2014 entities, enums, and the per-entity tool surface.",
2033
+ mimeType: "text/plain"
2034
+ },
2035
+ async () => {
2036
+ ctx.logger.debug(`Resource ${schemaUri} requested`);
2037
+ const schema = `# FluidGrids Domain (Overview)
2038
+
2039
+ Visual workflow automation. A workflow is a graph of nodes; running one produces a run.
2040
+
2041
+ ## Core entities
2042
+ - WorkflowDefinition \u2014 identified by (workflowKey, version). Many versions per key;
2043
+ at most ONE is ACTIVE. Saving over a published version forks a new version.
2044
+ - WorkflowRun \u2014 one execution. Has per-node state and a log stream.
2045
+ - NodeEndpointConfig \u2014 an available node type at a version (BUILTIN | CUSTOM | STORE).
2046
+ - Connection \u2014 a stored credential against a Provider. Secrets live in the vault.
2047
+ - EventRegistration \u2014 an event source (webhook) that triggers a workflow.
2048
+ - ScheduledJob \u2014 a cron/interval schedule that triggers a workflow.
2049
+
2050
+ ## Enums
2051
+ - WorkflowStatus: ACTIVE | ARCHIVED | DEPRECATED | DRAFT
2052
+ - RunStatus: PENDING | RUNNING | WAITING | COMPLETED | FAILED | CANCELLED | TERMINATED
2053
+ (UPPERCASE on the wire \u2014 comparing lowercase is a known source of hangs)
2054
+ - RunLogLevel: DEBUG | INFO | WARN | ERROR
2055
+ - PublishType: BUILTIN | CUSTOM | STORE
2056
+ - NodeConfigStatus: AVAILABLE | DEPRECATED | DISABLED
2057
+ - EventStatus: ACTIVE | PAUSED | DISABLED | ARCHIVED
2058
+
2059
+ ## Typical sequence
2060
+ 1. ${ctx.productName}_nodes_list \u2014 see what nodes exist
2061
+ 2. ${ctx.productName}_workflows_create \u2014 create a definition with a definitionJson graph
2062
+ 3. ${ctx.productName}_workflows_publish / _activate \u2014 make a version executable
2063
+ 4. ${ctx.productName}_workflows_trigger \u2014 start a run
2064
+ 5. ${ctx.productName}_runs_get / _runs_logs \u2014 follow it to a terminal status
2065
+
2066
+ ## Tier
2067
+ Every tool here is workspace tier and needs a workspace context. Sign in and
2068
+ select a workspace with the auth tools first.
2069
+ `;
2070
+ return { contents: [{ uri: schemaUri, mimeType: "text/plain", text: schema }] };
2071
+ }
2072
+ );
2073
+ server.registerResource(
2074
+ "fluidgrids-nodes",
2075
+ nodesUri,
2076
+ {
2077
+ title: "FluidGrids Node Catalogue",
2078
+ description: "The node types currently available to build workflows with, read live from the node endpoint config registry.",
2079
+ mimeType: "application/json"
2080
+ },
2081
+ async () => {
2082
+ ctx.logger.debug(`Resource ${nodesUri} requested`);
2083
+ try {
2084
+ const data = await ctx.gql.workspace.request(LIST_NODES, {
2085
+ status: "AVAILABLE"
2086
+ });
2087
+ return {
2088
+ contents: [
2089
+ {
2090
+ uri: nodesUri,
2091
+ mimeType: "application/json",
2092
+ text: JSON.stringify(data.nodeEndpointConfigs, null, 2)
2093
+ }
2094
+ ]
2095
+ };
2096
+ } catch (error) {
2097
+ const message = safeErrorMessage(error);
2098
+ ctx.logger.error("fluidgrids nodes resource failed", { error: message });
2099
+ return {
2100
+ contents: [
2101
+ {
2102
+ uri: nodesUri,
2103
+ mimeType: "application/json",
2104
+ text: JSON.stringify(
2105
+ {
2106
+ error: message,
2107
+ hint: "Sign in and select a workspace first \u2014 the node registry is workspace-scoped."
2108
+ },
2109
+ null,
2110
+ 2
2111
+ )
2112
+ }
2113
+ ]
2114
+ };
2115
+ }
2116
+ }
2117
+ );
2118
+ }
2119
+
2120
+ // src/modules/fluidgrids/index.ts
2121
+ var fluidgridsModule = {
2122
+ id: "fluidgrids",
2123
+ version: "0.0.1",
2124
+ displayName: "FluidGrids",
2125
+ capabilities: { tools: {}, resources: {}, prompts: {} },
2126
+ register(server, ctx) {
2127
+ const tools = [];
2128
+ const resources = [];
2129
+ const prompts = [];
2130
+ const trackTool = (n) => {
2131
+ tools.push(n);
2132
+ return n;
2133
+ };
2134
+ const trackResource = (uri) => {
2135
+ resources.push(uri);
2136
+ return uri;
2137
+ };
2138
+ const trackPrompt = (n) => {
2139
+ prompts.push(n);
2140
+ return n;
2141
+ };
2142
+ registerWorkflowTools(server, ctx, trackTool);
2143
+ registerRunTools(server, ctx, trackTool);
2144
+ registerNodeTools(server, ctx, trackTool);
2145
+ registerCredentialTools(server, ctx, trackTool);
2146
+ registerWebhookTools(server, ctx, trackTool);
2147
+ registerScheduledJobTools(server, ctx, trackTool);
2148
+ registerInsightTools(server, ctx, trackTool);
2149
+ registerFluidgridsResources(server, ctx, trackResource);
2150
+ registerFluidgridsPrompts(server, ctx, trackPrompt);
2151
+ return { tools, resources, prompts };
2152
+ }
2153
+ };
2154
+ var fluidgrids_default = fluidgridsModule;
2155
+
2156
+ module.exports = fluidgrids_default;
2157
+ //# sourceMappingURL=index.cjs.map
2158
+ //# sourceMappingURL=index.cjs.map