@burdenoff/mcp-libs 2026.628.1 → 2026.629.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/modules/adaptercloud/index.cjs +1841 -0
  2. package/dist/modules/adaptercloud/index.cjs.map +1 -0
  3. package/dist/modules/adaptercloud/index.d.cts +8 -0
  4. package/dist/modules/adaptercloud/index.d.ts +8 -0
  5. package/dist/modules/adaptercloud/index.js +1780 -0
  6. package/dist/modules/adaptercloud/index.js.map +1 -0
  7. package/dist/modules/atheletebridge/index.cjs +1707 -0
  8. package/dist/modules/atheletebridge/index.cjs.map +1 -0
  9. package/dist/modules/atheletebridge/index.d.cts +8 -0
  10. package/dist/modules/atheletebridge/index.d.ts +8 -0
  11. package/dist/modules/atheletebridge/index.js +1646 -0
  12. package/dist/modules/atheletebridge/index.js.map +1 -0
  13. package/dist/modules/coolandlovely/index.cjs +1935 -0
  14. package/dist/modules/coolandlovely/index.cjs.map +1 -0
  15. package/dist/modules/coolandlovely/index.d.cts +8 -0
  16. package/dist/modules/coolandlovely/index.d.ts +8 -0
  17. package/dist/modules/coolandlovely/index.js +1874 -0
  18. package/dist/modules/coolandlovely/index.js.map +1 -0
  19. package/dist/modules/hookmovies/index.cjs +2024 -0
  20. package/dist/modules/hookmovies/index.cjs.map +1 -0
  21. package/dist/modules/hookmovies/index.d.cts +8 -0
  22. package/dist/modules/hookmovies/index.d.ts +8 -0
  23. package/dist/modules/hookmovies/index.js +1963 -0
  24. package/dist/modules/hookmovies/index.js.map +1 -0
  25. package/dist/modules/labsofscience/index.cjs +2039 -0
  26. package/dist/modules/labsofscience/index.cjs.map +1 -0
  27. package/dist/modules/labsofscience/index.d.cts +8 -0
  28. package/dist/modules/labsofscience/index.d.ts +8 -0
  29. package/dist/modules/labsofscience/index.js +1978 -0
  30. package/dist/modules/labsofscience/index.js.map +1 -0
  31. package/dist/modules/subscriberbot/index.cjs +2037 -0
  32. package/dist/modules/subscriberbot/index.cjs.map +1 -0
  33. package/dist/modules/subscriberbot/index.d.cts +8 -0
  34. package/dist/modules/subscriberbot/index.d.ts +8 -0
  35. package/dist/modules/subscriberbot/index.js +1976 -0
  36. package/dist/modules/subscriberbot/index.js.map +1 -0
  37. package/package.json +1 -1
