@carrierllc/mcp 0.13.6 → 0.13.9
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-BIZFEVMT.js → chunk-DF2PGR5H.js} +8 -2
- package/dist/chunk-DF2PGR5H.js.map +1 -0
- package/dist/cli.js +1605 -1082
- package/dist/cli.js.map +1 -1
- package/dist/index.js +186 -65
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/plugin/carrier/.claude-plugin/plugin.json +1 -1
- package/plugin/carrier/skills/publish-storefront/SKILL.md +114 -0
- package/templates/storefront/src/vendor/carrier/client.ts +9 -1
- package/dist/chunk-BIZFEVMT.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
usageOverPeriodParams,
|
|
70
70
|
verifyStorefront,
|
|
71
71
|
withOcsListSummary
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-DF2PGR5H.js";
|
|
73
73
|
import "./chunk-SHKKVIIA.js";
|
|
74
74
|
|
|
75
75
|
// src/index.ts
|
|
@@ -1062,22 +1062,22 @@ function boundZonesResult(raw, opts = {}) {
|
|
|
1062
1062
|
const { verbose = false, resellerId } = opts;
|
|
1063
1063
|
const maxZones = opts.maxZones ?? ZONES_MAX_ZONES;
|
|
1064
1064
|
const maxOperators = opts.maxOperators ?? (verbose ? ZONES_VERBOSE_MAX_OPERATORS : ZONES_MAX_OPERATORS);
|
|
1065
|
-
const totalOperators = all.reduce((n,
|
|
1065
|
+
const totalOperators = all.reduce((n, z24) => n + (z24.operators?.length ?? 0), 0);
|
|
1066
1066
|
const keptZones = all.slice(0, maxZones);
|
|
1067
1067
|
let budget = maxOperators;
|
|
1068
1068
|
let returnedOperators = 0;
|
|
1069
|
-
const zones = keptZones.map((
|
|
1070
|
-
const ops =
|
|
1069
|
+
const zones = keptZones.map((z24) => {
|
|
1070
|
+
const ops = z24.operators ?? [];
|
|
1071
1071
|
const take = Math.max(0, Math.min(ops.length, budget));
|
|
1072
1072
|
budget -= take;
|
|
1073
1073
|
returnedOperators += take;
|
|
1074
1074
|
const sliced = ops.slice(0, take);
|
|
1075
1075
|
if (verbose) {
|
|
1076
|
-
return { ...
|
|
1076
|
+
return { ...z24, operators: sliced, operatorCount: ops.length };
|
|
1077
1077
|
}
|
|
1078
1078
|
return {
|
|
1079
|
-
zoneId:
|
|
1080
|
-
zoneName:
|
|
1079
|
+
zoneId: z24.zoneId,
|
|
1080
|
+
zoneName: z24.zoneName,
|
|
1081
1081
|
operatorCount: ops.length,
|
|
1082
1082
|
operators: sliced.map((o) => ({
|
|
1083
1083
|
net: o.networkId,
|
|
@@ -5055,7 +5055,7 @@ function registerAllBacklogTools(server2, ctx) {
|
|
|
5055
5055
|
}
|
|
5056
5056
|
|
|
5057
5057
|
// src/tools-carrier-ask.ts
|
|
5058
|
-
import { z as
|
|
5058
|
+
import { z as z12 } from "zod";
|
|
5059
5059
|
|
|
5060
5060
|
// src/tools-ui-agent.ts
|
|
5061
5061
|
import { z as z4 } from "zod";
|
|
@@ -7573,6 +7573,125 @@ function registerStorefrontDeployTools(server2, props2) {
|
|
|
7573
7573
|
);
|
|
7574
7574
|
}
|
|
7575
7575
|
|
|
7576
|
+
// src/tools-atlas.ts
|
|
7577
|
+
import { z as z11 } from "zod";
|
|
7578
|
+
|
|
7579
|
+
// src/atlas-public.ts
|
|
7580
|
+
var ATLAS_PUBLIC_BASE_URL = "https://atlas.carrier.llc";
|
|
7581
|
+
function atlasBaseUrl(env) {
|
|
7582
|
+
return (env.ATLAS_BASE_URL ?? ATLAS_PUBLIC_BASE_URL).replace(/\/+$/, "");
|
|
7583
|
+
}
|
|
7584
|
+
function atlasCoveragePath(input) {
|
|
7585
|
+
const country = input.country.trim().toUpperCase();
|
|
7586
|
+
if (!/^[A-Z]{2}$/.test(country)) {
|
|
7587
|
+
throw new Error("country must be a 2-letter ISO 3166-1 alpha-2 code");
|
|
7588
|
+
}
|
|
7589
|
+
const params = new URLSearchParams({ country });
|
|
7590
|
+
if (input.status) params.set("status", input.status);
|
|
7591
|
+
if (input.technology) params.set("technology", input.technology);
|
|
7592
|
+
return `/v1/atlas/coverage?${params.toString()}`;
|
|
7593
|
+
}
|
|
7594
|
+
function atlasNetworkPath(mcc, mnc) {
|
|
7595
|
+
if (!/^\d{3}$/.test(mcc) || !/^\d{2,3}$/.test(mnc)) {
|
|
7596
|
+
throw new Error("mcc must be 3 digits and mnc must be 2 or 3 digits");
|
|
7597
|
+
}
|
|
7598
|
+
return `/v1/atlas/mno/${mcc}/${mnc}`;
|
|
7599
|
+
}
|
|
7600
|
+
async function atlasPublicGet(baseUrl2, path) {
|
|
7601
|
+
const url = `${baseUrl2}${path}`;
|
|
7602
|
+
let response;
|
|
7603
|
+
try {
|
|
7604
|
+
response = await fetch(url, {
|
|
7605
|
+
method: "GET",
|
|
7606
|
+
headers: { Accept: "application/json" },
|
|
7607
|
+
signal: AbortSignal.timeout(8e3)
|
|
7608
|
+
});
|
|
7609
|
+
} catch (err7) {
|
|
7610
|
+
const message = err7 instanceof Error ? err7.message : String(err7);
|
|
7611
|
+
throw new Error(`Atlas request failed: ${message}`);
|
|
7612
|
+
}
|
|
7613
|
+
const text = await response.text();
|
|
7614
|
+
let body2 = text;
|
|
7615
|
+
if (text) {
|
|
7616
|
+
try {
|
|
7617
|
+
body2 = JSON.parse(text);
|
|
7618
|
+
} catch {
|
|
7619
|
+
body2 = text;
|
|
7620
|
+
}
|
|
7621
|
+
}
|
|
7622
|
+
if (!response.ok) {
|
|
7623
|
+
const detail = body2 && typeof body2 === "object" && "error" in body2 ? String(body2.error) : text.slice(0, 200);
|
|
7624
|
+
throw new Error(`Atlas ${response.status}: ${detail || response.statusText}`);
|
|
7625
|
+
}
|
|
7626
|
+
return body2;
|
|
7627
|
+
}
|
|
7628
|
+
|
|
7629
|
+
// src/tools-atlas.ts
|
|
7630
|
+
var ATLAS_TOOL_SCOPES = {
|
|
7631
|
+
get_atlas_coverage: "read",
|
|
7632
|
+
get_atlas_network_status: "read"
|
|
7633
|
+
};
|
|
7634
|
+
var coverageSchema = {
|
|
7635
|
+
country: z11.string().regex(/^[A-Za-z]{2}$/, "country must be a 2-letter ISO code").describe("ISO 3166-1 alpha-2 country code, for example JP or NL"),
|
|
7636
|
+
status: z11.enum(["up", "degraded", "down", "unknown"]).optional().describe("Keep only networks whose latest probe has this status"),
|
|
7637
|
+
technology: z11.enum(["2G", "3G", "4G", "5G"]).optional().describe("Keep only networks of this radio generation")
|
|
7638
|
+
};
|
|
7639
|
+
var networkSchema = {
|
|
7640
|
+
mcc: z11.string().regex(/^\d{3}$/, "mcc must be 3 digits").describe("Mobile Country Code"),
|
|
7641
|
+
mnc: z11.string().regex(/^\d{2,3}$/, "mnc must be 2 or 3 digits").describe("Mobile Network Code")
|
|
7642
|
+
};
|
|
7643
|
+
function jsonResult2(body2) {
|
|
7644
|
+
return {
|
|
7645
|
+
content: [{ type: "text", text: JSON.stringify(body2, null, 2) }]
|
|
7646
|
+
};
|
|
7647
|
+
}
|
|
7648
|
+
function registerAtlasTools(server2, ctx) {
|
|
7649
|
+
server2.registerTool(
|
|
7650
|
+
"get_atlas_coverage",
|
|
7651
|
+
{
|
|
7652
|
+
title: "Atlas coverage",
|
|
7653
|
+
description: "List the mobile networks Carrier Atlas has configured for one country. The catalog is OCS coverage metadata refreshed every 15 minutes. It is not licensed live telemetry, and a network with status 'unknown' has not been probed yet. Use this for 'which networks are in Japan', 'coverage in NL', 'MNOs for country US'. Params: country (ISO 3166-1 alpha-2, required), status (up|degraded|down|unknown), technology (2G|3G|4G|5G). Do NOT use this for where a subscriber is attached right now \u2014 that is a subscriber location tool. Do NOT use this for fleet health.",
|
|
7654
|
+
inputSchema: coverageSchema,
|
|
7655
|
+
annotations: { readOnlyHint: true }
|
|
7656
|
+
},
|
|
7657
|
+
wrapHandler(
|
|
7658
|
+
"get_atlas_coverage",
|
|
7659
|
+
"atlas.coverage",
|
|
7660
|
+
"read",
|
|
7661
|
+
ctx,
|
|
7662
|
+
async (args, _token) => {
|
|
7663
|
+
const path = atlasCoveragePath({
|
|
7664
|
+
country: args.country,
|
|
7665
|
+
status: args.status,
|
|
7666
|
+
technology: args.technology
|
|
7667
|
+
});
|
|
7668
|
+
const body2 = await atlasPublicGet(atlasBaseUrl(ctx.env), path);
|
|
7669
|
+
return jsonResult2(body2);
|
|
7670
|
+
}
|
|
7671
|
+
)
|
|
7672
|
+
);
|
|
7673
|
+
server2.registerTool(
|
|
7674
|
+
"get_atlas_network_status",
|
|
7675
|
+
{
|
|
7676
|
+
title: "Atlas network status",
|
|
7677
|
+
description: "Read one mobile network from Carrier Atlas by MCC and MNC, including the latest status sample and the last 24 hours of probes. Status comes from the 15-minute OCS coverage cron. 'unknown' means the catalog row exists and has not been probed. Use this for 'status of MCC 440 MNC 10', 'is this operator in the Atlas catalog'. Params: mcc (3 digits), mnc (2 or 3 digits). Do NOT use this for a subscriber's current radio attachment.",
|
|
7678
|
+
inputSchema: networkSchema,
|
|
7679
|
+
annotations: { readOnlyHint: true }
|
|
7680
|
+
},
|
|
7681
|
+
wrapHandler(
|
|
7682
|
+
"get_atlas_network_status",
|
|
7683
|
+
"atlas.network",
|
|
7684
|
+
"read",
|
|
7685
|
+
ctx,
|
|
7686
|
+
async (args, _token) => {
|
|
7687
|
+
const path = atlasNetworkPath(args.mcc, args.mnc);
|
|
7688
|
+
const body2 = await atlasPublicGet(atlasBaseUrl(ctx.env), path);
|
|
7689
|
+
return jsonResult2(body2);
|
|
7690
|
+
}
|
|
7691
|
+
)
|
|
7692
|
+
);
|
|
7693
|
+
}
|
|
7694
|
+
|
|
7576
7695
|
// src/credits.ts
|
|
7577
7696
|
var TIER_CREDIT_ALLOTMENTS = {
|
|
7578
7697
|
free: 5e3,
|
|
@@ -8946,7 +9065,8 @@ var ALL_TOOL_SCOPES = Object.freeze({
|
|
|
8946
9065
|
...STRIPE_PROXY_TOOL_SCOPES,
|
|
8947
9066
|
...STOREFRONT_LOGO_TOOL_SCOPES,
|
|
8948
9067
|
// Storefront deploy tools exist only in this package, not in the Worker.
|
|
8949
|
-
...STOREFRONT_DEPLOY_TOOL_SCOPES
|
|
9068
|
+
...STOREFRONT_DEPLOY_TOOL_SCOPES,
|
|
9069
|
+
...ATLAS_TOOL_SCOPES
|
|
8950
9070
|
});
|
|
8951
9071
|
var TOOL_REGISTRY = new Set(Object.keys(ALL_TOOL_SCOPES));
|
|
8952
9072
|
var UNREGISTERED_TOOLS = /* @__PURE__ */ new Set(["stripe_proxy_call"]);
|
|
@@ -9621,15 +9741,15 @@ function registerAllCarrierAskTools(server2, ctx) {
|
|
|
9621
9741
|
title: "Natural Language Carrier Tool Router",
|
|
9622
9742
|
description: "Use this when you want to perform a carrier operation but don't know which specific tool to call. Describe your intent in plain language and carrier_ask will identify the correct tool(s) and suggest the required parameters. For simple read intents, it executes directly and returns results. For destructive operations it returns a confirm_token that you must pass in a second call. Params: `intent` (string \u2014 natural language description of what you want to do), `context` (optional: iccid, account_id, reseller_id if already known). Returns: RouteResult \u2014 confirmed | pending_confirm | ambiguous | none. Do NOT use this when you know the right tool \u2014 direct calls are faster and cheaper.",
|
|
9623
9743
|
inputSchema: {
|
|
9624
|
-
intent:
|
|
9744
|
+
intent: z12.string().min(3).describe(
|
|
9625
9745
|
"Natural-language description of the operation to perform (e.g. 'suspend ICCID 89316 until next month', 'show fleet health', 'assign Europe 5GB package to subscriber 89316...')"
|
|
9626
9746
|
),
|
|
9627
|
-
context:
|
|
9628
|
-
iccid:
|
|
9629
|
-
account_id:
|
|
9630
|
-
reseller_id:
|
|
9747
|
+
context: z12.object({
|
|
9748
|
+
iccid: z12.string().optional().describe("Subscriber ICCID if already known"),
|
|
9749
|
+
account_id: z12.number().optional().describe("Account ID if already known"),
|
|
9750
|
+
reseller_id: z12.number().optional().describe("Reseller ID if already known")
|
|
9631
9751
|
}).optional().describe("Optional pre-resolved context to improve routing accuracy"),
|
|
9632
|
-
confirm_token:
|
|
9752
|
+
confirm_token: z12.string().optional().describe(
|
|
9633
9753
|
"One-time token from a previous carrier_ask call with confirm_required=true. Providing this executes the previously staged destructive operation."
|
|
9634
9754
|
)
|
|
9635
9755
|
}
|
|
@@ -9833,7 +9953,7 @@ function registerAllCarrierAskTools(server2, ctx) {
|
|
|
9833
9953
|
title: "Describe a Carrier Tool",
|
|
9834
9954
|
description: "Get full documentation for any registered Carrier MCP tool: description, parameters, 2-3 example invocations, required scope, destructive flag, and guidance. Params: `tool_name` (exact MCP tool name, e.g. 'assign_package'). Returns: structured tool metadata. Does NOT execute the tool.",
|
|
9835
9955
|
inputSchema: {
|
|
9836
|
-
tool_name:
|
|
9956
|
+
tool_name: z12.string().describe("The exact MCP tool name to describe (e.g. 'assign_package', 'hlr_set_bitrate')")
|
|
9837
9957
|
}
|
|
9838
9958
|
},
|
|
9839
9959
|
wrapHandler(
|
|
@@ -9926,7 +10046,7 @@ function buildExamples(toolName) {
|
|
|
9926
10046
|
}
|
|
9927
10047
|
|
|
9928
10048
|
// src/list-recent-ocs-events.ts
|
|
9929
|
-
import { z as
|
|
10049
|
+
import { z as z13 } from "zod";
|
|
9930
10050
|
|
|
9931
10051
|
// src/ocs-scoping.ts
|
|
9932
10052
|
function managedOwnAccountId(auth) {
|
|
@@ -10094,10 +10214,10 @@ var ALLOWED_EVENT_TYPES = [
|
|
|
10094
10214
|
"usage.anomaly"
|
|
10095
10215
|
];
|
|
10096
10216
|
var listRecentOcsEventsSchema = {
|
|
10097
|
-
iccid:
|
|
10098
|
-
limit:
|
|
10099
|
-
event_types:
|
|
10100
|
-
since:
|
|
10217
|
+
iccid: z13.string().regex(/^\d{19,20}$/).describe("ICCID, 19 or 20 digits, ITU-T E.118 format"),
|
|
10218
|
+
limit: z13.number().int().min(1).max(50).default(20).describe("Max events to return, newest first"),
|
|
10219
|
+
event_types: z13.array(z13.enum(ALLOWED_EVENT_TYPES)).optional().describe("Filter to specific event types"),
|
|
10220
|
+
since: z13.string().datetime().optional().describe("ISO-8601 timestamp; only events after this point")
|
|
10101
10221
|
};
|
|
10102
10222
|
async function listRecentOcsEvents2(iccid, limit, eventTypes, since, kv) {
|
|
10103
10223
|
return listRecentOcsEvents(iccid, limit, eventTypes, since, kv);
|
|
@@ -10160,7 +10280,7 @@ function registerListRecentOcsEventsTool(server2, ctx) {
|
|
|
10160
10280
|
}
|
|
10161
10281
|
|
|
10162
10282
|
// src/tools-rate-governor.ts
|
|
10163
|
-
import { z as
|
|
10283
|
+
import { z as z14 } from "zod";
|
|
10164
10284
|
var MONITORED_ENDPOINTS = [
|
|
10165
10285
|
"subscriberNetworkEventsOverPeriod",
|
|
10166
10286
|
// 30/min
|
|
@@ -10192,7 +10312,7 @@ function registerRateLimitStatusTool(server2, ctx) {
|
|
|
10192
10312
|
title: "API Rate-Limit Governor Status",
|
|
10193
10313
|
description: "Inspect Bridge4IP OCS rate-limit governor state \u2014 bucket fill levels, per-endpoint limits, and 80% alert thresholds. Use this to answer: 'are we rate limited', 'check ocs quota', 'how full is the rate limit bucket', 'rate limit status'. Params: `endpoint` (optional \u2014 OCS camelCase method name to inspect a single bucket, e.g. 'subscriberUsageOverPeriod'; omit for all monitored endpoints). Returns: per-endpoint { limit_per_min, batch_cap_per_min, calls_in_window, batch_calls_in_window, utilisation_pct, alert (true when \u226580% of limit) }. Note: counts come from the in-process sliding-window log (same key as OCS calls: API token + endpoint) \u2014 they reset when the Worker isolate recycles. Use as a relative signal, not an exact counter. Do NOT use this to adjust limits \u2014 limits are set by Bridge4IP contract and cannot be changed via MCP.",
|
|
10194
10314
|
inputSchema: {
|
|
10195
|
-
endpoint:
|
|
10315
|
+
endpoint: z14.string().optional().describe(
|
|
10196
10316
|
"OCS method name in camelCase (e.g. 'subscriberUsageOverPeriod'). Omit to return status for all monitored endpoints."
|
|
10197
10317
|
)
|
|
10198
10318
|
},
|
|
@@ -10248,7 +10368,7 @@ function registerRateLimitStatusTool(server2, ctx) {
|
|
|
10248
10368
|
}
|
|
10249
10369
|
|
|
10250
10370
|
// src/tools-depletion-events.ts
|
|
10251
|
-
import { z as
|
|
10371
|
+
import { z as z15 } from "zod";
|
|
10252
10372
|
function ok4(payload) {
|
|
10253
10373
|
return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
|
|
10254
10374
|
}
|
|
@@ -10276,10 +10396,10 @@ function registerDepletionEventsTool(server2, ctx) {
|
|
|
10276
10396
|
title: "Subscriber Bundle Depletion Events",
|
|
10277
10397
|
description: "Look up bundle depletion events for a subscriber (or list recent fleet-wide depletions). Returns the most recent bundle.depleted event stored when the prepaid usage webhook received a last_slice notification. Events are retained for 7 days. Use subscriberId to check a specific subscriber, or omit to list the 20 most recent fleet-wide depletions. Requires 'read' scope.",
|
|
10278
10398
|
inputSchema: {
|
|
10279
|
-
subscriberId:
|
|
10399
|
+
subscriberId: z15.string().optional().describe(
|
|
10280
10400
|
"OCS subscriber ID to look up. Omit to list the 20 most recent fleet-wide depletions."
|
|
10281
10401
|
),
|
|
10282
|
-
since:
|
|
10402
|
+
since: z15.string().optional().describe(
|
|
10283
10403
|
"ISO-8601 timestamp \u2014 only return events at or after this time (for single-subscriber lookup)."
|
|
10284
10404
|
)
|
|
10285
10405
|
},
|
|
@@ -10394,7 +10514,7 @@ function registerDepletionEventsTool(server2, ctx) {
|
|
|
10394
10514
|
}
|
|
10395
10515
|
|
|
10396
10516
|
// src/tools-country-history.ts
|
|
10397
|
-
import { z as
|
|
10517
|
+
import { z as z16 } from "zod";
|
|
10398
10518
|
function isoDate(now, daysAgo = 0) {
|
|
10399
10519
|
const d = new Date(now.getTime() - daysAgo * 864e5);
|
|
10400
10520
|
return d.toISOString().slice(0, 10);
|
|
@@ -10417,10 +10537,10 @@ function registerCountryHistoryTool(server2, ctx) {
|
|
|
10417
10537
|
title: "Subscriber Country History",
|
|
10418
10538
|
description: "Return cross-border movement history for a subscriber, reconstructed from OCS Gy charging events. Reads `gyAnswer.events` from `subscriberNetworkEventsOverPeriod` \u2014 every Gy record carries its own country, operator and MCC \u2014 and collapses consecutive same-country records into stays with first-seen and last-seen timestamps. This needs no webhook: it works with Relay LU and Relay Gy off. Relay `country.entered` events from the 24h ring-buffer are merged in as a supplement when present. Use this to answer: 'where has subscriber X traveled', 'show country history for ICCID', 'border crossings for this SIM'. Params: `subscriberId` (ICCID, 19\u201320 digits), `startDate`/`endDate` (YYYY-MM-DD, max 7 days apart, default the last 7 days), `limit` (1\u201350, default 20, newest first). Returns: `stays` ({ country, country_name, first_seen, last_seen, operators, mccs, event_count, used_bytes }), `transitions` ({ from, to, at }), and `country_events` in the legacy flat shape. `used_bytes` already handles the string-typed `usedUnits` and its 'N/A' values. Do NOT use this for raw per-session records \u2014 use `subscriber_network_events` for those.",
|
|
10419
10539
|
inputSchema: {
|
|
10420
|
-
subscriberId:
|
|
10421
|
-
startDate:
|
|
10422
|
-
endDate:
|
|
10423
|
-
limit:
|
|
10540
|
+
subscriberId: z16.string().regex(/^\d{19,20}$/, "subscriberId must be a 19\u201320 digit ICCID").describe("Subscriber ICCID (19\u201320 digits, ITU-T E.118)"),
|
|
10541
|
+
startDate: z16.string().regex(/^\d{4}-\d{2}-\d{2}$/, "startDate must be YYYY-MM-DD").optional().describe("Start of the period, YYYY-MM-DD inclusive (default: 7 days ago)"),
|
|
10542
|
+
endDate: z16.string().regex(/^\d{4}-\d{2}-\d{2}$/, "endDate must be YYYY-MM-DD").optional().describe("End of the period, YYYY-MM-DD inclusive, max 7 days from start (default: today)"),
|
|
10543
|
+
limit: z16.number().int().min(1).max(50).default(20).optional().describe("Maximum number of country_events to return, newest first (default 20, max 50)")
|
|
10424
10544
|
},
|
|
10425
10545
|
annotations: { readOnlyHint: true, idempotentHint: true }
|
|
10426
10546
|
},
|
|
@@ -10528,7 +10648,7 @@ function registerCountryHistoryTool(server2, ctx) {
|
|
|
10528
10648
|
}
|
|
10529
10649
|
|
|
10530
10650
|
// src/apps/fleet-health-app.ts
|
|
10531
|
-
import { z as
|
|
10651
|
+
import { z as z17 } from "zod";
|
|
10532
10652
|
import {
|
|
10533
10653
|
registerAppTool,
|
|
10534
10654
|
registerAppResource,
|
|
@@ -10640,7 +10760,7 @@ function registerFleetHealthApp(server2, ctx) {
|
|
|
10640
10760
|
title: "Fleet Health Dashboard",
|
|
10641
10761
|
description: "Draw the fleet overview as an interactive panel: eSIM status, per-account breakdown and low-balance alerts. Returns structuredContent for the panel, so it only helps a client that can render MCP UI resources. Do NOT use this when the answer has to be readable text, or in any headless or scripted context \u2014 `fleet_health` returns the same data as prose.",
|
|
10642
10762
|
inputSchema: {
|
|
10643
|
-
accountId:
|
|
10763
|
+
accountId: z17.number().optional().describe("Filter to a specific account (omit for all)")
|
|
10644
10764
|
},
|
|
10645
10765
|
annotations: { readOnlyHint: true },
|
|
10646
10766
|
_meta: {
|
|
@@ -10683,7 +10803,7 @@ function registerFleetHealthApp(server2, ctx) {
|
|
|
10683
10803
|
}
|
|
10684
10804
|
|
|
10685
10805
|
// src/apps/provisioning-wizard.ts
|
|
10686
|
-
import { z as
|
|
10806
|
+
import { z as z18 } from "zod";
|
|
10687
10807
|
import {
|
|
10688
10808
|
registerAppTool as registerAppTool2,
|
|
10689
10809
|
registerAppResource as registerAppResource2,
|
|
@@ -10788,10 +10908,10 @@ function registerProvisioningWizard(server2, ctx) {
|
|
|
10788
10908
|
title: "eSIM Provisioning Wizard",
|
|
10789
10909
|
description: "Interactive 3-step wizard to provision an eSIM: select subscriber, choose package template, preview (dry_run) and confirm execution.",
|
|
10790
10910
|
inputSchema: {
|
|
10791
|
-
step:
|
|
10792
|
-
wizardId:
|
|
10793
|
-
subscriber_iccid:
|
|
10794
|
-
package_template_id:
|
|
10911
|
+
step: z18.enum(["init", "select-package", "preview", "confirm"]).describe("Current wizard step"),
|
|
10912
|
+
wizardId: z18.string().optional().describe("Wizard session ID (absent on init)"),
|
|
10913
|
+
subscriber_iccid: z18.string().optional().describe("Subscriber ICCID (required for select-package)"),
|
|
10914
|
+
package_template_id: z18.number().optional().describe("Package template ID (required for preview)")
|
|
10795
10915
|
},
|
|
10796
10916
|
_meta: {
|
|
10797
10917
|
ui: {
|
|
@@ -11061,7 +11181,7 @@ function registerProvisioningWizard(server2, ctx) {
|
|
|
11061
11181
|
}
|
|
11062
11182
|
|
|
11063
11183
|
// src/apps/balance-topup.ts
|
|
11064
|
-
import { z as
|
|
11184
|
+
import { z as z19 } from "zod";
|
|
11065
11185
|
import {
|
|
11066
11186
|
registerAppTool as registerAppTool3,
|
|
11067
11187
|
registerAppResource as registerAppResource3,
|
|
@@ -11114,9 +11234,9 @@ function registerBalanceTopupApp(server2, ctx) {
|
|
|
11114
11234
|
title: "Balance Top-up Form",
|
|
11115
11235
|
description: "Adjust the OCS reseller-account balance behind one subscriber, through a form panel the user can review before it commits. Defaults to preview: a call that omits `preview` returns a projection and writes nothing. Only `preview: false` performs the OCS write. Params: `iccid` (subscriber identifier used to find the account), `delta` (amount to add when positive, deduct when negative), `preview` (boolean, default true). Requires `admin` scope plus recent MFA, and a client that can render UI panels. Do NOT use this in a headless or scripted context \u2014 call `modify_account_balance` directly, which takes an `accountId` and needs no panel. Do NOT use this for a subscriber's own balance \u2014 the `iccid` here only locates the account; per-subscriber money is `modify_subscriber_balance`. Do NOT use this for the Carrier prepaid wallet or MCP credits \u2014 see `wallet_topup_checkout` and `credit_balance`.",
|
|
11116
11236
|
inputSchema: {
|
|
11117
|
-
iccid:
|
|
11118
|
-
delta:
|
|
11119
|
-
preview:
|
|
11237
|
+
iccid: z19.string().describe("The subscriber ICCID for the account lookup"),
|
|
11238
|
+
delta: z19.number().describe("Amount to add (positive) or deduct (negative) from the account balance"),
|
|
11239
|
+
preview: z19.boolean().default(true).describe("If true, return preview without writing. If false, execute the balance change.")
|
|
11120
11240
|
},
|
|
11121
11241
|
annotations: { destructiveHint: true },
|
|
11122
11242
|
_meta: {
|
|
@@ -11199,7 +11319,7 @@ function registerAllApps(server2, ctx) {
|
|
|
11199
11319
|
}
|
|
11200
11320
|
|
|
11201
11321
|
// src/prompts.ts
|
|
11202
|
-
import { z as
|
|
11322
|
+
import { z as z20 } from "zod";
|
|
11203
11323
|
function registerAllPrompts(server2) {
|
|
11204
11324
|
server2.registerPrompt(
|
|
11205
11325
|
"fleet_health_report",
|
|
@@ -11235,7 +11355,7 @@ Format as a structured report with sections, tables, and actionable recommendati
|
|
|
11235
11355
|
{
|
|
11236
11356
|
title: "Subscriber Deep Dive",
|
|
11237
11357
|
description: "Comprehensive analysis of a single subscriber: profile, packages, usage patterns, location history, recommendations.",
|
|
11238
|
-
argsSchema: { iccid:
|
|
11358
|
+
argsSchema: { iccid: z20.string().describe("The subscriber ICCID to analyse") }
|
|
11239
11359
|
},
|
|
11240
11360
|
async ({ iccid }) => ({
|
|
11241
11361
|
messages: [
|
|
@@ -11334,7 +11454,7 @@ Analyze and present:
|
|
|
11334
11454
|
{
|
|
11335
11455
|
title: "Bulk Operations Planner",
|
|
11336
11456
|
description: "Plan bulk operations safely: mass package assignments, account migrations, balance adjustments, or status changes.",
|
|
11337
|
-
argsSchema: { operation:
|
|
11457
|
+
argsSchema: { operation: z20.string().describe("Describe the bulk operation you want to perform") }
|
|
11338
11458
|
},
|
|
11339
11459
|
async ({ operation }) => ({
|
|
11340
11460
|
messages: [
|
|
@@ -11367,7 +11487,7 @@ NEVER execute destructive operations without confirmation.`
|
|
|
11367
11487
|
}
|
|
11368
11488
|
|
|
11369
11489
|
// src/tools-pricing.ts
|
|
11370
|
-
import { z as
|
|
11490
|
+
import { z as z21 } from "zod";
|
|
11371
11491
|
function registerAllPricingTools(server2, ctx) {
|
|
11372
11492
|
const allTools = [...PRICING_TOOLS, ...PROJECTS_TOOLS];
|
|
11373
11493
|
for (const tool of allTools) {
|
|
@@ -11474,19 +11594,19 @@ function buildZodSchema(schema) {
|
|
|
11474
11594
|
for (const [key, prop] of Object.entries(properties)) {
|
|
11475
11595
|
let field;
|
|
11476
11596
|
if (prop.enum) {
|
|
11477
|
-
field =
|
|
11597
|
+
field = z21.enum(prop.enum);
|
|
11478
11598
|
} else if (prop.type === "number") {
|
|
11479
|
-
field =
|
|
11599
|
+
field = z21.number();
|
|
11480
11600
|
} else if (prop.type === "boolean") {
|
|
11481
|
-
field =
|
|
11601
|
+
field = z21.boolean();
|
|
11482
11602
|
} else if (prop.type === "array") {
|
|
11483
11603
|
if (prop.items?.type === "number") {
|
|
11484
|
-
field =
|
|
11604
|
+
field = z21.array(z21.number());
|
|
11485
11605
|
} else {
|
|
11486
|
-
field =
|
|
11606
|
+
field = z21.array(z21.string());
|
|
11487
11607
|
}
|
|
11488
11608
|
} else {
|
|
11489
|
-
field =
|
|
11609
|
+
field = z21.string();
|
|
11490
11610
|
}
|
|
11491
11611
|
const required = schema.required ?? [];
|
|
11492
11612
|
if (!required.includes(key)) {
|
|
@@ -11501,7 +11621,7 @@ function buildZodSchema(schema) {
|
|
|
11501
11621
|
}
|
|
11502
11622
|
|
|
11503
11623
|
// src/tools-greenzone.ts
|
|
11504
|
-
import { z as
|
|
11624
|
+
import { z as z22 } from "zod";
|
|
11505
11625
|
|
|
11506
11626
|
// src/greenzone-whitelist.ts
|
|
11507
11627
|
var STATE_KEY = "greenzone:state";
|
|
@@ -11792,9 +11912,9 @@ function registerGreenzoneTools(server2, ctx) {
|
|
|
11792
11912
|
title: "Greenzone Whitelist \u2014 Add",
|
|
11793
11913
|
description: "Add a hostname and/or IP address to the Bridge4IP Greenzone whitelist. The Greenzone whitelist controls which hosts/IPs are exempt from data charging after a subscriber's bundle is depleted. This operates via browser automation (Kapture) against the OCS portal \u2014 no REST API exists for this surface. Provide `host` (e.g. 'example.com') and/or `ip` (e.g. '203.0.113.0/24'). At least one of host or ip must be provided. Returns Kapture step sequence for Claude Code to execute. Requires 'write' scope and Kapture running in Sam's Chrome.",
|
|
11794
11914
|
inputSchema: {
|
|
11795
|
-
host:
|
|
11796
|
-
ip:
|
|
11797
|
-
dry_run:
|
|
11915
|
+
host: z22.string().optional().describe("Hostname to whitelist (e.g. 'example.com')"),
|
|
11916
|
+
ip: z22.string().optional().describe("IP address or CIDR to whitelist (e.g. '203.0.113.0/24')"),
|
|
11917
|
+
dry_run: z22.boolean().optional().describe("If true, return the Kapture steps without executing portal automation")
|
|
11798
11918
|
},
|
|
11799
11919
|
annotations: { destructiveHint: true }
|
|
11800
11920
|
},
|
|
@@ -11853,9 +11973,9 @@ function registerGreenzoneTools(server2, ctx) {
|
|
|
11853
11973
|
title: "Greenzone Whitelist \u2014 Remove",
|
|
11854
11974
|
description: "Remove a hostname and/or IP address from the Bridge4IP Greenzone whitelist. This operates via browser automation (Kapture) against the OCS portal. Provide `host` and/or `ip` to remove \u2014 at least one required. Returns Kapture step sequence for Claude Code to execute. Requires 'write' scope and Kapture running in Sam's Chrome.",
|
|
11855
11975
|
inputSchema: {
|
|
11856
|
-
host:
|
|
11857
|
-
ip:
|
|
11858
|
-
dry_run:
|
|
11976
|
+
host: z22.string().optional().describe("Hostname to remove from whitelist"),
|
|
11977
|
+
ip: z22.string().optional().describe("IP address or CIDR to remove from whitelist"),
|
|
11978
|
+
dry_run: z22.boolean().optional().describe("If true, return the Kapture steps without executing portal automation")
|
|
11859
11979
|
},
|
|
11860
11980
|
annotations: { destructiveHint: true }
|
|
11861
11981
|
},
|
|
@@ -11914,7 +12034,7 @@ function registerGreenzoneTools(server2, ctx) {
|
|
|
11914
12034
|
title: "Greenzone Whitelist \u2014 List",
|
|
11915
12035
|
description: "List current Greenzone whitelist entries from the KV cache. Returns all whitelisted hosts and IPs, when the state was last synced, and whether the last hourly reconciliation detected drift from the portal. This is a fast read from KV \u2014 no browser automation required. Use `from_portal: true` to trigger a live portal read via Kapture instead of KV. Requires 'read' scope.",
|
|
11916
12036
|
inputSchema: {
|
|
11917
|
-
from_portal:
|
|
12037
|
+
from_portal: z22.boolean().optional().describe(
|
|
11918
12038
|
"When true, return Kapture steps to read live portal state instead of KV cache"
|
|
11919
12039
|
)
|
|
11920
12040
|
},
|
|
@@ -11966,7 +12086,7 @@ function registerGreenzoneTools(server2, ctx) {
|
|
|
11966
12086
|
}
|
|
11967
12087
|
|
|
11968
12088
|
// src/tools-ui-agent-generic.ts
|
|
11969
|
-
import { z as
|
|
12089
|
+
import { z as z23 } from "zod";
|
|
11970
12090
|
var COST_PER_STEP_USD = 0.014;
|
|
11971
12091
|
var SESSION_OVERHEAD_USD = 5e-3;
|
|
11972
12092
|
function estimateCostUsd2(steps) {
|
|
@@ -12008,13 +12128,13 @@ function registerUiAgentGenericTools(server2, ctx, runtime) {
|
|
|
12008
12128
|
title: "Dispatch Generic Browsing Agent",
|
|
12009
12129
|
description: "Send a plain-language task to a hosted browsing agent, which drives a real browser on the open web \u2014 navigating pages, searching, extracting content, filling forms outside the OCS portal. Each run costs roughly $0.20-1.00 in model spend against your own BROWSER_USE_API_KEY, so treat it as the expensive last resort, not a lookup. Limited to CARRIER_BROWSER_USE_MAX_RUNS runs per CLI session (default 10). Params: `prompt` (1-4000 chars \u2014 name the target URL and the exact data or action), `max_steps` (1-30, default 15; prices the dry-run estimate only), `dry_run` (true returns only `estimated_cost_usd` and creates no session). Returns the finished result: unlike the hosted Worker, a local CLI has no background runtime, so this call blocks for the length of the run. Requires `write` scope. Do NOT use this to work out which Carrier tool answers a request \u2014 that is `carrier_ask`, which costs nothing. Do NOT use this for anything the OCS API already covers; every other tool here is faster, free, and audited.",
|
|
12010
12130
|
inputSchema: {
|
|
12011
|
-
prompt:
|
|
12131
|
+
prompt: z23.string().min(1).max(4e3).describe(
|
|
12012
12132
|
"Natural-language task description for the browsing agent. Be specific: include target URLs, data to extract, or actions to perform."
|
|
12013
12133
|
),
|
|
12014
|
-
max_steps:
|
|
12134
|
+
max_steps: z23.number().int().min(1).max(30).optional().describe(
|
|
12015
12135
|
"Advisory step budget (1\u201330, default 15). Prices the dry-run estimate; the hosted agent sets its own depth."
|
|
12016
12136
|
),
|
|
12017
|
-
dry_run:
|
|
12137
|
+
dry_run: z23.boolean().optional().describe(
|
|
12018
12138
|
"Preview cost estimate without dispatching. Returns estimated_cost_usd only \u2014 no browser session is created."
|
|
12019
12139
|
)
|
|
12020
12140
|
}
|
|
@@ -12151,7 +12271,7 @@ function registerUiAgentGenericTools(server2, ctx, runtime) {
|
|
|
12151
12271
|
title: "Poll Browsing Agent Task Status",
|
|
12152
12272
|
description: "Returns the current state of a browsing-agent task by `task_id`, including its result once finished. In the local CLI, ui_agent_ask already returns the finished result, so this is mainly for re-reading a task within the same session. Task records do not survive the CLI process exiting. Requires `read` scope.",
|
|
12153
12273
|
inputSchema: {
|
|
12154
|
-
task_id:
|
|
12274
|
+
task_id: z23.string().describe("Task ID returned by ui_agent_ask")
|
|
12155
12275
|
}
|
|
12156
12276
|
},
|
|
12157
12277
|
async (args) => {
|
|
@@ -12298,6 +12418,7 @@ registerStorefrontLogoTools(
|
|
|
12298
12418
|
props
|
|
12299
12419
|
);
|
|
12300
12420
|
registerStorefrontDeployTools(server, props);
|
|
12421
|
+
registerAtlasTools(server, toolCtx);
|
|
12301
12422
|
registerAllPrompts(server);
|
|
12302
12423
|
var transport = new StdioServerTransport();
|
|
12303
12424
|
await server.connect(transport);
|