@togglhq/mcp 1.6.10 → 1.6.11

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/build/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as runMcpCli } from "./src-BHKKOqzB.js";
2
+ import { n as runMcpCli } from "./src-DHcD1uso.js";
3
3
  //#region src/cli.ts
4
4
  runMcpCli();
5
5
  //#endregion
package/build/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { n as runMcpCli, t as bootstrapServer } from "./src-BHKKOqzB.js";
2
+ import { n as runMcpCli, t as bootstrapServer } from "./src-DHcD1uso.js";
3
3
  export { bootstrapServer, runMcpCli };
@@ -31852,6 +31852,10 @@ function openAuthBrowser(url) {
31852
31852
  });
31853
31853
  }
31854
31854
  const TOGGL_OAUTH_CLIENT_ID = "000000";
31855
+ /** Production accounts-be client for hosted `/focus/cli/auth-code` redirects. */
31856
+ const TOGGL_OAUTH_MANUAL_CLIENT_ID = "2ca88f39-18c5-4686-9101-3d3b7bd24470";
31857
+ /** Staging accounts-be client for hosted `/focus/cli/auth-code` redirects. */
31858
+ const TOGGL_OAUTH_MANUAL_STAGING_CLIENT_ID = "88972024-c0b3-46d1-8191-e48fb876434c";
31855
31859
  const TOGGL_OAUTH_CALLBACK_PORT = 8716;
31856
31860
  const TOGGL_OAUTH_LOGIN_TIMEOUT_MS = 12e4;
31857
31861
  const TOGGL_OAUTH_MANUAL_CALLBACK_PATH = "/focus/cli/auth-code";
