@pgnio/helios-mcp 0.2.0 → 0.2.1

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/cli.js CHANGED
@@ -920,11 +920,15 @@ var HeliosAgentMcpAuthService = class {
920
920
  requestedConstraints
921
921
  });
922
922
  if (pendingLogin) {
923
- return {
924
- ...pendingLogin,
925
- connected: false,
926
- message: formatHeliosLoginPrompt(pendingLogin)
927
- };
923
+ const polled = await this.pollLogin(pendingLogin.deviceCode).catch(() => null);
924
+ if (polled?.status === "connected") return polled;
925
+ if (polled?.status !== "rejected" && polled?.status !== "expired") {
926
+ return {
927
+ ...pendingLogin,
928
+ connected: false,
929
+ message: formatHeliosLoginPrompt(pendingLogin)
930
+ };
931
+ }
928
932
  }
929
933
  const started = await this.startLogin({
930
934
  clientName: options.clientName ?? "Helios MCP",
@@ -937,7 +941,24 @@ var HeliosAgentMcpAuthService = class {
937
941
  message: formatHeliosLoginPrompt(started)
938
942
  };
939
943
  }
944
+ /** Polls the given login, or the stored pending one when no device code is given. */
940
945
  async pollLogin(deviceCode) {
946
+ if (!deviceCode) {
947
+ const pending = await this.sessionStore.getPendingLogin();
948
+ if (!pending) {
949
+ const session = await this.getValidSession();
950
+ if (session) return { ...sanitizeAgentSession(session), connected: true, status: "connected" };
951
+ return {
952
+ status: "failed",
953
+ connected: false,
954
+ message: "No Helios login is in progress. Call helios_auth_ensure_login to start one."
955
+ };
956
+ }
957
+ deviceCode = pending.deviceCode;
958
+ } else {
959
+ const pending = await this.sessionStore.getPendingLogin();
960
+ if (pending && pending.userCode.toUpperCase() === deviceCode.trim().toUpperCase()) deviceCode = pending.deviceCode;
961
+ }
941
962
  try {
942
963
  const response = await this.client.exchangeDeviceCode(deviceCode);
943
964
  const session = createStoredAgentSession(response, this.now());
@@ -1072,7 +1093,7 @@ User code: ${result.userCode}
1072
1093
 
1073
1094
  Requested scopes: ${result.requestedScope.join(", ")}
1074
1095
 
1075
- After approving access, ask me to continue and I will finish connecting.`;
1096
+ After approving access, call helios_auth_ensure_login (or helios_auth_poll_login) again to finish connecting.`;
1076
1097
  }
1077
1098
  function isPendingLoginCompatible(pendingLogin, requestedScope, requestedConstraints) {
1078
1099
  const pendingScope = new Set(pendingLogin.requestedScope);
@@ -2016,7 +2037,8 @@ function asPending2(login) {
2016
2037
  // src/tools.ts
2017
2038
  var import_zod5 = require("zod");
2018
2039
  var pollLoginInputSchema = import_zod5.z.object({
2019
- deviceCode: import_zod5.z.string().min(1)
2040
+ /** Optional: defaults to the login started by helios_auth_ensure_login / helios_auth_start_login. */
2041
+ deviceCode: import_zod5.z.string().min(1).optional()
2020
2042
  });
2021
2043
  var startLoginOutputSchema = import_zod5.z.object({
2022
2044
  status: import_zod5.z.literal("pending"),
@@ -2325,7 +2347,7 @@ function createHeliosAuthToolDefinitions(service) {
2325
2347
  {
2326
2348
  name: "helios_auth_ensure_login",
2327
2349
  title: "Ensure Helios Login",
2328
- description: "Ensures a delegated Helios session exists, or starts a login flow and returns a ready-to-display approval prompt.",
2350
+ description: "Ensures a delegated Helios session exists, or starts a login flow and returns a ready-to-display approval prompt. Call it again after the person approves: it finishes connecting.",
2329
2351
  inputSchema: ensureLoginInputSchema,
2330
2352
  async execute(input) {
2331
2353
  const result = ensureLoginOutputSchema.parse(await service.ensureLogin(input));
@@ -2347,7 +2369,7 @@ function createHeliosAuthToolDefinitions(service) {
2347
2369
  {
2348
2370
  name: "helios_auth_poll_login",
2349
2371
  title: "Poll Helios Login",
2350
- description: "Polls the device flow until the delegated Helios login is approved or rejected.",
2372
+ description: "Checks whether the Helios login was approved and finishes connecting. The device code is optional; without it, the login in progress is checked.",
2351
2373
  inputSchema: pollLoginInputSchema,
2352
2374
  async execute(input) {
2353
2375
  const result = pollLoginOutputSchema.parse(await service.pollLogin(input.deviceCode));
@@ -2786,7 +2808,7 @@ function withManualLoginFields(result) {
2786
2808
  return {
2787
2809
  actionRequired: true,
2788
2810
  loginUrl: result.verificationUriComplete,
2789
- nextStep: "Open the login URL in your browser, approve Helios access, then ask me to continue."
2811
+ nextStep: "Open the login URL in your browser, approve Helios access, then call helios_auth_ensure_login again to finish connecting."
2790
2812
  };
2791
2813
  }
2792
2814
  function buildPortfolioText(result) {
@@ -2799,7 +2821,7 @@ ${result.verificationUriComplete}
2799
2821
 
2800
2822
  User code: ${result.userCode}
2801
2823
 
2802
- After approving access, ask me to continue and I will finish connecting.`;
2824
+ After approving access, call helios_auth_ensure_login (or helios_auth_poll_login) again to finish connecting.`;
2803
2825
  }
2804
2826
 
2805
2827
  // src/server.ts
@@ -2813,7 +2835,7 @@ async function createHeliosAgentMcpServer(options) {
2813
2835
  const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
2814
2836
  const server = new McpServer({
2815
2837
  name: "helios",
2816
- version: "0.1.0"
2838
+ version: "0.2.1"
2817
2839
  });
2818
2840
  const sessionStore = options.sessionStore ?? new FileAgentSessionStore(options.sessionPath ?? getDefaultHeliosAgentMcpSessionPath());
2819
2841
  const client = new HeliosAgentAuthClient({
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createHeliosAgentMcpServer
4
- } from "./chunk-NWGWXYTS.mjs";
4
+ } from "./chunk-NCF7ASJB.mjs";
5
5
 
6
6
  // src/cli.ts
7
7
  async function main() {
package/dist/index.d.mts CHANGED
@@ -795,7 +795,8 @@ declare class HeliosAgentMcpAuthService {
795
795
  invalidateIfUnauthorized(error: unknown, options?: EnsureLoginOptions): Promise<PendingLoginResult | null>;
796
796
  refreshSessionAfterUnauthorized(error: unknown): Promise<StoredAgentSession | null>;
797
797
  ensureLogin(options?: EnsureLoginOptions): Promise<EnsureLoginResult>;
798
- pollLogin(deviceCode: string): Promise<PollLoginResult>;
798
+ /** Polls the given login, or the stored pending one when no device code is given. */
799
+ pollLogin(deviceCode?: string): Promise<PollLoginResult>;
799
800
  whoami(): Promise<AgentSessionView>;
800
801
  getAccessToken(): Promise<string | null>;
801
802
  requireSession(): Promise<StoredAgentSession>;
@@ -1176,10 +1177,10 @@ declare function createHeliosAuthToolDefinitions(service: HeliosAgentMcpAuthServ
1176
1177
  title: string;
1177
1178
  description: string;
1178
1179
  inputSchema: z.ZodObject<{
1179
- deviceCode: z.ZodString;
1180
+ deviceCode: z.ZodOptional<z.ZodString>;
1180
1181
  }, z.core.$strip>;
1181
1182
  execute(input: {
1182
- deviceCode: string;
1183
+ deviceCode?: string | undefined;
1183
1184
  }): Promise<{
1184
1185
  content: {
1185
1186
  type: "text";
package/dist/index.d.ts CHANGED
@@ -795,7 +795,8 @@ declare class HeliosAgentMcpAuthService {
795
795
  invalidateIfUnauthorized(error: unknown, options?: EnsureLoginOptions): Promise<PendingLoginResult | null>;
796
796
  refreshSessionAfterUnauthorized(error: unknown): Promise<StoredAgentSession | null>;
797
797
  ensureLogin(options?: EnsureLoginOptions): Promise<EnsureLoginResult>;
798
- pollLogin(deviceCode: string): Promise<PollLoginResult>;
798
+ /** Polls the given login, or the stored pending one when no device code is given. */
799
+ pollLogin(deviceCode?: string): Promise<PollLoginResult>;
799
800
  whoami(): Promise<AgentSessionView>;
800
801
  getAccessToken(): Promise<string | null>;
801
802
  requireSession(): Promise<StoredAgentSession>;
@@ -1176,10 +1177,10 @@ declare function createHeliosAuthToolDefinitions(service: HeliosAgentMcpAuthServ
1176
1177
  title: string;
1177
1178
  description: string;
1178
1179
  inputSchema: z.ZodObject<{
1179
- deviceCode: z.ZodString;
1180
+ deviceCode: z.ZodOptional<z.ZodString>;
1180
1181
  }, z.core.$strip>;
1181
1182
  execute(input: {
1182
- deviceCode: string;
1183
+ deviceCode?: string | undefined;
1183
1184
  }): Promise<{
1184
1185
  content: {
1185
1186
  type: "text";
package/dist/index.js CHANGED
@@ -954,11 +954,15 @@ var HeliosAgentMcpAuthService = class {
954
954
  requestedConstraints
955
955
  });
956
956
  if (pendingLogin) {
957
- return {
958
- ...pendingLogin,
959
- connected: false,
960
- message: formatHeliosLoginPrompt(pendingLogin)
961
- };
957
+ const polled = await this.pollLogin(pendingLogin.deviceCode).catch(() => null);
958
+ if (polled?.status === "connected") return polled;
959
+ if (polled?.status !== "rejected" && polled?.status !== "expired") {
960
+ return {
961
+ ...pendingLogin,
962
+ connected: false,
963
+ message: formatHeliosLoginPrompt(pendingLogin)
964
+ };
965
+ }
962
966
  }
963
967
  const started = await this.startLogin({
964
968
  clientName: options.clientName ?? "Helios MCP",
@@ -971,7 +975,24 @@ var HeliosAgentMcpAuthService = class {
971
975
  message: formatHeliosLoginPrompt(started)
972
976
  };
973
977
  }
978
+ /** Polls the given login, or the stored pending one when no device code is given. */
974
979
  async pollLogin(deviceCode) {
980
+ if (!deviceCode) {
981
+ const pending = await this.sessionStore.getPendingLogin();
982
+ if (!pending) {
983
+ const session = await this.getValidSession();
984
+ if (session) return { ...sanitizeAgentSession(session), connected: true, status: "connected" };
985
+ return {
986
+ status: "failed",
987
+ connected: false,
988
+ message: "No Helios login is in progress. Call helios_auth_ensure_login to start one."
989
+ };
990
+ }
991
+ deviceCode = pending.deviceCode;
992
+ } else {
993
+ const pending = await this.sessionStore.getPendingLogin();
994
+ if (pending && pending.userCode.toUpperCase() === deviceCode.trim().toUpperCase()) deviceCode = pending.deviceCode;
995
+ }
975
996
  try {
976
997
  const response = await this.client.exchangeDeviceCode(deviceCode);
977
998
  const session = createStoredAgentSession(response, this.now());
@@ -1106,7 +1127,7 @@ User code: ${result.userCode}
1106
1127
 
1107
1128
  Requested scopes: ${result.requestedScope.join(", ")}
1108
1129
 
1109
- After approving access, ask me to continue and I will finish connecting.`;
1130
+ After approving access, call helios_auth_ensure_login (or helios_auth_poll_login) again to finish connecting.`;
1110
1131
  }
1111
1132
  function isPendingLoginCompatible(pendingLogin, requestedScope, requestedConstraints) {
1112
1133
  const pendingScope = new Set(pendingLogin.requestedScope);
@@ -2084,7 +2105,8 @@ function asPending2(login) {
2084
2105
  // src/tools.ts
2085
2106
  var import_zod5 = require("zod");
2086
2107
  var pollLoginInputSchema = import_zod5.z.object({
2087
- deviceCode: import_zod5.z.string().min(1)
2108
+ /** Optional: defaults to the login started by helios_auth_ensure_login / helios_auth_start_login. */
2109
+ deviceCode: import_zod5.z.string().min(1).optional()
2088
2110
  });
2089
2111
  var startLoginOutputSchema = import_zod5.z.object({
2090
2112
  status: import_zod5.z.literal("pending"),
@@ -2393,7 +2415,7 @@ function createHeliosAuthToolDefinitions(service) {
2393
2415
  {
2394
2416
  name: "helios_auth_ensure_login",
2395
2417
  title: "Ensure Helios Login",
2396
- description: "Ensures a delegated Helios session exists, or starts a login flow and returns a ready-to-display approval prompt.",
2418
+ description: "Ensures a delegated Helios session exists, or starts a login flow and returns a ready-to-display approval prompt. Call it again after the person approves: it finishes connecting.",
2397
2419
  inputSchema: ensureLoginInputSchema,
2398
2420
  async execute(input) {
2399
2421
  const result = ensureLoginOutputSchema.parse(await service.ensureLogin(input));
@@ -2415,7 +2437,7 @@ function createHeliosAuthToolDefinitions(service) {
2415
2437
  {
2416
2438
  name: "helios_auth_poll_login",
2417
2439
  title: "Poll Helios Login",
2418
- description: "Polls the device flow until the delegated Helios login is approved or rejected.",
2440
+ description: "Checks whether the Helios login was approved and finishes connecting. The device code is optional; without it, the login in progress is checked.",
2419
2441
  inputSchema: pollLoginInputSchema,
2420
2442
  async execute(input) {
2421
2443
  const result = pollLoginOutputSchema.parse(await service.pollLogin(input.deviceCode));
@@ -2854,7 +2876,7 @@ function withManualLoginFields(result) {
2854
2876
  return {
2855
2877
  actionRequired: true,
2856
2878
  loginUrl: result.verificationUriComplete,
2857
- nextStep: "Open the login URL in your browser, approve Helios access, then ask me to continue."
2879
+ nextStep: "Open the login URL in your browser, approve Helios access, then call helios_auth_ensure_login again to finish connecting."
2858
2880
  };
2859
2881
  }
2860
2882
  function buildPortfolioText(result) {
@@ -2867,7 +2889,7 @@ ${result.verificationUriComplete}
2867
2889
 
2868
2890
  User code: ${result.userCode}
2869
2891
 
2870
- After approving access, ask me to continue and I will finish connecting.`;
2892
+ After approving access, call helios_auth_ensure_login (or helios_auth_poll_login) again to finish connecting.`;
2871
2893
  }
2872
2894
 
2873
2895
  // src/server.ts
@@ -2881,7 +2903,7 @@ async function createHeliosAgentMcpServer(options) {
2881
2903
  const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
2882
2904
  const server = new McpServer({
2883
2905
  name: "helios",
2884
- version: "0.1.0"
2906
+ version: "0.2.1"
2885
2907
  });
2886
2908
  const sessionStore = options.sessionStore ?? new FileAgentSessionStore(options.sessionPath ?? getDefaultHeliosAgentMcpSessionPath());
2887
2909
  const client = new HeliosAgentAuthClient({
package/dist/index.mjs CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  pendingAgentLoginSchema,
24
24
  retryAfterUnauthorizedRefresh,
25
25
  toolAnnotations
26
- } from "./chunk-NWGWXYTS.mjs";
26
+ } from "./chunk-NCF7ASJB.mjs";
27
27
  export {
28
28
  FileAgentSessionStore,
29
29
  HOSTED_RECONNECT_MESSAGE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgnio/helios-mcp",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Helios MCP server: connect an AI agent to your Helios account to read markets and your portfolio and to trade on Hyperliquid. Most apps can use the hosted URL https://helios.pgn.io/mcp instead.",
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://helios.pgn.io/?connect=ai",