@transcend-io/mcp-server-consent 0.3.5 → 0.4.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 CHANGED
@@ -6,7 +6,7 @@ Transcend MCP Server for consent management. Provides tools for managing consent
6
6
 
7
7
  Requires **Node.js ≥ 22.12** (see `engines` in `package.json`).
8
8
 
9
- For local runs from this repository, copy [`secret.env.example`](../../../secret.env.example) to **`secret.env`** at the repo root (gitignored) and set your API key (see **Run from the monorepo**). The key must be created with **MCP** enabled in the Transcend dashboard (a toggle when you create the key).
9
+ For local runs from this repository, copy [`secret.env.example`](../../../secret.env.example) to **`secret.env`** at the repo root (gitignored) and set the OAuth environment variables (see **Run from the monorepo**).
10
10
 
11
11
  ## Install
12
12
 
@@ -21,12 +21,31 @@ Or run from a checkout of this repository (see **Run from the monorepo** below).
21
21
  ## Usage
22
22
 
23
23
  ```bash
24
- # With TRANSCEND_API_KEY in the environment; from the monorepo use secret.env (see Run from the monorepo)
25
- TRANSCEND_API_KEY=your-api-key transcend-mcp-consent
24
+ # With OAuth env vars in the environment; from the monorepo use secret.env (see Run from the monorepo)
25
+ TRANSCEND_OAUTH_CLIENT_ID=your-client-id \
26
+ TRANSCEND_OAUTH_CLIENT_SECRET=your-client-secret \
27
+ TRANSCEND_OAUTH_REDIRECT_PORT=your-client-redirect-port \
28
+ transcend-mcp-consent
26
29
  ```
27
30
 
28
31
  The process speaks MCP over **stdio** and is meant to be launched by an MCP client (for example Cursor or Claude Desktop), not used as an interactive shell.
29
32
 
33
+ ### OAuth client setup
34
+
35
+ OAuth stdio is the recommended path for MCP clients (Cursor, Claude Desktop). Requires **org admin** access to create OAuth clients.
36
+
37
+ 1. Navigate to [app.transcend.com/admin/oauth-clients](https://app.transcend.com/admin/oauth-clients) and create an OAuth client.
38
+ 2. Copy the **client ID** and **client secret**.
39
+ 3. Register `http://127.0.0.1:{port}/callback` — use **`127.0.0.1`, not `localhost`**, and ensure the path is `/callback`. Set `TRANSCEND_OAUTH_REDIRECT_PORT` to the matching port.
40
+
41
+ At startup the server verifies client ID, secret, and redirect URI. On first tool call it opens a browser for login. Tokens are session-only (in-memory).
42
+
43
+ **OAuth scopes:** `ViewConsentManager`, `ViewAssignedConsentManager`, `ManageConsentManager`, `ManageAssignedConsentManager`, `ViewDataFlow`, `ManageDataFlow`. The signed-in user must hold these permissions. See [`src/scopes.ts`](./src/scopes.ts).
44
+
45
+ Full setup, troubleshooting, and multi-server guidance: [MCP root README](../README.md#oauth-client-setup).
46
+
47
+ > **API key alternative:** set `TRANSCEND_API_KEY` instead of OAuth vars for stdio (OAuth is disabled when both are set).
48
+
30
49
  ### MCP client configuration
31
50
 
32
51
  `npx` runs the package’s `transcend-mcp-consent` binary (see `bin` in `package.json`).
@@ -38,7 +57,9 @@ The process speaks MCP over **stdio** and is meant to be launched by an MCP clie
38
57
  "command": "npx",
39
58
  "args": ["-y", "@transcend-io/mcp-server-consent"],
40
59
  "env": {
41
- "TRANSCEND_API_KEY": "your-api-key"
60
+ "TRANSCEND_OAUTH_CLIENT_ID": "your-client-id",
61
+ "TRANSCEND_OAUTH_CLIENT_SECRET": "your-client-secret",
62
+ "TRANSCEND_OAUTH_REDIRECT_PORT": "your-client-redirect-port"
42
63
  }
43
64
  }
44
65
  }
