@mcpcloud/cli 0.5.0 → 0.7.0-next-20260628020545

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.
Files changed (2) hide show
  1. package/dist/index.js +64 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2819,11 +2819,11 @@ var ERROR_REMEDIATION = {
2819
2819
  api_key_name_required: "Pass --name <…> when creating an API key.",
2820
2820
  api_key_id_required: "Pass an apiKeyId. List existing keys with `mcp api-keys list`.",
2821
2821
  api_key_not_found: "No such API key for this user. Run `mcp api-keys list` to see live IDs.",
2822
- organization_not_selected: "Pass --org <id> or run `mcp config set-org <id>`.",
2823
- organization_id_required: "Pass --org <id> or run `mcp config set-org <id>`.",
2822
+ organization_not_selected: "Pass --org <id> or run `mcp config set-org <name|id>`.",
2823
+ organization_id_required: "Pass --org <id> or run `mcp config set-org <name|id>`.",
2824
2824
  organization_context_required: "Pass --org <id> for machine-driven flows; browser sessions infer it.",
2825
- organization_access_denied: "You're not a member of this organization. `mcp whoami` lists ones you can use.",
2826
- organization_access_required: "You're not a member of this organization. `mcp whoami` lists ones you can use.",
2825
+ organization_access_denied: "Not a member of that organization — a stale saved org is the usual cause after switching accounts. Run `mcp orgs list`, then `mcp config set-org <name>`.",
2826
+ organization_access_required: "Not a member of that organization — a stale saved org is the usual cause after switching accounts. Run `mcp orgs list`, then `mcp config set-org <name>`.",
2827
2827
  organization_mismatch: "The deployment belongs to a different org. Pass --org <correct-id>.",
2828
2828
  insufficient_role: "Your role doesn't permit this action. Contact an org owner.",
2829
2829
  resource_not_found: "No such resource for this org. Verify the ID with the matching `list` command.",
@@ -3457,12 +3457,13 @@ function registerAuthCommands(program2) {
3457
3457
  setApiKey(result.apiKey);
3458
3458
  const previousBaseUrl = readConfig().baseUrl ?? null;
3459
3459
  let baseUrlChanged = false;
3460
+ const config = readConfig();
3461
+ delete config.defaultOrganizationId;
3460
3462
  if (result.apiBaseUrl && result.apiBaseUrl !== previousBaseUrl) {
3461
- const config = readConfig();
3462
3463
  config.baseUrl = result.apiBaseUrl;
3463
- writeConfig(config);
3464
3464
  baseUrlChanged = true;
3465
3465
  }
3466
+ writeConfig(config);
3466
3467
  printSuccess(`Signed in${result.user?.email ? ` as ${c.bold(result.user.email)}` : ""}.`);
3467
3468
  if (result.apiKeyName)
3468
3469
  printInfo(c.dim(` key name: ${result.apiKeyName}`));
@@ -3496,6 +3497,7 @@ function registerAuthCommands(program2) {
3496
3497
  program2.command("logout").description("Remove the saved API key from ~/.mcpcloud/config.json").action(runAction(() => {
3497
3498
  const config = readConfig();
3498
3499
  delete config.apiKey;
3500
+ delete config.defaultOrganizationId;
3499
3501
  writeConfig(config);
3500
3502
  printSuccess("API key removed.");
3501
3503
  }));
@@ -3571,6 +3573,35 @@ class NoOrganizationError extends Error {
3571
3573
  this.name = "NoOrganizationError";
3572
3574
  }
3573
3575
  }
3576
+ async function resolveOrgReference(reference) {
3577
+ const ref = reference.trim();
3578
+ let data;
3579
+ try {
3580
+ data = await api.get("/api/v1/organizations");
3581
+ } catch {
3582
+ return { id: ref, matchedBy: "verbatim" };
3583
+ }
3584
+ const orgs = data.organizations ?? [];
3585
+ const byId = orgs.find((org) => org.id === ref);
3586
+ if (byId)
3587
+ return { id: byId.id, matchedBy: "id", name: byId.name };
3588
+ const lower = ref.toLowerCase();
3589
+ const byName = orgs.filter((org) => (org.name ?? "").toLowerCase() === lower);
3590
+ if (byName.length > 1) {
3591
+ throw new Error(`Multiple organizations are named "${reference}". Pass the org id instead (see \`mcp orgs list\`).`);
3592
+ }
3593
+ const nameMatch = byName[0];
3594
+ if (nameMatch)
3595
+ return { id: nameMatch.id, matchedBy: "name", name: nameMatch.name };
3596
+ const bySlug = orgs.find((org) => (org.slug ?? "").toLowerCase() === lower);
3597
+ if (bySlug)
3598
+ return { id: bySlug.id, matchedBy: "slug", name: bySlug.name };
3599
+ const available = orgs.map((org) => ` • ${org.name ?? org.id}${org.slug ? ` (${org.slug})` : ""} — ${org.id}`).join(`
3600
+ `);
3601
+ throw new Error(`No organization matching "${reference}".` + (available ? `
3602
+ Your organizations:
3603
+ ${available}` : " Run `mcp orgs list` to see your organizations."));
3604
+ }
3574
3605
  async function resolveOrgId(orgId) {
3575
3606
  if (orgId && orgId.trim())
3576
3607
  return orgId.trim();
@@ -8825,15 +8856,17 @@ function registerConfigCommands(program2) {
8825
8856
  }
8826
8857
  printSuccess("Cleared saved dashboard URL.");
8827
8858
  }));
