@carrierllc/mcp 0.0.1 → 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.
- package/README.md +216 -3
- package/dist/apps/app-state.d.ts +19 -0
- package/dist/apps/app-state.d.ts.map +1 -0
- package/dist/apps/app-state.js +28 -0
- package/dist/apps/app-state.js.map +1 -0
- package/dist/apps/balance-topup.d.ts +19 -0
- package/dist/apps/balance-topup.d.ts.map +1 -0
- package/dist/apps/balance-topup.js +121 -0
- package/dist/apps/balance-topup.js.map +1 -0
- package/dist/apps/fleet-health-app.d.ts +29 -0
- package/dist/apps/fleet-health-app.d.ts.map +1 -0
- package/dist/apps/fleet-health-app.js +152 -0
- package/dist/apps/fleet-health-app.js.map +1 -0
- package/dist/apps/index.d.ts +37 -0
- package/dist/apps/index.d.ts.map +1 -0
- package/dist/apps/index.js +42 -0
- package/dist/apps/index.js.map +1 -0
- package/dist/apps/provisioning-wizard.d.ts +11 -0
- package/dist/apps/provisioning-wizard.d.ts.map +1 -0
- package/dist/apps/provisioning-wizard.js +345 -0
- package/dist/apps/provisioning-wizard.js.map +1 -0
- package/dist/audit.d.ts +31 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +42 -0
- package/dist/audit.js.map +1 -0
- package/dist/billing-thresholds.d.ts +71 -0
- package/dist/billing-thresholds.d.ts.map +1 -0
- package/dist/billing-thresholds.js +238 -0
- package/dist/billing-thresholds.js.map +1 -0
- package/dist/billing.d.ts +95 -0
- package/dist/billing.d.ts.map +1 -0
- package/dist/billing.js +239 -0
- package/dist/billing.js.map +1 -0
- package/dist/clerk.d.ts +125 -0
- package/dist/clerk.d.ts.map +1 -0
- package/dist/clerk.js +389 -0
- package/dist/clerk.js.map +1 -0
- package/dist/client.d.ts +35 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +75 -0
- package/dist/client.js.map +1 -0
- package/dist/credits.d.ts +165 -0
- package/dist/credits.d.ts.map +1 -0
- package/dist/credits.js +483 -0
- package/dist/credits.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/intelligence.d.ts +4 -0
- package/dist/intelligence.d.ts.map +1 -0
- package/dist/intelligence.js +899 -0
- package/dist/intelligence.js.map +1 -0
- package/dist/list-recent-ocs-events.d.ts +48 -0
- package/dist/list-recent-ocs-events.d.ts.map +1 -0
- package/dist/list-recent-ocs-events.js +160 -0
- package/dist/list-recent-ocs-events.js.map +1 -0
- package/dist/manus-client.d.ts +429 -0
- package/dist/manus-client.d.ts.map +1 -0
- package/dist/manus-client.js +401 -0
- package/dist/manus-client.js.map +1 -0
- package/dist/manus-common.d.ts +5 -0
- package/dist/manus-common.d.ts.map +1 -0
- package/dist/manus-common.js +5 -0
- package/dist/manus-common.js.map +1 -0
- package/dist/manus-schedule.d.ts +74 -0
- package/dist/manus-schedule.d.ts.map +1 -0
- package/dist/manus-schedule.js +213 -0
- package/dist/manus-schedule.js.map +1 -0
- package/dist/manus-usage.d.ts +32 -0
- package/dist/manus-usage.d.ts.map +1 -0
- package/dist/manus-usage.js +120 -0
- package/dist/manus-usage.js.map +1 -0
- package/dist/manus-webhook.d.ts +60 -0
- package/dist/manus-webhook.d.ts.map +1 -0
- package/dist/manus-webhook.js +361 -0
- package/dist/manus-webhook.js.map +1 -0
- package/dist/pricing-tools.d.ts +26 -0
- package/dist/pricing-tools.d.ts.map +1 -0
- package/dist/pricing-tools.js +428 -0
- package/dist/pricing-tools.js.map +1 -0
- package/dist/projects-tools.d.ts +39 -0
- package/dist/projects-tools.d.ts.map +1 -0
- package/dist/projects-tools.js +545 -0
- package/dist/projects-tools.js.map +1 -0
- package/dist/prompts.d.ts +7 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +151 -0
- package/dist/prompts.js.map +1 -0
- package/dist/stripe-connect-tools.d.ts +33 -0
- package/dist/stripe-connect-tools.d.ts.map +1 -0
- package/dist/stripe-connect-tools.js +504 -0
- package/dist/stripe-connect-tools.js.map +1 -0
- package/dist/timing-safe-equal.d.ts +5 -0
- package/dist/timing-safe-equal.d.ts.map +1 -0
- package/dist/timing-safe-equal.js +13 -0
- package/dist/timing-safe-equal.js.map +1 -0
- package/dist/tools-backlog.d.ts +28 -0
- package/dist/tools-backlog.d.ts.map +1 -0
- package/dist/tools-backlog.js +315 -0
- package/dist/tools-backlog.js.map +1 -0
- package/dist/tools-carrier-ask.d.ts +138 -0
- package/dist/tools-carrier-ask.d.ts.map +1 -0
- package/dist/tools-carrier-ask.js +913 -0
- package/dist/tools-carrier-ask.js.map +1 -0
- package/dist/tools-pricing.d.ts +18 -0
- package/dist/tools-pricing.d.ts.map +1 -0
- package/dist/tools-pricing.js +172 -0
- package/dist/tools-pricing.js.map +1 -0
- package/dist/tools-ui-agent-ask.d.ts +29 -0
- package/dist/tools-ui-agent-ask.d.ts.map +1 -0
- package/dist/tools-ui-agent-ask.js +272 -0
- package/dist/tools-ui-agent-ask.js.map +1 -0
- package/dist/tools-ui-agent-schedule.d.ts +29 -0
- package/dist/tools-ui-agent-schedule.d.ts.map +1 -0
- package/dist/tools-ui-agent-schedule.js +517 -0
- package/dist/tools-ui-agent-schedule.js.map +1 -0
- package/dist/tools-ui-agent.d.ts +40 -0
- package/dist/tools-ui-agent.d.ts.map +1 -0
- package/dist/tools-ui-agent.js +508 -0
- package/dist/tools-ui-agent.js.map +1 -0
- package/dist/tools.d.ts +60 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +1295 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +291 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -7
- package/index.js +0 -1
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Carrier MCP — Stripe Connect tools (Phase 16).
|
|
3
|
+
*
|
|
4
|
+
* Provides AI-agent access to the operator Stripe Connect layer.
|
|
5
|
+
* All tools call the Stripe API directly using STRIPE_SECRET_KEY from env.
|
|
6
|
+
* The connected account ID is looked up from CARRIER_USERS KV
|
|
7
|
+
* under key `stripe_account:<operatorId>`.
|
|
8
|
+
*
|
|
9
|
+
* Tools registered here:
|
|
10
|
+
* stripe_connect_status — read-only: account status + capabilities
|
|
11
|
+
* stripe_connect_payouts — read-only: list recent payouts
|
|
12
|
+
* stripe_connect_balance — read-only: available + pending balance
|
|
13
|
+
* stripe_connect_refund — write (HARD_BLOCK): refund a charge
|
|
14
|
+
* stripe_connect_dispute_list — read-only: list active disputes
|
|
15
|
+
* radar_review_list — read-only: list pending Radar reviews
|
|
16
|
+
* radar_review_approve — admin (HARD_BLOCK): approve a review
|
|
17
|
+
* radar_review_decline — admin (HARD_BLOCK): decline/close a review
|
|
18
|
+
* radar_value_list_add — admin (HARD_BLOCK): add to block/allow list
|
|
19
|
+
* radar_rule_toggle — admin: documented stub (Stripe API limitation)
|
|
20
|
+
*
|
|
21
|
+
* HARD_BLOCK pattern: destructive tools require a confirm_token stored in
|
|
22
|
+
* OAUTH_KV with a 5-min TTL (same pattern as pricing-tools.ts).
|
|
23
|
+
*/
|
|
24
|
+
import { z } from "zod";
|
|
25
|
+
import * as Sentry from "@sentry/cloudflare";
|
|
26
|
+
import { writeAudit } from "./audit.js";
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Helpers
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
/** Hard-block confirm token stored in KV with 5-min TTL. */
|
|
31
|
+
async function verifyConfirmToken(env, sub, toolName, token) {
|
|
32
|
+
const key = `confirm:${sub}:${toolName}`;
|
|
33
|
+
const stored = await env.OAUTH_KV.get(key);
|
|
34
|
+
if (!stored || stored !== token)
|
|
35
|
+
return false;
|
|
36
|
+
await env.OAUTH_KV.delete(key); // single-use
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
async function issueConfirmToken(env, sub, toolName) {
|
|
40
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
41
|
+
const token = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
42
|
+
const key = `confirm:${sub}:${toolName}`;
|
|
43
|
+
await env.OAUTH_KV.put(key, token, { expirationTtl: 300 }); // 5 min TTL
|
|
44
|
+
return token;
|
|
45
|
+
}
|
|
46
|
+
function ok(text) {
|
|
47
|
+
return { content: [{ type: "text", text }] };
|
|
48
|
+
}
|
|
49
|
+
function err(text) {
|
|
50
|
+
return { isError: true, content: [{ type: "text", text }] };
|
|
51
|
+
}
|
|
52
|
+
/** Call Stripe REST API (GET). */
|
|
53
|
+
async function stripeGet(stripeKey, path, connectedAccountId) {
|
|
54
|
+
const headers = { Authorization: `Bearer ${stripeKey}` };
|
|
55
|
+
if (connectedAccountId)
|
|
56
|
+
headers["Stripe-Account"] = connectedAccountId;
|
|
57
|
+
const res = await fetch(`https://api.stripe.com${path}`, { headers });
|
|
58
|
+
const data = (await res.json());
|
|
59
|
+
return { ok: res.ok, status: res.status, data };
|
|
60
|
+
}
|
|
61
|
+
/** Call Stripe REST API (POST, form-encoded). */
|
|
62
|
+
async function stripePost(stripeKey, path, params, connectedAccountId) {
|
|
63
|
+
const headers = {
|
|
64
|
+
Authorization: `Bearer ${stripeKey}`,
|
|
65
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
66
|
+
};
|
|
67
|
+
if (connectedAccountId)
|
|
68
|
+
headers["Stripe-Account"] = connectedAccountId;
|
|
69
|
+
const res = await fetch(`https://api.stripe.com${path}`, {
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers,
|
|
72
|
+
body: new URLSearchParams(params).toString(),
|
|
73
|
+
});
|
|
74
|
+
const data = (await res.json());
|
|
75
|
+
return { ok: res.ok, status: res.status, data };
|
|
76
|
+
}
|
|
77
|
+
/** Doc + registry merge — mirrors the tool inventory in this file's header comment. */
|
|
78
|
+
export const STRIPE_CONNECT_TOOL_SCOPES = {
|
|
79
|
+
stripe_connect_status: "read",
|
|
80
|
+
stripe_connect_payouts: "read",
|
|
81
|
+
stripe_connect_balance: "read",
|
|
82
|
+
stripe_connect_refund: "write",
|
|
83
|
+
stripe_connect_dispute_list: "read",
|
|
84
|
+
radar_review_list: "read",
|
|
85
|
+
radar_review_approve: "admin",
|
|
86
|
+
radar_review_decline: "admin",
|
|
87
|
+
radar_value_list_add: "admin",
|
|
88
|
+
radar_rule_toggle: "admin",
|
|
89
|
+
};
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
// Registration
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
export function registerStripeConnectTools(server, ctx) {
|
|
94
|
+
const { env, props } = ctx;
|
|
95
|
+
const operatorId = props.org_id ?? props.sub;
|
|
96
|
+
const kvKey = `stripe_account:${operatorId}`;
|
|
97
|
+
/** Look up the operator's connected Stripe account ID from KV. */
|
|
98
|
+
async function getAccountId() {
|
|
99
|
+
return env.CARRIER_USERS.get(kvKey);
|
|
100
|
+
}
|
|
101
|
+
// -------------------------------------------------------------------------
|
|
102
|
+
// stripe_connect_status
|
|
103
|
+
// -------------------------------------------------------------------------
|
|
104
|
+
server.tool("stripe_connect_status", "Read-only: returns the Stripe Connect account status, capabilities, and requirements for the authenticated operator.", {
|
|
105
|
+
operator_id: z
|
|
106
|
+
.string()
|
|
107
|
+
.optional()
|
|
108
|
+
.describe("Override operator_id (admin use). Defaults to caller's org/user."),
|
|
109
|
+
}, async ({ operator_id }) => {
|
|
110
|
+
const opId = operator_id ?? operatorId;
|
|
111
|
+
const opKvKey = operator_id ? `stripe_account:${operator_id}` : kvKey;
|
|
112
|
+
const start = Date.now();
|
|
113
|
+
try {
|
|
114
|
+
const stripeKey = env.STRIPE_SECRET_KEY;
|
|
115
|
+
if (!stripeKey)
|
|
116
|
+
return err("Stripe not configured");
|
|
117
|
+
const accountId = await env.CARRIER_USERS.get(opKvKey);
|
|
118
|
+
if (!accountId) {
|
|
119
|
+
return ok(JSON.stringify({ status: "not_connected", operator_id: opId }));
|
|
120
|
+
}
|
|
121
|
+
const result = await stripeGet(stripeKey, `/v1/accounts/${accountId}`);
|
|
122
|
+
if (!result.ok)
|
|
123
|
+
return err(`Stripe error: ${JSON.stringify(result.data)}`);
|
|
124
|
+
const a = result.data;
|
|
125
|
+
const status = a.charges_enabled && a.details_submitted ? "active" : "pending";
|
|
126
|
+
writeAudit(env, {
|
|
127
|
+
tool_name: "stripe_connect_status",
|
|
128
|
+
ocs_method: "stripe.account.read",
|
|
129
|
+
status: "ok",
|
|
130
|
+
dry_run: false,
|
|
131
|
+
duration_ms: Date.now() - start,
|
|
132
|
+
sub: props.sub,
|
|
133
|
+
reseller_id: props.reseller_id,
|
|
134
|
+
});
|
|
135
|
+
return ok(JSON.stringify({
|
|
136
|
+
status,
|
|
137
|
+
operator_id: opId,
|
|
138
|
+
account_id: accountId,
|
|
139
|
+
charges_enabled: a.charges_enabled,
|
|
140
|
+
payouts_enabled: a.payouts_enabled,
|
|
141
|
+
details_submitted: a.details_submitted,
|
|
142
|
+
requirements: a.requirements,
|
|
143
|
+
capabilities: a.capabilities,
|
|
144
|
+
default_currency: a.default_currency,
|
|
145
|
+
payout_schedule: a.settings?.payouts?.schedule,
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
Sentry.captureException(e);
|
|
150
|
+
return err(`Error: ${e instanceof Error ? e.message : "unknown"}`);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
// -------------------------------------------------------------------------
|
|
154
|
+
// stripe_connect_payouts
|
|
155
|
+
// -------------------------------------------------------------------------
|
|
156
|
+
server.tool("stripe_connect_payouts", "Read-only: list recent payouts for the operator's connected Stripe account.", {
|
|
157
|
+
limit: z.number().int().min(1).max(50).default(10).describe("Number of payouts to return."),
|
|
158
|
+
status: z
|
|
159
|
+
.enum(["pending", "paid", "failed", "canceled", "in_transit"])
|
|
160
|
+
.optional()
|
|
161
|
+
.describe("Filter by payout status."),
|
|
162
|
+
}, async ({ limit, status }) => {
|
|
163
|
+
const start = Date.now();
|
|
164
|
+
try {
|
|
165
|
+
const stripeKey = env.STRIPE_SECRET_KEY;
|
|
166
|
+
if (!stripeKey)
|
|
167
|
+
return err("Stripe not configured");
|
|
168
|
+
const accountId = await getAccountId();
|
|
169
|
+
if (!accountId)
|
|
170
|
+
return err("No connected Stripe account found.");
|
|
171
|
+
const params = new URLSearchParams({ limit: String(limit) });
|
|
172
|
+
if (status)
|
|
173
|
+
params.set("status", status);
|
|
174
|
+
const result = await stripeGet(stripeKey, `/v1/payouts?${params.toString()}`, accountId);
|
|
175
|
+
if (!result.ok)
|
|
176
|
+
return err(`Stripe error: ${JSON.stringify(result.data)}`);
|
|
177
|
+
writeAudit(env, {
|
|
178
|
+
tool_name: "stripe_connect_payouts",
|
|
179
|
+
ocs_method: "stripe.payouts.list",
|
|
180
|
+
status: "ok",
|
|
181
|
+
dry_run: false,
|
|
182
|
+
duration_ms: Date.now() - start,
|
|
183
|
+
sub: props.sub,
|
|
184
|
+
reseller_id: props.reseller_id,
|
|
185
|
+
});
|
|
186
|
+
return ok(JSON.stringify({ payouts: result.data.data, has_more: result.data.has_more }));
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
Sentry.captureException(e);
|
|
190
|
+
return err(`Error: ${e instanceof Error ? e.message : "unknown"}`);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
// -------------------------------------------------------------------------
|
|
194
|
+
// stripe_connect_balance
|
|
195
|
+
// -------------------------------------------------------------------------
|
|
196
|
+
server.tool("stripe_connect_balance", "Read-only: returns the current available and pending balance per currency for the operator's connected Stripe account.", {}, async () => {
|
|
197
|
+
const start = Date.now();
|
|
198
|
+
try {
|
|
199
|
+
const stripeKey = env.STRIPE_SECRET_KEY;
|
|
200
|
+
if (!stripeKey)
|
|
201
|
+
return err("Stripe not configured");
|
|
202
|
+
const accountId = await getAccountId();
|
|
203
|
+
if (!accountId)
|
|
204
|
+
return err("No connected Stripe account found.");
|
|
205
|
+
const result = await stripeGet(stripeKey, `/v1/balance`, accountId);
|
|
206
|
+
if (!result.ok)
|
|
207
|
+
return err(`Stripe error: ${JSON.stringify(result.data)}`);
|
|
208
|
+
writeAudit(env, {
|
|
209
|
+
tool_name: "stripe_connect_balance",
|
|
210
|
+
ocs_method: "stripe.balance.read",
|
|
211
|
+
status: "ok",
|
|
212
|
+
dry_run: false,
|
|
213
|
+
duration_ms: Date.now() - start,
|
|
214
|
+
sub: props.sub,
|
|
215
|
+
reseller_id: props.reseller_id,
|
|
216
|
+
});
|
|
217
|
+
return ok(JSON.stringify({
|
|
218
|
+
account_id: accountId,
|
|
219
|
+
available: result.data.available ?? [],
|
|
220
|
+
pending: result.data.pending ?? [],
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
catch (e) {
|
|
224
|
+
Sentry.captureException(e);
|
|
225
|
+
return err(`Error: ${e instanceof Error ? e.message : "unknown"}`);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
// -------------------------------------------------------------------------
|
|
229
|
+
// stripe_connect_refund (HARD_BLOCK)
|
|
230
|
+
// -------------------------------------------------------------------------
|
|
231
|
+
server.tool("stripe_connect_refund", "Admin: issue a refund on a charge via the operator's connected Stripe account. Requires confirm_token (call without token first to get one).", {
|
|
232
|
+
charge_id: z.string().min(1).describe("Stripe charge ID (ch_...)."),
|
|
233
|
+
amount_cents: z
|
|
234
|
+
.number()
|
|
235
|
+
.int()
|
|
236
|
+
.min(1)
|
|
237
|
+
.optional()
|
|
238
|
+
.describe("Partial refund amount in cents. Omit for full refund."),
|
|
239
|
+
reason: z.enum(["duplicate", "fraudulent", "requested_by_customer"]).optional(),
|
|
240
|
+
confirm_token: z
|
|
241
|
+
.string()
|
|
242
|
+
.optional()
|
|
243
|
+
.describe("Confirmation token from previous call. Required to execute."),
|
|
244
|
+
}, async ({ charge_id, amount_cents, reason, confirm_token }) => {
|
|
245
|
+
const start = Date.now();
|
|
246
|
+
const toolName = "stripe_connect_refund";
|
|
247
|
+
if (!confirm_token) {
|
|
248
|
+
const token = await issueConfirmToken(env, props.sub, toolName);
|
|
249
|
+
return ok(`HARD_BLOCK: Refund ${amount_cents ? `${amount_cents} cents on` : "(full) on"} charge ${charge_id} requires confirmation.\n` +
|
|
250
|
+
`confirm_token: ${token}\n` +
|
|
251
|
+
`Call again with confirm_token="${token}" to execute. Token expires in 5 minutes.`);
|
|
252
|
+
}
|
|
253
|
+
const valid = await verifyConfirmToken(env, props.sub, toolName, confirm_token);
|
|
254
|
+
if (!valid) {
|
|
255
|
+
return err("Invalid or expired confirm_token. Call without token to get a new one.");
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
const stripeKey = env.STRIPE_SECRET_KEY;
|
|
259
|
+
if (!stripeKey)
|
|
260
|
+
return err("Stripe not configured");
|
|
261
|
+
const accountId = await getAccountId();
|
|
262
|
+
if (!accountId)
|
|
263
|
+
return err("No connected Stripe account found.");
|
|
264
|
+
const params = { charge: charge_id };
|
|
265
|
+
if (amount_cents)
|
|
266
|
+
params.amount = String(amount_cents);
|
|
267
|
+
if (reason)
|
|
268
|
+
params.reason = reason;
|
|
269
|
+
const result = await stripePost(stripeKey, "/v1/refunds", params, accountId);
|
|
270
|
+
if (!result.ok)
|
|
271
|
+
return err(`Stripe error: ${JSON.stringify(result.data)}`);
|
|
272
|
+
writeAudit(env, {
|
|
273
|
+
tool_name: toolName,
|
|
274
|
+
ocs_method: "stripe.refund.create",
|
|
275
|
+
status: "ok",
|
|
276
|
+
dry_run: false,
|
|
277
|
+
duration_ms: Date.now() - start,
|
|
278
|
+
sub: props.sub,
|
|
279
|
+
reseller_id: props.reseller_id,
|
|
280
|
+
});
|
|
281
|
+
return ok(`Refund issued: ${result.data.id} — status: ${result.data.status}`);
|
|
282
|
+
}
|
|
283
|
+
catch (e) {
|
|
284
|
+
Sentry.captureException(e);
|
|
285
|
+
return err(`Error: ${e instanceof Error ? e.message : "unknown"}`);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
// -------------------------------------------------------------------------
|
|
289
|
+
// stripe_connect_dispute_list
|
|
290
|
+
// -------------------------------------------------------------------------
|
|
291
|
+
server.tool("stripe_connect_dispute_list", "Read-only: list active disputes for the operator's connected Stripe account.", {
|
|
292
|
+
limit: z.number().int().min(1).max(50).default(10),
|
|
293
|
+
status: z
|
|
294
|
+
.string()
|
|
295
|
+
.optional()
|
|
296
|
+
.describe("Filter by dispute status (e.g. needs_response, under_review)."),
|
|
297
|
+
}, async ({ limit, status }) => {
|
|
298
|
+
const start = Date.now();
|
|
299
|
+
try {
|
|
300
|
+
const stripeKey = env.STRIPE_SECRET_KEY;
|
|
301
|
+
if (!stripeKey)
|
|
302
|
+
return err("Stripe not configured");
|
|
303
|
+
const accountId = await getAccountId();
|
|
304
|
+
if (!accountId)
|
|
305
|
+
return err("No connected Stripe account found.");
|
|
306
|
+
const params = new URLSearchParams({ limit: String(limit) });
|
|
307
|
+
if (status)
|
|
308
|
+
params.set("status", status);
|
|
309
|
+
const result = await stripeGet(stripeKey, `/v1/disputes?${params.toString()}`, accountId);
|
|
310
|
+
if (!result.ok)
|
|
311
|
+
return err(`Stripe error: ${JSON.stringify(result.data)}`);
|
|
312
|
+
writeAudit(env, {
|
|
313
|
+
tool_name: "stripe_connect_dispute_list",
|
|
314
|
+
ocs_method: "stripe.disputes.list",
|
|
315
|
+
status: "ok",
|
|
316
|
+
dry_run: false,
|
|
317
|
+
duration_ms: Date.now() - start,
|
|
318
|
+
sub: props.sub,
|
|
319
|
+
reseller_id: props.reseller_id,
|
|
320
|
+
});
|
|
321
|
+
return ok(JSON.stringify({ disputes: result.data.data, has_more: result.data.has_more }));
|
|
322
|
+
}
|
|
323
|
+
catch (e) {
|
|
324
|
+
Sentry.captureException(e);
|
|
325
|
+
return err(`Error: ${e instanceof Error ? e.message : "unknown"}`);
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
// -------------------------------------------------------------------------
|
|
329
|
+
// radar_review_list
|
|
330
|
+
// -------------------------------------------------------------------------
|
|
331
|
+
server.tool("radar_review_list", "Read-only: list pending Radar reviews requiring manual platform decision.", {
|
|
332
|
+
open_only: z.boolean().default(true).describe("If true, only returns open (undecided) reviews."),
|
|
333
|
+
limit: z.number().int().min(1).max(50).default(10),
|
|
334
|
+
}, async ({ open_only, limit }) => {
|
|
335
|
+
const start = Date.now();
|
|
336
|
+
try {
|
|
337
|
+
const stripeKey = env.STRIPE_SECRET_KEY;
|
|
338
|
+
if (!stripeKey)
|
|
339
|
+
return err("Stripe not configured");
|
|
340
|
+
const params = new URLSearchParams({ limit: String(limit) });
|
|
341
|
+
if (open_only)
|
|
342
|
+
params.set("open", "true");
|
|
343
|
+
const result = await stripeGet(stripeKey, `/v1/radar/reviews?${params.toString()}`);
|
|
344
|
+
if (!result.ok)
|
|
345
|
+
return err(`Stripe error: ${JSON.stringify(result.data)}`);
|
|
346
|
+
writeAudit(env, {
|
|
347
|
+
tool_name: "radar_review_list",
|
|
348
|
+
ocs_method: "stripe.radar.reviews.list",
|
|
349
|
+
status: "ok",
|
|
350
|
+
dry_run: false,
|
|
351
|
+
duration_ms: Date.now() - start,
|
|
352
|
+
sub: props.sub,
|
|
353
|
+
reseller_id: props.reseller_id,
|
|
354
|
+
});
|
|
355
|
+
return ok(JSON.stringify({ reviews: result.data.data, has_more: result.data.has_more }));
|
|
356
|
+
}
|
|
357
|
+
catch (e) {
|
|
358
|
+
Sentry.captureException(e);
|
|
359
|
+
return err(`Error: ${e instanceof Error ? e.message : "unknown"}`);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
// -------------------------------------------------------------------------
|
|
363
|
+
// radar_review_approve (HARD_BLOCK)
|
|
364
|
+
// -------------------------------------------------------------------------
|
|
365
|
+
server.tool("radar_review_approve", "Admin: approve a Radar review, allowing the charge to proceed. Requires confirm_token.", {
|
|
366
|
+
review_id: z.string().min(1).describe("Stripe Radar review ID (prv_...)."),
|
|
367
|
+
confirm_token: z.string().optional(),
|
|
368
|
+
}, async ({ review_id, confirm_token }) => {
|
|
369
|
+
const toolName = "radar_review_approve";
|
|
370
|
+
const start = Date.now();
|
|
371
|
+
if (!confirm_token) {
|
|
372
|
+
const token = await issueConfirmToken(env, props.sub, toolName);
|
|
373
|
+
return ok(`HARD_BLOCK: Approving review ${review_id} allows the charge to proceed.\n` +
|
|
374
|
+
`confirm_token: ${token}\nCall again with confirm_token="${token}" to execute. Expires in 5 minutes.`);
|
|
375
|
+
}
|
|
376
|
+
const valid = await verifyConfirmToken(env, props.sub, toolName, confirm_token);
|
|
377
|
+
if (!valid)
|
|
378
|
+
return err("Invalid or expired confirm_token.");
|
|
379
|
+
try {
|
|
380
|
+
const stripeKey = env.STRIPE_SECRET_KEY;
|
|
381
|
+
if (!stripeKey)
|
|
382
|
+
return err("Stripe not configured");
|
|
383
|
+
const result = await stripePost(stripeKey, `/v1/radar/reviews/${review_id}/approve`, {});
|
|
384
|
+
if (!result.ok)
|
|
385
|
+
return err(`Stripe error: ${JSON.stringify(result.data)}`);
|
|
386
|
+
writeAudit(env, {
|
|
387
|
+
tool_name: toolName,
|
|
388
|
+
ocs_method: "stripe.radar.review.approve",
|
|
389
|
+
status: "ok",
|
|
390
|
+
dry_run: false,
|
|
391
|
+
duration_ms: Date.now() - start,
|
|
392
|
+
sub: props.sub,
|
|
393
|
+
reseller_id: props.reseller_id,
|
|
394
|
+
});
|
|
395
|
+
return ok(`Review ${review_id} approved. Charge will proceed.`);
|
|
396
|
+
}
|
|
397
|
+
catch (e) {
|
|
398
|
+
Sentry.captureException(e);
|
|
399
|
+
return err(`Error: ${e instanceof Error ? e.message : "unknown"}`);
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
// -------------------------------------------------------------------------
|
|
403
|
+
// radar_review_decline (HARD_BLOCK)
|
|
404
|
+
// -------------------------------------------------------------------------
|
|
405
|
+
server.tool("radar_review_decline", "Admin: decline a Radar review, blocking/closing the charge. Requires confirm_token.", {
|
|
406
|
+
review_id: z.string().min(1),
|
|
407
|
+
confirm_token: z.string().optional(),
|
|
408
|
+
}, async ({ review_id, confirm_token }) => {
|
|
409
|
+
const toolName = "radar_review_decline";
|
|
410
|
+
const start = Date.now();
|
|
411
|
+
if (!confirm_token) {
|
|
412
|
+
const token = await issueConfirmToken(env, props.sub, toolName);
|
|
413
|
+
return ok(`HARD_BLOCK: Declining review ${review_id} will close/block the charge.\n` +
|
|
414
|
+
`confirm_token: ${token}\nExpires in 5 minutes.`);
|
|
415
|
+
}
|
|
416
|
+
const valid = await verifyConfirmToken(env, props.sub, toolName, confirm_token);
|
|
417
|
+
if (!valid)
|
|
418
|
+
return err("Invalid or expired confirm_token.");
|
|
419
|
+
try {
|
|
420
|
+
const stripeKey = env.STRIPE_SECRET_KEY;
|
|
421
|
+
if (!stripeKey)
|
|
422
|
+
return err("Stripe not configured");
|
|
423
|
+
// Stripe closes a review by approving it with close_reason=fraudulent
|
|
424
|
+
// or by calling close on the underlying charge. The /approve endpoint
|
|
425
|
+
// with a reason is the supported path for platform-level decline.
|
|
426
|
+
const result = await stripePost(stripeKey, `/v1/radar/reviews/${review_id}/approve`, { reason: "fraudulent" });
|
|
427
|
+
if (!result.ok)
|
|
428
|
+
return err(`Stripe error: ${JSON.stringify(result.data)}`);
|
|
429
|
+
writeAudit(env, {
|
|
430
|
+
tool_name: toolName,
|
|
431
|
+
ocs_method: "stripe.radar.review.decline",
|
|
432
|
+
status: "ok",
|
|
433
|
+
dry_run: false,
|
|
434
|
+
duration_ms: Date.now() - start,
|
|
435
|
+
sub: props.sub,
|
|
436
|
+
reseller_id: props.reseller_id,
|
|
437
|
+
});
|
|
438
|
+
return ok(`Review ${review_id} declined.`);
|
|
439
|
+
}
|
|
440
|
+
catch (e) {
|
|
441
|
+
Sentry.captureException(e);
|
|
442
|
+
return err(`Error: ${e instanceof Error ? e.message : "unknown"}`);
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
// -------------------------------------------------------------------------
|
|
446
|
+
// radar_value_list_add (HARD_BLOCK)
|
|
447
|
+
// -------------------------------------------------------------------------
|
|
448
|
+
server.tool("radar_value_list_add", "Admin: add an item (email, IP, card fingerprint, country code) to a Stripe Radar block/allow list. Requires confirm_token.", {
|
|
449
|
+
value_list_id: z.string().min(1).describe("Stripe Radar value list ID (rsl_...)."),
|
|
450
|
+
value: z
|
|
451
|
+
.string()
|
|
452
|
+
.min(1)
|
|
453
|
+
.describe("The value to add (email, IP address, country code, etc.)."),
|
|
454
|
+
confirm_token: z.string().optional(),
|
|
455
|
+
}, async ({ value_list_id, value, confirm_token }) => {
|
|
456
|
+
const toolName = "radar_value_list_add";
|
|
457
|
+
const start = Date.now();
|
|
458
|
+
if (!confirm_token) {
|
|
459
|
+
const token = await issueConfirmToken(env, props.sub, toolName);
|
|
460
|
+
return ok(`HARD_BLOCK: Adding "${value}" to list ${value_list_id} will affect future charge decisions.\n` +
|
|
461
|
+
`confirm_token: ${token}\nExpires in 5 minutes.`);
|
|
462
|
+
}
|
|
463
|
+
const valid = await verifyConfirmToken(env, props.sub, toolName, confirm_token);
|
|
464
|
+
if (!valid)
|
|
465
|
+
return err("Invalid or expired confirm_token.");
|
|
466
|
+
try {
|
|
467
|
+
const stripeKey = env.STRIPE_SECRET_KEY;
|
|
468
|
+
if (!stripeKey)
|
|
469
|
+
return err("Stripe not configured");
|
|
470
|
+
const result = await stripePost(stripeKey, "/v1/radar/value_list_items", { value_list: value_list_id, value });
|
|
471
|
+
if (!result.ok)
|
|
472
|
+
return err(`Stripe error: ${JSON.stringify(result.data)}`);
|
|
473
|
+
writeAudit(env, {
|
|
474
|
+
tool_name: toolName,
|
|
475
|
+
ocs_method: "stripe.radar.value_list.add",
|
|
476
|
+
status: "ok",
|
|
477
|
+
dry_run: false,
|
|
478
|
+
duration_ms: Date.now() - start,
|
|
479
|
+
sub: props.sub,
|
|
480
|
+
reseller_id: props.reseller_id,
|
|
481
|
+
});
|
|
482
|
+
return ok(`Added "${value}" to Radar list ${value_list_id}.`);
|
|
483
|
+
}
|
|
484
|
+
catch (e) {
|
|
485
|
+
Sentry.captureException(e);
|
|
486
|
+
return err(`Error: ${e instanceof Error ? e.message : "unknown"}`);
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
// -------------------------------------------------------------------------
|
|
490
|
+
// radar_rule_toggle
|
|
491
|
+
// -------------------------------------------------------------------------
|
|
492
|
+
server.tool("radar_rule_toggle", "Admin: enable or disable a Stripe Radar rule. NOTE: Stripe does not expose rule CRUD via the public API — this tool returns Dashboard instructions.", {
|
|
493
|
+
rule_id: z.string().min(1).describe("Stripe Radar rule ID."),
|
|
494
|
+
enabled: z.boolean().describe("true = enable, false = disable."),
|
|
495
|
+
}, async ({ rule_id, enabled }) => {
|
|
496
|
+
// Stripe Radar rules are not manageable via the REST API — only the Dashboard.
|
|
497
|
+
return ok(`Stripe Radar does not expose rule enable/disable via the public API.\n` +
|
|
498
|
+
`To ${enabled ? "enable" : "disable"} rule ${rule_id}:\n` +
|
|
499
|
+
`1. Open https://dashboard.stripe.com/radar/rules\n` +
|
|
500
|
+
`2. Find rule ${rule_id} and toggle it ${enabled ? "on" : "off"}.\n\n` +
|
|
501
|
+
`Note: If you need this automated, use the Radar for Platforms beta — contact Stripe support at https://support.stripe.com.`);
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
//# sourceMappingURL=stripe-connect-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe-connect-tools.js","sourceRoot":"","sources":["../src/stripe-connect-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timing-safe-equal.d.ts","sourceRoot":"","sources":["../src/timing-safe-equal.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAO7D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constant-time string equality for secrets, bearer tokens, and hex digests (ASCII).
|
|
3
|
+
*/
|
|
4
|
+
export function timingSafeEqual(a, b) {
|
|
5
|
+
if (a.length !== b.length)
|
|
6
|
+
return false;
|
|
7
|
+
let diff = 0;
|
|
8
|
+
for (let i = 0; i < a.length; i++) {
|
|
9
|
+
diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
10
|
+
}
|
|
11
|
+
return diff === 0;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=timing-safe-equal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timing-safe-equal.js","sourceRoot":"","sources":["../src/timing-safe-equal.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,CAAS,EAAE,CAAS;IAClD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Carrier MCP — v1.1 backlog tool registrations (9 tools).
|
|
3
|
+
*
|
|
4
|
+
* These are OCS methods confirmed live in the eSIMVault API docs but not yet
|
|
5
|
+
* exposed in the v1 server. All 9 are wired here to close coverage gaps
|
|
6
|
+
* identified in the 2026-05-12 forensic audit (mango/.planning/research/03-carrier-llc-audit.md).
|
|
7
|
+
*
|
|
8
|
+
* Scope assignments:
|
|
9
|
+
* write — affect_subscriber_phone_number, modify_subscriber_mobile_plan,
|
|
10
|
+
* modify_subscriber_package_active_period, modify_subscriber_voip_plan,
|
|
11
|
+
* push_steering_to_subscriber
|
|
12
|
+
* read — get_subscriber_location_by_cell_id, list_destination_lists
|
|
13
|
+
* admin — reset_subscriber_gz_counter
|
|
14
|
+
*
|
|
15
|
+
* Schema notes:
|
|
16
|
+
* - All ICCID-accepting tools use the subscriber-record lookup cache pattern
|
|
17
|
+
* (resolveSubscriberByIccid) for IMSI resolution where required.
|
|
18
|
+
* - pushSteeringToSubs is listed as "write" in the live docs; marked write here
|
|
19
|
+
* pending confirmation from eSIMVault support (gap G-04).
|
|
20
|
+
* - resetSubsGzCounter is admin-scoped; usage counter resets are irreversible.
|
|
21
|
+
*/
|
|
22
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
23
|
+
import { type ToolContext } from "./tools.js";
|
|
24
|
+
import type { ToolScope } from "./types.js";
|
|
25
|
+
/** Scope lookup for the 9 backlog tools. */
|
|
26
|
+
export declare const BACKLOG_TOOL_SCOPES: Record<string, ToolScope>;
|
|
27
|
+
export declare function registerAllBacklogTools(server: McpServer, ctx: ToolContext): void;
|
|
28
|
+
//# sourceMappingURL=tools-backlog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools-backlog.d.ts","sourceRoot":"","sources":["../src/tools-backlog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAW5C,4CAA4C;AAC5C,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CASzD,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,WAAW,GACf,IAAI,CA6XN"}
|