@burdenoff/mcp-libs 2026.627.6 → 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,2037 @@
1
+ 'use strict';
2
+
3
+ require('graphql-request');
4
+ require('cross-fetch');
5
+ require('@modelcontextprotocol/sdk/server/mcp.js');
6
+ require('@modelcontextprotocol/sdk/types.js');
7
+ var zod = require('zod');
8
+
9
+ // src/core/auth/store.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/subscriberbot/operations.ts
66
+ var PROVIDER_FIELDS = `
67
+ id name slug description category status industry region language
68
+ logoFileId websiteUrl tags churnRiskScore vendorHealthScore
69
+ workspaceId createdAt updatedAt
70
+ `;
71
+ var PLAN_FIELDS = `
72
+ id name description amount currency interval features isActive
73
+ providerId workspaceId createdAt updatedAt
74
+ `;
75
+ var ENTITLEMENT_FIELDS = `
76
+ id name description type quota used unit isActive
77
+ relationshipId workspaceId createdAt updatedAt
78
+ `;
79
+ var ASSET_FIELDS = `
80
+ id name type secretRef expiresAt relationshipId workspaceId
81
+ createdAt updatedAt file { id }
82
+ `;
83
+ var RENEWAL_EVENT_FIELDS = `
84
+ id eventType detail amount currency occursAt notified
85
+ relationshipId workspaceId createdAt updatedAt
86
+ `;
87
+ var RELATIONSHIP_FIELDS = `
88
+ id label kind status amount currency interval autoRenew discoverySource
89
+ healthScore notes tags providerId planId ownerId startedAt renewsAt
90
+ trialEndsAt cancelledAt workspaceId createdAt updatedAt
91
+ `;
92
+ var PAYMENT_INSTRUMENT_FIELDS = `
93
+ id label type status brand last4 expiryMonth expiryYear isDefault
94
+ ownerId workspaceId createdAt updatedAt
95
+ `;
96
+ var INVOICE_FIELDS = `
97
+ id number status currency subtotal taxAmount total issueDate dueDate
98
+ paidAt lineItems paymentInstrumentId relationshipId workspaceId
99
+ createdAt updatedAt file { id }
100
+ `;
101
+ var CHANNEL_FIELDS = `
102
+ id type status address label ingestEnabled verifiedAt
103
+ ownerId workspaceId createdAt updatedAt
104
+ `;
105
+ var INBOX_MESSAGE_FIELDS = `
106
+ id subject preview category categoryConfidence actionRequired isRead
107
+ externalId receivedAt channelId relationshipId workspaceId
108
+ createdAt updatedAt
109
+ `;
110
+ var AGENT_FIELDS = `
111
+ id name description kind status config lastRunAt
112
+ ownerId workspaceId createdAt updatedAt
113
+ `;
114
+ var POLICY_FIELDS = `
115
+ id name description action condition isEnabled triggerCount
116
+ lastTriggeredAt agentId workspaceId createdAt updatedAt
117
+ `;
118
+ var WORKFLOW_FIELDS = `
119
+ id name description status triggerEvent steps runCount lastRunAt
120
+ workspaceId createdAt updatedAt
121
+ `;
122
+ var GET_PROVIDER = `
123
+ query SubscriberbotGetProvider($id: ID!) {
124
+ subProvider(id: $id) {
125
+ ${PROVIDER_FIELDS}
126
+ plans { ${PLAN_FIELDS} }
127
+ }
128
+ }
129
+ `;
130
+ var LIST_PROVIDERS = `
131
+ query SubscriberbotListProviders(
132
+ $category: SubProviderCategory
133
+ $status: SubProviderStatus
134
+ $search: String
135
+ $pagination: PaginationInput
136
+ ) {
137
+ subListProviders(
138
+ category: $category
139
+ status: $status
140
+ search: $search
141
+ pagination: $pagination
142
+ ) {
143
+ items { ${PROVIDER_FIELDS} }
144
+ pageInfo { cursor hasMore }
145
+ }
146
+ }
147
+ `;
148
+ var CREATE_PROVIDER = `
149
+ mutation SubscriberbotCreateProvider($input: SubCreateProviderInput!) {
150
+ subCreateProvider(input: $input) {
151
+ ${PROVIDER_FIELDS}
152
+ }
153
+ }
154
+ `;
155
+ var UPDATE_PROVIDER = `
156
+ mutation SubscriberbotUpdateProvider($id: ID!, $input: SubUpdateProviderInput!) {
157
+ subUpdateProvider(id: $id, input: $input) {
158
+ ${PROVIDER_FIELDS}
159
+ }
160
+ }
161
+ `;
162
+ var ARCHIVE_PROVIDER = `
163
+ mutation SubscriberbotArchiveProvider($id: ID!) {
164
+ subArchiveProvider(id: $id)
165
+ }
166
+ `;
167
+ var LIST_PLANS = `
168
+ query SubscriberbotListPlans($providerId: ID) {
169
+ subListPlans(providerId: $providerId) {
170
+ ${PLAN_FIELDS}
171
+ }
172
+ }
173
+ `;
174
+ var CREATE_PLAN = `
175
+ mutation SubscriberbotCreatePlan($input: SubCreatePlanInput!) {
176
+ subCreatePlan(input: $input) {
177
+ ${PLAN_FIELDS}
178
+ }
179
+ }
180
+ `;
181
+ var GET_RELATIONSHIP = `
182
+ query SubscriberbotGetRelationship($id: ID!) {
183
+ subRelationship(id: $id) {
184
+ ${RELATIONSHIP_FIELDS}
185
+ provider { id name slug category status }
186
+ plan { id name amount currency interval }
187
+ entitlements { ${ENTITLEMENT_FIELDS} }
188
+ assets { ${ASSET_FIELDS} }
189
+ renewalEvents { ${RENEWAL_EVENT_FIELDS} }
190
+ }
191
+ }
192
+ `;
193
+ var LIST_RELATIONSHIPS = `
194
+ query SubscriberbotListRelationships(
195
+ $kind: SubRelationshipKind
196
+ $status: SubRelationshipStatus
197
+ $ownerId: ID
198
+ $providerId: ID
199
+ $pagination: PaginationInput
200
+ ) {
201
+ subListRelationships(
202
+ kind: $kind
203
+ status: $status
204
+ ownerId: $ownerId
205
+ providerId: $providerId
206
+ pagination: $pagination
207
+ ) {
208
+ items { ${RELATIONSHIP_FIELDS} }
209
+ pageInfo { cursor hasMore }
210
+ }
211
+ }
212
+ `;
213
+ var CREATE_RELATIONSHIP = `
214
+ mutation SubscriberbotCreateRelationship($input: SubCreateRelationshipInput!) {
215
+ subCreateRelationship(input: $input) {
216
+ ${RELATIONSHIP_FIELDS}
217
+ }
218
+ }
219
+ `;
220
+ var UPDATE_RELATIONSHIP = `
221
+ mutation SubscriberbotUpdateRelationship($id: ID!, $input: SubUpdateRelationshipInput!) {
222
+ subUpdateRelationship(id: $id, input: $input) {
223
+ ${RELATIONSHIP_FIELDS}
224
+ }
225
+ }
226
+ `;
227
+ var CANCEL_RELATIONSHIP = `
228
+ mutation SubscriberbotCancelRelationship($id: ID!) {
229
+ subCancelRelationship(id: $id) {
230
+ ${RELATIONSHIP_FIELDS}
231
+ }
232
+ }
233
+ `;
234
+ var TRANSITION_RELATIONSHIP = `
235
+ mutation SubscriberbotTransitionRelationship($id: ID!, $status: SubRelationshipStatus!) {
236
+ subTransitionRelationship(id: $id, status: $status) {
237
+ ${RELATIONSHIP_FIELDS}
238
+ }
239
+ }
240
+ `;
241
+ var LIST_ENTITLEMENTS = `
242
+ query SubscriberbotListEntitlements($relationshipId: ID!) {
243
+ subListEntitlements(relationshipId: $relationshipId) {
244
+ ${ENTITLEMENT_FIELDS}
245
+ }
246
+ }
247
+ `;
248
+ var CREATE_ENTITLEMENT = `
249
+ mutation SubscriberbotCreateEntitlement($input: SubCreateEntitlementInput!) {
250
+ subCreateEntitlement(input: $input) {
251
+ ${ENTITLEMENT_FIELDS}
252
+ }
253
+ }
254
+ `;
255
+ var LIST_ASSETS = `
256
+ query SubscriberbotListAssets($relationshipId: ID!) {
257
+ subListAssets(relationshipId: $relationshipId) {
258
+ ${ASSET_FIELDS}
259
+ }
260
+ }
261
+ `;
262
+ var CREATE_ASSET = `
263
+ mutation SubscriberbotCreateAsset($input: SubCreateAssetInput!) {
264
+ subCreateAsset(input: $input) {
265
+ ${ASSET_FIELDS}
266
+ }
267
+ }
268
+ `;
269
+ var LIST_RENEWAL_EVENTS = `
270
+ query SubscriberbotListRenewalEvents($relationshipId: ID, $upcomingOnly: Boolean) {
271
+ subListRenewalEvents(relationshipId: $relationshipId, upcomingOnly: $upcomingOnly) {
272
+ ${RENEWAL_EVENT_FIELDS}
273
+ }
274
+ }
275
+ `;
276
+ var LIST_PAYMENT_INSTRUMENTS = `
277
+ query SubscriberbotListPaymentInstruments($ownerId: ID) {
278
+ subListPaymentInstruments(ownerId: $ownerId) {
279
+ ${PAYMENT_INSTRUMENT_FIELDS}
280
+ }
281
+ }
282
+ `;
283
+ var CREATE_PAYMENT_INSTRUMENT = `
284
+ mutation SubscriberbotCreatePaymentInstrument($input: SubCreatePaymentInstrumentInput!) {
285
+ subCreatePaymentInstrument(input: $input) {
286
+ ${PAYMENT_INSTRUMENT_FIELDS}
287
+ }
288
+ }
289
+ `;
290
+ var REMOVE_PAYMENT_INSTRUMENT = `
291
+ mutation SubscriberbotRemovePaymentInstrument($id: ID!) {
292
+ subRemovePaymentInstrument(id: $id)
293
+ }
294
+ `;
295
+ var LIST_INVOICES = `
296
+ query SubscriberbotListInvoices(
297
+ $relationshipId: ID
298
+ $status: SubInvoiceStatus
299
+ $pagination: PaginationInput
300
+ ) {
301
+ subListInvoices(relationshipId: $relationshipId, status: $status, pagination: $pagination) {
302
+ items { ${INVOICE_FIELDS} }
303
+ pageInfo { cursor hasMore }
304
+ }
305
+ }
306
+ `;
307
+ var CREATE_INVOICE = `
308
+ mutation SubscriberbotCreateInvoice($input: SubCreateInvoiceInput!) {
309
+ subCreateInvoice(input: $input) {
310
+ ${INVOICE_FIELDS}
311
+ }
312
+ }
313
+ `;
314
+ var MARK_INVOICE_PAID = `
315
+ mutation SubscriberbotMarkInvoicePaid($id: ID!) {
316
+ subMarkInvoicePaid(id: $id) {
317
+ ${INVOICE_FIELDS}
318
+ }
319
+ }
320
+ `;
321
+ var LIST_CHANNELS = `
322
+ query SubscriberbotListChannels($ownerId: ID) {
323
+ subListChannels(ownerId: $ownerId) {
324
+ ${CHANNEL_FIELDS}
325
+ }
326
+ }
327
+ `;
328
+ var CREATE_CHANNEL = `
329
+ mutation SubscriberbotCreateChannel($input: SubCreateChannelInput!) {
330
+ subCreateChannel(input: $input) {
331
+ ${CHANNEL_FIELDS}
332
+ }
333
+ }
334
+ `;
335
+ var VERIFY_CHANNEL = `
336
+ mutation SubscriberbotVerifyChannel($id: ID!) {
337
+ subVerifyChannel(id: $id) {
338
+ ${CHANNEL_FIELDS}
339
+ }
340
+ }
341
+ `;
342
+ var LIST_INBOX_MESSAGES = `
343
+ query SubscriberbotListInboxMessages(
344
+ $category: SubMessageCategory
345
+ $channelId: ID
346
+ $relationshipId: ID
347
+ $unreadOnly: Boolean
348
+ $pagination: PaginationInput
349
+ ) {
350
+ subListInboxMessages(
351
+ category: $category
352
+ channelId: $channelId
353
+ relationshipId: $relationshipId
354
+ unreadOnly: $unreadOnly
355
+ pagination: $pagination
356
+ ) {
357
+ items { ${INBOX_MESSAGE_FIELDS} }
358
+ pageInfo { cursor hasMore }
359
+ }
360
+ }
361
+ `;
362
+ var INGEST_MESSAGE = `
363
+ mutation SubscriberbotIngestMessage($input: SubIngestMessageInput!) {
364
+ subIngestMessage(input: $input) {
365
+ ${INBOX_MESSAGE_FIELDS}
366
+ }
367
+ }
368
+ `;
369
+ var MARK_MESSAGE_READ = `
370
+ mutation SubscriberbotMarkMessageRead($id: ID!) {
371
+ subMarkMessageRead(id: $id) {
372
+ ${INBOX_MESSAGE_FIELDS}
373
+ }
374
+ }
375
+ `;
376
+ var GET_AGENT = `
377
+ query SubscriberbotGetAgent($id: ID!) {
378
+ subAgent(id: $id) {
379
+ ${AGENT_FIELDS}
380
+ policies { ${POLICY_FIELDS} }
381
+ }
382
+ }
383
+ `;
384
+ var LIST_AGENTS = `
385
+ query SubscriberbotListAgents($kind: SubAgentKind, $ownerId: ID, $status: SubAgentStatus) {
386
+ subListAgents(kind: $kind, ownerId: $ownerId, status: $status) {
387
+ ${AGENT_FIELDS}
388
+ }
389
+ }
390
+ `;
391
+ var CREATE_AGENT = `
392
+ mutation SubscriberbotCreateAgent($input: SubCreateAgentInput!) {
393
+ subCreateAgent(input: $input) {
394
+ ${AGENT_FIELDS}
395
+ }
396
+ }
397
+ `;
398
+ var SET_AGENT_STATUS = `
399
+ mutation SubscriberbotSetAgentStatus($id: ID!, $status: SubAgentStatus!) {
400
+ subSetAgentStatus(id: $id, status: $status) {
401
+ ${AGENT_FIELDS}
402
+ }
403
+ }
404
+ `;
405
+ var LIST_POLICIES = `
406
+ query SubscriberbotListPolicies($agentId: ID) {
407
+ subListPolicies(agentId: $agentId) {
408
+ ${POLICY_FIELDS}
409
+ }
410
+ }
411
+ `;
412
+ var CREATE_POLICY = `
413
+ mutation SubscriberbotCreatePolicy($input: SubCreatePolicyInput!) {
414
+ subCreatePolicy(input: $input) {
415
+ ${POLICY_FIELDS}
416
+ }
417
+ }
418
+ `;
419
+ var LIST_WORKFLOWS = `
420
+ query SubscriberbotListWorkflows($status: SubWorkflowStatus) {
421
+ subListWorkflows(status: $status) {
422
+ ${WORKFLOW_FIELDS}
423
+ }
424
+ }
425
+ `;
426
+ var CREATE_WORKFLOW = `
427
+ mutation SubscriberbotCreateWorkflow($input: SubCreateWorkflowInput!) {
428
+ subCreateWorkflow(input: $input) {
429
+ ${WORKFLOW_FIELDS}
430
+ }
431
+ }
432
+ `;
433
+ var ACTIVATE_WORKFLOW = `
434
+ mutation SubscriberbotActivateWorkflow($id: ID!) {
435
+ subActivateWorkflow(id: $id) {
436
+ ${WORKFLOW_FIELDS}
437
+ }
438
+ }
439
+ `;
440
+ var HEALTH = `
441
+ query SubscriberbotHealth {
442
+ subHealth
443
+ }
444
+ `;
445
+ var SubAgentKindEnum = zod.z.enum([
446
+ "COMPLIANCE",
447
+ "CONCIERGE",
448
+ "COST",
449
+ "DISCOVERY",
450
+ "MIGRATION",
451
+ "NEGOTIATION",
452
+ "NEWSLETTER",
453
+ "RENEWAL",
454
+ "VENDOR"
455
+ ]).describe("The specialised role of an AI agent");
456
+ var SubAgentStatusEnum = zod.z.enum(["AUTONOMOUS", "DISABLED", "SUGGEST_ONLY"]).describe("An agent's operating posture");
457
+ var SubAssetTypeEnum = zod.z.enum([
458
+ "CERTIFICATE",
459
+ "CONTRACT",
460
+ "CREDENTIAL",
461
+ "DOMAIN",
462
+ "INVOICE",
463
+ "LICENSE_KEY",
464
+ "RECEIPT",
465
+ "WARRANTY"
466
+ ]).describe("The kind of asset attached to a relationship");
467
+ var SubBillingIntervalEnum = zod.z.enum(["DAILY", "FREE", "LIFETIME", "MONTHLY", "QUARTERLY", "USAGE_BASED", "WEEKLY", "YEARLY"]).describe("Billing cadence of a plan or relationship");
468
+ zod.z.enum(["DISABLED", "PENDING", "VERIFIED"]).describe("Verification status of a communication channel");
469
+ var SubChannelTypeEnum = zod.z.enum(["DISCORD", "EMAIL", "PUSH", "SLACK", "SMS", "WEBHOOK", "WHATSAPP"]).describe("Transport type of a communication channel");
470
+ var SubDiscoverySourceEnum = zod.z.enum(["AI_AGENT", "EMAIL_SCAN", "IMPORT", "MANUAL", "PAYMENT_SCAN", "PROVIDER_CONNECT"]).describe("How a relationship was discovered");
471
+ var SubEntitlementTypeEnum = zod.z.enum(["CONTENT", "DISCOUNT", "FEATURE_ACCESS", "SEAT", "SUPPORT_TIER", "USAGE_QUOTA"]).describe("The kind of entitlement granted by a relationship");
472
+ var SubInvoiceStatusEnum = zod.z.enum(["CANCELLED", "DRAFT", "FAILED", "ISSUED", "OVERDUE", "PAID", "REFUNDED"]).describe("Lifecycle status of an invoice");
473
+ var SubMessageCategoryEnum = zod.z.enum([
474
+ "BILLING",
475
+ "MARKETING",
476
+ "OTHER",
477
+ "PRODUCT_UPDATE",
478
+ "RENEWAL",
479
+ "REQUIRED_ACTION",
480
+ "SECURITY_ALERT"
481
+ ]).describe("Classification of a universal-inbox message");
482
+ zod.z.enum(["ACTIVE", "EXPIRED", "EXPIRING", "REMOVED"]).describe("Status of a payment instrument");
483
+ var SubPaymentInstrumentTypeEnum = zod.z.enum(["BANK_ACCOUNT", "CARD", "OTHER", "PAYPAL", "UPI", "WALLET"]).describe("Type of a payment instrument");
484
+ var SubPolicyActionEnum = zod.z.enum(["ALERT", "CANCEL", "CREATE_TASK", "DOWNGRADE", "PAUSE", "RENEW", "UPGRADE"]).describe("The action an autonomous policy takes when triggered");
485
+ var SubProviderCategoryEnum = zod.z.enum([
486
+ "AI_SERVICE",
487
+ "ASSOCIATION",
488
+ "COMMUNITY",
489
+ "CONTRACT",
490
+ "EDUCATION",
491
+ "FINANCIAL",
492
+ "INSURANCE",
493
+ "LICENSE",
494
+ "MEMBERSHIP",
495
+ "NEWSLETTER",
496
+ "NEWS_DIGEST",
497
+ "OTHER",
498
+ "SAAS",
499
+ "STREAMING",
500
+ "TELECOM",
501
+ "UTILITY"
502
+ ]).describe("Category of a provider in the global registry");
503
+ var SubProviderStatusEnum = zod.z.enum(["CLAIMED", "DEPRECATED", "UNVERIFIED", "VERIFIED"]).describe("Lifecycle/trust status of a provider");
504
+ var SubRelationshipKindEnum = zod.z.enum([
505
+ "CONTRACT",
506
+ "ENROLLMENT",
507
+ "LICENSE",
508
+ "MEMBERSHIP",
509
+ "NEWSLETTER",
510
+ "RECURRING_PAYMENT",
511
+ "SUBSCRIPTION",
512
+ "TRIAL"
513
+ ]).describe("The kind of recurring relationship");
514
+ var SubRelationshipStatusEnum = zod.z.enum(["ACTIVE", "CANCELLED", "EXPIRED", "LAPSED", "PAST_DUE", "PAUSED", "TRIAL"]).describe("Lifecycle status of a relationship");
515
+ var SubWorkflowStatusEnum = zod.z.enum(["ACTIVE", "ARCHIVED", "DRAFT", "PAUSED"]).describe("Lifecycle status of an automation workflow");
516
+ var JsonObject = zod.z.record(zod.z.string(), zod.z.unknown());
517
+ var JsonValue = zod.z.union([JsonObject, zod.z.array(zod.z.unknown())]);
518
+ function registerProviderTools(server, ctx, track) {
519
+ server.registerTool(
520
+ track(mcpToolName(ctx.productName, "providers_get")),
521
+ {
522
+ title: "Get Provider",
523
+ description: "Fetch a single provider from the global registry by ID, including its plans.",
524
+ inputSchema: { id: zod.z.string().describe("Provider ID") }
525
+ },
526
+ async ({ id }) => {
527
+ try {
528
+ const data = await ctx.gql.workspace.request(GET_PROVIDER, { id });
529
+ if (!data.subProvider) return errorResult(`Provider ${id} not found`);
530
+ return jsonResult(data.subProvider);
531
+ } catch (error) {
532
+ ctx.logger.error("subscriberbot providers_get failed", { error: String(error) });
533
+ return errorResult(
534
+ `Failed to get provider: ${error instanceof Error ? error.message : String(error)}`
535
+ );
536
+ }
537
+ }
538
+ );
539
+ server.registerTool(
540
+ track(mcpToolName(ctx.productName, "providers_list")),
541
+ {
542
+ title: "List Providers",
543
+ description: "Discovery: search/browse the global provider registry with optional category/status/text filters and pagination. Returns a connection ({ items, pageInfo }).",
544
+ inputSchema: {
545
+ category: SubProviderCategoryEnum.optional().describe("Filter by category"),
546
+ status: SubProviderStatusEnum.optional().describe("Filter by trust/lifecycle status"),
547
+ search: zod.z.string().optional().describe("Free-text search across provider name/description"),
548
+ limit: zod.z.number().int().optional().describe("Page size (default 50)"),
549
+ offset: zod.z.number().int().optional().describe("Pagination offset (default 0)"),
550
+ cursor: zod.z.string().optional().describe("Opaque pagination cursor")
551
+ }
552
+ },
553
+ async ({ category, status, search, limit, offset, cursor }) => {
554
+ try {
555
+ const pagination = {};
556
+ if (limit !== void 0) pagination.limit = limit;
557
+ if (offset !== void 0) pagination.offset = offset;
558
+ if (cursor !== void 0) pagination.cursor = cursor;
559
+ const data = await ctx.gql.workspace.request(
560
+ LIST_PROVIDERS,
561
+ {
562
+ category,
563
+ status,
564
+ search,
565
+ pagination: Object.keys(pagination).length > 0 ? pagination : void 0
566
+ }
567
+ );
568
+ return jsonResult(data.subListProviders);
569
+ } catch (error) {
570
+ ctx.logger.error("subscriberbot providers_list failed", { error: String(error) });
571
+ return errorResult(
572
+ `Failed to list providers: ${error instanceof Error ? error.message : String(error)}`
573
+ );
574
+ }
575
+ }
576
+ );
577
+ server.registerTool(
578
+ track(mcpToolName(ctx.productName, "providers_create")),
579
+ {
580
+ title: "Create Provider",
581
+ description: "Register a new provider in the global registry. Only `name` is required; `slug` should be unique within the workspace.",
582
+ inputSchema: {
583
+ name: zod.z.string().min(1).describe("Provider display name"),
584
+ slug: zod.z.string().optional().describe("URL slug, unique within the workspace"),
585
+ category: SubProviderCategoryEnum.optional().describe("Provider category (default OTHER)"),
586
+ status: SubProviderStatusEnum.optional().describe(
587
+ "Trust/lifecycle status (default UNVERIFIED)"
588
+ ),
589
+ description: zod.z.string().optional().describe("Provider description"),
590
+ industry: zod.z.string().optional().describe("Industry"),
591
+ region: zod.z.string().optional().describe("Region"),
592
+ language: zod.z.string().optional().describe("Primary language"),
593
+ websiteUrl: zod.z.string().optional().describe("Provider website URL"),
594
+ logoFileId: zod.z.string().optional().describe("wspace-files-svc File ID for the logo"),
595
+ tags: zod.z.array(zod.z.string()).optional().describe("Free-form tags")
596
+ }
597
+ },
598
+ async ({
599
+ name,
600
+ slug,
601
+ category,
602
+ status,
603
+ description,
604
+ industry,
605
+ region,
606
+ language,
607
+ websiteUrl,
608
+ logoFileId,
609
+ tags
610
+ }) => {
611
+ try {
612
+ const input = { name };
613
+ if (slug !== void 0) input.slug = slug;
614
+ if (category !== void 0) input.category = category;
615
+ if (status !== void 0) input.status = status;
616
+ if (description !== void 0) input.description = description;
617
+ if (industry !== void 0) input.industry = industry;
618
+ if (region !== void 0) input.region = region;
619
+ if (language !== void 0) input.language = language;
620
+ if (websiteUrl !== void 0) input.websiteUrl = websiteUrl;
621
+ if (logoFileId !== void 0) input.logoFileId = logoFileId;
622
+ if (tags !== void 0) input.tags = tags;
623
+ const data = await ctx.gql.workspace.request(CREATE_PROVIDER, { input });
624
+ return jsonResult(data.subCreateProvider);
625
+ } catch (error) {
626
+ ctx.logger.error("subscriberbot providers_create failed", { error: String(error) });
627
+ return errorResult(
628
+ `Failed to create provider: ${error instanceof Error ? error.message : String(error)}`
629
+ );
630
+ }
631
+ }
632
+ );
633
+ server.registerTool(
634
+ track(mcpToolName(ctx.productName, "providers_update")),
635
+ {
636
+ title: "Update Provider",
637
+ description: "Update a provider. At least one mutable field must be provided. Use `status` to verify/claim/deprecate; set churn/vendor-health scores for vendor intelligence.",
638
+ inputSchema: {
639
+ id: zod.z.string().describe("Provider ID"),
640
+ name: zod.z.string().optional().describe("Updated display name"),
641
+ slug: zod.z.string().optional().describe("Updated slug"),
642
+ category: SubProviderCategoryEnum.optional().describe("Updated category"),
643
+ status: SubProviderStatusEnum.optional().describe("Updated trust/lifecycle status"),
644
+ description: zod.z.string().optional().describe("Updated description"),
645
+ industry: zod.z.string().optional().describe("Updated industry"),
646
+ region: zod.z.string().optional().describe("Updated region"),
647
+ language: zod.z.string().optional().describe("Updated language"),
648
+ websiteUrl: zod.z.string().optional().describe("Updated website URL"),
649
+ logoFileId: zod.z.string().optional().describe("Updated logo File ID"),
650
+ tags: zod.z.array(zod.z.string()).optional().describe("Updated tags"),
651
+ churnRiskScore: zod.z.number().int().optional().describe("Churn-risk score (0-100)"),
652
+ vendorHealthScore: zod.z.number().int().optional().describe("Vendor-health score (0-100)")
653
+ }
654
+ },
655
+ async ({
656
+ id,
657
+ name,
658
+ slug,
659
+ category,
660
+ status,
661
+ description,
662
+ industry,
663
+ region,
664
+ language,
665
+ websiteUrl,
666
+ logoFileId,
667
+ tags,
668
+ churnRiskScore,
669
+ vendorHealthScore
670
+ }) => {
671
+ try {
672
+ const input = {};
673
+ if (name !== void 0) input.name = name;
674
+ if (slug !== void 0) input.slug = slug;
675
+ if (category !== void 0) input.category = category;
676
+ if (status !== void 0) input.status = status;
677
+ if (description !== void 0) input.description = description;
678
+ if (industry !== void 0) input.industry = industry;
679
+ if (region !== void 0) input.region = region;
680
+ if (language !== void 0) input.language = language;
681
+ if (websiteUrl !== void 0) input.websiteUrl = websiteUrl;
682
+ if (logoFileId !== void 0) input.logoFileId = logoFileId;
683
+ if (tags !== void 0) input.tags = tags;
684
+ if (churnRiskScore !== void 0) input.churnRiskScore = churnRiskScore;
685
+ if (vendorHealthScore !== void 0) input.vendorHealthScore = vendorHealthScore;
686
+ if (Object.keys(input).length === 0) {
687
+ return errorResult("No updates specified \u2014 provide at least one mutable provider field");
688
+ }
689
+ const data = await ctx.gql.workspace.request(UPDATE_PROVIDER, { id, input });
690
+ return jsonResult(data.subUpdateProvider);
691
+ } catch (error) {
692
+ ctx.logger.error("subscriberbot providers_update failed", { error: String(error) });
693
+ return errorResult(
694
+ `Failed to update provider: ${error instanceof Error ? error.message : String(error)}`
695
+ );
696
+ }
697
+ }
698
+ );
699
+ server.registerTool(
700
+ track(mcpToolName(ctx.productName, "providers_archive")),
701
+ {
702
+ title: "Archive Provider",
703
+ description: "Archive (soft-delete) a provider. Returns true on success.",
704
+ inputSchema: { id: zod.z.string().describe("Provider ID") }
705
+ },
706
+ async ({ id }) => {
707
+ try {
708
+ const data = await ctx.gql.workspace.request(
709
+ ARCHIVE_PROVIDER,
710
+ { id }
711
+ );
712
+ return jsonResult({ archived: data.subArchiveProvider, id });
713
+ } catch (error) {
714
+ ctx.logger.error("subscriberbot providers_archive failed", { error: String(error) });
715
+ return errorResult(
716
+ `Failed to archive provider: ${error instanceof Error ? error.message : String(error)}`
717
+ );
718
+ }
719
+ }
720
+ );
721
+ }
722
+ function registerPlanTools(server, ctx, track) {
723
+ server.registerTool(
724
+ track(mcpToolName(ctx.productName, "plans_list")),
725
+ {
726
+ title: "List Plans",
727
+ description: "List plans, optionally filtered by provider.",
728
+ inputSchema: {
729
+ providerId: zod.z.string().optional().describe("Filter by provider ID")
730
+ }
731
+ },
732
+ async ({ providerId }) => {
733
+ try {
734
+ const data = await ctx.gql.workspace.request(LIST_PLANS, { providerId });
735
+ return jsonResult(data.subListPlans);
736
+ } catch (error) {
737
+ ctx.logger.error("subscriberbot plans_list failed", { error: String(error) });
738
+ return errorResult(
739
+ `Failed to list plans: ${error instanceof Error ? error.message : String(error)}`
740
+ );
741
+ }
742
+ }
743
+ );
744
+ server.registerTool(
745
+ track(mcpToolName(ctx.productName, "plans_create")),
746
+ {
747
+ title: "Create Plan",
748
+ description: "Create a plan for a provider.",
749
+ inputSchema: {
750
+ providerId: zod.z.string().min(1).describe("Provider ID this plan belongs to"),
751
+ name: zod.z.string().min(1).describe("Plan name"),
752
+ amount: zod.z.number().optional().describe("Plan amount"),
753
+ currency: zod.z.string().optional().describe("ISO currency code"),
754
+ interval: SubBillingIntervalEnum.optional().describe("Billing interval (default MONTHLY)"),
755
+ description: zod.z.string().optional().describe("Plan description"),
756
+ features: zod.z.array(zod.z.string()).optional().describe("Feature list")
757
+ }
758
+ },
759
+ async ({ providerId, name, amount, currency, interval, description, features }) => {
760
+ try {
761
+ const input = { providerId, name };
762
+ if (amount !== void 0) input.amount = amount;
763
+ if (currency !== void 0) input.currency = currency;
764
+ if (interval !== void 0) input.interval = interval;
765
+ if (description !== void 0) input.description = description;
766
+ if (features !== void 0) input.features = features;
767
+ const data = await ctx.gql.workspace.request(
768
+ CREATE_PLAN,
769
+ { input }
770
+ );
771
+ return jsonResult(data.subCreatePlan);
772
+ } catch (error) {
773
+ ctx.logger.error("subscriberbot plans_create failed", { error: String(error) });
774
+ return errorResult(
775
+ `Failed to create plan: ${error instanceof Error ? error.message : String(error)}`
776
+ );
777
+ }
778
+ }
779
+ );
780
+ }
781
+ function registerRelationshipTools(server, ctx, track) {
782
+ server.registerTool(
783
+ track(mcpToolName(ctx.productName, "relationships_get")),
784
+ {
785
+ title: "Get Relationship",
786
+ description: "Fetch a single relationship by ID, including its provider, plan, entitlements, assets, and renewal events.",
787
+ inputSchema: { id: zod.z.string().describe("Relationship ID") }
788
+ },
789
+ async ({ id }) => {
790
+ try {
791
+ const data = await ctx.gql.workspace.request(GET_RELATIONSHIP, { id });
792
+ if (!data.subRelationship) return errorResult(`Relationship ${id} not found`);
793
+ return jsonResult(data.subRelationship);
794
+ } catch (error) {
795
+ ctx.logger.error("subscriberbot relationships_get failed", { error: String(error) });
796
+ return errorResult(
797
+ `Failed to get relationship: ${error instanceof Error ? error.message : String(error)}`
798
+ );
799
+ }
800
+ }
801
+ );
802
+ server.registerTool(
803
+ track(mcpToolName(ctx.productName, "relationships_list")),
804
+ {
805
+ title: "List Relationships",
806
+ description: "List recurring relationships with optional kind/status/owner/provider filters and pagination. Returns a connection ({ items, pageInfo }).",
807
+ inputSchema: {
808
+ kind: SubRelationshipKindEnum.optional().describe("Filter by relationship kind"),
809
+ status: SubRelationshipStatusEnum.optional().describe("Filter by lifecycle status"),
810
+ ownerId: zod.z.string().optional().describe("Filter by owner user ID"),
811
+ providerId: zod.z.string().optional().describe("Filter by provider ID"),
812
+ limit: zod.z.number().int().optional().describe("Page size (default 50)"),
813
+ offset: zod.z.number().int().optional().describe("Pagination offset (default 0)"),
814
+ cursor: zod.z.string().optional().describe("Opaque pagination cursor")
815
+ }
816
+ },
817
+ async ({ kind, status, ownerId, providerId, limit, offset, cursor }) => {
818
+ try {
819
+ const pagination = {};
820
+ if (limit !== void 0) pagination.limit = limit;
821
+ if (offset !== void 0) pagination.offset = offset;
822
+ if (cursor !== void 0) pagination.cursor = cursor;
823
+ const data = await ctx.gql.workspace.request(
824
+ LIST_RELATIONSHIPS,
825
+ {
826
+ kind,
827
+ status,
828
+ ownerId,
829
+ providerId,
830
+ pagination: Object.keys(pagination).length > 0 ? pagination : void 0
831
+ }
832
+ );
833
+ return jsonResult(data.subListRelationships);
834
+ } catch (error) {
835
+ ctx.logger.error("subscriberbot relationships_list failed", { error: String(error) });
836
+ return errorResult(
837
+ `Failed to list relationships: ${error instanceof Error ? error.message : String(error)}`
838
+ );
839
+ }
840
+ }
841
+ );
842
+ server.registerTool(
843
+ track(mcpToolName(ctx.productName, "relationships_create")),
844
+ {
845
+ title: "Create Relationship",
846
+ description: "Create a recurring relationship (subscription / membership / license / contract). Only `label` is required.",
847
+ inputSchema: {
848
+ label: zod.z.string().min(1).describe("Human-readable label"),
849
+ kind: SubRelationshipKindEnum.optional().describe(
850
+ "Relationship kind (default SUBSCRIPTION)"
851
+ ),
852
+ status: SubRelationshipStatusEnum.optional().describe("Initial status (default ACTIVE)"),
853
+ providerId: zod.z.string().optional().describe("Provider ID"),
854
+ planId: zod.z.string().optional().describe("Plan ID"),
855
+ ownerId: zod.z.string().optional().describe("Owner user ID"),
856
+ amount: zod.z.number().optional().describe("Recurring amount"),
857
+ currency: zod.z.string().optional().describe("ISO currency code"),
858
+ interval: SubBillingIntervalEnum.optional().describe("Billing interval (default MONTHLY)"),
859
+ autoRenew: zod.z.boolean().optional().describe("Whether the relationship auto-renews (default true)"),
860
+ discoverySource: SubDiscoverySourceEnum.optional().describe(
861
+ "How it was discovered (default MANUAL)"
862
+ ),
863
+ notes: zod.z.string().optional().describe("Free-form notes"),
864
+ tags: zod.z.array(zod.z.string()).optional().describe("Tags"),
865
+ startedAt: zod.z.string().optional().describe("Start datetime (ISO 8601)"),
866
+ renewsAt: zod.z.string().optional().describe("Next renewal datetime (ISO 8601)"),
867
+ trialEndsAt: zod.z.string().optional().describe("Trial-end datetime (ISO 8601)")
868
+ }
869
+ },
870
+ async (args) => {
871
+ try {
872
+ const input = { label: args.label };
873
+ const optional = [
874
+ "kind",
875
+ "status",
876
+ "providerId",
877
+ "planId",
878
+ "ownerId",
879
+ "amount",
880
+ "currency",
881
+ "interval",
882
+ "autoRenew",
883
+ "discoverySource",
884
+ "notes",
885
+ "tags",
886
+ "startedAt",
887
+ "renewsAt",
888
+ "trialEndsAt"
889
+ ];
890
+ for (const key of optional) {
891
+ if (args[key] !== void 0) input[key] = args[key];
892
+ }
893
+ const data = await ctx.gql.workspace.request(CREATE_RELATIONSHIP, { input });
894
+ return jsonResult(data.subCreateRelationship);
895
+ } catch (error) {
896
+ ctx.logger.error("subscriberbot relationships_create failed", { error: String(error) });
897
+ return errorResult(
898
+ `Failed to create relationship: ${error instanceof Error ? error.message : String(error)}`
899
+ );
900
+ }
901
+ }
902
+ );
903
+ server.registerTool(
904
+ track(mcpToolName(ctx.productName, "relationships_update")),
905
+ {
906
+ title: "Update Relationship",
907
+ description: "Update a relationship. At least one mutable field must be provided.",
908
+ inputSchema: {
909
+ id: zod.z.string().describe("Relationship ID"),
910
+ label: zod.z.string().optional().describe("Updated label"),
911
+ kind: SubRelationshipKindEnum.optional().describe("Updated kind"),
912
+ providerId: zod.z.string().optional().describe("Updated provider ID"),
913
+ planId: zod.z.string().optional().describe("Updated plan ID"),
914
+ amount: zod.z.number().optional().describe("Updated amount"),
915
+ currency: zod.z.string().optional().describe("Updated currency"),
916
+ interval: SubBillingIntervalEnum.optional().describe("Updated billing interval"),
917
+ autoRenew: zod.z.boolean().optional().describe("Updated auto-renew flag"),
918
+ healthScore: zod.z.number().int().optional().describe("Relationship health score (0-100)"),
919
+ notes: zod.z.string().optional().describe("Updated notes"),
920
+ tags: zod.z.array(zod.z.string()).optional().describe("Updated tags"),
921
+ startedAt: zod.z.string().optional().describe("Updated start datetime (ISO 8601)"),
922
+ renewsAt: zod.z.string().optional().describe("Updated renewal datetime (ISO 8601)"),
923
+ trialEndsAt: zod.z.string().optional().describe("Updated trial-end datetime (ISO 8601)")
924
+ }
925
+ },
926
+ async ({ id, ...rest }) => {
927
+ try {
928
+ const input = {};
929
+ for (const [key, value] of Object.entries(rest)) {
930
+ if (value !== void 0) input[key] = value;
931
+ }
932
+ if (Object.keys(input).length === 0) {
933
+ return errorResult(
934
+ "No updates specified \u2014 provide at least one mutable relationship field"
935
+ );
936
+ }
937
+ const data = await ctx.gql.workspace.request(UPDATE_RELATIONSHIP, { id, input });
938
+ return jsonResult(data.subUpdateRelationship);
939
+ } catch (error) {
940
+ ctx.logger.error("subscriberbot relationships_update failed", { error: String(error) });
941
+ return errorResult(
942
+ `Failed to update relationship: ${error instanceof Error ? error.message : String(error)}`
943
+ );
944
+ }
945
+ }
946
+ );
947
+ server.registerTool(
948
+ track(mcpToolName(ctx.productName, "relationships_cancel")),
949
+ {
950
+ title: "Cancel Relationship",
951
+ description: "Cancel a relationship (sets status CANCELLED and stamps cancelledAt).",
952
+ inputSchema: { id: zod.z.string().describe("Relationship ID") }
953
+ },
954
+ async ({ id }) => {
955
+ try {
956
+ const data = await ctx.gql.workspace.request(CANCEL_RELATIONSHIP, { id });
957
+ return jsonResult(data.subCancelRelationship);
958
+ } catch (error) {
959
+ ctx.logger.error("subscriberbot relationships_cancel failed", { error: String(error) });
960
+ return errorResult(
961
+ `Failed to cancel relationship: ${error instanceof Error ? error.message : String(error)}`
962
+ );
963
+ }
964
+ }
965
+ );
966
+ server.registerTool(
967
+ track(mcpToolName(ctx.productName, "relationships_transition")),
968
+ {
969
+ title: "Transition Relationship",
970
+ description: "Advance a relationship through its lifecycle with a validated status transition.",
971
+ inputSchema: {
972
+ id: zod.z.string().describe("Relationship ID"),
973
+ status: SubRelationshipStatusEnum.describe("Target lifecycle status")
974
+ }
975
+ },
976
+ async ({ id, status }) => {
977
+ try {
978
+ const data = await ctx.gql.workspace.request(TRANSITION_RELATIONSHIP, { id, status });
979
+ return jsonResult(data.subTransitionRelationship);
980
+ } catch (error) {
981
+ ctx.logger.error("subscriberbot relationships_transition failed", { error: String(error) });
982
+ return errorResult(
983
+ `Failed to transition relationship: ${error instanceof Error ? error.message : String(error)}`
984
+ );
985
+ }
986
+ }
987
+ );
988
+ }
989
+ function registerEntitlementTools(server, ctx, track) {
990
+ server.registerTool(
991
+ track(mcpToolName(ctx.productName, "entitlements_list")),
992
+ {
993
+ title: "List Entitlements",
994
+ description: "List the entitlements granted by a relationship.",
995
+ inputSchema: { relationshipId: zod.z.string().describe("Relationship ID (required)") }
996
+ },
997
+ async ({ relationshipId }) => {
998
+ try {
999
+ const data = await ctx.gql.workspace.request(LIST_ENTITLEMENTS, { relationshipId });
1000
+ return jsonResult(data.subListEntitlements);
1001
+ } catch (error) {
1002
+ ctx.logger.error("subscriberbot entitlements_list failed", { error: String(error) });
1003
+ return errorResult(
1004
+ `Failed to list entitlements: ${error instanceof Error ? error.message : String(error)}`
1005
+ );
1006
+ }
1007
+ }
1008
+ );
1009
+ server.registerTool(
1010
+ track(mcpToolName(ctx.productName, "entitlements_create")),
1011
+ {
1012
+ title: "Create Entitlement",
1013
+ description: "Add an entitlement to a relationship.",
1014
+ inputSchema: {
1015
+ relationshipId: zod.z.string().min(1).describe("Relationship ID"),
1016
+ name: zod.z.string().min(1).describe("Entitlement name"),
1017
+ type: SubEntitlementTypeEnum.optional().describe(
1018
+ "Entitlement type (default FEATURE_ACCESS)"
1019
+ ),
1020
+ description: zod.z.string().optional().describe("Description"),
1021
+ quota: zod.z.number().int().optional().describe("Quota count"),
1022
+ unit: zod.z.string().optional().describe('Quota unit (e.g. "seats", "GB")')
1023
+ }
1024
+ },
1025
+ async ({ relationshipId, name, type, description, quota, unit }) => {
1026
+ try {
1027
+ const input = { relationshipId, name };
1028
+ if (type !== void 0) input.type = type;
1029
+ if (description !== void 0) input.description = description;
1030
+ if (quota !== void 0) input.quota = quota;
1031
+ if (unit !== void 0) input.unit = unit;
1032
+ const data = await ctx.gql.workspace.request(CREATE_ENTITLEMENT, { input });
1033
+ return jsonResult(data.subCreateEntitlement);
1034
+ } catch (error) {
1035
+ ctx.logger.error("subscriberbot entitlements_create failed", { error: String(error) });
1036
+ return errorResult(
1037
+ `Failed to create entitlement: ${error instanceof Error ? error.message : String(error)}`
1038
+ );
1039
+ }
1040
+ }
1041
+ );
1042
+ }
1043
+ function registerAssetTools(server, ctx, track) {
1044
+ server.registerTool(
1045
+ track(mcpToolName(ctx.productName, "assets_list")),
1046
+ {
1047
+ title: "List Assets",
1048
+ description: "List the assets attached to a relationship.",
1049
+ inputSchema: { relationshipId: zod.z.string().describe("Relationship ID (required)") }
1050
+ },
1051
+ async ({ relationshipId }) => {
1052
+ try {
1053
+ const data = await ctx.gql.workspace.request(LIST_ASSETS, { relationshipId });
1054
+ return jsonResult(data.subListAssets);
1055
+ } catch (error) {
1056
+ ctx.logger.error("subscriberbot assets_list failed", { error: String(error) });
1057
+ return errorResult(
1058
+ `Failed to list assets: ${error instanceof Error ? error.message : String(error)}`
1059
+ );
1060
+ }
1061
+ }
1062
+ );
1063
+ server.registerTool(
1064
+ track(mcpToolName(ctx.productName, "assets_create")),
1065
+ {
1066
+ title: "Create Asset",
1067
+ description: "Attach an asset to a relationship. `fileId` references a wspace-files-svc File; `secretRef` references a vault secret for credentials.",
1068
+ inputSchema: {
1069
+ relationshipId: zod.z.string().min(1).describe("Relationship ID"),
1070
+ name: zod.z.string().min(1).describe("Asset name"),
1071
+ type: SubAssetTypeEnum.optional().describe("Asset type (default RECEIPT)"),
1072
+ fileId: zod.z.string().optional().describe("wspace-files-svc File ID"),
1073
+ secretRef: zod.z.string().optional().describe("Vault secret reference for credentials"),
1074
+ expiresAt: zod.z.string().optional().describe("Expiry datetime (ISO 8601)")
1075
+ }
1076
+ },
1077
+ async ({ relationshipId, name, type, fileId, secretRef, expiresAt }) => {
1078
+ try {
1079
+ const input = { relationshipId, name };
1080
+ if (type !== void 0) input.type = type;
1081
+ if (fileId !== void 0) input.fileId = fileId;
1082
+ if (secretRef !== void 0) input.secretRef = secretRef;
1083
+ if (expiresAt !== void 0) input.expiresAt = expiresAt;
1084
+ const data = await ctx.gql.workspace.request(CREATE_ASSET, { input });
1085
+ return jsonResult(data.subCreateAsset);
1086
+ } catch (error) {
1087
+ ctx.logger.error("subscriberbot assets_create failed", { error: String(error) });
1088
+ return errorResult(
1089
+ `Failed to create asset: ${error instanceof Error ? error.message : String(error)}`
1090
+ );
1091
+ }
1092
+ }
1093
+ );
1094
+ }
1095
+ function registerRenewalTools(server, ctx, track) {
1096
+ server.registerTool(
1097
+ track(mcpToolName(ctx.productName, "renewal_events_list")),
1098
+ {
1099
+ title: "List Renewal Events",
1100
+ description: "List renewal events, optionally scoped to a relationship and/or filtered to upcoming events only.",
1101
+ inputSchema: {
1102
+ relationshipId: zod.z.string().optional().describe("Filter by relationship ID"),
1103
+ upcomingOnly: zod.z.boolean().optional().describe("Only return events that have not yet occurred")
1104
+ }
1105
+ },
1106
+ async ({ relationshipId, upcomingOnly }) => {
1107
+ try {
1108
+ const data = await ctx.gql.workspace.request(LIST_RENEWAL_EVENTS, { relationshipId, upcomingOnly });
1109
+ return jsonResult(data.subListRenewalEvents);
1110
+ } catch (error) {
1111
+ ctx.logger.error("subscriberbot renewals_list failed", { error: String(error) });
1112
+ return errorResult(
1113
+ `Failed to list renewal events: ${error instanceof Error ? error.message : String(error)}`
1114
+ );
1115
+ }
1116
+ }
1117
+ );
1118
+ }
1119
+ function registerPaymentInstrumentTools(server, ctx, track) {
1120
+ server.registerTool(
1121
+ track(mcpToolName(ctx.productName, "payment_instruments_list")),
1122
+ {
1123
+ title: "List Payment Instruments",
1124
+ description: "List stored payment instruments, optionally filtered by owner.",
1125
+ inputSchema: { ownerId: zod.z.string().optional().describe("Filter by owner user ID") }
1126
+ },
1127
+ async ({ ownerId }) => {
1128
+ try {
1129
+ const data = await ctx.gql.workspace.request(LIST_PAYMENT_INSTRUMENTS, { ownerId });
1130
+ return jsonResult(data.subListPaymentInstruments);
1131
+ } catch (error) {
1132
+ ctx.logger.error("subscriberbot payment_instruments_list failed", { error: String(error) });
1133
+ return errorResult(
1134
+ `Failed to list payment instruments: ${error instanceof Error ? error.message : String(error)}`
1135
+ );
1136
+ }
1137
+ }
1138
+ );
1139
+ server.registerTool(
1140
+ track(mcpToolName(ctx.productName, "payment_instruments_create")),
1141
+ {
1142
+ title: "Create Payment Instrument",
1143
+ description: "Store a payment instrument. Never send raw card numbers \u2014 use `processorToken` from your PSP plus display-only fields (brand, last4, expiry).",
1144
+ inputSchema: {
1145
+ label: zod.z.string().min(1).describe('Display label (e.g. "Personal Visa")'),
1146
+ type: SubPaymentInstrumentTypeEnum.optional().describe("Instrument type (default CARD)"),
1147
+ ownerId: zod.z.string().optional().describe("Owner user ID"),
1148
+ brand: zod.z.string().optional().describe('Card/wallet brand (e.g. "Visa")'),
1149
+ last4: zod.z.string().optional().describe("Last 4 digits (display only)"),
1150
+ expiryMonth: zod.z.number().int().optional().describe("Expiry month (1-12)"),
1151
+ expiryYear: zod.z.number().int().optional().describe("Expiry year (4-digit)"),
1152
+ isDefault: zod.z.boolean().optional().describe("Mark as the default instrument (default false)"),
1153
+ processorToken: zod.z.string().optional().describe("Opaque PSP token (never a raw PAN)")
1154
+ }
1155
+ },
1156
+ async ({
1157
+ label,
1158
+ type,
1159
+ ownerId,
1160
+ brand,
1161
+ last4,
1162
+ expiryMonth,
1163
+ expiryYear,
1164
+ isDefault,
1165
+ processorToken
1166
+ }) => {
1167
+ try {
1168
+ const input = { label };
1169
+ if (type !== void 0) input.type = type;
1170
+ if (ownerId !== void 0) input.ownerId = ownerId;
1171
+ if (brand !== void 0) input.brand = brand;
1172
+ if (last4 !== void 0) input.last4 = last4;
1173
+ if (expiryMonth !== void 0) input.expiryMonth = expiryMonth;
1174
+ if (expiryYear !== void 0) input.expiryYear = expiryYear;
1175
+ if (isDefault !== void 0) input.isDefault = isDefault;
1176
+ if (processorToken !== void 0) input.processorToken = processorToken;
1177
+ const data = await ctx.gql.workspace.request(CREATE_PAYMENT_INSTRUMENT, { input });
1178
+ return jsonResult(data.subCreatePaymentInstrument);
1179
+ } catch (error) {
1180
+ ctx.logger.error("subscriberbot payment_instruments_create failed", {
1181
+ error: String(error)
1182
+ });
1183
+ return errorResult(
1184
+ `Failed to create payment instrument: ${error instanceof Error ? error.message : String(error)}`
1185
+ );
1186
+ }
1187
+ }
1188
+ );
1189
+ server.registerTool(
1190
+ track(mcpToolName(ctx.productName, "payment_instruments_remove")),
1191
+ {
1192
+ title: "Remove Payment Instrument",
1193
+ description: "Remove a stored payment instrument. Returns true on success.",
1194
+ inputSchema: { id: zod.z.string().describe("Payment instrument ID") }
1195
+ },
1196
+ async ({ id }) => {
1197
+ try {
1198
+ const data = await ctx.gql.workspace.request(
1199
+ REMOVE_PAYMENT_INSTRUMENT,
1200
+ { id }
1201
+ );
1202
+ return jsonResult({ removed: data.subRemovePaymentInstrument, id });
1203
+ } catch (error) {
1204
+ ctx.logger.error("subscriberbot payment_instruments_remove failed", {
1205
+ error: String(error)
1206
+ });
1207
+ return errorResult(
1208
+ `Failed to remove payment instrument: ${error instanceof Error ? error.message : String(error)}`
1209
+ );
1210
+ }
1211
+ }
1212
+ );
1213
+ }
1214
+ function registerInvoiceTools(server, ctx, track) {
1215
+ server.registerTool(
1216
+ track(mcpToolName(ctx.productName, "invoices_list")),
1217
+ {
1218
+ title: "List Invoices",
1219
+ description: "List invoices with optional relationship/status filters and pagination. Returns a connection ({ items, pageInfo }).",
1220
+ inputSchema: {
1221
+ relationshipId: zod.z.string().optional().describe("Filter by relationship ID"),
1222
+ status: SubInvoiceStatusEnum.optional().describe("Filter by invoice status"),
1223
+ limit: zod.z.number().int().optional().describe("Page size (default 50)"),
1224
+ offset: zod.z.number().int().optional().describe("Pagination offset (default 0)"),
1225
+ cursor: zod.z.string().optional().describe("Opaque pagination cursor")
1226
+ }
1227
+ },
1228
+ async ({ relationshipId, status, limit, offset, cursor }) => {
1229
+ try {
1230
+ const pagination = {};
1231
+ if (limit !== void 0) pagination.limit = limit;
1232
+ if (offset !== void 0) pagination.offset = offset;
1233
+ if (cursor !== void 0) pagination.cursor = cursor;
1234
+ const data = await ctx.gql.workspace.request(
1235
+ LIST_INVOICES,
1236
+ {
1237
+ relationshipId,
1238
+ status,
1239
+ pagination: Object.keys(pagination).length > 0 ? pagination : void 0
1240
+ }
1241
+ );
1242
+ return jsonResult(data.subListInvoices);
1243
+ } catch (error) {
1244
+ ctx.logger.error("subscriberbot invoices_list failed", { error: String(error) });
1245
+ return errorResult(
1246
+ `Failed to list invoices: ${error instanceof Error ? error.message : String(error)}`
1247
+ );
1248
+ }
1249
+ }
1250
+ );
1251
+ server.registerTool(
1252
+ track(mcpToolName(ctx.productName, "invoices_create")),
1253
+ {
1254
+ title: "Create Invoice",
1255
+ description: "Create an invoice against a relationship. `lineItems` is arbitrary JSON; `fileId` references a wspace-files-svc File holding the PDF.",
1256
+ inputSchema: {
1257
+ relationshipId: zod.z.string().min(1).describe("Relationship ID"),
1258
+ number: zod.z.string().optional().describe("Invoice number"),
1259
+ status: SubInvoiceStatusEnum.optional().describe("Invoice status (default ISSUED)"),
1260
+ currency: zod.z.string().optional().describe("ISO currency code"),
1261
+ subtotal: zod.z.number().optional().describe("Subtotal amount"),
1262
+ taxAmount: zod.z.number().optional().describe("Tax amount"),
1263
+ total: zod.z.number().optional().describe("Total amount"),
1264
+ issueDate: zod.z.string().optional().describe("Issue datetime (ISO 8601)"),
1265
+ dueDate: zod.z.string().optional().describe("Due datetime (ISO 8601)"),
1266
+ lineItems: JsonValue.optional().describe("Line items as JSON (object or array)"),
1267
+ paymentInstrumentId: zod.z.string().optional().describe("Payment instrument ID"),
1268
+ fileId: zod.z.string().optional().describe("wspace-files-svc File ID for the invoice PDF")
1269
+ }
1270
+ },
1271
+ async (args) => {
1272
+ try {
1273
+ const input = { relationshipId: args.relationshipId };
1274
+ const optional = [
1275
+ "number",
1276
+ "status",
1277
+ "currency",
1278
+ "subtotal",
1279
+ "taxAmount",
1280
+ "total",
1281
+ "issueDate",
1282
+ "dueDate",
1283
+ "lineItems",
1284
+ "paymentInstrumentId",
1285
+ "fileId"
1286
+ ];
1287
+ for (const key of optional) {
1288
+ if (args[key] !== void 0) input[key] = args[key];
1289
+ }
1290
+ const data = await ctx.gql.workspace.request(CREATE_INVOICE, { input });
1291
+ return jsonResult(data.subCreateInvoice);
1292
+ } catch (error) {
1293
+ ctx.logger.error("subscriberbot invoices_create failed", { error: String(error) });
1294
+ return errorResult(
1295
+ `Failed to create invoice: ${error instanceof Error ? error.message : String(error)}`
1296
+ );
1297
+ }
1298
+ }
1299
+ );
1300
+ server.registerTool(
1301
+ track(mcpToolName(ctx.productName, "invoices_mark_paid")),
1302
+ {
1303
+ title: "Mark Invoice Paid",
1304
+ description: "Mark an invoice as paid (sets status PAID and stamps paidAt).",
1305
+ inputSchema: { id: zod.z.string().describe("Invoice ID") }
1306
+ },
1307
+ async ({ id }) => {
1308
+ try {
1309
+ const data = await ctx.gql.workspace.request(MARK_INVOICE_PAID, { id });
1310
+ return jsonResult(data.subMarkInvoicePaid);
1311
+ } catch (error) {
1312
+ ctx.logger.error("subscriberbot invoices_mark_paid failed", { error: String(error) });
1313
+ return errorResult(
1314
+ `Failed to mark invoice paid: ${error instanceof Error ? error.message : String(error)}`
1315
+ );
1316
+ }
1317
+ }
1318
+ );
1319
+ }
1320
+ function registerChannelTools(server, ctx, track) {
1321
+ server.registerTool(
1322
+ track(mcpToolName(ctx.productName, "channels_list")),
1323
+ {
1324
+ title: "List Channels",
1325
+ description: "List communication channels, optionally filtered by owner.",
1326
+ inputSchema: { ownerId: zod.z.string().optional().describe("Filter by owner user ID") }
1327
+ },
1328
+ async ({ ownerId }) => {
1329
+ try {
1330
+ const data = await ctx.gql.workspace.request(LIST_CHANNELS, { ownerId });
1331
+ return jsonResult(data.subListChannels);
1332
+ } catch (error) {
1333
+ ctx.logger.error("subscriberbot channels_list failed", { error: String(error) });
1334
+ return errorResult(
1335
+ `Failed to list channels: ${error instanceof Error ? error.message : String(error)}`
1336
+ );
1337
+ }
1338
+ }
1339
+ );
1340
+ server.registerTool(
1341
+ track(mcpToolName(ctx.productName, "channels_create")),
1342
+ {
1343
+ title: "Create Channel",
1344
+ description: "Register a communication channel. `address` is the endpoint (email address, phone number, webhook URL, \u2026).",
1345
+ inputSchema: {
1346
+ address: zod.z.string().min(1).describe("Channel endpoint (email/phone/URL)"),
1347
+ type: SubChannelTypeEnum.optional().describe("Channel type (default EMAIL)"),
1348
+ label: zod.z.string().optional().describe("Display label"),
1349
+ ownerId: zod.z.string().optional().describe("Owner user ID"),
1350
+ ingestEnabled: zod.z.boolean().optional().describe("Whether inbound ingestion is enabled (default true)")
1351
+ }
1352
+ },
1353
+ async ({ address, type, label, ownerId, ingestEnabled }) => {
1354
+ try {
1355
+ const input = { address };
1356
+ if (type !== void 0) input.type = type;
1357
+ if (label !== void 0) input.label = label;
1358
+ if (ownerId !== void 0) input.ownerId = ownerId;
1359
+ if (ingestEnabled !== void 0) input.ingestEnabled = ingestEnabled;
1360
+ const data = await ctx.gql.workspace.request(CREATE_CHANNEL, { input });
1361
+ return jsonResult(data.subCreateChannel);
1362
+ } catch (error) {
1363
+ ctx.logger.error("subscriberbot channels_create failed", { error: String(error) });
1364
+ return errorResult(
1365
+ `Failed to create channel: ${error instanceof Error ? error.message : String(error)}`
1366
+ );
1367
+ }
1368
+ }
1369
+ );
1370
+ server.registerTool(
1371
+ track(mcpToolName(ctx.productName, "channels_verify")),
1372
+ {
1373
+ title: "Verify Channel",
1374
+ description: "Mark a communication channel as verified (sets status VERIFIED, stamps verifiedAt).",
1375
+ inputSchema: { id: zod.z.string().describe("Channel ID") }
1376
+ },
1377
+ async ({ id }) => {
1378
+ try {
1379
+ const data = await ctx.gql.workspace.request(VERIFY_CHANNEL, { id });
1380
+ return jsonResult(data.subVerifyChannel);
1381
+ } catch (error) {
1382
+ ctx.logger.error("subscriberbot channels_verify failed", { error: String(error) });
1383
+ return errorResult(
1384
+ `Failed to verify channel: ${error instanceof Error ? error.message : String(error)}`
1385
+ );
1386
+ }
1387
+ }
1388
+ );
1389
+ }
1390
+ function registerInboxTools(server, ctx, track) {
1391
+ server.registerTool(
1392
+ track(mcpToolName(ctx.productName, "inbox_list")),
1393
+ {
1394
+ title: "List Inbox Messages",
1395
+ description: "The Universal Inbox \u2014 list merged subscription communications with optional category/channel/relationship/unread filters and pagination. Returns a connection ({ items, pageInfo }).",
1396
+ inputSchema: {
1397
+ category: SubMessageCategoryEnum.optional().describe("Filter by message category"),
1398
+ channelId: zod.z.string().optional().describe("Filter by source channel ID"),
1399
+ relationshipId: zod.z.string().optional().describe("Filter by linked relationship ID"),
1400
+ unreadOnly: zod.z.boolean().optional().describe("Only return unread messages"),
1401
+ limit: zod.z.number().int().optional().describe("Page size (default 50)"),
1402
+ offset: zod.z.number().int().optional().describe("Pagination offset (default 0)"),
1403
+ cursor: zod.z.string().optional().describe("Opaque pagination cursor")
1404
+ }
1405
+ },
1406
+ async ({ category, channelId, relationshipId, unreadOnly, limit, offset, cursor }) => {
1407
+ try {
1408
+ const pagination = {};
1409
+ if (limit !== void 0) pagination.limit = limit;
1410
+ if (offset !== void 0) pagination.offset = offset;
1411
+ if (cursor !== void 0) pagination.cursor = cursor;
1412
+ const data = await ctx.gql.workspace.request(
1413
+ LIST_INBOX_MESSAGES,
1414
+ {
1415
+ category,
1416
+ channelId,
1417
+ relationshipId,
1418
+ unreadOnly,
1419
+ pagination: Object.keys(pagination).length > 0 ? pagination : void 0
1420
+ }
1421
+ );
1422
+ return jsonResult(data.subListInboxMessages);
1423
+ } catch (error) {
1424
+ ctx.logger.error("subscriberbot inbox_list failed", { error: String(error) });
1425
+ return errorResult(
1426
+ `Failed to list inbox messages: ${error instanceof Error ? error.message : String(error)}`
1427
+ );
1428
+ }
1429
+ }
1430
+ );
1431
+ server.registerTool(
1432
+ track(mcpToolName(ctx.productName, "inbox_ingest")),
1433
+ {
1434
+ title: "Ingest Inbox Message",
1435
+ description: "Ingest a new communication into the universal inbox from a channel. `receivedAt` and `channelId` are required.",
1436
+ inputSchema: {
1437
+ channelId: zod.z.string().min(1).describe("Source channel ID"),
1438
+ receivedAt: zod.z.string().describe("When the message was received (ISO 8601)"),
1439
+ category: SubMessageCategoryEnum.optional().describe("Message category (default OTHER)"),
1440
+ categoryConfidence: zod.z.number().int().optional().describe("Classifier confidence (0-100)"),
1441
+ actionRequired: zod.z.boolean().optional().describe("Whether the message requires action (default false)"),
1442
+ subject: zod.z.string().optional().describe("Message subject"),
1443
+ preview: zod.z.string().optional().describe("Short preview/snippet"),
1444
+ externalId: zod.z.string().optional().describe("External message ID (for de-dup)"),
1445
+ relationshipId: zod.z.string().optional().describe("Linked relationship ID")
1446
+ }
1447
+ },
1448
+ async (args) => {
1449
+ try {
1450
+ const input = {
1451
+ channelId: args.channelId,
1452
+ receivedAt: args.receivedAt
1453
+ };
1454
+ const optional = [
1455
+ "category",
1456
+ "categoryConfidence",
1457
+ "actionRequired",
1458
+ "subject",
1459
+ "preview",
1460
+ "externalId",
1461
+ "relationshipId"
1462
+ ];
1463
+ for (const key of optional) {
1464
+ if (args[key] !== void 0) input[key] = args[key];
1465
+ }
1466
+ const data = await ctx.gql.workspace.request(INGEST_MESSAGE, { input });
1467
+ return jsonResult(data.subIngestMessage);
1468
+ } catch (error) {
1469
+ ctx.logger.error("subscriberbot inbox_ingest failed", { error: String(error) });
1470
+ return errorResult(
1471
+ `Failed to ingest message: ${error instanceof Error ? error.message : String(error)}`
1472
+ );
1473
+ }
1474
+ }
1475
+ );
1476
+ server.registerTool(
1477
+ track(mcpToolName(ctx.productName, "inbox_mark_read")),
1478
+ {
1479
+ title: "Mark Message Read",
1480
+ description: "Mark a universal-inbox message as read.",
1481
+ inputSchema: { id: zod.z.string().describe("Inbox message ID") }
1482
+ },
1483
+ async ({ id }) => {
1484
+ try {
1485
+ const data = await ctx.gql.workspace.request(MARK_MESSAGE_READ, { id });
1486
+ return jsonResult(data.subMarkMessageRead);
1487
+ } catch (error) {
1488
+ ctx.logger.error("subscriberbot inbox_mark_read failed", { error: String(error) });
1489
+ return errorResult(
1490
+ `Failed to mark message read: ${error instanceof Error ? error.message : String(error)}`
1491
+ );
1492
+ }
1493
+ }
1494
+ );
1495
+ }
1496
+ function registerAgentTools(server, ctx, track) {
1497
+ server.registerTool(
1498
+ track(mcpToolName(ctx.productName, "agents_get")),
1499
+ {
1500
+ title: "Get Agent",
1501
+ description: "Fetch a single AI agent by ID, including its policies.",
1502
+ inputSchema: { id: zod.z.string().describe("Agent ID") }
1503
+ },
1504
+ async ({ id }) => {
1505
+ try {
1506
+ const data = await ctx.gql.workspace.request(GET_AGENT, { id });
1507
+ if (!data.subAgent) return errorResult(`Agent ${id} not found`);
1508
+ return jsonResult(data.subAgent);
1509
+ } catch (error) {
1510
+ ctx.logger.error("subscriberbot agents_get failed", { error: String(error) });
1511
+ return errorResult(
1512
+ `Failed to get agent: ${error instanceof Error ? error.message : String(error)}`
1513
+ );
1514
+ }
1515
+ }
1516
+ );
1517
+ server.registerTool(
1518
+ track(mcpToolName(ctx.productName, "agents_list")),
1519
+ {
1520
+ title: "List Agents",
1521
+ description: "List AI agents with optional kind/owner/status filters.",
1522
+ inputSchema: {
1523
+ kind: SubAgentKindEnum.optional().describe("Filter by agent kind"),
1524
+ ownerId: zod.z.string().optional().describe("Filter by owner user ID"),
1525
+ status: SubAgentStatusEnum.optional().describe("Filter by operating posture")
1526
+ }
1527
+ },
1528
+ async ({ kind, ownerId, status }) => {
1529
+ try {
1530
+ const data = await ctx.gql.workspace.request(LIST_AGENTS, { kind, ownerId, status });
1531
+ return jsonResult(data.subListAgents);
1532
+ } catch (error) {
1533
+ ctx.logger.error("subscriberbot agents_list failed", { error: String(error) });
1534
+ return errorResult(
1535
+ `Failed to list agents: ${error instanceof Error ? error.message : String(error)}`
1536
+ );
1537
+ }
1538
+ }
1539
+ );
1540
+ server.registerTool(
1541
+ track(mcpToolName(ctx.productName, "agents_create")),
1542
+ {
1543
+ title: "Create Agent",
1544
+ description: "Create an AI agent. Defaults to kind=DISCOVERY and status=SUGGEST_ONLY (no autonomous action until promoted).",
1545
+ inputSchema: {
1546
+ name: zod.z.string().min(1).describe("Agent name"),
1547
+ kind: SubAgentKindEnum.optional().describe("Agent kind (default DISCOVERY)"),
1548
+ status: SubAgentStatusEnum.optional().describe("Operating posture (default SUGGEST_ONLY)"),
1549
+ description: zod.z.string().optional().describe("Agent description"),
1550
+ ownerId: zod.z.string().optional().describe("Owner user ID"),
1551
+ config: JsonObject.optional().describe("Agent configuration as JSON")
1552
+ }
1553
+ },
1554
+ async ({ name, kind, status, description, ownerId, config }) => {
1555
+ try {
1556
+ const input = { name };
1557
+ if (kind !== void 0) input.kind = kind;
1558
+ if (status !== void 0) input.status = status;
1559
+ if (description !== void 0) input.description = description;
1560
+ if (ownerId !== void 0) input.ownerId = ownerId;
1561
+ if (config !== void 0) input.config = config;
1562
+ const data = await ctx.gql.workspace.request(CREATE_AGENT, { input });
1563
+ return jsonResult(data.subCreateAgent);
1564
+ } catch (error) {
1565
+ ctx.logger.error("subscriberbot agents_create failed", { error: String(error) });
1566
+ return errorResult(
1567
+ `Failed to create agent: ${error instanceof Error ? error.message : String(error)}`
1568
+ );
1569
+ }
1570
+ }
1571
+ );
1572
+ server.registerTool(
1573
+ track(mcpToolName(ctx.productName, "agents_set_status")),
1574
+ {
1575
+ title: "Set Agent Status",
1576
+ description: "Change an agent's operating posture (DISABLED / SUGGEST_ONLY / AUTONOMOUS).",
1577
+ inputSchema: {
1578
+ id: zod.z.string().describe("Agent ID"),
1579
+ status: SubAgentStatusEnum.describe("Target operating posture")
1580
+ }
1581
+ },
1582
+ async ({ id, status }) => {
1583
+ try {
1584
+ const data = await ctx.gql.workspace.request(SET_AGENT_STATUS, { id, status });
1585
+ return jsonResult(data.subSetAgentStatus);
1586
+ } catch (error) {
1587
+ ctx.logger.error("subscriberbot agents_set_status failed", { error: String(error) });
1588
+ return errorResult(
1589
+ `Failed to set agent status: ${error instanceof Error ? error.message : String(error)}`
1590
+ );
1591
+ }
1592
+ }
1593
+ );
1594
+ }
1595
+ function registerPolicyTools(server, ctx, track) {
1596
+ server.registerTool(
1597
+ track(mcpToolName(ctx.productName, "policies_list")),
1598
+ {
1599
+ title: "List Policies",
1600
+ description: "List autonomous policies, optionally filtered by agent.",
1601
+ inputSchema: { agentId: zod.z.string().optional().describe("Filter by agent ID") }
1602
+ },
1603
+ async ({ agentId }) => {
1604
+ try {
1605
+ const data = await ctx.gql.workspace.request(LIST_POLICIES, { agentId });
1606
+ return jsonResult(data.subListPolicies);
1607
+ } catch (error) {
1608
+ ctx.logger.error("subscriberbot policies_list failed", { error: String(error) });
1609
+ return errorResult(
1610
+ `Failed to list policies: ${error instanceof Error ? error.message : String(error)}`
1611
+ );
1612
+ }
1613
+ }
1614
+ );
1615
+ server.registerTool(
1616
+ track(mcpToolName(ctx.productName, "policies_create")),
1617
+ {
1618
+ title: "Create Policy",
1619
+ description: "Create an autonomous policy for an agent. `condition` is arbitrary JSON evaluated to decide whether `action` fires.",
1620
+ inputSchema: {
1621
+ agentId: zod.z.string().min(1).describe("Agent ID this policy belongs to"),
1622
+ name: zod.z.string().min(1).describe("Policy name"),
1623
+ action: SubPolicyActionEnum.optional().describe("Action when triggered (default ALERT)"),
1624
+ description: zod.z.string().optional().describe("Policy description"),
1625
+ condition: JsonObject.optional().describe("Trigger condition as JSON"),
1626
+ isEnabled: zod.z.boolean().optional().describe("Whether the policy is enabled (default true)")
1627
+ }
1628
+ },
1629
+ async ({ agentId, name, action, description, condition, isEnabled }) => {
1630
+ try {
1631
+ const input = { agentId, name };
1632
+ if (action !== void 0) input.action = action;
1633
+ if (description !== void 0) input.description = description;
1634
+ if (condition !== void 0) input.condition = condition;
1635
+ if (isEnabled !== void 0) input.isEnabled = isEnabled;
1636
+ const data = await ctx.gql.workspace.request(CREATE_POLICY, { input });
1637
+ return jsonResult(data.subCreatePolicy);
1638
+ } catch (error) {
1639
+ ctx.logger.error("subscriberbot policies_create failed", { error: String(error) });
1640
+ return errorResult(
1641
+ `Failed to create policy: ${error instanceof Error ? error.message : String(error)}`
1642
+ );
1643
+ }
1644
+ }
1645
+ );
1646
+ }
1647
+ function registerWorkflowTools(server, ctx, track) {
1648
+ server.registerTool(
1649
+ track(mcpToolName(ctx.productName, "workflows_list")),
1650
+ {
1651
+ title: "List Workflows",
1652
+ description: "List automation workflows, optionally filtered by status.",
1653
+ inputSchema: {
1654
+ status: SubWorkflowStatusEnum.optional().describe("Filter by workflow status")
1655
+ }
1656
+ },
1657
+ async ({ status }) => {
1658
+ try {
1659
+ const data = await ctx.gql.workspace.request(LIST_WORKFLOWS, { status });
1660
+ return jsonResult(data.subListWorkflows);
1661
+ } catch (error) {
1662
+ ctx.logger.error("subscriberbot workflows_list failed", { error: String(error) });
1663
+ return errorResult(
1664
+ `Failed to list workflows: ${error instanceof Error ? error.message : String(error)}`
1665
+ );
1666
+ }
1667
+ }
1668
+ );
1669
+ server.registerTool(
1670
+ track(mcpToolName(ctx.productName, "workflows_create")),
1671
+ {
1672
+ title: "Create Workflow",
1673
+ description: "Create an event-triggered automation workflow. `triggerEvent` names the event; `steps` is arbitrary JSON describing the step graph.",
1674
+ inputSchema: {
1675
+ name: zod.z.string().min(1).describe("Workflow name"),
1676
+ triggerEvent: zod.z.string().min(1).describe("Event name that triggers the workflow"),
1677
+ description: zod.z.string().optional().describe("Workflow description"),
1678
+ steps: JsonValue.optional().describe("Step definition as JSON (object or array)")
1679
+ }
1680
+ },
1681
+ async ({ name, triggerEvent, description, steps }) => {
1682
+ try {
1683
+ const input = { name, triggerEvent };
1684
+ if (description !== void 0) input.description = description;
1685
+ if (steps !== void 0) input.steps = steps;
1686
+ const data = await ctx.gql.workspace.request(CREATE_WORKFLOW, { input });
1687
+ return jsonResult(data.subCreateWorkflow);
1688
+ } catch (error) {
1689
+ ctx.logger.error("subscriberbot workflows_create failed", { error: String(error) });
1690
+ return errorResult(
1691
+ `Failed to create workflow: ${error instanceof Error ? error.message : String(error)}`
1692
+ );
1693
+ }
1694
+ }
1695
+ );
1696
+ server.registerTool(
1697
+ track(mcpToolName(ctx.productName, "workflows_activate")),
1698
+ {
1699
+ title: "Activate Workflow",
1700
+ description: "Activate a workflow (sets status ACTIVE).",
1701
+ inputSchema: { id: zod.z.string().describe("Workflow ID") }
1702
+ },
1703
+ async ({ id }) => {
1704
+ try {
1705
+ const data = await ctx.gql.workspace.request(ACTIVATE_WORKFLOW, { id });
1706
+ return jsonResult(data.subActivateWorkflow);
1707
+ } catch (error) {
1708
+ ctx.logger.error("subscriberbot workflows_activate failed", { error: String(error) });
1709
+ return errorResult(
1710
+ `Failed to activate workflow: ${error instanceof Error ? error.message : String(error)}`
1711
+ );
1712
+ }
1713
+ }
1714
+ );
1715
+ }
1716
+
1717
+ // src/modules/subscriberbot/tools/health.ts
1718
+ function registerHealthTools(server, ctx, track) {
1719
+ server.registerTool(
1720
+ track(mcpToolName(ctx.productName, "health")),
1721
+ {
1722
+ title: "Subscriber Bot Health Check",
1723
+ description: "Public liveness/identity probe for the Subscriber Bot subgraph (subHealth). Requires no authentication.",
1724
+ inputSchema: {}
1725
+ },
1726
+ async () => {
1727
+ try {
1728
+ const data = await ctx.gql.workspace.request(HEALTH, {});
1729
+ return jsonResult({ ok: true, status: data.subHealth });
1730
+ } catch (error) {
1731
+ ctx.logger.error("subscriberbot health failed", { error: String(error) });
1732
+ return errorResult(
1733
+ `Subscriber Bot health check failed: ${error instanceof Error ? error.message : String(error)}`
1734
+ );
1735
+ }
1736
+ }
1737
+ );
1738
+ }
1739
+
1740
+ // src/modules/subscriberbot/resources.ts
1741
+ function registerSubscriberbotResources(server, ctx, track) {
1742
+ const schemaUri = track(mcpResourceUri(ctx.productName, "schema"));
1743
+ const providersUri = track(mcpResourceUri(ctx.productName, "providers"));
1744
+ const relationshipsUri = track(mcpResourceUri(ctx.productName, "relationships"));
1745
+ const inboxUri = track(mcpResourceUri(ctx.productName, "inbox"));
1746
+ server.registerResource(
1747
+ "subscriberbot-schema",
1748
+ schemaUri,
1749
+ {
1750
+ title: "Subscriber Bot Domain Schema",
1751
+ description: "Overview of the Subscriber Bot domain \u2014 the Universal Digital Relationship OS: entities, enums, and the per-entity tool surface.",
1752
+ mimeType: "text/plain"
1753
+ },
1754
+ async () => {
1755
+ ctx.logger.debug(`Resource ${schemaUri} requested`);
1756
+ const schema = `# Subscriber Bot Domain (Overview)
1757
+
1758
+ The Universal Digital Relationship Operating System \u2014 system of record for every
1759
+ recurring digital relationship.
1760
+
1761
+ ## Entities
1762
+ - SubProvider \u2014 a provider in the global discovery registry (has plans)
1763
+ - SubPlan \u2014 a provider's pricing plan
1764
+ - SubRelationship \u2014 the core object: a subscription / membership / license / contract
1765
+ - SubEntitlement \u2014 what a relationship grants (seats, quotas, feature access, \u2026)
1766
+ - SubAsset \u2014 documents/credentials attached to a relationship (refs wspace-files File)
1767
+ - SubRenewalEvent \u2014 renewal / trial-end / price-change / cancellation timeline events
1768
+ - SubPaymentInstrument \u2014 stored card / bank / wallet (universal billing layer)
1769
+ - SubInvoice \u2014 invoice ledger entry (refs wspace-files File for the PDF)
1770
+ - SubCommunicationChannel \u2014 inbound/outbound channel feeding the inbox
1771
+ - SubInboxMessage \u2014 a merged subscription communication (the Universal Inbox)
1772
+ - SubAiAgent \u2014 an automation-layer specialised agent (has policies)
1773
+ - SubPolicy \u2014 an autonomous rule (condition \u2192 action) evaluated by an agent
1774
+ - SubWorkflow \u2014 an event-triggered automation workflow
1775
+
1776
+ ## Key enums
1777
+ - SubRelationshipKind: SUBSCRIPTION, MEMBERSHIP, LICENSE, CONTRACT, TRIAL, NEWSLETTER, ENROLLMENT, RECURRING_PAYMENT
1778
+ - SubRelationshipStatus: ACTIVE, TRIAL, PAST_DUE, PAUSED, LAPSED, EXPIRED, CANCELLED
1779
+ - SubBillingInterval: DAILY, WEEKLY, MONTHLY, QUARTERLY, YEARLY, LIFETIME, USAGE_BASED, FREE
1780
+ - SubProviderCategory: SAAS, STREAMING, TELECOM, UTILITY, FINANCIAL, INSURANCE, NEWSLETTER, MEMBERSHIP, AI_SERVICE, \u2026 (16)
1781
+ - SubInvoiceStatus: DRAFT, ISSUED, PAID, OVERDUE, FAILED, REFUNDED, CANCELLED
1782
+ - SubMessageCategory: BILLING, RENEWAL, REQUIRED_ACTION, SECURITY_ALERT, PRODUCT_UPDATE, MARKETING, OTHER
1783
+ - SubAgentKind: DISCOVERY, RENEWAL, COST, NEGOTIATION, MIGRATION, COMPLIANCE, CONCIERGE, VENDOR, NEWSLETTER
1784
+ - SubAgentStatus: DISABLED, SUGGEST_ONLY, AUTONOMOUS
1785
+
1786
+ ## Tool groups
1787
+ providers, plans, relationships, entitlements, assets, renewal_events,
1788
+ payment_instruments, invoices, channels, inbox, agents, policies, workflows, health.
1789
+ All run against the WORKSPACE gateway (workspace-scoped) except the public health probe.
1790
+ `;
1791
+ return {
1792
+ contents: [{ uri: schemaUri, text: schema, mimeType: "text/plain" }]
1793
+ };
1794
+ }
1795
+ );
1796
+ server.registerResource(
1797
+ "subscriberbot-providers",
1798
+ providersUri,
1799
+ {
1800
+ title: "Subscriber Bot Provider Registry",
1801
+ description: "The first 50 providers in the bound workspace registry.",
1802
+ mimeType: "application/json"
1803
+ },
1804
+ async () => {
1805
+ ctx.logger.debug(`Resource ${providersUri} requested`);
1806
+ try {
1807
+ const data = await ctx.gql.workspace.request(
1808
+ LIST_PROVIDERS,
1809
+ {
1810
+ pagination: { limit: 50, offset: 0 }
1811
+ }
1812
+ );
1813
+ return {
1814
+ contents: [
1815
+ {
1816
+ uri: providersUri,
1817
+ text: JSON.stringify(data.subListProviders, null, 2),
1818
+ mimeType: "application/json"
1819
+ }
1820
+ ]
1821
+ };
1822
+ } catch (error) {
1823
+ return {
1824
+ contents: [
1825
+ {
1826
+ uri: providersUri,
1827
+ text: JSON.stringify({
1828
+ error: error instanceof Error ? error.message : String(error)
1829
+ }),
1830
+ mimeType: "application/json"
1831
+ }
1832
+ ]
1833
+ };
1834
+ }
1835
+ }
1836
+ );
1837
+ server.registerResource(
1838
+ "subscriberbot-relationships",
1839
+ relationshipsUri,
1840
+ {
1841
+ title: "Subscriber Bot Relationships",
1842
+ description: "The first 50 recurring relationships in the bound workspace.",
1843
+ mimeType: "application/json"
1844
+ },
1845
+ async () => {
1846
+ ctx.logger.debug(`Resource ${relationshipsUri} requested`);
1847
+ try {
1848
+ const data = await ctx.gql.workspace.request(
1849
+ LIST_RELATIONSHIPS,
1850
+ { pagination: { limit: 50, offset: 0 } }
1851
+ );
1852
+ return {
1853
+ contents: [
1854
+ {
1855
+ uri: relationshipsUri,
1856
+ text: JSON.stringify(data.subListRelationships, null, 2),
1857
+ mimeType: "application/json"
1858
+ }
1859
+ ]
1860
+ };
1861
+ } catch (error) {
1862
+ return {
1863
+ contents: [
1864
+ {
1865
+ uri: relationshipsUri,
1866
+ text: JSON.stringify({
1867
+ error: error instanceof Error ? error.message : String(error)
1868
+ }),
1869
+ mimeType: "application/json"
1870
+ }
1871
+ ]
1872
+ };
1873
+ }
1874
+ }
1875
+ );
1876
+ server.registerResource(
1877
+ "subscriberbot-inbox",
1878
+ inboxUri,
1879
+ {
1880
+ title: "Subscriber Bot Universal Inbox",
1881
+ description: "The first 50 merged subscription communications in the bound workspace.",
1882
+ mimeType: "application/json"
1883
+ },
1884
+ async () => {
1885
+ ctx.logger.debug(`Resource ${inboxUri} requested`);
1886
+ try {
1887
+ const data = await ctx.gql.workspace.request(
1888
+ LIST_INBOX_MESSAGES,
1889
+ { pagination: { limit: 50, offset: 0 } }
1890
+ );
1891
+ return {
1892
+ contents: [
1893
+ {
1894
+ uri: inboxUri,
1895
+ text: JSON.stringify(data.subListInboxMessages, null, 2),
1896
+ mimeType: "application/json"
1897
+ }
1898
+ ]
1899
+ };
1900
+ } catch (error) {
1901
+ return {
1902
+ contents: [
1903
+ {
1904
+ uri: inboxUri,
1905
+ text: JSON.stringify({
1906
+ error: error instanceof Error ? error.message : String(error)
1907
+ }),
1908
+ mimeType: "application/json"
1909
+ }
1910
+ ]
1911
+ };
1912
+ }
1913
+ }
1914
+ );
1915
+ }
1916
+ function registerSubscriberbotPrompts(server, ctx, track) {
1917
+ const p = ctx.productName;
1918
+ const onboardingName = track(mcpPromptName(p, "relationship-onboarding"));
1919
+ const triageName = track(mcpPromptName(p, "inbox-triage"));
1920
+ server.registerPrompt(
1921
+ onboardingName,
1922
+ {
1923
+ title: "Relationship Onboarding",
1924
+ description: "Guide for onboarding a new recurring relationship end to end: find/create the provider and plan, create the relationship, and capture its entitlements, assets, and renewal cadence.",
1925
+ argsSchema: {
1926
+ providerName: zod.z.string().optional().describe("Provider/vendor name"),
1927
+ label: zod.z.string().optional().describe("Label for the relationship")
1928
+ }
1929
+ },
1930
+ ({ providerName, label }) => {
1931
+ ctx.logger.debug(`Prompt ${onboardingName} called`, { providerName, label });
1932
+ const providerNote = providerName ? `Search the registry for "${providerName}" with ${p}_providers_list; create it with ${p}_providers_create if missing.` : `Ask the user for the provider name, then search with ${p}_providers_list (create with ${p}_providers_create if missing).`;
1933
+ const labelNote = label ? `Use the label "${label}".` : "Ask the user for a label for the relationship.";
1934
+ return {
1935
+ messages: [
1936
+ {
1937
+ role: "user",
1938
+ content: {
1939
+ type: "text",
1940
+ text: `Help me onboard a new recurring relationship in Subscriber Bot.
1941
+
1942
+ 1. **Provider**: ${providerNote}
1943
+ 2. **Plan**: Use ${p}_plans_list for the provider; create one with ${p}_plans_create (amount, currency, interval) if needed.
1944
+ 3. **Create Relationship**: Use ${p}_relationships_create. ${labelNote} Set kind (SUBSCRIPTION / MEMBERSHIP / LICENSE / CONTRACT), providerId, planId, amount/currency/interval, autoRenew, and renewsAt.
1945
+ 4. **Entitlements**: Use ${p}_entitlements_create for each seat/quota/feature the relationship grants.
1946
+ 5. **Assets**: Use ${p}_assets_create to attach contracts/receipts/license keys (reference a wspace-files File via fileId).
1947
+ 6. **Confirm**: Re-read with ${p}_relationships_get and summarise the renewal cadence.
1948
+
1949
+ Show results at each step and confirm before finishing.`
1950
+ }
1951
+ }
1952
+ ]
1953
+ };
1954
+ }
1955
+ );
1956
+ server.registerPrompt(
1957
+ triageName,
1958
+ {
1959
+ title: "Inbox & Renewal Triage",
1960
+ description: "Daily triage workflow: work the universal inbox, mark actioned messages read, handle upcoming renewals, settle invoices, and tune automation agents/policies.",
1961
+ argsSchema: {
1962
+ relationshipId: zod.z.string().optional().describe("Relationship ID to focus on")
1963
+ }
1964
+ },
1965
+ ({ relationshipId }) => {
1966
+ ctx.logger.debug(`Prompt ${triageName} called`, { relationshipId });
1967
+ const scopeNote = relationshipId ? `Focus on relationship "${relationshipId}".` : `Work across all relationships (use ${p}_relationships_list to pick).`;
1968
+ return {
1969
+ messages: [
1970
+ {
1971
+ role: "user",
1972
+ content: {
1973
+ type: "text",
1974
+ text: `Run daily Subscriber Bot triage. ${scopeNote}
1975
+
1976
+ 1. **Required actions**: Use ${p}_inbox_list with category=REQUIRED_ACTION (and unreadOnly=true) to find messages needing attention; mark handled ones with ${p}_inbox_mark_read.
1977
+ 2. **Renewals**: Use ${p}_renewal_events_list with upcomingOnly=true to find imminent renewals/trial-ends; for each decide renew vs cancel (${p}_relationships_transition / ${p}_relationships_cancel).
1978
+ 3. **Billing**: Use ${p}_invoices_list with status=ISSUED or OVERDUE; settle paid ones with ${p}_invoices_mark_paid.
1979
+ 4. **Security**: Use ${p}_inbox_list with category=SECURITY_ALERT and escalate.
1980
+ 5. **Automation**: Use ${p}_agents_list and ${p}_policies_list to review autonomous coverage; promote a trusted agent with ${p}_agents_set_status (SUGGEST_ONLY \u2192 AUTONOMOUS) where appropriate.
1981
+
1982
+ Summarise what needs attention after each step.`
1983
+ }
1984
+ }
1985
+ ]
1986
+ };
1987
+ }
1988
+ );
1989
+ }
1990
+
1991
+ // src/modules/subscriberbot/index.ts
1992
+ var subscriberbotModule = {
1993
+ id: "subscriberbot",
1994
+ version: "0.0.1",
1995
+ displayName: "Subscriber Bot",
1996
+ dependsOn: ["auth"],
1997
+ capabilities: { tools: {}, resources: {}, prompts: {} },
1998
+ register(server, ctx) {
1999
+ const tools = [];
2000
+ const resources = [];
2001
+ const prompts = [];
2002
+ const trackTool = (n) => {
2003
+ tools.push(n);
2004
+ return n;
2005
+ };
2006
+ const trackResource = (uri) => {
2007
+ resources.push(uri);
2008
+ return uri;
2009
+ };
2010
+ const trackPrompt = (n) => {
2011
+ prompts.push(n);
2012
+ return n;
2013
+ };
2014
+ registerProviderTools(server, ctx, trackTool);
2015
+ registerPlanTools(server, ctx, trackTool);
2016
+ registerRelationshipTools(server, ctx, trackTool);
2017
+ registerEntitlementTools(server, ctx, trackTool);
2018
+ registerAssetTools(server, ctx, trackTool);
2019
+ registerRenewalTools(server, ctx, trackTool);
2020
+ registerPaymentInstrumentTools(server, ctx, trackTool);
2021
+ registerInvoiceTools(server, ctx, trackTool);
2022
+ registerChannelTools(server, ctx, trackTool);
2023
+ registerInboxTools(server, ctx, trackTool);
2024
+ registerAgentTools(server, ctx, trackTool);
2025
+ registerPolicyTools(server, ctx, trackTool);
2026
+ registerWorkflowTools(server, ctx, trackTool);
2027
+ registerHealthTools(server, ctx, trackTool);
2028
+ registerSubscriberbotResources(server, ctx, trackResource);
2029
+ registerSubscriberbotPrompts(server, ctx, trackPrompt);
2030
+ return { tools, resources, prompts };
2031
+ }
2032
+ };
2033
+ var subscriberbot_default = subscriberbotModule;
2034
+
2035
+ module.exports = subscriberbot_default;
2036
+ //# sourceMappingURL=index.cjs.map
2037
+ //# sourceMappingURL=index.cjs.map