@togglhq/mcp 1.13.139 → 1.13.141
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 +4 -0
- package/build/cli.js +2 -2
- package/build/index.js +1 -1
- package/build/{src-b7HQlTt1.js → src-ZNZfSwsi.js} +248 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,6 +100,10 @@ One tool per domain (for example `tasks`, `projects`, `time-entries`, `organizat
|
|
|
100
100
|
|
|
101
101
|
**Mutation confirmation:** mutating tools return `confirm_required` with a `confirm_token` on the first call; repeat with `confirm_token` to execute.
|
|
102
102
|
|
|
103
|
+
### Deep links
|
|
104
|
+
|
|
105
|
+
- **deep-links** — read-only, no API calls. `action: "get"` returns the Toggl 2.0 web URL for a `task`, `project`, `time_entry`, `calendar_day`, `report` or `member` in the active organization and workspace, on the profile's environment (production or staging). It also returns a Track URL where the IDs map (members, by organization user ID); otherwise `track.url` is `null` with a `note` saying why. A time entry needs `task_id` to open directly; `calendar_day` opens the calendar on the week of its `date`. Example: `{ "action": "get", "data": { "entity": "report", "report_type": "detailed", "period": "prevMonth" } }`.
|
|
106
|
+
|
|
103
107
|
### Workspace, profiles, and auth
|
|
104
108
|
|
|
105
109
|
- **workspace-list** — list workspaces (`refresh: true` refetches from Accounts)
|
package/build/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as PUBLIC_SENTRY_PRIVACY_OPTIONS, c as initProductAnalytics, d as shutdownProductAnalytics, i as runMcpCli, l as resolveProductAnalyticsDistinctId, o as captureToolInvocation, s as getProductAnalyticsDistinctId, u as resolvePublicSentryDsn } from "./src-
|
|
2
|
+
import { a as PUBLIC_SENTRY_PRIVACY_OPTIONS, c as initProductAnalytics, d as shutdownProductAnalytics, i as runMcpCli, l as resolveProductAnalyticsDistinctId, o as captureToolInvocation, s as getProductAnalyticsDistinctId, u as resolvePublicSentryDsn } from "./src-ZNZfSwsi.js";
|
|
3
3
|
import * as Sentry from "@sentry/node";
|
|
4
4
|
//#region src/analytics-tool-metadata.ts
|
|
5
5
|
/**
|
|
@@ -162,7 +162,7 @@ function wrapServerWithProductAnalytics(server) {
|
|
|
162
162
|
}
|
|
163
163
|
//#endregion
|
|
164
164
|
//#region src/cli.ts
|
|
165
|
-
const packageVersion = "1.13.
|
|
165
|
+
const packageVersion = "1.13.141";
|
|
166
166
|
let sentryEnabled = false;
|
|
167
167
|
let productAnalyticsEnabled = false;
|
|
168
168
|
runMcpCli({
|
package/build/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as runMcpCli, n as MCP_MAX_TOOL_INPUT_ELEMENTS, r as bootstrapServer, t as MCP_CACHE_TTL_MS } from "./src-
|
|
2
|
+
import { i as runMcpCli, n as MCP_MAX_TOOL_INPUT_ELEMENTS, r as bootstrapServer, t as MCP_CACHE_TTL_MS } from "./src-ZNZfSwsi.js";
|
|
3
3
|
export { MCP_CACHE_TTL_MS, MCP_MAX_TOOL_INPUT_ELEMENTS, bootstrapServer, runMcpCli };
|
|
@@ -38538,7 +38538,7 @@ const PublicMeEntryRequestSchema = /* @__PURE__ */ object$2({
|
|
|
38538
38538
|
]))
|
|
38539
38539
|
});
|
|
38540
38540
|
//#endregion
|
|
38541
|
-
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.
|
|
38541
|
+
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.295_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_rea_e5acbc3a5b17d0e06ad550edd08ba899/node_modules/@toggl/queries/dist/org/invitation/requests.mjs
|
|
38542
38542
|
async function getInvitations(httpClient, signal) {
|
|
38543
38543
|
return (await httpClient.get(`invitations`, { signal })).json();
|
|
38544
38544
|
}
|
|
@@ -38555,7 +38555,7 @@ async function resendInvitation(httpClient, organization_id, organization_user_i
|
|
|
38555
38555
|
return (await httpClient.post(`organizations/${organization_id}/invitations/${organization_user_id}/resend`, { signal })).json();
|
|
38556
38556
|
}
|
|
38557
38557
|
//#endregion
|
|
38558
|
-
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.
|
|
38558
|
+
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.295_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_rea_e5acbc3a5b17d0e06ad550edd08ba899/node_modules/@toggl/queries/dist/org/utils/requests.mjs
|
|
38559
38559
|
function buildSearchParams(params, flattenArrays = false) {
|
|
38560
38560
|
const searchParams = new URLSearchParams();
|
|
38561
38561
|
Object.entries(params).forEach(([key, value]) => {
|
|
@@ -38567,7 +38567,7 @@ function buildSearchParams(params, flattenArrays = false) {
|
|
|
38567
38567
|
return searchParams;
|
|
38568
38568
|
}
|
|
38569
38569
|
//#endregion
|
|
38570
|
-
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.
|
|
38570
|
+
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.295_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_rea_e5acbc3a5b17d0e06ad550edd08ba899/node_modules/@toggl/queries/dist/org/organization-user/requests.mjs
|
|
38571
38571
|
async function getOrganizationUser(httpClient, organization_id, organization_user_id, signal) {
|
|
38572
38572
|
return (await httpClient.get(`organizations/${organization_id}/users/${organization_user_id}`, { signal })).json();
|
|
38573
38573
|
}
|
|
@@ -38582,7 +38582,7 @@ async function patchOrganizationUserActive(httpClient, organization_id, organiza
|
|
|
38582
38582
|
return (await httpClient.patch(`organizations/${organization_id}/users/${organization_user_id}/active_status/${status}`, { signal })).json();
|
|
38583
38583
|
}
|
|
38584
38584
|
//#endregion
|
|
38585
|
-
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.
|
|
38585
|
+
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.295_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_rea_e5acbc3a5b17d0e06ad550edd08ba899/node_modules/@toggl/queries/dist/org/workspace/requests.mjs
|
|
38586
38586
|
async function getWorkspaces(httpClient, organization_id, signal) {
|
|
38587
38587
|
return (await httpClient.get(`organizations/${organization_id}/workspaces`, { signal })).json();
|
|
38588
38588
|
}
|
|
@@ -38602,7 +38602,7 @@ const WorkingHoursUpdateInputSchema = /* @__PURE__ */ object$2({
|
|
|
38602
38602
|
});
|
|
38603
38603
|
const StatusOKSchema = /* @__PURE__ */ object$2({ status: /* @__PURE__ */ string$1() });
|
|
38604
38604
|
//#endregion
|
|
38605
|
-
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.
|
|
38605
|
+
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.295_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_rea_e5acbc3a5b17d0e06ad550edd08ba899/node_modules/@toggl/queries/dist/org/holiday-calendar/requests.mjs
|
|
38606
38606
|
async function holidayListDates(httpClient, organization_id, { year, country }, signal) {
|
|
38607
38607
|
return (await httpClient.get(`holidays/organizations/${organization_id}/calendar/dates`, {
|
|
38608
38608
|
signal,
|
|
@@ -38613,12 +38613,12 @@ async function holidayListDates(httpClient, organization_id, { year, country },
|
|
|
38613
38613
|
})).json();
|
|
38614
38614
|
}
|
|
38615
38615
|
//#endregion
|
|
38616
|
-
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.
|
|
38616
|
+
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.295_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_rea_e5acbc3a5b17d0e06ad550edd08ba899/node_modules/@toggl/queries/dist/shared-data/status/requests.mjs
|
|
38617
38617
|
async function getStatus(httpClient, signal) {
|
|
38618
38618
|
return (await httpClient.get(`shared_data/api/status`, { signal })).json();
|
|
38619
38619
|
}
|
|
38620
38620
|
//#endregion
|
|
38621
|
-
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.
|
|
38621
|
+
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.295_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_rea_e5acbc3a5b17d0e06ad550edd08ba899/node_modules/@toggl/queries/dist/org/timeoff/requests.mjs
|
|
38622
38622
|
async function timeoffListMyEntries(httpClient, organization_id, { from, to }, signal) {
|
|
38623
38623
|
return (await httpClient.get(`timeoff/organizations/${organization_id}/me`, {
|
|
38624
38624
|
signal,
|
|
@@ -38646,7 +38646,7 @@ async function timeoffDeleteMyEntry(httpClient, organization_id, id, signal) {
|
|
|
38646
38646
|
return response.json();
|
|
38647
38647
|
}
|
|
38648
38648
|
//#endregion
|
|
38649
|
-
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.
|
|
38649
|
+
//#region ../../node_modules/.pnpm/@toggl+queries@2.2.295_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_rea_e5acbc3a5b17d0e06ad550edd08ba899/node_modules/@toggl/queries/dist/shared-data/working-hours/requests.mjs
|
|
38650
38650
|
async function getMyWorkingHours(httpClient, organization_id, signal) {
|
|
38651
38651
|
return (await httpClient.get(`shared_data/api/workinghours/${organization_id}/me`, { signal })).json();
|
|
38652
38652
|
}
|
|
@@ -38671,7 +38671,7 @@ async function deleteMyWorkingHours(httpClient, organization_id, data, signal) {
|
|
|
38671
38671
|
return response.json();
|
|
38672
38672
|
}
|
|
38673
38673
|
//#endregion
|
|
38674
|
-
//#region ../cli-core/build/focus-client-
|
|
38674
|
+
//#region ../cli-core/build/focus-client-CGpMYUFy.js
|
|
38675
38675
|
/** Request header the API reads to attribute traffic to MCP or CLI. */
|
|
38676
38676
|
const TOGGL_CLIENT_HEADER = "X-Toggl-Client";
|
|
38677
38677
|
/** Header the Focus API reads for analytics and presence `platform_origin`. */
|
|
@@ -38908,9 +38908,12 @@ var FocusClient = class {
|
|
|
38908
38908
|
organizationIdNum;
|
|
38909
38909
|
workspaceId;
|
|
38910
38910
|
workspaceIdNum;
|
|
38911
|
+
/** Focus origin without the `/api` suffix, e.g. `https://focus.toggl.com`. */
|
|
38912
|
+
focusBaseUrl;
|
|
38911
38913
|
constructor(config) {
|
|
38912
38914
|
let baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
38913
38915
|
if (!baseUrl.endsWith("/api")) baseUrl += "/api";
|
|
38916
|
+
this.focusBaseUrl = baseUrl.slice(0, -4);
|
|
38914
38917
|
this.tokenProvider = config.tokenProvider;
|
|
38915
38918
|
this.clientSurface = config.clientSurface;
|
|
38916
38919
|
this.userId = config.userId;
|
|
@@ -39825,7 +39828,7 @@ function parseIdEnv(env, name) {
|
|
|
39825
39828
|
if (id <= 0 || id > Number.MAX_SAFE_INTEGER) throw new ApiTokenAuthError(`${name} must be a positive integer.`);
|
|
39826
39829
|
return id;
|
|
39827
39830
|
}
|
|
39828
|
-
function positiveId(value) {
|
|
39831
|
+
function positiveId$1(value) {
|
|
39829
39832
|
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
|
|
39830
39833
|
}
|
|
39831
39834
|
function focusApiBase(focusApiUrl) {
|
|
@@ -39887,12 +39890,12 @@ async function resolveApiTokenIdentity(options) {
|
|
|
39887
39890
|
if (userId === void 0) {
|
|
39888
39891
|
const me = await getJson(`${api}/accounts/me`, token, options);
|
|
39889
39892
|
if (me.status === 401) throw new ApiTokenAuthError(INVALID_KEY_MESSAGE, 401);
|
|
39890
|
-
userId = positiveId(me.body?.user_account_id);
|
|
39893
|
+
userId = positiveId$1(me.body?.user_account_id);
|
|
39891
39894
|
if (userId === void 0) throw new ApiTokenAuthError(`Could not determine your Toggl user ID (${me.status}). Set ${TOGGL_USER_ID_ENV}.`, me.status);
|
|
39892
39895
|
userSource = "api";
|
|
39893
39896
|
}
|
|
39894
|
-
const hostedMcpWorkspaceId = positiveId(settings.body.mcp_active_workspace_id);
|
|
39895
|
-
const hostedMcpOrganizationId = positiveId(settings.body.mcp_active_organization_id);
|
|
39897
|
+
const hostedMcpWorkspaceId = positiveId$1(settings.body.mcp_active_workspace_id);
|
|
39898
|
+
const hostedMcpOrganizationId = positiveId$1(settings.body.mcp_active_organization_id);
|
|
39896
39899
|
let workspaceId;
|
|
39897
39900
|
let workspaceSource;
|
|
39898
39901
|
if (options.workspaceIdOverride !== void 0) {
|
|
@@ -39902,7 +39905,7 @@ async function resolveApiTokenIdentity(options) {
|
|
|
39902
39905
|
workspaceId = envWorkspaceId;
|
|
39903
39906
|
workspaceSource = "env";
|
|
39904
39907
|
} else {
|
|
39905
|
-
workspaceId = positiveId(settings.body.current_workspace_id) ?? hostedMcpWorkspaceId;
|
|
39908
|
+
workspaceId = positiveId$1(settings.body.current_workspace_id) ?? hostedMcpWorkspaceId;
|
|
39906
39909
|
workspaceSource = "api";
|
|
39907
39910
|
}
|
|
39908
39911
|
if (workspaceId === void 0) throw new ApiTokenAuthError(`Could not determine a workspace: your Toggl 2.0 settings have no current workspace. Set ${TOGGL_WORKSPACE_ID_ENV}.`);
|
|
@@ -41085,7 +41088,8 @@ const AUTH_ERROR = {
|
|
|
41085
41088
|
const FOCUS_CLIENT_SYNC_PASSTHROUGH_PROP_KEYS = [
|
|
41086
41089
|
"httpClient",
|
|
41087
41090
|
"organizationId",
|
|
41088
|
-
"workspaceIdNumber"
|
|
41091
|
+
"workspaceIdNumber",
|
|
41092
|
+
"focusBaseUrl"
|
|
41089
41093
|
];
|
|
41090
41094
|
function readFocusClientSyncPassthroughProp(client, prop) {
|
|
41091
41095
|
if (!client) return;
|
|
@@ -41171,7 +41175,7 @@ function createAuthenticatedClientProxy() {
|
|
|
41171
41175
|
} });
|
|
41172
41176
|
}
|
|
41173
41177
|
//#endregion
|
|
41174
|
-
//#region ../operations/build/validation-
|
|
41178
|
+
//#region ../operations/build/validation-CQfYPZ9x.js
|
|
41175
41179
|
const optionalNumber = /* @__PURE__ */ optional$1(/* @__PURE__ */ number$2());
|
|
41176
41180
|
const perPageField = (max) => /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ number$2(), /* @__PURE__ */ integer(), /* @__PURE__ */ minValue$1(1), /* @__PURE__ */ maxValue$1(max), /* @__PURE__ */ description$1(`Results per page (1-${max})`)));
|
|
41177
41181
|
const perPageSchema = perPageField(100);
|
|
@@ -42209,6 +42213,226 @@ const versionOverrides = { "focus.version.service": {
|
|
|
42209
42213
|
description: "MCP package version plus the Focus API service revision.",
|
|
42210
42214
|
agentGuidance: "mcp.package is this published MCP package version (e.g. 1.8.0). focus_api is the Focus API process revision (git SHA / build number) — it does not change when you update the npm MCP package."
|
|
42211
42215
|
} };
|
|
42216
|
+
const DEEP_LINK_ENTITIES = [
|
|
42217
|
+
"task",
|
|
42218
|
+
"project",
|
|
42219
|
+
"time_entry",
|
|
42220
|
+
"calendar_day",
|
|
42221
|
+
"report",
|
|
42222
|
+
"member"
|
|
42223
|
+
];
|
|
42224
|
+
const DEEP_LINK_REPORT_TYPES = [
|
|
42225
|
+
"summary",
|
|
42226
|
+
"detailed",
|
|
42227
|
+
"profitability",
|
|
42228
|
+
"utilization",
|
|
42229
|
+
"workload",
|
|
42230
|
+
"time-accounting",
|
|
42231
|
+
"time-off"
|
|
42232
|
+
];
|
|
42233
|
+
const DEEP_LINK_REPORT_PERIODS = [
|
|
42234
|
+
"today",
|
|
42235
|
+
"yesterday",
|
|
42236
|
+
"thisWeek",
|
|
42237
|
+
"nextWeek",
|
|
42238
|
+
"weekToDate",
|
|
42239
|
+
"prevWeek",
|
|
42240
|
+
"last2Weeks",
|
|
42241
|
+
"thisMonth",
|
|
42242
|
+
"nextMonth",
|
|
42243
|
+
"prevMonth",
|
|
42244
|
+
"monthToDate",
|
|
42245
|
+
"thisQuarter",
|
|
42246
|
+
"nextQuarter",
|
|
42247
|
+
"quarterToDate",
|
|
42248
|
+
"thisSemester",
|
|
42249
|
+
"semesterToDate",
|
|
42250
|
+
"last30Days",
|
|
42251
|
+
"last90Days",
|
|
42252
|
+
"lastQuarter",
|
|
42253
|
+
"lastSemester",
|
|
42254
|
+
"last12Months",
|
|
42255
|
+
"thisYear",
|
|
42256
|
+
"yearToDate",
|
|
42257
|
+
"prevYear",
|
|
42258
|
+
"allTime"
|
|
42259
|
+
];
|
|
42260
|
+
const PROJECT_TABS = [
|
|
42261
|
+
"tasks",
|
|
42262
|
+
"board",
|
|
42263
|
+
"timeline",
|
|
42264
|
+
"dashboard",
|
|
42265
|
+
"members",
|
|
42266
|
+
"period"
|
|
42267
|
+
];
|
|
42268
|
+
const MEMBER_TABS = ["time-off"];
|
|
42269
|
+
const DEEP_LINK_TABS = [...PROJECT_TABS, ...MEMBER_TABS];
|
|
42270
|
+
const PERIOD_REPORT_TYPES = new Set(DEEP_LINK_REPORT_TYPES.filter((type) => type !== "time-off"));
|
|
42271
|
+
const positiveId = /* @__PURE__ */ pipe$2(/* @__PURE__ */ number$2(), /* @__PURE__ */ integer(), /* @__PURE__ */ minValue$1(1));
|
|
42272
|
+
const isoDay = /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ isoDate$1("must be YYYY-MM-DD"));
|
|
42273
|
+
const DeepLinkInputSchema = /* @__PURE__ */ object$2({
|
|
42274
|
+
entity: /* @__PURE__ */ picklist$1(DEEP_LINK_ENTITIES),
|
|
42275
|
+
id: /* @__PURE__ */ optional$1(positiveId),
|
|
42276
|
+
task_id: /* @__PURE__ */ optional$1(positiveId),
|
|
42277
|
+
project_id: /* @__PURE__ */ optional$1(positiveId),
|
|
42278
|
+
date: /* @__PURE__ */ optional$1(isoDay),
|
|
42279
|
+
report_type: /* @__PURE__ */ optional$1(/* @__PURE__ */ picklist$1(DEEP_LINK_REPORT_TYPES)),
|
|
42280
|
+
period: /* @__PURE__ */ optional$1(/* @__PURE__ */ picklist$1(DEEP_LINK_REPORT_PERIODS)),
|
|
42281
|
+
from: /* @__PURE__ */ optional$1(isoDay),
|
|
42282
|
+
to: /* @__PURE__ */ optional$1(isoDay),
|
|
42283
|
+
tab: /* @__PURE__ */ optional$1(/* @__PURE__ */ picklist$1(DEEP_LINK_TABS))
|
|
42284
|
+
});
|
|
42285
|
+
const ENTITIES_WITH_ID = new Set([
|
|
42286
|
+
"task",
|
|
42287
|
+
"project",
|
|
42288
|
+
"time_entry",
|
|
42289
|
+
"member"
|
|
42290
|
+
]);
|
|
42291
|
+
/** Cross-field rules the schema cannot carry; returns the first violation. */
|
|
42292
|
+
function deepLinkInputError(input) {
|
|
42293
|
+
if (input.id === void 0 && ENTITIES_WITH_ID.has(input.entity)) return "id is required for task, project, time_entry and member (member id is the organization user ID)";
|
|
42294
|
+
if (input.tab !== void 0 && !(input.entity === "project" && PROJECT_TABS.includes(input.tab)) && !(input.entity === "member" && MEMBER_TABS.includes(input.tab))) return `tab is ${PROJECT_TABS.join("|")} for project, or ${MEMBER_TABS.join("|")} for member`;
|
|
42295
|
+
if (input.from === void 0 !== (input.to === void 0)) return "from and to must be passed together";
|
|
42296
|
+
if (input.period !== void 0 && input.from !== void 0) return "pass either period or from/to, not both";
|
|
42297
|
+
if ((input.period !== void 0 || input.from !== void 0) && !(input.entity === "report" && PERIOD_REPORT_TYPES.has(input.report_type ?? "summary"))) return "period and from/to apply only to report entities other than time-off";
|
|
42298
|
+
if (input.from !== void 0 && input.to !== void 0 && input.from > input.to) return "from must not be after to";
|
|
42299
|
+
}
|
|
42300
|
+
const FOCUS_HOST_PATTERN = /^focus\.((?:[a-z0-9-]+\.)*toggl\.(?:com|space))$/i;
|
|
42301
|
+
const APP_HOST_PATTERN = /^app\.(toggl\.(?:com|space)|[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.ms\.toggl\.space)$/i;
|
|
42302
|
+
function trackBaseUrlFor(focusBaseUrl) {
|
|
42303
|
+
const hostname = new URL(focusBaseUrl).hostname.toLowerCase();
|
|
42304
|
+
const base = FOCUS_HOST_PATTERN.exec(hostname)?.[1] ?? APP_HOST_PATTERN.exec(hostname)?.[1];
|
|
42305
|
+
return base ? `https://track.${base}` : null;
|
|
42306
|
+
}
|
|
42307
|
+
function withQuery(url, params) {
|
|
42308
|
+
const search = new URLSearchParams();
|
|
42309
|
+
for (const [key, value] of Object.entries(params)) if (value !== void 0) search.set(key, value);
|
|
42310
|
+
const query = search.toString();
|
|
42311
|
+
return query ? `${url}?${query}` : url;
|
|
42312
|
+
}
|
|
42313
|
+
function trackUnmapped(input) {
|
|
42314
|
+
switch (input.entity) {
|
|
42315
|
+
case "calendar_day":
|
|
42316
|
+
case "report": return {
|
|
42317
|
+
url: null,
|
|
42318
|
+
note: "Track calendar and reports are scoped to a Track workspace; a Toggl 2.0 workspace ID is not a Track workspace ID."
|
|
42319
|
+
};
|
|
42320
|
+
default: return {
|
|
42321
|
+
url: null,
|
|
42322
|
+
note: `Toggl 2.0 ${input.entity.replace("_", " ")} IDs are not Track IDs (imports and Track sync create new records), so no Track URL maps.`
|
|
42323
|
+
};
|
|
42324
|
+
}
|
|
42325
|
+
}
|
|
42326
|
+
/** Builds the links for input that already passed `deepLinkInputError`. */
|
|
42327
|
+
function buildDeepLinks(input, context) {
|
|
42328
|
+
const origin = context.focusBaseUrl.replace(/\/+$/, "");
|
|
42329
|
+
const workspaceRoot = `${origin}/${context.organizationId}/workspaces/${context.workspaceId}`;
|
|
42330
|
+
const trackBase = trackBaseUrlFor(origin);
|
|
42331
|
+
let focus;
|
|
42332
|
+
let track = trackUnmapped(input);
|
|
42333
|
+
switch (input.entity) {
|
|
42334
|
+
case "task":
|
|
42335
|
+
focus = {
|
|
42336
|
+
url: withQuery(input.project_id !== void 0 ? `${workspaceRoot}/projects/${input.project_id}` : `${workspaceRoot}/calendar`, { tid: String(input.id) }),
|
|
42337
|
+
note: input.project_id !== void 0 ? "Opens the task editor over its project." : "Opens the task editor over the calendar; pass project_id to open it over the project instead."
|
|
42338
|
+
};
|
|
42339
|
+
break;
|
|
42340
|
+
case "project":
|
|
42341
|
+
focus = { url: `${workspaceRoot}/projects/${input.id}${input.tab ? `/${input.tab}` : ""}` };
|
|
42342
|
+
break;
|
|
42343
|
+
case "time_entry":
|
|
42344
|
+
if (input.task_id !== void 0) focus = {
|
|
42345
|
+
url: withQuery(`${workspaceRoot}/calendar`, {
|
|
42346
|
+
tid: String(input.task_id),
|
|
42347
|
+
teid: String(input.id)
|
|
42348
|
+
}),
|
|
42349
|
+
note: "Opens the time entry inside its task's editor."
|
|
42350
|
+
};
|
|
42351
|
+
else focus = {
|
|
42352
|
+
url: `${workspaceRoot}/calendar`,
|
|
42353
|
+
note: "A time entry is only addressable through its task; pass task_id to open it directly. Without it this is the calendar."
|
|
42354
|
+
};
|
|
42355
|
+
break;
|
|
42356
|
+
case "calendar_day":
|
|
42357
|
+
focus = {
|
|
42358
|
+
url: withQuery(`${workspaceRoot}/calendar`, { d: input.date }),
|
|
42359
|
+
note: input.date ? `Opens the week of ${input.date}.` : "Opens the current week."
|
|
42360
|
+
};
|
|
42361
|
+
break;
|
|
42362
|
+
case "report": {
|
|
42363
|
+
const reportType = input.report_type ?? "summary";
|
|
42364
|
+
const period = input.period !== void 0 ? { preset: input.period } : input.from !== void 0 ? {
|
|
42365
|
+
from: input.from,
|
|
42366
|
+
to: input.to
|
|
42367
|
+
} : void 0;
|
|
42368
|
+
focus = { url: withQuery(`${workspaceRoot}/reports/${reportType}`, { pe: period ? JSON.stringify(period) : void 0 }) };
|
|
42369
|
+
break;
|
|
42370
|
+
}
|
|
42371
|
+
case "member":
|
|
42372
|
+
focus = { url: `${workspaceRoot}/members/${input.id}${input.tab ? `/${input.tab}` : ""}` };
|
|
42373
|
+
track = trackBase ? {
|
|
42374
|
+
url: `${trackBase}/organization/${context.organizationId}/members/${input.id}/time-off`,
|
|
42375
|
+
note: input.tab === "time-off" ? void 0 : "Track has no member profile page; this is the member's Track time-off page."
|
|
42376
|
+
} : {
|
|
42377
|
+
url: null,
|
|
42378
|
+
note: `No Track host is known for ${new URL(origin).hostname}.`
|
|
42379
|
+
};
|
|
42380
|
+
break;
|
|
42381
|
+
}
|
|
42382
|
+
return {
|
|
42383
|
+
entity: input.entity,
|
|
42384
|
+
organization_id: context.organizationId,
|
|
42385
|
+
workspace_id: context.workspaceId,
|
|
42386
|
+
focus,
|
|
42387
|
+
track
|
|
42388
|
+
};
|
|
42389
|
+
}
|
|
42390
|
+
const deepLinkOperations = [{
|
|
42391
|
+
id: "focus.deep-links.get",
|
|
42392
|
+
family: "focus",
|
|
42393
|
+
resource: "deep-links",
|
|
42394
|
+
action: "get",
|
|
42395
|
+
title: "Get deep links",
|
|
42396
|
+
description: "Build Toggl 2.0 web URLs (and Track URLs where IDs map) for a task, project, time entry, calendar day, report or member. Read-only; makes no API calls.",
|
|
42397
|
+
agentGuidance: "member id is the organization user ID. time_entry needs task_id to open the entry itself. report_type defaults to summary; set period (preset) or from/to (YYYY-MM-DD) for a date range. track.url is null with a note when the IDs do not map to Track.",
|
|
42398
|
+
safety: "read",
|
|
42399
|
+
destructive: false,
|
|
42400
|
+
cli: {
|
|
42401
|
+
group: [],
|
|
42402
|
+
command: "deep-link",
|
|
42403
|
+
interactive: "hidden",
|
|
42404
|
+
examples: [{
|
|
42405
|
+
description: "Link to a task",
|
|
42406
|
+
data: {
|
|
42407
|
+
entity: "task",
|
|
42408
|
+
id: 123
|
|
42409
|
+
}
|
|
42410
|
+
}, {
|
|
42411
|
+
description: "Link to last month's detailed report",
|
|
42412
|
+
data: {
|
|
42413
|
+
entity: "report",
|
|
42414
|
+
report_type: "detailed",
|
|
42415
|
+
period: "prevMonth"
|
|
42416
|
+
}
|
|
42417
|
+
}]
|
|
42418
|
+
},
|
|
42419
|
+
mcp: { entityTool: "deep-links" },
|
|
42420
|
+
inputSchema: DeepLinkInputSchema,
|
|
42421
|
+
execute: (input, { client }) => {
|
|
42422
|
+
const deepLinkInput = input;
|
|
42423
|
+
const error = deepLinkInputError(deepLinkInput);
|
|
42424
|
+
if (error) return Promise.resolve({
|
|
42425
|
+
ok: false,
|
|
42426
|
+
status: 400,
|
|
42427
|
+
message: error
|
|
42428
|
+
});
|
|
42429
|
+
return client.runGeneratedRequest("getDeepLinks", () => Promise.resolve(buildDeepLinks(deepLinkInput, {
|
|
42430
|
+
focusBaseUrl: client.focusBaseUrl,
|
|
42431
|
+
organizationId: client.organizationId,
|
|
42432
|
+
workspaceId: client.workspaceIdNumber
|
|
42433
|
+
})));
|
|
42434
|
+
}
|
|
42435
|
+
}];
|
|
42212
42436
|
const dateRangeDay = /* @__PURE__ */ pipe$2(/* @__PURE__ */ string$1(), /* @__PURE__ */ regex(/^\d{4}-\d{2}-\d{2}$/, "must be YYYY-MM-DD"));
|
|
42213
42437
|
const TimeOffMeUpdateInputSchema = /* @__PURE__ */ intersect([/* @__PURE__ */ object$2({ timeoff_id: /* @__PURE__ */ number$2() }), PublicMeEntryRequestSchema]);
|
|
42214
42438
|
const emptySchema = /* @__PURE__ */ object$2({});
|
|
@@ -57889,7 +58113,11 @@ function applyOverrides(operation) {
|
|
|
57889
58113
|
}
|
|
57890
58114
|
};
|
|
57891
58115
|
}
|
|
57892
|
-
const operations = [
|
|
58116
|
+
const operations = [
|
|
58117
|
+
...generatedFocusOperations.map((operation) => applyOverrides(operation)),
|
|
58118
|
+
...orgSharedOperations,
|
|
58119
|
+
...deepLinkOperations
|
|
58120
|
+
];
|
|
57893
58121
|
function visibleOperations() {
|
|
57894
58122
|
return operations.filter((operation) => !operation.hidden);
|
|
57895
58123
|
}
|
|
@@ -59004,7 +59232,7 @@ function registerWorkspaceTools(server) {
|
|
|
59004
59232
|
//#region src/package-version.ts
|
|
59005
59233
|
function mcpPackageVersion() {
|
|
59006
59234
|
try {
|
|
59007
|
-
return "1.13.
|
|
59235
|
+
return "1.13.141";
|
|
59008
59236
|
} catch {
|
|
59009
59237
|
return "unknown";
|
|
59010
59238
|
}
|
|
@@ -59185,7 +59413,7 @@ import_main.default.config({
|
|
|
59185
59413
|
quiet: true,
|
|
59186
59414
|
ignore: ["MISSING_ENV_FILE"]
|
|
59187
59415
|
});
|
|
59188
|
-
const packageVersion = "1.13.
|
|
59416
|
+
const packageVersion = "1.13.141";
|
|
59189
59417
|
const MCP_CACHE_TTL_MS = 300 * 1e3;
|
|
59190
59418
|
const MCP_MAX_TOOL_INPUT_ELEMENTS = 1e4;
|
|
59191
59419
|
function resolvePublicUrls() {
|
|
@@ -59305,4 +59533,4 @@ function bootstrapServer(options = {}) {
|
|
|
59305
59533
|
//#endregion
|
|
59306
59534
|
export { PUBLIC_SENTRY_PRIVACY_OPTIONS as a, initProductAnalytics as c, shutdownProductAnalytics as d, runMcpCli as i, resolveProductAnalyticsDistinctId as l, MCP_MAX_TOOL_INPUT_ELEMENTS as n, captureToolInvocation as o, bootstrapServer as r, getProductAnalyticsDistinctId as s, MCP_CACHE_TTL_MS as t, resolvePublicSentryDsn as u };
|
|
59307
59535
|
|
|
59308
|
-
//# sourceMappingURL=src-
|
|
59536
|
+
//# sourceMappingURL=src-ZNZfSwsi.js.map
|