@mcp-use/cli 2.20.1-canary.3 → 2.21.0-canary.4

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
@@ -1180,6 +1180,10 @@ async function isLoggedIn() {
1180
1180
  const apiKey = await getApiKey();
1181
1181
  return !!apiKey;
1182
1182
  }
1183
+ async function getProfileId() {
1184
+ const config = await readConfig();
1185
+ return config.profileId || null;
1186
+ }
1183
1187
  async function getWebUrl() {
1184
1188
  return DEFAULT_WEB_URL;
1185
1189
  }
@@ -1188,9 +1192,11 @@ async function getWebUrl() {
1188
1192
  var McpUseAPI = class _McpUseAPI {
1189
1193
  baseUrl;
1190
1194
  apiKey;
1191
- constructor(baseUrl, apiKey) {
1195
+ profileId;
1196
+ constructor(baseUrl, apiKey, profileId) {
1192
1197
  this.baseUrl = baseUrl || "";
1193
1198
  this.apiKey = apiKey;
1199
+ this.profileId = profileId;
1194
1200
  }
1195
1201
  /**
1196
1202
  * Initialize API client with config
@@ -1198,7 +1204,14 @@ var McpUseAPI = class _McpUseAPI {
1198
1204
  static async create() {
1199
1205
  const baseUrl = await getApiUrl();
1200
1206
  const apiKey = await getApiKey();
1201
- return new _McpUseAPI(baseUrl, apiKey ?? void 0);
1207
+ const profileId = await getProfileId();
1208
+ return new _McpUseAPI(baseUrl, apiKey ?? void 0, profileId ?? void 0);
1209
+ }
1210
+ /**
1211
+ * Override the profile ID for this API client instance (e.g. from --org flag)
1212
+ */
1213
+ setProfileId(profileId) {
1214
+ this.profileId = profileId;
1202
1215
  }
1203
1216
  /**
1204
1217
  * Make authenticated request
@@ -1212,6 +1225,9 @@ var McpUseAPI = class _McpUseAPI {
1212
1225
  if (this.apiKey) {
1213
1226
  headers["x-api-key"] = this.apiKey;
1214
1227
  }
1228
+ if (this.profileId) {
1229
+ headers["x-profile-id"] = this.profileId;
1230
+ }
1215
1231
  const timeout = options.timeout || 3e4;
1216
1232
  const controller = new AbortController();
1217
1233
  const timeoutId = setTimeout(() => controller.abort(), timeout);
@@ -1262,6 +1278,14 @@ var McpUseAPI = class _McpUseAPI {
1262
1278
  async testAuth() {
1263
1279
  return this.request("/test-auth");
1264
1280
  }
1281
+ /**
1282
+ * Set the user's default profile (organization) on the server
1283
+ */
1284
+ async setDefaultProfile(profileId) {
1285
+ await this.request(`/profiles/${profileId}/set-default`, {
1286
+ method: "POST"
1287
+ });
1288
+ }
1265
1289
  /**
1266
1290
  * Create deployment
1267
1291
  */
@@ -1286,6 +1310,9 @@ var McpUseAPI = class _McpUseAPI {
1286
1310
  if (this.apiKey) {
1287
1311
  headers["x-api-key"] = this.apiKey;
1288
1312
  }
1313
+ if (this.profileId) {
1314
+ headers["x-profile-id"] = this.profileId;
1315
+ }
1289
1316
  const response = await fetch(url, { headers });
1290
1317
  if (!response.ok) {
1291
1318
  throw new Error(`Failed to stream logs: ${response.status}`);
@@ -1367,6 +1394,9 @@ var McpUseAPI = class _McpUseAPI {
1367
1394
  if (this.apiKey) {
1368
1395
  headers["x-api-key"] = this.apiKey;
1369
1396
  }
1397
+ if (this.profileId) {
1398
+ headers["x-profile-id"] = this.profileId;
1399
+ }
1370
1400
  const response = await fetch(url, {
1371
1401
  method: "POST",
1372
1402
  headers,
@@ -1428,6 +1458,7 @@ var McpUseAPI = class _McpUseAPI {
1428
1458
  formData.append("source_file", blob, basename(filePath));
1429
1459
  const headers = {};
1430
1460
  if (this.apiKey) headers["x-api-key"] = this.apiKey;
1461
+ if (this.profileId) headers["x-profile-id"] = this.profileId;
1431
1462
  const response = await fetch(
1432
1463
  `${this.baseUrl}/deployments/${deploymentId}/redeploy`,
1433
1464
  {
@@ -1762,6 +1793,45 @@ async function startCallbackServer(port, expectedState) {
1762
1793
  server.on("error", reject);
1763
1794
  });
1764
1795
  }
1796
+ async function promptOrgSelection(profiles, defaultProfileId) {
1797
+ if (profiles.length === 0) return null;
1798
+ if (profiles.length === 1) {
1799
+ return profiles[0];
1800
+ }
1801
+ console.log(source_default.cyan.bold("\n\u{1F3E2} Select an organization:\n"));
1802
+ for (let i = 0; i < profiles.length; i++) {
1803
+ const p = profiles[i];
1804
+ const marker = p.id === defaultProfileId ? source_default.green(" (current)") : "";
1805
+ const slug = p.slug ? source_default.gray(` (${p.slug})`) : "";
1806
+ console.log(
1807
+ ` ${source_default.white(`${i + 1}.`)} ${p.profile_name}${slug}${marker}`
1808
+ );
1809
+ }
1810
+ const readline = await import("readline");
1811
+ const rl = readline.createInterface({
1812
+ input: process.stdin,
1813
+ output: process.stdout
1814
+ });
1815
+ return new Promise((resolve2) => {
1816
+ const defaultIdx = defaultProfileId ? profiles.findIndex((p) => p.id === defaultProfileId) : 0;
1817
+ const defaultDisplay = defaultIdx >= 0 ? defaultIdx + 1 : 1;
1818
+ rl.question(
1819
+ source_default.gray(`
1820
+ Enter number [${defaultDisplay}]: `),
1821
+ (answer) => {
1822
+ rl.close();
1823
+ const trimmed = answer.trim();
1824
+ const idx = trimmed === "" ? defaultIdx : parseInt(trimmed, 10) - 1;
1825
+ if (idx >= 0 && idx < profiles.length) {
1826
+ resolve2(profiles[idx]);
1827
+ } else {
1828
+ console.log(source_default.yellow("Invalid selection, using default."));
1829
+ resolve2(profiles[defaultIdx >= 0 ? defaultIdx : 0]);
1830
+ }
1831
+ }
1832
+ );
1833
+ });
1834
+ }
1765
1835
  async function loginCommand(options) {
1766
1836
  try {
1767
1837
  if (await isLoggedIn()) {
@@ -1823,6 +1893,31 @@ async function loginCommand(options) {
1823
1893
  const masked = apiKey.substring(0, 6) + "...";
1824
1894
  console.log(source_default.white("API Key: ") + source_default.gray(masked));
1825
1895
  }
1896
+ const profiles = authInfo.profiles ?? [];
1897
+ if (profiles.length > 0) {
1898
+ let selectedProfile = null;
1899
+ if (profiles.length === 1) {
1900
+ selectedProfile = profiles[0];
1901
+ } else {
1902
+ selectedProfile = await promptOrgSelection(
1903
+ profiles,
1904
+ authInfo.default_profile_id
1905
+ );
1906
+ }
1907
+ if (selectedProfile) {
1908
+ const config = await readConfig();
1909
+ await writeConfig({
1910
+ ...config,
1911
+ profileId: selectedProfile.id,
1912
+ profileName: selectedProfile.profile_name,
1913
+ profileSlug: selectedProfile.slug ?? void 0
1914
+ });
1915
+ const slug = selectedProfile.slug ? source_default.gray(` (${selectedProfile.slug})`) : "";
1916
+ console.log(
1917
+ source_default.white("Org: ") + source_default.cyan(selectedProfile.profile_name) + slug
1918
+ );
1919
+ }
1920
+ }
1826
1921
  } catch (error) {
1827
1922
  console.log(
1828
1923
  source_default.gray(
@@ -1888,6 +1983,27 @@ async function whoamiCommand() {
1888
1983
  const masked = apiKey.substring(0, 6) + "...";
1889
1984
  console.log(source_default.white("API Key: ") + source_default.gray(masked));
1890
1985
  }
1986
+ const config = await readConfig();
1987
+ const profiles = authInfo.profiles ?? [];
1988
+ if (profiles.length > 0) {
1989
+ const activeProfile = profiles.find(
1990
+ (p) => p.id === (config.profileId || authInfo.default_profile_id)
1991
+ );
1992
+ if (activeProfile) {
1993
+ const slug = activeProfile.slug ? source_default.gray(` (${activeProfile.slug})`) : "";
1994
+ console.log(
1995
+ source_default.white("Org: ") + source_default.cyan(activeProfile.profile_name) + slug
1996
+ );
1997
+ }
1998
+ if (profiles.length > 1) {
1999
+ console.log(
2000
+ source_default.gray(
2001
+ `
2002
+ ${profiles.length} organizations available. Use ` + source_default.white("npx mcp-use org list") + " to see all."
2003
+ )
2004
+ );
2005
+ }
2006
+ }
1891
2007
  } catch (error) {
1892
2008
  console.error(
1893
2009
  source_default.red.bold("\n\u2717 Failed to get user info:"),
@@ -3364,10 +3480,15 @@ async function displayDeploymentProgress(api, deployment) {
3364
3480
  const mcpServerUrl = getMcpServerUrl(finalDeployment);
3365
3481
  let dashboardUrl = null;
3366
3482
  const webUrl = (await getWebUrl()).replace(/\/$/, "");
3367
- if (finalDeployment.serverSlug) {
3368
- dashboardUrl = `${webUrl}/cloud/servers/${finalDeployment.serverSlug}`;
3369
- } else if (finalDeployment.serverId) {
3370
- dashboardUrl = `${webUrl}/cloud/servers/${finalDeployment.serverId}`;
3483
+ const config = await readConfig();
3484
+ const orgSlug = config.profileSlug;
3485
+ const serverRef = finalDeployment.serverSlug || finalDeployment.serverId;
3486
+ if (serverRef) {
3487
+ if (orgSlug) {
3488
+ dashboardUrl = `${webUrl}/cloud/${orgSlug}/servers/${serverRef}`;
3489
+ } else {
3490
+ dashboardUrl = `${webUrl}/cloud/servers/${serverRef}`;
3491
+ }
3371
3492
  }
3372
3493
  const inspectorUrl = `https://inspector.manufact.com/inspector?autoConnect=${encodeURIComponent(
3373
3494
  mcpServerUrl
@@ -3767,6 +3888,34 @@ async function deployCommand(options) {
3767
3888
  }
3768
3889
  console.log();
3769
3890
  const api = await McpUseAPI.create();
3891
+ if (options.org) {
3892
+ try {
3893
+ const authInfo = await api.testAuth();
3894
+ const match = (authInfo.profiles ?? []).find(
3895
+ (p) => p.slug === options.org || p.id === options.org || p.profile_name.toLowerCase() === options.org.toLowerCase()
3896
+ );
3897
+ if (match) {
3898
+ api.setProfileId(match.id);
3899
+ const slug = match.slug ? source_default.gray(` (${match.slug})`) : "";
3900
+ console.log(
3901
+ source_default.gray("Organization: ") + source_default.cyan(match.profile_name) + slug
3902
+ );
3903
+ } else {
3904
+ console.error(
3905
+ source_default.red(
3906
+ `\u2717 Organization "${options.org}" not found. Run ${source_default.white("npx mcp-use org list")} to see available organizations.`
3907
+ )
3908
+ );
3909
+ process.exit(1);
3910
+ }
3911
+ } catch (error) {
3912
+ console.error(
3913
+ source_default.red("\u2717 Failed to resolve organization:"),
3914
+ source_default.red(error instanceof Error ? error.message : "Unknown error")
3915
+ );
3916
+ process.exit(1);
3917
+ }
3918
+ }
3770
3919
  let githubVerified = false;
3771
3920
  try {
3772
3921
  console.log(source_default.gray(`[DEBUG] API URL: ${api.baseUrl}`));
@@ -3943,6 +4092,18 @@ async function deployCommand(options) {
3943
4092
  healthCheckPath: "/healthz",
3944
4093
  serverId
3945
4094
  };
4095
+ if (!options.org) {
4096
+ try {
4097
+ const config = await readConfig();
4098
+ if (config.profileName) {
4099
+ const slug = config.profileSlug ? source_default.gray(` (${config.profileSlug})`) : "";
4100
+ console.log(
4101
+ source_default.gray("Organization: ") + source_default.cyan(config.profileName) + slug
4102
+ );
4103
+ }
4104
+ } catch {
4105
+ }
4106
+ }
3946
4107
  console.log(source_default.gray("Creating deployment..."));
3947
4108
  const deployment = await api.createDeployment(deploymentRequest);
3948
4109
  console.log(
@@ -4502,6 +4663,125 @@ function createDeploymentsCommand() {
4502
4663
  return deploymentsCommand;
4503
4664
  }
4504
4665
 
4666
+ // src/commands/org.ts
4667
+ async function ensureLoggedIn() {
4668
+ if (!await isLoggedIn()) {
4669
+ console.log(source_default.yellow("\u26A0\uFE0F You are not logged in."));
4670
+ console.log(
4671
+ source_default.gray("Run " + source_default.white("npx mcp-use login") + " to get started.")
4672
+ );
4673
+ return false;
4674
+ }
4675
+ return true;
4676
+ }
4677
+ async function orgListCommand() {
4678
+ try {
4679
+ if (!await ensureLoggedIn()) return;
4680
+ const api = await McpUseAPI.create();
4681
+ const authInfo = await api.testAuth();
4682
+ const config = await readConfig();
4683
+ const profiles = authInfo.profiles ?? [];
4684
+ const activeId = config.profileId || authInfo.default_profile_id;
4685
+ if (profiles.length === 0) {
4686
+ console.log(source_default.yellow("No organizations found."));
4687
+ return;
4688
+ }
4689
+ console.log(source_default.cyan.bold("\u{1F3E2} Your organizations:\n"));
4690
+ for (const p of profiles) {
4691
+ const isActive = p.id === activeId;
4692
+ const marker = isActive ? source_default.green(" \u2190 active") : "";
4693
+ const slug = p.slug ? source_default.gray(` (${p.slug})`) : "";
4694
+ const role = source_default.gray(` [${p.role}]`);
4695
+ const name = isActive ? source_default.cyan.bold(p.profile_name) : source_default.white(p.profile_name);
4696
+ console.log(` ${name}${slug}${role}${marker}`);
4697
+ }
4698
+ if (profiles.length > 1) {
4699
+ console.log(
4700
+ source_default.gray("\nSwitch with " + source_default.white("npx mcp-use org switch"))
4701
+ );
4702
+ }
4703
+ } catch (error) {
4704
+ console.error(
4705
+ source_default.red.bold("\n\u2717 Failed to list organizations:"),
4706
+ source_default.red(error instanceof Error ? error.message : "Unknown error")
4707
+ );
4708
+ process.exit(1);
4709
+ }
4710
+ }
4711
+ async function orgSwitchCommand() {
4712
+ try {
4713
+ if (!await ensureLoggedIn()) return;
4714
+ const api = await McpUseAPI.create();
4715
+ const authInfo = await api.testAuth();
4716
+ const config = await readConfig();
4717
+ const profiles = authInfo.profiles ?? [];
4718
+ if (profiles.length === 0) {
4719
+ console.log(source_default.yellow("No organizations found."));
4720
+ return;
4721
+ }
4722
+ if (profiles.length === 1) {
4723
+ const p = profiles[0];
4724
+ const slug2 = p.slug ? source_default.gray(` (${p.slug})`) : "";
4725
+ console.log(
4726
+ source_default.yellow(
4727
+ `You only have one organization: ${source_default.cyan(p.profile_name)}${slug2}`
4728
+ )
4729
+ );
4730
+ return;
4731
+ }
4732
+ const activeId = config.profileId || authInfo.default_profile_id;
4733
+ const selected = await promptOrgSelection(profiles, activeId);
4734
+ if (!selected) {
4735
+ console.log(source_default.yellow("No organization selected."));
4736
+ return;
4737
+ }
4738
+ await writeConfig({
4739
+ ...config,
4740
+ profileId: selected.id,
4741
+ profileName: selected.profile_name,
4742
+ profileSlug: selected.slug ?? void 0
4743
+ });
4744
+ try {
4745
+ await api.setDefaultProfile(selected.id);
4746
+ } catch {
4747
+ }
4748
+ const slug = selected.slug ? source_default.gray(` (${selected.slug})`) : "";
4749
+ console.log(
4750
+ source_default.green.bold("\n\u2713 Switched to ") + source_default.cyan.bold(selected.profile_name) + slug
4751
+ );
4752
+ } catch (error) {
4753
+ console.error(
4754
+ source_default.red.bold("\n\u2717 Failed to switch organization:"),
4755
+ source_default.red(error instanceof Error ? error.message : "Unknown error")
4756
+ );
4757
+ process.exit(1);
4758
+ }
4759
+ }
4760
+ async function orgCurrentCommand() {
4761
+ try {
4762
+ if (!await ensureLoggedIn()) return;
4763
+ const config = await readConfig();
4764
+ if (!config.profileId) {
4765
+ console.log(
4766
+ source_default.yellow(
4767
+ "No organization selected. Run " + source_default.white("npx mcp-use org switch") + " to pick one."
4768
+ )
4769
+ );
4770
+ return;
4771
+ }
4772
+ const slug = config.profileSlug ? source_default.gray(` (${config.profileSlug})`) : "";
4773
+ console.log(
4774
+ source_default.cyan.bold("\u{1F3E2} Active organization: ") + source_default.white(config.profileName || config.profileId) + slug
4775
+ );
4776
+ } catch (error) {
4777
+ console.error(
4778
+ source_default.red.bold("\n\u2717 Failed to get organization:"),
4779
+ source_default.red(error instanceof Error ? error.message : "Unknown error")
4780
+ );
4781
+ process.exit(1);
4782
+ }
4783
+ }
4784
+
4505
4785
  // src/commands/skills.ts
4506
4786
  import { Command as Command3 } from "commander";
4507
4787
  import { cpSync, existsSync as existsSync2, mkdtempSync, readdirSync, rmSync } from "fs";
@@ -6552,6 +6832,16 @@ program.command("logout").description("Logout from Manufact cloud").action(async
6552
6832
  program.command("whoami").description("Show current user information").action(async () => {
6553
6833
  await whoamiCommand();
6554
6834
  });
6835
+ var orgCommand = program.command("org").description("Manage organizations");
6836
+ orgCommand.command("list").description("List your organizations").action(async () => {
6837
+ await orgListCommand();
6838
+ });
6839
+ orgCommand.command("switch").description("Switch the active organization").action(async () => {
6840
+ await orgSwitchCommand();
6841
+ });
6842
+ orgCommand.command("current").description("Show the currently active organization").action(async () => {
6843
+ await orgCurrentCommand();
6844
+ });
6555
6845
  program.command("deploy").description("Deploy MCP server from GitHub to Manufact cloud").option("--open", "Open deployment in browser after successful deploy").option("--name <name>", "Custom deployment name").option("--port <port>", "Server port", "3000").option("--runtime <runtime>", "Runtime (node or python)").option(
6556
6846
  "--new",
6557
6847
  "Force creation of new deployment instead of reusing linked deployment"
@@ -6561,6 +6851,9 @@ program.command("deploy").description("Deploy MCP server from GitHub to Manufact
6561
6851
  ).option("--env-file <path>", "Path to .env file with environment variables").option(
6562
6852
  "--root-dir <path>",
6563
6853
  "Root directory within repo to deploy from (for monorepos)"
6854
+ ).option(
6855
+ "--org <slug-or-id>",
6856
+ "Deploy to a specific organization (by slug or ID)"
6564
6857
  ).action(async (options) => {
6565
6858
  await deployCommand({
6566
6859
  open: options.open,
@@ -6570,7 +6863,8 @@ program.command("deploy").description("Deploy MCP server from GitHub to Manufact
6570
6863
  new: options.new,
6571
6864
  env: options.env,
6572
6865
  envFile: options.envFile,
6573
- rootDir: options.rootDir
6866
+ rootDir: options.rootDir,
6867
+ org: options.org
6574
6868
  });
6575
6869
  });
6576
6870
  program.addCommand(createClientCommand());