@@ -49,7 +70,7 @@ When developing in this repository, reuse the same variable names from root **`s
49
70
 
50
71
  ### Run from the monorepo
51
72
 
52
- 1. **Credentials** — From the repository root, copy [`secret.env.example`](../../../secret.env.example) to **`secret.env`** and set `TRANSCEND_API_KEY` (and optional URL overrides).
73
+ 1. **Credentials** — From the repository root, copy [`secret.env.example`](../../../secret.env.example) to **`secret.env`** and set `TRANSCEND_OAUTH_CLIENT_ID`, `TRANSCEND_OAUTH_CLIENT_SECRET`, and `TRANSCEND_OAUTH_REDIRECT_PORT` (and optional URL overrides).
53
74
 
54
75
  2. **Build and run** — `node ./dist/cli.mjs` matches the `transcend-mcp-consent` `bin` (use `node` because `pnpm exec transcend-mcp-consent` may not resolve this package’s own binary in a pnpm workspace):
55
76
 
@@ -66,11 +87,16 @@ See [CONTRIBUTING.md](../../../CONTRIBUTING.md#mcp-servers) for workspace layout
66
87
 
67
88
  ### Environment variables
68
89
 
69
- | Variable | Required | Default | Description |
70
- | ------------------- | -------- | ------------------------------------------ | -------------------------------------------------- |
71
- | `TRANSCEND_API_KEY` | Yes | — | Transcend API key |
72
- | `TRANSCEND_API_URL` | No | `https://api.transcend.io` | GraphQL backend API URL (matches CLI convention) |
73
- | `SOMBRA_URL` | No | `https://multi-tenant.sombra.transcend.io` | Sombra REST API URL (matches CLI / SDK convention) |
90
+ | Variable | Required (stdio OAuth) | Default | Description |
91
+ | ------------------------------- | ---------------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
92
+ | `TRANSCEND_OAUTH_CLIENT_ID` | Yes | — | Client ID from [app.transcend.com/admin/oauth-clients](https://app.transcend.com/admin/oauth-clients) |
93
+ | `TRANSCEND_OAUTH_CLIENT_SECRET` | Yes | | Client secret from the same OAuth clients page |
94
+ | `TRANSCEND_OAUTH_REDIRECT_PORT` | Yes | | Localhost port for the OAuth callback server; **must match the port in your registered redirect URI** |
95
+ | `TRANSCEND_OAUTH_REDIRECT_HOST` | No | `127.0.0.1` | Loopback host for the OAuth callback (`127.0.0.1` or `::1` for `http://[::1]:{port}/callback`) |
96
+ | `TRANSCEND_OAUTH_ISSUER` | No | auto-detected | OAuth issuer URL; production auto-detects region. Test-only override |
97
+ | `TRANSCEND_API_KEY` | No | — | API key for stdio (alternative to OAuth). Disables OAuth when set alongside client ID |
98
+ | `TRANSCEND_API_URL` | No | `https://api.transcend.io` | GraphQL backend API URL (matches CLI convention) |
99
+ | `SOMBRA_URL` | No | `https://multi-tenant.sombra.transcend.io` | Sombra REST API URL (matches CLI / SDK convention) |
74
100
 
75
101
  **Monorepo:** keep these in root **`secret.env`** (from [`secret.env.example`](../../../secret.env.example)); see **Run from the monorepo**.
76
102
 
@@ -91,7 +117,7 @@ See [CONTRIBUTING.md](../../../CONTRIBUTING.md#mcp-servers) for workspace layout
91
117
  - `consent_update_data_flows` — Update data flows
92
118
  - `consent_bulk_triage` — Bulk approve or junk cookies and data flows
93
119
 
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).
120
+ Analytics tools require the **ViewConsentManager** scope (included in this server's OAuth scopes). See [Consent Analytics Using GraphQL API](https://docs.transcend.io/docs/articles/consent-management/configuration/consent-stats-with-gql-api).
95
121
 
96
122
  ## Related packages
97
123
 
package/dist/cli.mjs CHANGED
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { t as getConsentTools } from "./tools-bVmFBYcw.mjs";
2
+ import { n as getConsentTools, t as CONSENT_OAUTH_SCOPES } from "./scopes-DF8-jJlM.mjs";
3
3
  import { createMCPServer } from "@transcend-io/mcp-server-base";
4
4
  //#region src/cli.ts
5
5
  createMCPServer({
6
6
  name: "transcend-mcp-consent",
7
7
  version: "1.0.0",
8
+ oauthScopes: CONSENT_OAUTH_SCOPES,
8
9
  getTools: getConsentTools
9
10
  });
10
11
  //#endregion
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { createMCPServer } from '@transcend-io/mcp-server-base';\n\nimport { getConsentTools } from './tools/index.js';\n\ncreateMCPServer({\n name: 'transcend-mcp-consent',\n version: '1.0.0',\n getTools: getConsentTools,\n});\n"],"mappings":";;;;AAKA,gBAAgB;CACd,MAAM;CACN,SAAS;CACT,UAAU;CACX,CAAC"}
1
+ {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { createMCPServer } from '@transcend-io/mcp-server-base';\n\nimport { CONSENT_OAUTH_SCOPES } from './scopes.js';\nimport { getConsentTools } from './tools/index.js';\n\ncreateMCPServer({\n name: 'transcend-mcp-consent',\n version: '1.0.0',\n oauthScopes: CONSENT_OAUTH_SCOPES,\n getTools: getConsentTools,\n});\n"],"mappings":";;;;AAMA,gBAAgB;CACd,MAAM;CACN,SAAS;CACT,aAAa;CACb,UAAU;CACX,CAAC"}
package/dist/index.d.mts CHANGED
@@ -1,11 +1,15 @@
1
1
  import { ToolClients, ToolDefinition, TranscendGraphQLBase, z } from "@transcend-io/mcp-server-base";
2
- import { ConsentTrackerStatus } from "@transcend-io/privacy-types";
2
+ import { ConsentTrackerStatus, ScopeName } from "@transcend-io/privacy-types";
3
3
  import * as _$zod_v4_core0 from "zod/v4/core";
4
4
  import * as _$zod from "zod";
5
5
 
6
6
  //#region src/tools/index.d.ts
7
7
  declare function getConsentTools(clients: ToolClients): ToolDefinition[];
8
8
  //#endregion
9
+ //#region src/scopes.d.ts
10
+ /** OAuth scopes required for Consent MCP tools (offline_access added by base). */
11
+ declare const CONSENT_OAUTH_SCOPES: readonly [ScopeName.ViewConsentManager, ScopeName.ViewAssignedConsentManager, ScopeName.ManageConsentManager, ScopeName.ManageAssignedConsentManager, ScopeName.ViewDataFlow, ScopeName.ManageDataFlow];
12
+ //#endregion
9
13
  //#region src/resolveAirgapBundleId.d.ts
10
14
  /**
11
15
  * Lazily resolve the airgap bundle ID from the API key.
@@ -67,16 +71,16 @@ declare const ListCookiesSchema: z.ZodObject<{
67
71
  limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
68
72
  offset: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
69
73
  status: z.ZodEnum<typeof ConsentTrackerStatus>;
70
- is_junk: z.ZodOptional<z.ZodBoolean>;
71
- show_zero_activity: z.ZodOptional<z.ZodBoolean>;
74
+ isJunk: z.ZodOptional<z.ZodBoolean>;
75
+ showZeroActivity: z.ZodOptional<z.ZodBoolean>;
72
76
  text: z.ZodOptional<z.ZodString>;
73
77
  service: z.ZodOptional<z.ZodString>;
74
- order_field: z.ZodOptional<z.ZodEnum<{
78
+ orderField: z.ZodOptional<z.ZodEnum<{
75
79
  Name: "name";
76
80
  CreatedAt: "createdAt";
77
81
  UpdatedAt: "updatedAt";
78
82
  }>>;
79
- order_direction: z.ZodOptional<z.ZodEnum<{
83
+ orderDirection: z.ZodOptional<z.ZodEnum<{
80
84
  Asc: "ASC";
81
85
  Desc: "DESC";
82
86
  }>>;
@@ -88,18 +92,18 @@ declare const ListDataFlowsSchema: z.ZodObject<{
88
92
  limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
89
93
  offset: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
90
94
  status: z.ZodEnum<typeof ConsentTrackerStatus>;
91
- is_junk: z.ZodOptional<z.ZodBoolean>;
92
- show_zero_activity: z.ZodOptional<z.ZodBoolean>;
95
+ isJunk: z.ZodOptional<z.ZodBoolean>;
96
+ showZeroActivity: z.ZodOptional<z.ZodBoolean>;
93
97
  text: z.ZodOptional<z.ZodString>;
94
98
  service: z.ZodOptional<z.ZodString>;
95
- order_field: z.ZodOptional<z.ZodEnum<{
99
+ orderField: z.ZodOptional<z.ZodEnum<{
96
100
  Value: "value";
97
101
  CreatedAt: "createdAt";
98
102
  UpdatedAt: "updatedAt";
99
103
  Occurrences: "occurrences";
100
104
  Service: "service";
101
105
  }>>;
102
- order_direction: z.ZodOptional<z.ZodEnum<{
106
+ orderDirection: z.ZodOptional<z.ZodEnum<{
103
107
  Asc: "ASC";
104
108
  Desc: "DESC";
105
109
  }>>;
@@ -181,20 +185,20 @@ type GetAnalyticsDataInput = z.infer<typeof GetAnalyticsDataSchema>;
181
185
  //#region src/tools/consent_update_cookies.d.ts
182
186
  declare const UpdateCookieItemSchema: z.ZodObject<{
183
187
  name: z.ZodString;
184
- tracking_purposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
188
+ trackingPurposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
185
189
  description: z.ZodOptional<z.ZodString>;
186
190
  service: z.ZodOptional<z.ZodString>;
187
- is_junk: z.ZodOptional<z.ZodBoolean>;
191
+ isJunk: z.ZodOptional<z.ZodBoolean>;
188
192
  status: z.ZodOptional<z.ZodEnum<typeof ConsentTrackerStatus>>;
189
193
  }, z.core.$strip>;
190
194
  type UpdateCookieItemInput = z.infer<typeof UpdateCookieItemSchema>;
191
195
  declare const UpdateCookiesSchema: z.ZodObject<{
192
196
  cookies: z.ZodArray<z.ZodObject<{
193
197
  name: z.ZodString;
194
- tracking_purposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
198
+ trackingPurposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
195
199
  description: z.ZodOptional<z.ZodString>;
196
200
  service: z.ZodOptional<z.ZodString>;
197
- is_junk: z.ZodOptional<z.ZodBoolean>;
201
+ isJunk: z.ZodOptional<z.ZodBoolean>;
198
202
  status: z.ZodOptional<z.ZodEnum<typeof ConsentTrackerStatus>>;
199
203
  }, z.core.$strip>>;
200
204
  }, z.core.$strip>;
@@ -203,20 +207,20 @@ type UpdateCookiesInput = z.infer<typeof UpdateCookiesSchema>;
203
207
  //#region src/tools/consent_update_data_flows.d.ts
204
208
  declare const UpdateDataFlowItemSchema: z.ZodObject<{
205
209
  id: z.ZodString;
206
- tracking_purposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
210
+ trackingPurposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
207
211
  description: z.ZodOptional<z.ZodString>;
208
212
  service: z.ZodOptional<z.ZodString>;
209
- is_junk: z.ZodOptional<z.ZodBoolean>;
213
+ isJunk: z.ZodOptional<z.ZodBoolean>;
210
214
  status: z.ZodOptional<z.ZodEnum<typeof ConsentTrackerStatus>>;
211
215
  }, z.core.$strip>;
212
216
  type UpdateDataFlowItemInput = z.infer<typeof UpdateDataFlowItemSchema>;
213
217
  declare const UpdateDataFlowsSchema: z.ZodObject<{
214
- data_flows: z.ZodArray<z.ZodObject<{
218
+ dataFlows: z.ZodArray<z.ZodObject<{
215
219
  id: z.ZodString;
216
- tracking_purposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
220
+ trackingPurposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
217
221
  description: z.ZodOptional<z.ZodString>;
218
222
  service: z.ZodOptional<z.ZodString>;
219
- is_junk: z.ZodOptional<z.ZodBoolean>;
223
+ isJunk: z.ZodOptional<z.ZodBoolean>;
220
224
  status: z.ZodOptional<z.ZodEnum<typeof ConsentTrackerStatus>>;
221
225
  }, z.core.$strip>>;
222
226
  }, z.core.$strip>;
@@ -233,7 +237,7 @@ declare const BulkTriageItemSchema: z.ZodObject<{
233
237
  Approve: "APPROVE";
234
238
  Junk: "JUNK";
235
239
  }>;
236
- tracking_purposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
240
+ trackingPurposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
237
241
  service: z.ZodOptional<z.ZodString>;
238
242
  }, z.core.$strip>;
239
243
  type BulkTriageItemInput = z.infer<typeof BulkTriageItemSchema>;
@@ -248,11 +252,11 @@ declare const BulkTriageSchema: z.ZodObject<{
248
252
  Approve: "APPROVE";
249
253
  Junk: "JUNK";
250
254
  }>;
251
- tracking_purposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
255
+ trackingPurposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
252
256
  service: z.ZodOptional<z.ZodString>;
253
257
  }, z.core.$strip>>;
254
258
  }, z.core.$strip>;
255
259
  type BulkTriageInput = z.infer<typeof BulkTriageSchema>;
256
260
  //#endregion
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 };
261
+ export { type BulkTriageInput, type BulkTriageItemInput, BulkTriageItemSchema, BulkTriageSchema, CONSENT_OAUTH_SCOPES, 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 };
258
262
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
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,KAAA,CAAA,SAAA,KAAc,cAAA,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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/tools/index.ts","../src/scopes.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":"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"}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
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
+ import { S as resolveAirgapBundleId, _ as GetAnalyticsDataSchema, a as UpdateCookieItemSchema, b as BulkTriageItemSchema, c as SetPreferencesSchema, d as ListDataFlowsSchema, f as ListCookiesSchema, g as GetInventoryStatsSchema, h as GetPreferencesSchema, i as UpdateDataFlowsSchema, l as ListRegimesSchema, m as GetTimeseriesAnalyticsSchema, n as getConsentTools, o as UpdateCookiesSchema, p as ListAirgapBundlesSchema, r as UpdateDataFlowItemSchema, s as PurposeConsentSchema, t as CONSENT_OAUTH_SCOPES, u as ListPurposesSchema, v as GetAggregateAnalyticsSchema, x as BulkTriageSchema, y as resolveAnalyticsDateRange } from "./scopes-DF8-jJlM.mjs";
2
+ export { BulkTriageItemSchema, BulkTriageSchema, CONSENT_OAUTH_SCOPES, GetAggregateAnalyticsSchema, GetAnalyticsDataSchema, GetInventoryStatsSchema, GetPreferencesSchema, GetTimeseriesAnalyticsSchema, ListAirgapBundlesSchema, ListCookiesSchema, ListDataFlowsSchema, ListPurposesSchema, ListRegimesSchema, PurposeConsentSchema, SetPreferencesSchema, UpdateCookieItemSchema, UpdateCookiesSchema, UpdateDataFlowItemSchema, UpdateDataFlowsSchema, getConsentTools, resolveAirgapBundleId, resolveAnalyticsDateRange };
@@ -1,5 +1,5 @@
1
1
  import { EmptySchema, createListResult, createToolResult, defineTool, z } from "@transcend-io/mcp-server-base";
2
- import { AirgapBundleAnalyticsBinInterval, AirgapBundleAnalyticsDimension, AirgapBundleAnalyticsMetric, ConsentManagerAnalyticsDataSource, ConsentManagerMetricBin, ConsentTrackerStatus, ConsentTrackerType, CookieOrderField, DataFlowOrderField, OrderDirection, TriageAction } from "@transcend-io/privacy-types";
2
+ import { AirgapBundleAnalyticsBinInterval, AirgapBundleAnalyticsDimension, AirgapBundleAnalyticsMetric, ConsentManagerAnalyticsDataSource, ConsentManagerMetricBin, ConsentTrackerStatus, ConsentTrackerType, CookieOrderField, DataFlowOrderField, OrderDirection, ScopeName, TriageAction } from "@transcend-io/privacy-types";
3
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();
@@ -21,7 +21,7 @@ const BulkTriageItemSchema = z.object({
21
21
  type: z.nativeEnum(ConsentTrackerType).describe("Item type"),
22
22
  id: z.string().describe("Item ID (for data flows) or cookie name (for cookies)"),
23
23
  action: z.nativeEnum(TriageAction).describe("Action to take: APPROVE or JUNK"),
24
- tracking_purposes: z.array(z.string()).optional().describe("Tracking purposes to assign (required when approving)"),
24
+ trackingPurposes: z.array(z.string()).optional().describe("Tracking purposes to assign (required when approving)"),
25
25
  service: z.string().optional().describe("Service name to assign")
26
26
  });
27
27
  const BulkTriageSchema = z.object({ items: z.array(BulkTriageItemSchema).min(1).describe("Items to triage") });
@@ -56,7 +56,7 @@ function createConsentBulkTriageTool(clients) {
56
56
  status: ConsentTrackerStatus.Live,
57
57
  isJunk: true
58
58
  },
59
- ...item.tracking_purposes ? { trackingPurposes: item.tracking_purposes } : {},
59
+ ...item.trackingPurposes ? { trackingPurposes: item.trackingPurposes } : {},
60
60
  ...item.service ? { service: item.service } : {}
61
61
  }));
62
62
  await clients.graphql.makeRequest(UPDATE_OR_CREATE_COOKIES, {
@@ -79,7 +79,7 @@ function createConsentBulkTriageTool(clients) {
79
79
  status: ConsentTrackerStatus.Live,
80
80
  isJunk: true
81
81
  },
82
- ...item.tracking_purposes ? { purposeIds: item.tracking_purposes } : {},
82
+ ...item.trackingPurposes ? { purposeIds: item.trackingPurposes } : {},
83
83
  ...item.service ? { service: item.service } : {}
84
84
  }));
85
85
  results.dataFlows = (await clients.graphql.makeRequest(UPDATE_DATA_FLOWS, {
@@ -369,15 +369,15 @@ function createConsentListAirgapBundlesTool(clients) {
369
369
  //#endregion
370
370
  //#region src/tools/consent_list_cookies.ts
371
371
  const ListCookiesSchema = z.object({
372
- limit: z.number().min(1).max(200).optional().default(50),
373
- offset: z.number().min(0).optional().default(0),
372
+ limit: z.number().min(1).max(200).optional().default(50).describe("Maximum number of cookies to return per page (1-200, default 50)."),
373
+ offset: z.number().min(0).optional().default(0).describe("Number of results to skip for pagination (default 0)."),
374
374
  status: z.nativeEnum(ConsentTrackerStatus).describe("Filter by status: NEEDS_REVIEW (triage) or LIVE (approved)"),
375
- is_junk: z.boolean().optional().describe("Filter by junk status"),
376
- show_zero_activity: z.boolean().optional().describe("Include items with zero activity"),
375
+ isJunk: z.boolean().optional().describe("Filter by junk status"),
376
+ showZeroActivity: z.boolean().optional().describe("Include items with zero activity"),
377
377
  text: z.string().optional().describe("Search text filter"),
378
378
  service: z.string().optional().describe("Filter by service name"),
379
- order_field: z.nativeEnum(CookieOrderField).optional().describe("Field to sort by"),
380
- order_direction: z.nativeEnum(OrderDirection).optional().describe("Sort direction: ASC or DESC")
379
+ orderField: z.nativeEnum(CookieOrderField).optional().describe("Field to sort by"),
380
+ orderDirection: z.nativeEnum(OrderDirection).optional().describe("Sort direction: ASC or DESC")
381
381
  });
382
382
  function createConsentListCookiesTool(clients) {
383
383
  return defineTool({
@@ -391,7 +391,7 @@ function createConsentListCookiesTool(clients) {
391
391
  idempotentHint: true
392
392
  },
393
393
  zodSchema: ListCookiesSchema,
394
- handler: async ({ limit, offset, status, is_junk, show_zero_activity, text, service, order_field, order_direction }) => {
394
+ handler: async ({ limit, offset, status, isJunk, showZeroActivity, text, service, orderField, orderDirection }) => {
395
395
  const airgapBundleId = await resolveAirgapBundleId(clients.graphql);
396
396
  const { nodes, totalCount } = (await clients.graphql.makeRequest(COOKIES, {
397
397
  input: { airgapBundleId },
@@ -399,14 +399,14 @@ function createConsentListCookiesTool(clients) {
399
399
  offset,
400
400
  filterBy: {
401
401
  status,
402
- ...is_junk !== void 0 ? { isJunk: is_junk } : {},
403
- ...show_zero_activity !== void 0 ? { showZeroActivity: show_zero_activity } : {},
402
+ ...isJunk !== void 0 ? { isJunk } : {},
403
+ ...showZeroActivity !== void 0 ? { showZeroActivity } : {},
404
404
  ...text ? { text } : {},
405
405
  ...service ? { service } : {}
406
406
  },
407
- ...order_field && order_direction ? { orderBy: [{
408
- field: order_field,
409
- direction: order_direction
407
+ ...orderField && orderDirection ? { orderBy: [{
408
+ field: orderField,
409
+ direction: orderDirection
410
410
  }] } : {}
411
411
  })).cookies;
412
412
  return createListResult(nodes, {
@@ -419,15 +419,15 @@ function createConsentListCookiesTool(clients) {
419
419
  //#endregion
420
420
  //#region src/tools/consent_list_data_flows.ts
421
421
  const ListDataFlowsSchema = z.object({
422
- limit: z.number().min(1).max(200).optional().default(50),
423
- offset: z.number().min(0).optional().default(0),
422
+ limit: z.number().min(1).max(200).optional().default(50).describe("Maximum number of data flows to return per page (1-200, default 50)."),
423
+ offset: z.number().min(0).optional().default(0).describe("Number of results to skip for pagination (default 0)."),
424
424
  status: z.nativeEnum(ConsentTrackerStatus).describe("Filter by status: NEEDS_REVIEW (triage) or LIVE (approved)"),
425
- is_junk: z.boolean().optional().describe("Filter by junk status"),
426
- show_zero_activity: z.boolean().optional().describe("Include items with zero activity"),
425
+ isJunk: z.boolean().optional().describe("Filter by junk status"),
426
+ showZeroActivity: z.boolean().optional().describe("Include items with zero activity"),
427
427
  text: z.string().optional().describe("Search text filter"),
428
428
  service: z.string().optional().describe("Filter by service name"),
429
- order_field: z.nativeEnum(DataFlowOrderField).optional().describe("Field to sort by"),
430
- order_direction: z.nativeEnum(OrderDirection).optional().describe("Sort direction: ASC or DESC")
429
+ orderField: z.nativeEnum(DataFlowOrderField).optional().describe("Field to sort by"),
430
+ orderDirection: z.nativeEnum(OrderDirection).optional().describe("Sort direction: ASC or DESC")
431
431
  });
432
432
  function createConsentListDataFlowsTool(clients) {
433
433
  return defineTool({
@@ -441,7 +441,7 @@ function createConsentListDataFlowsTool(clients) {
441
441
  idempotentHint: true
442
442
  },
443
443
  zodSchema: ListDataFlowsSchema,
444
- handler: async ({ limit, offset, status, is_junk, show_zero_activity, text, service, order_field, order_direction }) => {
444
+ handler: async ({ limit, offset, status, isJunk, showZeroActivity, text, service, orderField, orderDirection }) => {
445
445
  const airgapBundleId = await resolveAirgapBundleId(clients.graphql);
446
446
  const { nodes, totalCount } = (await clients.graphql.makeRequest(DATA_FLOWS, {
447
447
  input: { airgapBundleId },
@@ -449,14 +449,14 @@ function createConsentListDataFlowsTool(clients) {
449
449
  offset,
450
450
  filterBy: {
451
451
  status,
452
- ...is_junk !== void 0 ? { isJunk: is_junk } : {},
453
- ...show_zero_activity !== void 0 ? { showZeroActivity: show_zero_activity } : {},
452
+ ...isJunk !== void 0 ? { isJunk } : {},
453
+ ...showZeroActivity !== void 0 ? { showZeroActivity } : {},
454
454
  ...text ? { text } : {},
455
455
  ...service ? { service } : {}
456
456
  },
457
- ...order_field && order_direction ? { orderBy: [{
458
- field: order_field,
459
- direction: order_direction
457
+ ...orderField && orderDirection ? { orderBy: [{
458
+ field: orderField,
459
+ direction: orderDirection
460
460
  }] } : {}
461
461
  })).dataFlows;
462
462
  return createListResult(nodes, {
@@ -468,7 +468,7 @@ function createConsentListDataFlowsTool(clients) {
468
468
  }
469
469
  //#endregion
470
470
  //#region src/tools/consent_list_purposes.ts
471
- const ListPurposesSchema = z.object({ limit: z.coerce.number().min(1).max(100).optional().default(50) });
471
+ const ListPurposesSchema = z.object({ limit: z.coerce.number().min(1).max(100).optional().default(50).describe("Maximum number of purposes to return (1-100, default 50).") });
472
472
  function createConsentListPurposesTool(clients) {
473
473
  return defineTool({
474
474
  name: "consent_list_purposes",
@@ -493,8 +493,8 @@ function createConsentListPurposesTool(clients) {
493
493
  //#endregion
494
494
  //#region src/tools/consent_list_regimes.ts
495
495
  const ListRegimesSchema = z.object({
496
- limit: z.coerce.number().min(1).max(100).optional().default(50),
497
- offset: z.coerce.number().min(0).optional().default(0)
496
+ limit: z.coerce.number().min(1).max(100).optional().default(50).describe("Maximum number of regimes to return per page (1-100, default 50)."),
497
+ offset: z.coerce.number().min(0).optional().default(0).describe("Number of results to skip for pagination (default 0).")
498
498
  });
499
499
  function createConsentListRegimesTool(clients) {
500
500
  return defineTool({
@@ -566,17 +566,17 @@ function createConsentSetPreferencesTool(clients) {
566
566
  //#region src/tools/consent_update_cookies.ts
567
567
  const UpdateCookieItemSchema = z.object({
568
568
  name: z.string().describe("Cookie name (used as the identifier for upsert)"),
569
- tracking_purposes: z.array(z.string()).optional().describe("Tracking purpose slugs (e.g., \"Advertising\", \"Analytics\")"),
569
+ trackingPurposes: z.array(z.string()).optional().describe("Tracking purpose slugs (e.g., \"Advertising\", \"Analytics\")"),
570
570
  description: z.string().optional().describe("Cookie description"),
571
571
  service: z.string().optional().describe("Service/integration name"),
572
- is_junk: z.boolean().optional().describe("Mark as junk"),
572
+ isJunk: z.boolean().optional().describe("Mark as junk"),
573
573
  status: z.nativeEnum(ConsentTrackerStatus).optional().describe("Set status to LIVE (approve) or NEEDS_REVIEW")
574
574
  });
575
575
  const UpdateCookiesSchema = z.object({ cookies: z.array(UpdateCookieItemSchema).min(1).describe("Cookies to update") });
576
576
  function createConsentUpdateCookiesTool(clients) {
577
577
  return defineTool({
578
578
  name: "consent_update_cookies",
579
- description: "Update one or more cookies. Use to approve (status=LIVE), junk (is_junk=true), assign tracking purposes, or set a service. The cookie \"name\" field is the identifier for upsert — existing cookies with matching names will be updated.",
579
+ description: "Update one or more cookies. Use to approve (status=LIVE), junk (isJunk=true), assign tracking purposes, or set a service. The cookie \"name\" field is the identifier for upsert — existing cookies with matching names will be updated.",
580
580
  category: "Consent Management",
581
581
  readOnly: false,
582
582
  confirmationHint: "Updates cookies in the consent manager",
@@ -590,10 +590,10 @@ function createConsentUpdateCookiesTool(clients) {
590
590
  const airgapBundleId = await resolveAirgapBundleId(clients.graphql);
591
591
  const cookieInputs = cookies.map((c) => ({
592
592
  name: c.name,
593
- ...c.tracking_purposes ? { trackingPurposes: c.tracking_purposes } : {},
593
+ ...c.trackingPurposes ? { trackingPurposes: c.trackingPurposes } : {},
594
594
  ...c.description !== void 0 ? { description: c.description } : {},
595
595
  ...c.service !== void 0 ? { service: c.service } : {},
596
- ...c.is_junk !== void 0 ? { isJunk: c.is_junk } : {},
596
+ ...c.isJunk !== void 0 ? { isJunk: c.isJunk } : {},
597
597
  ...c.status !== void 0 ? { status: c.status } : {}
598
598
  }));
599
599
  await clients.graphql.makeRequest(UPDATE_OR_CREATE_COOKIES, {
@@ -617,17 +617,17 @@ function createConsentUpdateCookiesTool(clients) {
617
617
  //#region src/tools/consent_update_data_flows.ts
618
618
  const UpdateDataFlowItemSchema = z.object({
619
619
  id: z.string().describe("Data flow ID"),
620
- tracking_purposes: z.array(z.string()).optional().describe("Tracking purpose slugs"),
620
+ trackingPurposes: z.array(z.string()).optional().describe("Tracking purpose slugs"),
621
621
  description: z.string().optional().describe("Data flow description"),
622
622
  service: z.string().optional().describe("Service/integration name"),
623
- is_junk: z.boolean().optional().describe("Mark as junk"),
623
+ isJunk: z.boolean().optional().describe("Mark as junk"),
624
624
  status: z.nativeEnum(ConsentTrackerStatus).optional().describe("Set status to LIVE (approve) or NEEDS_REVIEW")
625
625
  });
626
- const UpdateDataFlowsSchema = z.object({ data_flows: z.array(UpdateDataFlowItemSchema).min(1).describe("Data flows to update") });
626
+ const UpdateDataFlowsSchema = z.object({ dataFlows: z.array(UpdateDataFlowItemSchema).min(1).describe("Data flows to update") });
627
627
  function createConsentUpdateDataFlowsTool(clients) {
628
628
  return defineTool({
629
629
  name: "consent_update_data_flows",
630
- description: "Update one or more data flows. Use to approve (status=LIVE), junk (is_junk=true), assign tracking purposes, or set a service.",
630
+ description: "Update one or more data flows. Use to approve (status=LIVE), junk (isJunk=true), assign tracking purposes, or set a service.",
631
631
  category: "Consent Management",
632
632
  readOnly: false,
633
633
  confirmationHint: "Updates data flows in the consent manager",
@@ -637,14 +637,14 @@ function createConsentUpdateDataFlowsTool(clients) {
637
637
  idempotentHint: true
638
638
  },
639
639
  zodSchema: UpdateDataFlowsSchema,
640
- handler: async ({ data_flows }) => {
640
+ handler: async ({ dataFlows }) => {
641
641
  const airgapBundleId = await resolveAirgapBundleId(clients.graphql);
642
- const dfInputs = data_flows.map((df) => ({
642
+ const dfInputs = dataFlows.map((df) => ({
643
643
  id: df.id,
644
- ...df.tracking_purposes ? { purposeIds: df.tracking_purposes } : {},
644
+ ...df.trackingPurposes ? { purposeIds: df.trackingPurposes } : {},
645
645
  ...df.description !== void 0 ? { description: df.description } : {},
646
646
  ...df.service !== void 0 ? { service: df.service } : {},
647
- ...df.is_junk !== void 0 ? { isJunk: df.is_junk } : {},
647
+ ...df.isJunk !== void 0 ? { isJunk: df.isJunk } : {},
648
648
  ...df.status !== void 0 ? { status: df.status } : {}
649
649
  }));
650
650
  const data = await clients.graphql.makeRequest(UPDATE_DATA_FLOWS, {
@@ -686,6 +686,17 @@ function getConsentTools(clients) {
686
686
  ];
687
687
  }
688
688
  //#endregion
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 };
689
+ //#region src/scopes.ts
690
+ /** OAuth scopes required for Consent MCP tools (offline_access added by base). */
691
+ const CONSENT_OAUTH_SCOPES = [
692
+ ScopeName.ViewConsentManager,
693
+ ScopeName.ViewAssignedConsentManager,
694
+ ScopeName.ManageConsentManager,
695
+ ScopeName.ManageAssignedConsentManager,
696
+ ScopeName.ViewDataFlow,
697
+ ScopeName.ManageDataFlow
698
+ ];
699
+ //#endregion
700
+ export { resolveAirgapBundleId as S, GetAnalyticsDataSchema as _, UpdateCookieItemSchema as a, BulkTriageItemSchema as b, SetPreferencesSchema as c, ListDataFlowsSchema as d, ListCookiesSchema as f, GetInventoryStatsSchema as g, GetPreferencesSchema as h, UpdateDataFlowsSchema as i, ListRegimesSchema as l, GetTimeseriesAnalyticsSchema as m, getConsentTools as n, UpdateCookiesSchema as o, ListAirgapBundlesSchema as p, UpdateDataFlowItemSchema as r, PurposeConsentSchema as s, CONSENT_OAUTH_SCOPES as t, ListPurposesSchema as u, GetAggregateAnalyticsSchema as v, BulkTriageSchema as x, resolveAnalyticsDateRange as y };
690
701
 
691
- //# sourceMappingURL=tools-bVmFBYcw.mjs.map
702
+ //# sourceMappingURL=scopes-DF8-jJlM.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopes-DF8-jJlM.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","../src/scopes.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 trackingPurposes: 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.trackingPurposes ? { trackingPurposes: item.trackingPurposes } : {}),\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.trackingPurposes ? { purposeIds: item.trackingPurposes } : {}),\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\n .number()\n .min(1)\n .max(200)\n .optional()\n .default(50)\n .describe('Maximum number of cookies to return per page (1-200, default 50).'),\n offset: z\n .number()\n .min(0)\n .optional()\n .default(0)\n .describe('Number of results to skip for pagination (default 0).'),\n status: z\n .nativeEnum(ConsentTrackerStatus)\n .describe('Filter by status: NEEDS_REVIEW (triage) or LIVE (approved)'),\n isJunk: z.boolean().optional().describe('Filter by junk status'),\n showZeroActivity: 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 orderField: z.nativeEnum(CookieOrderField).optional().describe('Field to sort by'),\n orderDirection: 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 isJunk,\n showZeroActivity,\n text,\n service,\n orderField,\n orderDirection,\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 ...(isJunk !== undefined ? { isJunk } : {}),\n ...(showZeroActivity !== undefined ? { showZeroActivity } : {}),\n ...(text ? { text } : {}),\n ...(service ? { service } : {}),\n },\n ...(orderField && orderDirection\n ? { orderBy: [{ field: orderField, direction: orderDirection }] }\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\n .number()\n .min(1)\n .max(200)\n .optional()\n .default(50)\n .describe('Maximum number of data flows to return per page (1-200, default 50).'),\n offset: z\n .number()\n .min(0)\n .optional()\n .default(0)\n .describe('Number of results to skip for pagination (default 0).'),\n status: z\n .nativeEnum(ConsentTrackerStatus)\n .describe('Filter by status: NEEDS_REVIEW (triage) or LIVE (approved)'),\n isJunk: z.boolean().optional().describe('Filter by junk status'),\n showZeroActivity: 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 orderField: z.nativeEnum(DataFlowOrderField).optional().describe('Field to sort by'),\n orderDirection: 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 isJunk,\n showZeroActivity,\n text,\n service,\n orderField,\n orderDirection,\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 ...(isJunk !== undefined ? { isJunk } : {}),\n ...(showZeroActivity !== undefined ? { showZeroActivity } : {}),\n ...(text ? { text } : {}),\n ...(service ? { service } : {}),\n },\n ...(orderField && orderDirection\n ? { orderBy: [{ field: orderField, direction: orderDirection }] }\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\n .number()\n .min(1)\n .max(100)\n .optional()\n .default(50)\n .describe('Maximum number of purposes to return (1-100, 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\n .number()\n .min(1)\n .max(100)\n .optional()\n .default(50)\n .describe('Maximum number of regimes to return per page (1-100, default 50).'),\n offset: z.coerce\n .number()\n .min(0)\n .optional()\n .default(0)\n .describe('Number of results to skip for pagination (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 trackingPurposes: 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 isJunk: 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 (isJunk=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.trackingPurposes ? { trackingPurposes: c.trackingPurposes } : {}),\n ...(c.description !== undefined ? { description: c.description } : {}),\n ...(c.service !== undefined ? { service: c.service } : {}),\n ...(c.isJunk !== undefined ? { isJunk: c.isJunk } : {}),\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 trackingPurposes: 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 isJunk: 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 dataFlows: 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 (isJunk=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 ({ dataFlows }) => {\n const airgapBundleId = await resolveAirgapBundleId(clients.graphql);\n const dfInputs: TranscendUpdateDataFlowInputGql[] = dataFlows.map((df) => ({\n id: df.id,\n ...(df.trackingPurposes ? { purposeIds: df.trackingPurposes } : {}),\n ...(df.description !== undefined ? { description: df.description } : {}),\n ...(df.service !== undefined ? { service: df.service } : {}),\n ...(df.isJunk !== undefined ? { isJunk: df.isJunk } : {}),\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","import { ScopeName } from '@transcend-io/privacy-types';\n\n/** OAuth scopes required for Consent MCP tools (offline_access added by base). */\nexport const CONSENT_OAUTH_SCOPES = [\n ScopeName.ViewConsentManager,\n ScopeName.ViewAssignedConsentManager,\n ScopeName.ManageConsentManager,\n ScopeName.ManageAssignedConsentManager,\n ScopeName.ViewDataFlow,\n ScopeName.ManageDataFlow,\n] as const;\n"],"mappings":";;;;AAMA,MAAM,gCAAgB,IAAI,SAAuC;;;;;;AAOjE,eAAsB,sBAAsB,SAAgD;CAC1F,MAAM,SAAS,cAAc,IAAI,QAAQ;AACzC,KAAI,OAAQ,QAAO;CAOnB,MAAM,MAAK,MALQ,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,kBAAkB,EACf,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,mBAAmB,EAAE,kBAAkB,KAAK,kBAAkB,GAAG,EAAE;KAC5E,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,mBAAmB,EAAE,YAAY,KAAK,kBAAkB,GAAG,EAAE;KACtE,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,SAAS,GAAG,EAAE;KAClD,EAAE;AAQH,YAAQ,aAAY,MAPG,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;;;;;;;AC/FJ,SAAgB,0BAA0B,MAOX;CAC7B,MAAM,UAAU,KAAK,MAAM,IAAI,KAAK,KAAK,IAAI,mBAAG,IAAI,MAAM;CAC1D,MAAM,eAAe,KAAK,QAAQ;CAClC,MAAM,YAAY,KAAK,QACnB,IAAI,KAAK,KAAK,MAAM,mBACpB,IAAI,KAAK,QAAQ,SAAS,GAAG,eAAe,KAAK,KAAK,KAAK,IAAK;AAEpE,KAAI,OAAO,MAAM,UAAU,SAAS,CAAC,IAAI,OAAO,MAAM,QAAQ,SAAS,CAAC,CACtE,OAAM,IAAI,MAAM,4BAA4B;AAE9C,KAAI,YAAY,QACd,OAAM,IAAI,MAAM,qCAAqC;AAGvD,QAAO;EACL,YAAY,KAAK,MAAM,UAAU,SAAS,GAAG,IAAK;EAClD,UAAU,KAAK,MAAM,QAAQ,SAAS,GAAG,IAAK;EAC9C,UAAU,UAAU,aAAa;EACjC,QAAQ,QAAQ,aAAa;EAC9B;;;;ACrCH,MAAM,gBAAgB,IAAI,IAAY,OAAO,OAAO,4BAA4B,CAAC;;AAGjF,MAAM,2BAAwE;CAC5E,WAAW,4BAA4B;CACvC,iBAAiB,4BAA4B;CAC7C,kBAAkB,4BAA4B;CAC/C;;;;AAKD,SAAgB,yBAAyB,QAAsD;CAC7F,MAAM,QAAQ,OAAO,aAAa;AAClC,KAAI,cAAc,IAAI,MAAM,CAC1B,QAAO;AAET,QAAO,yBAAyB,UAAU;;AAG5C,MAAa,oCAAoC,EAAE,YAChD,UAAW,OAAO,UAAU,WAAW,yBAAyB,MAAM,GAAG,OAC1E,EAAE,WAAW,4BAA4B,CAC1C;;;ACZD,MAAa,8BAA8B,EAAE,OAAO;CAClD,QAAQ,kCAAkC,SACxC,oHACD;CACD,OAAO,EACJ,QAAQ,CACR,UAAU,CACV,SAAS,mEAAmE;CAC/E,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,4CAA4C;CAChF,MAAM,EAAE,OACL,QAAQ,CACR,IAAI,EAAE,CACN,IAAI,IAAI,CACR,UAAU,CACV,SAAS,8DAA8D;CAC1E,oBAAoB,EACjB,MAAM,EAAE,WAAW,+BAA+B,CAAC,CACnD,UAAU,CACV,SACC,2FACD;CACJ,CAAC;AAGF,SAAgB,uCAAuC,SAAsB;AAC3E,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAGF,UAAU;EACV,UAAU;EACV,aAAa;GAAE,cAAc;GAAM,iBAAiB;GAAO,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,OAAO,EAAE,QAAQ,OAAO,KAAK,MAAM,yBAAyB;GACnE,MAAM,iBAAiB,MAAM,sBAAsB,QAAQ,QAAQ;GACnE,MAAM,QAAQ,0BAA0B;IAAE;IAAO;IAAK;IAAM,CAAC;GAc7D,MAAM,SAAQ,MAZN,QAAQ,QAAQ,YACpB,mCACA;IACE,IAAI;IACJ,OAAO;KACL;KACA,OAAO,MAAM;KACb,KAAK,MAAM;KACX,GAAI,oBAAoB,SAAS,EAAE,mBAAmB,oBAAoB,GAAG,EAAE;KAChF;IACF,CACF,EACgB,+BAA+B;AAElD,UAAO,iBAAiB,MAAM;IAC5B;IACA;IACA,QAAQ;KACN,OAAO,MAAM;KACb,KAAK,MAAM;KACX,YAAY,MAAM;KAClB,UAAU,MAAM;KACjB;IACD;IACA,WAAW,MAAM;IAClB,CAAC;;EAEL,CAAC;;;;ACtEJ,MAAa,yBAAyB,EAAE,OAAO;CAC7C,aAAa,EACV,WAAW,kCAAkC,CAC7C,SACC,qIAED;CACH,OAAO,EACJ,QAAQ,CACR,UAAU,CACV,SAAS,mEAAmE;CAC/E,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,4CAA4C;CAChF,MAAM,EAAE,OACL,QAAQ,CACR,IAAI,EAAE,CACN,IAAI,IAAI,CACR,UAAU,CACV,SAAS,8DAA8D;CAC1E,KAAK,EACF,WAAW,wBAAwB,CACnC,UAAU,CACV,QAAQ,wBAAwB,MAAM,CACtC,SAAS,2DAA2D;CACxE,CAAC;AAGF,SAAgB,kCAAkC,SAAsB;AACtE,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAGF,UAAU;EACV,UAAU;EACV,aAAa;GAAE,cAAc;GAAM,iBAAiB;GAAO,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,OAAO,EAAE,aAAa,OAAO,KAAK,MAAM,UAAU;GACzD,MAAM,iBAAiB,MAAM,sBAAsB,QAAQ,QAAQ;GACnE,MAAM,QAAQ,0BAA0B;IAAE;IAAO;IAAK;IAAM,CAAC;GAc7D,MAAM,UAAS,MAbI,QAAQ,QAAQ,YAEhC,gCAAgC,EACjC,OAAO;IACL,YAAY;IACZ,WAAW,MAAM;IACjB,SAAS,MAAM;IACf,cAAc;IACd;IACA,aAAa;IACb,kBAAkB;IACnB,EACF,CAAC,EACkB,cAAc;AAElC,UAAO,iBAAiB,MAAM;IAC5B;IACA,YAAY;IACZ,aAAa;IACb,QAAQ;KACN,OAAO,MAAM;KACb,KAAK,MAAM;KACZ;IACD;IACD,CAAC;;EAEL,CAAC;;;;AClEJ,MAAa,0BAA0B,EAAE,OAAO,EAAE,CAAC;AAGnD,SAAgB,mCAAmC,SAAsB;AACvE,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAGF,UAAU;EACV,UAAU;EACV,aAAa;GAAE,cAAc;GAAM,iBAAiB;GAAO,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,YAAY;GAEnB,MAAM,YAAY,EAAE,OAAO,EAAE,gBAAA,MADA,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;;;;AClCJ,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;;;;AChBJ,MAAa,+BAA+B,EAAE,OAAO;CACnD,QAAQ,kCAAkC,SACxC,qJAED;CACD,OAAO,EACJ,QAAQ,CACR,UAAU,CACV,SAAS,mEAAmE;CAC/E,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,4CAA4C;CAChF,MAAM,EAAE,OACL,QAAQ,CACR,IAAI,EAAE,CACN,IAAI,IAAI,CACR,UAAU,CACV,SAAS,8DAA8D;CAC1E,cAAc,EACX,WAAW,iCAAiC,CAC5C,UAAU,CACV,QAAQ,iCAAiC,OAAO,CAChD,SAAS,8CAA8C;CAC3D,CAAC;AAGF,SAAgB,wCAAwC,SAAsB;AAC5E,QAAO,WAAW;EAChB,MAAM;EACN,aACE;EAGF,UAAU;EACV,UAAU;EACV,aAAa;GAAE,cAAc;GAAM,iBAAiB;GAAO,gBAAgB;GAAM;EACjF,WAAW;EACX,SAAS,OAAO,EAAE,QAAQ,OAAO,KAAK,MAAM,mBAAmB;GAC7D,MAAM,iBAAiB,MAAM,sBAAsB,QAAQ,QAAQ;GACnE,MAAM,QAAQ,0BAA0B;IAAE;IAAO;IAAK;IAAM,CAAC;GAc7D,MAAM,SAAQ,MAZN,QAAQ,QAAQ,YACpB,oCACA;IACE,IAAI;IACJ,OAAO;KACL;KACA,OAAO,MAAM;KACb,KAAK,MAAM;KACX,aAAa;KACd;IACF,CACF,EACgB,gCAAgC;AAEnD,UAAO,iBAAiB,MAAM;IAC5B;IACA;IACA,aAAa;IACb,QAAQ;KACN,OAAO,MAAM;KACb,KAAK,MAAM;KACX,YAAY,MAAM;KAClB,UAAU,MAAM;KACjB;IACD;IACA,WAAW,MAAM;IAClB,CAAC;;EAEL,CAAC;;;;ACtEJ,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,OAAM,MAJX,QAAQ,QAAQ,YACjC,uBACA,EAAE,CACH,EACkC,eAAe,eAAe;;EAEpE,CAAC;;;;ACrBJ,MAAa,oBAAoB,EAAE,OAAO;CACxC,OAAO,EACJ,QAAQ,CACR,IAAI,EAAE,CACN,IAAI,IAAI,CACR,UAAU,CACV,QAAQ,GAAG,CACX,SAAS,oEAAoE;CAChF,QAAQ,EACL,QAAQ,CACR,IAAI,EAAE,CACN,UAAU,CACV,QAAQ,EAAE,CACV,SAAS,wDAAwD;CACpE,QAAQ,EACL,WAAW,qBAAqB,CAChC,SAAS,6DAA6D;CACzE,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,wBAAwB;CAChE,kBAAkB,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,mCAAmC;CACrF,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,qBAAqB;CAC1D,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,yBAAyB;CACjE,YAAY,EAAE,WAAW,iBAAiB,CAAC,UAAU,CAAC,SAAS,mBAAmB;CAClF,gBAAgB,EAAE,WAAW,eAAe,CAAC,UAAU,CAAC,SAAS,8BAA8B;CAChG,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,QACA,kBACA,MACA,SACA,YACA,qBACI;GACJ,MAAM,iBAAiB,MAAM,sBAAsB,QAAQ,QAAQ;GAgBnE,MAAM,EAAE,OAAO,gBAAe,MAfX,QAAQ,QAAQ,YAAyC,SAAS;IACnF,OAAO,EAAE,gBAAgB;IACzB,OAAO;IACP;IACA,UAAU;KACR;KACA,GAAI,WAAW,KAAA,IAAY,EAAE,QAAQ,GAAG,EAAE;KAC1C,GAAI,qBAAqB,KAAA,IAAY,EAAE,kBAAkB,GAAG,EAAE;KAC9D,GAAI,OAAO,EAAE,MAAM,GAAG,EAAE;KACxB,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;KAC/B;IACD,GAAI,cAAc,iBACd,EAAE,SAAS,CAAC;KAAE,OAAO;KAAY,WAAW;KAAgB,CAAC,EAAE,GAC/D,EAAE;IACP,CAAC,EACiC;AACnC,UAAO,iBAAiB,OAAO;IAC7B;IACA,aAAa,SAAS,MAAM,SAAS;IACtC,CAAC;;EAEL,CAAC;;;;ACtEJ,MAAa,sBAAsB,EAAE,OAAO;CAC1C,OAAO,EACJ,QAAQ,CACR,IAAI,EAAE,CACN,IAAI,IAAI,CACR,UAAU,CACV,QAAQ,GAAG,CACX,SAAS,uEAAuE;CACnF,QAAQ,EACL,QAAQ,CACR,IAAI,EAAE,CACN,UAAU,CACV,QAAQ,EAAE,CACV,SAAS,wDAAwD;CACpE,QAAQ,EACL,WAAW,qBAAqB,CAChC,SAAS,6DAA6D;CACzE,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,wBAAwB;CAChE,kBAAkB,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,mCAAmC;CACrF,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,qBAAqB;CAC1D,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,yBAAyB;CACjE,YAAY,EAAE,WAAW,mBAAmB,CAAC,UAAU,CAAC,SAAS,mBAAmB;CACpF,gBAAgB,EAAE,WAAW,eAAe,CAAC,UAAU,CAAC,SAAS,8BAA8B;CAChG,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,QACA,kBACA,MACA,SACA,YACA,qBACI;GACJ,MAAM,iBAAiB,MAAM,sBAAsB,QAAQ,QAAQ;GAgBnE,MAAM,EAAE,OAAO,gBAAe,MAfX,QAAQ,QAAQ,YAA2C,YAAY;IACxF,OAAO,EAAE,gBAAgB;IACzB,OAAO;IACP;IACA,UAAU;KACR;KACA,GAAI,WAAW,KAAA,IAAY,EAAE,QAAQ,GAAG,EAAE;KAC1C,GAAI,qBAAqB,KAAA,IAAY,EAAE,kBAAkB,GAAG,EAAE;KAC9D,GAAI,OAAO,EAAE,MAAM,GAAG,EAAE;KACxB,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;KAC/B;IACD,GAAI,cAAc,iBACd,EAAE,SAAS,CAAC;KAAE,OAAO;KAAY,WAAW;KAAgB,CAAC,EAAE,GAC/D,EAAE;IACP,CAAC,EACiC;AACnC,UAAO,iBAAiB,OAAO;IAC7B;IACA,aAAa,SAAS,MAAM,SAAS;IACtC,CAAC;;EAEL,CAAC;;;;AC7EJ,MAAa,qBAAqB,EAAE,OAAO,EACzC,OAAO,EAAE,OACN,QAAQ,CACR,IAAI,EAAE,CACN,IAAI,IAAI,CACR,UAAU,CACV,QAAQ,GAAG,CACX,SAAS,4DAA4D,EACzE,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,gBAAe,MAHX,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;;;;AC7BJ,MAAa,oBAAoB,EAAE,OAAO;CACxC,OAAO,EAAE,OACN,QAAQ,CACR,IAAI,EAAE,CACN,IAAI,IAAI,CACR,UAAU,CACV,QAAQ,GAAG,CACX,SAAS,oEAAoE;CAChF,QAAQ,EAAE,OACP,QAAQ,CACR,IAAI,EAAE,CACN,UAAU,CACV,QAAQ,EAAE,CACV,SAAS,wDAAwD;CACrE,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,WAAU,MAJX,QAAQ,QAAQ,YAA6C,aAAa;IAC3F,OAAO;IACP;IACD,CAAC,EACiC;AACnC,UAAO,iBAAiB,OAAO;IAC7B;IACA,aAAa,SAAS,MAAM,SAAS;IACtC,CAAC;;EAEL,CAAC;;;;ACvCJ,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,GAAG,MAVgB,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,kBAAkB,EACf,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,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,eAAe;CACvD,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,mBAAmB,EAAE,kBAAkB,EAAE,kBAAkB,GAAG,EAAE;IACtE,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,WAAW,KAAA,IAAY,EAAE,QAAQ,EAAE,QAAQ,GAAG,EAAE;IACtD,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,kBAAkB,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,SAAS,yBAAyB;CACnF,aAAa,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,wBAAwB;CACpE,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,2BAA2B;CACnE,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,eAAe;CACvD,QAAQ,EACL,WAAW,qBAAqB,CAChC,UAAU,CACV,SAAS,+CAA+C;CAC5D,CAAC;AAGF,MAAa,wBAAwB,EAAE,OAAO,EAC5C,WAAW,EAAE,MAAM,yBAAyB,CAAC,IAAI,EAAE,CAAC,SAAS,uBAAuB,EACrF,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,gBAAgB;GAChC,MAAM,iBAAiB,MAAM,sBAAsB,QAAQ,QAAQ;GACnE,MAAM,WAA8C,UAAU,KAAK,QAAQ;IACzE,IAAI,GAAG;IACP,GAAI,GAAG,mBAAmB,EAAE,YAAY,GAAG,kBAAkB,GAAG,EAAE;IAClE,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,WAAW,KAAA,IAAY,EAAE,QAAQ,GAAG,QAAQ,GAAG,EAAE;IACxD,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;;;;ACnDJ,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,mCAAmC,QAAQ;EAC3C,uCAAuC,QAAQ;EAC/C,wCAAwC,QAAQ;EAChD,kCAAkC,QAAQ;EAC1C,+BAA+B,QAAQ;EACvC,iCAAiC,QAAQ;EACzC,4BAA4B,QAAQ;EACrC;;;;;AC9BH,MAAa,uBAAuB;CAClC,UAAU;CACV,UAAU;CACV,UAAU;CACV,UAAU;CACV,UAAU;CACV,UAAU;CACX"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transcend-io/mcp-server-consent",
3
- "version": "0.3.5",
3
+ "version": "0.4.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",
@@ -32,9 +32,9 @@
32
32
  "dependencies": {
33
33
  "@modelcontextprotocol/sdk": "^1.29.0",
34
34
  "zod": "^4.3.6",
35
- "@transcend-io/mcp-server-base": "0.4.5",
36
- "@transcend-io/privacy-types": "5.3.1",
37
- "@transcend-io/sdk": "1.2.8"
35
+ "@transcend-io/mcp-server-base": "0.5.0",
36
+ "@transcend-io/privacy-types": "5.3.2",
37
+ "@transcend-io/sdk": "1.2.10"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@arethetypeswrong/cli": "^0.18.2",
@@ -1 +0,0 @@
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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"}