@carrierllc/mcp 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/apps/app-state.d.ts +19 -0
  2. package/dist/apps/app-state.d.ts.map +1 -0
  3. package/dist/apps/app-state.js +28 -0
  4. package/dist/apps/app-state.js.map +1 -0
  5. package/dist/apps/balance-topup.d.ts +19 -0
  6. package/dist/apps/balance-topup.d.ts.map +1 -0
  7. package/dist/apps/balance-topup.js +121 -0
  8. package/dist/apps/balance-topup.js.map +1 -0
  9. package/dist/apps/fleet-health-app.d.ts +29 -0
  10. package/dist/apps/fleet-health-app.d.ts.map +1 -0
  11. package/dist/apps/fleet-health-app.js +152 -0
  12. package/dist/apps/fleet-health-app.js.map +1 -0
  13. package/dist/apps/index.d.ts +37 -0
  14. package/dist/apps/index.d.ts.map +1 -0
  15. package/dist/apps/index.js +42 -0
  16. package/dist/apps/index.js.map +1 -0
  17. package/dist/apps/provisioning-wizard.d.ts +11 -0
  18. package/dist/apps/provisioning-wizard.d.ts.map +1 -0
  19. package/dist/apps/provisioning-wizard.js +345 -0
  20. package/dist/apps/provisioning-wizard.js.map +1 -0
  21. package/dist/audit.d.ts +31 -0
  22. package/dist/audit.d.ts.map +1 -0
  23. package/dist/audit.js +42 -0
  24. package/dist/audit.js.map +1 -0
  25. package/dist/billing-thresholds.d.ts +71 -0
  26. package/dist/billing-thresholds.d.ts.map +1 -0
  27. package/dist/billing-thresholds.js +238 -0
  28. package/dist/billing-thresholds.js.map +1 -0
  29. package/dist/billing.d.ts +95 -0
  30. package/dist/billing.d.ts.map +1 -0
  31. package/dist/billing.js +239 -0
  32. package/dist/billing.js.map +1 -0
  33. package/dist/clerk.d.ts +125 -0
  34. package/dist/clerk.d.ts.map +1 -0
  35. package/dist/clerk.js +389 -0
  36. package/dist/clerk.js.map +1 -0
  37. package/dist/client.d.ts +12 -15
  38. package/dist/client.d.ts.map +1 -1
  39. package/dist/client.js +48 -55
  40. package/dist/client.js.map +1 -1
  41. package/dist/credits.d.ts +165 -0
  42. package/dist/credits.d.ts.map +1 -0
  43. package/dist/credits.js +483 -0
  44. package/dist/credits.js.map +1 -0
  45. package/dist/index.d.ts +6 -11
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +74 -23
  48. package/dist/index.js.map +1 -1
  49. package/dist/intelligence.d.ts +2 -8
  50. package/dist/intelligence.d.ts.map +1 -1
  51. package/dist/intelligence.js +321 -154
  52. package/dist/intelligence.js.map +1 -1
  53. package/dist/list-recent-ocs-events.d.ts +48 -0
  54. package/dist/list-recent-ocs-events.d.ts.map +1 -0
  55. package/dist/list-recent-ocs-events.js +160 -0
  56. package/dist/list-recent-ocs-events.js.map +1 -0
  57. package/dist/manus-client.d.ts +429 -0
  58. package/dist/manus-client.d.ts.map +1 -0
  59. package/dist/manus-client.js +401 -0
  60. package/dist/manus-client.js.map +1 -0
  61. package/dist/manus-common.d.ts +5 -0
  62. package/dist/manus-common.d.ts.map +1 -0
  63. package/dist/manus-common.js +5 -0
  64. package/dist/manus-common.js.map +1 -0
  65. package/dist/manus-schedule.d.ts +74 -0
  66. package/dist/manus-schedule.d.ts.map +1 -0
  67. package/dist/manus-schedule.js +213 -0
  68. package/dist/manus-schedule.js.map +1 -0
  69. package/dist/manus-usage.d.ts +32 -0
  70. package/dist/manus-usage.d.ts.map +1 -0
  71. package/dist/manus-usage.js +120 -0
  72. package/dist/manus-usage.js.map +1 -0
  73. package/dist/manus-webhook.d.ts +60 -0
  74. package/dist/manus-webhook.d.ts.map +1 -0
  75. package/dist/manus-webhook.js +361 -0
  76. package/dist/manus-webhook.js.map +1 -0
  77. package/dist/pricing-tools.d.ts +26 -0
  78. package/dist/pricing-tools.d.ts.map +1 -0
  79. package/dist/pricing-tools.js +428 -0
  80. package/dist/pricing-tools.js.map +1 -0
  81. package/dist/projects-tools.d.ts +39 -0
  82. package/dist/projects-tools.d.ts.map +1 -0
  83. package/dist/projects-tools.js +545 -0
  84. package/dist/projects-tools.js.map +1 -0
  85. package/dist/prompts.d.ts +1 -0
  86. package/dist/prompts.d.ts.map +1 -1
  87. package/dist/prompts.js +1 -0
  88. package/dist/prompts.js.map +1 -1
  89. package/dist/stripe-connect-tools.d.ts +33 -0
  90. package/dist/stripe-connect-tools.d.ts.map +1 -0
  91. package/dist/stripe-connect-tools.js +504 -0
  92. package/dist/stripe-connect-tools.js.map +1 -0
  93. package/dist/timing-safe-equal.d.ts +5 -0
  94. package/dist/timing-safe-equal.d.ts.map +1 -0
  95. package/dist/timing-safe-equal.js +13 -0
  96. package/dist/timing-safe-equal.js.map +1 -0
  97. package/dist/tools-backlog.d.ts +28 -0
  98. package/dist/tools-backlog.d.ts.map +1 -0
  99. package/dist/tools-backlog.js +315 -0
  100. package/dist/tools-backlog.js.map +1 -0
  101. package/dist/tools-carrier-ask.d.ts +138 -0
  102. package/dist/tools-carrier-ask.d.ts.map +1 -0
  103. package/dist/tools-carrier-ask.js +913 -0
  104. package/dist/tools-carrier-ask.js.map +1 -0
  105. package/dist/tools-pricing.d.ts +18 -0
  106. package/dist/tools-pricing.d.ts.map +1 -0
  107. package/dist/tools-pricing.js +172 -0
  108. package/dist/tools-pricing.js.map +1 -0
  109. package/dist/tools-ui-agent-ask.d.ts +29 -0
  110. package/dist/tools-ui-agent-ask.d.ts.map +1 -0
  111. package/dist/tools-ui-agent-ask.js +272 -0
  112. package/dist/tools-ui-agent-ask.js.map +1 -0
  113. package/dist/tools-ui-agent-schedule.d.ts +29 -0
  114. package/dist/tools-ui-agent-schedule.d.ts.map +1 -0
  115. package/dist/tools-ui-agent-schedule.js +517 -0
  116. package/dist/tools-ui-agent-schedule.js.map +1 -0
  117. package/dist/tools-ui-agent.d.ts +40 -0
  118. package/dist/tools-ui-agent.d.ts.map +1 -0
  119. package/dist/tools-ui-agent.js +508 -0
  120. package/dist/tools-ui-agent.js.map +1 -0
  121. package/dist/tools.d.ts +44 -13
  122. package/dist/tools.d.ts.map +1 -1
  123. package/dist/tools.js +794 -201
  124. package/dist/tools.js.map +1 -1
  125. package/dist/types.d.ts +291 -0
  126. package/dist/types.d.ts.map +1 -0
  127. package/dist/types.js +5 -0
  128. package/dist/types.js.map +1 -0
  129. package/package.json +14 -8
