@carrierllc/mcp 0.2.4 → 0.2.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/index.js +82 -25
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/.metadata_never_index +0 -0
package/dist/index.js
CHANGED
|
@@ -530,13 +530,22 @@ function registerAllTools(server2, ctx) {
|
|
|
530
530
|
"list_subscribers",
|
|
531
531
|
{
|
|
532
532
|
title: "List Subscribers",
|
|
533
|
-
description: "Use this to list subscribers with optional filters and pagination. Good for fleet enumeration, bulk status checks, and finding subscribers by account or status. Params: `accountId` (integer,
|
|
534
|
-
inputSchema: {
|
|
533
|
+
description: "Use this to list subscribers with optional filters and pagination. Good for fleet enumeration, bulk status checks, and finding subscribers by account or status. OCS REQUIRES at least one search key \u2014 provide exactly one of: `imsi`, `iccid`, `activationCode`, `accountId`, or `msisdn`. Calling with no key will be rejected before reaching OCS. Params: `imsi` (string), `iccid` (string), `activationCode` (string), `accountId` (integer), `msisdn` (string), `status` (string, e.g. 'ACTIVE'/'SUSPENDED'), `offset` (integer, pagination \u2014 default 0), `limit` (integer, max results \u2014 always set to avoid unbounded fetches; recommended max 100 per call). Returns: array of subscriber summary records with ICCID, status, and account. Do NOT use this to fetch full details for a specific subscriber \u2014 use `get_subscriber` for that.",
|
|
534
|
+
inputSchema: z.object({
|
|
535
|
+
imsi: z.string().optional().describe("Filter by IMSI"),
|
|
536
|
+
iccid: z.string().optional().describe("Filter by ICCID"),
|
|
537
|
+
activationCode: z.string().optional().describe("Filter by activation code"),
|
|
535
538
|
accountId: z.number().optional().describe("Filter by account ID"),
|
|
539
|
+
msisdn: z.string().optional().describe("Filter by MSISDN"),
|
|
536
540
|
status: z.string().optional().describe("Filter by status"),
|
|
537
541
|
offset: z.number().optional().describe("Pagination offset"),
|
|
538
542
|
limit: z.number().optional().describe("Max results to return")
|
|
539
|
-
}
|
|
543
|
+
}).refine(
|
|
544
|
+
(d) => d.imsi !== void 0 || d.iccid !== void 0 || d.activationCode !== void 0 || d.accountId !== void 0 || d.msisdn !== void 0,
|
|
545
|
+
{
|
|
546
|
+
message: "Provide at least one of: imsi, iccid, activationCode, accountId, msisdn"
|
|
547
|
+
}
|
|
548
|
+
),
|
|
540
549
|
annotations: { readOnlyHint: true }
|
|
541
550
|
},
|
|
542
551
|
wrapHandler(
|
|
@@ -546,7 +555,11 @@ function registerAllTools(server2, ctx) {
|
|
|
546
555
|
ctx,
|
|
547
556
|
async (args, token2) => {
|
|
548
557
|
const params = {};
|
|
558
|
+
if (args.imsi) params.imsi = args.imsi;
|
|
559
|
+
if (args.iccid) params.iccid = args.iccid;
|
|
560
|
+
if (args.activationCode) params.activationCode = args.activationCode;
|
|
549
561
|
if (args.accountId !== void 0) params.accountId = args.accountId;
|
|
562
|
+
if (args.msisdn) params.msisdn = args.msisdn;
|
|
550
563
|
if (args.status) params.status = args.status;
|
|
551
564
|
if (args.offset !== void 0) params.offset = args.offset;
|
|
552
565
|
const client = new OcsClient(ctx.env.CARRIER_OCS_BASE_URL, token2);
|
|
@@ -3120,9 +3133,11 @@ function registerIntelligenceTools(server2, ctx) {
|
|
|
3120
3133
|
safeCall(ctx.env, token2, "listResellerAccount", {})
|
|
3121
3134
|
]);
|
|
3122
3135
|
const sections = ["# Fleet Health Dashboard\n"];
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3136
|
+
let totalActive = 0, totalSuspended = 0, totalInventory = 0, totalOther = 0;
|
|
3137
|
+
const statusOk = statusResult.data && Array.isArray(statusResult.data);
|
|
3138
|
+
const statusAccounts = statusOk ? statusResult.data : [];
|
|
3139
|
+
if (statusOk) {
|
|
3140
|
+
for (const account of statusAccounts) {
|
|
3126
3141
|
totalActive += Number(account.active ?? 0);
|
|
3127
3142
|
totalSuspended += Number(account.suspended ?? 0);
|
|
3128
3143
|
totalInventory += Number(account.inventory ?? account.notActivated ?? 0);
|
|
@@ -3131,37 +3146,79 @@ function registerIntelligenceTools(server2, ctx) {
|
|
|
3131
3146
|
const total = totalActive + totalSuspended + totalInventory + totalOther;
|
|
3132
3147
|
const utilization = total > 0 ? (totalActive / total * 100).toFixed(1) : "0";
|
|
3133
3148
|
sections.push(`## eSIM Fleet Status`);
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3149
|
+
if (total === 0) {
|
|
3150
|
+
sections.push(`No eSIMs provisioned across ${statusAccounts.length} account(s).`);
|
|
3151
|
+
} else {
|
|
3152
|
+
sections.push(`| Metric | Count | % |`);
|
|
3153
|
+
sections.push(`|--------|-------|---|`);
|
|
3154
|
+
sections.push(`| Active | ${totalActive} | ${(totalActive / total * 100).toFixed(1)}% |`);
|
|
3155
|
+
sections.push(`| Suspended | ${totalSuspended} | ${(totalSuspended / total * 100).toFixed(1)}% |`);
|
|
3156
|
+
sections.push(`| Inventory | ${totalInventory} | ${(totalInventory / total * 100).toFixed(1)}% |`);
|
|
3157
|
+
sections.push(`| Other | ${totalOther} | ${(totalOther / total * 100).toFixed(1)}% |`);
|
|
3158
|
+
sections.push(`| **Total** | **${total}** | |`);
|
|
3144
3159
|
sections.push(`
|
|
3145
|
-
|
|
3160
|
+
**Fleet Utilization: ${utilization}%**`);
|
|
3161
|
+
if (totalSuspended > totalActive * 0.1) {
|
|
3162
|
+
sections.push(`
|
|
3163
|
+
High suspension rate (${totalSuspended} suspended vs ${totalActive} active)`);
|
|
3164
|
+
}
|
|
3146
3165
|
}
|
|
3166
|
+
} else {
|
|
3167
|
+
sections.push(`## eSIM Fleet Status`);
|
|
3168
|
+
sections.push(`Unavailable: ${statusResult.error ?? "esimStatusPerAccount returned no data"}`);
|
|
3147
3169
|
}
|
|
3148
|
-
|
|
3149
|
-
|
|
3170
|
+
const accountsOk = accountsResult.data && Array.isArray(accountsResult.data);
|
|
3171
|
+
const accounts = accountsOk ? accountsResult.data : [];
|
|
3172
|
+
if (accountsOk) {
|
|
3173
|
+
const lowBalance = accounts.filter(
|
|
3150
3174
|
(a) => Number(a.balance ?? 0) < 10
|
|
3151
3175
|
);
|
|
3176
|
+
const packageOnlyZero = accounts.filter(
|
|
3177
|
+
(a) => Boolean(a.packageOnly) && Number(a.balance ?? 0) <= 0
|
|
3178
|
+
);
|
|
3179
|
+
sections.push(`
|
|
3180
|
+
## Account Summary`);
|
|
3181
|
+
sections.push(`- Total accounts: ${accounts.length}`);
|
|
3182
|
+
sections.push(`- Low balance (< 10): ${lowBalance.length}`);
|
|
3183
|
+
sections.push(`- Package-only with 0 balance: ${packageOnlyZero.length}`);
|
|
3152
3184
|
if (lowBalance.length > 0) {
|
|
3153
3185
|
sections.push(`
|
|
3154
|
-
|
|
3155
|
-
sections.push(`| Account | Balance |`);
|
|
3156
|
-
sections.push(
|
|
3186
|
+
### Low Balance Accounts (< 10)`);
|
|
3187
|
+
sections.push(`| Account | Balance | packageOnly |`);
|
|
3188
|
+
sections.push(`|---------|---------|-------------|`);
|
|
3157
3189
|
for (const a of lowBalance) {
|
|
3158
|
-
sections.push(`| ${a.name ?? a.accountId ?? "?"} | ${Number(a.balance ?? 0).toFixed(2)} |`);
|
|
3190
|
+
sections.push(`| ${a.name ?? a.accountId ?? "?"} | ${Number(a.balance ?? 0).toFixed(2)} | ${a.packageOnly ? "yes" : "no"} |`);
|
|
3159
3191
|
}
|
|
3160
3192
|
}
|
|
3193
|
+
const critical = packageOnlyZero.length;
|
|
3194
|
+
const warning = lowBalance.length - critical;
|
|
3195
|
+
const healthy = accounts.length - lowBalance.length;
|
|
3196
|
+
sections.push(`
|
|
3197
|
+
## Fleet Health Verdict`);
|
|
3198
|
+
sections.push(`- Healthy: ${healthy}`);
|
|
3199
|
+
sections.push(`- Warning (low balance, not package-only-zero): ${Math.max(warning, 0)}`);
|
|
3200
|
+
sections.push(`- Critical (package-only and 0 balance): ${critical}`);
|
|
3201
|
+
if (accounts.length === 0) {
|
|
3202
|
+
sections.push(`
|
|
3203
|
+
No accounts found under this reseller.`);
|
|
3204
|
+
} else if (critical > 0) {
|
|
3205
|
+
sections.push(`
|
|
3206
|
+
Action: top up package-only accounts at 0 balance to keep packages assignable.`);
|
|
3207
|
+
} else if (lowBalance.length === 0) {
|
|
3208
|
+
sections.push(`
|
|
3209
|
+
All accounts healthy.`);
|
|
3210
|
+
}
|
|
3211
|
+
} else {
|
|
3161
3212
|
sections.push(`
|
|
3162
3213
|
## Account Summary`);
|
|
3163
|
-
sections.push(
|
|
3164
|
-
|
|
3214
|
+
sections.push(`Unavailable: ${accountsResult.error ?? "listResellerAccount returned no data"}`);
|
|
3215
|
+
}
|
|
3216
|
+
if (!statusOk && !accountsOk) {
|
|
3217
|
+
sections.push(`
|
|
3218
|
+
## Errors`);
|
|
3219
|
+
if (statusResult.error) sections.push(`- esimStatusPerAccount: ${statusResult.error}`);
|
|
3220
|
+
if (accountsResult.error) sections.push(`- listResellerAccount: ${accountsResult.error}`);
|
|
3221
|
+
return result(sections.join("\n"), true);
|
|
3165
3222
|
}
|
|
3166
3223
|
return result(sections.join("\n"));
|
|
3167
3224
|
});
|