@@ -31865,6 +31869,16 @@ function togglOAuthRedirectUri(port = TOGGL_OAUTH_CALLBACK_PORT) {
31865
31869
  function togglOAuthManualRedirectUri(accountsApiUrl) {
31866
31870
  return `${accountsApiUrl.replace(/\/$/, "")}${TOGGL_OAUTH_MANUAL_CALLBACK_PATH}`;
31867
31871
  }
31872
+ /**
31873
+ * Localhost CLI login keeps the test client (`000000`, domain `http://localhost`).
31874
+ * Manual/headless login uses dedicated first-party clients whose domain prefixes
31875
+ * match the hosted auth-code page. Do not send `000000` with a hosted redirect.
31876
+ */
31877
+ function resolveTogglOAuthClientId(flowMode, accountsApiUrl) {
31878
+ if (flowMode !== "manual") return TOGGL_OAUTH_CLIENT_ID;
31879
+ if (accountsApiUrl.replace(/\/$/, "") === "https://accounts.toggl.space") return TOGGL_OAUTH_MANUAL_STAGING_CLIENT_ID;
31880
+ return TOGGL_OAUTH_MANUAL_CLIENT_ID;
31881
+ }
31868
31882
  const BACKGROUND_DARK_SVG = `<svg width="1440" height="900" viewBox="0 0 1440 900" fill="none" xmlns="http://www.w3.org/2000/svg">
31869
31883
  <g clip-path="url(#clip0_11555_363)">
31870
31884
  <g clip-path="url(#clip1_11555_363)">
@@ -32213,12 +32227,12 @@ function waitForOAuthCallback(port = TOGGL_OAUTH_CALLBACK_PORT, timeoutMs = TOGG
32213
32227
  });
32214
32228
  });
32215
32229
  }
32216
- async function exchangeAuthorizationCode(accountsApiUrl, code, verifier, redirectUri = togglOAuthRedirectUri()) {
32230
+ async function exchangeAuthorizationCode(accountsApiUrl, code, verifier, redirectUri = togglOAuthRedirectUri(), clientId = TOGGL_OAUTH_CLIENT_ID) {
32217
32231
  const params = new URLSearchParams({
32218
32232
  grant_type: "authorization_code",
32219
32233
  code,
32220
32234
  code_verifier: verifier,
32221
- client_id: TOGGL_OAUTH_CLIENT_ID,
32235
+ client_id: clientId,
32222
32236
  redirect_uri: redirectUri
32223
32237
  });
32224
32238
  const response = await fetch(`${accountsApiUrl}/api/oauth/token?${params}`, { method: "POST" });
@@ -32255,7 +32269,7 @@ function resolveTogglOAuthFlowMode(options) {
32255
32269
  }
32256
32270
  function buildTogglOAuthAuthorizationUrl(options) {
32257
32271
  return `${options.accountsApiUrl.replace(/\/$/, "")}/focus/login/?${new URLSearchParams({
32258
- client_id: TOGGL_OAUTH_CLIENT_ID,
32272
+ client_id: resolveTogglOAuthClientId(options.flowMode, options.accountsApiUrl),
32259
32273
  code_challenge: options.codeChallenge,
32260
32274
  code_challenge_method: "S256",
32261
32275
  redirect_uri: options.redirectUri,
@@ -32271,6 +32285,7 @@ async function obtainTogglOAuthAuthorizationCode(options) {
32271
32285
  authorizationCode: options.authorizationCode
32272
32286
  });
32273
32287
  const redirectUri = resolveTogglOAuthRedirectUri(options.accountsApiUrl, flowMode);
32288
+ const clientId = resolveTogglOAuthClientId(flowMode, options.accountsApiUrl);
32274
32289
  const { verifier, challenge } = generateOAuthPKCE();
32275
32290
  const authUrl = buildTogglOAuthAuthorizationUrl({
32276
32291
  accountsApiUrl: options.accountsApiUrl,
@@ -32308,6 +32323,7 @@ async function obtainTogglOAuthAuthorizationCode(options) {
32308
32323
  code,
32309
32324
  verifier,
32310
32325
  redirectUri,
32326
+ clientId,
32311
32327
  flowMode
32312
32328
  };
32313
32329
  }
@@ -32374,11 +32390,11 @@ const PUBLIC_MCP_PACKAGE_NAME = "@togglhq/mcp";
32374
32390
  function npxMcpAuthCommand() {
32375
32391
  return `npx ${PUBLIC_MCP_PACKAGE_NAME} auth`;
32376
32392
  }
32377
- async function refreshTokens(accountsApiUrl, refreshToken) {
32393
+ async function refreshTokens(accountsApiUrl, refreshToken, clientId = TOGGL_OAUTH_CLIENT_ID) {
32378
32394
  const params = new URLSearchParams({
32379
32395
  grant_type: "refresh_token",
32380
32396
  refresh_token: refreshToken,
32381
- client_id: TOGGL_OAUTH_CLIENT_ID
32397
+ client_id: clientId
32382
32398
  });
32383
32399
  const response = await fetch(`${accountsApiUrl}/api/oauth/token?${params}`, { method: "POST" });
32384
32400
  if (!response.ok) {
@@ -32392,7 +32408,7 @@ async function getValidToken$1(scope = "cli", profile) {
32392
32408
  if (!authConfig) throw new Error(scope === "cli" ? "Not authenticated. Run `toggl auth` to sign in." : `Not authenticated. Run \`${npxMcpAuthCommand()}\` to sign in.`);
32393
32409
  const now = Date.now() / 1e3;
32394
32410
  if (authConfig.expires_at > now + 60) return authConfig.access_token;
32395
- const tokens = await refreshTokens(authConfig.accounts_api_url, authConfig.refresh_token);
32411
+ const tokens = await refreshTokens(authConfig.accounts_api_url, authConfig.refresh_token, authConfig.oauth_client_id ?? "000000");
32396
32412
  authConfig.access_token = tokens.access_token;
32397
32413
  authConfig.refresh_token = tokens.refresh_token;
32398
32414
  authConfig.expires_at = now + tokens.expires_in;
@@ -32485,7 +32501,7 @@ async function runAuthFlow(accountsApiUrl = "https://accounts.toggl.com", focusA
32485
32501
  log("Continuing MCP authentication with existing session...\n");
32486
32502
  } else {
32487
32503
  log("Toggl 2.0 MCP — Authentication\n");
32488
- const { code, verifier, redirectUri } = await obtainTogglOAuthAuthorizationCode({
32504
+ const { code, verifier, redirectUri, clientId } = await obtainTogglOAuthAuthorizationCode({
32489
32505
  accountsApiUrl,
32490
32506
  flowMode: options.oauthFlowMode ?? (options.manualPrompt ? "manual" : "local"),
32491
32507
  authorizationCode: options.authorizationCode,
@@ -32493,7 +32509,7 @@ async function runAuthFlow(accountsApiUrl = "https://accounts.toggl.com", focusA
32493
32509
  log
32494
32510
  });
32495
32511
  log("Exchanging authorization code...");
32496
- const tokens = await exchangeAuthorizationCode(accountsApiUrl, code, verifier, redirectUri);
32512
+ const tokens = await exchangeAuthorizationCode(accountsApiUrl, code, verifier, redirectUri, clientId);
32497
32513
  log("Fetching account info...");
32498
32514
  const user = await fetchAccountsApiMe(accountsApiUrl, tokens.access_token);
32499
32515
  if (!user.user_account_id) throw new Error("Could not determine user ID from API response.");
@@ -32506,6 +32522,7 @@ async function runAuthFlow(accountsApiUrl = "https://accounts.toggl.com", focusA
32506
32522
  accounts_api_url: accountsApiUrl,
32507
32523
  focus_api_url: focusApiUrl,
32508
32524
  authenticated_at: (/* @__PURE__ */ new Date()).toISOString(),
32525
+ oauth_client_id: clientId,
32509
32526
  workspaces,
32510
32527
  default_workspace_id: user.default_workspace_id
32511
32528
  };
@@ -32534,6 +32551,7 @@ async function runAuthFlow(accountsApiUrl = "https://accounts.toggl.com", focusA
32534
32551
  focus_api_url: pendingContext.focus_api_url,
32535
32552
  accounts_api_url: pendingContext.accounts_api_url,
32536
32553
  authenticated_at: pendingContext.authenticated_at,
32554
+ oauth_client_id: pendingContext.oauth_client_id,
32537
32555
  workspaces
32538
32556
  };
32539
32557
  saveConfig(config);
@@ -44939,7 +44957,7 @@ import_main.default.config({
44939
44957
  quiet: true,
44940
44958
  ignore: ["MISSING_ENV_FILE"]
44941
44959
  });
44942
- const packageVersion = "1.6.10";
44960
+ const packageVersion = "1.6.11";
44943
44961
  function resolvePublicUrls() {
44944
44962
  return {
44945
44963
  focusApiUrl: process.env.TOGGL_FOCUS_API_URL ?? "https://focus.toggl.com",
@@ -45004,4 +45022,4 @@ function bootstrapServer(options = {}) {
45004
45022
  //#endregion
45005
45023
  export { runMcpCli as n, bootstrapServer as t };
45006
45024
 
45007
- //# sourceMappingURL=src-BHKKOqzB.js.map
45025
+ //# sourceMappingURL=src-DHcD1uso.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@togglhq/mcp",
3
- "version": "1.6.10",
3
+ "version": "1.6.11",
4
4
  "description": "Toggl 2.0 MCP server for Claude Code, Claude Desktop, and other MCP clients.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",