@transcend-io/mcp-server-consent 0.2.15 → 0.3.0
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 +6 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +79 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{tools-DLlRbNSf.mjs → tools-bVmFBYcw.mjs} +210 -16
- package/dist/tools-bVmFBYcw.mjs.map +1 -0
- package/package.json +3 -3
- package/dist/tools-DLlRbNSf.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -83,11 +83,16 @@ See [CONTRIBUTING.md](../../../CONTRIBUTING.md#mcp-servers) for workspace layout
|
|
|
83
83
|
- `consent_list_cookies` — List cookies
|
|
84
84
|
- `consent_list_airgap_bundles` — List Airgap bundles
|
|
85
85
|
- `consent_list_regimes` — List consent regimes
|
|
86
|
-
- `
|
|
86
|
+
- `consent_get_inventory_stats` — Cookie/data-flow inventory triage counts (live, needs review, junk)
|
|
87
|
+
- `consent_get_aggregate_analytics` — Aggregate consent analytics (`airgapBundleAggregateAnalytics`)
|
|
88
|
+
- `consent_get_timeseries_analytics` — Timeseries consent analytics (`airgapBundleTimeseriesAnalytics`)
|
|
89
|
+
- `consent_get_analytics_data` — Consent metrics via `analyticsData` (opt-in/out, signals, sessions)
|
|
87
90
|
- `consent_update_cookies` — Update cookies (approve, junk, assign purposes)
|
|
88
91
|
- `consent_update_data_flows` — Update data flows
|
|
89
92
|
- `consent_bulk_triage` — Bulk approve or junk cookies and data flows
|
|
90
93
|
|
|
94
|
+
Analytics tools require the **ViewConsentManager** API key scope. See [Consent Analytics Using GraphQL API](https://docs.transcend.io/docs/articles/consent-management/configuration/consent-stats-with-gql-api).
|
|
95
|
+
|
|
91
96
|
## Related packages
|
|
92
97
|
|
|
93
98
|
Also available as part of the unified [`@transcend-io/mcp`](../mcp/README.md), which includes all domains. See the [root README](../../../README.md#mcp-servers) for the full list.
|
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -14,6 +14,26 @@ declare function getConsentTools(clients: ToolClients): ToolDefinition[];
|
|
|
14
14
|
*/
|
|
15
15
|
declare function resolveAirgapBundleId(graphql: TranscendGraphQLBase): Promise<string>;
|
|
16
16
|
//#endregion
|
|
17
|
+
//#region src/analyticsDateRange.d.ts
|
|
18
|
+
interface ResolvedAnalyticsDateRange {
|
|
19
|
+
/** Start time as epoch seconds */
|
|
20
|
+
startEpoch: number;
|
|
21
|
+
/** End time as epoch seconds */
|
|
22
|
+
endEpoch: number;
|
|
23
|
+
/** Start time as ISO string (for legacy analyticsData API) */
|
|
24
|
+
startIso: string;
|
|
25
|
+
/** End time as ISO string (for legacy analyticsData API) */
|
|
26
|
+
endIso: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve a date range from explicit ISO timestamps or a lookback window.
|
|
30
|
+
*/
|
|
31
|
+
declare function resolveAnalyticsDateRange(args: {
|
|
32
|
+
/** Explicit start datetime (ISO 8601) */start?: string; /** Explicit end datetime (ISO 8601) */
|
|
33
|
+
end?: string; /** Lookback window in days when start is omitted (default 7) */
|
|
34
|
+
days?: number;
|
|
35
|
+
}): ResolvedAnalyticsDateRange;
|
|
36
|
+
//#endregion
|
|
17
37
|
//#region src/tools/consent_get_preferences.d.ts
|
|
18
38
|
declare const GetPreferencesSchema: z.ZodObject<{
|
|
19
39
|
identifier: z.ZodString;
|
|
@@ -99,9 +119,64 @@ declare const ListRegimesSchema: z.ZodObject<{
|
|
|
99
119
|
}, z.core.$strip>;
|
|
100
120
|
type ListRegimesInput = z.infer<typeof ListRegimesSchema>;
|
|
101
121
|
//#endregion
|
|
102
|
-
//#region src/tools/
|
|
103
|
-
declare const
|
|
104
|
-
type
|
|
122
|
+
//#region src/tools/consent_get_inventory_stats.d.ts
|
|
123
|
+
declare const GetInventoryStatsSchema: z.ZodObject<{}, z.core.$strip>;
|
|
124
|
+
type GetInventoryStatsInput = z.infer<typeof GetInventoryStatsSchema>;
|
|
125
|
+
//#endregion
|
|
126
|
+
//#region src/tools/consent_get_aggregate_analytics.d.ts
|
|
127
|
+
declare const GetAggregateAnalyticsSchema: z.ZodObject<{
|
|
128
|
+
metric: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodEnum<{
|
|
129
|
+
ConsentChanged: "CONSENT_CHANGED";
|
|
130
|
+
SignalDetected: "SIGNAL_DETECTED";
|
|
131
|
+
SiteSessions: "SITE_SESSIONS";
|
|
132
|
+
PageViews: "PAGE_VIEWS";
|
|
133
|
+
}>>;
|
|
134
|
+
start: z.ZodOptional<z.ZodString>;
|
|
135
|
+
end: z.ZodOptional<z.ZodString>;
|
|
136
|
+
days: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
137
|
+
include_dimensions: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
138
|
+
NewValue: "NEW_VALUE";
|
|
139
|
+
Regime: "REGIME";
|
|
140
|
+
Purpose: "PURPOSE";
|
|
141
|
+
}>>>;
|
|
142
|
+
}, z.core.$strip>;
|
|
143
|
+
type GetAggregateAnalyticsInput = z.infer<typeof GetAggregateAnalyticsSchema>;
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/tools/consent_get_timeseries_analytics.d.ts
|
|
146
|
+
declare const GetTimeseriesAnalyticsSchema: z.ZodObject<{
|
|
147
|
+
metric: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodEnum<{
|
|
148
|
+
ConsentChanged: "CONSENT_CHANGED";
|
|
149
|
+
SignalDetected: "SIGNAL_DETECTED";
|
|
150
|
+
SiteSessions: "SITE_SESSIONS";
|
|
151
|
+
PageViews: "PAGE_VIEWS";
|
|
152
|
+
}>>;
|
|
153
|
+
start: z.ZodOptional<z.ZodString>;
|
|
154
|
+
end: z.ZodOptional<z.ZodString>;
|
|
155
|
+
days: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
156
|
+
bin_interval: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
157
|
+
Minute: "1m";
|
|
158
|
+
Hourly: "1h";
|
|
159
|
+
Daily: "1d";
|
|
160
|
+
}>>>;
|
|
161
|
+
}, z.core.$strip>;
|
|
162
|
+
type GetTimeseriesAnalyticsInput = z.infer<typeof GetTimeseriesAnalyticsSchema>;
|
|
163
|
+
//#endregion
|
|
164
|
+
//#region src/tools/consent_get_analytics_data.d.ts
|
|
165
|
+
declare const GetAnalyticsDataSchema: z.ZodObject<{
|
|
166
|
+
data_source: z.ZodEnum<{
|
|
167
|
+
PrivacySignalTimeseries: "PRIVACY_SIGNAL_TIMESERIES";
|
|
168
|
+
ConsentChangesTimeseries: "CONSENT_CHANGES_TIMESERIES";
|
|
169
|
+
ConsentSessionsByRegime: "CONSENT_SESSIONS_BY_REGIME";
|
|
170
|
+
}>;
|
|
171
|
+
start: z.ZodOptional<z.ZodString>;
|
|
172
|
+
end: z.ZodOptional<z.ZodString>;
|
|
173
|
+
days: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
174
|
+
bin: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
175
|
+
Hourly: "1h";
|
|
176
|
+
Daily: "1d";
|
|
177
|
+
}>>>;
|
|
178
|
+
}, z.core.$strip>;
|
|
179
|
+
type GetAnalyticsDataInput = z.infer<typeof GetAnalyticsDataSchema>;
|
|
105
180
|
//#endregion
|
|
106
181
|
//#region src/tools/consent_update_cookies.d.ts
|
|
107
182
|
declare const UpdateCookieItemSchema: z.ZodObject<{
|
|
@@ -179,5 +254,5 @@ declare const BulkTriageSchema: z.ZodObject<{
|
|
|
179
254
|
}, z.core.$strip>;
|
|
180
255
|
type BulkTriageInput = z.infer<typeof BulkTriageSchema>;
|
|
181
256
|
//#endregion
|
|
182
|
-
export { type BulkTriageInput, type BulkTriageItemInput, BulkTriageItemSchema, BulkTriageSchema, type
|
|
257
|
+
export { type BulkTriageInput, type BulkTriageItemInput, BulkTriageItemSchema, BulkTriageSchema, type GetAggregateAnalyticsInput, GetAggregateAnalyticsSchema, type GetAnalyticsDataInput, GetAnalyticsDataSchema, type GetInventoryStatsInput, GetInventoryStatsSchema, type GetPreferencesInput, GetPreferencesSchema, type GetTimeseriesAnalyticsInput, GetTimeseriesAnalyticsSchema, type ListAirgapBundlesInput, ListAirgapBundlesSchema, type ListCookiesInput, ListCookiesSchema, type ListDataFlowsInput, ListDataFlowsSchema, type ListPurposesInput, ListPurposesSchema, type ListRegimesInput, ListRegimesSchema, type PurposeConsentInput, PurposeConsentSchema, type SetPreferencesInput, SetPreferencesSchema, type UpdateCookieItemInput, UpdateCookieItemSchema, type UpdateCookiesInput, UpdateCookiesSchema, type UpdateDataFlowItemInput, UpdateDataFlowItemSchema, type UpdateDataFlowsInput, UpdateDataFlowsSchema, getConsentTools, resolveAirgapBundleId, resolveAnalyticsDateRange };
|
|
183
258
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/tools/index.ts","../src/resolveAirgapBundleId.ts","../src/tools/consent_get_preferences.ts","../src/tools/consent_set_preferences.ts","../src/tools/consent_list_airgap_bundles.ts","../src/tools/consent_list_cookies.ts","../src/tools/consent_list_data_flows.ts","../src/tools/consent_list_purposes.ts","../src/tools/consent_list_regimes.ts","../src/tools/
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/tools/index.ts","../src/resolveAirgapBundleId.ts","../src/analyticsDateRange.ts","../src/tools/consent_get_preferences.ts","../src/tools/consent_set_preferences.ts","../src/tools/consent_list_airgap_bundles.ts","../src/tools/consent_list_cookies.ts","../src/tools/consent_list_data_flows.ts","../src/tools/consent_list_purposes.ts","../src/tools/consent_list_regimes.ts","../src/tools/consent_get_inventory_stats.ts","../src/tools/consent_get_aggregate_analytics.ts","../src/tools/consent_get_timeseries_analytics.ts","../src/tools/consent_get_analytics_data.ts","../src/tools/consent_update_cookies.ts","../src/tools/consent_update_data_flows.ts","../src/tools/consent_bulk_triage.ts"],"mappings":";;;;;;iBAiBgB,eAAA,CAAgB,OAAA,EAAS,WAAA,GAAc,cAAA;;;;;;;;iBCJjC,qBAAA,CAAsB,OAAA,EAAS,oBAAA,GAAuB,OAAA;;;UCb3D,0BAAA;;EAEf,UAAA;;EAEA,QAAA;;EAEA,QAAA;EFW6B;EET7B,MAAA;AAAA;;;;iBAMc,yBAAA,CAA0B,IAAA;EFG2B,yCEDnE,KAAA;EAEA,GAAA,WDLoB;ECOpB,IAAA;AAAA,IACE,0BAAA;;;cCnBS,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;KAIrB,mBAAA,GAAsB,CAAA,CAAE,KAAA,QAAa,oBAAA;;;cCJpC,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;KAIrB,mBAAA,GAAsB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAEpC,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;KAMrB,mBAAA,GAAsB,CAAA,CAAE,KAAA,QAAa,oBAAA;;;cCHpC,uBAAA,EAAuB,GAAA,CAAA,SAAA,KAAc,YAAA,CAAd,MAAA;AAAA,KACxB,sBAAA,GAAyB,MAAA;;;cCFxB,iBAAA,EAAiB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;KAalB,gBAAA,GAAmB,CAAA,CAAE,KAAA,QAAa,iBAAA;;;cCbjC,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;KAapB,kBAAA,GAAqB,CAAA,CAAE,KAAA,QAAa,mBAAA;;;cCpBnC,kBAAA,EAAkB,CAAA,CAAA,SAAA;;;KAGnB,iBAAA,GAAoB,CAAA,CAAE,KAAA,QAAa,kBAAA;;;cCHlC,iBAAA,EAAiB,CAAA,CAAA,SAAA;;;;KAIlB,gBAAA,GAAmB,CAAA,CAAE,KAAA,QAAa,iBAAA;;;cCGjC,uBAAA,EAAuB,CAAA,CAAA,SAAA,KAAA,CAAA,CAAA,IAAA,CAAA,MAAA;AAAA,KACxB,sBAAA,GAAyB,CAAA,CAAE,KAAA,QAAa,uBAAA;;;cCGvC,2BAAA,EAA2B,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;KAsB5B,0BAAA,GAA6B,CAAA,CAAE,KAAA,QAAa,2BAAA;;;cCtB3C,4BAAA,EAA4B,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;KAsB7B,2BAAA,GAA8B,CAAA,CAAE,KAAA,QAAa,4BAAA;;;cC1B5C,sBAAA,EAAsB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;KAwBvB,qBAAA,GAAwB,CAAA,CAAE,KAAA,QAAa,sBAAA;;;cCxBtC,sBAAA,EAAsB,CAAA,CAAA,SAAA;;;;;;;;KAcvB,qBAAA,GAAwB,CAAA,CAAE,KAAA,QAAa,sBAAA;AAAA,cAEtC,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;;;;;;;KAGpB,kBAAA,GAAqB,CAAA,CAAE,KAAA,QAAa,mBAAA;;;cCnBnC,wBAAA,EAAwB,CAAA,CAAA,SAAA;;;;;;;;KAWzB,uBAAA,GAA0B,CAAA,CAAE,KAAA,QAAa,wBAAA;AAAA,cAExC,qBAAA,EAAqB,CAAA,CAAA,SAAA;;;;;;;;;;KAGtB,oBAAA,GAAuB,CAAA,CAAE,KAAA,QAAa,qBAAA;;;cCTrC,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;KAUrB,mBAAA,GAAsB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAEpC,gBAAA,EAAgB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;KAGjB,eAAA,GAAkB,CAAA,CAAE,KAAA,QAAa,gBAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
export { BulkTriageItemSchema, BulkTriageSchema,
|
|
1
|
+
import { _ as GetAggregateAnalyticsSchema, a as UpdateCookiesSchema, b as BulkTriageSchema, c as ListRegimesSchema, d as ListCookiesSchema, f as ListAirgapBundlesSchema, g as GetAnalyticsDataSchema, h as GetInventoryStatsSchema, i as UpdateCookieItemSchema, l as ListPurposesSchema, m as GetPreferencesSchema, n as UpdateDataFlowItemSchema, o as PurposeConsentSchema, p as GetTimeseriesAnalyticsSchema, r as UpdateDataFlowsSchema, s as SetPreferencesSchema, t as getConsentTools, u as ListDataFlowsSchema, v as resolveAnalyticsDateRange, x as resolveAirgapBundleId, y as BulkTriageItemSchema } from "./tools-bVmFBYcw.mjs";
|
|
2
|
+
export { BulkTriageItemSchema, BulkTriageSchema, GetAggregateAnalyticsSchema, GetAnalyticsDataSchema, GetInventoryStatsSchema, GetPreferencesSchema, GetTimeseriesAnalyticsSchema, ListAirgapBundlesSchema, ListCookiesSchema, ListDataFlowsSchema, ListPurposesSchema, ListRegimesSchema, PurposeConsentSchema, SetPreferencesSchema, UpdateCookieItemSchema, UpdateCookiesSchema, UpdateDataFlowItemSchema, UpdateDataFlowsSchema, getConsentTools, resolveAirgapBundleId, resolveAnalyticsDateRange };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EmptySchema, createListResult, createToolResult, defineTool, z } from "@transcend-io/mcp-server-base";
|
|
2
|
-
import { ConsentTrackerStatus, ConsentTrackerType, CookieOrderField, DataFlowOrderField, OrderDirection, TriageAction } from "@transcend-io/privacy-types";
|
|
3
|
-
import { COOKIES, COOKIE_STATS, DATA_FLOWS, DATA_FLOW_STATS, EXPERIENCES, FETCH_CONSENT_MANAGER, FETCH_CONSENT_MANAGER_ID, PURPOSES, UPDATE_DATA_FLOWS, UPDATE_OR_CREATE_COOKIES } from "@transcend-io/sdk";
|
|
2
|
+
import { AirgapBundleAnalyticsBinInterval, AirgapBundleAnalyticsDimension, AirgapBundleAnalyticsMetric, ConsentManagerAnalyticsDataSource, ConsentManagerMetricBin, ConsentTrackerStatus, ConsentTrackerType, CookieOrderField, DataFlowOrderField, OrderDirection, TriageAction } from "@transcend-io/privacy-types";
|
|
3
|
+
import { AIRGAP_BUNDLE_AGGREGATE_ANALYTICS, AIRGAP_BUNDLE_TIMESERIES_ANALYTICS, CONSENT_MANAGER_ANALYTICS_DATA, COOKIES, COOKIE_STATS, DATA_FLOWS, DATA_FLOW_STATS, EXPERIENCES, FETCH_CONSENT_MANAGER, FETCH_CONSENT_MANAGER_ID, PURPOSES, UPDATE_DATA_FLOWS, UPDATE_OR_CREATE_COOKIES } from "@transcend-io/sdk";
|
|
4
4
|
//#region src/resolveAirgapBundleId.ts
|
|
5
5
|
const bundleIdCache = /* @__PURE__ */ new WeakMap();
|
|
6
6
|
/**
|
|
@@ -99,6 +99,169 @@ function createConsentBulkTriageTool(clients) {
|
|
|
99
99
|
});
|
|
100
100
|
}
|
|
101
101
|
//#endregion
|
|
102
|
+
//#region src/analyticsDateRange.ts
|
|
103
|
+
/**
|
|
104
|
+
* Resolve a date range from explicit ISO timestamps or a lookback window.
|
|
105
|
+
*/
|
|
106
|
+
function resolveAnalyticsDateRange(args) {
|
|
107
|
+
const endDate = args.end ? new Date(args.end) : /* @__PURE__ */ new Date();
|
|
108
|
+
const lookbackDays = args.days ?? 7;
|
|
109
|
+
const startDate = args.start ? new Date(args.start) : /* @__PURE__ */ new Date(endDate.getTime() - lookbackDays * 24 * 60 * 60 * 1e3);
|
|
110
|
+
if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) throw new Error("Invalid start or end date");
|
|
111
|
+
if (startDate > endDate) throw new Error("Start date must be before end date");
|
|
112
|
+
return {
|
|
113
|
+
startEpoch: Math.floor(startDate.getTime() / 1e3),
|
|
114
|
+
endEpoch: Math.floor(endDate.getTime() / 1e3),
|
|
115
|
+
startIso: startDate.toISOString(),
|
|
116
|
+
endIso: endDate.toISOString()
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region src/normalizeAnalyticsMetric.ts
|
|
121
|
+
const VALID_METRICS = new Set(Object.values(AirgapBundleAnalyticsMetric));
|
|
122
|
+
/** Common agent/API guesses mapped to GraphQL AnalyticsEvent values */
|
|
123
|
+
const ANALYTICS_METRIC_ALIASES = {
|
|
124
|
+
PAGE_VIEW: AirgapBundleAnalyticsMetric.PageViews,
|
|
125
|
+
CONSENT_SESSION: AirgapBundleAnalyticsMetric.SiteSessions,
|
|
126
|
+
CONSENT_SESSIONS: AirgapBundleAnalyticsMetric.SiteSessions
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Normalize metric input, accepting common aliases (e.g. PAGE_VIEW → PAGE_VIEWS).
|
|
130
|
+
*/
|
|
131
|
+
function normalizeAnalyticsMetric(metric) {
|
|
132
|
+
const upper = metric.toUpperCase();
|
|
133
|
+
if (VALID_METRICS.has(upper)) return upper;
|
|
134
|
+
return ANALYTICS_METRIC_ALIASES[upper] ?? upper;
|
|
135
|
+
}
|
|
136
|
+
const airgapBundleAnalyticsMetricSchema = z.preprocess((value) => typeof value === "string" ? normalizeAnalyticsMetric(value) : value, z.nativeEnum(AirgapBundleAnalyticsMetric));
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region src/tools/consent_get_aggregate_analytics.ts
|
|
139
|
+
const GetAggregateAnalyticsSchema = z.object({
|
|
140
|
+
metric: airgapBundleAnalyticsMetricSchema.describe("Analytics metric to query. CONSENT_CHANGED for opt-in/out counts; SITE_SESSIONS or PAGE_VIEWS for traffic totals."),
|
|
141
|
+
start: z.string().optional().describe("Start datetime (ISO 8601). Defaults to `days` lookback from end."),
|
|
142
|
+
end: z.string().optional().describe("End datetime (ISO 8601). Defaults to now."),
|
|
143
|
+
days: z.coerce.number().min(1).max(365).optional().describe("Lookback window in days when start is omitted (default: 7)."),
|
|
144
|
+
include_dimensions: z.array(z.nativeEnum(AirgapBundleAnalyticsDimension)).optional().describe("Dimension breakdowns (e.g. NEW_VALUE, REGIME, PURPOSE). Recommended for CONSENT_CHANGED.")
|
|
145
|
+
});
|
|
146
|
+
function createConsentGetAggregateAnalyticsTool(clients) {
|
|
147
|
+
return defineTool({
|
|
148
|
+
name: "consent_get_aggregate_analytics",
|
|
149
|
+
description: "Query aggregate consent analytics via airgapBundleAggregateAnalytics. Use CONSENT_CHANGED with NEW_VALUE/REGIME/PURPOSE for opt-in/out counts; SITE_SESSIONS or PAGE_VIEWS for total traffic. Requires ViewConsentManager API key scope.",
|
|
150
|
+
category: "Consent Management",
|
|
151
|
+
readOnly: true,
|
|
152
|
+
annotations: {
|
|
153
|
+
readOnlyHint: true,
|
|
154
|
+
destructiveHint: false,
|
|
155
|
+
idempotentHint: true
|
|
156
|
+
},
|
|
157
|
+
zodSchema: GetAggregateAnalyticsSchema,
|
|
158
|
+
handler: async ({ metric, start, end, days, include_dimensions }) => {
|
|
159
|
+
const airgapBundleId = await resolveAirgapBundleId(clients.graphql);
|
|
160
|
+
const range = resolveAnalyticsDateRange({
|
|
161
|
+
start,
|
|
162
|
+
end,
|
|
163
|
+
days
|
|
164
|
+
});
|
|
165
|
+
const items = (await clients.graphql.makeRequest(AIRGAP_BUNDLE_AGGREGATE_ANALYTICS, {
|
|
166
|
+
id: airgapBundleId,
|
|
167
|
+
input: {
|
|
168
|
+
metric,
|
|
169
|
+
start: range.startEpoch,
|
|
170
|
+
end: range.endEpoch,
|
|
171
|
+
...include_dimensions?.length ? { includeDimensions: include_dimensions } : {}
|
|
172
|
+
}
|
|
173
|
+
})).airgapBundleAggregateAnalytics.items;
|
|
174
|
+
return createToolResult(true, {
|
|
175
|
+
airgapBundleId,
|
|
176
|
+
metric,
|
|
177
|
+
period: {
|
|
178
|
+
start: range.startIso,
|
|
179
|
+
end: range.endIso,
|
|
180
|
+
startEpoch: range.startEpoch,
|
|
181
|
+
endEpoch: range.endEpoch
|
|
182
|
+
},
|
|
183
|
+
items,
|
|
184
|
+
totalRows: items.length
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/tools/consent_get_analytics_data.ts
|
|
191
|
+
const GetAnalyticsDataSchema = z.object({
|
|
192
|
+
data_source: z.nativeEnum(ConsentManagerAnalyticsDataSource).describe("analyticsData source: PRIVACY_SIGNAL_TIMESERIES (DNT/GPC), CONSENT_CHANGES_TIMESERIES (opt-in/out), or CONSENT_SESSIONS_BY_REGIME."),
|
|
193
|
+
start: z.string().optional().describe("Start datetime (ISO 8601). Defaults to `days` lookback from end."),
|
|
194
|
+
end: z.string().optional().describe("End datetime (ISO 8601). Defaults to now."),
|
|
195
|
+
days: z.coerce.number().min(1).max(365).optional().describe("Lookback window in days when start is omitted (default: 7)."),
|
|
196
|
+
bin: z.nativeEnum(ConsentManagerMetricBin).optional().default(ConsentManagerMetricBin.Daily).describe("Time bin size for analyticsData (1h or 1d, default: 1d).")
|
|
197
|
+
});
|
|
198
|
+
function createConsentGetAnalyticsDataTool(clients) {
|
|
199
|
+
return defineTool({
|
|
200
|
+
name: "consent_get_analytics_data",
|
|
201
|
+
description: "Query consent metrics via the analyticsData GraphQL query. Returns timeseries for privacy signals (DNT/GPC), consent changes (opt-in/out), or sessions by regime. Requires ViewConsentManager API key scope.",
|
|
202
|
+
category: "Consent Management",
|
|
203
|
+
readOnly: true,
|
|
204
|
+
annotations: {
|
|
205
|
+
readOnlyHint: true,
|
|
206
|
+
destructiveHint: false,
|
|
207
|
+
idempotentHint: true
|
|
208
|
+
},
|
|
209
|
+
zodSchema: GetAnalyticsDataSchema,
|
|
210
|
+
handler: async ({ data_source, start, end, days, bin }) => {
|
|
211
|
+
const airgapBundleId = await resolveAirgapBundleId(clients.graphql);
|
|
212
|
+
const range = resolveAnalyticsDateRange({
|
|
213
|
+
start,
|
|
214
|
+
end,
|
|
215
|
+
days
|
|
216
|
+
});
|
|
217
|
+
const series = (await clients.graphql.makeRequest(CONSENT_MANAGER_ANALYTICS_DATA, { input: {
|
|
218
|
+
dataSource: data_source,
|
|
219
|
+
startDate: range.startIso,
|
|
220
|
+
endDate: range.endIso,
|
|
221
|
+
forceRefetch: true,
|
|
222
|
+
airgapBundleId,
|
|
223
|
+
binInterval: bin,
|
|
224
|
+
smoothTimeseries: false
|
|
225
|
+
} })).analyticsData.series;
|
|
226
|
+
return createToolResult(true, {
|
|
227
|
+
airgapBundleId,
|
|
228
|
+
dataSource: data_source,
|
|
229
|
+
binInterval: bin,
|
|
230
|
+
period: {
|
|
231
|
+
start: range.startIso,
|
|
232
|
+
end: range.endIso
|
|
233
|
+
},
|
|
234
|
+
series
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
//#endregion
|
|
240
|
+
//#region src/tools/consent_get_inventory_stats.ts
|
|
241
|
+
const GetInventoryStatsSchema = z.object({});
|
|
242
|
+
function createConsentGetInventoryStatsTool(clients) {
|
|
243
|
+
return defineTool({
|
|
244
|
+
name: "consent_get_inventory_stats",
|
|
245
|
+
description: "Get cookie and data-flow inventory triage counts: live (approved), needs review, and junk. This is inventory status, not consent analytics — use consent_get_aggregate_analytics or consent_get_timeseries_analytics for opt-in/out and signal metrics.",
|
|
246
|
+
category: "Consent Management",
|
|
247
|
+
readOnly: true,
|
|
248
|
+
annotations: {
|
|
249
|
+
readOnlyHint: true,
|
|
250
|
+
destructiveHint: false,
|
|
251
|
+
idempotentHint: true
|
|
252
|
+
},
|
|
253
|
+
zodSchema: GetInventoryStatsSchema,
|
|
254
|
+
handler: async () => {
|
|
255
|
+
const variables = { input: { airgapBundleId: await resolveAirgapBundleId(clients.graphql) } };
|
|
256
|
+
const [cookieData, dfData] = await Promise.all([clients.graphql.makeRequest(COOKIE_STATS, variables), clients.graphql.makeRequest(DATA_FLOW_STATS, variables)]);
|
|
257
|
+
return createToolResult(true, {
|
|
258
|
+
cookies: cookieData.cookieStats,
|
|
259
|
+
dataFlows: dfData.dataFlowStats
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
//#endregion
|
|
102
265
|
//#region src/tools/consent_get_preferences.ts
|
|
103
266
|
const GetPreferencesSchema = z.object({
|
|
104
267
|
identifier: z.string().describe("User identifier (e.g., email, user ID)"),
|
|
@@ -131,12 +294,18 @@ function createConsentGetPreferencesTool(clients) {
|
|
|
131
294
|
});
|
|
132
295
|
}
|
|
133
296
|
//#endregion
|
|
134
|
-
//#region src/tools/
|
|
135
|
-
const
|
|
136
|
-
|
|
297
|
+
//#region src/tools/consent_get_timeseries_analytics.ts
|
|
298
|
+
const GetTimeseriesAnalyticsSchema = z.object({
|
|
299
|
+
metric: airgapBundleAnalyticsMetricSchema.describe("Analytics metric to query. PAGE_VIEWS for daily page-view volume; SITE_SESSIONS for sessions; SIGNAL_DETECTED for GPC/DNT signal counts over time."),
|
|
300
|
+
start: z.string().optional().describe("Start datetime (ISO 8601). Defaults to `days` lookback from end."),
|
|
301
|
+
end: z.string().optional().describe("End datetime (ISO 8601). Defaults to now."),
|
|
302
|
+
days: z.coerce.number().min(1).max(365).optional().describe("Lookback window in days when start is omitted (default: 7)."),
|
|
303
|
+
bin_interval: z.nativeEnum(AirgapBundleAnalyticsBinInterval).optional().default(AirgapBundleAnalyticsBinInterval.Hourly).describe("Time bin size: 1m, 1h, or 1d (default: 1h).")
|
|
304
|
+
});
|
|
305
|
+
function createConsentGetTimeseriesAnalyticsTool(clients) {
|
|
137
306
|
return defineTool({
|
|
138
|
-
name: "
|
|
139
|
-
description: "
|
|
307
|
+
name: "consent_get_timeseries_analytics",
|
|
308
|
+
description: "Query timeseries consent analytics via airgapBundleTimeseriesAnalytics. Use PAGE_VIEWS or SITE_SESSIONS for traffic volume; SIGNAL_DETECTED for privacy signal counts. Requires ViewConsentManager API key scope.",
|
|
140
309
|
category: "Consent Management",
|
|
141
310
|
readOnly: true,
|
|
142
311
|
annotations: {
|
|
@@ -144,13 +313,35 @@ function createConsentGetTriageStatsTool(clients) {
|
|
|
144
313
|
destructiveHint: false,
|
|
145
314
|
idempotentHint: true
|
|
146
315
|
},
|
|
147
|
-
zodSchema:
|
|
148
|
-
handler: async () => {
|
|
149
|
-
const
|
|
150
|
-
const
|
|
316
|
+
zodSchema: GetTimeseriesAnalyticsSchema,
|
|
317
|
+
handler: async ({ metric, start, end, days, bin_interval }) => {
|
|
318
|
+
const airgapBundleId = await resolveAirgapBundleId(clients.graphql);
|
|
319
|
+
const range = resolveAnalyticsDateRange({
|
|
320
|
+
start,
|
|
321
|
+
end,
|
|
322
|
+
days
|
|
323
|
+
});
|
|
324
|
+
const items = (await clients.graphql.makeRequest(AIRGAP_BUNDLE_TIMESERIES_ANALYTICS, {
|
|
325
|
+
id: airgapBundleId,
|
|
326
|
+
input: {
|
|
327
|
+
metric,
|
|
328
|
+
start: range.startEpoch,
|
|
329
|
+
end: range.endEpoch,
|
|
330
|
+
binInterval: bin_interval
|
|
331
|
+
}
|
|
332
|
+
})).airgapBundleTimeseriesAnalytics.items;
|
|
151
333
|
return createToolResult(true, {
|
|
152
|
-
|
|
153
|
-
|
|
334
|
+
airgapBundleId,
|
|
335
|
+
metric,
|
|
336
|
+
binInterval: bin_interval,
|
|
337
|
+
period: {
|
|
338
|
+
start: range.startIso,
|
|
339
|
+
end: range.endIso,
|
|
340
|
+
startEpoch: range.startEpoch,
|
|
341
|
+
endEpoch: range.endEpoch
|
|
342
|
+
},
|
|
343
|
+
items,
|
|
344
|
+
totalRows: items.length
|
|
154
345
|
});
|
|
155
346
|
}
|
|
156
347
|
});
|
|
@@ -485,13 +676,16 @@ function getConsentTools(clients) {
|
|
|
485
676
|
createConsentListCookiesTool(clients),
|
|
486
677
|
createConsentListAirgapBundlesTool(clients),
|
|
487
678
|
createConsentListRegimesTool(clients),
|
|
488
|
-
|
|
679
|
+
createConsentGetInventoryStatsTool(clients),
|
|
680
|
+
createConsentGetAggregateAnalyticsTool(clients),
|
|
681
|
+
createConsentGetTimeseriesAnalyticsTool(clients),
|
|
682
|
+
createConsentGetAnalyticsDataTool(clients),
|
|
489
683
|
createConsentUpdateCookiesTool(clients),
|
|
490
684
|
createConsentUpdateDataFlowsTool(clients),
|
|
491
685
|
createConsentBulkTriageTool(clients)
|
|
492
686
|
];
|
|
493
687
|
}
|
|
494
688
|
//#endregion
|
|
495
|
-
export {
|
|
689
|
+
export { GetAggregateAnalyticsSchema as _, UpdateCookiesSchema as a, BulkTriageSchema as b, ListRegimesSchema as c, ListCookiesSchema as d, ListAirgapBundlesSchema as f, GetAnalyticsDataSchema as g, GetInventoryStatsSchema as h, UpdateCookieItemSchema as i, ListPurposesSchema as l, GetPreferencesSchema as m, UpdateDataFlowItemSchema as n, PurposeConsentSchema as o, GetTimeseriesAnalyticsSchema as p, UpdateDataFlowsSchema as r, SetPreferencesSchema as s, getConsentTools as t, ListDataFlowsSchema as u, resolveAnalyticsDateRange as v, resolveAirgapBundleId as x, BulkTriageItemSchema as y };
|
|
496
690
|
|
|
497
|
-
//# sourceMappingURL=tools-
|
|
691
|
+
//# sourceMappingURL=tools-bVmFBYcw.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools-bVmFBYcw.mjs","names":[],"sources":["../src/resolveAirgapBundleId.ts","../src/tools/consent_bulk_triage.ts","../src/analyticsDateRange.ts","../src/normalizeAnalyticsMetric.ts","../src/tools/consent_get_aggregate_analytics.ts","../src/tools/consent_get_analytics_data.ts","../src/tools/consent_get_inventory_stats.ts","../src/tools/consent_get_preferences.ts","../src/tools/consent_get_timeseries_analytics.ts","../src/tools/consent_list_airgap_bundles.ts","../src/tools/consent_list_cookies.ts","../src/tools/consent_list_data_flows.ts","../src/tools/consent_list_purposes.ts","../src/tools/consent_list_regimes.ts","../src/tools/consent_set_preferences.ts","../src/tools/consent_update_cookies.ts","../src/tools/consent_update_data_flows.ts","../src/tools/index.ts"],"sourcesContent":["import type { TranscendGraphQLBase } from '@transcend-io/mcp-server-base';\nimport {\n FETCH_CONSENT_MANAGER_ID,\n type TranscendCliFetchConsentManagerIdResponse,\n} from '@transcend-io/sdk';\n\nconst bundleIdCache = new WeakMap<TranscendGraphQLBase, string>();\n\n/**\n * Lazily resolve the airgap bundle ID from the API key.\n * Caches the result per GraphQL client instance so subsequent\n * calls return instantly without an extra network request.\n */\nexport async function resolveAirgapBundleId(graphql: TranscendGraphQLBase): Promise<string> {\n const cached = bundleIdCache.get(graphql);\n if (cached) return cached;\n\n const data = await graphql.makeRequest<TranscendCliFetchConsentManagerIdResponse>(\n FETCH_CONSENT_MANAGER_ID,\n {},\n );\n\n const id = data.consentManager.consentManager.id;\n bundleIdCache.set(graphql, id);\n return id;\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport {\n ConsentTrackerStatus,\n ConsentTrackerType,\n TriageAction,\n} from '@transcend-io/privacy-types';\nimport {\n UPDATE_OR_CREATE_COOKIES,\n UPDATE_DATA_FLOWS,\n type TranscendUpdateCookieInputGql,\n type TranscendUpdateDataFlowInputGql,\n type TranscendCliUpdateOrCreateCookiesResponse,\n type TranscendCliUpdateDataFlowsResponse,\n} from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const BulkTriageItemSchema = z.object({\n type: z.nativeEnum(ConsentTrackerType).describe('Item type'),\n id: z.string().describe('Item ID (for data flows) or cookie name (for cookies)'),\n action: z.nativeEnum(TriageAction).describe('Action to take: APPROVE or JUNK'),\n tracking_purposes: z\n .array(z.string())\n .optional()\n .describe('Tracking purposes to assign (required when approving)'),\n service: z.string().optional().describe('Service name to assign'),\n});\nexport type BulkTriageItemInput = z.infer<typeof BulkTriageItemSchema>;\n\nexport const BulkTriageSchema = z.object({\n items: z.array(BulkTriageItemSchema).min(1).describe('Items to triage'),\n});\nexport type BulkTriageInput = z.infer<typeof BulkTriageSchema>;\n\nexport function createConsentBulkTriageTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_bulk_triage',\n description:\n 'Bulk triage action: approve or junk multiple cookies and data flows in a single call. ' +\n 'For cookies, APPROVE sets status=LIVE; JUNK sets isJunk=true. ' +\n 'For data flows, same behavior. Optionally assign tracking purposes and service when approving.',\n category: 'Consent Management',\n readOnly: false,\n confirmationHint: 'Bulk approves or junks cookies and data flows',\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },\n zodSchema: BulkTriageSchema,\n handler: async ({ items }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const cookieItems = items.filter((i) => i.type === 'cookie');\n const dfItems = items.filter((i) => i.type === 'data_flow');\n\n const results: {\n /** Updated cookies */\n cookies: { name: string; action: string; status: string }[];\n /** Updated data flows */\n dataFlows: { id: string; action: string; status: string }[];\n } = { cookies: [], dataFlows: [] };\n\n if (cookieItems.length > 0) {\n const cookieInputs: TranscendUpdateCookieInputGql[] = cookieItems.map((item) => ({\n name: item.id,\n ...(item.action === 'APPROVE'\n ? { status: ConsentTrackerStatus.Live, isJunk: false }\n : { status: ConsentTrackerStatus.Live, isJunk: true }),\n ...(item.tracking_purposes ? { trackingPurposes: item.tracking_purposes } : {}),\n ...(item.service ? { service: item.service } : {}),\n }));\n await clients.graphql.makeRequest<TranscendCliUpdateOrCreateCookiesResponse>(\n UPDATE_OR_CREATE_COOKIES,\n {\n airgapBundleId,\n cookies: cookieInputs,\n },\n );\n results.cookies = cookieInputs.map((c) => ({\n name: c.name,\n action: c.isJunk ? 'JUNKED' : 'APPROVED',\n status: c.status || 'LIVE',\n }));\n }\n\n if (dfItems.length > 0) {\n const dfInputs: TranscendUpdateDataFlowInputGql[] = dfItems.map((item) => ({\n id: item.id,\n ...(item.action === 'APPROVE'\n ? { status: ConsentTrackerStatus.Live, isJunk: false }\n : { status: ConsentTrackerStatus.Live, isJunk: true }),\n ...(item.tracking_purposes ? { purposeIds: item.tracking_purposes } : {}),\n ...(item.service ? { service: item.service } : {}),\n }));\n const dfResult = await clients.graphql.makeRequest<TranscendCliUpdateDataFlowsResponse>(\n UPDATE_DATA_FLOWS,\n {\n airgapBundleId,\n dataFlows: dfInputs,\n },\n );\n results.dataFlows = dfResult.updateDataFlows.dataFlows.map((df) => ({\n id: df.id,\n action: df.isJunk ? 'JUNKED' : 'APPROVED',\n status: df.status,\n }));\n }\n\n return createToolResult(true, {\n totalProcessed: cookieItems.length + dfItems.length,\n ...results,\n });\n },\n });\n}\n","export interface ResolvedAnalyticsDateRange {\n /** Start time as epoch seconds */\n startEpoch: number;\n /** End time as epoch seconds */\n endEpoch: number;\n /** Start time as ISO string (for legacy analyticsData API) */\n startIso: string;\n /** End time as ISO string (for legacy analyticsData API) */\n endIso: string;\n}\n\n/**\n * Resolve a date range from explicit ISO timestamps or a lookback window.\n */\nexport function resolveAnalyticsDateRange(args: {\n /** Explicit start datetime (ISO 8601) */\n start?: string;\n /** Explicit end datetime (ISO 8601) */\n end?: string;\n /** Lookback window in days when start is omitted (default 7) */\n days?: number;\n}): ResolvedAnalyticsDateRange {\n const endDate = args.end ? new Date(args.end) : new Date();\n const lookbackDays = args.days ?? 7;\n const startDate = args.start\n ? new Date(args.start)\n : new Date(endDate.getTime() - lookbackDays * 24 * 60 * 60 * 1000);\n\n if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) {\n throw new Error('Invalid start or end date');\n }\n if (startDate > endDate) {\n throw new Error('Start date must be before end date');\n }\n\n return {\n startEpoch: Math.floor(startDate.getTime() / 1000),\n endEpoch: Math.floor(endDate.getTime() / 1000),\n startIso: startDate.toISOString(),\n endIso: endDate.toISOString(),\n };\n}\n","import { z } from '@transcend-io/mcp-server-base';\nimport { AirgapBundleAnalyticsMetric } from '@transcend-io/privacy-types';\n\nconst VALID_METRICS = new Set<string>(Object.values(AirgapBundleAnalyticsMetric));\n\n/** Common agent/API guesses mapped to GraphQL AnalyticsEvent values */\nconst ANALYTICS_METRIC_ALIASES: Record<string, AirgapBundleAnalyticsMetric> = {\n PAGE_VIEW: AirgapBundleAnalyticsMetric.PageViews,\n CONSENT_SESSION: AirgapBundleAnalyticsMetric.SiteSessions,\n CONSENT_SESSIONS: AirgapBundleAnalyticsMetric.SiteSessions,\n};\n\n/**\n * Normalize metric input, accepting common aliases (e.g. PAGE_VIEW → PAGE_VIEWS).\n */\nexport function normalizeAnalyticsMetric(metric: string): AirgapBundleAnalyticsMetric | string {\n const upper = metric.toUpperCase();\n if (VALID_METRICS.has(upper)) {\n return upper as AirgapBundleAnalyticsMetric;\n }\n return ANALYTICS_METRIC_ALIASES[upper] ?? upper;\n}\n\nexport const airgapBundleAnalyticsMetricSchema = z.preprocess(\n (value) => (typeof value === 'string' ? normalizeAnalyticsMetric(value) : value),\n z.nativeEnum(AirgapBundleAnalyticsMetric),\n);\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport {\n AirgapBundleAnalyticsDimension,\n AirgapBundleAnalyticsMetric,\n} from '@transcend-io/privacy-types';\nimport {\n AIRGAP_BUNDLE_AGGREGATE_ANALYTICS,\n type TranscendCliAirgapBundleAggregateAnalyticsResponse,\n} from '@transcend-io/sdk';\n\nimport { resolveAnalyticsDateRange } from '../analyticsDateRange.js';\nimport { airgapBundleAnalyticsMetricSchema } from '../normalizeAnalyticsMetric.js';\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const GetAggregateAnalyticsSchema = z.object({\n metric: airgapBundleAnalyticsMetricSchema.describe(\n 'Analytics metric to query. CONSENT_CHANGED for opt-in/out counts; SITE_SESSIONS or PAGE_VIEWS for traffic totals.',\n ),\n start: z\n .string()\n .optional()\n .describe('Start datetime (ISO 8601). Defaults to `days` lookback from end.'),\n end: z.string().optional().describe('End datetime (ISO 8601). Defaults to now.'),\n days: z.coerce\n .number()\n .min(1)\n .max(365)\n .optional()\n .describe('Lookback window in days when start is omitted (default: 7).'),\n include_dimensions: z\n .array(z.nativeEnum(AirgapBundleAnalyticsDimension))\n .optional()\n .describe(\n 'Dimension breakdowns (e.g. NEW_VALUE, REGIME, PURPOSE). Recommended for CONSENT_CHANGED.',\n ),\n});\nexport type GetAggregateAnalyticsInput = z.infer<typeof GetAggregateAnalyticsSchema>;\n\nexport function createConsentGetAggregateAnalyticsTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_get_aggregate_analytics',\n description:\n 'Query aggregate consent analytics via airgapBundleAggregateAnalytics. ' +\n 'Use CONSENT_CHANGED with NEW_VALUE/REGIME/PURPOSE for opt-in/out counts; ' +\n 'SITE_SESSIONS or PAGE_VIEWS for total traffic. Requires ViewConsentManager API key scope.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: GetAggregateAnalyticsSchema,\n handler: async ({ metric, start, end, days, include_dimensions }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const range = resolveAnalyticsDateRange({ start, end, days });\n const data =\n await clients.graphql.makeRequest<TranscendCliAirgapBundleAggregateAnalyticsResponse>(\n AIRGAP_BUNDLE_AGGREGATE_ANALYTICS,\n {\n id: airgapBundleId,\n input: {\n metric,\n start: range.startEpoch,\n end: range.endEpoch,\n ...(include_dimensions?.length ? { includeDimensions: include_dimensions } : {}),\n },\n },\n );\n const items = data.airgapBundleAggregateAnalytics.items;\n\n return createToolResult(true, {\n airgapBundleId,\n metric,\n period: {\n start: range.startIso,\n end: range.endIso,\n startEpoch: range.startEpoch,\n endEpoch: range.endEpoch,\n },\n items,\n totalRows: items.length,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport {\n ConsentManagerAnalyticsDataSource,\n ConsentManagerMetricBin,\n} from '@transcend-io/privacy-types';\nimport { CONSENT_MANAGER_ANALYTICS_DATA, type ConsentManagerMetric } from '@transcend-io/sdk';\n\nimport { resolveAnalyticsDateRange } from '../analyticsDateRange.js';\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const GetAnalyticsDataSchema = z.object({\n data_source: z\n .nativeEnum(ConsentManagerAnalyticsDataSource)\n .describe(\n 'analyticsData source: PRIVACY_SIGNAL_TIMESERIES (DNT/GPC), ' +\n 'CONSENT_CHANGES_TIMESERIES (opt-in/out), or CONSENT_SESSIONS_BY_REGIME.',\n ),\n start: z\n .string()\n .optional()\n .describe('Start datetime (ISO 8601). Defaults to `days` lookback from end.'),\n end: z.string().optional().describe('End datetime (ISO 8601). Defaults to now.'),\n days: z.coerce\n .number()\n .min(1)\n .max(365)\n .optional()\n .describe('Lookback window in days when start is omitted (default: 7).'),\n bin: z\n .nativeEnum(ConsentManagerMetricBin)\n .optional()\n .default(ConsentManagerMetricBin.Daily)\n .describe('Time bin size for analyticsData (1h or 1d, default: 1d).'),\n});\nexport type GetAnalyticsDataInput = z.infer<typeof GetAnalyticsDataSchema>;\n\nexport function createConsentGetAnalyticsDataTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_get_analytics_data',\n description:\n 'Query consent metrics via the analyticsData GraphQL query. ' +\n 'Returns timeseries for privacy signals (DNT/GPC), consent changes (opt-in/out), ' +\n 'or sessions by regime. Requires ViewConsentManager API key scope.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: GetAnalyticsDataSchema,\n handler: async ({ data_source, start, end, days, bin }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const range = resolveAnalyticsDateRange({ start, end, days });\n const data = await clients.graphql.makeRequest<{\n analyticsData: { series: ConsentManagerMetric[] };\n }>(CONSENT_MANAGER_ANALYTICS_DATA, {\n input: {\n dataSource: data_source,\n startDate: range.startIso,\n endDate: range.endIso,\n forceRefetch: true,\n airgapBundleId,\n binInterval: bin,\n smoothTimeseries: false,\n },\n });\n const series = data.analyticsData.series;\n\n return createToolResult(true, {\n airgapBundleId,\n dataSource: data_source,\n binInterval: bin,\n period: {\n start: range.startIso,\n end: range.endIso,\n },\n series,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport {\n COOKIE_STATS,\n DATA_FLOW_STATS,\n type TranscendCliCookieStatsResponse,\n type TranscendCliDataFlowStatsResponse,\n} from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const GetInventoryStatsSchema = z.object({});\nexport type GetInventoryStatsInput = z.infer<typeof GetInventoryStatsSchema>;\n\nexport function createConsentGetInventoryStatsTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_get_inventory_stats',\n description:\n 'Get cookie and data-flow inventory triage counts: live (approved), needs review, and junk. ' +\n 'This is inventory status, not consent analytics — use consent_get_aggregate_analytics or ' +\n 'consent_get_timeseries_analytics for opt-in/out and signal metrics.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: GetInventoryStatsSchema,\n handler: async () => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const variables = { input: { airgapBundleId } };\n const [cookieData, dfData] = await Promise.all([\n clients.graphql.makeRequest<TranscendCliCookieStatsResponse>(COOKIE_STATS, variables),\n clients.graphql.makeRequest<TranscendCliDataFlowStatsResponse>(DATA_FLOW_STATS, variables),\n ]);\n return createToolResult(true, {\n cookies: cookieData.cookieStats,\n dataFlows: dfData.dataFlowStats,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nexport const GetPreferencesSchema = z.object({\n identifier: z.string().describe('User identifier (e.g., email, user ID)'),\n partition: z.string().optional().describe('Partition/organization context (optional)'),\n});\nexport type GetPreferencesInput = z.infer<typeof GetPreferencesSchema>;\n\nexport function createConsentGetPreferencesTool(clients: ToolClients) {\n const { rest } = clients;\n return defineTool({\n name: 'consent_get_preferences',\n description: 'Get consent preferences for a specific user/identifier',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: GetPreferencesSchema,\n handler: async ({ identifier, partition }) => {\n const result = await rest.getConsentPreferences(identifier, partition);\n if (!result) {\n return createToolResult(true, {\n found: false,\n message: 'No consent preferences found for this identifier',\n });\n }\n return createToolResult(true, {\n found: true,\n preferences: result,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport {\n AirgapBundleAnalyticsBinInterval,\n AirgapBundleAnalyticsMetric,\n} from '@transcend-io/privacy-types';\nimport {\n AIRGAP_BUNDLE_TIMESERIES_ANALYTICS,\n type TranscendCliAirgapBundleTimeseriesAnalyticsResponse,\n} from '@transcend-io/sdk';\n\nimport { resolveAnalyticsDateRange } from '../analyticsDateRange.js';\nimport { airgapBundleAnalyticsMetricSchema } from '../normalizeAnalyticsMetric.js';\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const GetTimeseriesAnalyticsSchema = z.object({\n metric: airgapBundleAnalyticsMetricSchema.describe(\n 'Analytics metric to query. PAGE_VIEWS for daily page-view volume; SITE_SESSIONS for sessions; ' +\n 'SIGNAL_DETECTED for GPC/DNT signal counts over time.',\n ),\n start: z\n .string()\n .optional()\n .describe('Start datetime (ISO 8601). Defaults to `days` lookback from end.'),\n end: z.string().optional().describe('End datetime (ISO 8601). Defaults to now.'),\n days: z.coerce\n .number()\n .min(1)\n .max(365)\n .optional()\n .describe('Lookback window in days when start is omitted (default: 7).'),\n bin_interval: z\n .nativeEnum(AirgapBundleAnalyticsBinInterval)\n .optional()\n .default(AirgapBundleAnalyticsBinInterval.Hourly)\n .describe('Time bin size: 1m, 1h, or 1d (default: 1h).'),\n});\nexport type GetTimeseriesAnalyticsInput = z.infer<typeof GetTimeseriesAnalyticsSchema>;\n\nexport function createConsentGetTimeseriesAnalyticsTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_get_timeseries_analytics',\n description:\n 'Query timeseries consent analytics via airgapBundleTimeseriesAnalytics. ' +\n 'Use PAGE_VIEWS or SITE_SESSIONS for traffic volume; SIGNAL_DETECTED for privacy signal counts. ' +\n 'Requires ViewConsentManager API key scope.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: GetTimeseriesAnalyticsSchema,\n handler: async ({ metric, start, end, days, bin_interval }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const range = resolveAnalyticsDateRange({ start, end, days });\n const data =\n await clients.graphql.makeRequest<TranscendCliAirgapBundleTimeseriesAnalyticsResponse>(\n AIRGAP_BUNDLE_TIMESERIES_ANALYTICS,\n {\n id: airgapBundleId,\n input: {\n metric,\n start: range.startEpoch,\n end: range.endEpoch,\n binInterval: bin_interval,\n },\n },\n );\n const items = data.airgapBundleTimeseriesAnalytics.items;\n\n return createToolResult(true, {\n airgapBundleId,\n metric,\n binInterval: bin_interval,\n period: {\n start: range.startIso,\n end: range.endIso,\n startEpoch: range.startEpoch,\n endEpoch: range.endEpoch,\n },\n items,\n totalRows: items.length,\n });\n },\n });\n}\n","import {\n createToolResult,\n defineTool,\n EmptySchema,\n type ToolClients,\n} from '@transcend-io/mcp-server-base';\nimport {\n FETCH_CONSENT_MANAGER,\n type TranscendCliFetchConsentManagerResponse,\n} from '@transcend-io/sdk';\n\nexport const ListAirgapBundlesSchema = EmptySchema;\nexport type ListAirgapBundlesInput = Record<string, never>;\n\nexport function createConsentListAirgapBundlesTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_list_airgap_bundles',\n description:\n 'Get the consent manager (airgap bundle) configured for your organization. ' +\n 'Returns the bundle ID, URLs, configuration, and domains.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListAirgapBundlesSchema,\n handler: async (_args) => {\n const data = await clients.graphql.makeRequest<TranscendCliFetchConsentManagerResponse>(\n FETCH_CONSENT_MANAGER,\n {},\n );\n return createToolResult(true, data.consentManager.consentManager);\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport {\n ConsentTrackerStatus,\n CookieOrderField,\n OrderDirection,\n} from '@transcend-io/privacy-types';\nimport { COOKIES, type TranscendCliCookiesResponse } from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const ListCookiesSchema = z.object({\n limit: z.number().min(1).max(200).optional().default(50),\n offset: z.number().min(0).optional().default(0),\n status: z\n .nativeEnum(ConsentTrackerStatus)\n .describe('Filter by status: NEEDS_REVIEW (triage) or LIVE (approved)'),\n is_junk: z.boolean().optional().describe('Filter by junk status'),\n show_zero_activity: z.boolean().optional().describe('Include items with zero activity'),\n text: z.string().optional().describe('Search text filter'),\n service: z.string().optional().describe('Filter by service name'),\n order_field: z.nativeEnum(CookieOrderField).optional().describe('Field to sort by'),\n order_direction: z.nativeEnum(OrderDirection).optional().describe('Sort direction: ASC or DESC'),\n});\nexport type ListCookiesInput = z.infer<typeof ListCookiesSchema>;\n\nexport function createConsentListCookiesTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_list_cookies',\n description:\n 'List cookies in your consent manager. ' +\n 'Requires a status filter: NEEDS_REVIEW for triage backlog, LIVE for approved cookies. ' +\n 'Returns name, service, tracking purposes, activity (occurrences), junk status, and more.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListCookiesSchema,\n handler: async ({\n limit,\n offset,\n status,\n is_junk,\n show_zero_activity,\n text,\n service,\n order_field,\n order_direction,\n }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const data = await clients.graphql.makeRequest<TranscendCliCookiesResponse>(COOKIES, {\n input: { airgapBundleId },\n first: limit,\n offset,\n filterBy: {\n status,\n ...(is_junk !== undefined ? { isJunk: is_junk } : {}),\n ...(show_zero_activity !== undefined ? { showZeroActivity: show_zero_activity } : {}),\n ...(text ? { text } : {}),\n ...(service ? { service } : {}),\n },\n ...(order_field && order_direction\n ? { orderBy: [{ field: order_field, direction: order_direction }] }\n : {}),\n });\n const { nodes, totalCount } = data.cookies;\n return createListResult(nodes, {\n totalCount,\n hasNextPage: offset + nodes.length < totalCount,\n });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport {\n ConsentTrackerStatus,\n DataFlowOrderField,\n OrderDirection,\n} from '@transcend-io/privacy-types';\nimport { DATA_FLOWS, type TranscendCliDataFlowsResponse } from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const ListDataFlowsSchema = z.object({\n limit: z.number().min(1).max(200).optional().default(50),\n offset: z.number().min(0).optional().default(0),\n status: z\n .nativeEnum(ConsentTrackerStatus)\n .describe('Filter by status: NEEDS_REVIEW (triage) or LIVE (approved)'),\n is_junk: z.boolean().optional().describe('Filter by junk status'),\n show_zero_activity: z.boolean().optional().describe('Include items with zero activity'),\n text: z.string().optional().describe('Search text filter'),\n service: z.string().optional().describe('Filter by service name'),\n order_field: z.nativeEnum(DataFlowOrderField).optional().describe('Field to sort by'),\n order_direction: z.nativeEnum(OrderDirection).optional().describe('Sort direction: ASC or DESC'),\n});\nexport type ListDataFlowsInput = z.infer<typeof ListDataFlowsSchema>;\n\nexport function createConsentListDataFlowsTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_list_data_flows',\n description:\n 'List data flows (network requests) in your consent manager. ' +\n 'Requires a status filter: NEEDS_REVIEW for triage backlog, LIVE for approved flows. ' +\n 'Returns value (URL/host), service, tracking purposes, activity (occurrences), and more.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListDataFlowsSchema,\n handler: async ({\n limit,\n offset,\n status,\n is_junk,\n show_zero_activity,\n text,\n service,\n order_field,\n order_direction,\n }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const data = await clients.graphql.makeRequest<TranscendCliDataFlowsResponse>(DATA_FLOWS, {\n input: { airgapBundleId },\n first: limit,\n offset,\n filterBy: {\n status,\n ...(is_junk !== undefined ? { isJunk: is_junk } : {}),\n ...(show_zero_activity !== undefined ? { showZeroActivity: show_zero_activity } : {}),\n ...(text ? { text } : {}),\n ...(service ? { service } : {}),\n },\n ...(order_field && order_direction\n ? { orderBy: [{ field: order_field, direction: order_direction }] }\n : {}),\n });\n const { nodes, totalCount } = data.dataFlows;\n return createListResult(nodes, {\n totalCount,\n hasNextPage: offset + nodes.length < totalCount,\n });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport { PURPOSES, type TranscendCliPurposesResponse } from '@transcend-io/sdk';\n\nexport const ListPurposesSchema = z.object({\n limit: z.coerce.number().min(1).max(100).optional().default(50),\n});\nexport type ListPurposesInput = z.infer<typeof ListPurposesSchema>;\n\nexport function createConsentListPurposesTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_list_purposes',\n description: 'List all tracking purposes configured for consent management (max ~100 results).',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListPurposesSchema,\n handler: async ({ limit }) => {\n const data = await clients.graphql.makeRequest<TranscendCliPurposesResponse>(PURPOSES, {\n first: Math.min(limit, 100),\n });\n const { nodes, totalCount } = data.purposes;\n return createListResult(nodes, {\n totalCount,\n hasNextPage: nodes.length < totalCount,\n });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport { EXPERIENCES, type TranscendCliExperiencesResponse } from '@transcend-io/sdk';\n\nexport const ListRegimesSchema = z.object({\n limit: z.coerce.number().min(1).max(100).optional().default(50),\n offset: z.coerce.number().min(0).optional().default(0),\n});\nexport type ListRegimesInput = z.infer<typeof ListRegimesSchema>;\n\nexport function createConsentListRegimesTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_list_regimes',\n description:\n 'List all consent experiences (regional regimes) configured for your organization. ' +\n 'Returns experience name, regions, purposes, opted-out purposes, and view state.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListRegimesSchema,\n handler: async ({ limit, offset }) => {\n const data = await clients.graphql.makeRequest<TranscendCliExperiencesResponse>(EXPERIENCES, {\n first: limit,\n offset,\n });\n const { totalCount, nodes } = data.experiences;\n return createListResult(nodes, {\n totalCount,\n hasNextPage: offset + nodes.length < totalCount,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nexport const PurposeConsentSchema = z.object({\n purpose: z.string().describe('Purpose slug'),\n enabled: z.boolean().describe('Whether consent is granted'),\n});\nexport type PurposeConsentInput = z.infer<typeof PurposeConsentSchema>;\n\nexport const SetPreferencesSchema = z.object({\n identifier: z.string().optional().describe('User identifier'),\n partition: z.string().describe('Partition/organization context'),\n purposes: z.array(PurposeConsentSchema).describe('Array of purpose consent settings'),\n confirmed: z.boolean().optional().describe('Whether consent was explicitly confirmed'),\n});\nexport type SetPreferencesInput = z.infer<typeof SetPreferencesSchema>;\n\nexport function createConsentSetPreferencesTool(clients: ToolClients) {\n const { rest } = clients;\n return defineTool({\n name: 'consent_set_preferences',\n description: 'Set consent preferences for a user (client-side sync)',\n category: 'Consent Management',\n readOnly: false,\n confirmationHint: 'Updates consent preferences for the user',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n zodSchema: SetPreferencesSchema,\n handler: async ({ partition, identifier, purposes, confirmed }) => {\n const result = await rest.syncConsent({\n partition,\n identifier,\n purposes: purposes.map((p) => ({\n purpose: p.purpose,\n enabled: p.enabled,\n })),\n confirmed,\n });\n return createToolResult(true, {\n ...result,\n message: 'Consent preferences synced successfully',\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport { ConsentTrackerStatus } from '@transcend-io/privacy-types';\nimport {\n UPDATE_OR_CREATE_COOKIES,\n type TranscendUpdateCookieInputGql,\n type TranscendCliUpdateOrCreateCookiesResponse,\n} from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const UpdateCookieItemSchema = z.object({\n name: z.string().describe('Cookie name (used as the identifier for upsert)'),\n tracking_purposes: z\n .array(z.string())\n .optional()\n .describe('Tracking purpose slugs (e.g., \"Advertising\", \"Analytics\")'),\n description: z.string().optional().describe('Cookie description'),\n service: z.string().optional().describe('Service/integration name'),\n is_junk: z.boolean().optional().describe('Mark as junk'),\n status: z\n .nativeEnum(ConsentTrackerStatus)\n .optional()\n .describe('Set status to LIVE (approve) or NEEDS_REVIEW'),\n});\nexport type UpdateCookieItemInput = z.infer<typeof UpdateCookieItemSchema>;\n\nexport const UpdateCookiesSchema = z.object({\n cookies: z.array(UpdateCookieItemSchema).min(1).describe('Cookies to update'),\n});\nexport type UpdateCookiesInput = z.infer<typeof UpdateCookiesSchema>;\n\nexport function createConsentUpdateCookiesTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_update_cookies',\n description:\n 'Update one or more cookies. Use to approve (status=LIVE), junk (is_junk=true), ' +\n 'assign tracking purposes, or set a service. The cookie \"name\" field is the identifier ' +\n 'for upsert — existing cookies with matching names will be updated.',\n category: 'Consent Management',\n readOnly: false,\n confirmationHint: 'Updates cookies in the consent manager',\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true },\n zodSchema: UpdateCookiesSchema,\n handler: async ({ cookies }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const cookieInputs: TranscendUpdateCookieInputGql[] = cookies.map((c) => ({\n name: c.name,\n ...(c.tracking_purposes ? { trackingPurposes: c.tracking_purposes } : {}),\n ...(c.description !== undefined ? { description: c.description } : {}),\n ...(c.service !== undefined ? { service: c.service } : {}),\n ...(c.is_junk !== undefined ? { isJunk: c.is_junk } : {}),\n ...(c.status !== undefined ? { status: c.status } : {}),\n }));\n await clients.graphql.makeRequest<TranscendCliUpdateOrCreateCookiesResponse>(\n UPDATE_OR_CREATE_COOKIES,\n {\n airgapBundleId,\n cookies: cookieInputs,\n },\n );\n return createToolResult(true, {\n updated: cookieInputs.length,\n cookies: cookieInputs.map((c) => ({\n name: c.name,\n status: c.status,\n isJunk: c.isJunk,\n trackingPurposes: c.trackingPurposes,\n service: c.service,\n })),\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport { ConsentTrackerStatus } from '@transcend-io/privacy-types';\nimport {\n UPDATE_DATA_FLOWS,\n type TranscendUpdateDataFlowInputGql,\n type TranscendCliUpdateDataFlowsResponse,\n} from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const UpdateDataFlowItemSchema = z.object({\n id: z.string().describe('Data flow ID'),\n tracking_purposes: z.array(z.string()).optional().describe('Tracking purpose slugs'),\n description: z.string().optional().describe('Data flow description'),\n service: z.string().optional().describe('Service/integration name'),\n is_junk: z.boolean().optional().describe('Mark as junk'),\n status: z\n .nativeEnum(ConsentTrackerStatus)\n .optional()\n .describe('Set status to LIVE (approve) or NEEDS_REVIEW'),\n});\nexport type UpdateDataFlowItemInput = z.infer<typeof UpdateDataFlowItemSchema>;\n\nexport const UpdateDataFlowsSchema = z.object({\n data_flows: z.array(UpdateDataFlowItemSchema).min(1).describe('Data flows to update'),\n});\nexport type UpdateDataFlowsInput = z.infer<typeof UpdateDataFlowsSchema>;\n\nexport function createConsentUpdateDataFlowsTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_update_data_flows',\n description:\n 'Update one or more data flows. Use to approve (status=LIVE), junk (is_junk=true), ' +\n 'assign tracking purposes, or set a service.',\n category: 'Consent Management',\n readOnly: false,\n confirmationHint: 'Updates data flows in the consent manager',\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true },\n zodSchema: UpdateDataFlowsSchema,\n handler: async ({ data_flows }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const dfInputs: TranscendUpdateDataFlowInputGql[] = data_flows.map((df) => ({\n id: df.id,\n ...(df.tracking_purposes ? { purposeIds: df.tracking_purposes } : {}),\n ...(df.description !== undefined ? { description: df.description } : {}),\n ...(df.service !== undefined ? { service: df.service } : {}),\n ...(df.is_junk !== undefined ? { isJunk: df.is_junk } : {}),\n ...(df.status !== undefined ? { status: df.status } : {}),\n }));\n const data = await clients.graphql.makeRequest<TranscendCliUpdateDataFlowsResponse>(\n UPDATE_DATA_FLOWS,\n {\n airgapBundleId,\n dataFlows: dfInputs,\n },\n );\n return createToolResult(true, {\n updated: data.updateDataFlows.dataFlows.length,\n dataFlows: data.updateDataFlows.dataFlows.map((df) => ({\n id: df.id,\n value: df.value,\n status: df.status,\n isJunk: df.isJunk,\n purposes: df.purposes.map((p) => p.name),\n service: df.service?.title,\n })),\n });\n },\n });\n}\n","import type { ToolDefinition, ToolClients } from '@transcend-io/mcp-server-base';\n\nimport { createConsentBulkTriageTool } from './consent_bulk_triage.js';\nimport { createConsentGetAggregateAnalyticsTool } from './consent_get_aggregate_analytics.js';\nimport { createConsentGetAnalyticsDataTool } from './consent_get_analytics_data.js';\nimport { createConsentGetInventoryStatsTool } from './consent_get_inventory_stats.js';\nimport { createConsentGetPreferencesTool } from './consent_get_preferences.js';\nimport { createConsentGetTimeseriesAnalyticsTool } from './consent_get_timeseries_analytics.js';\nimport { createConsentListAirgapBundlesTool } from './consent_list_airgap_bundles.js';\nimport { createConsentListCookiesTool } from './consent_list_cookies.js';\nimport { createConsentListDataFlowsTool } from './consent_list_data_flows.js';\nimport { createConsentListPurposesTool } from './consent_list_purposes.js';\nimport { createConsentListRegimesTool } from './consent_list_regimes.js';\nimport { createConsentSetPreferencesTool } from './consent_set_preferences.js';\nimport { createConsentUpdateCookiesTool } from './consent_update_cookies.js';\nimport { createConsentUpdateDataFlowsTool } from './consent_update_data_flows.js';\n\nexport function getConsentTools(clients: ToolClients): ToolDefinition[] {\n return [\n createConsentGetPreferencesTool(clients),\n createConsentSetPreferencesTool(clients),\n createConsentListPurposesTool(clients),\n createConsentListDataFlowsTool(clients),\n createConsentListCookiesTool(clients),\n createConsentListAirgapBundlesTool(clients),\n createConsentListRegimesTool(clients),\n createConsentGetInventoryStatsTool(clients),\n createConsentGetAggregateAnalyticsTool(clients),\n createConsentGetTimeseriesAnalyticsTool(clients),\n createConsentGetAnalyticsDataTool(clients),\n createConsentUpdateCookiesTool(clients),\n createConsentUpdateDataFlowsTool(clients),\n createConsentBulkTriageTool(clients),\n ];\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transcend-io/mcp-server-consent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Transcend MCP Server — Consent Management tools.",
|
|
5
5
|
"homepage": "https://github.com/transcend-io/tools/tree/main/packages/mcp/mcp-server-consent",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
34
34
|
"zod": "^4.3.6",
|
|
35
35
|
"@transcend-io/mcp-server-base": "0.4.5",
|
|
36
|
-
"@transcend-io/
|
|
37
|
-
"@transcend-io/
|
|
36
|
+
"@transcend-io/sdk": "1.2.3",
|
|
37
|
+
"@transcend-io/privacy-types": "5.2.2"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tools-DLlRbNSf.mjs","names":[],"sources":["../src/resolveAirgapBundleId.ts","../src/tools/consent_bulk_triage.ts","../src/tools/consent_get_preferences.ts","../src/tools/consent_get_triage_stats.ts","../src/tools/consent_list_airgap_bundles.ts","../src/tools/consent_list_cookies.ts","../src/tools/consent_list_data_flows.ts","../src/tools/consent_list_purposes.ts","../src/tools/consent_list_regimes.ts","../src/tools/consent_set_preferences.ts","../src/tools/consent_update_cookies.ts","../src/tools/consent_update_data_flows.ts","../src/tools/index.ts"],"sourcesContent":["import type { TranscendGraphQLBase } from '@transcend-io/mcp-server-base';\nimport {\n FETCH_CONSENT_MANAGER_ID,\n type TranscendCliFetchConsentManagerIdResponse,\n} from '@transcend-io/sdk';\n\nconst bundleIdCache = new WeakMap<TranscendGraphQLBase, string>();\n\n/**\n * Lazily resolve the airgap bundle ID from the API key.\n * Caches the result per GraphQL client instance so subsequent\n * calls return instantly without an extra network request.\n */\nexport async function resolveAirgapBundleId(graphql: TranscendGraphQLBase): Promise<string> {\n const cached = bundleIdCache.get(graphql);\n if (cached) return cached;\n\n const data = await graphql.makeRequest<TranscendCliFetchConsentManagerIdResponse>(\n FETCH_CONSENT_MANAGER_ID,\n {},\n );\n\n const id = data.consentManager.consentManager.id;\n bundleIdCache.set(graphql, id);\n return id;\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport {\n ConsentTrackerStatus,\n ConsentTrackerType,\n TriageAction,\n} from '@transcend-io/privacy-types';\nimport {\n UPDATE_OR_CREATE_COOKIES,\n UPDATE_DATA_FLOWS,\n type TranscendUpdateCookieInputGql,\n type TranscendUpdateDataFlowInputGql,\n type TranscendCliUpdateOrCreateCookiesResponse,\n type TranscendCliUpdateDataFlowsResponse,\n} from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const BulkTriageItemSchema = z.object({\n type: z.nativeEnum(ConsentTrackerType).describe('Item type'),\n id: z.string().describe('Item ID (for data flows) or cookie name (for cookies)'),\n action: z.nativeEnum(TriageAction).describe('Action to take: APPROVE or JUNK'),\n tracking_purposes: z\n .array(z.string())\n .optional()\n .describe('Tracking purposes to assign (required when approving)'),\n service: z.string().optional().describe('Service name to assign'),\n});\nexport type BulkTriageItemInput = z.infer<typeof BulkTriageItemSchema>;\n\nexport const BulkTriageSchema = z.object({\n items: z.array(BulkTriageItemSchema).min(1).describe('Items to triage'),\n});\nexport type BulkTriageInput = z.infer<typeof BulkTriageSchema>;\n\nexport function createConsentBulkTriageTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_bulk_triage',\n description:\n 'Bulk triage action: approve or junk multiple cookies and data flows in a single call. ' +\n 'For cookies, APPROVE sets status=LIVE; JUNK sets isJunk=true. ' +\n 'For data flows, same behavior. Optionally assign tracking purposes and service when approving.',\n category: 'Consent Management',\n readOnly: false,\n confirmationHint: 'Bulk approves or junks cookies and data flows',\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },\n zodSchema: BulkTriageSchema,\n handler: async ({ items }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const cookieItems = items.filter((i) => i.type === 'cookie');\n const dfItems = items.filter((i) => i.type === 'data_flow');\n\n const results: {\n /** Updated cookies */\n cookies: { name: string; action: string; status: string }[];\n /** Updated data flows */\n dataFlows: { id: string; action: string; status: string }[];\n } = { cookies: [], dataFlows: [] };\n\n if (cookieItems.length > 0) {\n const cookieInputs: TranscendUpdateCookieInputGql[] = cookieItems.map((item) => ({\n name: item.id,\n ...(item.action === 'APPROVE'\n ? { status: ConsentTrackerStatus.Live, isJunk: false }\n : { status: ConsentTrackerStatus.Live, isJunk: true }),\n ...(item.tracking_purposes ? { trackingPurposes: item.tracking_purposes } : {}),\n ...(item.service ? { service: item.service } : {}),\n }));\n await clients.graphql.makeRequest<TranscendCliUpdateOrCreateCookiesResponse>(\n UPDATE_OR_CREATE_COOKIES,\n {\n airgapBundleId,\n cookies: cookieInputs,\n },\n );\n results.cookies = cookieInputs.map((c) => ({\n name: c.name,\n action: c.isJunk ? 'JUNKED' : 'APPROVED',\n status: c.status || 'LIVE',\n }));\n }\n\n if (dfItems.length > 0) {\n const dfInputs: TranscendUpdateDataFlowInputGql[] = dfItems.map((item) => ({\n id: item.id,\n ...(item.action === 'APPROVE'\n ? { status: ConsentTrackerStatus.Live, isJunk: false }\n : { status: ConsentTrackerStatus.Live, isJunk: true }),\n ...(item.tracking_purposes ? { purposeIds: item.tracking_purposes } : {}),\n ...(item.service ? { service: item.service } : {}),\n }));\n const dfResult = await clients.graphql.makeRequest<TranscendCliUpdateDataFlowsResponse>(\n UPDATE_DATA_FLOWS,\n {\n airgapBundleId,\n dataFlows: dfInputs,\n },\n );\n results.dataFlows = dfResult.updateDataFlows.dataFlows.map((df) => ({\n id: df.id,\n action: df.isJunk ? 'JUNKED' : 'APPROVED',\n status: df.status,\n }));\n }\n\n return createToolResult(true, {\n totalProcessed: cookieItems.length + dfItems.length,\n ...results,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nexport const GetPreferencesSchema = z.object({\n identifier: z.string().describe('User identifier (e.g., email, user ID)'),\n partition: z.string().optional().describe('Partition/organization context (optional)'),\n});\nexport type GetPreferencesInput = z.infer<typeof GetPreferencesSchema>;\n\nexport function createConsentGetPreferencesTool(clients: ToolClients) {\n const { rest } = clients;\n return defineTool({\n name: 'consent_get_preferences',\n description: 'Get consent preferences for a specific user/identifier',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: GetPreferencesSchema,\n handler: async ({ identifier, partition }) => {\n const result = await rest.getConsentPreferences(identifier, partition);\n if (!result) {\n return createToolResult(true, {\n found: false,\n message: 'No consent preferences found for this identifier',\n });\n }\n return createToolResult(true, {\n found: true,\n preferences: result,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport {\n COOKIE_STATS,\n DATA_FLOW_STATS,\n type TranscendCliCookieStatsResponse,\n type TranscendCliDataFlowStatsResponse,\n} from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const GetCookieStatsSchema = z.object({});\nexport type GetCookieStatsInput = z.infer<typeof GetCookieStatsSchema>;\n\nexport function createConsentGetTriageStatsTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_get_triage_stats',\n description:\n 'Get statistics on cookies and data flows: live (approved), needs review (triage), ' +\n 'and junk counts.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: GetCookieStatsSchema,\n handler: async () => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const variables = { input: { airgapBundleId } };\n const [cookieData, dfData] = await Promise.all([\n clients.graphql.makeRequest<TranscendCliCookieStatsResponse>(COOKIE_STATS, variables),\n clients.graphql.makeRequest<TranscendCliDataFlowStatsResponse>(DATA_FLOW_STATS, variables),\n ]);\n return createToolResult(true, {\n cookies: cookieData.cookieStats,\n dataFlows: dfData.dataFlowStats,\n });\n },\n });\n}\n","import {\n createToolResult,\n defineTool,\n EmptySchema,\n type ToolClients,\n} from '@transcend-io/mcp-server-base';\nimport {\n FETCH_CONSENT_MANAGER,\n type TranscendCliFetchConsentManagerResponse,\n} from '@transcend-io/sdk';\n\nexport const ListAirgapBundlesSchema = EmptySchema;\nexport type ListAirgapBundlesInput = Record<string, never>;\n\nexport function createConsentListAirgapBundlesTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_list_airgap_bundles',\n description:\n 'Get the consent manager (airgap bundle) configured for your organization. ' +\n 'Returns the bundle ID, URLs, configuration, and domains.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListAirgapBundlesSchema,\n handler: async (_args) => {\n const data = await clients.graphql.makeRequest<TranscendCliFetchConsentManagerResponse>(\n FETCH_CONSENT_MANAGER,\n {},\n );\n return createToolResult(true, data.consentManager.consentManager);\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport {\n ConsentTrackerStatus,\n CookieOrderField,\n OrderDirection,\n} from '@transcend-io/privacy-types';\nimport { COOKIES, type TranscendCliCookiesResponse } from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const ListCookiesSchema = z.object({\n limit: z.number().min(1).max(200).optional().default(50),\n offset: z.number().min(0).optional().default(0),\n status: z\n .nativeEnum(ConsentTrackerStatus)\n .describe('Filter by status: NEEDS_REVIEW (triage) or LIVE (approved)'),\n is_junk: z.boolean().optional().describe('Filter by junk status'),\n show_zero_activity: z.boolean().optional().describe('Include items with zero activity'),\n text: z.string().optional().describe('Search text filter'),\n service: z.string().optional().describe('Filter by service name'),\n order_field: z.nativeEnum(CookieOrderField).optional().describe('Field to sort by'),\n order_direction: z.nativeEnum(OrderDirection).optional().describe('Sort direction: ASC or DESC'),\n});\nexport type ListCookiesInput = z.infer<typeof ListCookiesSchema>;\n\nexport function createConsentListCookiesTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_list_cookies',\n description:\n 'List cookies in your consent manager. ' +\n 'Requires a status filter: NEEDS_REVIEW for triage backlog, LIVE for approved cookies. ' +\n 'Returns name, service, tracking purposes, activity (occurrences), junk status, and more.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListCookiesSchema,\n handler: async ({\n limit,\n offset,\n status,\n is_junk,\n show_zero_activity,\n text,\n service,\n order_field,\n order_direction,\n }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const data = await clients.graphql.makeRequest<TranscendCliCookiesResponse>(COOKIES, {\n input: { airgapBundleId },\n first: limit,\n offset,\n filterBy: {\n status,\n ...(is_junk !== undefined ? { isJunk: is_junk } : {}),\n ...(show_zero_activity !== undefined ? { showZeroActivity: show_zero_activity } : {}),\n ...(text ? { text } : {}),\n ...(service ? { service } : {}),\n },\n ...(order_field && order_direction\n ? { orderBy: [{ field: order_field, direction: order_direction }] }\n : {}),\n });\n const { nodes, totalCount } = data.cookies;\n return createListResult(nodes, {\n totalCount,\n hasNextPage: offset + nodes.length < totalCount,\n });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport {\n ConsentTrackerStatus,\n DataFlowOrderField,\n OrderDirection,\n} from '@transcend-io/privacy-types';\nimport { DATA_FLOWS, type TranscendCliDataFlowsResponse } from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const ListDataFlowsSchema = z.object({\n limit: z.number().min(1).max(200).optional().default(50),\n offset: z.number().min(0).optional().default(0),\n status: z\n .nativeEnum(ConsentTrackerStatus)\n .describe('Filter by status: NEEDS_REVIEW (triage) or LIVE (approved)'),\n is_junk: z.boolean().optional().describe('Filter by junk status'),\n show_zero_activity: z.boolean().optional().describe('Include items with zero activity'),\n text: z.string().optional().describe('Search text filter'),\n service: z.string().optional().describe('Filter by service name'),\n order_field: z.nativeEnum(DataFlowOrderField).optional().describe('Field to sort by'),\n order_direction: z.nativeEnum(OrderDirection).optional().describe('Sort direction: ASC or DESC'),\n});\nexport type ListDataFlowsInput = z.infer<typeof ListDataFlowsSchema>;\n\nexport function createConsentListDataFlowsTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_list_data_flows',\n description:\n 'List data flows (network requests) in your consent manager. ' +\n 'Requires a status filter: NEEDS_REVIEW for triage backlog, LIVE for approved flows. ' +\n 'Returns value (URL/host), service, tracking purposes, activity (occurrences), and more.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListDataFlowsSchema,\n handler: async ({\n limit,\n offset,\n status,\n is_junk,\n show_zero_activity,\n text,\n service,\n order_field,\n order_direction,\n }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const data = await clients.graphql.makeRequest<TranscendCliDataFlowsResponse>(DATA_FLOWS, {\n input: { airgapBundleId },\n first: limit,\n offset,\n filterBy: {\n status,\n ...(is_junk !== undefined ? { isJunk: is_junk } : {}),\n ...(show_zero_activity !== undefined ? { showZeroActivity: show_zero_activity } : {}),\n ...(text ? { text } : {}),\n ...(service ? { service } : {}),\n },\n ...(order_field && order_direction\n ? { orderBy: [{ field: order_field, direction: order_direction }] }\n : {}),\n });\n const { nodes, totalCount } = data.dataFlows;\n return createListResult(nodes, {\n totalCount,\n hasNextPage: offset + nodes.length < totalCount,\n });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport { PURPOSES, type TranscendCliPurposesResponse } from '@transcend-io/sdk';\n\nexport const ListPurposesSchema = z.object({\n limit: z.coerce.number().min(1).max(100).optional().default(50),\n});\nexport type ListPurposesInput = z.infer<typeof ListPurposesSchema>;\n\nexport function createConsentListPurposesTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_list_purposes',\n description: 'List all tracking purposes configured for consent management (max ~100 results).',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListPurposesSchema,\n handler: async ({ limit }) => {\n const data = await clients.graphql.makeRequest<TranscendCliPurposesResponse>(PURPOSES, {\n first: Math.min(limit, 100),\n });\n const { nodes, totalCount } = data.purposes;\n return createListResult(nodes, {\n totalCount,\n hasNextPage: nodes.length < totalCount,\n });\n },\n });\n}\n","import { createListResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport { EXPERIENCES, type TranscendCliExperiencesResponse } from '@transcend-io/sdk';\n\nexport const ListRegimesSchema = z.object({\n limit: z.coerce.number().min(1).max(100).optional().default(50),\n offset: z.coerce.number().min(0).optional().default(0),\n});\nexport type ListRegimesInput = z.infer<typeof ListRegimesSchema>;\n\nexport function createConsentListRegimesTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_list_regimes',\n description:\n 'List all consent experiences (regional regimes) configured for your organization. ' +\n 'Returns experience name, regions, purposes, opted-out purposes, and view state.',\n category: 'Consent Management',\n readOnly: true,\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n zodSchema: ListRegimesSchema,\n handler: async ({ limit, offset }) => {\n const data = await clients.graphql.makeRequest<TranscendCliExperiencesResponse>(EXPERIENCES, {\n first: limit,\n offset,\n });\n const { totalCount, nodes } = data.experiences;\n return createListResult(nodes, {\n totalCount,\n hasNextPage: offset + nodes.length < totalCount,\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\n\nexport const PurposeConsentSchema = z.object({\n purpose: z.string().describe('Purpose slug'),\n enabled: z.boolean().describe('Whether consent is granted'),\n});\nexport type PurposeConsentInput = z.infer<typeof PurposeConsentSchema>;\n\nexport const SetPreferencesSchema = z.object({\n identifier: z.string().optional().describe('User identifier'),\n partition: z.string().describe('Partition/organization context'),\n purposes: z.array(PurposeConsentSchema).describe('Array of purpose consent settings'),\n confirmed: z.boolean().optional().describe('Whether consent was explicitly confirmed'),\n});\nexport type SetPreferencesInput = z.infer<typeof SetPreferencesSchema>;\n\nexport function createConsentSetPreferencesTool(clients: ToolClients) {\n const { rest } = clients;\n return defineTool({\n name: 'consent_set_preferences',\n description: 'Set consent preferences for a user (client-side sync)',\n category: 'Consent Management',\n readOnly: false,\n confirmationHint: 'Updates consent preferences for the user',\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n zodSchema: SetPreferencesSchema,\n handler: async ({ partition, identifier, purposes, confirmed }) => {\n const result = await rest.syncConsent({\n partition,\n identifier,\n purposes: purposes.map((p) => ({\n purpose: p.purpose,\n enabled: p.enabled,\n })),\n confirmed,\n });\n return createToolResult(true, {\n ...result,\n message: 'Consent preferences synced successfully',\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport { ConsentTrackerStatus } from '@transcend-io/privacy-types';\nimport {\n UPDATE_OR_CREATE_COOKIES,\n type TranscendUpdateCookieInputGql,\n type TranscendCliUpdateOrCreateCookiesResponse,\n} from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const UpdateCookieItemSchema = z.object({\n name: z.string().describe('Cookie name (used as the identifier for upsert)'),\n tracking_purposes: z\n .array(z.string())\n .optional()\n .describe('Tracking purpose slugs (e.g., \"Advertising\", \"Analytics\")'),\n description: z.string().optional().describe('Cookie description'),\n service: z.string().optional().describe('Service/integration name'),\n is_junk: z.boolean().optional().describe('Mark as junk'),\n status: z\n .nativeEnum(ConsentTrackerStatus)\n .optional()\n .describe('Set status to LIVE (approve) or NEEDS_REVIEW'),\n});\nexport type UpdateCookieItemInput = z.infer<typeof UpdateCookieItemSchema>;\n\nexport const UpdateCookiesSchema = z.object({\n cookies: z.array(UpdateCookieItemSchema).min(1).describe('Cookies to update'),\n});\nexport type UpdateCookiesInput = z.infer<typeof UpdateCookiesSchema>;\n\nexport function createConsentUpdateCookiesTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_update_cookies',\n description:\n 'Update one or more cookies. Use to approve (status=LIVE), junk (is_junk=true), ' +\n 'assign tracking purposes, or set a service. The cookie \"name\" field is the identifier ' +\n 'for upsert — existing cookies with matching names will be updated.',\n category: 'Consent Management',\n readOnly: false,\n confirmationHint: 'Updates cookies in the consent manager',\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true },\n zodSchema: UpdateCookiesSchema,\n handler: async ({ cookies }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const cookieInputs: TranscendUpdateCookieInputGql[] = cookies.map((c) => ({\n name: c.name,\n ...(c.tracking_purposes ? { trackingPurposes: c.tracking_purposes } : {}),\n ...(c.description !== undefined ? { description: c.description } : {}),\n ...(c.service !== undefined ? { service: c.service } : {}),\n ...(c.is_junk !== undefined ? { isJunk: c.is_junk } : {}),\n ...(c.status !== undefined ? { status: c.status } : {}),\n }));\n await clients.graphql.makeRequest<TranscendCliUpdateOrCreateCookiesResponse>(\n UPDATE_OR_CREATE_COOKIES,\n {\n airgapBundleId,\n cookies: cookieInputs,\n },\n );\n return createToolResult(true, {\n updated: cookieInputs.length,\n cookies: cookieInputs.map((c) => ({\n name: c.name,\n status: c.status,\n isJunk: c.isJunk,\n trackingPurposes: c.trackingPurposes,\n service: c.service,\n })),\n });\n },\n });\n}\n","import { createToolResult, defineTool, z, type ToolClients } from '@transcend-io/mcp-server-base';\nimport { ConsentTrackerStatus } from '@transcend-io/privacy-types';\nimport {\n UPDATE_DATA_FLOWS,\n type TranscendUpdateDataFlowInputGql,\n type TranscendCliUpdateDataFlowsResponse,\n} from '@transcend-io/sdk';\n\nimport { resolveAirgapBundleId } from '../resolveAirgapBundleId.js';\n\nexport const UpdateDataFlowItemSchema = z.object({\n id: z.string().describe('Data flow ID'),\n tracking_purposes: z.array(z.string()).optional().describe('Tracking purpose slugs'),\n description: z.string().optional().describe('Data flow description'),\n service: z.string().optional().describe('Service/integration name'),\n is_junk: z.boolean().optional().describe('Mark as junk'),\n status: z\n .nativeEnum(ConsentTrackerStatus)\n .optional()\n .describe('Set status to LIVE (approve) or NEEDS_REVIEW'),\n});\nexport type UpdateDataFlowItemInput = z.infer<typeof UpdateDataFlowItemSchema>;\n\nexport const UpdateDataFlowsSchema = z.object({\n data_flows: z.array(UpdateDataFlowItemSchema).min(1).describe('Data flows to update'),\n});\nexport type UpdateDataFlowsInput = z.infer<typeof UpdateDataFlowsSchema>;\n\nexport function createConsentUpdateDataFlowsTool(clients: ToolClients) {\n return defineTool({\n name: 'consent_update_data_flows',\n description:\n 'Update one or more data flows. Use to approve (status=LIVE), junk (is_junk=true), ' +\n 'assign tracking purposes, or set a service.',\n category: 'Consent Management',\n readOnly: false,\n confirmationHint: 'Updates data flows in the consent manager',\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true },\n zodSchema: UpdateDataFlowsSchema,\n handler: async ({ data_flows }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const dfInputs: TranscendUpdateDataFlowInputGql[] = data_flows.map((df) => ({\n id: df.id,\n ...(df.tracking_purposes ? { purposeIds: df.tracking_purposes } : {}),\n ...(df.description !== undefined ? { description: df.description } : {}),\n ...(df.service !== undefined ? { service: df.service } : {}),\n ...(df.is_junk !== undefined ? { isJunk: df.is_junk } : {}),\n ...(df.status !== undefined ? { status: df.status } : {}),\n }));\n const data = await clients.graphql.makeRequest<TranscendCliUpdateDataFlowsResponse>(\n UPDATE_DATA_FLOWS,\n {\n airgapBundleId,\n dataFlows: dfInputs,\n },\n );\n return createToolResult(true, {\n updated: data.updateDataFlows.dataFlows.length,\n dataFlows: data.updateDataFlows.dataFlows.map((df) => ({\n id: df.id,\n value: df.value,\n status: df.status,\n isJunk: df.isJunk,\n purposes: df.purposes.map((p) => p.name),\n service: df.service?.title,\n })),\n });\n },\n });\n}\n","import type { ToolDefinition, ToolClients } from '@transcend-io/mcp-server-base';\n\nimport { createConsentBulkTriageTool } from './consent_bulk_triage.js';\nimport { createConsentGetPreferencesTool } from './consent_get_preferences.js';\nimport { createConsentGetTriageStatsTool } from './consent_get_triage_stats.js';\nimport { createConsentListAirgapBundlesTool } from './consent_list_airgap_bundles.js';\nimport { createConsentListCookiesTool } from './consent_list_cookies.js';\nimport { createConsentListDataFlowsTool } from './consent_list_data_flows.js';\nimport { createConsentListPurposesTool } from './consent_list_purposes.js';\nimport { createConsentListRegimesTool } from './consent_list_regimes.js';\nimport { createConsentSetPreferencesTool } from './consent_set_preferences.js';\nimport { createConsentUpdateCookiesTool } from './consent_update_cookies.js';\nimport { createConsentUpdateDataFlowsTool } from './consent_update_data_flows.js';\n\nexport function getConsentTools(clients: ToolClients): ToolDefinition[] {\n return [\n createConsentGetPreferencesTool(clients),\n createConsentSetPreferencesTool(clients),\n createConsentListPurposesTool(clients),\n createConsentListDataFlowsTool(clients),\n createConsentListCookiesTool(clients),\n createConsentListAirgapBundlesTool(clients),\n createConsentListRegimesTool(clients),\n createConsentGetTriageStatsTool(clients),\n createConsentUpdateCookiesTool(clients),\n createConsentUpdateDataFlowsTool(clients),\n createConsentBulkTriageTool(clients),\n ];\n}\n"],"mappings":";;;;AAMA,MAAM,gCAAgB,IAAI,SAAuC;;;;;;AAOjE,eAAsB,sBAAsB,SAAgD;CAC1F,MAAM,SAAS,cAAc,IAAI,QAAQ;AACzC,KAAI,OAAQ,QAAO;CAOnB,MAAM,MALO,MAAM,QAAQ,YACzB,0BACA,EAAE,CACH,EAEe,eAAe,eAAe;AAC9C,eAAc,IAAI,SAAS,GAAG;AAC9B,QAAO;;;;ACPT,MAAa,uBAAuB,EAAE,OAAO;CAC3C,MAAM,EAAE,WAAW,mBAAmB,CAAC,SAAS,YAAY;CAC5D,IAAI,EAAE,QAAQ,CAAC,SAAS,wDAAwD;CAChF,QAAQ,EAAE,WAAW,aAAa,CAAC,SAAS,kCAAkC;CAC9E,mBAAmB,EAChB,MAAM,EAAE,QAAQ,CAAC,CACjB,UAAU,CACV,SAAS,wDAAwD;CACpE,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,yBAAyB;CAClE,CAAC;AAGF,MAAa,mBAAmB,EAAE,OAAO,EACvC,OAAO,EAAE,MAAM,qBAAqB,CAAC,IAAI,EAAE,CAAC,SAAS,kBAAkB,EACxE,CAAC;AAGF,SAAgB,4BAA4B,SAAsB;AAChE,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAGF,UAAU;EACV,UAAU;EACV,kBAAkB;EAClB,aAAa;GAAE,cAAc;GAAO,iBAAiB;GAAM,gBAAgB;GAAO;EAClF,WAAW;EACX,SAAS,OAAO,EAAE,YAAY;GAC5B,MAAM,iBAAiB,MAAM,sBAAsB,QAAQ,QAAQ;GACnE,MAAM,cAAc,MAAM,QAAQ,MAAM,EAAE,SAAS,SAAS;GAC5D,MAAM,UAAU,MAAM,QAAQ,MAAM,EAAE,SAAS,YAAY;GAE3D,MAAM,UAKF;IAAE,SAAS,EAAE;IAAE,WAAW,EAAE;IAAE;AAElC,OAAI,YAAY,SAAS,GAAG;IAC1B,MAAM,eAAgD,YAAY,KAAK,UAAU;KAC/E,MAAM,KAAK;KACX,GAAI,KAAK,WAAW,YAChB;MAAE,QAAQ,qBAAqB;MAAM,QAAQ;MAAO,GACpD;MAAE,QAAQ,qBAAqB;MAAM,QAAQ;MAAM;KACvD,GAAI,KAAK,oBAAoB,EAAE,kBAAkB,KAAK,mBAAmB,GAAG,EAAE;KAC9E,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,SAAS,GAAG,EAAE;KAClD,EAAE;AACH,UAAM,QAAQ,QAAQ,YACpB,0BACA;KACE;KACA,SAAS;KACV,CACF;AACD,YAAQ,UAAU,aAAa,KAAK,OAAO;KACzC,MAAM,EAAE;KACR,QAAQ,EAAE,SAAS,WAAW;KAC9B,QAAQ,EAAE,UAAU;KACrB,EAAE;;AAGL,OAAI,QAAQ,SAAS,GAAG;IACtB,MAAM,WAA8C,QAAQ,KAAK,UAAU;KACzE,IAAI,KAAK;KACT,GAAI,KAAK,WAAW,YAChB;MAAE,QAAQ,qBAAqB;MAAM,QAAQ;MAAO,GACpD;MAAE,QAAQ,qBAAqB;MAAM,QAAQ;MAAM;KACvD,GAAI,KAAK,oBAAoB,EAAE,YAAY,KAAK,mBAAmB,GAAG,EAAE;KACxE,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,SAAS,GAAG,EAAE;KAClD,EAAE;AAQH,YAAQ,aAPS,MAAM,QAAQ,QAAQ,YACrC,mBACA;KACE;KACA,WAAW;KACZ,CACF,EAC4B,gBAAgB,UAAU,KAAK,QAAQ;KAClE,IAAI,GAAG;KACP,QAAQ,GAAG,SAAS,WAAW;KAC/B,QAAQ,GAAG;KACZ,EAAE;;AAGL,UAAO,iBAAiB,MAAM;IAC5B,gBAAgB,YAAY,SAAS,QAAQ;IAC7C,GAAG;IACJ,CAAC;;EAEL,CAAC;;;;AC3GJ,MAAa,uBAAuB,EAAE,OAAO;CAC3C,YAAY,EAAE,QAAQ,CAAC,SAAS,yCAAyC;CACzE,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,4CAA4C;CACvF,CAAC;AAGF,SAAgB,gCAAgC,SAAsB;CACpE,MAAM,EAAE,SAAS;AACjB,QAAO,WAAW;EAChB,MAAM;EACN,aAAa;EACb,UAAU;EACV,UAAU;EACV,aAAa;GAAE,cAAc;GAAM,iBAAiB;GAAO,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,OAAO,EAAE,YAAY,gBAAgB;GAC5C,MAAM,SAAS,MAAM,KAAK,sBAAsB,YAAY,UAAU;AACtE,OAAI,CAAC,OACH,QAAO,iBAAiB,MAAM;IAC5B,OAAO;IACP,SAAS;IACV,CAAC;AAEJ,UAAO,iBAAiB,MAAM;IAC5B,OAAO;IACP,aAAa;IACd,CAAC;;EAEL,CAAC;;;;ACpBJ,MAAa,uBAAuB,EAAE,OAAO,EAAE,CAAC;AAGhD,SAAgB,gCAAgC,SAAsB;AACpE,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAEF,UAAU;EACV,UAAU;EACV,aAAa;GAAE,cAAc;GAAM,iBAAiB;GAAO,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,YAAY;GAEnB,MAAM,YAAY,EAAE,OAAO,EAAE,gBADN,MAAM,sBAAsB,QAAQ,QAAQ,EACtB,EAAE;GAC/C,MAAM,CAAC,YAAY,UAAU,MAAM,QAAQ,IAAI,CAC7C,QAAQ,QAAQ,YAA6C,cAAc,UAAU,EACrF,QAAQ,QAAQ,YAA+C,iBAAiB,UAAU,CAC3F,CAAC;AACF,UAAO,iBAAiB,MAAM;IAC5B,SAAS,WAAW;IACpB,WAAW,OAAO;IACnB,CAAC;;EAEL,CAAC;;;;ACxBJ,MAAa,0BAA0B;AAGvC,SAAgB,mCAAmC,SAAsB;AACvE,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAEF,UAAU;EACV,UAAU;EACV,aAAa;GAAE,cAAc;GAAM,iBAAiB;GAAO,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,OAAO,UAAU;AAKxB,UAAO,iBAAiB,OAJX,MAAM,QAAQ,QAAQ,YACjC,uBACA,EAAE,CACH,EACkC,eAAe,eAAe;;EAEpE,CAAC;;;;ACrBJ,MAAa,oBAAoB,EAAE,OAAO;CACxC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG;CACxD,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE;CAC/C,QAAQ,EACL,WAAW,qBAAqB,CAChC,SAAS,6DAA6D;CACzE,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,wBAAwB;CACjE,oBAAoB,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,mCAAmC;CACvF,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,qBAAqB;CAC1D,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,yBAAyB;CACjE,aAAa,EAAE,WAAW,iBAAiB,CAAC,UAAU,CAAC,SAAS,mBAAmB;CACnF,iBAAiB,EAAE,WAAW,eAAe,CAAC,UAAU,CAAC,SAAS,8BAA8B;CACjG,CAAC;AAGF,SAAgB,6BAA6B,SAAsB;AACjE,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAGF,UAAU;EACV,UAAU;EACV,aAAa;GAAE,cAAc;GAAM,iBAAiB;GAAO,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,OAAO,EACd,OACA,QACA,QACA,SACA,oBACA,MACA,SACA,aACA,sBACI;GACJ,MAAM,iBAAiB,MAAM,sBAAsB,QAAQ,QAAQ;GAgBnE,MAAM,EAAE,OAAO,gBAfF,MAAM,QAAQ,QAAQ,YAAyC,SAAS;IACnF,OAAO,EAAE,gBAAgB;IACzB,OAAO;IACP;IACA,UAAU;KACR;KACA,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,SAAS,GAAG,EAAE;KACpD,GAAI,uBAAuB,KAAA,IAAY,EAAE,kBAAkB,oBAAoB,GAAG,EAAE;KACpF,GAAI,OAAO,EAAE,MAAM,GAAG,EAAE;KACxB,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;KAC/B;IACD,GAAI,eAAe,kBACf,EAAE,SAAS,CAAC;KAAE,OAAO;KAAa,WAAW;KAAiB,CAAC,EAAE,GACjE,EAAE;IACP,CAAC,EACiC;AACnC,UAAO,iBAAiB,OAAO;IAC7B;IACA,aAAa,SAAS,MAAM,SAAS;IACtC,CAAC;;EAEL,CAAC;;;;AC3DJ,MAAa,sBAAsB,EAAE,OAAO;CAC1C,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG;CACxD,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE;CAC/C,QAAQ,EACL,WAAW,qBAAqB,CAChC,SAAS,6DAA6D;CACzE,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,wBAAwB;CACjE,oBAAoB,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,mCAAmC;CACvF,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,qBAAqB;CAC1D,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,yBAAyB;CACjE,aAAa,EAAE,WAAW,mBAAmB,CAAC,UAAU,CAAC,SAAS,mBAAmB;CACrF,iBAAiB,EAAE,WAAW,eAAe,CAAC,UAAU,CAAC,SAAS,8BAA8B;CACjG,CAAC;AAGF,SAAgB,+BAA+B,SAAsB;AACnE,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAGF,UAAU;EACV,UAAU;EACV,aAAa;GAAE,cAAc;GAAM,iBAAiB;GAAO,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,OAAO,EACd,OACA,QACA,QACA,SACA,oBACA,MACA,SACA,aACA,sBACI;GACJ,MAAM,iBAAiB,MAAM,sBAAsB,QAAQ,QAAQ;GAgBnE,MAAM,EAAE,OAAO,gBAfF,MAAM,QAAQ,QAAQ,YAA2C,YAAY;IACxF,OAAO,EAAE,gBAAgB;IACzB,OAAO;IACP;IACA,UAAU;KACR;KACA,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,SAAS,GAAG,EAAE;KACpD,GAAI,uBAAuB,KAAA,IAAY,EAAE,kBAAkB,oBAAoB,GAAG,EAAE;KACpF,GAAI,OAAO,EAAE,MAAM,GAAG,EAAE;KACxB,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;KAC/B;IACD,GAAI,eAAe,kBACf,EAAE,SAAS,CAAC;KAAE,OAAO;KAAa,WAAW;KAAiB,CAAC,EAAE,GACjE,EAAE;IACP,CAAC,EACiC;AACnC,UAAO,iBAAiB,OAAO;IAC7B;IACA,aAAa,SAAS,MAAM,SAAS;IACtC,CAAC;;EAEL,CAAC;;;;AClEJ,MAAa,qBAAqB,EAAE,OAAO,EACzC,OAAO,EAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG,EAChE,CAAC;AAGF,SAAgB,8BAA8B,SAAsB;AAClE,QAAO,WAAW;EAChB,MAAM;EACN,aAAa;EACb,UAAU;EACV,UAAU;EACV,aAAa;GAAE,cAAc;GAAM,iBAAiB;GAAO,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,OAAO,EAAE,YAAY;GAI5B,MAAM,EAAE,OAAO,gBAHF,MAAM,QAAQ,QAAQ,YAA0C,UAAU,EACrF,OAAO,KAAK,IAAI,OAAO,IAAI,EAC5B,CAAC,EACiC;AACnC,UAAO,iBAAiB,OAAO;IAC7B;IACA,aAAa,MAAM,SAAS;IAC7B,CAAC;;EAEL,CAAC;;;;ACvBJ,MAAa,oBAAoB,EAAE,OAAO;CACxC,OAAO,EAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG;CAC/D,QAAQ,EAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE;CACvD,CAAC;AAGF,SAAgB,6BAA6B,SAAsB;AACjE,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAEF,UAAU;EACV,UAAU;EACV,aAAa;GAAE,cAAc;GAAM,iBAAiB;GAAO,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,OAAO,EAAE,OAAO,aAAa;GAKpC,MAAM,EAAE,YAAY,WAJP,MAAM,QAAQ,QAAQ,YAA6C,aAAa;IAC3F,OAAO;IACP;IACD,CAAC,EACiC;AACnC,UAAO,iBAAiB,OAAO;IAC7B;IACA,aAAa,SAAS,MAAM,SAAS;IACtC,CAAC;;EAEL,CAAC;;;;AC5BJ,MAAa,uBAAuB,EAAE,OAAO;CAC3C,SAAS,EAAE,QAAQ,CAAC,SAAS,eAAe;CAC5C,SAAS,EAAE,SAAS,CAAC,SAAS,6BAA6B;CAC5D,CAAC;AAGF,MAAa,uBAAuB,EAAE,OAAO;CAC3C,YAAY,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,kBAAkB;CAC7D,WAAW,EAAE,QAAQ,CAAC,SAAS,iCAAiC;CAChE,UAAU,EAAE,MAAM,qBAAqB,CAAC,SAAS,oCAAoC;CACrF,WAAW,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,2CAA2C;CACvF,CAAC;AAGF,SAAgB,gCAAgC,SAAsB;CACpE,MAAM,EAAE,SAAS;AACjB,QAAO,WAAW;EAChB,MAAM;EACN,aAAa;EACb,UAAU;EACV,UAAU;EACV,kBAAkB;EAClB,aAAa;GAAE,cAAc;GAAO,iBAAiB;GAAO,gBAAgB;GAAM;EAClF,WAAW;EACX,SAAS,OAAO,EAAE,WAAW,YAAY,UAAU,gBAAgB;AAUjE,UAAO,iBAAiB,MAAM;IAC5B,GAVa,MAAM,KAAK,YAAY;KACpC;KACA;KACA,UAAU,SAAS,KAAK,OAAO;MAC7B,SAAS,EAAE;MACX,SAAS,EAAE;MACZ,EAAE;KACH;KACD,CAAC;IAGA,SAAS;IACV,CAAC;;EAEL,CAAC;;;;AC/BJ,MAAa,yBAAyB,EAAE,OAAO;CAC7C,MAAM,EAAE,QAAQ,CAAC,SAAS,kDAAkD;CAC5E,mBAAmB,EAChB,MAAM,EAAE,QAAQ,CAAC,CACjB,UAAU,CACV,SAAS,gEAA4D;CACxE,aAAa,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,qBAAqB;CACjE,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,2BAA2B;CACnE,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,eAAe;CACxD,QAAQ,EACL,WAAW,qBAAqB,CAChC,UAAU,CACV,SAAS,+CAA+C;CAC5D,CAAC;AAGF,MAAa,sBAAsB,EAAE,OAAO,EAC1C,SAAS,EAAE,MAAM,uBAAuB,CAAC,IAAI,EAAE,CAAC,SAAS,oBAAoB,EAC9E,CAAC;AAGF,SAAgB,+BAA+B,SAAsB;AACnE,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAGF,UAAU;EACV,UAAU;EACV,kBAAkB;EAClB,aAAa;GAAE,cAAc;GAAO,iBAAiB;GAAM,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,OAAO,EAAE,cAAc;GAC9B,MAAM,iBAAiB,MAAM,sBAAsB,QAAQ,QAAQ;GACnE,MAAM,eAAgD,QAAQ,KAAK,OAAO;IACxE,MAAM,EAAE;IACR,GAAI,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,mBAAmB,GAAG,EAAE;IACxE,GAAI,EAAE,gBAAgB,KAAA,IAAY,EAAE,aAAa,EAAE,aAAa,GAAG,EAAE;IACrE,GAAI,EAAE,YAAY,KAAA,IAAY,EAAE,SAAS,EAAE,SAAS,GAAG,EAAE;IACzD,GAAI,EAAE,YAAY,KAAA,IAAY,EAAE,QAAQ,EAAE,SAAS,GAAG,EAAE;IACxD,GAAI,EAAE,WAAW,KAAA,IAAY,EAAE,QAAQ,EAAE,QAAQ,GAAG,EAAE;IACvD,EAAE;AACH,SAAM,QAAQ,QAAQ,YACpB,0BACA;IACE;IACA,SAAS;IACV,CACF;AACD,UAAO,iBAAiB,MAAM;IAC5B,SAAS,aAAa;IACtB,SAAS,aAAa,KAAK,OAAO;KAChC,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,QAAQ,EAAE;KACV,kBAAkB,EAAE;KACpB,SAAS,EAAE;KACZ,EAAE;IACJ,CAAC;;EAEL,CAAC;;;;AC7DJ,MAAa,2BAA2B,EAAE,OAAO;CAC/C,IAAI,EAAE,QAAQ,CAAC,SAAS,eAAe;CACvC,mBAAmB,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,SAAS,yBAAyB;CACpF,aAAa,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,wBAAwB;CACpE,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,2BAA2B;CACnE,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,eAAe;CACxD,QAAQ,EACL,WAAW,qBAAqB,CAChC,UAAU,CACV,SAAS,+CAA+C;CAC5D,CAAC;AAGF,MAAa,wBAAwB,EAAE,OAAO,EAC5C,YAAY,EAAE,MAAM,yBAAyB,CAAC,IAAI,EAAE,CAAC,SAAS,uBAAuB,EACtF,CAAC;AAGF,SAAgB,iCAAiC,SAAsB;AACrE,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAEF,UAAU;EACV,UAAU;EACV,kBAAkB;EAClB,aAAa;GAAE,cAAc;GAAO,iBAAiB;GAAM,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,OAAO,EAAE,iBAAiB;GACjC,MAAM,iBAAiB,MAAM,sBAAsB,QAAQ,QAAQ;GACnE,MAAM,WAA8C,WAAW,KAAK,QAAQ;IAC1E,IAAI,GAAG;IACP,GAAI,GAAG,oBAAoB,EAAE,YAAY,GAAG,mBAAmB,GAAG,EAAE;IACpE,GAAI,GAAG,gBAAgB,KAAA,IAAY,EAAE,aAAa,GAAG,aAAa,GAAG,EAAE;IACvE,GAAI,GAAG,YAAY,KAAA,IAAY,EAAE,SAAS,GAAG,SAAS,GAAG,EAAE;IAC3D,GAAI,GAAG,YAAY,KAAA,IAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,EAAE;IAC1D,GAAI,GAAG,WAAW,KAAA,IAAY,EAAE,QAAQ,GAAG,QAAQ,GAAG,EAAE;IACzD,EAAE;GACH,MAAM,OAAO,MAAM,QAAQ,QAAQ,YACjC,mBACA;IACE;IACA,WAAW;IACZ,CACF;AACD,UAAO,iBAAiB,MAAM;IAC5B,SAAS,KAAK,gBAAgB,UAAU;IACxC,WAAW,KAAK,gBAAgB,UAAU,KAAK,QAAQ;KACrD,IAAI,GAAG;KACP,OAAO,GAAG;KACV,QAAQ,GAAG;KACX,QAAQ,GAAG;KACX,UAAU,GAAG,SAAS,KAAK,MAAM,EAAE,KAAK;KACxC,SAAS,GAAG,SAAS;KACtB,EAAE;IACJ,CAAC;;EAEL,CAAC;;;;ACtDJ,SAAgB,gBAAgB,SAAwC;AACtE,QAAO;EACL,gCAAgC,QAAQ;EACxC,gCAAgC,QAAQ;EACxC,8BAA8B,QAAQ;EACtC,+BAA+B,QAAQ;EACvC,6BAA6B,QAAQ;EACrC,mCAAmC,QAAQ;EAC3C,6BAA6B,QAAQ;EACrC,gCAAgC,QAAQ;EACxC,+BAA+B,QAAQ;EACvC,iCAAiC,QAAQ;EACzC,4BAA4B,QAAQ;EACrC"}
|