@carrierllc/mcp 0.10.4 → 0.10.6
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/dist/{chunk-KC3FPQ7P.js → chunk-DQHSDVIJ.js} +161 -16
- package/dist/chunk-DQHSDVIJ.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.js +95 -43
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-KC3FPQ7P.js.map +0 -1
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
esimStatusPerAccountParams,
|
|
19
19
|
extractDailyUsage,
|
|
20
20
|
extractEsimStatusCounts,
|
|
21
|
+
extractResellerBalance,
|
|
22
|
+
extractSubscriberStatus,
|
|
21
23
|
filterActiveSubscribers,
|
|
22
24
|
fleetScreen,
|
|
23
25
|
formatBytes,
|
|
@@ -26,17 +28,24 @@ import {
|
|
|
26
28
|
getLimitForEndpoint,
|
|
27
29
|
getRateLimitWindowCounts,
|
|
28
30
|
imsiFromSubscriberRecord,
|
|
31
|
+
isActivePackage,
|
|
29
32
|
isTargetId,
|
|
30
33
|
lastNDaysPeriod,
|
|
31
34
|
loadStorefrontBrand,
|
|
32
35
|
locationParams,
|
|
33
36
|
mergeEnvLocal,
|
|
37
|
+
networkEventRows,
|
|
34
38
|
networkEventsOverPeriodParams,
|
|
35
39
|
normalizePackageTemplate,
|
|
36
40
|
normalizePackageTemplateChanges,
|
|
37
41
|
ocsLocalDateTime,
|
|
38
42
|
packageActivePeriodParams,
|
|
43
|
+
packageDataLimit,
|
|
44
|
+
packageDataUsed,
|
|
45
|
+
packageExpiry,
|
|
46
|
+
packageName,
|
|
39
47
|
prepaidPackageLimits,
|
|
48
|
+
prepaidPackageRows,
|
|
40
49
|
probeAll,
|
|
41
50
|
provisionClerk,
|
|
42
51
|
rankTargets,
|
|
@@ -48,10 +57,12 @@ import {
|
|
|
48
57
|
storefrontClerkUrls,
|
|
49
58
|
subscriberIdParams,
|
|
50
59
|
subscriberRows,
|
|
60
|
+
subscriberSimId,
|
|
61
|
+
summarizeNetworkEvents,
|
|
51
62
|
usageOverPeriodParams,
|
|
52
63
|
verifyStorefront,
|
|
53
64
|
withOcsListSummary
|
|
54
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-DQHSDVIJ.js";
|
|
55
66
|
import "./chunk-SHKKVIIA.js";
|
|
56
67
|
|
|
57
68
|
// src/index.ts
|
|
@@ -313,7 +324,7 @@ async function invokeModelRaw(creds, payload, opts = {}, signal) {
|
|
|
313
324
|
}
|
|
314
325
|
var PENDING_ASK_PREFIX = "manus_pending_ask:";
|
|
315
326
|
var PENDING_ASK_TTL_SECONDS = 24 * 3600;
|
|
316
|
-
var OCS_DASHBOARD_DEFAULT = "https://
|
|
327
|
+
var OCS_DASHBOARD_DEFAULT = "https://portal-esimvault.cloud";
|
|
317
328
|
function buildLoginPreamble(dashboardUrl) {
|
|
318
329
|
return `STEP 1 \u2014 LOGIN:
|
|
319
330
|
Navigate to ${dashboardUrl}/login (or the main page if no /login path).
|
|
@@ -1824,7 +1835,7 @@ function registerAllTools(server2, ctx) {
|
|
|
1824
1835
|
"list_subscriber_packages",
|
|
1825
1836
|
{
|
|
1826
1837
|
title: "List Subscriber Packages",
|
|
1827
|
-
description: "Use this to retrieve all prepaid packages currently assigned to a subscriber. Returns each package's allowance (data/voice/SMS), consumed usage, expiry date, status, and packageId. Always call this before any package modification tool (`modify_package_limits`, `modify_package_expiry`, `modify_package_status`, `delete_subscriber_package`) to confirm the correct packageId and current state. Params: `iccid` (subscriber identifier). Returns: `{ summary,
|
|
1838
|
+
description: "Use this to retrieve all prepaid packages currently assigned to a subscriber. Returns each package's allowance (data/voice/SMS), consumed usage, expiry date, status, and packageId. Always call this before any package modification tool (`modify_package_limits`, `modify_package_expiry`, `modify_package_status`, `delete_subscriber_package`) to confirm the correct packageId and current state. Params: `iccid` (subscriber identifier). Returns: `{ summary, packages: [...] }` \u2014 package records with `packageId`, `name`, `status`, `dataLimit`, `dataUsed`, `expirationDate` and a `recurring` flag, behind a server-counted `summary.total` and a `summary.breakdown` over status and recurring. Answer 'how many' from `summary`, not by counting rows. Do NOT use this to browse the product catalog \u2014 use `list_package_templates` for that.",
|
|
1828
1839
|
inputSchema: { iccid: z.string().describe("The subscriber ICCID") },
|
|
1829
1840
|
annotations: { readOnlyHint: true }
|
|
1830
1841
|
},
|
|
@@ -4061,57 +4072,44 @@ function registerIntelligenceTools(server2, ctx) {
|
|
|
4061
4072
|
const sub = await safeCall(ctx.env, token2, "getSingleSubscriber", { iccid });
|
|
4062
4073
|
if (sub.error) return result(`Failed to fetch subscriber: ${sub.error}`, true);
|
|
4063
4074
|
if (!sub.data) return result("Subscriber not found", true);
|
|
4064
|
-
const status =
|
|
4075
|
+
const status = (extractSubscriberStatus(sub.data) ?? "").toUpperCase();
|
|
4065
4076
|
const balance = Number(sub.data.balance ?? 0);
|
|
4066
|
-
if (status
|
|
4077
|
+
if (status === "") {
|
|
4078
|
+
findings.push("OCS status could not be read from the subscriber record");
|
|
4079
|
+
if (severity === "healthy") severity = "info";
|
|
4080
|
+
} else if (status !== "ACTIVE") {
|
|
4067
4081
|
findings.push(`OCS status is ${status} (not ACTIVE)`);
|
|
4068
4082
|
actions.push(`Reactivate subscriber via modify_subscriber_status`);
|
|
4069
4083
|
severity = "critical";
|
|
4070
4084
|
}
|
|
4071
|
-
if (balance <= 0) {
|
|
4072
|
-
findings.push(`Balance is ${balance} \u2014 subscriber may be blocked from usage`);
|
|
4073
|
-
actions.push(`Top up balance via modify_subscriber_balance`);
|
|
4074
|
-
if (severity !== "critical") severity = "warning";
|
|
4075
|
-
}
|
|
4076
|
-
const simId = sub.data.simId ?? sub.data.sim_id ?? sub.data.id;
|
|
4077
|
-
const sim = simId !== void 0 ? await safeCall(ctx.env, token2, "getSimProviderStatus", Number(simId)) : { data: null, error: null };
|
|
4078
|
-
if (sim.data) {
|
|
4079
|
-
const simStatus = String(sim.data.simStatus ?? sim.data.status ?? "").toUpperCase();
|
|
4080
|
-
if (simStatus && !["ENABLED", "ACTIVE", "ACTIVATED"].includes(simStatus)) {
|
|
4081
|
-
findings.push(`SIM provider status is ${simStatus} \u2014 SIM may be disabled at network level`);
|
|
4082
|
-
actions.push(`Enable SIM via change_sim_status`);
|
|
4083
|
-
severity = "critical";
|
|
4084
|
-
}
|
|
4085
|
-
}
|
|
4086
4085
|
const pkgs = await safeCall(ctx.env, token2, "listSubscriberPrepaidPackages", { iccid });
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
(p) => String(p.status ?? "").toUpperCase() === "ACTIVE"
|
|
4090
|
-
);
|
|
4086
|
+
const activePkgs = prepaidPackageRows(pkgs.data).filter(isActivePackage);
|
|
4087
|
+
if (!pkgs.error) {
|
|
4091
4088
|
if (activePkgs.length === 0) {
|
|
4092
4089
|
findings.push("No active packages \u2014 subscriber has no data/voice/SMS allowance");
|
|
4093
4090
|
actions.push("Assign a package via assign_package");
|
|
4094
4091
|
severity = "critical";
|
|
4095
4092
|
} else {
|
|
4096
4093
|
for (const pkg of activePkgs) {
|
|
4097
|
-
const
|
|
4098
|
-
const
|
|
4094
|
+
const label = packageName(pkg);
|
|
4095
|
+
const dataUsed = packageDataUsed(pkg);
|
|
4096
|
+
const dataLimit = packageDataLimit(pkg);
|
|
4099
4097
|
if (dataLimit > 0 && dataUsed >= dataLimit) {
|
|
4100
4098
|
findings.push(
|
|
4101
|
-
`Package "${
|
|
4099
|
+
`Package "${label}" data depleted: ${formatBytes(dataUsed)} / ${formatBytes(dataLimit)}`
|
|
4102
4100
|
);
|
|
4103
4101
|
actions.push("Assign additional package or increase limits via modify_package_limits");
|
|
4104
4102
|
if (severity !== "critical") severity = "warning";
|
|
4105
4103
|
}
|
|
4106
|
-
const expiry =
|
|
4104
|
+
const expiry = packageExpiry(pkg);
|
|
4107
4105
|
if (expiry) {
|
|
4108
4106
|
const days = daysUntil(expiry);
|
|
4109
4107
|
if (days < 0) {
|
|
4110
|
-
findings.push(`Package "${
|
|
4108
|
+
findings.push(`Package "${label}" expired ${Math.abs(days)} days ago`);
|
|
4111
4109
|
actions.push("Remove expired package and assign a new one");
|
|
4112
4110
|
if (severity !== "critical") severity = "warning";
|
|
4113
4111
|
} else if (days <= 3) {
|
|
4114
|
-
findings.push(`Package "${
|
|
4112
|
+
findings.push(`Package "${label}" expires in ${days} day(s)`);
|
|
4115
4113
|
actions.push("Consider renewing or assigning a recurring package");
|
|
4116
4114
|
if (severity === "healthy") severity = "info";
|
|
4117
4115
|
}
|
|
@@ -4119,23 +4117,61 @@ function registerIntelligenceTools(server2, ctx) {
|
|
|
4119
4117
|
}
|
|
4120
4118
|
}
|
|
4121
4119
|
}
|
|
4120
|
+
if (balance <= 0 && activePkgs.length === 0) {
|
|
4121
|
+
findings.push(`Balance is ${balance} \u2014 subscriber may be blocked from usage`);
|
|
4122
|
+
actions.push(`Top up balance via modify_subscriber_balance`);
|
|
4123
|
+
if (severity !== "critical") severity = "warning";
|
|
4124
|
+
}
|
|
4125
|
+
const simId = subscriberSimId(sub.data);
|
|
4126
|
+
const sim = simId !== void 0 ? await safeCall(ctx.env, token2, "getSimProviderStatus", simId) : { data: null, error: null };
|
|
4127
|
+
if (sim.data) {
|
|
4128
|
+
const simStatus = String(sim.data.simStatus ?? sim.data.status ?? "").toUpperCase();
|
|
4129
|
+
if (simStatus && !["ENABLED", "ACTIVE", "ACTIVATED"].includes(simStatus)) {
|
|
4130
|
+
findings.push(`SIM provider status is ${simStatus} \u2014 SIM may be disabled at network level`);
|
|
4131
|
+
actions.push(`Enable SIM via change_sim_status`);
|
|
4132
|
+
severity = "critical";
|
|
4133
|
+
}
|
|
4134
|
+
}
|
|
4122
4135
|
const now = /* @__PURE__ */ new Date();
|
|
4123
4136
|
const eventWindow = lastNDaysPeriod(3, now);
|
|
4124
4137
|
const events = await safeCall(ctx.env, token2, "subscriberNetworkEventsOverPeriod", {
|
|
4125
4138
|
subscriber: { iccid },
|
|
4126
4139
|
period: eventWindow
|
|
4127
4140
|
});
|
|
4128
|
-
if (events.
|
|
4129
|
-
|
|
4130
|
-
|
|
4141
|
+
if (!events.error) {
|
|
4142
|
+
const net = summarizeNetworkEvents(networkEventRows(events.data));
|
|
4143
|
+
if (net.total === 0) {
|
|
4144
|
+
findings.push("No network events in last 72 hours \u2014 device may be powered off or out of coverage");
|
|
4131
4145
|
if (severity === "healthy") severity = "warning";
|
|
4132
4146
|
} else {
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4147
|
+
if (net.creditLimitReached > 0) {
|
|
4148
|
+
findings.push(
|
|
4149
|
+
`${net.creditLimitReached} data session(s) refused with CreditLimitReached \u2014 bundle is out of credit at the charging layer`
|
|
4150
|
+
);
|
|
4151
|
+
actions.push("Assign a package or raise limits via modify_package_limits");
|
|
4152
|
+
severity = "critical";
|
|
4153
|
+
}
|
|
4154
|
+
if (net.roamingNotAllowed > 0) {
|
|
4155
|
+
findings.push(
|
|
4156
|
+
`${net.roamingNotAllowed} attach(es) rejected 5004 (roaming not allowed) \u2014 operator not permitted for this subscriber`
|
|
4157
|
+
);
|
|
4158
|
+
actions.push("Review the steering list via list_steering_lists and modify_subscriber_steering_list");
|
|
4159
|
+
if (severity !== "critical") severity = "warning";
|
|
4160
|
+
}
|
|
4161
|
+
if (net.mapTimeouts > 0) {
|
|
4162
|
+
findings.push(`${net.mapTimeouts} MAP signalling leg(s) timed out \u2014 2G/3G attach is unreliable here`);
|
|
4163
|
+
if (severity === "healthy") severity = "info";
|
|
4164
|
+
}
|
|
4165
|
+
if (net.operators.length >= 3) {
|
|
4166
|
+
findings.push(
|
|
4167
|
+
`Attached across ${net.operators.length} operators (${net.operators.join(", ")}) \u2014 possible steering ping-pong, sessions may be torn down repeatedly`
|
|
4168
|
+
);
|
|
4169
|
+
if (severity === "healthy") severity = "info";
|
|
4170
|
+
}
|
|
4171
|
+
findings.push(`${net.total} network event(s), last at ${net.lastEventTime || "unknown"}`);
|
|
4136
4172
|
}
|
|
4137
4173
|
}
|
|
4138
|
-
const imsiForBitrate =
|
|
4174
|
+
const imsiForBitrate = imsiFromSubscriberRecord(sub.data) ?? null;
|
|
4139
4175
|
const bitrate = imsiForBitrate ? await safeCall(ctx.env, token2, "hlrGetBitrate", { imsi: imsiForBitrate }) : { data: null, error: null };
|
|
4140
4176
|
if (bitrate.data) {
|
|
4141
4177
|
const rate = Number(bitrate.data.bitrate ?? bitrate.data.maxBitrate ?? 0);
|
|
@@ -4164,7 +4200,7 @@ function registerIntelligenceTools(server2, ctx) {
|
|
|
4164
4200
|
`## Raw Status`,
|
|
4165
4201
|
`- OCS Status: ${status}`,
|
|
4166
4202
|
`- Balance: ${balance}`,
|
|
4167
|
-
`- Active Packages: ${pkgs.
|
|
4203
|
+
`- Active Packages: ${pkgs.error ? "unknown" : activePkgs.length}`
|
|
4168
4204
|
].join("\n");
|
|
4169
4205
|
return result(report);
|
|
4170
4206
|
});
|
|
@@ -4249,9 +4285,7 @@ High suspension rate (${totalSuspended} suspended vs ${totalActive} active)`);
|
|
|
4249
4285
|
const criticalZero = accounts.filter(
|
|
4250
4286
|
(a) => a.packageOnly === false && Number(a.balance ?? 0) <= 0
|
|
4251
4287
|
);
|
|
4252
|
-
const
|
|
4253
|
-
const rawBalance = resellerRaw?.getResellerInfo?.balance;
|
|
4254
|
-
const resellerBalance = rawBalance === void 0 || rawBalance === null ? null : Number(rawBalance);
|
|
4288
|
+
const resellerBalance = extractResellerBalance(resellerInfoResult?.data);
|
|
4255
4289
|
const resellerOutOfCredit = resellerBalance !== null && resellerBalance <= 0;
|
|
4256
4290
|
sections.push(`
|
|
4257
4291
|
## Account Summary`);
|
|
@@ -5860,6 +5894,20 @@ function registerAllUiAgentTools(server2, ctx, runtime, optIn = readPortalOptIn(
|
|
|
5860
5894
|
};
|
|
5861
5895
|
}
|
|
5862
5896
|
const resellerId = args.reseller_id ?? ctx.props.reseller_id;
|
|
5897
|
+
if (typeof resellerId !== "number" || !Number.isFinite(resellerId)) {
|
|
5898
|
+
return {
|
|
5899
|
+
isError: true,
|
|
5900
|
+
content: [
|
|
5901
|
+
{
|
|
5902
|
+
type: "text",
|
|
5903
|
+
text: JSON.stringify({
|
|
5904
|
+
error: "reseller_id_unresolved",
|
|
5905
|
+
message: "Could not resolve a reseller id from the session. Pass reseller_id explicitly."
|
|
5906
|
+
})
|
|
5907
|
+
}
|
|
5908
|
+
]
|
|
5909
|
+
};
|
|
5910
|
+
}
|
|
5863
5911
|
const requested = [
|
|
5864
5912
|
args.relay_gy === void 0 ? null : `Relay Gy: ${args.relay_gy ? "enable" : "disable"}`,
|
|
5865
5913
|
args.relay_calls_sms === void 0 ? null : `Calls/SMS relay: ${args.relay_calls_sms ? "enable" : "disable"}`,
|
|
@@ -10390,10 +10438,14 @@ async function listRecentOcsEvents(iccid, limit, eventTypes, since, kv) {
|
|
|
10390
10438
|
var ALLOWED_EVENT_TYPES = [
|
|
10391
10439
|
"esim.activated",
|
|
10392
10440
|
"esim.disabled",
|
|
10393
|
-
"
|
|
10441
|
+
"esim.enabled",
|
|
10442
|
+
"package.low_balance",
|
|
10443
|
+
"package.low_quota",
|
|
10444
|
+
"package.expiring",
|
|
10445
|
+
"package.expired",
|
|
10394
10446
|
"location.changed",
|
|
10395
10447
|
"country.entered",
|
|
10396
|
-
"
|
|
10448
|
+
"usage.anomaly"
|
|
10397
10449
|
];
|
|
10398
10450
|
var listRecentOcsEventsSchema = {
|
|
10399
10451
|
iccid: z12.string().regex(/^\d{19,20}$/).describe("ICCID, 19 or 20 digits, ITU-T E.118 format"),
|