@@ -0,0 +1,361 @@
1
+ /**
2
+ * Manus webhook receiver.
3
+ *
4
+ * Receives push notifications from Manus for UI-agent tasks dispatched by
5
+ * tools-ui-agent.ts. Eliminates the need for client-side polling.
6
+ *
7
+ * ROUTE
8
+ * -----
9
+ * POST /manus-webhook
10
+ *
11
+ * AUTHENTICATION
12
+ * --------------
13
+ * Header: X-Manus-Signature: <hex>
14
+ * Payload: HMAC-SHA256(key=MANUS_WEBHOOK_SECRET, message=raw_request_body)
15
+ * Format: raw hex string (no "sha256=" prefix — per Manus docs).
16
+ *
17
+ * IDEMPOTENCY
18
+ * -----------
19
+ * event_id stored in CARRIER_USERS KV under key `manus_event:{event_id}` with
20
+ * 7-day TTL. Replayed events return 200+deduplicated without re-processing.
21
+ *
22
+ * EVENT TYPES
23
+ * -----------
24
+ * task_created — fires immediately after task.create; logged only.
25
+ * task_stopped — fires on completion or ask; updates audit log + AE.
26
+ * stop_reason:
27
+ * "finish" — task completed; attachment URLs logged if present.
28
+ * Clears any pending-ask KV entry for this task.
29
+ * "ask" — task paused, waiting for user input.
30
+ * Writes manus_pending_ask:{task_id} to CARRIER_USERS KV (24h TTL).
31
+ * Emits ui_agent_needs_input AE event with truncated question.
32
+ *
33
+ * PENDING-ASK KV SCHEMA
34
+ * ---------------------
35
+ * Key: manus_pending_ask:{task_id}
36
+ * Value: JSON { task_id, question, task_url, asked_at }
37
+ * TTL: 24 hours (86400 seconds)
38
+ *
39
+ * AUDIT LOG SCHEMA (Analytics Engine blobs[]):
40
+ * blobs[0] = "manus_webhook"
41
+ * blobs[1] = event_type ("task_created" | "task_stopped")
42
+ * blobs[2] = stop_reason ("finish" | "ask" | "ui_agent_awaiting_input" | "")
43
+ * blobs[3] = task_id
44
+ * blobs[4] = attachment_count (stringified number) or truncated question for ask events
45
+ * doubles[0] = latency_ms (0 for task_created)
46
+ * indexes[0] = task_id
47
+ */
48
+ import { timingSafeEqual } from "./timing-safe-equal.js";
49
+ // ---------------------------------------------------------------------------
50
+ // R2 attachment persistence constants
51
+ // ---------------------------------------------------------------------------
52
+ /** Max bytes to fetch per attachment (25 MB). */
53
+ const MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
54
+ /** R2 key prefix for Manus attachment files. */
55
+ const R2_PREFIX = "manus-attachments";
56
+ /**
57
+ * Patterns that identify Cloudflare-hosted URLs.
58
+ * Attachments already on CF infrastructure are skipped — no re-upload needed.
59
+ */
60
+ const CF_ZONE_PATTERNS = [
61
+ /\.r2\.dev$/,
62
+ /\.carrier\.llc$/,
63
+ /\.cloudflare\.net$/,
64
+ /\.workers\.dev$/,
65
+ ];
66
+ // ---------------------------------------------------------------------------
67
+ // Constants
68
+ // ---------------------------------------------------------------------------
69
+ const SIGNATURE_HEADER = "x-manus-signature";
70
+ /** 7-day TTL for idempotency keys. */
71
+ const DEDUP_TTL_SECONDS = 7 * 24 * 3600;
72
+ /** 24-hour TTL for pending-ask entries. */
73
+ export const PENDING_ASK_TTL_SECONDS = 24 * 3600;
74
+ /** KV key prefix for pending-ask entries. */
75
+ export const PENDING_ASK_PREFIX = "manus_pending_ask:";
76
+ /** Max chars of question to store in AE audit (credentials protection). */
77
+ const QUESTION_TRUNCATE_CHARS = 200;
78
+ // ---------------------------------------------------------------------------
79
+ // Handler entry point
80
+ // ---------------------------------------------------------------------------
81
+ export async function handleManusWebhook(request, env) {
82
+ if (!env.MANUS_WEBHOOK_SECRET) {
83
+ console.error("[manus-webhook] MANUS_WEBHOOK_SECRET not configured");
84
+ return new Response("Webhook receiver not configured", { status: 503 });
85
+ }
86
+ // 1. Read raw body (must happen before any .json() / .text() calls)
87
+ const body = await request.text();
88
+ // 2. Verify HMAC-SHA256 signature
89
+ const sigHeader = request.headers.get(SIGNATURE_HEADER);
90
+ const verified = await verifyHmacSignature(body, sigHeader, env.MANUS_WEBHOOK_SECRET);
91
+ if (!verified) {
92
+ console.warn("[manus-webhook] rejected — invalid or missing signature");
93
+ return new Response("Unauthorized", { status: 401 });
94
+ }
95
+ // 3. Parse payload
96
+ let payload;
97
+ try {
98
+ payload = JSON.parse(body);
99
+ }
100
+ catch {
101
+ return new Response("Invalid JSON body", { status: 400 });
102
+ }
103
+ if (!payload.event_id || !payload.event_type || !payload.task_detail?.task_id) {
104
+ return new Response("Missing required fields: event_id, event_type, task_detail.task_id", { status: 400 });
105
+ }
106
+ const { event_id, event_type, task_detail, attachments, stop_reason, message } = payload;
107
+ const { task_id } = task_detail;
108
+ // 4. Idempotency — CARRIER_USERS KV, 7-day TTL
109
+ const dedupKey = `manus_event:${event_id}`;
110
+ const alreadyProcessed = await env.CARRIER_USERS.get(dedupKey);
111
+ if (alreadyProcessed !== null) {
112
+ console.log(`[manus-webhook] deduplicated event_id=${event_id}`);
113
+ return Response.json({ ok: true, deduplicated: true });
114
+ }
115
+ // 5. Mark as processed (write before handling so concurrent replays are safe)
116
+ await env.CARRIER_USERS.put(dedupKey, "1", {
117
+ expirationTtl: DEDUP_TTL_SECONDS,
118
+ });
119
+ try {
120
+ // 6. Handle event
121
+ if (event_type === "task_created") {
122
+ handleTaskCreated(env, task_id, event_id);
123
+ return Response.json({ ok: true });
124
+ }
125
+ if (event_type === "task_stopped") {
126
+ await handleTaskStopped(env, task_id, event_id, stop_reason, attachments, message, task_detail.task_url);
127
+ return Response.json({ ok: true });
128
+ }
129
+ // Unknown event type — log + ack
130
+ console.log(`[manus-webhook] unknown event_type=${event_type} task_id=${task_id}`);
131
+ return Response.json({ ok: true });
132
+ }
133
+ catch (err) {
134
+ try {
135
+ await env.CARRIER_USERS.delete(dedupKey);
136
+ }
137
+ catch (rollbackErr) {
138
+ console.error(`[manus-webhook] dedup rollback failed: ${rollbackErr.message}`);
139
+ }
140
+ throw err;
141
+ }
142
+ }
143
+ // ---------------------------------------------------------------------------
144
+ // Event handlers
145
+ // ---------------------------------------------------------------------------
146
+ function handleTaskCreated(env, task_id, event_id) {
147
+ console.log(`[manus-webhook] task_created task_id=${task_id} event_id=${event_id}`);
148
+ writeManusAudit(env, {
149
+ event_type: "task_created",
150
+ task_id,
151
+ stop_reason: "",
152
+ attachment_count: 0,
153
+ latency_ms: 0,
154
+ });
155
+ }
156
+ async function handleTaskStopped(env, task_id, event_id, stop_reason, attachments, message, task_url) {
157
+ const reason = stop_reason ?? "unknown";
158
+ const attachmentCount = attachments?.length ?? 0;
159
+ if (reason === "finish") {
160
+ console.log(`[manus-webhook] task_stopped:finish task_id=${task_id} attachments=${attachmentCount}`);
161
+ if (attachmentCount > 0) {
162
+ const urls = (attachments ?? []).map((a) => `${a.name}: ${a.url}`).join(", ");
163
+ console.log(`[manus-webhook] attachments task_id=${task_id} urls=[${urls}]`);
164
+ }
165
+ // Persist attachments to R2 before clearing the pending-ask entry.
166
+ if (attachmentCount > 0) {
167
+ for (const attachment of attachments ?? []) {
168
+ await persistAttachmentToR2(env, task_id, attachment);
169
+ }
170
+ }
171
+ // Clear any pending-ask entry now that the task has finished.
172
+ const pendingKey = `${PENDING_ASK_PREFIX}${task_id}`;
173
+ await env.CARRIER_USERS.delete(pendingKey);
174
+ console.log(`[manus-webhook] cleared pending-ask for task_id=${task_id}`);
175
+ }
176
+ else if (reason === "ask") {
177
+ const question = message ?? "";
178
+ const truncatedQuestion = question.slice(0, QUESTION_TRUNCATE_CHARS);
179
+ console.log(`[manus-webhook] task_stopped:needs_user_input task_id=${task_id} question_len=${question.length}`);
180
+ // Write pending-ask entry to KV with 24h TTL.
181
+ const pendingKey = `${PENDING_ASK_PREFIX}${task_id}`;
182
+ const pendingEntry = {
183
+ task_id,
184
+ question,
185
+ task_url: task_url ?? "",
186
+ asked_at: new Date().toISOString(),
187
+ };
188
+ await env.CARRIER_USERS.put(pendingKey, JSON.stringify(pendingEntry), {
189
+ expirationTtl: PENDING_ASK_TTL_SECONDS,
190
+ });
191
+ // Emit ask-specific AE event with truncated question (blobs[2]="ui_agent_awaiting_input").
192
+ // The generic writeManusAudit below also fires (blobs[2]="ask") for compatibility.
193
+ writeManusAuditAsk(env, {
194
+ task_id,
195
+ truncated_question: truncatedQuestion,
196
+ event_id,
197
+ });
198
+ }
199
+ else {
200
+ console.log(`[manus-webhook] task_stopped:${reason} task_id=${task_id} event_id=${event_id}`);
201
+ }
202
+ writeManusAudit(env, {
203
+ event_type: "task_stopped",
204
+ task_id,
205
+ stop_reason: reason,
206
+ attachment_count: attachmentCount,
207
+ latency_ms: 0, // no task_created timestamp available without a lookup; 0 is accurate per current design
208
+ });
209
+ }
210
+ // ---------------------------------------------------------------------------
211
+ // R2 attachment persistence
212
+ // ---------------------------------------------------------------------------
213
+ /**
214
+ * Fetch an attachment from Manus and stream it to R2.
215
+ * Skips CF-hosted URLs (already on Cloudflare infrastructure).
216
+ * Enforces 25 MB cap via Content-Length header and buffer size check.
217
+ */
218
+ async function persistAttachmentToR2(env, task_id, attachment) {
219
+ // Skip CF-hosted URLs — no re-upload needed
220
+ try {
221
+ const hostname = new URL(attachment.url).hostname;
222
+ if (CF_ZONE_PATTERNS.some((re) => re.test(hostname))) {
223
+ console.log(`[manus-webhook] skipping CF-hosted attachment url=${attachment.url}`);
224
+ return;
225
+ }
226
+ }
227
+ catch {
228
+ console.warn(`[manus-webhook] invalid attachment URL: ${attachment.url}`);
229
+ return;
230
+ }
231
+ let res;
232
+ try {
233
+ res = await fetch(attachment.url);
234
+ }
235
+ catch (err) {
236
+ console.error(`[manus-webhook] fetch attachment failed url=${attachment.url}: ${err.message}`);
237
+ return;
238
+ }
239
+ if (!res.ok) {
240
+ console.warn(`[manus-webhook] attachment fetch non-ok status=${res.status} url=${attachment.url}`);
241
+ return;
242
+ }
243
+ // Check Content-Length header before buffering
244
+ const contentLengthHeader = res.headers.get("content-length");
245
+ if (contentLengthHeader !== null) {
246
+ const declared = parseInt(contentLengthHeader, 10);
247
+ if (!isNaN(declared) && declared > MAX_ATTACHMENT_BYTES) {
248
+ console.warn(`[manus-webhook] attachment too large (content-length=${declared}) url=${attachment.url} — skipping`);
249
+ return;
250
+ }
251
+ }
252
+ let buffer;
253
+ try {
254
+ buffer = await res.arrayBuffer();
255
+ }
256
+ catch (err) {
257
+ console.error(`[manus-webhook] attachment buffer failed: ${err.message}`);
258
+ return;
259
+ }
260
+ if (buffer.byteLength > MAX_ATTACHMENT_BYTES) {
261
+ console.warn(`[manus-webhook] attachment too large (actual=${buffer.byteLength}) url=${attachment.url} — skipping`);
262
+ return;
263
+ }
264
+ const filename = sanitiseFilename(attachment.name);
265
+ const r2Key = `${R2_PREFIX}/${task_id}/${filename}`;
266
+ const contentType = res.headers.get("content-type") ?? "application/octet-stream";
267
+ try {
268
+ await env.DOWNLOADS.put(r2Key, buffer, {
269
+ httpMetadata: { contentType },
270
+ });
271
+ console.log(`[manus-webhook] stored attachment r2=${r2Key} size=${buffer.byteLength}`);
272
+ }
273
+ catch (err) {
274
+ console.error(`[manus-webhook] R2 put failed key=${r2Key}: ${err.message}`);
275
+ }
276
+ }
277
+ /**
278
+ * Sanitise an attachment filename for safe use as an R2 key component.
279
+ * - Strips path separators
280
+ * - Collapses whitespace to underscores
281
+ * - Replaces unsafe characters
282
+ * - Truncates to 200 chars
283
+ */
284
+ function sanitiseFilename(name) {
285
+ return name
286
+ .replace(/[/\\]/g, "_")
287
+ .replace(/\s+/g, "_")
288
+ .replace(/[^a-zA-Z0-9._\-]/g, "_")
289
+ .slice(0, 200);
290
+ }
291
+ function writeManusAudit(env, entry) {
292
+ // Fire-and-forget — AE writes are best-effort
293
+ try {
294
+ env.AUDIT_LOG.writeDataPoint({
295
+ blobs: [
296
+ "manus_webhook",
297
+ entry.event_type,
298
+ entry.stop_reason,
299
+ entry.task_id,
300
+ String(entry.attachment_count),
301
+ ],
302
+ doubles: [entry.latency_ms],
303
+ indexes: [entry.task_id],
304
+ });
305
+ }
306
+ catch (err) {
307
+ console.error(`[manus-webhook] audit write failed: ${err.message}`);
308
+ }
309
+ }
310
+ function writeManusAuditAsk(env, entry) {
311
+ // Separate AE event for ask-path — status distinguishes from finish.
312
+ // blobs[2] = "ui_agent_awaiting_input" distinguishes from "finish" status.
313
+ try {
314
+ env.AUDIT_LOG.writeDataPoint({
315
+ blobs: [
316
+ "manus_webhook",
317
+ "task_stopped",
318
+ "ui_agent_awaiting_input",
319
+ entry.task_id,
320
+ entry.truncated_question,
321
+ entry.event_id,
322
+ ],
323
+ doubles: [0],
324
+ indexes: [entry.task_id],
325
+ });
326
+ }
327
+ catch (err) {
328
+ console.error(`[manus-webhook] ask audit write failed: ${err.message}`);
329
+ }
330
+ }
331
+ // ---------------------------------------------------------------------------
332
+ // HMAC-SHA256 signature verification
333
+ // ---------------------------------------------------------------------------
334
+ /**
335
+ * Verify HMAC-SHA256 signature from Manus.
336
+ * Header value is a raw hex string (64 chars, no "sha256=" prefix).
337
+ * Falls back to also accepting "sha256=<hex>" for forward-compat.
338
+ */
339
+ async function verifyHmacSignature(body, header, secret) {
340
+ if (!header)
341
+ return false;
342
+ // Accept raw hex or "sha256=<hex>"
343
+ const hex = header.startsWith("sha256=") ? header.slice(7) : header;
344
+ if (!/^[0-9a-f]{64}$/i.test(hex))
345
+ return false;
346
+ const enc = new TextEncoder();
347
+ let keyMaterial;
348
+ try {
349
+ keyMaterial = await crypto.subtle.importKey("raw", enc.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
350
+ }
351
+ catch {
352
+ return false;
353
+ }
354
+ const sig = await crypto.subtle.sign("HMAC", keyMaterial, enc.encode(body));
355
+ const computed = Array.from(new Uint8Array(sig))
356
+ .map((b) => b.toString(16).padStart(2, "0"))
357
+ .join("");
358
+ const normalizedHex = hex.toLowerCase();
359
+ return timingSafeEqual(computed, normalizedHex);
360
+ }
361
+ //# sourceMappingURL=manus-webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manus-webhook.js","sourceRoot":"","sources":["../src/manus-webhook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Carrier MCP — Pricing & Credits MCP Tools
3
+ *
4
+ * Exposes credit management, billing configuration, and usage analytics
5
+ * as MCP tools. These tools allow AI agents and users to:
6
+ * - Check credit balance and usage
7
+ * - Configure billing thresholds
8
+ * - View volume discount status
9
+ * - Manage overage settings
10
+ * - View billing history and projections
11
+ *
12
+ * Inspired by Stripe Projects CLI patterns:
13
+ * - `stripe projects billing show` → credit_balance
14
+ * - `stripe projects upgrade` → upgrade_plan
15
+ * - `stripe projects billing add` → configure_billing
16
+ */
17
+ import type { Env, CarrierProps, ToolScope } from "./types.js";
18
+ export interface PricingToolDef {
19
+ name: string;
20
+ description: string;
21
+ scope: ToolScope;
22
+ inputSchema: Record<string, unknown>;
23
+ handler: (env: Env, props: CarrierProps, args: Record<string, unknown>) => Promise<unknown>;
24
+ }
25
+ export declare const PRICING_TOOLS: PricingToolDef[];
26
+ //# sourceMappingURL=pricing-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing-tools.d.ts","sourceRoot":"","sources":["../src/pricing-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAsB/D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,CACP,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAED,eAAO,MAAM,aAAa,EAAE,cAAc,EAmXzC,CAAC"}