@carrierllc/mcp 0.13.7 → 0.13.10
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-U2UVUM3D.js → chunk-AUOGFI2I.js} +44 -6
- package/dist/chunk-AUOGFI2I.js.map +1 -0
- package/dist/cli.js +1565 -1095
- package/dist/cli.js.map +1 -1
- package/dist/index.js +18 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/plugin/carrier/skills/publish-storefront/SKILL.md +114 -0
- package/templates/storefront/src/vendor/carrier/client.ts +9 -1
- package/dist/chunk-U2UVUM3D.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carrierllc/mcp",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.10",
|
|
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
|
|
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) {
|