@carrierllc/mcp 0.13.7 → 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/index.js CHANGED
@@ -69,7 +69,7 @@ import {
69
69
  usageOverPeriodParams,
70
70
  verifyStorefront,
71
71
  withOcsListSummary
72
- } from "./chunk-U2UVUM3D.js";
72
+ } from "./chunk-DF2PGR5H.js";
73
73
  import "./chunk-SHKKVIIA.js";
74
74
 
75
75
  // src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carrierllc/mcp",
3
- "version": "0.13.7",
3
+ "version": "0.13.9",
4
4
  "description": "Carrier MCP \u2014 natural-language control of MVNO/eSIM fleets via eSIMVault OCS. Stdio mode for direct integration with Claude Desktop, Cursor, Windsurf, and MCP-compatible clients. Ships the `carrier` CLI (plugin install + white-label eSIM storefront scaffold).",
5
5
  "license": "MIT",
6
6
  "author": "Carrier (Lifecycle Innovations Limited)",
@@ -51,6 +51,7 @@
51
51
  "eslint": "^10.9.1",
52
52
  "tsup": "^8.5.1",
53
53
  "typescript": "^5.9.3",
54
+ "@carrierllc/sdk": "workspace:*",
54
55
  "@carrier/ai": "workspace:*",
55
56
  "@carrier/ocs-client": "workspace:*",
