@cookiemunch/mcp 0.7.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * stdio entry point for the Cookie Munch MCP server. Reads COOKIEMUNCH_API_KEY
4
+ * (required) and COOKIEMUNCH_BASE_URL (optional) from the environment, builds the
5
+ * server, and serves it over stdio — the transport Claude Desktop / Claude Code use
6
+ * to spawn local MCP servers.
7
+ */
8
+ export {};
package/dist/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createCookieMunchMcp
4
- } from "./chunk-3C3J6N2L.js";
4
+ } from "./chunk-FI6MOPOJ.js";
5
5
 
6
6
  // src/bin.ts
7
7
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -11,7 +11,7 @@ function registerConfigTools(tool, client) {
11
11
  const blockingModeEnum = z.enum(["auto", "manual"]);
12
12
  const bannerModeEnum = z.enum(["opt-in", "opt-out", "off"]);
13
13
  const bannerTypeEnum = z.enum(["multilevel", "inline", "accept-decline", "accept-only", "do-not-sell"]);
14
- const bannerLayoutEnum = z.enum(["top", "bottom", "push-down", "popup", "overlay"]);
14
+ const bannerLayoutEnum = z.enum(["top", "bottom", "push-down", "popup", "overlay", "sidebar"]);
15
15
  const consentModeModeEnum = z.enum(["basic", "advanced"]);
16
16
  const geoRuleSchema = z.object({
17
17
  match: z.object({
@@ -187,9 +187,14 @@ function registerConfigTools(tool, client) {
187
187
  const setBannerBasicsSchema = z.object({
188
188
  cbid: z.string().describe("Site identifier (cbid)."),
189
189
  type: bannerTypeEnum.optional().describe("Banner type. multilevel | inline | accept-decline | accept-only | do-not-sell."),
190
- layout: bannerLayoutEnum.optional().describe("Banner layout. top | bottom | push-down | popup | overlay."),
190
+ layout: bannerLayoutEnum.optional().describe("Banner layout. top | bottom | push-down | popup | overlay | sidebar."),
191
191
  preset: z.enum(["bar", "box", "full"]).optional().describe("Named shape that sets type/secondLayer (and layout for box): bar = slim one-row bar + categories in a modal; box = centred card + modal; full = every category in the first layer."),
192
- secondLayer: z.enum(["expand", "popup", "modal"]).optional().describe("Where the categories open from an inline banner."),
192
+ secondLayer: z.enum(["expand", "popup", "modal", "sidebar"]).optional().describe("Where the categories open from an inline banner."),
193
+ sidebar: z.object({
194
+ side: z.enum(["left", "right"]).optional(),
195
+ width: z.number().min(280).max(640).optional(),
196
+ backdrop: z.boolean().optional()
197
+ }).optional().describe("The drawer of a sidebar layout or second layer: side (default right, mirrored for RTL), width in px 280\u2013640 (default 400), backdrop (default true). Merged onto the stored value."),
193
198
  density: z.enum(["comfortable", "compact"]).optional().describe("compact = one-row bar from 760px wide."),
194
199
  theme: z.record(z.unknown()).optional().describe("Partial ThemeTokens \u2014 deep-merged onto the existing banner theme. Includes `scrollbar`: { style: themed|thin|native|hidden, thumb?, thumbHover?, track?, width? 4\u201316, radius? 0\u2013999 }."),
195
200
  content: z.record(z.unknown()).optional().describe("Partial BannerContent \u2014 banner copy overrides (title, body, button labels, policyUrl, etc.).")
@@ -199,7 +204,7 @@ function registerConfigTools(tool, client) {
199
204
  "Configure v1 banner appearance for a site: preset, type, layout, second layer, density, theme tokens, and copy (content.preferencesTitle titles the preferences dialog). Fetches the current config, patches only those banner fields, and PUTs. Setting type or secondLayer (or layout under the box preset) without a preset removes the stored preset, which would otherwise re-derive them.",
200
205
  setBannerBasicsSchema.shape,
201
206
  async (a) => {
202
- const { cbid: siteId, type, layout, preset, secondLayer, density, theme, content } = setBannerBasicsSchema.parse(a);
207
+ const { cbid: siteId, type, layout, preset, secondLayer, sidebar, density, theme, content } = setBannerBasicsSchema.parse(a);
203
208
  const cfg = await client.sites.getConfig(siteId);
204
209
  const existingBanner = cfg["banner"] ?? {};
205
210
  const existingTheme = existingBanner["theme"] ?? {};
@@ -209,12 +214,14 @@ function registerConfigTools(tool, client) {
209
214
  ...type !== void 0 ? { type } : {},
210
215
  ...layout !== void 0 ? { layout } : {},
211
216
  ...secondLayer !== void 0 ? { secondLayer } : {},
217
+ ...sidebar !== void 0 ? { sidebar: { ...existingBanner["sidebar"], ...sidebar } } : {},
212
218
  ...density !== void 0 ? { density } : {},
213
219
  ...preset !== void 0 ? { preset } : {},
214
220
  ...theme !== void 0 ? { theme: { ...existingTheme, ...theme } } : {},
215
221
  ...content !== void 0 ? { content: { ...existingContent, ...content } } : {}
216
222
  };
217
- const owned = type !== void 0 || secondLayer !== void 0 || layout !== void 0 && banner["preset"] === "box";
223
+ const ownedLayout = layout !== void 0 && (banner["preset"] === "box" || banner["preset"] === "bar" && !["top", "bottom", "push-down"].includes(layout));
224
+ const owned = type !== void 0 || secondLayer !== void 0 || ownedLayout;
218
225
  if (preset === void 0 && owned) delete banner["preset"];
219
226
  return client.sites.putConfig(siteId, { ...cfg, banner });
220
227
  }
@@ -508,6 +515,19 @@ function registerPlatformTools(tool, client) {
508
515
  { days: z2.number().int().positive().optional() },
509
516
  (a) => client.regulatory.upcoming(a.days)
510
517
  );
518
+ tool(
519
+ "get_site_upcoming_regulations",
520
+ "Privacy laws taking effect soon (default 90 days) where a site\u2019s visitors are: those whose jurisdiction holds at least minShare (default 0.01) of the site\u2019s last 30 days of consent decisions. Each has daysUntil, trafficShare and, for a US state law, what changes (GPC duty, sensitive-data opt-in, minors rule). A shipped dataset with a review date, not legal advice.",
521
+ {
522
+ cbid: z2.string().describe("The site id."),
523
+ days: z2.number().int().positive().optional(),
524
+ minShare: z2.number().min(0).max(1).optional()
525
+ },
526
+ (a) => client.regulatory.upcomingForSite(a.cbid, {
527
+ ...a.days !== void 0 ? { days: a.days } : {},
528
+ ...a.minShare !== void 0 ? { minShare: a.minShare } : {}
529
+ })
530
+ );
511
531
  tool(
512
532
  "get_dsr_sla",
513
533
  "The rights queue at a glance: how many requests are overdue, due today, due soon or on track, plus the overdue ids.",
@@ -551,8 +571,10 @@ function registerPlatformTools(tool, client) {
551
571
  revokeAtlasIdGrant: z2.boolean().optional().describe("A preset param, when the preset's params list it: default false. True adds an optional step that revokes the person's app grant on erasure; a credential without the scope reports skipped: insufficient_scope."),
552
572
  label: z2.string().optional().describe("Your name for the credential, shown beside keyPrefix."),
553
573
  system: z2.string().optional().describe("The name this connection answers to in a plan, e.g. identity or crm. Required unless the preset has a default."),
554
- baseUrl: z2.string().optional().describe("The system's public https origin. Required unless the preset sets it."),
555
- secretKey: z2.string().describe("Its API key, with whatever scope that system needs to export and erase a user."),
574
+ baseUrl: z2.string().optional().describe("The system's public https origin, or a base with a path (cm-standard-v1 v4 on: the path replaces /api/privacy; cm-standard-v2: the contract paths hang off it). Required unless the preset sets it."),
575
+ secretKey: z2.string().optional().describe("Its API key, with whatever scope that system needs to export and erase a user. Send this or mintFrom."),
576
+ mintFrom: z2.string().optional().describe("In place of secretKey: a partner id (one that registered an executorKeyUrl, e.g. chatly, forumulate, referalli) that mints the key for the site under its partner link. The connection is scoped to that site. With dryRun, the answer's mint says who would mint it; nothing is minted."),
577
+ externalId: z2.string().optional().describe("With mintFrom: the partner account the key is minted for. Default: the one the site's live link for that partner names."),
556
578
  webhookSecret: z2.string().optional().describe("Signing secret of its webhook endpoint. Optional: polling closes tasks without it."),
557
579
  auto: z2.boolean().optional().describe("Open a sub-task automatically when a request reaches fulfilment. Default true."),
558
580
  orchestrator: z2.union([z2.literal(1), z2.literal(2)]).optional().describe("How it takes part in cases. Default 2 (v2 headers on every call); 1 is the v1 adapter. The answer carries a completionSecret, shown once, that signs its completions."),
@@ -921,12 +943,12 @@ function registerKeyAndTagTools(tool, client) {
921
943
  const tagsSchema = z4.object({
922
944
  type: z4.enum(TAGGED),
923
945
  id: z4.string(),
924
- metadata: z4.record(z4.union([z4.string(), z4.number(), z4.boolean(), z4.null()])).describe("Keys to set; null removes one. forgedeck_sandbox cannot be set here."),
946
+ metadata: z4.record(z4.union([z4.string(), z4.number(), z4.boolean(), z4.null()])).describe("Keys to set; null removes one. stack_sandbox cannot be set here."),
925
947
  dryRun: z4.boolean().optional().describe("Answer with the diff, storing nothing. Do this first.")
926
948
  });
927
949
  tool(
928
950
  "update_resource_tags",
929
- "Change a resource\u2019s tags (merge). For adopting resources created before tags existed, e.g. forgedeck_product and forgedeck_env. A resource can never be made a sandbox after it was created.",
951
+ "Change a resource\u2019s tags (merge). For adopting resources created before tags existed, e.g. stack_product and stack_env. A resource can never be made a sandbox after it was created.",
930
952
  tagsSchema.shape,
931
953
  (a) => {
932
954
  const { type, id, metadata, dryRun } = tagsSchema.parse(a);
@@ -961,7 +983,7 @@ function registerKeyAndTagTools(tool, client) {
961
983
  );
962
984
  tool(
963
985
  "get_provision_env",
964
- "What `forgedeck env` writes for a product provisioned with this forgedeck ref: variable names, non-secret values (cbid, script URL, API base) and references for secrets, never a secret. Read-only.",
986
+ "What `env` writes for a product provisioned with this stack ref: variable names, non-secret values (cbid, script URL, API base) and references for secrets, never a secret. Read-only.",
965
987
  { ref: z4.string() },
966
988
  (a) => client.provisionEnv(a.ref)
967
989
  );
@@ -1407,13 +1429,13 @@ ${JSON.stringify(r, null, 2)}` : r;
1407
1429
  type: z6.string().describe("access | deletion | closure | restriction | rectification, or erasure / erase / export."),
1408
1430
  emails: z6.array(z6.string()).optional().describe("The person's addresses."),
1409
1431
  identity: z6.object({ iss: z6.string(), sub: z6.string(), ext: z6.string().optional(), principal: z6.string().optional() }).optional().describe("A signed-in identity from the site's sign-in issuer. People are never linked on email when it is present."),
1410
- source: z6.enum(["product", "atlas", "admin"]).optional(),
1432
+ source: z6.enum(["product", "identity", "admin"]).optional().describe("identity: the site's sign-in provider, whichever it is."),
1411
1433
  reason: z6.string().optional(),
1412
1434
  skipSystems: z6.array(z6.string()).optional().describe("System names, connection ids, or self."),
1413
1435
  fulfill: z6.boolean().optional(),
1414
1436
  test: z6.boolean().optional(),
1415
1437
  idempotencyKey: z6.string().optional(),
1416
- trace: z6.string().optional().describe("An X-ForgeDeck-Trace to keep, from the caller.")
1438
+ trace: z6.string().optional().describe("An X-Trace-Id to keep, from the caller.")
1417
1439
  },
1418
1440
  (a) => client.dsar.openCase(
1419
1441
  {
@@ -1452,7 +1474,7 @@ ${JSON.stringify(r, null, 2)}` : r;
1452
1474
  );
1453
1475
  tool(
1454
1476
  "find_dsar_by_trace",
1455
- "The rights request carrying one X-ForgeDeck-Trace id \u2014 to follow one event across products. Read-only.",
1477
+ "The rights request carrying one X-Trace-Id id \u2014 to follow one event across products. Read-only.",
1456
1478
  { trace: z6.string() },
1457
1479
  (a) => client.dsar.listByTrace(a.trace)
1458
1480
  );
@@ -1482,6 +1504,22 @@ ${JSON.stringify(r, null, 2)}` : r;
1482
1504
  typeof a.iss === "string" && typeof a.sub === "string" ? { iss: a.iss, sub: a.sub } : { email: String(a.email ?? "") }
1483
1505
  )
1484
1506
  );
1507
+ tool(
1508
+ "connect_identity_provider",
1509
+ "Connect an identity provider's privacy orchestrator in one call, so it opens a rights case here when a person deletes their account there. Mints a key holding only dsar:write, locked to the site (no keys:write needed), and hands it to the provider, authorised with the provider instance key. The minted key is never returned, only its prefix; connecting again replaces it. Built in: atlas. Any other provider: pass connector. Run with dryRun first: it mints and sends nothing.",
1510
+ {
1511
+ provider: z6.string().describe("The provider id, e.g. atlas."),
1512
+ cbid: z6.string().describe("The site the provider opens cases on."),
1513
+ providerKey: z6.string().describe("The provider instance's secret key (Atlas: the instance secret key). Used for this one call, never stored."),
1514
+ connector: z6.object({ url: z6.string(), method: z6.enum(["PUT", "POST"]).optional(), body: z6.record(z6.unknown()) }).optional().describe('Only for a provider with no built-in connector: its https orchestrator URL and JSON body; a body value "{apiKey}" becomes the minted key.'),
1515
+ dryRun: z6.boolean().optional().describe("Show the key and the request that would be made, minting and sending nothing.")
1516
+ },
1517
+ (a) => client.integrations.connect(
1518
+ a.provider,
1519
+ { cbid: a.cbid, providerKey: a.providerKey, ...a.connector ? { connector: a.connector } : {} },
1520
+ { dryRun: a.dryRun === true }
1521
+ )
1522
+ );
1485
1523
  tool(
1486
1524
  "advance_dsar",
1487
1525
  "Advance a DSAR to a new status (received \u2192 verifying \u2192 in_progress \u2192 completed, or rejected).",
@@ -1869,7 +1907,7 @@ ${JSON.stringify(r, null, 2)}` : r;
1869
1907
  (a) => client.sites.applyImport(a.cbid, a.data, a.overwrite ? { overwrite: true } : void 0)
1870
1908
  );
1871
1909
  const declarationShape = {
1872
- category: z6.string().describe("necessary, preferences, statistics, marketing, or one of the site\u2019s categories.custom ids."),
1910
+ category: z6.string().describe("necessary, preferences, statistics, marketing, or one of the site\u2019s categories.suite or categories.custom ids."),
1873
1911
  purpose: z6.string().describe("What the cookie does, as visitors will read it \u2014 and the fallback for any language purposes lacks."),
1874
1912
  purposes: z6.record(z6.string(), z6.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.'),
1875
1913
  provider: z6.string().optional(),
@@ -2419,7 +2457,7 @@ ${JSON.stringify(r, null, 2)}` : r;
2419
2457
  }
2420
2458
 
2421
2459
  // src/index.ts
2422
- var MCP_VERSION = "0.7.1";
2460
+ var MCP_VERSION = "0.9.0";
2423
2461
  function createCookieMunchMcp(opts) {
2424
2462
  const client = opts.client ?? createCookieMunch({ apiKey: opts.apiKey, baseUrl: opts.baseUrl, userAgent: opts.userAgent ?? `cookiemunch-mcp/${MCP_VERSION}` });
2425
2463
  const server = new McpServer({ name: "cookiemunch", version: "1.0.0" });
@@ -2432,4 +2470,4 @@ export {
2432
2470
  MCP_VERSION,
2433
2471
  createCookieMunchMcp
2434
2472
  };
2435
- //# sourceMappingURL=chunk-3C3J6N2L.js.map
2473
+ //# sourceMappingURL=chunk-FI6MOPOJ.js.map