8828
- config.command("set-org <organizationId>").description("Save a default organization ID").action(runAction((organizationId) => {
8859
+ config.command("set-org <organization>").description("Save a default organization (by name, slug, or id)").action(runAction(async (organization) => {
8860
+ const resolved = await resolveOrgReference(organization);
8829
8861
  const c2 = readConfig();
8830
- c2.defaultOrganizationId = organizationId;
8862
+ c2.defaultOrganizationId = resolved.id;
8831
8863
  writeConfig(c2);
8832
8864
  if (isJsonMode()) {
8833
- printJson({ defaultOrganizationId: organizationId });
8865
+ printJson({ defaultOrganizationId: resolved.id });
8834
8866
  return;
8835
8867
  }
8836
- printSuccess(`Saved default organization: ${organizationId}`);
8868
+ const label = resolved.name && resolved.matchedBy !== "id" ? `${resolved.name} (${resolved.id})` : resolved.id;
8869
+ printSuccess(`Saved default organization: ${label}`);
8837
8870
  }));
8838
8871
  config.command("clear-org").description("Remove the saved default organization ID").action(runAction(() => {
8839
8872
  const c2 = readConfig();
@@ -29860,6 +29893,9 @@ function validateSourceType2(value) {
29860
29893
  }
29861
29894
  async function runSpecInit(args) {
29862
29895
  const { orgId, opts } = args;
29896
+ if (opts.name && !isJsonMode()) {
29897
+ printWarn("--name is ignored with --from-spec; the server name comes from the spec. Rename it later in the dashboard or with the API.");
29898
+ }
29863
29899
  const sourceType = validateSourceType2(opts.sourceType);
29864
29900
  const payload = await readSpecSource(opts.fromSpec, sourceType);
29865
29901
  const { project, created: projectCreated } = await pickProject(orgId, opts.project);
@@ -29944,6 +29980,22 @@ async function runSpecInit(args) {
29944
29980
  // src/commands/installation.ts
29945
29981
  function registerInstallationCommands(program2) {
29946
29982
  const installation = program2.command("installation").description("Manage your skill / artifact installations");
29983
+ installation.command("list").description("List your active installations and their ids").action(runAction(async () => {
29984
+ const data = await api.get("/api/v1/installations");
29985
+ printList(data.installations.map((i) => ({
29986
+ id: i.installationId,
29987
+ type: i.artifactType,
29988
+ artifact: i.artifactName,
29989
+ version: i.version,
29990
+ installed: formatDate(i.installedAt)
29991
+ })), [
29992
+ { key: "id", label: "ID", width: 24 },
29993
+ { key: "type", label: "Type", width: 8 },
29994
+ { key: "artifact", label: "Artifact", width: 28 },
29995
+ { key: "version", label: "Version", width: 12 },
29996
+ { key: "installed", label: "Installed", width: 22 }
29997
+ ], data);
29998
+ }));
29947
29999
  installation.command("disable <installationId>").description("Disable an installation by id (replay-as-success on already-disabled rows)").option("--org <organizationId>", "Organization ID").addHelpText("after", [
29948
30000
  "",
29949
30001
  "Notes:",
@@ -30612,6 +30664,8 @@ function registerUsageCommands(program2) {
30612
30664
  window: `${usageData.usage.windowDays}d (since ${formatDate(usageData.usage.windowStartedAt)})`,
30613
30665
  requests: t.requestCount,
30614
30666
  allowed: t.allowedCount,
30667
+ "billable invocations": usageData.usage.invocations?.billableCount ?? t.allowedToolCallCount ?? 0,
30668
+ "invocation cost": formatMicros(usageData.usage.invocations?.billedMicros),
30615
30669
  "rate-limited": t.rateLimitedCount,
30616
30670
  unauthorized: t.unauthorizedCount,
30617
30671
  failed: t.failedCount,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcpcloud/cli",
3
- "version": "0.5.0",
3
+ "version": "0.7.0-next-20260628020545",
4
4
  "description": "The official CLI for MCPCloud — manage projects, servers, skills, and API keys from the terminal",
5
5
  "type": "module",
6
6
  "bin": {