@@ -0,0 +1,1841 @@
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/adaptercloud/tools/adapters.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/result.ts
22
+ function jsonResult(data, structured) {
23
+ const result = {
24
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
25
+ };
26
+ return result;
27
+ }
28
+ function errorResult(message, hint) {
29
+ const text = hint ? `${message}
30
+
31
+ Hint: ${hint}` : message;
32
+ return { content: [{ type: "text", text }], isError: true };
33
+ }
34
+
35
+ // src/core/tool-name.ts
36
+ var MAX_TOOL_NAME_LENGTH = 63;
37
+ function assertSafeName(name, kind) {
38
+ if (name.length > MAX_TOOL_NAME_LENGTH) {
39
+ throw new McpInternalError(
40
+ `Tool name '${name}' exceeds ${MAX_TOOL_NAME_LENGTH} characters (some MCP clients truncate at 64).`
41
+ );
42
+ }
43
+ return name;
44
+ }
45
+ function mcpToolName(productName, ...parts) {
46
+ if (!productName) {
47
+ throw new McpInternalError("mcpToolName: productName is required");
48
+ }
49
+ const name = [productName, ...parts].filter(Boolean).join("_");
50
+ return assertSafeName(name);
51
+ }
52
+ function mcpResourceUri(productName, ...parts) {
53
+ if (!productName) {
54
+ throw new McpInternalError("mcpResourceUri: productName is required");
55
+ }
56
+ return `${productName}://${parts.filter(Boolean).join("/")}`;
57
+ }
58
+ function mcpPromptName(productName, ...parts) {
59
+ if (!productName) {
60
+ throw new McpInternalError("mcpPromptName: productName is required");
61
+ }
62
+ return [productName, ...parts].filter(Boolean).join("-");
63
+ }
64
+
65
+ // src/modules/adaptercloud/operations.ts
66
+ var PAGE_INFO_FIELDS = `
67
+ pageInfo { cursor hasMore }
68
+ `;
69
+ var ADAPTER_FIELDS = `
70
+ id name slug description kind status vendor version capabilities configSchema
71
+ tags workspaceId createdAt updatedAt
72
+ `;
73
+ var CONNECTION_FIELDS = `
74
+ id name adapterId authMethod status environment region config secretRef
75
+ targetRef resourceCount lastSyncedAt lastError tags workspaceId
76
+ createdAt updatedAt
77
+ `;
78
+ var RESOURCE_FIELDS = `
79
+ id connectionId externalId name resourceType region state monthlyCost
80
+ attributes providerTags tags lastSeenAt workspaceId createdAt updatedAt
81
+ `;
82
+ var TOPOLOGY_EDGE_FIELDS = `
83
+ id fromResourceId toResourceId kind weight bidirectional attributes
84
+ workspaceId createdAt updatedAt
85
+ `;
86
+ var POLICY_FIELDS = `
87
+ id name description kind enforcement severity expression appliesTo isActive
88
+ tags workspaceId createdAt updatedAt
89
+ `;
90
+ var VIOLATION_FIELDS = `
91
+ id policyId resourceId severity status message evidence detectedAt
92
+ resolvedAt resolvedById waiverReason workspaceId createdAt updatedAt
93
+ `;
94
+ var DRIFT_FIELDS = `
95
+ id resourceId attributePath expectedValue observedValue severity status
96
+ detectedAt remediatedAt workspaceId createdAt updatedAt
97
+ `;
98
+ var SYNC_RUN_FIELDS = `
99
+ id connectionId kind status startedAt finishedAt discoveredCount
100
+ reconciledCount driftCount violationCount summary error workspaceId
101
+ createdAt updatedAt
102
+ `;
103
+ var COST_RECORD_FIELDS = `
104
+ id connectionId resourceId service amount currency periodStart periodEnd
105
+ breakdown workspaceId createdAt updatedAt
106
+ `;
107
+ var GET_ADAPTER = `
108
+ query AdaGetAdapter($id: ID!) {
109
+ adaAdapter(id: $id) {
110
+ ${ADAPTER_FIELDS}
111
+ connections { id name status environment resourceCount }
112
+ }
113
+ }
114
+ `;
115
+ var LIST_ADAPTERS = `
116
+ query AdaListAdapters(
117
+ $kind: AdaAdapterKind
118
+ $status: AdaAdapterStatus
119
+ $pagination: PaginationInput
120
+ ) {
121
+ adaListAdapters(kind: $kind, status: $status, pagination: $pagination) {
122
+ items { ${ADAPTER_FIELDS} }
123
+ ${PAGE_INFO_FIELDS}
124
+ }
125
+ }
126
+ `;
127
+ var CREATE_ADAPTER = `
128
+ mutation AdaCreateAdapter($input: AdaCreateAdapterInput!) {
129
+ adaCreateAdapter(input: $input) {
130
+ ${ADAPTER_FIELDS}
131
+ }
132
+ }
133
+ `;
134
+ var UPDATE_ADAPTER = `
135
+ mutation AdaUpdateAdapter($id: ID!, $input: AdaUpdateAdapterInput!) {
136
+ adaUpdateAdapter(id: $id, input: $input) {
137
+ ${ADAPTER_FIELDS}
138
+ }
139
+ }
140
+ `;
141
+ var ARCHIVE_ADAPTER = `
142
+ mutation AdaArchiveAdapter($id: ID!) {
143
+ adaArchiveAdapter(id: $id)
144
+ }
145
+ `;
146
+ var GET_CONNECTION = `
147
+ query AdaGetConnection($id: ID!) {
148
+ adaConnection(id: $id) {
149
+ ${CONNECTION_FIELDS}
150
+ adapter { id name slug kind status }
151
+ resources { id name resourceType state monthlyCost }
152
+ }
153
+ }
154
+ `;
155
+ var LIST_CONNECTIONS = `
156
+ query AdaListConnections(
157
+ $adapterId: ID
158
+ $status: AdaConnectionStatus
159
+ $pagination: PaginationInput
160
+ ) {
161
+ adaListConnections(adapterId: $adapterId, status: $status, pagination: $pagination) {
162
+ items { ${CONNECTION_FIELDS} }
163
+ ${PAGE_INFO_FIELDS}
164
+ }
165
+ }
166
+ `;
167
+ var CREATE_CONNECTION = `
168
+ mutation AdaCreateConnection($input: AdaCreateConnectionInput!) {
169
+ adaCreateConnection(input: $input) {
170
+ ${CONNECTION_FIELDS}
171
+ }
172
+ }
173
+ `;
174
+ var UPDATE_CONNECTION = `
175
+ mutation AdaUpdateConnection($id: ID!, $input: AdaUpdateConnectionInput!) {
176
+ adaUpdateConnection(id: $id, input: $input) {
177
+ ${CONNECTION_FIELDS}
178
+ }
179
+ }
180
+ `;
181
+ var DISABLE_CONNECTION = `
182
+ mutation AdaDisableConnection($id: ID!) {
183
+ adaDisableConnection(id: $id) {
184
+ ${CONNECTION_FIELDS}
185
+ }
186
+ }
187
+ `;
188
+ var SET_CONNECTION_STATUS = `
189
+ mutation AdaSetConnectionStatus($id: ID!, $status: AdaConnectionStatus!) {
190
+ adaSetConnectionStatus(id: $id, status: $status) {
191
+ ${CONNECTION_FIELDS}
192
+ }
193
+ }
194
+ `;
195
+ var GET_RESOURCE = `
196
+ query AdaGetResource($id: ID!) {
197
+ adaResource(id: $id) {
198
+ ${RESOURCE_FIELDS}
199
+ connection { id name status }
200
+ dependsOn { id name resourceType state }
201
+ }
202
+ }
203
+ `;
204
+ var LIST_RESOURCES = `
205
+ query AdaListResources(
206
+ $connectionId: ID
207
+ $resourceType: String
208
+ $state: AdaResourceState
209
+ $pagination: PaginationInput
210
+ ) {
211
+ adaListResources(
212
+ connectionId: $connectionId
213
+ resourceType: $resourceType
214
+ state: $state
215
+ pagination: $pagination
216
+ ) {
217
+ items { ${RESOURCE_FIELDS} }
218
+ ${PAGE_INFO_FIELDS}
219
+ }
220
+ }
221
+ `;
222
+ var REGISTER_RESOURCE = `
223
+ mutation AdaRegisterResource($input: AdaRegisterResourceInput!) {
224
+ adaRegisterResource(input: $input) {
225
+ ${RESOURCE_FIELDS}
226
+ }
227
+ }
228
+ `;
229
+ var LIST_TOPOLOGY_EDGES = `
230
+ query AdaListTopologyEdges($kind: AdaEdgeKind, $resourceId: ID) {
231
+ adaListTopologyEdges(kind: $kind, resourceId: $resourceId) {
232
+ ${TOPOLOGY_EDGE_FIELDS}
233
+ }
234
+ }
235
+ `;
236
+ var CREATE_TOPOLOGY_EDGE = `
237
+ mutation AdaCreateTopologyEdge($input: AdaCreateTopologyEdgeInput!) {
238
+ adaCreateTopologyEdge(input: $input) {
239
+ ${TOPOLOGY_EDGE_FIELDS}
240
+ }
241
+ }
242
+ `;
243
+ var GET_POLICY = `
244
+ query AdaGetPolicy($id: ID!) {
245
+ adaPolicy(id: $id) {
246
+ ${POLICY_FIELDS}
247
+ violations { id resourceId severity status message }
248
+ }
249
+ }
250
+ `;
251
+ var LIST_POLICIES = `
252
+ query AdaListPolicies(
253
+ $kind: AdaPolicyKind
254
+ $isActive: Boolean
255
+ $pagination: PaginationInput
256
+ ) {
257
+ adaListPolicies(kind: $kind, isActive: $isActive, pagination: $pagination) {
258
+ items { ${POLICY_FIELDS} }
259
+ ${PAGE_INFO_FIELDS}
260
+ }
261
+ }
262
+ `;
263
+ var CREATE_POLICY = `
264
+ mutation AdaCreatePolicy($input: AdaCreatePolicyInput!) {
265
+ adaCreatePolicy(input: $input) {
266
+ ${POLICY_FIELDS}
267
+ }
268
+ }
269
+ `;
270
+ var UPDATE_POLICY = `
271
+ mutation AdaUpdatePolicy($id: ID!, $input: AdaUpdatePolicyInput!) {
272
+ adaUpdatePolicy(id: $id, input: $input) {
273
+ ${POLICY_FIELDS}
274
+ }
275
+ }
276
+ `;
277
+ var ARCHIVE_POLICY = `
278
+ mutation AdaArchivePolicy($id: ID!) {
279
+ adaArchivePolicy(id: $id)
280
+ }
281
+ `;
282
+ var LIST_VIOLATIONS = `
283
+ query AdaListViolations(
284
+ $policyId: ID
285
+ $resourceId: ID
286
+ $status: AdaViolationStatus
287
+ $pagination: PaginationInput
288
+ ) {
289
+ adaListViolations(
290
+ policyId: $policyId
291
+ resourceId: $resourceId
292
+ status: $status
293
+ pagination: $pagination
294
+ ) {
295
+ items { ${VIOLATION_FIELDS} }
296
+ ${PAGE_INFO_FIELDS}
297
+ }
298
+ }
299
+ `;
300
+ var RECORD_VIOLATION = `
301
+ mutation AdaRecordViolation($input: AdaRecordViolationInput!) {
302
+ adaRecordViolation(input: $input) {
303
+ ${VIOLATION_FIELDS}
304
+ }
305
+ }
306
+ `;
307
+ var RESOLVE_VIOLATION = `
308
+ mutation AdaResolveViolation(
309
+ $id: ID!
310
+ $status: AdaViolationStatus!
311
+ $waiverReason: String
312
+ ) {
313
+ adaResolveViolation(id: $id, status: $status, waiverReason: $waiverReason) {
314
+ ${VIOLATION_FIELDS}
315
+ }
316
+ }
317
+ `;
318
+ var LIST_DRIFT_RECORDS = `
319
+ query AdaListDriftRecords($resourceId: ID, $status: AdaDriftStatus) {
320
+ adaListDriftRecords(resourceId: $resourceId, status: $status) {
321
+ ${DRIFT_FIELDS}
322
+ }
323
+ }
324
+ `;
325
+ var RECORD_DRIFT = `
326
+ mutation AdaRecordDrift($input: AdaRecordDriftInput!) {
327
+ adaRecordDrift(input: $input) {
328
+ ${DRIFT_FIELDS}
329
+ }
330
+ }
331
+ `;
332
+ var REMEDIATE_DRIFT = `
333
+ mutation AdaRemediateDrift($id: ID!) {
334
+ adaRemediateDrift(id: $id) {
335
+ ${DRIFT_FIELDS}
336
+ }
337
+ }
338
+ `;
339
+ var GET_SYNC_RUN = `
340
+ query AdaGetSyncRun($id: ID!) {
341
+ adaSyncRun(id: $id) {
342
+ ${SYNC_RUN_FIELDS}
343
+ }
344
+ }
345
+ `;
346
+ var LIST_SYNC_RUNS = `
347
+ query AdaListSyncRuns(
348
+ $connectionId: ID
349
+ $status: AdaSyncStatus
350
+ $pagination: PaginationInput
351
+ ) {
352
+ adaListSyncRuns(connectionId: $connectionId, status: $status, pagination: $pagination) {
353
+ items { ${SYNC_RUN_FIELDS} }
354
+ ${PAGE_INFO_FIELDS}
355
+ }
356
+ }
357
+ `;
358
+ var START_SYNC_RUN = `
359
+ mutation AdaStartSyncRun($input: AdaStartSyncRunInput!) {
360
+ adaStartSyncRun(input: $input) {
361
+ ${SYNC_RUN_FIELDS}
362
+ }
363
+ }
364
+ `;
365
+ var COMPLETE_SYNC_RUN = `
366
+ mutation AdaCompleteSyncRun($id: ID!, $input: AdaCompleteSyncRunInput) {
367
+ adaCompleteSyncRun(id: $id, input: $input) {
368
+ ${SYNC_RUN_FIELDS}
369
+ }
370
+ }
371
+ `;
372
+ var FAIL_SYNC_RUN = `
373
+ mutation AdaFailSyncRun($id: ID!, $error: String!) {
374
+ adaFailSyncRun(id: $id, error: $error) {
375
+ ${SYNC_RUN_FIELDS}
376
+ }
377
+ }
378
+ `;
379
+ var CANCEL_SYNC_RUN = `
380
+ mutation AdaCancelSyncRun($id: ID!) {
381
+ adaCancelSyncRun(id: $id) {
382
+ ${SYNC_RUN_FIELDS}
383
+ }
384
+ }
385
+ `;
386
+ var LIST_COST_RECORDS = `
387
+ query AdaListCostRecords($connectionId: ID, $resourceId: ID, $service: String) {
388
+ adaListCostRecords(connectionId: $connectionId, resourceId: $resourceId, service: $service) {
389
+ ${COST_RECORD_FIELDS}
390
+ }
391
+ }
392
+ `;
393
+ var COST_SUMMARY = `
394
+ query AdaCostSummary($connectionId: ID) {
395
+ adaCostSummary(connectionId: $connectionId) {
396
+ currency
397
+ total
398
+ lines { service total }
399
+ }
400
+ }
401
+ `;
402
+ var INGEST_COST = `
403
+ mutation AdaIngestCost($input: AdaIngestCostInput!) {
404
+ adaIngestCost(input: $input) {
405
+ ${COST_RECORD_FIELDS}
406
+ }
407
+ }
408
+ `;
409
+ var HEALTH = `
410
+ query AdaHealth {
411
+ adaHealth
412
+ }
413
+ `;
414
+ var AdapterKindEnum = zod.z.enum([
415
+ "CUSTOM",
416
+ "DATA_SYSTEM",
417
+ "EDGE",
418
+ "KUBERNETES",
419
+ "NETWORK",
420
+ "ON_PREM",
421
+ "PRIVATE_CLOUD",
422
+ "PUBLIC_CLOUD",
423
+ "SAAS"
424
+ ]).describe("Class of infrastructure an adapter integrates");
425
+ var AdapterStatusEnum = zod.z.enum(["ARCHIVED", "DEPRECATED", "DRAFT", "PUBLISHED"]).describe("Lifecycle status of an adapter");
426
+ var AuthMethodEnum = zod.z.enum(["API_KEY", "CERTIFICATE", "IAM_ROLE", "NONE", "OAUTH2", "SERVICE_ACCOUNT"]).describe("Authentication method a connection uses against the target system");
427
+ var ConnectionStatusEnum = zod.z.enum(["CONNECTED", "DEGRADED", "DISABLED", "ERROR", "PENDING"]).describe("Health/lifecycle status of a connection");
428
+ var ResourceStateEnum = zod.z.enum(["DELETED", "DISCOVERED", "DRIFTED", "ORPHANED", "RECONCILED"]).describe("Reconciliation state of a discovered resource");
429
+ var EdgeKindEnum = zod.z.enum(["CONNECTS_TO", "CONTAINS", "DEPENDS_ON", "REPLICATES_TO", "ROUTES_TO"]).describe("Relationship kind of a topology edge between two resources");
430
+ var PolicyKindEnum = zod.z.enum(["COMPLIANCE", "COST", "GUARDRAIL", "NAMING", "SECURITY", "TAGGING"]).describe("Category of a governance policy");
431
+ var PolicyEnforcementEnum = zod.z.enum(["ADVISORY", "BLOCK", "WARN"]).describe("Enforcement mode of a governance policy");
432
+ var SeverityEnum = zod.z.enum(["CRITICAL", "HIGH", "INFO", "LOW", "MEDIUM"]).describe("Severity classification (policies, violations, drift)");
433
+ var ViolationStatusEnum = zod.z.enum(["ACKNOWLEDGED", "OPEN", "RESOLVED", "WAIVED"]).describe("Lifecycle status of a policy violation");
434
+ var DriftStatusEnum = zod.z.enum(["ACKNOWLEDGED", "DETECTED", "IGNORED", "REMEDIATED"]).describe("Lifecycle status of a drift record");
435
+ var SyncKindEnum = zod.z.enum(["COST_INGEST", "DISCOVERY", "FULL", "RECONCILE"]).describe("Kind of sync run against a connection");
436
+ var SyncStatusEnum = zod.z.enum(["CANCELLED", "FAILED", "QUEUED", "RUNNING", "SUCCEEDED"]).describe("Lifecycle status of a sync run");
437
+ var JsonObject = zod.z.record(zod.z.string(), zod.z.unknown());
438
+ var PaginationFields = {
439
+ limit: zod.z.number().int().optional().describe("Page size (PaginationInput.limit, default 50)"),
440
+ offset: zod.z.number().int().optional().describe("Pagination offset (PaginationInput.offset, default 0)"),
441
+ cursor: zod.z.string().optional().describe("Opaque cursor from a previous page (PaginationInput.cursor)")
442
+ };
443
+ function buildPagination(args) {
444
+ const pagination = {};
445
+ if (args.limit !== void 0) pagination.limit = args.limit;
446
+ if (args.offset !== void 0) pagination.offset = args.offset;
447
+ if (args.cursor !== void 0) pagination.cursor = args.cursor;
448
+ return Object.keys(pagination).length > 0 ? pagination : void 0;
449
+ }
450
+
451
+ // src/modules/adaptercloud/tools/adapters.ts
452
+ function registerAdapterTools(server, ctx, track) {
453
+ server.registerTool(
454
+ track(mcpToolName(ctx.productName, "adapters_get")),
455
+ {
456
+ title: "Get Adapter",
457
+ description: "Fetch a single AdapterCloud adapter (integration definition) by ID, including its connections.",
458
+ inputSchema: { id: zod.z.string().describe("Adapter ID") }
459
+ },
460
+ async ({ id }) => {
461
+ try {
462
+ const data = await ctx.gql.workspace.request(GET_ADAPTER, { id });
463
+ if (!data.adaAdapter) return errorResult(`Adapter ${id} not found`);
464
+ return jsonResult(data.adaAdapter);
465
+ } catch (error) {
466
+ ctx.logger.error("adaptercloud adapters_get failed", { error: String(error) });
467
+ return errorResult(
468
+ `Failed to get adapter: ${error instanceof Error ? error.message : String(error)}`
469
+ );
470
+ }
471
+ }
472
+ );
473
+ server.registerTool(
474
+ track(mcpToolName(ctx.productName, "adapters_list")),
475
+ {
476
+ title: "List Adapters",
477
+ description: "List adapters in the bound workspace with optional kind/status filters and pagination. Returns a page envelope { items, pageInfo }.",
478
+ inputSchema: {
479
+ kind: AdapterKindEnum.optional().describe("Filter by infrastructure kind"),
480
+ status: AdapterStatusEnum.optional().describe("Filter by lifecycle status"),
481
+ ...PaginationFields
482
+ }
483
+ },
484
+ async ({ kind, status, limit, offset, cursor }) => {
485
+ try {
486
+ const data = await ctx.gql.workspace.request(LIST_ADAPTERS, {
487
+ kind,
488
+ status,
489
+ pagination: buildPagination({ limit, offset, cursor })
490
+ });
491
+ return jsonResult(data.adaListAdapters);
492
+ } catch (error) {
493
+ ctx.logger.error("adaptercloud adapters_list failed", { error: String(error) });
494
+ return errorResult(
495
+ `Failed to list adapters: ${error instanceof Error ? error.message : String(error)}`
496
+ );
497
+ }
498
+ }
499
+ );
500
+ server.registerTool(
501
+ track(mcpToolName(ctx.productName, "adapters_create")),
502
+ {
503
+ title: "Create Adapter",
504
+ description: "Register a new adapter (integration definition). `slug` must be unique within the workspace. `configSchema` is an optional JSON Schema describing connection config.",
505
+ inputSchema: {
506
+ name: zod.z.string().min(1).describe("Adapter display name"),
507
+ slug: zod.z.string().min(1).describe("URL slug, unique within the workspace"),
508
+ kind: AdapterKindEnum.optional().describe("Infrastructure kind (default CUSTOM)"),
509
+ status: AdapterStatusEnum.optional().describe("Initial lifecycle status (default DRAFT)"),
510
+ vendor: zod.z.string().optional().describe("Vendor / provider name"),
511
+ version: zod.z.string().optional().describe("Adapter version string"),
512
+ description: zod.z.string().optional().describe("Adapter description"),
513
+ capabilities: zod.z.array(zod.z.string()).optional().describe('Capability tags (e.g. "discovery", "cost", "drift")'),
514
+ configSchema: JsonObject.optional().describe("JSON Schema for connection config"),
515
+ tags: zod.z.array(zod.z.string()).optional().describe("Free-form tags")
516
+ }
517
+ },
518
+ async ({
519
+ name,
520
+ slug,
521
+ kind,
522
+ status,
523
+ vendor,
524
+ version,
525
+ description,
526
+ capabilities,
527
+ configSchema,
528
+ tags
529
+ }) => {
530
+ try {
531
+ const input = { name, slug };
532
+ if (kind !== void 0) input.kind = kind;
533
+ if (status !== void 0) input.status = status;
534
+ if (vendor !== void 0) input.vendor = vendor;
535
+ if (version !== void 0) input.version = version;
536
+ if (description !== void 0) input.description = description;
537
+ if (capabilities !== void 0) input.capabilities = capabilities;
538
+ if (configSchema !== void 0) input.configSchema = configSchema;
539
+ if (tags !== void 0) input.tags = tags;
540
+ const data = await ctx.gql.workspace.request(CREATE_ADAPTER, { input });
541
+ return jsonResult(data.adaCreateAdapter);
542
+ } catch (error) {
543
+ ctx.logger.error("adaptercloud adapters_create failed", { error: String(error) });
544
+ return errorResult(
545
+ `Failed to create adapter: ${error instanceof Error ? error.message : String(error)}`
546
+ );
547
+ }
548
+ }
549
+ );
550
+ server.registerTool(
551
+ track(mcpToolName(ctx.productName, "adapters_update")),
552
+ {
553
+ title: "Update Adapter",
554
+ description: "Update an adapter. At least one mutable field must be provided. Use `status` to publish/deprecate an adapter.",
555
+ inputSchema: {
556
+ id: zod.z.string().describe("Adapter ID"),
557
+ name: zod.z.string().optional().describe("Updated display name"),
558
+ kind: AdapterKindEnum.optional().describe("Updated infrastructure kind"),
559
+ status: AdapterStatusEnum.optional().describe("Updated lifecycle status"),
560
+ vendor: zod.z.string().optional().describe("Updated vendor name"),
561
+ version: zod.z.string().optional().describe("Updated version string"),
562
+ description: zod.z.string().optional().describe("Updated description"),
563
+ capabilities: zod.z.array(zod.z.string()).optional().describe("Updated capability tags"),
564
+ configSchema: JsonObject.optional().describe("Updated connection config JSON Schema"),
565
+ tags: zod.z.array(zod.z.string()).optional().describe("Updated tags")
566
+ }
567
+ },
568
+ async ({
569
+ id,
570
+ name,
571
+ kind,
572
+ status,
573
+ vendor,
574
+ version,
575
+ description,
576
+ capabilities,
577
+ configSchema,
578
+ tags
579
+ }) => {
580
+ try {
581
+ const input = {};
582
+ if (name !== void 0) input.name = name;
583
+ if (kind !== void 0) input.kind = kind;
584
+ if (status !== void 0) input.status = status;
585
+ if (vendor !== void 0) input.vendor = vendor;
586
+ if (version !== void 0) input.version = version;
587
+ if (description !== void 0) input.description = description;
588
+ if (capabilities !== void 0) input.capabilities = capabilities;
589
+ if (configSchema !== void 0) input.configSchema = configSchema;
590
+ if (tags !== void 0) input.tags = tags;
591
+ if (Object.keys(input).length === 0) {
592
+ return errorResult(
593
+ "No updates specified \u2014 provide at least one of name/kind/status/vendor/version/description/capabilities/configSchema/tags"
594
+ );
595
+ }
596
+ const data = await ctx.gql.workspace.request(UPDATE_ADAPTER, { id, input });
597
+ return jsonResult(data.adaUpdateAdapter);
598
+ } catch (error) {
599
+ ctx.logger.error("adaptercloud adapters_update failed", { error: String(error) });
600
+ return errorResult(
601
+ `Failed to update adapter: ${error instanceof Error ? error.message : String(error)}`
602
+ );
603
+ }
604
+ }
605
+ );
606
+ server.registerTool(
607
+ track(mcpToolName(ctx.productName, "adapters_archive")),
608
+ {
609
+ title: "Archive Adapter",
610
+ description: "Archive (soft-delete) an adapter. Returns true on success.",
611
+ inputSchema: { id: zod.z.string().describe("Adapter ID") }
612
+ },
613
+ async ({ id }) => {
614
+ try {
615
+ const data = await ctx.gql.workspace.request(
616
+ ARCHIVE_ADAPTER,
617
+ { id }
618
+ );
619
+ return jsonResult({ archived: data.adaArchiveAdapter, id });
620
+ } catch (error) {
621
+ ctx.logger.error("adaptercloud adapters_archive failed", { error: String(error) });
622
+ return errorResult(
623
+ `Failed to archive adapter: ${error instanceof Error ? error.message : String(error)}`
624
+ );
625
+ }
626
+ }
627
+ );
628
+ }
629
+ function registerConnectionTools(server, ctx, track) {
630
+ server.registerTool(
631
+ track(mcpToolName(ctx.productName, "connections_get")),
632
+ {
633
+ title: "Get Connection",
634
+ description: "Fetch a single connection by ID, including its adapter and discovered resources.",
635
+ inputSchema: { id: zod.z.string().describe("Connection ID") }
636
+ },
637
+ async ({ id }) => {
638
+ try {
639
+ const data = await ctx.gql.workspace.request(GET_CONNECTION, { id });
640
+ if (!data.adaConnection) return errorResult(`Connection ${id} not found`);
641
+ return jsonResult(data.adaConnection);
642
+ } catch (error) {
643
+ ctx.logger.error("adaptercloud connections_get failed", { error: String(error) });
644
+ return errorResult(
645
+ `Failed to get connection: ${error instanceof Error ? error.message : String(error)}`
646
+ );
647
+ }
648
+ }
649
+ );
650
+ server.registerTool(
651
+ track(mcpToolName(ctx.productName, "connections_list")),
652
+ {
653
+ title: "List Connections",
654
+ description: "List connections in the bound workspace with optional adapter/status filters and pagination. Returns a page envelope { items, pageInfo }.",
655
+ inputSchema: {
656
+ adapterId: zod.z.string().optional().describe("Filter by adapter ID"),
657
+ status: ConnectionStatusEnum.optional().describe("Filter by connection status"),
658
+ ...PaginationFields
659
+ }
660
+ },
661
+ async ({ adapterId, status, limit, offset, cursor }) => {
662
+ try {
663
+ const data = await ctx.gql.workspace.request(LIST_CONNECTIONS, {
664
+ adapterId,
665
+ status,
666
+ pagination: buildPagination({ limit, offset, cursor })
667
+ });
668
+ return jsonResult(data.adaListConnections);
669
+ } catch (error) {
670
+ ctx.logger.error("adaptercloud connections_list failed", { error: String(error) });
671
+ return errorResult(
672
+ `Failed to list connections: ${error instanceof Error ? error.message : String(error)}`
673
+ );
674
+ }
675
+ }
676
+ );
677
+ server.registerTool(
678
+ track(mcpToolName(ctx.productName, "connections_create")),
679
+ {
680
+ title: "Create Connection",
681
+ description: "Create a connection to a target system for an adapter. `config` holds non-secret connection settings; secrets are referenced by `secretRef`.",
682
+ inputSchema: {
683
+ adapterId: zod.z.string().min(1).describe("Adapter this connection uses"),
684
+ name: zod.z.string().min(1).describe("Connection display name"),
685
+ authMethod: AuthMethodEnum.optional().describe("Authentication method (default NONE)"),
686
+ environment: zod.z.string().optional().describe('Environment, e.g. "prod", "staging"'),
687
+ region: zod.z.string().optional().describe('Target region, e.g. "us-east-1"'),
688
+ config: JsonObject.optional().describe("Non-secret connection config JSON"),
689
+ secretRef: zod.z.string().optional().describe("Reference to a stored secret (not the secret)"),
690
+ targetRef: zod.z.string().optional().describe("Opaque reference to the target system"),
691
+ tags: zod.z.array(zod.z.string()).optional().describe("Free-form tags")
692
+ }
693
+ },
694
+ async ({
695
+ adapterId,
696
+ name,
697
+ authMethod,
698
+ environment,
699
+ region,
700
+ config,
701
+ secretRef,
702
+ targetRef,
703
+ tags
704
+ }) => {
705
+ try {
706
+ const input = { adapterId, name };
707
+ if (authMethod !== void 0) input.authMethod = authMethod;
708
+ if (environment !== void 0) input.environment = environment;
709
+ if (region !== void 0) input.region = region;
710
+ if (config !== void 0) input.config = config;
711
+ if (secretRef !== void 0) input.secretRef = secretRef;
712
+ if (targetRef !== void 0) input.targetRef = targetRef;
713
+ if (tags !== void 0) input.tags = tags;
714
+ const data = await ctx.gql.workspace.request(CREATE_CONNECTION, { input });
715
+ return jsonResult(data.adaCreateConnection);
716
+ } catch (error) {
717
+ ctx.logger.error("adaptercloud connections_create failed", { error: String(error) });
718
+ return errorResult(
719
+ `Failed to create connection: ${error instanceof Error ? error.message : String(error)}`
720
+ );
721
+ }
722
+ }
723
+ );
724
+ server.registerTool(
725
+ track(mcpToolName(ctx.productName, "connections_update")),
726
+ {
727
+ title: "Update Connection",
728
+ description: "Update a connection. At least one mutable field must be provided. To change health/lifecycle status use connections_set_status instead.",
729
+ inputSchema: {
730
+ id: zod.z.string().describe("Connection ID"),
731
+ name: zod.z.string().optional().describe("Updated display name"),
732
+ authMethod: AuthMethodEnum.optional().describe("Updated authentication method"),
733
+ environment: zod.z.string().optional().describe("Updated environment"),
734
+ region: zod.z.string().optional().describe("Updated region"),
735
+ config: JsonObject.optional().describe("Updated non-secret connection config JSON"),
736
+ secretRef: zod.z.string().optional().describe("Updated secret reference"),
737
+ targetRef: zod.z.string().optional().describe("Updated target reference"),
738
+ tags: zod.z.array(zod.z.string()).optional().describe("Updated tags")
739
+ }
740
+ },
741
+ async ({ id, name, authMethod, environment, region, config, secretRef, targetRef, tags }) => {
742
+ try {
743
+ const input = {};
744
+ if (name !== void 0) input.name = name;
745
+ if (authMethod !== void 0) input.authMethod = authMethod;
746
+ if (environment !== void 0) input.environment = environment;
747
+ if (region !== void 0) input.region = region;
748
+ if (config !== void 0) input.config = config;
749
+ if (secretRef !== void 0) input.secretRef = secretRef;
750
+ if (targetRef !== void 0) input.targetRef = targetRef;
751
+ if (tags !== void 0) input.tags = tags;
752
+ if (Object.keys(input).length === 0) {
753
+ return errorResult(
754
+ "No updates specified \u2014 provide at least one of name/authMethod/environment/region/config/secretRef/targetRef/tags"
755
+ );
756
+ }
757
+ const data = await ctx.gql.workspace.request(UPDATE_CONNECTION, { id, input });
758
+ return jsonResult(data.adaUpdateConnection);
759
+ } catch (error) {
760
+ ctx.logger.error("adaptercloud connections_update failed", { error: String(error) });
761
+ return errorResult(
762
+ `Failed to update connection: ${error instanceof Error ? error.message : String(error)}`
763
+ );
764
+ }
765
+ }
766
+ );
767
+ server.registerTool(
768
+ track(mcpToolName(ctx.productName, "connections_disable")),
769
+ {
770
+ title: "Disable Connection",
771
+ description: "Disable a connection (stops future syncs). Returns the updated connection.",
772
+ inputSchema: { id: zod.z.string().describe("Connection ID") }
773
+ },
774
+ async ({ id }) => {
775
+ try {
776
+ const data = await ctx.gql.workspace.request(DISABLE_CONNECTION, { id });
777
+ return jsonResult(data.adaDisableConnection);
778
+ } catch (error) {
779
+ ctx.logger.error("adaptercloud connections_disable failed", { error: String(error) });
780
+ return errorResult(
781
+ `Failed to disable connection: ${error instanceof Error ? error.message : String(error)}`
782
+ );
783
+ }
784
+ }
785
+ );
786
+ server.registerTool(
787
+ track(mcpToolName(ctx.productName, "connections_set_status")),
788
+ {
789
+ title: "Set Connection Status",
790
+ description: "Transition a connection's health/lifecycle status (validated against the connection lifecycle): PENDING, CONNECTED, DEGRADED, ERROR, DISABLED.",
791
+ inputSchema: {
792
+ id: zod.z.string().describe("Connection ID"),
793
+ status: ConnectionStatusEnum.describe("New connection status")
794
+ }
795
+ },
796
+ async ({ id, status }) => {
797
+ try {
798
+ const data = await ctx.gql.workspace.request(SET_CONNECTION_STATUS, { id, status });
799
+ return jsonResult(data.adaSetConnectionStatus);
800
+ } catch (error) {
801
+ ctx.logger.error("adaptercloud connections_set_status failed", { error: String(error) });
802
+ return errorResult(
803
+ `Failed to set connection status: ${error instanceof Error ? error.message : String(error)}`
804
+ );
805
+ }
806
+ }
807
+ );
808
+ }
809
+ function registerResourceTools(server, ctx, track) {
810
+ server.registerTool(
811
+ track(mcpToolName(ctx.productName, "resources_get")),
812
+ {
813
+ title: "Get Resource",
814
+ description: "Fetch a single discovered resource by ID, including its connection and dependency edges.",
815
+ inputSchema: { id: zod.z.string().describe("Resource ID") }
816
+ },
817
+ async ({ id }) => {
818
+ try {
819
+ const data = await ctx.gql.workspace.request(GET_RESOURCE, { id });
820
+ if (!data.adaResource) return errorResult(`Resource ${id} not found`);
821
+ return jsonResult(data.adaResource);
822
+ } catch (error) {
823
+ ctx.logger.error("adaptercloud resources_get failed", { error: String(error) });
824
+ return errorResult(
825
+ `Failed to get resource: ${error instanceof Error ? error.message : String(error)}`
826
+ );
827
+ }
828
+ }
829
+ );
830
+ server.registerTool(
831
+ track(mcpToolName(ctx.productName, "resources_list")),
832
+ {
833
+ title: "List Resources",
834
+ description: "List discovered resources with optional connection/resourceType/state filters and pagination. Returns a page envelope { items, pageInfo }.",
835
+ inputSchema: {
836
+ connectionId: zod.z.string().optional().describe("Filter by connection ID"),
837
+ resourceType: zod.z.string().optional().describe('Filter by provider resource type, e.g. "aws_instance"'),
838
+ state: ResourceStateEnum.optional().describe("Filter by reconciliation state"),
839
+ ...PaginationFields
840
+ }
841
+ },
842
+ async ({ connectionId, resourceType, state, limit, offset, cursor }) => {
843
+ try {
844
+ const data = await ctx.gql.workspace.request(LIST_RESOURCES, {
845
+ connectionId,
846
+ resourceType,
847
+ state,
848
+ pagination: buildPagination({ limit, offset, cursor })
849
+ });
850
+ return jsonResult(data.adaListResources);
851
+ } catch (error) {
852
+ ctx.logger.error("adaptercloud resources_list failed", { error: String(error) });
853
+ return errorResult(
854
+ `Failed to list resources: ${error instanceof Error ? error.message : String(error)}`
855
+ );
856
+ }
857
+ }
858
+ );
859
+ server.registerTool(
860
+ track(mcpToolName(ctx.productName, "resources_register")),
861
+ {
862
+ title: "Register Resource",
863
+ description: "Upsert a discovered resource for a connection (idempotent by externalId). Re-registering the same externalId updates the existing resource.",
864
+ inputSchema: {
865
+ connectionId: zod.z.string().min(1).describe("Connection the resource was discovered through"),
866
+ externalId: zod.z.string().min(1).describe("Provider-native unique ID (idempotency key)"),
867
+ name: zod.z.string().min(1).describe("Resource display name"),
868
+ resourceType: zod.z.string().min(1).describe('Provider resource type, e.g. "aws_instance"'),
869
+ region: zod.z.string().optional().describe("Resource region"),
870
+ monthlyCost: zod.z.number().optional().describe("Estimated monthly cost"),
871
+ attributes: JsonObject.optional().describe("Provider-native resource attributes JSON"),
872
+ providerTags: JsonObject.optional().describe("Provider-native tags JSON"),
873
+ tags: zod.z.array(zod.z.string()).optional().describe("Workspace-side free-form tags")
874
+ }
875
+ },
876
+ async ({
877
+ connectionId,
878
+ externalId,
879
+ name,
880
+ resourceType,
881
+ region,
882
+ monthlyCost,
883
+ attributes,
884
+ providerTags,
885
+ tags
886
+ }) => {
887
+ try {
888
+ const input = { connectionId, externalId, name, resourceType };
889
+ if (region !== void 0) input.region = region;
890
+ if (monthlyCost !== void 0) input.monthlyCost = monthlyCost;
891
+ if (attributes !== void 0) input.attributes = attributes;
892
+ if (providerTags !== void 0) input.providerTags = providerTags;
893
+ if (tags !== void 0) input.tags = tags;
894
+ const data = await ctx.gql.workspace.request(REGISTER_RESOURCE, { input });
895
+ return jsonResult(data.adaRegisterResource);
896
+ } catch (error) {
897
+ ctx.logger.error("adaptercloud resources_register failed", { error: String(error) });
898
+ return errorResult(
899
+ `Failed to register resource: ${error instanceof Error ? error.message : String(error)}`
900
+ );
901
+ }
902
+ }
903
+ );
904
+ }
905
+ function registerTopologyTools(server, ctx, track) {
906
+ server.registerTool(
907
+ track(mcpToolName(ctx.productName, "topology_list")),
908
+ {
909
+ title: "List Topology Edges",
910
+ description: "List topology edges (resource relationships), optionally filtered by edge kind and/or a resource ID (edges touching that resource).",
911
+ inputSchema: {
912
+ kind: EdgeKindEnum.optional().describe("Filter by edge kind"),
913
+ resourceId: zod.z.string().optional().describe("Filter to edges touching this resource")
914
+ }
915
+ },
916
+ async ({ kind, resourceId }) => {
917
+ try {
918
+ const data = await ctx.gql.workspace.request(LIST_TOPOLOGY_EDGES, { kind, resourceId });
919
+ return jsonResult(data.adaListTopologyEdges);
920
+ } catch (error) {
921
+ ctx.logger.error("adaptercloud topology_list failed", { error: String(error) });
922
+ return errorResult(
923
+ `Failed to list topology edges: ${error instanceof Error ? error.message : String(error)}`
924
+ );
925
+ }
926
+ }
927
+ );
928
+ server.registerTool(
929
+ track(mcpToolName(ctx.productName, "topology_create_edge")),
930
+ {
931
+ title: "Create Topology Edge",
932
+ description: "Create a topology edge between two resources (e.g. DEPENDS_ON, ROUTES_TO, CONTAINS). Set `bidirectional` for symmetric relationships.",
933
+ inputSchema: {
934
+ fromResourceId: zod.z.string().min(1).describe("Source resource ID"),
935
+ toResourceId: zod.z.string().min(1).describe("Target resource ID"),
936
+ kind: EdgeKindEnum.optional().describe("Edge kind (default DEPENDS_ON)"),
937
+ weight: zod.z.number().int().optional().describe("Edge weight"),
938
+ bidirectional: zod.z.boolean().optional().describe("Whether the edge is symmetric (default false)"),
939
+ attributes: JsonObject.optional().describe("Edge attributes JSON")
940
+ }
941
+ },
942
+ async ({ fromResourceId, toResourceId, kind, weight, bidirectional, attributes }) => {
943
+ try {
944
+ const input = { fromResourceId, toResourceId };
945
+ if (kind !== void 0) input.kind = kind;
946
+ if (weight !== void 0) input.weight = weight;
947
+ if (bidirectional !== void 0) input.bidirectional = bidirectional;
948
+ if (attributes !== void 0) input.attributes = attributes;
949
+ const data = await ctx.gql.workspace.request(CREATE_TOPOLOGY_EDGE, { input });
950
+ return jsonResult(data.adaCreateTopologyEdge);
951
+ } catch (error) {
952
+ ctx.logger.error("adaptercloud topology_create_edge failed", { error: String(error) });
953
+ return errorResult(
954
+ `Failed to create topology edge: ${error instanceof Error ? error.message : String(error)}`
955
+ );
956
+ }
957
+ }
958
+ );
959
+ }
960
+ function registerPolicyTools(server, ctx, track) {
961
+ server.registerTool(
962
+ track(mcpToolName(ctx.productName, "policies_get")),
963
+ {
964
+ title: "Get Policy",
965
+ description: "Fetch a single governance policy by ID, including its violations.",
966
+ inputSchema: { id: zod.z.string().describe("Policy ID") }
967
+ },
968
+ async ({ id }) => {
969
+ try {
970
+ const data = await ctx.gql.workspace.request(GET_POLICY, { id });
971
+ if (!data.adaPolicy) return errorResult(`Policy ${id} not found`);
972
+ return jsonResult(data.adaPolicy);
973
+ } catch (error) {
974
+ ctx.logger.error("adaptercloud policies_get failed", { error: String(error) });
975
+ return errorResult(
976
+ `Failed to get policy: ${error instanceof Error ? error.message : String(error)}`
977
+ );
978
+ }
979
+ }
980
+ );
981
+ server.registerTool(
982
+ track(mcpToolName(ctx.productName, "policies_list")),
983
+ {
984
+ title: "List Policies",
985
+ description: "List governance policies with optional kind/isActive filters and pagination. Returns a page envelope { items, pageInfo }.",
986
+ inputSchema: {
987
+ kind: PolicyKindEnum.optional().describe("Filter by policy kind"),
988
+ isActive: zod.z.boolean().optional().describe("Filter by active flag"),
989
+ ...PaginationFields
990
+ }
991
+ },
992
+ async ({ kind, isActive, limit, offset, cursor }) => {
993
+ try {
994
+ const data = await ctx.gql.workspace.request(LIST_POLICIES, {
995
+ kind,
996
+ isActive,
997
+ pagination: buildPagination({ limit, offset, cursor })
998
+ });
999
+ return jsonResult(data.adaListPolicies);
1000
+ } catch (error) {
1001
+ ctx.logger.error("adaptercloud policies_list failed", { error: String(error) });
1002
+ return errorResult(
1003
+ `Failed to list policies: ${error instanceof Error ? error.message : String(error)}`
1004
+ );
1005
+ }
1006
+ }
1007
+ );
1008
+ server.registerTool(
1009
+ track(mcpToolName(ctx.productName, "policies_create")),
1010
+ {
1011
+ title: "Create Policy",
1012
+ description: "Create a governance policy. `expression` is the required policy-rule JSON; `appliesTo` is an optional list of resource-type selectors.",
1013
+ inputSchema: {
1014
+ name: zod.z.string().min(1).describe("Policy name"),
1015
+ expression: JsonObject.describe("Policy-rule expression JSON (required)"),
1016
+ kind: PolicyKindEnum.optional().describe("Policy kind (default GUARDRAIL)"),
1017
+ enforcement: PolicyEnforcementEnum.optional().describe("Enforcement mode (default WARN)"),
1018
+ severity: SeverityEnum.optional().describe("Severity (default MEDIUM)"),
1019
+ description: zod.z.string().optional().describe("Policy description"),
1020
+ appliesTo: zod.z.array(zod.z.string()).optional().describe("Resource-type selectors the policy applies to"),
1021
+ isActive: zod.z.boolean().optional().describe("Whether the policy is active (default true)"),
1022
+ tags: zod.z.array(zod.z.string()).optional().describe("Free-form tags")
1023
+ }
1024
+ },
1025
+ async ({
1026
+ name,
1027
+ expression,
1028
+ kind,
1029
+ enforcement,
1030
+ severity,
1031
+ description,
1032
+ appliesTo,
1033
+ isActive,
1034
+ tags
1035
+ }) => {
1036
+ try {
1037
+ const input = { name, expression };
1038
+ if (kind !== void 0) input.kind = kind;
1039
+ if (enforcement !== void 0) input.enforcement = enforcement;
1040
+ if (severity !== void 0) input.severity = severity;
1041
+ if (description !== void 0) input.description = description;
1042
+ if (appliesTo !== void 0) input.appliesTo = appliesTo;
1043
+ if (isActive !== void 0) input.isActive = isActive;
1044
+ if (tags !== void 0) input.tags = tags;
1045
+ const data = await ctx.gql.workspace.request(CREATE_POLICY, { input });
1046
+ return jsonResult(data.adaCreatePolicy);
1047
+ } catch (error) {
1048
+ ctx.logger.error("adaptercloud policies_create failed", { error: String(error) });
1049
+ return errorResult(
1050
+ `Failed to create policy: ${error instanceof Error ? error.message : String(error)}`
1051
+ );
1052
+ }
1053
+ }
1054
+ );
1055
+ server.registerTool(
1056
+ track(mcpToolName(ctx.productName, "policies_update")),
1057
+ {
1058
+ title: "Update Policy",
1059
+ description: "Update a governance policy. At least one mutable field must be provided. Use `isActive` to enable/disable a policy.",
1060
+ inputSchema: {
1061
+ id: zod.z.string().describe("Policy ID"),
1062
+ name: zod.z.string().optional().describe("Updated name"),
1063
+ expression: JsonObject.optional().describe("Updated policy-rule expression JSON"),
1064
+ kind: PolicyKindEnum.optional().describe("Updated policy kind"),
1065
+ enforcement: PolicyEnforcementEnum.optional().describe("Updated enforcement mode"),
1066
+ severity: SeverityEnum.optional().describe("Updated severity"),
1067
+ description: zod.z.string().optional().describe("Updated description"),
1068
+ appliesTo: zod.z.array(zod.z.string()).optional().describe("Updated resource-type selectors"),
1069
+ isActive: zod.z.boolean().optional().describe("Updated active flag"),
1070
+ tags: zod.z.array(zod.z.string()).optional().describe("Updated tags")
1071
+ }
1072
+ },
1073
+ async ({
1074
+ id,
1075
+ name,
1076
+ expression,
1077
+ kind,
1078
+ enforcement,
1079
+ severity,
1080
+ description,
1081
+ appliesTo,
1082
+ isActive,
1083
+ tags
1084
+ }) => {
1085
+ try {
1086
+ const input = {};
1087
+ if (name !== void 0) input.name = name;
1088
+ if (expression !== void 0) input.expression = expression;
1089
+ if (kind !== void 0) input.kind = kind;
1090
+ if (enforcement !== void 0) input.enforcement = enforcement;
1091
+ if (severity !== void 0) input.severity = severity;
1092
+ if (description !== void 0) input.description = description;
1093
+ if (appliesTo !== void 0) input.appliesTo = appliesTo;
1094
+ if (isActive !== void 0) input.isActive = isActive;
1095
+ if (tags !== void 0) input.tags = tags;
1096
+ if (Object.keys(input).length === 0) {
1097
+ return errorResult(
1098
+ "No updates specified \u2014 provide at least one of name/expression/kind/enforcement/severity/description/appliesTo/isActive/tags"
1099
+ );
1100
+ }
1101
+ const data = await ctx.gql.workspace.request(UPDATE_POLICY, { id, input });
1102
+ return jsonResult(data.adaUpdatePolicy);
1103
+ } catch (error) {
1104
+ ctx.logger.error("adaptercloud policies_update failed", { error: String(error) });
1105
+ return errorResult(
1106
+ `Failed to update policy: ${error instanceof Error ? error.message : String(error)}`
1107
+ );
1108
+ }
1109
+ }
1110
+ );
1111
+ server.registerTool(
1112
+ track(mcpToolName(ctx.productName, "policies_archive")),
1113
+ {
1114
+ title: "Archive Policy",
1115
+ description: "Archive (soft-delete) a governance policy. Returns true on success.",
1116
+ inputSchema: { id: zod.z.string().describe("Policy ID") }
1117
+ },
1118
+ async ({ id }) => {
1119
+ try {
1120
+ const data = await ctx.gql.workspace.request(
1121
+ ARCHIVE_POLICY,
1122
+ { id }
1123
+ );
1124
+ return jsonResult({ archived: data.adaArchivePolicy, id });
1125
+ } catch (error) {
1126
+ ctx.logger.error("adaptercloud policies_archive failed", { error: String(error) });
1127
+ return errorResult(
1128
+ `Failed to archive policy: ${error instanceof Error ? error.message : String(error)}`
1129
+ );
1130
+ }
1131
+ }
1132
+ );
1133
+ }
1134
+ function registerViolationTools(server, ctx, track) {
1135
+ server.registerTool(
1136
+ track(mcpToolName(ctx.productName, "violations_list")),
1137
+ {
1138
+ title: "List Violations",
1139
+ description: "List policy violations with optional policy/resource/status filters and pagination. Returns a page envelope { items, pageInfo }.",
1140
+ inputSchema: {
1141
+ policyId: zod.z.string().optional().describe("Filter by policy ID"),
1142
+ resourceId: zod.z.string().optional().describe("Filter by resource ID"),
1143
+ status: ViolationStatusEnum.optional().describe("Filter by violation status"),
1144
+ ...PaginationFields
1145
+ }
1146
+ },
1147
+ async ({ policyId, resourceId, status, limit, offset, cursor }) => {
1148
+ try {
1149
+ const data = await ctx.gql.workspace.request(LIST_VIOLATIONS, {
1150
+ policyId,
1151
+ resourceId,
1152
+ status,
1153
+ pagination: buildPagination({ limit, offset, cursor })
1154
+ });
1155
+ return jsonResult(data.adaListViolations);
1156
+ } catch (error) {
1157
+ ctx.logger.error("adaptercloud violations_list failed", { error: String(error) });
1158
+ return errorResult(
1159
+ `Failed to list violations: ${error instanceof Error ? error.message : String(error)}`
1160
+ );
1161
+ }
1162
+ }
1163
+ );
1164
+ server.registerTool(
1165
+ track(mcpToolName(ctx.productName, "violations_record")),
1166
+ {
1167
+ title: "Record Violation",
1168
+ description: "Record a policy violation against a resource. `evidence` is optional JSON supporting the finding.",
1169
+ inputSchema: {
1170
+ policyId: zod.z.string().min(1).describe("Violated policy ID"),
1171
+ resourceId: zod.z.string().min(1).describe("Offending resource ID"),
1172
+ message: zod.z.string().min(1).describe("Human-readable violation message"),
1173
+ severity: SeverityEnum.optional().describe(
1174
+ "Severity override (defaults to policy severity)"
1175
+ ),
1176
+ evidence: JsonObject.optional().describe("Supporting evidence JSON")
1177
+ }
1178
+ },
1179
+ async ({ policyId, resourceId, message, severity, evidence }) => {
1180
+ try {
1181
+ const input = { policyId, resourceId, message };
1182
+ if (severity !== void 0) input.severity = severity;
1183
+ if (evidence !== void 0) input.evidence = evidence;
1184
+ const data = await ctx.gql.workspace.request(RECORD_VIOLATION, { input });
1185
+ return jsonResult(data.adaRecordViolation);
1186
+ } catch (error) {
1187
+ ctx.logger.error("adaptercloud violations_record failed", { error: String(error) });
1188
+ return errorResult(
1189
+ `Failed to record violation: ${error instanceof Error ? error.message : String(error)}`
1190
+ );
1191
+ }
1192
+ }
1193
+ );
1194
+ server.registerTool(
1195
+ track(mcpToolName(ctx.productName, "violations_resolve")),
1196
+ {
1197
+ title: "Resolve Violation",
1198
+ description: "Resolve or waive a violation (validated transition). Waiving (status=WAIVED) requires a `waiverReason`.",
1199
+ inputSchema: {
1200
+ id: zod.z.string().describe("Violation ID"),
1201
+ status: ViolationStatusEnum.describe("New status (e.g. RESOLVED, WAIVED, ACKNOWLEDGED)"),
1202
+ waiverReason: zod.z.string().optional().describe("Reason \u2014 required when status is WAIVED")
1203
+ }
1204
+ },
1205
+ async ({ id, status, waiverReason }) => {
1206
+ try {
1207
+ const data = await ctx.gql.workspace.request(RESOLVE_VIOLATION, { id, status, waiverReason });
1208
+ return jsonResult(data.adaResolveViolation);
1209
+ } catch (error) {
1210
+ ctx.logger.error("adaptercloud violations_resolve failed", { error: String(error) });
1211
+ return errorResult(
1212
+ `Failed to resolve violation: ${error instanceof Error ? error.message : String(error)}`
1213
+ );
1214
+ }
1215
+ }
1216
+ );
1217
+ }
1218
+ function registerDriftTools(server, ctx, track) {
1219
+ server.registerTool(
1220
+ track(mcpToolName(ctx.productName, "drift_list")),
1221
+ {
1222
+ title: "List Drift Records",
1223
+ description: "List configuration-drift records, optionally filtered by resource and/or status. Returns a plain array.",
1224
+ inputSchema: {
1225
+ resourceId: zod.z.string().optional().describe("Filter by resource ID"),
1226
+ status: DriftStatusEnum.optional().describe("Filter by drift status")
1227
+ }
1228
+ },
1229
+ async ({ resourceId, status }) => {
1230
+ try {
1231
+ const data = await ctx.gql.workspace.request(LIST_DRIFT_RECORDS, { resourceId, status });
1232
+ return jsonResult(data.adaListDriftRecords);
1233
+ } catch (error) {
1234
+ ctx.logger.error("adaptercloud drift_list failed", { error: String(error) });
1235
+ return errorResult(
1236
+ `Failed to list drift records: ${error instanceof Error ? error.message : String(error)}`
1237
+ );
1238
+ }
1239
+ }
1240
+ );
1241
+ server.registerTool(
1242
+ track(mcpToolName(ctx.productName, "drift_record")),
1243
+ {
1244
+ title: "Record Drift",
1245
+ description: "Record a configuration-drift finding for a resource at a given attribute path, capturing expected vs observed values.",
1246
+ inputSchema: {
1247
+ resourceId: zod.z.string().min(1).describe("Drifted resource ID"),
1248
+ attributePath: zod.z.string().min(1).describe('Attribute path that drifted, e.g. "tags.env"'),
1249
+ expectedValue: JsonObject.optional().describe("Expected value JSON"),
1250
+ observedValue: JsonObject.optional().describe("Observed value JSON"),
1251
+ severity: SeverityEnum.optional().describe("Severity of the drift")
1252
+ }
1253
+ },
1254
+ async ({ resourceId, attributePath, expectedValue, observedValue, severity }) => {
1255
+ try {
1256
+ const input = { resourceId, attributePath };
1257
+ if (expectedValue !== void 0) input.expectedValue = expectedValue;
1258
+ if (observedValue !== void 0) input.observedValue = observedValue;
1259
+ if (severity !== void 0) input.severity = severity;
1260
+ const data = await ctx.gql.workspace.request(RECORD_DRIFT, { input });
1261
+ return jsonResult(data.adaRecordDrift);
1262
+ } catch (error) {
1263
+ ctx.logger.error("adaptercloud drift_record failed", { error: String(error) });
1264
+ return errorResult(
1265
+ `Failed to record drift: ${error instanceof Error ? error.message : String(error)}`
1266
+ );
1267
+ }
1268
+ }
1269
+ );
1270
+ server.registerTool(
1271
+ track(mcpToolName(ctx.productName, "drift_remediate")),
1272
+ {
1273
+ title: "Remediate Drift",
1274
+ description: "Mark a drift record as remediated. Returns the updated drift record.",
1275
+ inputSchema: { id: zod.z.string().describe("Drift record ID") }
1276
+ },
1277
+ async ({ id }) => {
1278
+ try {
1279
+ const data = await ctx.gql.workspace.request(REMEDIATE_DRIFT, { id });
1280
+ return jsonResult(data.adaRemediateDrift);
1281
+ } catch (error) {
1282
+ ctx.logger.error("adaptercloud drift_remediate failed", { error: String(error) });
1283
+ return errorResult(
1284
+ `Failed to remediate drift: ${error instanceof Error ? error.message : String(error)}`
1285
+ );
1286
+ }
1287
+ }
1288
+ );
1289
+ }
1290
+ function registerSyncTools(server, ctx, track) {
1291
+ server.registerTool(
1292
+ track(mcpToolName(ctx.productName, "sync_get")),
1293
+ {
1294
+ title: "Get Sync Run",
1295
+ description: "Fetch a single sync run by ID, including its counts and summary.",
1296
+ inputSchema: { id: zod.z.string().describe("Sync run ID") }
1297
+ },
1298
+ async ({ id }) => {
1299
+ try {
1300
+ const data = await ctx.gql.workspace.request(GET_SYNC_RUN, { id });
1301
+ if (!data.adaSyncRun) return errorResult(`Sync run ${id} not found`);
1302
+ return jsonResult(data.adaSyncRun);
1303
+ } catch (error) {
1304
+ ctx.logger.error("adaptercloud sync_get failed", { error: String(error) });
1305
+ return errorResult(
1306
+ `Failed to get sync run: ${error instanceof Error ? error.message : String(error)}`
1307
+ );
1308
+ }
1309
+ }
1310
+ );
1311
+ server.registerTool(
1312
+ track(mcpToolName(ctx.productName, "sync_list")),
1313
+ {
1314
+ title: "List Sync Runs",
1315
+ description: "List sync runs with optional connection/status filters and pagination. Returns a page envelope { items, pageInfo }.",
1316
+ inputSchema: {
1317
+ connectionId: zod.z.string().optional().describe("Filter by connection ID"),
1318
+ status: SyncStatusEnum.optional().describe("Filter by sync status"),
1319
+ ...PaginationFields
1320
+ }
1321
+ },
1322
+ async ({ connectionId, status, limit, offset, cursor }) => {
1323
+ try {
1324
+ const data = await ctx.gql.workspace.request(LIST_SYNC_RUNS, {
1325
+ connectionId,
1326
+ status,
1327
+ pagination: buildPagination({ limit, offset, cursor })
1328
+ });
1329
+ return jsonResult(data.adaListSyncRuns);
1330
+ } catch (error) {
1331
+ ctx.logger.error("adaptercloud sync_list failed", { error: String(error) });
1332
+ return errorResult(
1333
+ `Failed to list sync runs: ${error instanceof Error ? error.message : String(error)}`
1334
+ );
1335
+ }
1336
+ }
1337
+ );
1338
+ server.registerTool(
1339
+ track(mcpToolName(ctx.productName, "sync_start")),
1340
+ {
1341
+ title: "Start Sync Run",
1342
+ description: "Start a sync run against a connection. `kind` selects DISCOVERY (default), RECONCILE, FULL, or COST_INGEST.",
1343
+ inputSchema: {
1344
+ connectionId: zod.z.string().min(1).describe("Connection to sync"),
1345
+ kind: SyncKindEnum.optional().describe("Sync kind (default DISCOVERY)")
1346
+ }
1347
+ },
1348
+ async ({ connectionId, kind }) => {
1349
+ try {
1350
+ const input = { connectionId };
1351
+ if (kind !== void 0) input.kind = kind;
1352
+ const data = await ctx.gql.workspace.request(START_SYNC_RUN, { input });
1353
+ return jsonResult(data.adaStartSyncRun);
1354
+ } catch (error) {
1355
+ ctx.logger.error("adaptercloud sync_start failed", { error: String(error) });
1356
+ return errorResult(
1357
+ `Failed to start sync run: ${error instanceof Error ? error.message : String(error)}`
1358
+ );
1359
+ }
1360
+ }
1361
+ );
1362
+ server.registerTool(
1363
+ track(mcpToolName(ctx.productName, "sync_complete")),
1364
+ {
1365
+ title: "Complete Sync Run",
1366
+ description: "Mark a sync run as succeeded, recording its discovered/reconciled/drift/violation counts and a summary.",
1367
+ inputSchema: {
1368
+ id: zod.z.string().describe("Sync run ID"),
1369
+ discoveredCount: zod.z.number().int().optional().describe("Number of resources discovered"),
1370
+ reconciledCount: zod.z.number().int().optional().describe("Number of resources reconciled"),
1371
+ driftCount: zod.z.number().int().optional().describe("Number of drift records detected"),
1372
+ violationCount: zod.z.number().int().optional().describe("Number of violations detected"),
1373
+ summary: JsonObject.optional().describe("Run summary JSON")
1374
+ }
1375
+ },
1376
+ async ({ id, discoveredCount, reconciledCount, driftCount, violationCount, summary }) => {
1377
+ try {
1378
+ const input = {};
1379
+ if (discoveredCount !== void 0) input.discoveredCount = discoveredCount;
1380
+ if (reconciledCount !== void 0) input.reconciledCount = reconciledCount;
1381
+ if (driftCount !== void 0) input.driftCount = driftCount;
1382
+ if (violationCount !== void 0) input.violationCount = violationCount;
1383
+ if (summary !== void 0) input.summary = summary;
1384
+ const data = await ctx.gql.workspace.request(COMPLETE_SYNC_RUN, {
1385
+ id,
1386
+ input: Object.keys(input).length > 0 ? input : void 0
1387
+ });
1388
+ return jsonResult(data.adaCompleteSyncRun);
1389
+ } catch (error) {
1390
+ ctx.logger.error("adaptercloud sync_complete failed", { error: String(error) });
1391
+ return errorResult(
1392
+ `Failed to complete sync run: ${error instanceof Error ? error.message : String(error)}`
1393
+ );
1394
+ }
1395
+ }
1396
+ );
1397
+ server.registerTool(
1398
+ track(mcpToolName(ctx.productName, "sync_fail")),
1399
+ {
1400
+ title: "Fail Sync Run",
1401
+ description: "Mark a sync run as failed with an error message.",
1402
+ inputSchema: {
1403
+ id: zod.z.string().describe("Sync run ID"),
1404
+ error: zod.z.string().min(1).describe("Failure reason / error message")
1405
+ }
1406
+ },
1407
+ async ({ id, error }) => {
1408
+ try {
1409
+ const data = await ctx.gql.workspace.request(FAIL_SYNC_RUN, { id, error });
1410
+ return jsonResult(data.adaFailSyncRun);
1411
+ } catch (err) {
1412
+ ctx.logger.error("adaptercloud sync_fail failed", { error: String(err) });
1413
+ return errorResult(
1414
+ `Failed to fail sync run: ${err instanceof Error ? err.message : String(err)}`
1415
+ );
1416
+ }
1417
+ }
1418
+ );
1419
+ server.registerTool(
1420
+ track(mcpToolName(ctx.productName, "sync_cancel")),
1421
+ {
1422
+ title: "Cancel Sync Run",
1423
+ description: "Cancel an in-flight or queued sync run. Returns the updated sync run.",
1424
+ inputSchema: { id: zod.z.string().describe("Sync run ID") }
1425
+ },
1426
+ async ({ id }) => {
1427
+ try {
1428
+ const data = await ctx.gql.workspace.request(CANCEL_SYNC_RUN, { id });
1429
+ return jsonResult(data.adaCancelSyncRun);
1430
+ } catch (error) {
1431
+ ctx.logger.error("adaptercloud sync_cancel failed", { error: String(error) });
1432
+ return errorResult(
1433
+ `Failed to cancel sync run: ${error instanceof Error ? error.message : String(error)}`
1434
+ );
1435
+ }
1436
+ }
1437
+ );
1438
+ }
1439
+ function registerCostTools(server, ctx, track) {
1440
+ server.registerTool(
1441
+ track(mcpToolName(ctx.productName, "cost_list")),
1442
+ {
1443
+ title: "List Cost Records",
1444
+ description: "List cost records, optionally filtered by connection, resource, and/or service. Returns a plain array.",
1445
+ inputSchema: {
1446
+ connectionId: zod.z.string().optional().describe("Filter by connection ID"),
1447
+ resourceId: zod.z.string().optional().describe("Filter by resource ID"),
1448
+ service: zod.z.string().optional().describe('Filter by cost service, e.g. "EC2"')
1449
+ }
1450
+ },
1451
+ async ({ connectionId, resourceId, service }) => {
1452
+ try {
1453
+ const data = await ctx.gql.workspace.request(LIST_COST_RECORDS, { connectionId, resourceId, service });
1454
+ return jsonResult(data.adaListCostRecords);
1455
+ } catch (error) {
1456
+ ctx.logger.error("adaptercloud cost_list failed", { error: String(error) });
1457
+ return errorResult(
1458
+ `Failed to list cost records: ${error instanceof Error ? error.message : String(error)}`
1459
+ );
1460
+ }
1461
+ }
1462
+ );
1463
+ server.registerTool(
1464
+ track(mcpToolName(ctx.productName, "cost_summary")),
1465
+ {
1466
+ title: "Cost Summary",
1467
+ description: "Aggregate spend grouped by cost service across the workspace, optionally scoped to a single connection.",
1468
+ inputSchema: {
1469
+ connectionId: zod.z.string().optional().describe("Scope the summary to one connection")
1470
+ }
1471
+ },
1472
+ async ({ connectionId }) => {
1473
+ try {
1474
+ const data = await ctx.gql.workspace.request(COST_SUMMARY, { connectionId });
1475
+ return jsonResult(data.adaCostSummary);
1476
+ } catch (error) {
1477
+ ctx.logger.error("adaptercloud cost_summary failed", { error: String(error) });
1478
+ return errorResult(
1479
+ `Failed to get cost summary: ${error instanceof Error ? error.message : String(error)}`
1480
+ );
1481
+ }
1482
+ }
1483
+ );
1484
+ server.registerTool(
1485
+ track(mcpToolName(ctx.productName, "cost_ingest")),
1486
+ {
1487
+ title: "Ingest Cost Record",
1488
+ description: "Ingest a cost record for a service over a billing period. `breakdown` is optional per-line-item JSON.",
1489
+ inputSchema: {
1490
+ service: zod.z.string().min(1).describe('Cost service, e.g. "EC2"'),
1491
+ amount: zod.z.number().describe("Cost amount"),
1492
+ periodStart: zod.z.string().min(1).describe("Billing period start (ISO 8601 DateTime)"),
1493
+ periodEnd: zod.z.string().min(1).describe("Billing period end (ISO 8601 DateTime)"),
1494
+ currency: zod.z.string().optional().describe('Currency code, e.g. "USD"'),
1495
+ connectionId: zod.z.string().optional().describe("Owning connection ID"),
1496
+ resourceId: zod.z.string().optional().describe("Owning resource ID"),
1497
+ breakdown: JsonObject.optional().describe("Per-line-item cost breakdown JSON")
1498
+ }
1499
+ },
1500
+ async ({
1501
+ service,
1502
+ amount,
1503
+ periodStart,
1504
+ periodEnd,
1505
+ currency,
1506
+ connectionId,
1507
+ resourceId,
1508
+ breakdown
1509
+ }) => {
1510
+ try {
1511
+ const input = { service, amount, periodStart, periodEnd };
1512
+ if (currency !== void 0) input.currency = currency;
1513
+ if (connectionId !== void 0) input.connectionId = connectionId;
1514
+ if (resourceId !== void 0) input.resourceId = resourceId;
1515
+ if (breakdown !== void 0) input.breakdown = breakdown;
1516
+ const data = await ctx.gql.workspace.request(INGEST_COST, { input });
1517
+ return jsonResult(data.adaIngestCost);
1518
+ } catch (error) {
1519
+ ctx.logger.error("adaptercloud cost_ingest failed", { error: String(error) });
1520
+ return errorResult(
1521
+ `Failed to ingest cost record: ${error instanceof Error ? error.message : String(error)}`
1522
+ );
1523
+ }
1524
+ }
1525
+ );
1526
+ }
1527
+
1528
+ // src/modules/adaptercloud/tools/health.ts
1529
+ function registerHealthTools(server, ctx, track) {
1530
+ server.registerTool(
1531
+ track(mcpToolName(ctx.productName, "health")),
1532
+ {
1533
+ title: "AdapterCloud Health Check",
1534
+ description: "Public health probe for the AdapterCloud subgraph (adaHealth). Requires no authentication.",
1535
+ inputSchema: {}
1536
+ },
1537
+ async () => {
1538
+ try {
1539
+ const data = await ctx.gql.workspace.request(HEALTH, {});
1540
+ return jsonResult({ ok: true, status: data.adaHealth });
1541
+ } catch (error) {
1542
+ ctx.logger.error("adaptercloud health failed", { error: String(error) });
1543
+ return errorResult(
1544
+ `AdapterCloud health check failed: ${error instanceof Error ? error.message : String(error)}`
1545
+ );
1546
+ }
1547
+ }
1548
+ );
1549
+ }
1550
+
1551
+ // src/modules/adaptercloud/resources.ts
1552
+ function registerAdaptercloudResources(server, ctx, track) {
1553
+ const schemaUri = track(mcpResourceUri(ctx.productName, "schema"));
1554
+ const adaptersUri = track(mcpResourceUri(ctx.productName, "adapters"));
1555
+ const connectionsUri = track(mcpResourceUri(ctx.productName, "connections"));
1556
+ const costUri = track(mcpResourceUri(ctx.productName, "cost"));
1557
+ server.registerResource(
1558
+ "adaptercloud-schema",
1559
+ schemaUri,
1560
+ {
1561
+ title: "AdapterCloud Domain Schema",
1562
+ description: "Overview of the AdapterCloud (InfraVerse) domain \u2014 entities, enums, and the per-entity tool surface.",
1563
+ mimeType: "text/plain"
1564
+ },
1565
+ async () => {
1566
+ ctx.logger.debug(`Resource ${schemaUri} requested`);
1567
+ const schema = `# AdapterCloud Domain (Overview)
1568
+
1569
+ InfraVerse \u2014 the digital-infrastructure continuum. Stitches fragmented
1570
+ infrastructure (multi-cloud, on-prem, edge, SaaS) into one continuous,
1571
+ governable fabric.
1572
+
1573
+ ## Entities
1574
+ - AdaAdapter \u2014 an integration definition (the adapter catalog)
1575
+ - AdaConnection \u2014 a live connection to a target system for an adapter
1576
+ - AdaResource \u2014 a discovered infrastructure resource (upserted by externalId)
1577
+ - AdaTopologyEdge \u2014 a dependency/relationship edge between two resources
1578
+ - AdaPolicy \u2014 a governance guardrail (with violations)
1579
+ - AdaPolicyViolation \u2014 a policy violation against a resource
1580
+ - AdaDriftRecord \u2014 a configuration-drift finding against a resource
1581
+ - AdaSyncRun \u2014 a discovery/reconcile/cost-ingest run against a connection
1582
+ - AdaCostRecord \u2014 a cost record for a service over a billing period
1583
+
1584
+ ## Enums
1585
+ - AdaAdapterKind: CUSTOM, DATA_SYSTEM, EDGE, KUBERNETES, NETWORK, ON_PREM, PRIVATE_CLOUD, PUBLIC_CLOUD, SAAS
1586
+ - AdaAdapterStatus: ARCHIVED, DEPRECATED, DRAFT, PUBLISHED
1587
+ - AdaAuthMethod: API_KEY, CERTIFICATE, IAM_ROLE, NONE, OAUTH2, SERVICE_ACCOUNT
1588
+ - AdaConnectionStatus: CONNECTED, DEGRADED, DISABLED, ERROR, PENDING
1589
+ - AdaResourceState: DELETED, DISCOVERED, DRIFTED, ORPHANED, RECONCILED
1590
+ - AdaEdgeKind: CONNECTS_TO, CONTAINS, DEPENDS_ON, REPLICATES_TO, ROUTES_TO
1591
+ - AdaPolicyKind: COMPLIANCE, COST, GUARDRAIL, NAMING, SECURITY, TAGGING
1592
+ - AdaPolicyEnforcement: ADVISORY, BLOCK, WARN
1593
+ - AdaSeverity: CRITICAL, HIGH, INFO, LOW, MEDIUM
1594
+ - AdaViolationStatus: ACKNOWLEDGED, OPEN, RESOLVED, WAIVED
1595
+ - AdaDriftStatus: ACKNOWLEDGED, DETECTED, IGNORED, REMEDIATED
1596
+ - AdaSyncKind: COST_INGEST, DISCOVERY, FULL, RECONCILE
1597
+ - AdaSyncStatus: CANCELLED, FAILED, QUEUED, RUNNING, SUCCEEDED
1598
+
1599
+ ## Tool groups
1600
+ adapters, connections, resources, topology (fabric); policies, violations, drift
1601
+ (governance); sync, cost (operations/FinOps); plus the public health probe.
1602
+ All run against the WORKSPACE gateway (workspace-scoped) except the public
1603
+ health probe.
1604
+ `;
1605
+ return {
1606
+ contents: [{ uri: schemaUri, text: schema, mimeType: "text/plain" }]
1607
+ };
1608
+ }
1609
+ );
1610
+ server.registerResource(
1611
+ "adaptercloud-adapters",
1612
+ adaptersUri,
1613
+ {
1614
+ title: "AdapterCloud Adapter Catalog",
1615
+ description: "The first 50 adapters (integration definitions) in the bound workspace.",
1616
+ mimeType: "application/json"
1617
+ },
1618
+ async () => {
1619
+ ctx.logger.debug(`Resource ${adaptersUri} requested`);
1620
+ try {
1621
+ const data = await ctx.gql.workspace.request(LIST_ADAPTERS, {
1622
+ pagination: { limit: 50, offset: 0 }
1623
+ });
1624
+ return {
1625
+ contents: [
1626
+ {
1627
+ uri: adaptersUri,
1628
+ text: JSON.stringify(data.adaListAdapters, null, 2),
1629
+ mimeType: "application/json"
1630
+ }
1631
+ ]
1632
+ };
1633
+ } catch (error) {
1634
+ return {
1635
+ contents: [
1636
+ {
1637
+ uri: adaptersUri,
1638
+ text: JSON.stringify({
1639
+ error: error instanceof Error ? error.message : String(error)
1640
+ }),
1641
+ mimeType: "application/json"
1642
+ }
1643
+ ]
1644
+ };
1645
+ }
1646
+ }
1647
+ );
1648
+ server.registerResource(
1649
+ "adaptercloud-connections",
1650
+ connectionsUri,
1651
+ {
1652
+ title: "AdapterCloud Connection Directory",
1653
+ description: "The first 50 connections in the bound workspace.",
1654
+ mimeType: "application/json"
1655
+ },
1656
+ async () => {
1657
+ ctx.logger.debug(`Resource ${connectionsUri} requested`);
1658
+ try {
1659
+ const data = await ctx.gql.workspace.request(
1660
+ LIST_CONNECTIONS,
1661
+ { pagination: { limit: 50, offset: 0 } }
1662
+ );
1663
+ return {
1664
+ contents: [
1665
+ {
1666
+ uri: connectionsUri,
1667
+ text: JSON.stringify(data.adaListConnections, null, 2),
1668
+ mimeType: "application/json"
1669
+ }
1670
+ ]
1671
+ };
1672
+ } catch (error) {
1673
+ return {
1674
+ contents: [
1675
+ {
1676
+ uri: connectionsUri,
1677
+ text: JSON.stringify({
1678
+ error: error instanceof Error ? error.message : String(error)
1679
+ }),
1680
+ mimeType: "application/json"
1681
+ }
1682
+ ]
1683
+ };
1684
+ }
1685
+ }
1686
+ );
1687
+ server.registerResource(
1688
+ "adaptercloud-cost",
1689
+ costUri,
1690
+ {
1691
+ title: "AdapterCloud Cost Summary",
1692
+ description: "Aggregate workspace spend grouped by cost service (FinOps headline).",
1693
+ mimeType: "application/json"
1694
+ },
1695
+ async () => {
1696
+ ctx.logger.debug(`Resource ${costUri} requested`);
1697
+ try {
1698
+ const data = await ctx.gql.workspace.request(COST_SUMMARY, {});
1699
+ return {
1700
+ contents: [
1701
+ {
1702
+ uri: costUri,
1703
+ text: JSON.stringify(data.adaCostSummary, null, 2),
1704
+ mimeType: "application/json"
1705
+ }
1706
+ ]
1707
+ };
1708
+ } catch (error) {
1709
+ return {
1710
+ contents: [
1711
+ {
1712
+ uri: costUri,
1713
+ text: JSON.stringify({
1714
+ error: error instanceof Error ? error.message : String(error)
1715
+ }),
1716
+ mimeType: "application/json"
1717
+ }
1718
+ ]
1719
+ };
1720
+ }
1721
+ }
1722
+ );
1723
+ }
1724
+ function registerAdaptercloudPrompts(server, ctx, track) {
1725
+ const p = ctx.productName;
1726
+ const onboardingName = track(mcpPromptName(p, "connection-onboarding"));
1727
+ const governanceName = track(mcpPromptName(p, "governance-sweep"));
1728
+ server.registerPrompt(
1729
+ onboardingName,
1730
+ {
1731
+ title: "Connection Onboarding",
1732
+ description: "Guide for connecting a new target system end to end: register an adapter, create a connection, run discovery, and review the discovered resources.",
1733
+ argsSchema: {
1734
+ adapterName: zod.z.string().optional().describe("Adapter / integration name"),
1735
+ kind: zod.z.string().optional().describe("Infrastructure kind (AdaAdapterKind)")
1736
+ }
1737
+ },
1738
+ ({ adapterName, kind }) => {
1739
+ ctx.logger.debug(`Prompt ${onboardingName} called`, { adapterName, kind });
1740
+ const nameNote = adapterName ? `Use the adapter name "${adapterName}".` : "Ask the user for the adapter / integration name.";
1741
+ const kindNote = kind ? `Use kind ${kind}.` : "Help the user pick an AdaAdapterKind.";
1742
+ return {
1743
+ messages: [
1744
+ {
1745
+ role: "user",
1746
+ content: {
1747
+ type: "text",
1748
+ text: `Help me connect a new target system to AdapterCloud.
1749
+
1750
+ 1. **Register Adapter**: Use ${p}_adapters_create. ${nameNote} ${kindNote} Provide a unique slug; optionally a configSchema and capabilities.
1751
+ 2. **Publish Adapter**: Use ${p}_adapters_update with status=PUBLISHED when the definition is ready.
1752
+ 3. **Create Connection**: Use ${p}_connections_create with the new adapterId, an authMethod, environment/region, and a secretRef (never inline secrets).
1753
+ 4. **Run Discovery**: Use ${p}_sync_start with the connectionId and kind=DISCOVERY, then poll ${p}_sync_get until status=SUCCEEDED.
1754
+ 5. **Review Resources**: Use ${p}_resources_list filtered by the new connectionId; inspect state and monthlyCost.
1755
+ 6. **Map Topology (optional)**: Use ${p}_topology_create_edge to record dependencies between discovered resources.
1756
+
1757
+ Show results at each step and confirm before running discovery.`
1758
+ }
1759
+ }
1760
+ ]
1761
+ };
1762
+ }
1763
+ );
1764
+ server.registerPrompt(
1765
+ governanceName,
1766
+ {
1767
+ title: "Governance Sweep",
1768
+ description: "Governance + FinOps review workflow: check connection health, triage drift and open violations, resolve/waive them, and review spend.",
1769
+ argsSchema: {
1770
+ connectionId: zod.z.string().optional().describe("Connection ID to scope the sweep")
1771
+ }
1772
+ },
1773
+ ({ connectionId }) => {
1774
+ ctx.logger.debug(`Prompt ${governanceName} called`, { connectionId });
1775
+ const scopeNote = connectionId ? `Scope the sweep to connection "${connectionId}".` : `First list connections with ${p}_connections_list and pick one (or sweep the whole workspace).`;
1776
+ return {
1777
+ messages: [
1778
+ {
1779
+ role: "user",
1780
+ content: {
1781
+ type: "text",
1782
+ text: `Run an AdapterCloud governance + FinOps sweep. ${scopeNote}
1783
+
1784
+ 1. **Connection Health**: Use ${p}_connections_list and flag any DEGRADED / ERROR connections.
1785
+ 2. **Drift**: Use ${p}_drift_list filtered by status=DETECTED. For each remediated item use ${p}_drift_remediate.
1786
+ 3. **Violations**: Use ${p}_violations_list filtered by status=OPEN. Resolve each with ${p}_violations_resolve (status=RESOLVED, or WAIVED with a waiverReason).
1787
+ 4. **Policies**: Use ${p}_policies_list to confirm the active guardrails; tighten enforcement with ${p}_policies_update if needed.
1788
+ 5. **Cost**: Use ${p}_cost_summary for headline spend by service, then ${p}_cost_list to drill into a specific service.
1789
+
1790
+ Summarize what needs attention after each step.`
1791
+ }
1792
+ }
1793
+ ]
1794
+ };
1795
+ }
1796
+ );
1797
+ }
1798
+
1799
+ // src/modules/adaptercloud/index.ts
1800
+ var adaptercloudModule = {
1801
+ id: "adaptercloud",
1802
+ version: "0.0.1",
1803
+ displayName: "AdapterCloud",
1804
+ dependsOn: ["auth"],
1805
+ capabilities: { tools: {}, resources: {}, prompts: {} },
1806
+ register(server, ctx) {
1807
+ const tools = [];
1808
+ const resources = [];
1809
+ const prompts = [];
1810
+ const trackTool = (n) => {
1811
+ tools.push(n);
1812
+ return n;
1813
+ };
1814
+ const trackResource = (uri) => {
1815
+ resources.push(uri);
1816
+ return uri;
1817
+ };
1818
+ const trackPrompt = (n) => {
1819
+ prompts.push(n);
1820
+ return n;
1821
+ };
1822
+ registerAdapterTools(server, ctx, trackTool);
1823
+ registerConnectionTools(server, ctx, trackTool);
1824
+ registerResourceTools(server, ctx, trackTool);
1825
+ registerTopologyTools(server, ctx, trackTool);
1826
+ registerPolicyTools(server, ctx, trackTool);
1827
+ registerViolationTools(server, ctx, trackTool);
1828
+ registerDriftTools(server, ctx, trackTool);
1829
+ registerSyncTools(server, ctx, trackTool);
1830
+ registerCostTools(server, ctx, trackTool);
1831
+ registerHealthTools(server, ctx, trackTool);
1832
+ registerAdaptercloudResources(server, ctx, trackResource);
1833
+ registerAdaptercloudPrompts(server, ctx, trackPrompt);
1834
+ return { tools, resources, prompts };
1835
+ }
1836
+ };
1837
+ var adaptercloud_default = adaptercloudModule;
1838
+
1839
+ module.exports = adaptercloud_default;
1840
+ //# sourceMappingURL=index.cjs.map
1841
+ //# sourceMappingURL=index.cjs.map