@cookiemunch/mcp 0.3.0 → 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/CHANGELOG.md +37 -0
- package/LICENSE +21 -0
- package/dist/bin.cjs +383 -203
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +2 -2
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-VP3KZHLC.js → chunk-WGUF6SJH.js} +384 -203
- package/dist/chunk-WGUF6SJH.js.map +1 -0
- package/dist/index.cjs +384 -202
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +3 -1
- package/package.json +16 -8
- package/dist/chunk-VP3KZHLC.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
+
MCP_VERSION: () => MCP_VERSION,
|
|
23
24
|
createCookieMunchMcp: () => createCookieMunchMcp,
|
|
24
25
|
registerTools: () => registerTools
|
|
25
26
|
});
|
|
@@ -28,7 +29,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
28
29
|
var import_sdk = require("@cookiemunch/sdk");
|
|
29
30
|
|
|
30
31
|
// src/tools.ts
|
|
31
|
-
var
|
|
32
|
+
var import_zod5 = require("zod");
|
|
32
33
|
|
|
33
34
|
// src/tools-config.ts
|
|
34
35
|
var import_zod = require("zod");
|
|
@@ -115,7 +116,7 @@ function registerConfigTools(tool, client) {
|
|
|
115
116
|
const setLanguagesSchema = import_zod.z.object({
|
|
116
117
|
cbid: import_zod.z.string().describe("Site identifier (cbid)."),
|
|
117
118
|
defaultCulture: import_zod.z.string().optional().describe('Default locale/culture code, e.g. "en", "fr". Stored in i18n.defaultCulture.'),
|
|
118
|
-
autoDetect: import_zod.z.boolean().optional().describe(
|
|
119
|
+
autoDetect: import_zod.z.union([import_zod.z.boolean(), import_zod.z.literal("page")]).optional().describe(`true: follow the visitor's browser language; false: defaultCulture for everyone; "page": follow the page's <html lang>, then the browser. Stored in i18n.autoDetect.`),
|
|
119
120
|
translations: import_zod.z.record(import_zod.z.record(import_zod.z.unknown())).optional().describe("Per-locale banner copy overrides. Merged onto banner.i18n (locale keys preserved)."),
|
|
120
121
|
overrides: import_zod.z.record(import_zod.z.object({ banner: import_zod.z.record(import_zod.z.string()).optional(), categories: import_zod.z.record(import_zod.z.object({ label: import_zod.z.string().optional(), description: import_zod.z.string().optional() })).optional() })).optional().describe("The site's own copy per language, keyed by tag (de, pt-BR): { banner: { title, body, \u2026 }, categories: { <id>: { label, description } } }. Each language given replaces its entry in i18n.overrides; other languages are kept. Strings the site wrote are shown as written in any language without an override \u2014 stock translations never replace them.")
|
|
121
122
|
});
|
|
@@ -563,12 +564,16 @@ function registerPlatformTools(tool, client) {
|
|
|
563
564
|
"connect_dsar_executor",
|
|
564
565
|
"Connect a system that runs part of a rights request \u2014 an identity platform, a CRM, anything with a rights API. Cookie Munch is not specific to any platform: the `profile` describes that system's API (paths, the words it uses for export/erase, its status vocabulary, how it signs webhooks), so connecting a new one needs no code. The secret key is stored encrypted and never returned; the response carries the webhook URL to configure in that system. Sub-tasks open automatically once a request reaches fulfilment (after identity verification), and completions are picked up by webhook or by polling.",
|
|
565
566
|
{
|
|
566
|
-
|
|
567
|
-
|
|
567
|
+
preset: import_zod2.z.string().optional().describe("Build profile (and, unless the preset takes baseUrl as a param, baseUrl) from a versioned preset instead of sending profile. list_dsar_executor_presets names them, what each needs, and which wait on another platform."),
|
|
568
|
+
presetVersion: import_zod2.z.number().int().optional().describe("With preset: the version to build. Default the latest."),
|
|
569
|
+
orgId: import_zod2.z.string().optional().describe("A preset param, when the preset's params list it."),
|
|
570
|
+
atlasIdAppId: import_zod2.z.string().optional().describe("A preset param, when the preset's params list it: the identity platform's app id, so an erasure also revokes the app's grant."),
|
|
571
|
+
system: import_zod2.z.string().optional().describe("The name this connection answers to in a plan, e.g. identity or crm. Required unless the preset has a default."),
|
|
572
|
+
baseUrl: import_zod2.z.string().optional().describe("The system's public https origin. Required unless the preset sets it."),
|
|
568
573
|
secretKey: import_zod2.z.string().describe("Its API key, with whatever scope that system needs to export and erase a user."),
|
|
569
574
|
webhookSecret: import_zod2.z.string().optional().describe("Signing secret of its webhook endpoint. Optional: polling closes tasks without it."),
|
|
570
575
|
auto: import_zod2.z.boolean().optional().describe("Open a sub-task automatically when a request reaches fulfilment. Default true."),
|
|
571
|
-
profile: import_zod2.z.record(import_zod2.z.unknown()).describe("How to drive that system: { open, poll, statuses } required, plus optional subjectLookup, auth, idempotencyHeader and webhook.
|
|
576
|
+
profile: import_zod2.z.record(import_zod2.z.unknown()).optional().describe("How to drive that system: { open, poll, statuses } required, plus optional subjectLookup, auth, idempotencyHeader, grantRevoke and webhook. Omit it when using preset."),
|
|
572
577
|
dryRun: import_zod2.z.boolean().optional().describe("Validate everything and answer the connection that would be created, storing nothing.")
|
|
573
578
|
},
|
|
574
579
|
(a) => {
|
|
@@ -576,6 +581,28 @@ function registerPlatformTools(tool, client) {
|
|
|
576
581
|
return dryRun === true ? client.fulfillment.dryRunConnectExecutor(input) : client.fulfillment.connectExecutor(input);
|
|
577
582
|
}
|
|
578
583
|
);
|
|
584
|
+
tool(
|
|
585
|
+
"list_dsar_executor_presets",
|
|
586
|
+
"The versioned executor presets: each one's name, params, latest version, and whether it is usable now or waits on another platform's API (waitingOn names the platform and its spec items). Also this org's canary address for connection tests. Read-only.",
|
|
587
|
+
{},
|
|
588
|
+
() => client.fulfillment.executorPresets()
|
|
589
|
+
);
|
|
590
|
+
tool(
|
|
591
|
+
"upgrade_dsar_executor_preset",
|
|
592
|
+
"Rebuild a connection's profile and address from its preset's latest version (or presetVersion), keeping its id, credentials, system and scope \u2014 or adopt a preset on a hand-written connection by naming it. Answers with a diff. Use dryRun first: the answer shows exactly what would change and nothing is stored.",
|
|
593
|
+
{
|
|
594
|
+
id: import_zod2.z.string().describe("The connection id."),
|
|
595
|
+
preset: import_zod2.z.string().optional().describe("Only to adopt a preset on a connection that has none."),
|
|
596
|
+
presetVersion: import_zod2.z.number().int().optional(),
|
|
597
|
+
orgId: import_zod2.z.string().optional(),
|
|
598
|
+
atlasIdAppId: import_zod2.z.string().optional(),
|
|
599
|
+
dryRun: import_zod2.z.boolean().optional().describe("Answer the diff and change nothing.")
|
|
600
|
+
},
|
|
601
|
+
(a) => {
|
|
602
|
+
const { id, dryRun, ...input } = a;
|
|
603
|
+
return dryRun === true ? client.fulfillment.dryRunUpgradeExecutorPreset(id, input) : client.fulfillment.upgradeExecutorPreset(id, input);
|
|
604
|
+
}
|
|
605
|
+
);
|
|
579
606
|
tool(
|
|
580
607
|
"test_dsar_executor_webhook",
|
|
581
608
|
"Would this webhook delivery from a connected system verify? Runs the receiver's exact check (headers, timestamp tolerance, prefix, HMAC) on headers and a raw body you supply, acts on nothing, and returns { verified, stage, reason } naming the stage that failed. `body` must be the raw request body string, byte for byte. Read-only.",
|
|
@@ -609,15 +636,17 @@ function registerPlatformTools(tool, client) {
|
|
|
609
636
|
);
|
|
610
637
|
tool(
|
|
611
638
|
"test_dsar_executor",
|
|
612
|
-
"Try a connected system against one email WITHOUT filing a rights request. Runs its subject lookup and returns the raw upstream answers (credentials removed) and a one-line verdict. The open step is rendered but not sent, unless open is true on an export, which opens and polls a real export once. An erasure is never sent by a test.",
|
|
639
|
+
"Try a connected system against one email (or the org canary, canary: true) WITHOUT filing a rights request. Runs its subject lookup and returns the raw upstream answers (credentials removed) and a one-line verdict; code base_url_redirects means its baseUrl redirects and the verdict names where. The open step is rendered but not sent, unless open is true on an export, which opens and polls a real export once. An erasure is never sent by a test.",
|
|
613
640
|
{
|
|
614
641
|
id: import_zod2.z.string().describe("The connection id."),
|
|
615
|
-
email: import_zod2.z.string().describe("The address to look up."),
|
|
642
|
+
email: import_zod2.z.string().optional().describe("The address to look up. Omit it with canary."),
|
|
643
|
+
canary: import_zod2.z.boolean().optional().describe("Use this org's canary address \u2014 no real person involved. A canary locate also updates the connection's health."),
|
|
616
644
|
operation: import_zod2.z.enum(["locate", "export", "erase"]).optional().describe("Default locate."),
|
|
617
645
|
open: import_zod2.z.boolean().optional().describe("For export only: open a real export and poll it once.")
|
|
618
646
|
},
|
|
619
647
|
(a) => client.fulfillment.testExecutor(a.id, {
|
|
620
|
-
email: a.email,
|
|
648
|
+
...typeof a.email === "string" ? { email: a.email } : {},
|
|
649
|
+
...a.canary === true ? { canary: true } : {},
|
|
621
650
|
...a.operation ? { operation: a.operation } : {},
|
|
622
651
|
...typeof a.open === "boolean" ? { open: a.open } : {}
|
|
623
652
|
})
|
|
@@ -703,31 +732,107 @@ function registerPlatformTools(tool, client) {
|
|
|
703
732
|
);
|
|
704
733
|
}
|
|
705
734
|
|
|
706
|
-
// src/tools-
|
|
735
|
+
// src/tools-integrations.ts
|
|
707
736
|
var import_zod3 = require("zod");
|
|
737
|
+
function registerIntegrationTools(tool, client) {
|
|
738
|
+
const updateSiteSchema = import_zod3.z.object({
|
|
739
|
+
cbid: import_zod3.z.string().describe("Site identifier (cbid)."),
|
|
740
|
+
domain: import_zod3.z.string().optional().describe("New domain, a bare hostname. A move clears verification: verify the new domain afterwards."),
|
|
741
|
+
name: import_zod3.z.string().nullable().optional().describe("Display name data subjects see on the rights page and in notices; null clears it."),
|
|
742
|
+
aliases: import_zod3.z.array(import_zod3.z.string()).optional().describe("Other hosts serving the site (replaces the list; [] clears it). Accepted consent origins, never verified claims."),
|
|
743
|
+
dryRun: import_zod3.z.boolean().optional().describe("Answer with the diff and its effects, storing nothing.")
|
|
744
|
+
});
|
|
745
|
+
tool(
|
|
746
|
+
"update_site",
|
|
747
|
+
"Rename or move a site: its domain, display name and aliases. The cbid and the consent ledger stay. Moving the domain clears verification; the scanner and preview links follow the new domain. Use dryRun first to see the diff and every effect.",
|
|
748
|
+
updateSiteSchema.shape,
|
|
749
|
+
(a) => {
|
|
750
|
+
const { cbid, dryRun, ...patch } = updateSiteSchema.parse(a);
|
|
751
|
+
return client.sites.update(cbid, patch, { dryRun });
|
|
752
|
+
}
|
|
753
|
+
);
|
|
754
|
+
tool(
|
|
755
|
+
"integration_health",
|
|
756
|
+
"Check every link a site\u2019s privacy wiring depends on: the domain, the snippet and CSP on the live page, connected systems (base URL redirects, a test lookup), webhooks, partner links, Atlas cookie_consent, cookies needing review, the rights page, the mail provider and the request SLA. Each row has ok (null = could not check) and a fix hint. Read-only.",
|
|
757
|
+
{ cbid: import_zod3.z.string().optional().describe("Site identifier; optional when the org has one site.") },
|
|
758
|
+
(a) => client.integrationHealth(a.cbid)
|
|
759
|
+
);
|
|
760
|
+
const provisionSchema = import_zod3.z.object({
|
|
761
|
+
product: import_zod3.z.string().describe("A slug naming the product."),
|
|
762
|
+
domain: import_zod3.z.string().describe("The product\u2019s domain (bare hostname)."),
|
|
763
|
+
name: import_zod3.z.string().optional(),
|
|
764
|
+
aliases: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
765
|
+
cbid: import_zod3.z.string().optional().describe("Update this site instead of matching by domain."),
|
|
766
|
+
atlas: import_zod3.z.object({ secretKey: import_zod3.z.string(), cookieConsent: import_zod3.z.boolean().optional(), dsrWebhook: import_zod3.z.boolean().optional(), frontendApiHost: import_zod3.z.string().optional().describe("Your Atlas frontend API host (auth.example.com): declares the Atlas sign-in cookies on the site.") }).optional().describe("Atlas secret key (sk_\u2026) \u2014 used for this call only, never stored or returned."),
|
|
767
|
+
forumulate: import_zod3.z.object({ token: import_zod3.z.string(), orgId: import_zod3.z.string(), consent: import_zod3.z.boolean().optional(), executorKey: import_zod3.z.boolean().optional(), label: import_zod3.z.string().optional() }).optional().describe("Forumulate org token \u2014 used for this call only, never stored or returned."),
|
|
768
|
+
rightsApi: import_zod3.z.object({ baseUrl: import_zod3.z.string(), secretKey: import_zod3.z.string(), profilePreset: import_zod3.z.string().optional() }).optional(),
|
|
769
|
+
dryRun: import_zod3.z.boolean().optional().describe("Report what each step would do; write nothing on any platform. Run this first.")
|
|
770
|
+
});
|
|
771
|
+
tool(
|
|
772
|
+
"provision_product",
|
|
773
|
+
"Wire a product\u2019s privacy in one call: create or update the site, connected systems, the Atlas request-completion webhook and hosted-page consent banner, and Forumulate consent and executor key. Writes across three platforms; run with dryRun first. Idempotent: a re-run answers every step unchanged. No secret appears in the result.",
|
|
774
|
+
provisionSchema.shape,
|
|
775
|
+
(a) => {
|
|
776
|
+
const { dryRun, ...input } = provisionSchema.parse(a);
|
|
777
|
+
return client.provision(input, { dryRun });
|
|
778
|
+
}
|
|
779
|
+
);
|
|
780
|
+
tool(
|
|
781
|
+
"list_site_partners",
|
|
782
|
+
"Which partner platforms (Forumulate, Atlas) receive this site\u2019s consent events, each with its status, and which partners are on offer. Read-only.",
|
|
783
|
+
{ cbid: import_zod3.z.string() },
|
|
784
|
+
(a) => client.sites.listPartners(a.cbid)
|
|
785
|
+
);
|
|
786
|
+
const linkSchema = import_zod3.z.object({
|
|
787
|
+
cbid: import_zod3.z.string(),
|
|
788
|
+
partner: import_zod3.z.enum(["forumulate", "atlas"]),
|
|
789
|
+
externalId: import_zod3.z.string().describe("The partner\u2019s id for the receiving account, e.g. a Forumulate organisation id."),
|
|
790
|
+
label: import_zod3.z.string().optional().describe('Shown with the partner name, e.g. "docs".'),
|
|
791
|
+
events: import_zod3.z.array(import_zod3.z.enum(["consent.recorded", "consent.withdrawn"])).optional(),
|
|
792
|
+
dryRun: import_zod3.z.boolean().optional()
|
|
793
|
+
});
|
|
794
|
+
tool(
|
|
795
|
+
"link_site_partner",
|
|
796
|
+
"Grant a partner platform this site\u2019s consent events (they start flowing out to it). No secret is created: deliveries are signed with Cookie Munch\u2019s own key. Idempotent.",
|
|
797
|
+
linkSchema.shape,
|
|
798
|
+
(a) => {
|
|
799
|
+
const { cbid, dryRun, ...input } = linkSchema.parse(a);
|
|
800
|
+
return client.sites.linkPartner(cbid, input, { dryRun });
|
|
801
|
+
}
|
|
802
|
+
);
|
|
803
|
+
tool(
|
|
804
|
+
"unlink_site_partner",
|
|
805
|
+
"Revoke a partner link: no further consent events go to that partner.",
|
|
806
|
+
{ cbid: import_zod3.z.string(), linkId: import_zod3.z.string() },
|
|
807
|
+
(a) => client.sites.unlinkPartner(a.cbid, a.linkId)
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// src/tools-rights-page.ts
|
|
812
|
+
var import_zod4 = require("zod");
|
|
708
813
|
function registerRightsTools(tool, client) {
|
|
709
|
-
const cbid = { cbid:
|
|
814
|
+
const cbid = { cbid: import_zod4.z.string().describe("Site identifier (cbid). Must belong to your org.") };
|
|
710
815
|
const base = {
|
|
711
|
-
baseUpdatedAt:
|
|
816
|
+
baseUpdatedAt: import_zod4.z.union([import_zod4.z.number().int(), import_zod4.z.string(), import_zod4.z.null()]).optional().describe("The draft\u2019s updatedAt from your last read (null if it had none). If someone saved since, the write is refused with 409 draft_conflict and the current draft; omit to overwrite regardless.")
|
|
712
817
|
};
|
|
713
818
|
const baseOpt = (a) => a.baseUpdatedAt !== void 0 ? { baseUpdatedAt: a.baseUpdatedAt } : {};
|
|
714
819
|
tool("get_rights_page", "Read the site\u2019s rights page DRAFT (the default page until first saved), with warnings that would block publishing.", cbid, (a) => client.rightsPage.get(a.cbid));
|
|
715
820
|
tool(
|
|
716
821
|
"update_rights_page",
|
|
717
822
|
"Replace the rights page draft with a full document (theme, sections, form, i18n, seo, customCss). Nothing goes live until publish_rights_page. Prefer patch_rights_page for small changes and preview_rights_page when unsure. Pass baseUpdatedAt (from get_rights_page) to avoid overwriting someone else\u2019s save: a mismatch is 409 draft_conflict with the current draft.",
|
|
718
|
-
{ ...cbid, page:
|
|
823
|
+
{ ...cbid, page: import_zod4.z.record(import_zod4.z.unknown()).describe("The whole RightsPage document (v: 1)."), ...base },
|
|
719
824
|
(a) => client.rightsPage.put(a.cbid, a.page, baseOpt(a))
|
|
720
825
|
);
|
|
721
826
|
tool(
|
|
722
827
|
"patch_rights_page",
|
|
723
828
|
"Change part of the rights page draft: objects merge, arrays (sections, request types, fields) replace whole, null removes a field. baseUpdatedAt works as on update_rights_page (409 draft_conflict).",
|
|
724
|
-
{ ...cbid, patch:
|
|
829
|
+
{ ...cbid, patch: import_zod4.z.record(import_zod4.z.unknown()), ...base },
|
|
725
830
|
(a) => client.rightsPage.patch(a.cbid, a.patch, baseOpt(a))
|
|
726
831
|
);
|
|
727
832
|
tool(
|
|
728
833
|
"preview_rights_page",
|
|
729
834
|
'Validate a rights-page write WITHOUT saving: returns the document as it would be stored and any publish warnings. mode "patch" (default) or "put".',
|
|
730
|
-
{ ...cbid, page:
|
|
835
|
+
{ ...cbid, page: import_zod4.z.record(import_zod4.z.unknown()), mode: import_zod4.z.enum(["patch", "put"]).optional() },
|
|
731
836
|
(a) => client.rightsPage.dryRun(a.cbid, a.page, { mode: a.mode ?? "patch" })
|
|
732
837
|
);
|
|
733
838
|
tool("get_published_rights_page", "Read the LIVE rights page document (404 not_published while the site shows the default page).", cbid, (a) => client.rightsPage.getPublished(a.cbid));
|
|
@@ -741,14 +846,14 @@ function registerRightsTools(tool, client) {
|
|
|
741
846
|
tool(
|
|
742
847
|
"rollback_rights_page",
|
|
743
848
|
"Publish an earlier version of the rights page again (as a new version): it goes live at once and REPLACES the current draft, so unpublished edits are lost and cannot be recovered (versions hold only published documents). Pass baseUpdatedAt (from get_rights_page) to refuse with 409 draft_conflict if anyone saved the draft since you read it.",
|
|
744
|
-
{ ...cbid, version:
|
|
849
|
+
{ ...cbid, version: import_zod4.z.number().int().min(1), ...base },
|
|
745
850
|
(a) => client.rightsPage.rollback(a.cbid, a.version, baseOpt(a))
|
|
746
851
|
);
|
|
747
852
|
}
|
|
748
853
|
function registerRightsPageTools(tool, client) {
|
|
749
|
-
const site =
|
|
854
|
+
const site = import_zod4.z.object({ cbid: import_zod4.z.string().describe("Site identifier (cbid). Must belong to your org.") });
|
|
750
855
|
const host = site.extend({
|
|
751
|
-
hostname:
|
|
856
|
+
hostname: import_zod4.z.string().describe("The custom hostname, e.g. privacy.example.com (unicode or punycode).")
|
|
752
857
|
});
|
|
753
858
|
tool(
|
|
754
859
|
"list_rights_page_domains",
|
|
@@ -888,10 +993,10 @@ function registerTools(server, client) {
|
|
|
888
993
|
}
|
|
889
994
|
});
|
|
890
995
|
};
|
|
891
|
-
const cbid = { cbid:
|
|
996
|
+
const cbid = { cbid: import_zod5.z.string().describe("Site identifier (cbid). Must belong to your org.") };
|
|
892
997
|
const range = {
|
|
893
|
-
from:
|
|
894
|
-
to:
|
|
998
|
+
from: import_zod5.z.number().optional().describe("Epoch-ms lower bound."),
|
|
999
|
+
to: import_zod5.z.number().optional().describe("Epoch-ms upper bound.")
|
|
895
1000
|
};
|
|
896
1001
|
tool(
|
|
897
1002
|
"whoami",
|
|
@@ -909,19 +1014,19 @@ function registerTools(server, client) {
|
|
|
909
1014
|
tool(
|
|
910
1015
|
"get_site",
|
|
911
1016
|
"One site: its domain, cbid and verification status. Read-only.",
|
|
912
|
-
{ cbid:
|
|
1017
|
+
{ cbid: import_zod5.z.string() },
|
|
913
1018
|
(a) => client.sites.get(a.cbid)
|
|
914
1019
|
);
|
|
915
1020
|
tool(
|
|
916
1021
|
"get_site_banner",
|
|
917
1022
|
"Which banner design a site uses, or bannerId null when none is assigned. Read-only.",
|
|
918
|
-
{ cbid:
|
|
1023
|
+
{ cbid: import_zod5.z.string() },
|
|
919
1024
|
(a) => client.sites.banner(a.cbid)
|
|
920
1025
|
);
|
|
921
1026
|
tool(
|
|
922
1027
|
"get_privacy_policy",
|
|
923
1028
|
"Generate the site's privacy and cookie policy as Markdown, naming the org's data controller. Needs a contact email: the one given, else the org controller's, else the owner's. Read-only \u2014 nothing is published.",
|
|
924
|
-
{ cbid:
|
|
1029
|
+
{ cbid: import_zod5.z.string(), contactEmail: import_zod5.z.string().optional(), effectiveDate: import_zod5.z.string().optional().describe("YYYY-MM-DD; defaults to today."), jurisdictions: import_zod5.z.array(import_zod5.z.string()).optional() },
|
|
925
1030
|
(a) => client.sites.policy(a.cbid, {
|
|
926
1031
|
...a.contactEmail ? { contactEmail: a.contactEmail } : {},
|
|
927
1032
|
...a.effectiveDate ? { effectiveDate: a.effectiveDate } : {},
|
|
@@ -931,7 +1036,7 @@ function registerTools(server, client) {
|
|
|
931
1036
|
tool(
|
|
932
1037
|
"set_ad_personalization",
|
|
933
1038
|
"Add or remove the separate 'personalised ads' choice on the site's live banner. With it on, accepting marketing no longer implies personalised ads unless `default` is true.",
|
|
934
|
-
{ cbid:
|
|
1039
|
+
{ cbid: import_zod5.z.string(), enabled: import_zod5.z.boolean(), default: import_zod5.z.boolean().optional(), label: import_zod5.z.string().optional() },
|
|
935
1040
|
(a) => client.sites.setAdPersonalization(a.cbid, {
|
|
936
1041
|
enabled: a.enabled,
|
|
937
1042
|
...a.default !== void 0 ? { default: a.default } : {},
|
|
@@ -942,11 +1047,11 @@ function registerTools(server, client) {
|
|
|
942
1047
|
"analyze_session",
|
|
943
1048
|
"Analyse a captured browsing session against the consent it ran under: which trackers fired after the visitor opted out, and what personal data left the page. Read-only.",
|
|
944
1049
|
{
|
|
945
|
-
cbid:
|
|
946
|
-
har:
|
|
947
|
-
requests:
|
|
948
|
-
consent:
|
|
949
|
-
gpc:
|
|
1050
|
+
cbid: import_zod5.z.string(),
|
|
1051
|
+
har: import_zod5.z.unknown().optional().describe("A HAR export of the session."),
|
|
1052
|
+
requests: import_zod5.z.array(import_zod5.z.unknown()).optional().describe("Or the requests directly."),
|
|
1053
|
+
consent: import_zod5.z.record(import_zod5.z.string(), import_zod5.z.boolean()).optional(),
|
|
1054
|
+
gpc: import_zod5.z.boolean().optional()
|
|
950
1055
|
},
|
|
951
1056
|
(a) => client.sites.analyzeSession(a.cbid, {
|
|
952
1057
|
...a.har !== void 0 ? { har: a.har } : {},
|
|
@@ -958,14 +1063,14 @@ function registerTools(server, client) {
|
|
|
958
1063
|
tool(
|
|
959
1064
|
"create_site",
|
|
960
1065
|
"Create a new site. The cbid is auto-generated if you omit it.",
|
|
961
|
-
{ domain:
|
|
1066
|
+
{ domain: import_zod5.z.string().describe("The site domain, e.g. example.com."), cbid: import_zod5.z.string().optional().describe("Optional explicit cbid.") },
|
|
962
1067
|
(a) => client.sites.create({ domain: a.domain, ...typeof a.cbid === "string" ? { cbid: a.cbid } : {} })
|
|
963
1068
|
);
|
|
964
1069
|
tool(
|
|
965
1070
|
"create_sites_bulk",
|
|
966
1071
|
"Create up to 100 sites in one call. Partial success: each item reports ok or its own error, and a bad or duplicate item fails only itself.",
|
|
967
1072
|
{
|
|
968
|
-
sites:
|
|
1073
|
+
sites: import_zod5.z.array(import_zod5.z.object({ domain: import_zod5.z.string(), cbid: import_zod5.z.string().optional(), platform: import_zod5.z.string().optional() })).min(1).max(100)
|
|
969
1074
|
},
|
|
970
1075
|
(a) => client.sites.createBulk(a.sites)
|
|
971
1076
|
);
|
|
@@ -975,15 +1080,15 @@ function registerTools(server, client) {
|
|
|
975
1080
|
"Replace (overwrite) the banner/consent configuration for a site via PUT. This is destructive, not a merge: any top-level SiteConfig field you omit from `config` reverts to its default rather than keeping its current value \u2014 unless keepUnspecified is true, in which case omitted top-level fields keep their stored value and only the fields you send are replaced (each whole). A top-level field sent as null reverts to its default. To change one setting, use patch_site_config instead \u2014 it merges server-side. Prefer the narrower set_* tools (set_blocking, set_banner_basics, etc.) when they cover your change.",
|
|
976
1081
|
{
|
|
977
1082
|
...cbid,
|
|
978
|
-
config:
|
|
979
|
-
keepUnspecified:
|
|
1083
|
+
config: import_zod5.z.record(import_zod5.z.unknown()).describe("The full SiteConfig to write, not a patch. Without keepUnspecified, omitted top-level fields are NOT preserved from the current config."),
|
|
1084
|
+
keepUnspecified: import_zod5.z.boolean().optional().describe("PUT ?keep=unspecified: keep the stored value of every top-level field `config` omits, instead of reverting it to its default.")
|
|
980
1085
|
},
|
|
981
1086
|
(a) => a.keepUnspecified === true ? client.sites.putConfig(a.cbid, a.config, { keep: "unspecified" }) : client.sites.putConfig(a.cbid, a.config)
|
|
982
1087
|
);
|
|
983
1088
|
tool(
|
|
984
1089
|
"patch_site_config",
|
|
985
1090
|
`Change part of a site's banner/consent configuration. The patch is a JSON Merge Patch (RFC 7386) over the stored config server-side: any field you omit keeps its current value, and a field set to null is REMOVED (it falls back to its default) \u2014 e.g. { "banner": { "i18n": { "es": null } } } drops the Spanish override. This is the safe way to flip one setting, and it needs no read-modify-write. Use update_site_config only when you genuinely mean to replace the whole document.`,
|
|
986
|
-
{ ...cbid, config:
|
|
1091
|
+
{ ...cbid, config: import_zod5.z.record(import_zod5.z.unknown()).describe('The subset of SiteConfig to change, e.g. { "banner": { "showRightsLink": true } }. Everything else is preserved; null removes a field.') },
|
|
987
1092
|
(a) => client.sites.patchConfig(a.cbid, a.config)
|
|
988
1093
|
);
|
|
989
1094
|
tool(
|
|
@@ -991,9 +1096,9 @@ function registerTools(server, client) {
|
|
|
991
1096
|
'Preview a config change WITHOUT saving it: returns the config as it would be saved, a diff of every field that would change, and any warnings (plan-gated or unrecognised fields). mode "patch" (default) previews patch_site_config; mode "put" previews update_site_config, and its diff lists everything a replace would revert to its default (unless keepUnspecified is true). Use it before any write you are not sure of.',
|
|
992
1097
|
{
|
|
993
1098
|
...cbid,
|
|
994
|
-
config:
|
|
995
|
-
mode:
|
|
996
|
-
keepUnspecified:
|
|
1099
|
+
config: import_zod5.z.record(import_zod5.z.unknown()).describe('The patch (or, with mode "put", the full config) to preview.'),
|
|
1100
|
+
mode: import_zod5.z.enum(["patch", "put"]).optional().describe("patch (default) merges; put replaces."),
|
|
1101
|
+
keepUnspecified: import_zod5.z.boolean().optional().describe('With mode "put": preview update_site_config with keepUnspecified (omitted top-level fields keep their stored value).')
|
|
997
1102
|
},
|
|
998
1103
|
(a) => client.sites.dryRunConfig(a.cbid, a.config, {
|
|
999
1104
|
mode: a.mode ?? "patch",
|
|
@@ -1005,8 +1110,8 @@ function registerTools(server, client) {
|
|
|
1005
1110
|
'Check a banner config for consent-button parity WITHOUT saving it: is "Accept all" more prominent than "Reject all" anywhere \u2014 a brighter or more saturated colour, a bigger or bolder button, Reject styled as a link, hidden, below the fold, set apart, missing from the first layer, or worded to guilt-trip? Regulators (EDPB, CNIL) treat that as a dark pattern. Returns findings, a 0\u2013100 score and the reject style that would match Accept. It checks exactly what the write would store: merged over the stored config as patch_site_config would, or with replace: true replaced as update_site_config would. Run it before writing any banner design.',
|
|
1006
1111
|
{
|
|
1007
1112
|
...cbid,
|
|
1008
|
-
config:
|
|
1009
|
-
replace:
|
|
1113
|
+
config: import_zod5.z.record(import_zod5.z.unknown()).describe("The proposed SiteConfig (or a partial one, or a v2 flow design)."),
|
|
1114
|
+
replace: import_zod5.z.boolean().optional().describe("Check what update_site_config (a full replace) would store, instead of what patch_site_config (a merge) would.")
|
|
1010
1115
|
},
|
|
1011
1116
|
async (a) => {
|
|
1012
1117
|
const r = await client.sites.lintConfig(a.cbid, a.config, a.replace === true ? { replace: true } : {});
|
|
@@ -1030,7 +1135,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1030
1135
|
tool(
|
|
1031
1136
|
"get_consent_log",
|
|
1032
1137
|
"Get recent anonymised consent records for a site.",
|
|
1033
|
-
{ ...cbid, ...range, limit:
|
|
1138
|
+
{ ...cbid, ...range, limit: import_zod5.z.number().optional().describe("Max records to return (default 200).") },
|
|
1034
1139
|
(a) => client.consent.log(a.cbid, {
|
|
1035
1140
|
from: a.from,
|
|
1036
1141
|
to: a.to,
|
|
@@ -1040,7 +1145,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1040
1145
|
tool(
|
|
1041
1146
|
"get_subject_consent",
|
|
1042
1147
|
"One person's consent records across every site in the org \u2014 web, mobile and desktop \u2014 by the subjectId your apps attach. Consent data: needs the consent:read scope. Read-only.",
|
|
1043
|
-
{ subjectId:
|
|
1148
|
+
{ subjectId: import_zod5.z.string() },
|
|
1044
1149
|
(a) => client.subjects.consent(a.subjectId)
|
|
1045
1150
|
);
|
|
1046
1151
|
tool("list_dsar", "List all Data Subject Access Requests for your organization.", {}, () => client.dsar.list());
|
|
@@ -1048,51 +1153,53 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1048
1153
|
"update_dsar_executor",
|
|
1049
1154
|
"Change a connected system in place \u2014 its profile, address, credential or auto flag. Only what you pass changes; the stored credential is kept unless you give a new one. With dryRun, answers the connection as it would be and a diff, and changes nothing.",
|
|
1050
1155
|
{
|
|
1051
|
-
id:
|
|
1052
|
-
patch:
|
|
1053
|
-
dryRun:
|
|
1156
|
+
id: import_zod5.z.string(),
|
|
1157
|
+
patch: import_zod5.z.record(import_zod5.z.unknown()),
|
|
1158
|
+
dryRun: import_zod5.z.boolean().optional().describe("Validate and diff without saving.")
|
|
1054
1159
|
},
|
|
1055
1160
|
(a) => a.dryRun === true ? client.fulfillment.dryRunUpdateExecutor(a.id, a.patch) : client.fulfillment.updateExecutor(a.id, a.patch)
|
|
1056
1161
|
);
|
|
1057
1162
|
tool(
|
|
1058
1163
|
"get_dsar",
|
|
1059
1164
|
"One rights request by id, including its status and the deadline it must be answered by.",
|
|
1060
|
-
{ id:
|
|
1165
|
+
{ id: import_zod5.z.string() },
|
|
1061
1166
|
(a) => client.dsar.get(a.id)
|
|
1062
1167
|
);
|
|
1063
1168
|
tool(
|
|
1064
1169
|
"erase_dsar_subject",
|
|
1065
1170
|
"For a deletion request that is past identity verification: erase the person\u2019s consent records on one site, identified by their consent stamp. Irreversible. The erasure is noted on the request. If the response carries a warning, nothing was cryptographically erased \u2014 tell the user.",
|
|
1066
|
-
{ id:
|
|
1171
|
+
{ id: import_zod5.z.string(), cbid: import_zod5.z.string(), stamp: import_zod5.z.string() },
|
|
1067
1172
|
(a) => client.dsar.erase(a.id, a.cbid, a.stamp)
|
|
1068
1173
|
);
|
|
1069
1174
|
tool(
|
|
1070
1175
|
"export_dsar_subject",
|
|
1071
1176
|
"For an access or portability request that is past identity verification: the person\u2019s consent records on one site, identified by their consent stamp. The export is noted on the request.",
|
|
1072
|
-
{ id:
|
|
1177
|
+
{ id: import_zod5.z.string(), cbid: import_zod5.z.string(), stamp: import_zod5.z.string() },
|
|
1073
1178
|
(a) => client.dsar.export(a.id, a.cbid, a.stamp)
|
|
1074
1179
|
);
|
|
1075
1180
|
tool(
|
|
1076
1181
|
"get_dsar_response_notice",
|
|
1077
1182
|
"The subject-facing response notice for a request, as plain text \u2014 what to send the person. Read-only; nothing is sent.",
|
|
1078
|
-
{ id:
|
|
1183
|
+
{ id: import_zod5.z.string() },
|
|
1079
1184
|
(a) => client.dsar.response(a.id)
|
|
1080
1185
|
);
|
|
1081
1186
|
tool(
|
|
1082
1187
|
"create_dsar",
|
|
1083
1188
|
"Open a new Data Subject Access Request.",
|
|
1084
1189
|
{
|
|
1085
|
-
type:
|
|
1086
|
-
subjectEmail:
|
|
1087
|
-
regulation:
|
|
1088
|
-
note:
|
|
1089
|
-
|
|
1190
|
+
type: import_zod5.z.enum(["access", "deletion", "rectification", "portability", "opt-out"]).describe("DSAR right being exercised."),
|
|
1191
|
+
subjectEmail: import_zod5.z.string().describe("The data subject\u2019s email."),
|
|
1192
|
+
regulation: import_zod5.z.enum(["gdpr", "ccpa"]).describe("Governing regulation."),
|
|
1193
|
+
note: import_zod5.z.string().optional().describe("Optional INTERNAL note; never shown to the data subject."),
|
|
1194
|
+
messageToSubject: import_zod5.z.string().max(2e3).optional().describe("The line the data subject reads in the response notice. Never an API key."),
|
|
1195
|
+
test: import_zod5.z.boolean().optional().describe("Mark it as a test request: kept off the SLA board and deletable afterwards with delete_test_dsar.")
|
|
1090
1196
|
},
|
|
1091
1197
|
(a) => client.dsar.create({
|
|
1092
1198
|
type: a.type,
|
|
1093
1199
|
subjectEmail: a.subjectEmail,
|
|
1094
1200
|
regulation: a.regulation,
|
|
1095
1201
|
...typeof a.note === "string" ? { note: a.note } : {},
|
|
1202
|
+
...typeof a.messageToSubject === "string" ? { messageToSubject: a.messageToSubject } : {},
|
|
1096
1203
|
...a.test === true ? { test: true } : {}
|
|
1097
1204
|
})
|
|
1098
1205
|
);
|
|
@@ -1100,11 +1207,11 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1100
1207
|
"create_rights_link",
|
|
1101
1208
|
"Mint a signed, single-use link to a site\u2019s hosted rights page for a person you know is signed in to that site. On the page their email is filled in and locked and the email-code step is skipped; the filed request is recorded as verified by their account. Give the link only to that person. Expires in 15 minutes by default (max 1 hour). Needs dsar:write.",
|
|
1102
1209
|
{
|
|
1103
|
-
cbid:
|
|
1104
|
-
email:
|
|
1105
|
-
userId:
|
|
1106
|
-
rights:
|
|
1107
|
-
ttlSeconds:
|
|
1210
|
+
cbid: import_zod5.z.string().describe("Site identifier (cbid). Must belong to your org."),
|
|
1211
|
+
email: import_zod5.z.string().describe("The signed-in person\u2019s verified email address."),
|
|
1212
|
+
userId: import_zod5.z.string().optional().describe("Your own account id for them; recorded on the request."),
|
|
1213
|
+
rights: import_zod5.z.array(import_zod5.z.enum(["access", "erasure", "rectification", "portability", "restriction", "objection", "opt_out_sale", "opt_out_targeted", "limit_sensitive"])).min(1).optional().describe("Limit the link to these rights. Default: every right the page offers."),
|
|
1214
|
+
ttlSeconds: import_zod5.z.number().int().min(60).max(3600).optional().describe("How long the link works, in seconds (default 900).")
|
|
1108
1215
|
},
|
|
1109
1216
|
(a) => client.rightsLinks.create(a.cbid, {
|
|
1110
1217
|
subject: { email: a.email, ...typeof a.userId === "string" ? { userId: a.userId } : {} },
|
|
@@ -1115,7 +1222,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1115
1222
|
tool(
|
|
1116
1223
|
"delete_test_dsar",
|
|
1117
1224
|
"Delete a TEST rights request (one created with test: true), with its tasks and their upstream log. Real requests cannot be deleted and are refused. The deletion is recorded in the audit log.",
|
|
1118
|
-
{ id:
|
|
1225
|
+
{ id: import_zod5.z.string().describe("The test request id.") },
|
|
1119
1226
|
async (a) => {
|
|
1120
1227
|
await client.dsar.delete(a.id);
|
|
1121
1228
|
return { deleted: a.id };
|
|
@@ -1124,17 +1231,18 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1124
1231
|
tool(
|
|
1125
1232
|
"mark_dsar_test",
|
|
1126
1233
|
"Mark a CLOSED rights request (completed or rejected) as a test request, after the fact \u2014 for trial requests filed before test: true existed. An open request is refused (request_not_closed), so a live obligation can never be relabelled. Recorded in the audit log; afterwards delete_test_dsar can remove it. Returns { request, changed }.",
|
|
1127
|
-
{ id:
|
|
1234
|
+
{ id: import_zod5.z.string().describe("The closed request id.") },
|
|
1128
1235
|
(a) => client.dsar.markTest(a.id)
|
|
1129
1236
|
);
|
|
1130
1237
|
tool(
|
|
1131
1238
|
"advance_dsar",
|
|
1132
1239
|
"Advance a DSAR to a new status (received \u2192 verifying \u2192 in_progress \u2192 completed, or rejected).",
|
|
1133
1240
|
{
|
|
1134
|
-
id:
|
|
1135
|
-
toStatus:
|
|
1241
|
+
id: import_zod5.z.string().describe("The DSAR id."),
|
|
1242
|
+
toStatus: import_zod5.z.enum(["received", "verifying", "in_progress", "completed", "rejected"]).describe("Target status."),
|
|
1243
|
+
messageToSubject: import_zod5.z.string().max(2e3).optional().describe("Replaces the line the data subject reads in the notice \u2014 for a rejection, why.")
|
|
1136
1244
|
},
|
|
1137
|
-
(a) => client.dsar.advance(a.id, a.toStatus)
|
|
1245
|
+
(a) => typeof a.messageToSubject === "string" ? client.dsar.advance(a.id, a.toStatus, { messageToSubject: a.messageToSubject }) : client.dsar.advance(a.id, a.toStatus)
|
|
1138
1246
|
);
|
|
1139
1247
|
tool(
|
|
1140
1248
|
"export_consent",
|
|
@@ -1145,7 +1253,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1145
1253
|
tool(
|
|
1146
1254
|
"get_receipt",
|
|
1147
1255
|
"Fetch the signed consent receipt for a single consent record (by stamp).",
|
|
1148
|
-
{ ...cbid, stamp:
|
|
1256
|
+
{ ...cbid, stamp: import_zod5.z.string().describe("The consent record stamp/id.") },
|
|
1149
1257
|
(a) => client.consent.receipt(a.cbid, a.stamp)
|
|
1150
1258
|
);
|
|
1151
1259
|
tool("delete_site", "Delete a site (cbid) and its configuration from your org.", { ...cbid }, async (a) => {
|
|
@@ -1157,13 +1265,13 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1157
1265
|
"create_vendor",
|
|
1158
1266
|
"Register a vendor (processor) and compute its risk score.",
|
|
1159
1267
|
{
|
|
1160
|
-
name:
|
|
1161
|
-
category:
|
|
1162
|
-
dataShared:
|
|
1163
|
-
dpaSigned:
|
|
1164
|
-
subprocessors:
|
|
1165
|
-
certifications:
|
|
1166
|
-
region:
|
|
1268
|
+
name: import_zod5.z.string().describe("Vendor name."),
|
|
1269
|
+
category: import_zod5.z.string().describe("Vendor category, e.g. analytics."),
|
|
1270
|
+
dataShared: import_zod5.z.array(import_zod5.z.string()).describe("Categories of data shared with the vendor."),
|
|
1271
|
+
dpaSigned: import_zod5.z.boolean().describe("Whether a Data Processing Agreement is signed."),
|
|
1272
|
+
subprocessors: import_zod5.z.number().describe("Number of subprocessors."),
|
|
1273
|
+
certifications: import_zod5.z.array(import_zod5.z.string()).describe("Compliance certifications, e.g. ISO27001."),
|
|
1274
|
+
region: import_zod5.z.string().describe("Primary processing region, e.g. EU.")
|
|
1167
1275
|
},
|
|
1168
1276
|
(a) => client.vendors.create({
|
|
1169
1277
|
name: a.name,
|
|
@@ -1181,13 +1289,13 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1181
1289
|
"create_ropa",
|
|
1182
1290
|
"Create a Record of Processing Activity (RoPA) entry.",
|
|
1183
1291
|
{
|
|
1184
|
-
name:
|
|
1185
|
-
purpose:
|
|
1186
|
-
legalBasis:
|
|
1187
|
-
dataCategories:
|
|
1188
|
-
recipients:
|
|
1189
|
-
retentionDays:
|
|
1190
|
-
crossBorderTransfer:
|
|
1292
|
+
name: import_zod5.z.string().describe("Activity name."),
|
|
1293
|
+
purpose: import_zod5.z.string().describe("Purpose of processing."),
|
|
1294
|
+
legalBasis: import_zod5.z.enum(["consent", "contract", "legal-obligation", "vital-interests", "public-task", "legitimate-interests"]).describe("GDPR legal basis."),
|
|
1295
|
+
dataCategories: import_zod5.z.array(import_zod5.z.string()).describe("Categories of personal data."),
|
|
1296
|
+
recipients: import_zod5.z.array(import_zod5.z.string()).describe("Recipients of the data."),
|
|
1297
|
+
retentionDays: import_zod5.z.number().describe("Retention period in days."),
|
|
1298
|
+
crossBorderTransfer: import_zod5.z.boolean().describe("Whether data is transferred across borders.")
|
|
1191
1299
|
},
|
|
1192
1300
|
(a) => client.ropa.create({
|
|
1193
1301
|
name: a.name,
|
|
@@ -1208,7 +1316,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1208
1316
|
tool(
|
|
1209
1317
|
"scan_site",
|
|
1210
1318
|
"Trigger a cookie crawl of a site (at most 90 s). Returns its scanId and state (queued). With wait: true, returns once it is done or failed \u2014 state, cookieCount, pagesVisited, durationMs, error. The stored list keeps cookies earlier crawls and real visits found; retire one the site no longer sets.",
|
|
1211
|
-
{ ...cbid, wait:
|
|
1319
|
+
{ ...cbid, wait: import_zod5.z.boolean().optional().describe("Wait for the scan to finish (up to 100 s) and return its outcome.") },
|
|
1212
1320
|
async (a) => {
|
|
1213
1321
|
let started;
|
|
1214
1322
|
try {
|
|
@@ -1222,7 +1330,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1222
1330
|
tool(
|
|
1223
1331
|
"get_scan_status",
|
|
1224
1332
|
"Get a site\u2019s last cookie scan: state (queued, scanning, done, failed), scanId, durationMs, cookieCount, pagesVisited and error when it failed.",
|
|
1225
|
-
{ ...cbid, wait:
|
|
1333
|
+
{ ...cbid, wait: import_zod5.z.number().min(0).max(60).optional().describe("Seconds (\u226460) to wait for a running scan to settle before answering.") },
|
|
1226
1334
|
(a) => a.wait !== void 0 ? client.sites.scanStatus(a.cbid, { wait: a.wait }) : client.sites.scanStatus(a.cbid)
|
|
1227
1335
|
);
|
|
1228
1336
|
tool(
|
|
@@ -1234,16 +1342,25 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1234
1342
|
tool("list_brand_kits", "List reusable brand kits (colors/logo/typography) for your org.", {}, () => client.brandKits.list());
|
|
1235
1343
|
tool("list_preferences", "List configurable consent preferences/purposes for your org.", {}, () => client.preferences.list());
|
|
1236
1344
|
tool("list_members", "List the members of your organization.", {}, () => client.members.list());
|
|
1237
|
-
tool("list_api_keys", "List the API keys for your organization (secrets are not returned).", {}, () => client.keys.list());
|
|
1345
|
+
tool("list_api_keys", "List the API keys for your organization (secrets are not returned), with each key\u2019s scopes, expiry and when it was last used.", {}, () => client.keys.list());
|
|
1346
|
+
tool(
|
|
1347
|
+
"api_key_report",
|
|
1348
|
+
"Key hygiene: keys not used for a while, keys with broad (full or wide write) access, and keys expiring soon, each with the reason. Read-only.",
|
|
1349
|
+
{
|
|
1350
|
+
unusedDays: import_zod5.z.number().int().min(1).max(3650).optional().describe("Unused for at least this many days (default 90)."),
|
|
1351
|
+
expiringDays: import_zod5.z.number().int().min(1).max(3650).optional().describe("Expiring within this many days (default 14).")
|
|
1352
|
+
},
|
|
1353
|
+
(a) => client.keys.report({ ...a.unusedDays !== void 0 ? { unusedDays: a.unusedDays } : {}, ...a.expiringDays !== void 0 ? { expiringDays: a.expiringDays } : {} })
|
|
1354
|
+
);
|
|
1238
1355
|
tool("get_usage", "Get the current usage/quota summary for your organization.", {}, () => client.usage());
|
|
1239
1356
|
tool("list_webhooks", "List webhook subscriptions for your organization.", {}, () => client.webhooks.list());
|
|
1240
1357
|
tool(
|
|
1241
1358
|
"create_webhook",
|
|
1242
1359
|
"Create a webhook subscription. The response includes the signing secret (shown once).",
|
|
1243
1360
|
{
|
|
1244
|
-
url:
|
|
1245
|
-
events:
|
|
1246
|
-
cbid:
|
|
1361
|
+
url: import_zod5.z.string().describe("HTTPS endpoint to deliver events to."),
|
|
1362
|
+
events: import_zod5.z.array(import_zod5.z.string()).describe("Event names to subscribe to, e.g. consent.created."),
|
|
1363
|
+
cbid: import_zod5.z.string().optional().describe("Optional site cbid to scope the subscription to.")
|
|
1247
1364
|
},
|
|
1248
1365
|
(a) => client.webhooks.create({
|
|
1249
1366
|
url: a.url,
|
|
@@ -1254,13 +1371,13 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1254
1371
|
tool(
|
|
1255
1372
|
"roll_webhook_secret",
|
|
1256
1373
|
"Rotate a webhook subscription\u2019s signing secret. The new secret is returned once; the receiving endpoint must be updated to verify with it.",
|
|
1257
|
-
{ id:
|
|
1374
|
+
{ id: import_zod5.z.string() },
|
|
1258
1375
|
(a) => client.webhooks.rollSecret(a.id)
|
|
1259
1376
|
);
|
|
1260
1377
|
tool(
|
|
1261
1378
|
"test_webhook",
|
|
1262
1379
|
"Send a signed test event to a webhook subscription now, and report what the endpoint answered.",
|
|
1263
|
-
{ id:
|
|
1380
|
+
{ id: import_zod5.z.string() },
|
|
1264
1381
|
(a) => client.webhooks.test(a.id)
|
|
1265
1382
|
);
|
|
1266
1383
|
tool(
|
|
@@ -1272,18 +1389,18 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1272
1389
|
tool(
|
|
1273
1390
|
"replay_webhook_dead_letter",
|
|
1274
1391
|
"Deliver a dead-lettered webhook event again, to the subscription as it is now.",
|
|
1275
|
-
{ id:
|
|
1392
|
+
{ id: import_zod5.z.string() },
|
|
1276
1393
|
(a) => client.webhooks.replayDeadLetter(a.id)
|
|
1277
1394
|
);
|
|
1278
1395
|
tool(
|
|
1279
1396
|
"update_webhook",
|
|
1280
1397
|
"Change a webhook subscription, or pause it with active:false (delivery stops; the subscription is kept). Only the fields given change. cbid: null widens it to every property in the org.",
|
|
1281
1398
|
{
|
|
1282
|
-
id:
|
|
1283
|
-
url:
|
|
1284
|
-
events:
|
|
1285
|
-
cbid:
|
|
1286
|
-
active:
|
|
1399
|
+
id: import_zod5.z.string(),
|
|
1400
|
+
url: import_zod5.z.string().optional(),
|
|
1401
|
+
events: import_zod5.z.array(import_zod5.z.string()).optional(),
|
|
1402
|
+
cbid: import_zod5.z.string().nullable().optional(),
|
|
1403
|
+
active: import_zod5.z.boolean().optional()
|
|
1287
1404
|
},
|
|
1288
1405
|
(a) => client.webhooks.update(a.id, {
|
|
1289
1406
|
...a.url !== void 0 ? { url: a.url } : {},
|
|
@@ -1292,20 +1409,20 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1292
1409
|
...a.active !== void 0 ? { active: a.active } : {}
|
|
1293
1410
|
})
|
|
1294
1411
|
);
|
|
1295
|
-
tool("delete_webhook", "Delete a webhook subscription by id.", { id:
|
|
1412
|
+
tool("delete_webhook", "Delete a webhook subscription by id.", { id: import_zod5.z.string().describe("The webhook subscription id.") }, async (a) => {
|
|
1296
1413
|
await client.webhooks.delete(a.id);
|
|
1297
1414
|
return { ok: true };
|
|
1298
1415
|
});
|
|
1299
1416
|
tool(
|
|
1300
1417
|
"verify_site",
|
|
1301
1418
|
"Verify that your organization controls a domain by one of three challenge methods (dns / meta / file). Required to unlock consent export and signed receipts.",
|
|
1302
|
-
{ ...cbid, method:
|
|
1419
|
+
{ ...cbid, method: import_zod5.z.enum(["dns", "meta", "file"]).describe("Challenge method: dns (TXT record), meta (HTML tag), or file (/.well-known/cookiemunch-verify.txt).") },
|
|
1303
1420
|
(a) => client.sites.verify(a.cbid, a.method)
|
|
1304
1421
|
);
|
|
1305
1422
|
tool(
|
|
1306
1423
|
"get_verification_challenge",
|
|
1307
1424
|
"Exactly what to publish to prove control of a site\u2019s domain: the DNS TXT record, the meta tag, the file, or installing the embed. Read-only \u2014 publish one, then call verify_site.",
|
|
1308
|
-
{ cbid:
|
|
1425
|
+
{ cbid: import_zod5.z.string() },
|
|
1309
1426
|
(a) => client.sites.verifyChallenge(a.cbid)
|
|
1310
1427
|
);
|
|
1311
1428
|
tool(
|
|
@@ -1317,15 +1434,15 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1317
1434
|
tool(
|
|
1318
1435
|
"get_flow",
|
|
1319
1436
|
"Get the v2 banner flow config for a site, including current views, categories, and any lint issues.",
|
|
1320
|
-
{ cbid:
|
|
1437
|
+
{ cbid: import_zod5.z.string().describe("Site identifier (cbid).") },
|
|
1321
1438
|
(a) => client.sites.getFlow(a.cbid)
|
|
1322
1439
|
);
|
|
1323
1440
|
tool(
|
|
1324
1441
|
"edit_flow",
|
|
1325
1442
|
"Apply a batch of structured edit operations to a site's v2 banner flow. All ops are validated server-side and the final config must be lint-clean before it is saved.",
|
|
1326
1443
|
{
|
|
1327
|
-
cbid:
|
|
1328
|
-
operations:
|
|
1444
|
+
cbid: import_zod5.z.string().describe("Site identifier (cbid)."),
|
|
1445
|
+
operations: import_zod5.z.array(import_zod5.z.record(import_zod5.z.unknown())).describe(
|
|
1329
1446
|
'Ordered list of ops. Each must have an "op" field: addView | removeView | addElement | setButtonTransition | addCustomCategory.'
|
|
1330
1447
|
)
|
|
1331
1448
|
},
|
|
@@ -1335,21 +1452,22 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1335
1452
|
"set_flow",
|
|
1336
1453
|
"Wholesale replace a site's v2 banner flow with a complete config (e.g. from a template). Validated server-side before it is saved.",
|
|
1337
1454
|
{
|
|
1338
|
-
cbid:
|
|
1339
|
-
config:
|
|
1455
|
+
cbid: import_zod5.z.string().describe("Site identifier (cbid)."),
|
|
1456
|
+
config: import_zod5.z.record(import_zod5.z.unknown()).describe("A full v2 FlowConfig object ({ v:2, flow, categories, ... }).")
|
|
1340
1457
|
},
|
|
1341
1458
|
(a) => client.sites.setFlow(a.cbid, a.config)
|
|
1342
1459
|
);
|
|
1343
1460
|
registerConfigTools(tool, client);
|
|
1344
1461
|
registerPlatformTools(tool, client);
|
|
1462
|
+
registerIntegrationTools(tool, client);
|
|
1345
1463
|
registerRightsTools(tool, client);
|
|
1346
1464
|
registerRightsPageTools(tool, client);
|
|
1347
1465
|
tool(
|
|
1348
1466
|
"invite_member",
|
|
1349
1467
|
"Invite a person to your organization by email. role must be admin, member, or viewer. The org is derived from the API key \u2014 you cannot invite into a different org.",
|
|
1350
1468
|
{
|
|
1351
|
-
email:
|
|
1352
|
-
role:
|
|
1469
|
+
email: import_zod5.z.string().describe("Email address of the person to invite."),
|
|
1470
|
+
role: import_zod5.z.enum(["admin", "member", "viewer"]).describe("Role to assign: admin, member, or viewer. owner is not assignable via API key.")
|
|
1353
1471
|
},
|
|
1354
1472
|
(a) => client.members.invite(a.email, a.role)
|
|
1355
1473
|
);
|
|
@@ -1357,8 +1475,8 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1357
1475
|
"set_member_role",
|
|
1358
1476
|
"Change the role of a member in your organization. The org owner's role cannot be changed.",
|
|
1359
1477
|
{
|
|
1360
|
-
userId:
|
|
1361
|
-
role:
|
|
1478
|
+
userId: import_zod5.z.string().describe("The userId of the member whose role to change."),
|
|
1479
|
+
role: import_zod5.z.enum(["admin", "member", "viewer"]).describe("New role: admin, member, or viewer.")
|
|
1362
1480
|
},
|
|
1363
1481
|
(a) => client.members.setRole(a.userId, a.role)
|
|
1364
1482
|
);
|
|
@@ -1366,7 +1484,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1366
1484
|
"remove_member",
|
|
1367
1485
|
"Remove a member from your organization. The org owner cannot be removed.",
|
|
1368
1486
|
{
|
|
1369
|
-
userId:
|
|
1487
|
+
userId: import_zod5.z.string().describe("The userId of the member to remove.")
|
|
1370
1488
|
},
|
|
1371
1489
|
async (a) => {
|
|
1372
1490
|
await client.members.remove(a.userId);
|
|
@@ -1377,11 +1495,11 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1377
1495
|
"create_brand_kit",
|
|
1378
1496
|
"Create a reusable brand kit (colors, logo, typography) for your organization's consent banners.",
|
|
1379
1497
|
{
|
|
1380
|
-
name:
|
|
1381
|
-
theme:
|
|
1382
|
-
content:
|
|
1383
|
-
logoUrl:
|
|
1384
|
-
customCss:
|
|
1498
|
+
name: import_zod5.z.string().describe("Display name for the brand kit."),
|
|
1499
|
+
theme: import_zod5.z.record(import_zod5.z.unknown()).describe("Theme tokens (colors, fonts, etc.) as a JSON object."),
|
|
1500
|
+
content: import_zod5.z.record(import_zod5.z.unknown()).optional().describe("Optional banner copy overrides."),
|
|
1501
|
+
logoUrl: import_zod5.z.string().optional().describe("Optional URL for your org logo."),
|
|
1502
|
+
customCss: import_zod5.z.string().optional().describe("Optional custom CSS string to inject into the banner.")
|
|
1385
1503
|
},
|
|
1386
1504
|
(a) => client.brandKits.create({
|
|
1387
1505
|
name: a.name,
|
|
@@ -1395,7 +1513,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1395
1513
|
"delete_brand_kit",
|
|
1396
1514
|
"Delete a brand kit by id. The kit must belong to your organization (cross-org deletes are rejected).",
|
|
1397
1515
|
{
|
|
1398
|
-
id:
|
|
1516
|
+
id: import_zod5.z.string().describe("The brand kit id to delete.")
|
|
1399
1517
|
},
|
|
1400
1518
|
async (a) => {
|
|
1401
1519
|
await client.brandKits.delete(a.id);
|
|
@@ -1406,63 +1524,65 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1406
1524
|
"save_preference",
|
|
1407
1525
|
"Save or update the consent preferences for an end-user (by subjectId) within your organization. purposes is a map of purpose-name \u2192 boolean.",
|
|
1408
1526
|
{
|
|
1409
|
-
subjectId:
|
|
1410
|
-
purposes:
|
|
1527
|
+
subjectId: import_zod5.z.string().describe("The end-user identifier (e.g. email or internal user id)."),
|
|
1528
|
+
purposes: import_zod5.z.record(import_zod5.z.boolean()).describe('Map of purpose names to consent values, e.g. { "newsletter": true, "analytics": false }.')
|
|
1411
1529
|
},
|
|
1412
1530
|
(a) => client.preferences.save(a.subjectId, a.purposes)
|
|
1413
1531
|
);
|
|
1414
1532
|
tool(
|
|
1415
1533
|
"get_preference",
|
|
1416
1534
|
"One end-user\u2019s saved preferences, by subjectId. Read-only.",
|
|
1417
|
-
{ subjectId:
|
|
1535
|
+
{ subjectId: import_zod5.z.string() },
|
|
1418
1536
|
(a) => client.preferences.get(a.subjectId)
|
|
1419
1537
|
);
|
|
1420
1538
|
tool(
|
|
1421
1539
|
"issue_api_key",
|
|
1422
1540
|
"Issue a new API key. The secret is returned once and never again. Prefer the least privilege the job needs: `scopes` limits what it can do, `cbids` locks it to specific sites (it then cannot reach anything org-wide), `expiresInDays` retires it. Omitting all three mints a full-access, org-wide, non-expiring key.",
|
|
1423
1541
|
{
|
|
1424
|
-
name:
|
|
1425
|
-
scopes:
|
|
1426
|
-
cbids:
|
|
1427
|
-
expiresInDays:
|
|
1542
|
+
name: import_zod5.z.string().optional(),
|
|
1543
|
+
scopes: import_zod5.z.array(import_zod5.z.string()).optional(),
|
|
1544
|
+
cbids: import_zod5.z.array(import_zod5.z.string()).min(1).optional(),
|
|
1545
|
+
expiresInDays: import_zod5.z.number().int().min(1).max(3650).optional(),
|
|
1546
|
+
expiresAt: import_zod5.z.string().optional().describe("Or the exact expiry, an ISO date-time (not with expiresInDays).")
|
|
1428
1547
|
},
|
|
1429
1548
|
(a) => client.keys.issue({
|
|
1549
|
+
...a.expiresAt ? { expiresAt: a.expiresAt } : {},
|
|
1430
1550
|
...a.name ? { name: a.name } : {},
|
|
1431
1551
|
...a.scopes ? { scopes: a.scopes } : {},
|
|
1432
1552
|
...a.cbids ? { cbids: a.cbids } : {},
|
|
1433
1553
|
...a.expiresInDays !== void 0 ? { expiresInDays: a.expiresInDays } : {}
|
|
1434
1554
|
})
|
|
1435
1555
|
);
|
|
1436
|
-
tool("revoke_api_key", "Revoke an API key by its prefix. Takes effect immediately; anything using that key stops working.", { prefix:
|
|
1556
|
+
tool("revoke_api_key", "Revoke an API key by its prefix. Takes effect immediately; anything using that key stops working.", { prefix: import_zod5.z.string() }, async (a) => {
|
|
1437
1557
|
await client.keys.revoke(a.prefix);
|
|
1438
1558
|
return { revoked: a.prefix };
|
|
1439
1559
|
});
|
|
1440
1560
|
tool(
|
|
1441
1561
|
"import_cookie_declaration",
|
|
1442
1562
|
"Read a cookie declaration exported from another CMP (OneTrust, Cookiebot, CookieYes, or any CSV/JSON with the same columns) and translate its categories into ours. Nothing is applied \u2014 it comes back for review, with the rows whose category could not be placed listed separately.",
|
|
1443
|
-
{ cbid:
|
|
1563
|
+
{ cbid: import_zod5.z.string(), data: import_zod5.z.string().describe("The exported file, as text (CSV or JSON).") },
|
|
1444
1564
|
(a) => client.sites.importDeclaration(a.cbid, a.data)
|
|
1445
1565
|
);
|
|
1446
1566
|
tool(
|
|
1447
1567
|
"apply_cookie_import",
|
|
1448
1568
|
"Import a cookie declaration exported from another CMP AND declare it: every row whose category mapped to ours and that has a purpose becomes a site declaration; the rest come back in `skipped` with the reason. Cookies the site already declared are kept unless overwrite is true. Prefer import_cookie_declaration first to review.",
|
|
1449
|
-
{ cbid:
|
|
1569
|
+
{ cbid: import_zod5.z.string(), data: import_zod5.z.string().describe("The exported file, as text (CSV or JSON)."), overwrite: import_zod5.z.boolean().optional() },
|
|
1450
1570
|
(a) => client.sites.applyImport(a.cbid, a.data, a.overwrite ? { overwrite: true } : void 0)
|
|
1451
1571
|
);
|
|
1452
1572
|
const declarationShape = {
|
|
1453
|
-
category:
|
|
1454
|
-
purpose:
|
|
1455
|
-
purposes:
|
|
1456
|
-
provider:
|
|
1457
|
-
expiry:
|
|
1458
|
-
domain:
|
|
1459
|
-
pattern:
|
|
1573
|
+
category: import_zod5.z.string().describe("necessary, preferences, statistics, marketing, or one of the site\u2019s categories.custom ids."),
|
|
1574
|
+
purpose: import_zod5.z.string().describe("What the cookie does, as visitors will read it \u2014 and the fallback for any language purposes lacks."),
|
|
1575
|
+
purposes: import_zod5.z.record(import_zod5.z.string(), import_zod5.z.string().max(1e3)).nullable().optional().describe('The purpose in other languages, keyed by BCP-47 tag: {"es": "\u2026", "pt-BR": "\u2026"}. The banner, data-cc="declaration" and cookie-declaration.js draw the visitor\u2019s language. null clears.'),
|
|
1576
|
+
provider: import_zod5.z.string().optional(),
|
|
1577
|
+
expiry: import_zod5.z.string().optional().describe('e.g. "Session", "30 days", "1 year" (the banner localises these forms).'),
|
|
1578
|
+
domain: import_zod5.z.string().optional(),
|
|
1579
|
+
pattern: import_zod5.z.boolean().optional().describe("Treat the name as a prefix wildcard (a trailing * does the same).")
|
|
1460
1580
|
};
|
|
1461
|
-
const dryRunArg =
|
|
1581
|
+
const dryRunArg = import_zod5.z.boolean().optional().describe("Store nothing: answer with the would-be declarations and a diff (added / removed / changed) to check first.");
|
|
1462
1582
|
tool(
|
|
1463
1583
|
"declare_cookie",
|
|
1464
1584
|
'Declare what one of the site\u2019s cookies is. Overrides the scanner, observed visits and the cookie database everywhere the declaration is shown (API, preference modal, data-cc="declaration"). Use for the site\u2019s own cookies the database cannot know. A name ending in * covers every cookie with that prefix.',
|
|
1465
|
-
{ cbid:
|
|
1585
|
+
{ cbid: import_zod5.z.string(), name: import_zod5.z.string(), ...declarationShape, dryRun: dryRunArg },
|
|
1466
1586
|
(a) => {
|
|
1467
1587
|
const { cbid: cbid2, name, dryRun, ...rest } = a;
|
|
1468
1588
|
return client.sites.declareCookie(cbid2, name, rest, dryRun ? { dryRun: true } : void 0);
|
|
@@ -1471,7 +1591,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1471
1591
|
tool(
|
|
1472
1592
|
"declare_cookies",
|
|
1473
1593
|
"Declare many cookies at once. All-or-nothing: one invalid item refuses the whole request and nothing is saved. replace: true also removes every declaration the list does not name.",
|
|
1474
|
-
{ cbid:
|
|
1594
|
+
{ cbid: import_zod5.z.string(), cookies: import_zod5.z.array(import_zod5.z.object({ name: import_zod5.z.string(), ...declarationShape })).max(500), replace: import_zod5.z.boolean().optional(), dryRun: dryRunArg },
|
|
1475
1595
|
(a) => {
|
|
1476
1596
|
const o = { ...a.replace ? { replace: true } : {}, ...a.dryRun ? { dryRun: true } : {} };
|
|
1477
1597
|
return client.sites.declareCookies(a.cbid, a.cookies, Object.keys(o).length ? o : void 0);
|
|
@@ -1480,7 +1600,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1480
1600
|
tool(
|
|
1481
1601
|
"undeclare_cookie",
|
|
1482
1602
|
"Remove a cookie declaration; the scanned/observed classification applies again.",
|
|
1483
|
-
{ cbid:
|
|
1603
|
+
{ cbid: import_zod5.z.string(), name: import_zod5.z.string(), dryRun: dryRunArg },
|
|
1484
1604
|
async (a) => {
|
|
1485
1605
|
if (a.dryRun) return client.sites.undeclareCookie(a.cbid, a.name, { dryRun: true });
|
|
1486
1606
|
await client.sites.undeclareCookie(a.cbid, a.name);
|
|
@@ -1491,11 +1611,11 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1491
1611
|
"retire_cookie",
|
|
1492
1612
|
'Retire a cookie the site renamed or stopped setting: it leaves the banner\u2019s cookie list, data-cc="declaration" and the public feed, and stays listed for the owner with retired. A name ending in * retires every cookie with that prefix; the name must match a scanned, observed or declared cookie. If a crawl or a real visit sees it again afterwards, it is listed again with review: retired_but_seen.',
|
|
1493
1613
|
{
|
|
1494
|
-
cbid:
|
|
1495
|
-
name:
|
|
1496
|
-
renamedTo:
|
|
1497
|
-
note:
|
|
1498
|
-
dryRun:
|
|
1614
|
+
cbid: import_zod5.z.string(),
|
|
1615
|
+
name: import_zod5.z.string(),
|
|
1616
|
+
renamedTo: import_zod5.z.string().max(256).optional().describe("The cookie\u2019s new name, if it was renamed."),
|
|
1617
|
+
note: import_zod5.z.string().max(1e3).optional(),
|
|
1618
|
+
dryRun: import_zod5.z.boolean().optional().describe("Store nothing: answer with the would-be retirement and list to check first.")
|
|
1499
1619
|
},
|
|
1500
1620
|
(a) => {
|
|
1501
1621
|
const input = { ...a.renamedTo ? { renamedTo: a.renamedTo } : {}, ...a.note ? { note: a.note } : {} };
|
|
@@ -1505,35 +1625,95 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1505
1625
|
tool(
|
|
1506
1626
|
"unretire_cookie",
|
|
1507
1627
|
"Un-retire a cookie: it is listed again everywhere.",
|
|
1508
|
-
{ cbid:
|
|
1628
|
+
{ cbid: import_zod5.z.string(), name: import_zod5.z.string(), dryRun: import_zod5.z.boolean().optional().describe("Store nothing: answer with what the list would be.") },
|
|
1509
1629
|
async (a) => {
|
|
1510
1630
|
if (a.dryRun) return client.sites.unretireCookie(a.cbid, a.name, { dryRun: true });
|
|
1511
1631
|
await client.sites.unretireCookie(a.cbid, a.name);
|
|
1512
1632
|
return { unretired: a.name };
|
|
1513
1633
|
}
|
|
1514
1634
|
);
|
|
1635
|
+
tool(
|
|
1636
|
+
"list_cookie_presets",
|
|
1637
|
+
"Declaration presets for the platforms a site is built on (atlas, forumulate, chatly, cookiemunch, referally): each one\u2019s parameters, what it has declared on this site, and whether the vendor\u2019s live manifest can be imported yet. Read-only.",
|
|
1638
|
+
{ cbid: import_zod5.z.string() },
|
|
1639
|
+
(a) => client.sites.cookiePresets(a.cbid)
|
|
1640
|
+
);
|
|
1641
|
+
tool(
|
|
1642
|
+
"apply_cookie_preset",
|
|
1643
|
+
"Apply (or re-sync) a vendor preset: declares exactly what that platform writes \u2014 cookies and browser storage, with domain and lifetime \u2014 marked as declared by that vendor. Re-applying removes keys the vendor no longer writes. Names the owner declared are kept (skipped). Atlas needs frontendApiHost (and crossSubdomainCookies, default true); Chatly needs publicId.",
|
|
1644
|
+
{
|
|
1645
|
+
cbid: import_zod5.z.string(),
|
|
1646
|
+
vendor: import_zod5.z.enum(["atlas", "forumulate", "chatly", "cookiemunch", "referally"]),
|
|
1647
|
+
frontendApiHost: import_zod5.z.string().optional().describe("Atlas: your frontend API host, e.g. auth.example.com."),
|
|
1648
|
+
crossSubdomainCookies: import_zod5.z.boolean().optional().describe("Atlas: default true \u2014 the cookies live on the parent domain."),
|
|
1649
|
+
publicId: import_zod5.z.string().optional().describe("Chatly: the channel public id (ch_web_\u2026)."),
|
|
1650
|
+
dragging: import_zod5.z.boolean().optional().describe("Chatly: the launcher can be dragged (adds the drag-position key)."),
|
|
1651
|
+
category: import_zod5.z.string().optional().describe("Chatly: the category for its keys (default necessary). Referally: default the site's referrals category, else marketing."),
|
|
1652
|
+
cookieDomain: import_zod5.z.string().optional().describe("Referally: the domain aff.js sets referally_ctx on, e.g. .example.com. Default the site domain."),
|
|
1653
|
+
cookieDays: import_zod5.z.number().int().min(1).max(400).optional().describe("Referally: how long the cookie lives, 1 to 400 days. Default 60."),
|
|
1654
|
+
dryRun: dryRunArg
|
|
1655
|
+
},
|
|
1656
|
+
(a) => {
|
|
1657
|
+
const params = {};
|
|
1658
|
+
for (const k of ["frontendApiHost", "crossSubdomainCookies", "publicId", "dragging", "category", "cookieDomain", "cookieDays"]) if (a[k] !== void 0) params[k] = a[k];
|
|
1659
|
+
return client.sites.applyCookiePreset(a.cbid, a.vendor, params, a.dryRun ? { dryRun: true } : void 0);
|
|
1660
|
+
}
|
|
1661
|
+
);
|
|
1662
|
+
tool(
|
|
1663
|
+
"remove_cookie_preset",
|
|
1664
|
+
"Remove every declaration a vendor preset made on this site.",
|
|
1665
|
+
{ cbid: import_zod5.z.string(), vendor: import_zod5.z.enum(["atlas", "forumulate", "chatly", "cookiemunch", "referally"]), dryRun: dryRunArg },
|
|
1666
|
+
(a) => client.sites.removeCookiePreset(a.cbid, a.vendor, a.dryRun ? { dryRun: true } : void 0)
|
|
1667
|
+
);
|
|
1668
|
+
tool(
|
|
1669
|
+
"delete_observed_cookie",
|
|
1670
|
+
"Remove every stored row of this name that crawls or real visits put in the site\u2019s cookie list (e.g. a name someone reported that the site never sets). A declaration of it stays. If real visits keep reporting it, it comes back quarantined.",
|
|
1671
|
+
{ cbid: import_zod5.z.string(), name: import_zod5.z.string(), dryRun: dryRunArg },
|
|
1672
|
+
async (a) => {
|
|
1673
|
+
if (a.dryRun) return client.sites.deleteObservedCookie(a.cbid, a.name, { dryRun: true });
|
|
1674
|
+
await client.sites.deleteObservedCookie(a.cbid, a.name);
|
|
1675
|
+
return { deleted: a.name };
|
|
1676
|
+
}
|
|
1677
|
+
);
|
|
1678
|
+
tool(
|
|
1679
|
+
"purge_observed_cookies",
|
|
1680
|
+
"Purge observed since T: remove every row a real visit first reported at or after `since` (and before `until`). Crawled rows and declarations stay. Rows from before provenance was recorded use their last-seen time, so run with dryRun first.",
|
|
1681
|
+
{
|
|
1682
|
+
cbid: import_zod5.z.string(),
|
|
1683
|
+
since: import_zod5.z.union([import_zod5.z.string(), import_zod5.z.number()]).describe("ISO-8601 time or epoch milliseconds."),
|
|
1684
|
+
until: import_zod5.z.union([import_zod5.z.string(), import_zod5.z.number()]).optional().describe("Optional end of the window (exclusive)."),
|
|
1685
|
+
dryRun: dryRunArg
|
|
1686
|
+
},
|
|
1687
|
+
(a) => client.sites.purgeObservedCookies(
|
|
1688
|
+
a.cbid,
|
|
1689
|
+
{ since: a.since, ...a.until !== void 0 ? { until: a.until } : {} },
|
|
1690
|
+
a.dryRun ? { dryRun: true } : void 0
|
|
1691
|
+
)
|
|
1692
|
+
);
|
|
1515
1693
|
tool(
|
|
1516
1694
|
"get_blocked_pages",
|
|
1517
1695
|
"Pages where the embed could not load its banner renderer \u2014 the page\u2019s Content Security Policy or Trusted Types policy refused it, so nobody there can be asked for consent. An empty list is healthy. Read-only.",
|
|
1518
|
-
{ cbid:
|
|
1696
|
+
{ cbid: import_zod5.z.string() },
|
|
1519
1697
|
(a) => client.sites.blocked(a.cbid)
|
|
1520
1698
|
);
|
|
1521
1699
|
tool(
|
|
1522
1700
|
"roll_api_key",
|
|
1523
1701
|
"Rotate an API key: returns a new secret once, with the same name, scopes, property lock and expiry. The old secret stops working immediately \u2014 if it is the key this server runs with, this server stops working too until it is reconfigured.",
|
|
1524
|
-
{ prefix:
|
|
1702
|
+
{ prefix: import_zod5.z.string() },
|
|
1525
1703
|
(a) => client.keys.roll(a.prefix)
|
|
1526
1704
|
);
|
|
1527
1705
|
tool(
|
|
1528
1706
|
"update_api_key",
|
|
1529
|
-
"Rename an API key,
|
|
1707
|
+
"Rename an API key, replace its scopes or the properties it is locked to, or set or remove its expiry. Only the fields given change; the secret does not.",
|
|
1530
1708
|
{
|
|
1531
|
-
prefix:
|
|
1532
|
-
name:
|
|
1533
|
-
scopes:
|
|
1534
|
-
cbids:
|
|
1709
|
+
prefix: import_zod5.z.string(),
|
|
1710
|
+
name: import_zod5.z.string().optional(),
|
|
1711
|
+
scopes: import_zod5.z.array(import_zod5.z.string()).optional(),
|
|
1712
|
+
cbids: import_zod5.z.array(import_zod5.z.string()).min(1).optional(),
|
|
1713
|
+
expiresAt: import_zod5.z.string().nullable().optional().describe("A new expiry (ISO date-time), or null to remove it.")
|
|
1535
1714
|
},
|
|
1536
1715
|
(a) => client.keys.update(a.prefix, {
|
|
1716
|
+
...a.expiresAt !== void 0 ? { expiresAt: a.expiresAt } : {},
|
|
1537
1717
|
...a.name !== void 0 ? { name: a.name } : {},
|
|
1538
1718
|
...a.scopes ? { scopes: a.scopes } : {},
|
|
1539
1719
|
...a.cbids ? { cbids: a.cbids } : {}
|
|
@@ -1543,7 +1723,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1543
1723
|
tool(
|
|
1544
1724
|
"update_org",
|
|
1545
1725
|
"Rename your organisation or set its logo. logoUrl: null removes the logo; upload an image with upload_asset to get a URL. Deleting the organisation is not possible here.",
|
|
1546
|
-
{ name:
|
|
1726
|
+
{ name: import_zod5.z.string().min(1).optional(), logoUrl: import_zod5.z.string().nullable().optional() },
|
|
1547
1727
|
(a) => client.org.update({
|
|
1548
1728
|
...a.name !== void 0 ? { name: a.name } : {},
|
|
1549
1729
|
...a.logoUrl !== void 0 ? { logoUrl: a.logoUrl } : {}
|
|
@@ -1559,20 +1739,20 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1559
1739
|
"set_mail_provider",
|
|
1560
1740
|
"Connect your own mail provider for rights-request mail \u2014 recommended, so codes come from your own domain. Replaces the stored one. It carries mail only after test_mail_provider succeeds; every save clears that. Omit secret to keep the stored one (same provider only).",
|
|
1561
1741
|
{
|
|
1562
|
-
provider:
|
|
1563
|
-
fromEmail:
|
|
1564
|
-
fromName:
|
|
1565
|
-
replyTo:
|
|
1566
|
-
secret:
|
|
1567
|
-
ses:
|
|
1568
|
-
smtp:
|
|
1742
|
+
provider: import_zod5.z.enum(["brevo", "sendgrid", "postmark", "resend", "ses", "smtp"]),
|
|
1743
|
+
fromEmail: import_zod5.z.string().describe("An address on a domain your provider has verified."),
|
|
1744
|
+
fromName: import_zod5.z.string().max(100).nullable().optional(),
|
|
1745
|
+
replyTo: import_zod5.z.string().nullable().optional(),
|
|
1746
|
+
secret: import_zod5.z.string().optional().describe("API key (Brevo, SendGrid, Resend), server token (Postmark), secret access key (SES) or SMTP password. Write-only."),
|
|
1747
|
+
ses: import_zod5.z.object({ region: import_zod5.z.string(), accessKeyId: import_zod5.z.string() }).optional().describe("Required for ses."),
|
|
1748
|
+
smtp: import_zod5.z.object({ host: import_zod5.z.string(), port: import_zod5.z.union([import_zod5.z.literal(25), import_zod5.z.literal(465), import_zod5.z.literal(587), import_zod5.z.literal(2525)]), security: import_zod5.z.enum(["tls", "starttls"]), username: import_zod5.z.string() }).optional().describe("Required for smtp. TLS is always required.")
|
|
1569
1749
|
},
|
|
1570
1750
|
(a) => client.org.mailProvider.set(a)
|
|
1571
1751
|
);
|
|
1572
1752
|
tool(
|
|
1573
1753
|
"test_mail_provider",
|
|
1574
1754
|
"Send a test message through your own mail provider (never Cookie Munch\u2019s) and report what it answered. Success marks the configuration verified, after which it carries all rights mail.",
|
|
1575
|
-
{ to:
|
|
1755
|
+
{ to: import_zod5.z.string().optional().describe("Recipient. Default: the reply-to, else the from address.") },
|
|
1576
1756
|
(a) => client.org.mailProvider.test(a.to)
|
|
1577
1757
|
);
|
|
1578
1758
|
tool(
|
|
@@ -1586,11 +1766,11 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1586
1766
|
);
|
|
1587
1767
|
const CAPTCHA_OFF = "Off removes spam protection beyond the hidden spam-trap field, the rate limits and the email code: expect more spam requests. Own keys are recommended.";
|
|
1588
1768
|
const captchaInput = {
|
|
1589
|
-
mode:
|
|
1590
|
-
provider:
|
|
1591
|
-
siteKey:
|
|
1592
|
-
secret:
|
|
1593
|
-
minScore:
|
|
1769
|
+
mode: import_zod5.z.enum(["own", "off"]).describe(`own: your own captcha provider keys (recommended). off: no captcha. ${CAPTCHA_OFF}`),
|
|
1770
|
+
provider: import_zod5.z.enum(["turnstile", "hcaptcha", "recaptcha_v2", "recaptcha_v3"]).optional().describe("Required for own."),
|
|
1771
|
+
siteKey: import_zod5.z.string().optional().describe("Required for own: the public site key. List your rights-page hostnames on it at the provider."),
|
|
1772
|
+
secret: import_zod5.z.string().optional().describe("The provider secret key. Write-only; never returned. Omit to keep the stored one (same provider)."),
|
|
1773
|
+
minScore: import_zod5.z.number().min(0.1).max(0.9).optional().describe("reCAPTCHA v3 only. Default 0.5.")
|
|
1594
1774
|
};
|
|
1595
1775
|
const captchaBody = (a) => ({
|
|
1596
1776
|
mode: a.mode,
|
|
@@ -1602,19 +1782,19 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1602
1782
|
tool(
|
|
1603
1783
|
"get_rights_captcha",
|
|
1604
1784
|
"The captcha on a site\u2019s hosted rights page: its own setting, else the organisation default, else off (`source` says which). Never returns the secret. Read-only.",
|
|
1605
|
-
{ cbid:
|
|
1785
|
+
{ cbid: import_zod5.z.string() },
|
|
1606
1786
|
(a) => client.rightsCaptcha.get(a.cbid)
|
|
1607
1787
|
);
|
|
1608
1788
|
tool(
|
|
1609
1789
|
"set_rights_captcha",
|
|
1610
1790
|
`Set a site\u2019s rights-page captcha: your own Turnstile, hCaptcha or reCAPTCHA keys (recommended; the provider must accept the secret before it is saved), or off. ${CAPTCHA_OFF} Audited with the old and new mode.`,
|
|
1611
|
-
{ cbid:
|
|
1791
|
+
{ cbid: import_zod5.z.string(), ...captchaInput },
|
|
1612
1792
|
(a) => client.rightsCaptcha.set(a.cbid, captchaBody(a))
|
|
1613
1793
|
);
|
|
1614
1794
|
tool(
|
|
1615
1795
|
"remove_rights_captcha",
|
|
1616
1796
|
"Remove a site\u2019s own captcha setting: it inherits the organisation default again (or off). Returns the setting now in force.",
|
|
1617
|
-
{ cbid:
|
|
1797
|
+
{ cbid: import_zod5.z.string() },
|
|
1618
1798
|
(a) => client.rightsCaptcha.remove(a.cbid)
|
|
1619
1799
|
);
|
|
1620
1800
|
tool(
|
|
@@ -1637,15 +1817,15 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1637
1817
|
);
|
|
1638
1818
|
const IDENTITY_NOTE = "The JWKS is fetched and checked before anything is saved. The session token must carry the email and a verified-email claim (default email_verified) set to true (Clerk: add email: {{user.primary_email_address}} to the session token; Clerk documents no claim for whether that address is verified, so either add your own or set trustEmailClaim). oidc_jwt needs an audience or authorizedParties.";
|
|
1639
1819
|
const identityInput = {
|
|
1640
|
-
type:
|
|
1641
|
-
issuer:
|
|
1642
|
-
jwksUrl:
|
|
1643
|
-
audience:
|
|
1644
|
-
authorizedParties:
|
|
1645
|
-
emailClaim:
|
|
1646
|
-
emailVerifiedClaim:
|
|
1647
|
-
sessionCookieName:
|
|
1648
|
-
trustEmailClaim:
|
|
1820
|
+
type: import_zod5.z.enum(["clerk", "atlas", "oidc_jwt"]).describe("clerk, atlas (Clerk-shaped), or oidc_jwt (any issuer that signs session JWTs with a published JWKS)."),
|
|
1821
|
+
issuer: import_zod5.z.string().describe("https URL exactly as in the token\u2019s iss (Clerk: your Frontend API URL)."),
|
|
1822
|
+
jwksUrl: import_zod5.z.string().optional().describe("Required for oidc_jwt; clerk/atlas default to <issuer>/.well-known/jwks.json."),
|
|
1823
|
+
audience: import_zod5.z.string().optional().describe("Expected aud. For oidc_jwt an audience or authorizedParties is required (a shared issuer mints tokens for every app)."),
|
|
1824
|
+
authorizedParties: import_zod5.z.array(import_zod5.z.string()).optional().describe("Your own origins (https://www.example.com) the token\u2019s azp must be one of. Required for clerk and atlas; for oidc_jwt when there is no audience."),
|
|
1825
|
+
emailClaim: import_zod5.z.string().optional().describe("Default email."),
|
|
1826
|
+
emailVerifiedClaim: import_zod5.z.string().optional().describe("Default email_verified; must be exactly true."),
|
|
1827
|
+
sessionCookieName: import_zod5.z.string().optional().describe("Default __session: the cookie the hosted page on your custom domain reads."),
|
|
1828
|
+
trustEmailClaim: import_zod5.z.boolean().optional().describe("clerk/atlas only, default false. True: a token without the verified claim is accepted, its email claim taken as verified. Set only if every address your provider puts in that claim is verified.")
|
|
1649
1829
|
};
|
|
1650
1830
|
const identityBody = (a) => {
|
|
1651
1831
|
const out = { type: a.type, issuer: a.issuer };
|
|
@@ -1655,19 +1835,19 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1655
1835
|
tool(
|
|
1656
1836
|
"get_rights_identity",
|
|
1657
1837
|
"The sign-in provider a site\u2019s rights requests are verified with: its own setting, else the organisation default, else none (`source` says which). Read-only.",
|
|
1658
|
-
{ cbid:
|
|
1838
|
+
{ cbid: import_zod5.z.string() },
|
|
1659
1839
|
(a) => client.rightsIdentity.get(a.cbid)
|
|
1660
1840
|
);
|
|
1661
1841
|
tool(
|
|
1662
1842
|
"set_rights_identity",
|
|
1663
1843
|
`Connect a site\u2019s sign-in provider so a visitor signed in to the site is verified by their session, with no code mail. ${IDENTITY_NOTE} Audited.`,
|
|
1664
|
-
{ cbid:
|
|
1844
|
+
{ cbid: import_zod5.z.string(), ...identityInput },
|
|
1665
1845
|
(a) => client.rightsIdentity.set(a.cbid, identityBody(a))
|
|
1666
1846
|
);
|
|
1667
1847
|
tool(
|
|
1668
1848
|
"remove_rights_identity",
|
|
1669
1849
|
"Remove a site\u2019s own sign-in provider: it inherits the organisation default again (or none). Returns the setting now in force.",
|
|
1670
|
-
{ cbid:
|
|
1850
|
+
{ cbid: import_zod5.z.string() },
|
|
1671
1851
|
(a) => client.rightsIdentity.remove(a.cbid)
|
|
1672
1852
|
);
|
|
1673
1853
|
tool(
|
|
@@ -1691,22 +1871,22 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1691
1871
|
tool(
|
|
1692
1872
|
"get_audit_log",
|
|
1693
1873
|
"The organisation\u2019s audit log, newest first: administrative changes made in the dashboard or through the API, and who made them. Read-only.",
|
|
1694
|
-
{ limit:
|
|
1874
|
+
{ limit: import_zod5.z.number().int().min(1).max(500).optional() },
|
|
1695
1875
|
(a) => client.audit(a.limit)
|
|
1696
1876
|
);
|
|
1697
1877
|
tool(
|
|
1698
1878
|
"upload_asset",
|
|
1699
1879
|
"Upload an image \u2014 a banner logo \u2014 and get its public URL. data is base64 (a data: URL also works); PNG, JPEG, WebP, GIF or SVG, up to 1,000,000 bytes.",
|
|
1700
1880
|
{
|
|
1701
|
-
data:
|
|
1702
|
-
contentType:
|
|
1881
|
+
data: import_zod5.z.string(),
|
|
1882
|
+
contentType: import_zod5.z.enum(["image/png", "image/jpeg", "image/webp", "image/gif", "image/svg+xml"])
|
|
1703
1883
|
},
|
|
1704
1884
|
(a) => client.assets.upload({ data: a.data, contentType: a.contentType })
|
|
1705
1885
|
);
|
|
1706
1886
|
tool(
|
|
1707
1887
|
"delete_asset",
|
|
1708
1888
|
"Delete a stored image by its URL (or file name). Only your own organisation\u2019s images can be named.",
|
|
1709
|
-
{ url:
|
|
1889
|
+
{ url: import_zod5.z.string().describe("The URL upload_asset returned, or just its file name.") },
|
|
1710
1890
|
async (a) => {
|
|
1711
1891
|
await client.assets.delete(a.url);
|
|
1712
1892
|
return { deleted: a.url };
|
|
@@ -1721,18 +1901,18 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1721
1901
|
tool(
|
|
1722
1902
|
"get_customer",
|
|
1723
1903
|
"One child org: its controller details and usage. Read-only.",
|
|
1724
|
-
{ id:
|
|
1904
|
+
{ id: import_zod5.z.string() },
|
|
1725
1905
|
(a) => client.reseller.get(a.id)
|
|
1726
1906
|
);
|
|
1727
1907
|
tool(
|
|
1728
1908
|
"provision_customer",
|
|
1729
1909
|
"Create a new child org under this reseller. With `mintKey`, its first API key is returned once. Counts toward the reseller plan\u2019s pooled limits.",
|
|
1730
1910
|
{
|
|
1731
|
-
name:
|
|
1732
|
-
ownerEmail:
|
|
1733
|
-
delegatedAccess:
|
|
1734
|
-
mintKey:
|
|
1735
|
-
keyScopes:
|
|
1911
|
+
name: import_zod5.z.string(),
|
|
1912
|
+
ownerEmail: import_zod5.z.string().optional(),
|
|
1913
|
+
delegatedAccess: import_zod5.z.boolean().optional().describe("Whether this reseller may act inside the child."),
|
|
1914
|
+
mintKey: import_zod5.z.boolean().optional(),
|
|
1915
|
+
keyScopes: import_zod5.z.array(import_zod5.z.string()).optional()
|
|
1736
1916
|
},
|
|
1737
1917
|
(a) => client.reseller.create({
|
|
1738
1918
|
name: a.name,
|
|
@@ -1746,10 +1926,10 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1746
1926
|
"update_customer",
|
|
1747
1927
|
"Change a child org\u2019s status, delegated access or DSAR routing. `dsarRouting: null` clears the override.",
|
|
1748
1928
|
{
|
|
1749
|
-
id:
|
|
1750
|
-
status:
|
|
1751
|
-
delegatedAccess:
|
|
1752
|
-
dsarRouting:
|
|
1929
|
+
id: import_zod5.z.string(),
|
|
1930
|
+
status: import_zod5.z.enum(["active", "suspended"]).optional(),
|
|
1931
|
+
delegatedAccess: import_zod5.z.boolean().optional(),
|
|
1932
|
+
dsarRouting: import_zod5.z.enum(["reseller", "child"]).nullable().optional()
|
|
1753
1933
|
},
|
|
1754
1934
|
(a) => client.reseller.update(a.id, {
|
|
1755
1935
|
...a.status ? { status: a.status } : {},
|
|
@@ -1760,7 +1940,7 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1760
1940
|
tool(
|
|
1761
1941
|
"suspend_customer",
|
|
1762
1942
|
"Suspend a child org: it stops ingesting consent and its keys stop working, and it can be reactivated with update_customer. Its data is kept. (Permanent deletion is deliberately not available here.)",
|
|
1763
|
-
{ id:
|
|
1943
|
+
{ id: import_zod5.z.string() },
|
|
1764
1944
|
async (a) => {
|
|
1765
1945
|
await client.reseller.deprovision(a.id);
|
|
1766
1946
|
return { suspended: a.id };
|
|
@@ -1769,85 +1949,87 @@ ${JSON.stringify(r, null, 2)}` : r;
|
|
|
1769
1949
|
tool(
|
|
1770
1950
|
"list_customer_keys",
|
|
1771
1951
|
"A child org's API key prefixes. Never the secrets. Read-only.",
|
|
1772
|
-
{ id:
|
|
1952
|
+
{ id: import_zod5.z.string() },
|
|
1773
1953
|
(a) => client.reseller.listKeys(a.id)
|
|
1774
1954
|
);
|
|
1775
1955
|
tool(
|
|
1776
1956
|
"issue_customer_key",
|
|
1777
1957
|
"Mint an API key for a child org. The secret is returned once. Prefer scopes and a property lock over a full-access key.",
|
|
1778
|
-
{ id:
|
|
1958
|
+
{ id: import_zod5.z.string(), name: import_zod5.z.string().optional(), scopes: import_zod5.z.array(import_zod5.z.string()).optional(), cbids: import_zod5.z.array(import_zod5.z.string()).min(1).optional() },
|
|
1779
1959
|
(a) => client.reseller.mintKey(a.id, {
|
|
1780
1960
|
...a.name ? { name: a.name } : {},
|
|
1781
1961
|
...a.scopes ? { scopes: a.scopes } : {},
|
|
1782
1962
|
...a.cbids ? { cbids: a.cbids } : {}
|
|
1783
1963
|
})
|
|
1784
1964
|
);
|
|
1785
|
-
tool("revoke_customer_key", "Revoke a child org's API key by prefix. Takes effect immediately.", { id:
|
|
1965
|
+
tool("revoke_customer_key", "Revoke a child org's API key by prefix. Takes effect immediately.", { id: import_zod5.z.string(), prefix: import_zod5.z.string() }, async (a) => {
|
|
1786
1966
|
await client.reseller.revokeKey(a.id, a.prefix);
|
|
1787
1967
|
return { revoked: a.prefix };
|
|
1788
1968
|
});
|
|
1789
1969
|
tool(
|
|
1790
1970
|
"erase_subject_data",
|
|
1791
1971
|
"IRREVERSIBLY crypto-erase a data subject's consent records by their consent-receipt stamp (GDPR/CCPA deletion). Destroys the encryption key; the tamper-evident chain stays intact.",
|
|
1792
|
-
{ cbid:
|
|
1972
|
+
{ cbid: import_zod5.z.string(), stamp: import_zod5.z.string() },
|
|
1793
1973
|
(a) => client.consent.eraseSubject(a.cbid, a.stamp)
|
|
1794
1974
|
);
|
|
1795
1975
|
tool(
|
|
1796
1976
|
"export_subject_data",
|
|
1797
1977
|
"Export a data subject's consent records (GDPR access/portability).",
|
|
1798
|
-
{ cbid:
|
|
1978
|
+
{ cbid: import_zod5.z.string(), stamp: import_zod5.z.string() },
|
|
1799
1979
|
(a) => client.consent.exportSubject(a.cbid, a.stamp)
|
|
1800
1980
|
);
|
|
1801
1981
|
tool("list_banners", "List reusable banner designs in your org.", {}, () => client.banners.list());
|
|
1802
1982
|
tool(
|
|
1803
1983
|
"create_banner",
|
|
1804
1984
|
"Create a reusable banner design.",
|
|
1805
|
-
{ name:
|
|
1985
|
+
{ name: import_zod5.z.string(), json: import_zod5.z.record(import_zod5.z.unknown()).describe("A v2 BannerConfig.") },
|
|
1806
1986
|
(a) => client.banners.create({ name: a.name, json: a.json })
|
|
1807
1987
|
);
|
|
1808
|
-
tool("get_banner", "Get a banner design by id.", { id:
|
|
1988
|
+
tool("get_banner", "Get a banner design by id.", { id: import_zod5.z.string() }, (a) => client.banners.get(a.id));
|
|
1809
1989
|
tool(
|
|
1810
1990
|
"update_banner",
|
|
1811
1991
|
"Update a banner design (name and/or config).",
|
|
1812
|
-
{ id:
|
|
1992
|
+
{ id: import_zod5.z.string(), name: import_zod5.z.string().optional(), json: import_zod5.z.record(import_zod5.z.unknown()).optional() },
|
|
1813
1993
|
(a) => client.banners.update(a.id, {
|
|
1814
1994
|
...a.name !== void 0 ? { name: a.name } : {},
|
|
1815
1995
|
...a.json !== void 0 ? { json: a.json } : {}
|
|
1816
1996
|
})
|
|
1817
1997
|
);
|
|
1818
|
-
tool("delete_banner", "Delete a banner design (fails if assigned to sites).", { id:
|
|
1998
|
+
tool("delete_banner", "Delete a banner design (fails if assigned to sites).", { id: import_zod5.z.string() }, async (a) => {
|
|
1819
1999
|
await client.banners.delete(a.id);
|
|
1820
2000
|
return { ok: true };
|
|
1821
2001
|
});
|
|
1822
2002
|
tool(
|
|
1823
2003
|
"get_banner_assignments",
|
|
1824
2004
|
"The sites (cbids) a banner design is currently assigned to. Read-only.",
|
|
1825
|
-
{ id:
|
|
2005
|
+
{ id: import_zod5.z.string() },
|
|
1826
2006
|
(a) => client.banners.assignments(a.id)
|
|
1827
2007
|
);
|
|
1828
2008
|
tool(
|
|
1829
2009
|
"assign_banner",
|
|
1830
2010
|
"Set which sites (cbids) use a banner design.",
|
|
1831
|
-
{ id:
|
|
2011
|
+
{ id: import_zod5.z.string(), cbids: import_zod5.z.array(import_zod5.z.string()) },
|
|
1832
2012
|
(a) => client.banners.setAssignments(a.id, a.cbids)
|
|
1833
2013
|
);
|
|
1834
2014
|
tool(
|
|
1835
2015
|
"publish_banner",
|
|
1836
2016
|
"Publish a design live to all its assigned sites.",
|
|
1837
|
-
{ id:
|
|
2017
|
+
{ id: import_zod5.z.string() },
|
|
1838
2018
|
(a) => client.banners.publish(a.id)
|
|
1839
2019
|
);
|
|
1840
2020
|
}
|
|
1841
2021
|
|
|
1842
2022
|
// src/index.ts
|
|
2023
|
+
var MCP_VERSION = "0.4.1";
|
|
1843
2024
|
function createCookieMunchMcp(opts) {
|
|
1844
|
-
const client = opts.client ?? (0, import_sdk.createCookieMunch)({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });
|
|
2025
|
+
const client = opts.client ?? (0, import_sdk.createCookieMunch)({ apiKey: opts.apiKey, baseUrl: opts.baseUrl, userAgent: opts.userAgent ?? `cookiemunch-mcp/${MCP_VERSION}` });
|
|
1845
2026
|
const server = new import_mcp.McpServer({ name: "cookiemunch", version: "1.0.0" });
|
|
1846
2027
|
registerTools(server, client);
|
|
1847
2028
|
return server;
|
|
1848
2029
|
}
|
|
1849
2030
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1850
2031
|
0 && (module.exports = {
|
|
2032
|
+
MCP_VERSION,
|
|
1851
2033
|
createCookieMunchMcp,
|
|
1852
2034
|
registerTools
|
|
1853
2035
|
});
|