@hyperstar/mcp 0.1.17 → 0.1.19

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/README.md CHANGED
@@ -41,8 +41,9 @@ path, use the equivalent `npm exec` form:
41
41
  npm exec --yes --package @hyperstar/mcp -- hyperstar-mcp
42
42
  ```
43
43
 
44
- For interactive local use, start with browser login. The CLI opens Hyperstar in
45
- your browser and never asks for a raw Hyperstar password in the terminal:
44
+ For interactive local use, start with browser login. An agent with shell access
45
+ on the same machine may run this command for the user. The CLI opens Hyperstar
46
+ in the browser and never asks for a raw Hyperstar password in the terminal:
46
47
 
47
48
  ```sh
48
49
  npx -y --package @hyperstar/mcp hyperstar login
@@ -50,6 +51,19 @@ npx -y --package @hyperstar/mcp hyperstar workspaces list --json
50
51
  npx -y --package @hyperstar/mcp hyperstar workspaces use <organization_id>
51
52
  ```
52
53
 
54
+ If the agent should not open the browser automatically, use `--no-open`. The
55
+ agent can show the printed URL to the user and keep the command running while
56
+ the browser completes the loopback callback:
57
+
58
+ ```sh
59
+ npx -y --package @hyperstar/mcp hyperstar login --no-open
60
+ ```
61
+
62
+ `hyperstar logout` revokes and clears the CLI token, but it does not sign out of
63
+ the browser session at `app.hyper-star.org`. To switch accounts, sign out in the
64
+ browser first or open the printed authorization URL in a private browser window.
65
+ After login, list workspaces and select exactly one before using workflow tools.
66
+
53
67
  For unattended automation, create a service-account key from Team -> API keys in
54
68
  the dashboard. Use the headless workflow preset. Enable inbox write only for
55
69
  agents that are allowed to send inbox replies.
@@ -368,6 +382,12 @@ and `prompts/list` discovery.
368
382
  multiple binaries.
369
383
  - `No Hyperstar auth configured`: run `hyperstar login` and select a workspace,
370
384
  or set `HYPERSTAR_API_KEY` in the MCP server environment.
385
+ - The agent says login must be run manually: the agent can run
386
+ `hyperstar login --no-open`, show the printed URL, and wait while the user
387
+ completes browser authentication on the same machine.
388
+ - Login keeps returning the same account: `hyperstar logout` clears only the CLI
389
+ token. Sign out of `app.hyper-star.org` in the browser or use a private window
390
+ for the authorization URL.
371
391
  - Workspace errors in browser-login mode: run
372
392
  `hyperstar workspaces list --json`, then
373
393
  `hyperstar workspaces use <organization_id>`.
@@ -9,7 +9,7 @@ export function createCliAuthClient(options) {
9
9
  code,
10
10
  code_verifier: verifier,
11
11
  client_id: CLI_CLIENT_ID,
12
- redirect_uri: redirectUri,
12
+ loopback_redirect: toLoopbackRedirect(redirectUri),
13
13
  }),
14
14
  refresh: async (refreshToken) => requestRefresh(fetcher, options.apiBaseUrl, now, {
15
15
  refresh_token: refreshToken,
@@ -102,6 +102,23 @@ async function requestToken(fetcher, apiBaseUrl, now, body) {
102
102
  }
103
103
  return parseTokenPair(payload, now);
104
104
  }
105
+ /** Convert the local callback URL to the API-safe descriptor. */
106
+ function toLoopbackRedirect(redirectUri) {
107
+ const url = new URL(redirectUri);
108
+ const port = Number(url.port);
109
+ if (url.protocol !== "http:" ||
110
+ url.pathname !== "/callback" ||
111
+ (url.hostname !== "127.0.0.1" && url.hostname !== "localhost") ||
112
+ !Number.isInteger(port) ||
113
+ port < 1024 ||
114
+ port > 65535) {
115
+ throw new Error("Hyperstar CLI callback URL was invalid");
116
+ }
117
+ return {
118
+ host: url.hostname === "127.0.0.1" ? "ipv4" : "localhost",
119
+ port,
120
+ };
121
+ }
105
122
  /** Rotate a refresh token using the backend refresh route. */
106
123
  async function requestRefresh(fetcher, apiBaseUrl, now, body) {
107
124
  const response = await fetcher(buildApiUrl(apiBaseUrl, "/api/v1/cli-auth/refresh"), {
@@ -0,0 +1,4 @@
1
+ export declare const CLI_USAGE: string;
2
+ export declare const BROWSER_SESSION_BOUNDARY = "Browser sessions are separate from CLI sessions; logout does not sign out of the browser account.";
3
+ export declare const BROWSER_ACCOUNT_SWITCH_GUIDANCE = "Browser sessions are separate from CLI sessions; sign out in the browser or use a private window to switch browser accounts.";
4
+ export declare const WORKSPACE_SELECTION_GUIDANCE = "Run `hyperstar workspaces list --json`, select exactly one workspace, then run `hyperstar workspaces use <organization_id>`.";
@@ -0,0 +1,18 @@
1
+ export const CLI_USAGE = [
2
+ "Usage: hyperstar <command> [options]",
3
+ "",
4
+ "Commands:",
5
+ " login [--no-open] Open browser login and save local CLI auth",
6
+ " logout Revoke and clear local CLI auth",
7
+ " whoami [--json] Print the authenticated principal",
8
+ " workspaces list [--json] List accessible workspaces",
9
+ " workspaces use <workspace_id> Select a workspace for Product API calls",
10
+ "",
11
+ "Options:",
12
+ " --json Print supported command output as JSON",
13
+ " --no-open Print the login URL without opening a browser",
14
+ " --help Show this help",
15
+ ].join("\n");
16
+ export const BROWSER_SESSION_BOUNDARY = "Browser sessions are separate from CLI sessions; logout does not sign out of the browser account.";
17
+ export const BROWSER_ACCOUNT_SWITCH_GUIDANCE = "Browser sessions are separate from CLI sessions; sign out in the browser or use a private window to switch browser accounts.";
18
+ export const WORKSPACE_SELECTION_GUIDANCE = "Run `hyperstar workspaces list --json`, select exactly one workspace, then run `hyperstar workspaces use <organization_id>`.";
package/dist/cli.js CHANGED
@@ -9,20 +9,7 @@ import { startLocalCallbackServer, } from "./auth/local-callback.js";
9
9
  import { createPkcePair, createState } from "./auth/pkce.js";
10
10
  import { DEFAULT_API_BASE_URL, DEFAULT_APP_BASE_URL, createCliWorkspaceSelection, normalizeBaseUrl, } from "./config.js";
11
11
  import { createHyperstarClient } from "./http.js";
12
- const CLI_USAGE = [
13
- "Usage: hyperstar <command> [options]",
14
- "",
15
- "Commands:",
16
- " login Open browser login and save local CLI auth",
17
- " logout Revoke and clear local CLI auth",
18
- " whoami [--json] Print the authenticated principal",
19
- " workspaces list [--json] List accessible workspaces",
20
- " workspaces use <workspace_id> Select a workspace for Product API calls",
21
- "",
22
- "Options:",
23
- " --json Print supported command output as JSON",
24
- " --help Show this help",
25
- ].join("\n");
12
+ import { BROWSER_ACCOUNT_SWITCH_GUIDANCE, BROWSER_SESSION_BOUNDARY, CLI_USAGE, WORKSPACE_SELECTION_GUIDANCE, } from "./cli-messages.js";
26
13
  /** Return whether a module URL is the process entrypoint, following npm bin symlinks. */
27
14
  export function isDirectCliInvocation(moduleUrl, argvPath, resolveRealpath = realpathSync) {
28
15
  if (argvPath === undefined) {
@@ -49,7 +36,14 @@ export async function runCli(argv = process.argv.slice(2), dependencies = {}) {
49
36
  const store = dependencies.stateStore ?? createFileCliAuthStateStore({ env });
50
37
  const fetcher = dependencies.fetcher;
51
38
  if (command.positionals[0] === "login") {
52
- await login({ env, store, fetcher, stdout, dependencies });
39
+ await login({
40
+ env,
41
+ store,
42
+ fetcher,
43
+ stdout,
44
+ dependencies,
45
+ noOpen: command.noOpen,
46
+ });
53
47
  return 0;
54
48
  }
55
49
  if (command.positionals[0] === "logout") {
@@ -104,6 +98,7 @@ function parseCommand(argv) {
104
98
  allowPositionals: true,
105
99
  options: {
106
100
  json: { type: "boolean", default: false },
101
+ "no-open": { type: "boolean", default: false },
107
102
  help: { type: "boolean", default: false },
108
103
  },
109
104
  });
@@ -111,6 +106,7 @@ function parseCommand(argv) {
111
106
  positionals: parsed.positionals,
112
107
  json: parsed.values.json ?? false,
113
108
  help: parsed.values.help ?? false,
109
+ noOpen: parsed.values["no-open"] ?? false,
114
110
  };
115
111
  }
116
112
  /** Complete browser-based local login and persist token state. */
@@ -128,13 +124,21 @@ async function login(options) {
128
124
  fetcher: options.fetcher,
129
125
  });
130
126
  const authorizeUrl = client.buildAuthorizeUrl(callback.callbackUrl, pkce, state);
127
+ options.stdout(`Hyperstar API: ${apiBaseUrl}`);
128
+ options.stdout(`Hyperstar app: ${appBaseUrl}`);
131
129
  options.stdout(`Open this URL to authorize Hyperstar CLI: ${authorizeUrl.toString()}`);
132
- try {
133
- await (options.dependencies.openBrowser ?? openBrowser)(authorizeUrl);
130
+ options.stdout(BROWSER_SESSION_BOUNDARY);
131
+ if (options.noOpen) {
132
+ options.stdout("Browser auto-open disabled. Open the URL above in a browser on this machine.");
134
133
  }
135
- catch (error) {
136
- void error;
137
- options.stdout("Could not open your browser automatically. Copy the URL above into your browser.");
134
+ else {
135
+ try {
136
+ await (options.dependencies.openBrowser ?? openBrowser)(authorizeUrl);
137
+ }
138
+ catch (error) {
139
+ void error;
140
+ options.stdout("Could not open your browser automatically. Copy the URL above into your browser.");
141
+ }
138
142
  }
139
143
  const callbackResult = await callback.result;
140
144
  if ("error" in callbackResult) {
@@ -149,6 +153,7 @@ async function login(options) {
149
153
  }));
150
154
  });
151
155
  options.stdout("Logged in to Hyperstar.");
156
+ options.stdout(WORKSPACE_SELECTION_GUIDANCE);
152
157
  }
153
158
  finally {
154
159
  await callback.close();
@@ -176,6 +181,7 @@ async function logout(options) {
176
181
  }
177
182
  });
178
183
  options.stdout("Logged out of Hyperstar.");
184
+ options.stdout(BROWSER_ACCOUNT_SWITCH_GUIDANCE);
179
185
  }
180
186
  /** Print the authenticated principal from the Product API. */
181
187
  async function whoami(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperstar/mcp",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "type": "module",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "description": "Local stdio MCP server and CLI for Hyperstar headless workflows.",