56
57
  "@carrier/ocs-spec": "workspace:*",
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: publish-storefront
3
+ description: Publish a Carrier-hosted eSIM storefront with POST /v1/storefronts. Use when a brand should go live on a slug.stores.carrier.llc address without a git deploy. Do not use the operator OCS catalog for this.
4
+ argument-hint: "[slug] [brand name]"
5
+ ---
6
+
7
+ # Publish a hosted storefront
8
+
9
+ This is the no-code path. Carrier hosts the shop. A slug is a subdomain, not a repository. A brand name such as Acme Mobile is stored as acme-mobile.
10
+
11
+ The description above is the trigger. Load this skill when the task is a hosted shop. Do not load the operator MCP catalog first.
12
+
13
+ ## Install, if this skill is not already available
14
+
15
+ Once per user, so every project sees it:
16
+
17
+ ```bash
18
+ npx skills add https://carrier.llc -g -a cursor -a claude-code -y
19
+ ```
20
+
21
+ If that host is not published yet, install this directory:
22
+
23
+ ```bash
24
+ npx skills add https://github.com/Lifecycle-Innovations-Limited/carrier.llc/tree/main/apps/mcp-stdio/plugin/carrier/skills/publish-storefront -g -a cursor -a claude-code -y
25
+ ```
26
+
27
+ ## Publish
28
+
29
+ `POST https://api.carrier.llc/v1/storefronts`
30
+
31
+ Required header: `Idempotency-Key` (stable per slug, max 255 characters).
32
+
33
+ Auth: `Authorization: Bearer` with an `ak_` key from the console. Do not put the key in the repo.
34
+
35
+ ```json
36
+ {
37
+ "slug": "acme",
38
+ "name": "Acme Mobile",
39
+ "status": "published",
40
+ "theme": { "accent": "#112233" },
41
+ "copy": {
42
+ "hero": "Acme lands",
43
+ "tagline": "Acme voice",
44
+ "supportEmail": "hello@acme.example",
45
+ "legalName": "Acme Ltd"
46
+ }
47
+ }
48
+ ```
49
+
50
+ The first publish needs the brand's own hero, tagline, support email, and legal name. Leaving them out does not fall back to Carrier's address.
51
+
52
+ A replay of the same key returns the original store. Send theme and copy again on that replay: the tool merges them onto the saved theme so a new accent does not wipe the logo. A second brand uses a different slug.
53
+
54
+ ## Price
55
+
56
+ `POST https://api.carrier.llc/v1/storefronts/{id}/plans`
57
+
58
+ ```json
59
+ {
60
+ "slug": "eu-1gb",
61
+ "name": "EU 1 GB",
62
+ "price_cents": 900,
63
+ "currency": "EUR",
64
+ "ocs_package_template_id": 77,
65
+ "data_gb": 1,
66
+ "validity_days": 7,
67
+ "regions": ["DE", "FR"],
68
+ "description": "Works in France.",
69
+ "active": true
70
+ }
71
+ ```
72
+
73
+ `price_cents` is the Stripe minor-unit amount. For EUR, 900 is 9.00. For JPY, 1000 is 1000 yen, not 100000. The OCS template id is the package that gets issued. Changing this price does not change another slug. Leave out data, validity, countries, buyer text, or whether the plan is for sale, and those stored values stay. When the shop has one plan, a price alone is enough: the CLI and the intent tool reuse that plan's slug, name, currency, and template id. A new plan can omit currency when every saved plan uses the same code.
74
+
75
+ To copy a connectivity plan the org already created, send its id instead of the template fields. Optional `price_cents` overrides the retail price. The shop address is derived from the plan name.
76
+
77
+ ```json
78
+ { "product_id": "cnp_abcdef0123456789abcdef0123456789", "price_cents": 1200 }
79
+ ```
80
+
81
+ A color or legal-name patch merges onto the stored shop, so the logo and hero stay. Send only the fields you want to change:
82
+
83
+ `PATCH https://api.carrier.llc/v1/storefronts/{id}`
84
+
85
+ ```json
86
+ { "theme": { "accent": "#112233", "logoUrl": "https://cdn.example/logo.png" }, "copy": { "hero": "Acme lands" } }
87
+ ```
88
+
89
+ CLI, after `carrier login`, or with npx:
90
+
91
+ ```bash
92
+ carrier site publish --slug acme --name "Acme Mobile" \
93
+ --accent "#112233" --hero "Acme lands" --tagline "Acme voice" \
94
+ --support-email hello@acme.example --legal-name "Acme Ltd" \
95
+ --product cnp_abcdef0123456789abcdef0123456789 --price 12.00
96
+ ```
97
+
98
+ `--price 9.00` is the same retail amount as `price_cents` 900. `--price 1000 --currency JPY` stores 1000. `--data-gb "1 GB"` stores 1. `--data-gb Unlimited` stores 0, which the shop shows as Unlimited. `--validity-days "7 days"` stores 7. `--countries "France, UK"` stores FR and GB. `--logo` is an https address or a PNG, JPEG, WebP, or GIF file under 70 KB. The intent field `logo_url` accepts that https address or the same picture as a data URL. An SVG or a `javascript:` address is refused.
99
+
100
+ ```bash
101
+ npx -y -p @carrierllc/mcp carrier site publish --slug acme --name "Acme Mobile" \
102
+ --hero "Acme lands" --tagline "Acme voice" \
103
+ --support-email hello@acme.example --legal-name "Acme Ltd"
104
+ ```
105
+
106
+ The CLI reads the existing store and merges color and copy before the PATCH. A successful publish prints `https://{slug}.stores.carrier.llc`.
107
+
108
+ `carrier site deploy` is the self-hosted twin. It does not publish this record.
109
+
110
+ `regions` accepts country names or two-letter codes. France is stored as FR and UK as GB. Leave it out to keep the countries already saved on that plan. A price change on one slug does not change another slug's countries.
111
+
112
+ `description` is the sentence buyers read under the plan name. Leave it out to keep the saved sentence. The intent tool field is `plan_description`. The CLI flag is `--plan-text`.
113
+
114
+ The developer MCP tool is `publish_storefront` on the intent server. It accepts `accent`, `hero`, `product_id`, `plan_slug`, `plan_name`, `price` (`9.00`, or `1000` with currency JPY) or `price_cents`, `currency`, `ocs_package_template_id`, `data_gb` (`1 GB`), `validity_days` (`7 days`), `regions` (France or DE), and `plan_description`. `product_id` copies a connectivity plan and does not need a template id. It is not an operator OCS tool.
@@ -103,7 +103,15 @@ export async function fetchTemplateCatalog(): Promise<TemplateCatalog> {
103
103
  const base = apiBase();
104
104
  if (!base) return sampleCatalog("unconfigured");
105
105
  try {
106
- const res = await fetch(`${base}/api/templates`, { next: { revalidate: 3600 } });
106
+ const slug = process.env.NEXT_PUBLIC_STOREFRONT_SLUG?.trim();
107
+ const templatesPath = slug
108
+ ? `/api/templates?storefront=${encodeURIComponent(slug)}`
109
+ : "/api/templates";
110
+ const res = await fetch(`${base}${templatesPath}`, {
111
+ next: slug
112
+ ? { revalidate: 60, tags: [`storefront:${slug}`] }
113
+ : { revalidate: 3600 },
114
+ });
107
115
  if (!res.ok) return sampleCatalog("upstream-error");
108
116
  const templates = (await res.json()) as SkuTemplate[];
109
117
  if (!Array.isArray(templates) || templates.length === 0) {