@transcend-io/mcp-server-consent 0.3.6 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -11
- package/dist/cli.mjs +2 -1
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +25 -21
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{tools-bVmFBYcw.mjs → scopes-DF8-jJlM.mjs} +57 -46
- package/dist/scopes-DF8-jJlM.mjs.map +1 -0
- package/package.json +4 -4
- package/dist/tools-bVmFBYcw.mjs.map +0 -1
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
|
|
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
|
|
25
|
-
|
|
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
|
-
"
|
|
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 `
|
|
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
|
|
70
|
-
|
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
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**
|
|
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 {
|
|
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":";;;;
|
|
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
|
-
|
|
71
|
-
|
|
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
|
-
|
|
78
|
+
orderField: z.ZodOptional<z.ZodEnum<{
|
|
75
79
|
Name: "name";
|
|
76
80
|
CreatedAt: "createdAt";
|
|
77
81
|
UpdatedAt: "updatedAt";
|
|
78
82
|
}>>;
|
|
79
|
-
|
|
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
|
-
|
|
92
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
188
|
+
trackingPurposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
185
189
|
description: z.ZodOptional<z.ZodString>;
|
|
186
190
|
service: z.ZodOptional<z.ZodString>;
|
|
187
|
-
|
|
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
|
-
|
|
198
|
+
trackingPurposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
195
199
|
description: z.ZodOptional<z.ZodString>;
|
|
196
200
|
service: z.ZodOptional<z.ZodString>;
|
|
197
|
-
|
|
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
|
-
|
|
210
|
+
trackingPurposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
207
211
|
description: z.ZodOptional<z.ZodString>;
|
|
208
212
|
service: z.ZodOptional<z.ZodString>;
|
|
209
|
-
|
|
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
|
-
|
|
218
|
+
dataFlows: z.ZodArray<z.ZodObject<{
|
|
215
219
|
id: z.ZodString;
|
|
216
|
-
|
|
220
|
+
trackingPurposes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
217
221
|
description: z.ZodOptional<z.ZodString>;
|
|
218
222
|
service: z.ZodOptional<z.ZodString>;
|
|
219
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/tools/index.ts","../src/resolveAirgapBundleId.ts","../src/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;;;;;;;;
|
|
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":";;;;;;iBAiBgB,eAAA,CAAgB,OAAA,EAAS,WAAA,GAAc,cAAA;;;;cCd1C,oBAAA,YAAoB,SAAA,CAAA,kBAAA,EAAA,SAAA,CAAA,0BAAA,EAAA,SAAA,CAAA,oBAAA,EAAA,SAAA,CAAA,4BAAA,EAAA,SAAA,CAAA,YAAA,EAAA,SAAA,CAAA,cAAA;;;;;;;;iBCUX,qBAAA,CAAsB,OAAA,EAAS,oBAAA,GAAuB,OAAA;;;UCb3D,0BAAA;;EAEf,UAAA;;EAEA,QAAA;;EAEA,QAAA;EHW6B;EGT7B,MAAA;AAAA;;;;iBAMc,yBAAA,CAA0B,IAAA;EHG2B,yCGDnE,KAAA;EAEA,GAAA,WFfW;EEiBX,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;;;;;;;;;;;;;;;;;;KAwBlB,gBAAA,GAAmB,CAAA,CAAE,KAAA,QAAa,iBAAA;;;cCxBjC,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;KAwBpB,kBAAA,GAAqB,CAAA,CAAE,KAAA,QAAa,mBAAA;;;cC/BnC,kBAAA,EAAkB,CAAA,CAAA,SAAA;;;KASnB,iBAAA,GAAoB,CAAA,CAAE,KAAA,QAAa,kBAAA;;;cCTlC,iBAAA,EAAiB,CAAA,CAAA,SAAA;;;;KAelB,gBAAA,GAAmB,CAAA,CAAE,KAAA,QAAa,iBAAA;;;cCRjC,uBAAA,EAAuB,CAAA,CAAA,SAAA,KAAA,CAAA,CAAA,IAAA,CAAA,MAAA;AAAA,KACxB,sBAAA,GAAyB,CAAA,CAAE,KAAA,QAAa,uBAAA;;;cCGvC,2BAAA,EAA2B,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;KAsB5B,0BAAA,GAA6B,CAAA,CAAE,KAAA,QAAa,2BAAA;;;cCtB3C,4BAAA,EAA4B,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;KAsB7B,2BAAA,GAA8B,CAAA,CAAE,KAAA,QAAa,4BAAA;;;cC1B5C,sBAAA,EAAsB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;KAwBvB,qBAAA,GAAwB,CAAA,CAAE,KAAA,QAAa,sBAAA;;;cCxBtC,sBAAA,EAAsB,CAAA,CAAA,SAAA;;;;;;;;KAcvB,qBAAA,GAAwB,CAAA,CAAE,KAAA,QAAa,sBAAA;AAAA,cAEtC,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;;;;;;;KAGpB,kBAAA,GAAqB,CAAA,CAAE,KAAA,QAAa,mBAAA;;;cCnBnC,wBAAA,EAAwB,CAAA,CAAA,SAAA;;;;;;;;KAWzB,uBAAA,GAA0B,CAAA,CAAE,KAAA,QAAa,wBAAA;AAAA,cAExC,qBAAA,EAAqB,CAAA,CAAA,SAAA;;;;;;;;;;KAGtB,oBAAA,GAAuB,CAAA,CAAE,KAAA,QAAa,qBAAA;;;cCTrC,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;KAUrB,mBAAA,GAAsB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAEpC,gBAAA,EAAgB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;KAGjB,eAAA,GAAkB,CAAA,CAAE,KAAA,QAAa,gBAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
export { BulkTriageItemSchema, BulkTriageSchema, 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
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
376
|
-
|
|
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
|
-
|
|
380
|
-
|
|
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,
|
|
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
|
-
...
|
|
403
|
-
...
|
|
402
|
+
...isJunk !== void 0 ? { isJunk } : {},
|
|
403
|
+
...showZeroActivity !== void 0 ? { showZeroActivity } : {},
|
|
404
404
|
...text ? { text } : {},
|
|
405
405
|
...service ? { service } : {}
|
|
406
406
|
},
|
|
407
|
-
...
|
|
408
|
-
field:
|
|
409
|
-
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
|
-
|
|
426
|
-
|
|
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
|
-
|
|
430
|
-
|
|
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,
|
|
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
|
-
...
|
|
453
|
-
...
|
|
452
|
+
...isJunk !== void 0 ? { isJunk } : {},
|
|
453
|
+
...showZeroActivity !== void 0 ? { showZeroActivity } : {},
|
|
454
454
|
...text ? { text } : {},
|
|
455
455
|
...service ? { service } : {}
|
|
456
456
|
},
|
|
457
|
-
...
|
|
458
|
-
field:
|
|
459
|
-
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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 (
|
|
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 ({
|
|
640
|
+
handler: async ({ dataFlows }) => {
|
|
641
641
|
const airgapBundleId = await resolveAirgapBundleId(clients.graphql);
|
|
642
|
-
const dfInputs =
|
|
642
|
+
const dfInputs = dataFlows.map((df) => ({
|
|
643
643
|
id: df.id,
|
|
644
|
-
...df.
|
|
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.
|
|
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
|
-
|
|
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=
|
|
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":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transcend-io/mcp-server-consent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
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.
|
|
36
|
-
"@transcend-io/privacy-types": "5.
|
|
37
|
-
"@transcend-io/sdk": "1.2.
|
|
35
|
+
"@transcend-io/mcp-server-base": "0.5.0",
|
|
36
|
+
"@transcend-io/privacy-types": "5.4.0",
|
|
37
|
+
"@transcend-io/sdk": "1.2.11"
|
|
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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"}
|