@cookiemunch/mcp 0.4.0 → 0.5.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/CHANGELOG.md ADDED
@@ -0,0 +1,44 @@
1
+ # Changelog: @cookiemunch/mcp
2
+
3
+ Every published release, newest first. Dates are the day the version was cut. Each release tracks the same-numbered `@cookiemunch/sdk`.
4
+
5
+ ## 0.5.0 (2026-10-23)
6
+
7
+ - Added: `get_org_controller`, `set_org_controller`, `remove_org_controller`.
8
+ - Added: `get_consent_sync_secret`, `rotate_consent_sync_secret`, `remove_consent_sync_secret`.
9
+ - Added: `mint_preference_center_token`.
10
+ - Changed: built on `@cookiemunch/sdk` 0.5.0.
11
+
12
+ ## 0.4.1 (2026-10-22)
13
+
14
+ - Added: `apply_cookie_preset` takes `referally` (`cookieDomain`, `cookieDays`, `category`).
15
+ - Added: requests send `User-Agent: cookiemunch-mcp/<version>`.
16
+
17
+ ## 0.4.0 (2026-10-19)
18
+
19
+ - Added: tools for site PATCH, integration health, `provision` and partner links.
20
+ - Added: executor preset and canary tools; declaration preset tools and observed-cookie removal.
21
+
22
+ ## 0.3.0 (2026-10-15)
23
+
24
+ - Added: `retire_cookie` and `unretire_cookie`; `scan_site` can wait for the result, including a scan already running.
25
+
26
+ ## 0.2.0 (2026-10-15)
27
+
28
+ - Added: executor webhook test and delivery log with dry runs.
29
+ - Added: `purposes` and `dryRun` on declared cookies; rights-page identity tools.
30
+ - Fixed: design-warning headers say what happened; notices are not blamed on Accept.
31
+
32
+ ## 0.1.2 (2026-10-15)
33
+
34
+ - Changed: the package builds standalone from its public repository and is published with npm provenance.
35
+
36
+ ## 0.1.1 (2026-10-14)
37
+
38
+ - Added: tools to declare, bulk-declare and undeclare cookies and to apply an import.
39
+ - Added: `preview_site_config` (dry run) and design warnings leading every config tool result.
40
+ - Added: rights-page tools (read, write, preview, publish, versions, rollback) and custom-domain tools.
41
+
42
+ ## 0.1.0 (2026-10-14)
43
+
44
+ - First release: the Developer API as MCP tools (`whoami`, sites, config, consent stats and log, DSAR, vendors, RoPA).
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cookie Munch
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/bin.cjs CHANGED
@@ -1515,6 +1515,21 @@ ${JSON.stringify(r, null, 2)}` : r;
1515
1515
  { subjectId: import_zod5.z.string() },
1516
1516
  (a) => client.preferences.get(a.subjectId)
1517
1517
  );
1518
+ tool(
1519
+ "mint_preference_center_token",
1520
+ "Mint a hosted preference-centre token for one visitor (POST /v1/preference-center/tokens), for a page to pass to CookieMunch.setSubjectToken. Give exactly one of email (resolved as the emailed preference link resolves it; an unknown address is subject_not_found) or subjectId. The token is a credential that opens that person\u2019s subscriptions and profile until expiresAt: never paste it into a shared URL, a ticket or a log, and keep ttlSeconds short (default 3600, max 86400). Needs subscriptions:write and profile:write, plus identity:read by email.",
1521
+ {
1522
+ cbid: import_zod5.z.string().describe("A site of your organisation."),
1523
+ email: import_zod5.z.string().optional().describe("The visitor\u2019s address. Give this or subjectId, not both."),
1524
+ subjectId: import_zod5.z.string().optional().describe("The subject id. Give this or email, not both."),
1525
+ ttlSeconds: import_zod5.z.number().int().min(1).max(86400).optional()
1526
+ },
1527
+ (a) => client.preferenceCenter.mintToken({
1528
+ cbid: a.cbid,
1529
+ ...a.email !== void 0 ? { email: a.email } : { subjectId: a.subjectId },
1530
+ ...a.ttlSeconds !== void 0 ? { ttlSeconds: a.ttlSeconds } : {}
1531
+ })
1532
+ );
1518
1533
  tool(
1519
1534
  "issue_api_key",
1520
1535
  "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.",
@@ -1614,7 +1629,7 @@ ${JSON.stringify(r, null, 2)}` : r;
1614
1629
  );
1615
1630
  tool(
1616
1631
  "list_cookie_presets",
1617
- "Declaration presets for the platforms a site is built on (atlas, forumulate, chatly, cookiemunch): each one\u2019s parameters, what it has declared on this site, and whether the vendor\u2019s live manifest can be imported yet. Read-only.",
1632
+ "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.",
1618
1633
  { cbid: import_zod5.z.string() },
1619
1634
  (a) => client.sites.cookiePresets(a.cbid)
1620
1635
  );
@@ -1623,24 +1638,26 @@ ${JSON.stringify(r, null, 2)}` : r;
1623
1638
  "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.",
1624
1639
  {
1625
1640
  cbid: import_zod5.z.string(),
1626
- vendor: import_zod5.z.enum(["atlas", "forumulate", "chatly", "cookiemunch"]),
1641
+ vendor: import_zod5.z.enum(["atlas", "forumulate", "chatly", "cookiemunch", "referally"]),
1627
1642
  frontendApiHost: import_zod5.z.string().optional().describe("Atlas: your frontend API host, e.g. auth.example.com."),
1628
1643
  crossSubdomainCookies: import_zod5.z.boolean().optional().describe("Atlas: default true \u2014 the cookies live on the parent domain."),
1629
1644
  publicId: import_zod5.z.string().optional().describe("Chatly: the channel public id (ch_web_\u2026)."),
1630
1645
  dragging: import_zod5.z.boolean().optional().describe("Chatly: the launcher can be dragged (adds the drag-position key)."),
1631
- category: import_zod5.z.string().optional().describe("Chatly: the category for its keys. Default necessary."),
1646
+ category: import_zod5.z.string().optional().describe("Chatly: the category for its keys (default necessary). Referally: default the site's referrals category, else marketing."),
1647
+ cookieDomain: import_zod5.z.string().optional().describe("Referally: the domain aff.js sets referally_ctx on, e.g. .example.com. Default the site domain."),
1648
+ cookieDays: import_zod5.z.number().int().min(1).max(400).optional().describe("Referally: how long the cookie lives, 1 to 400 days. Default 60."),
1632
1649
  dryRun: dryRunArg
1633
1650
  },
1634
1651
  (a) => {
1635
1652
  const params = {};
1636
- for (const k of ["frontendApiHost", "crossSubdomainCookies", "publicId", "dragging", "category"]) if (a[k] !== void 0) params[k] = a[k];
1653
+ for (const k of ["frontendApiHost", "crossSubdomainCookies", "publicId", "dragging", "category", "cookieDomain", "cookieDays"]) if (a[k] !== void 0) params[k] = a[k];
1637
1654
  return client.sites.applyCookiePreset(a.cbid, a.vendor, params, a.dryRun ? { dryRun: true } : void 0);
1638
1655
  }
1639
1656
  );
1640
1657
  tool(
1641
1658
  "remove_cookie_preset",
1642
1659
  "Remove every declaration a vendor preset made on this site.",
1643
- { cbid: import_zod5.z.string(), vendor: import_zod5.z.enum(["atlas", "forumulate", "chatly", "cookiemunch"]), dryRun: dryRunArg },
1660
+ { cbid: import_zod5.z.string(), vendor: import_zod5.z.enum(["atlas", "forumulate", "chatly", "cookiemunch", "referally"]), dryRun: dryRunArg },
1644
1661
  (a) => client.sites.removeCookiePreset(a.cbid, a.vendor, a.dryRun ? { dryRun: true } : void 0)
1645
1662
  );
1646
1663
  tool(
@@ -1742,6 +1759,37 @@ ${JSON.stringify(r, null, 2)}` : r;
1742
1759
  return { removed: true };
1743
1760
  }
1744
1761
  );
1762
+ tool(
1763
+ "get_org_controller",
1764
+ "The organisation\u2019s own data-controller identity: who every rights notice names, before any site config controller block. `set: false` when there is none. Read-only.",
1765
+ {},
1766
+ () => client.org.controller.get()
1767
+ );
1768
+ tool(
1769
+ "set_org_controller",
1770
+ "Set the organisation\u2019s data-controller identity. Replaces it: a field left out is removed. Needed for a notice on a rights request filed without a cbid when the organisation has several sites. Needs an unscoped key or rights:write. Audited.",
1771
+ {
1772
+ legalName: import_zod5.z.string().describe("Required: the legal name of the data controller."),
1773
+ contactEmail: import_zod5.z.string().optional().describe("Where people reach the controller about their data."),
1774
+ address: import_zod5.z.string().optional(),
1775
+ dpoContact: import_zod5.z.string().optional().describe("The Data Protection Officer: a name, an email address, or both.")
1776
+ },
1777
+ (a) => client.org.controller.set({
1778
+ legalName: a.legalName,
1779
+ ...a.contactEmail !== void 0 ? { contactEmail: a.contactEmail } : {},
1780
+ ...a.address !== void 0 ? { address: a.address } : {},
1781
+ ...a.dpoContact !== void 0 ? { dpoContact: a.dpoContact } : {}
1782
+ })
1783
+ );
1784
+ tool(
1785
+ "remove_org_controller",
1786
+ "Remove the organisation\u2019s data-controller identity. Notices then name the request\u2019s site config controller block; a request without a cbid in an organisation with several sites gets no notice.",
1787
+ {},
1788
+ async () => {
1789
+ await client.org.controller.remove();
1790
+ return { removed: true };
1791
+ }
1792
+ );
1745
1793
  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.";
1746
1794
  const captchaInput = {
1747
1795
  mode: import_zod5.z.enum(["own", "off"]).describe(`own: your own captcha provider keys (recommended). off: no captcha. ${CAPTCHA_OFF}`),
@@ -1757,6 +1805,24 @@ ${JSON.stringify(r, null, 2)}` : r;
1757
1805
  ...a.secret !== void 0 ? { secret: a.secret } : {},
1758
1806
  ...a.minScore !== void 0 ? { minScore: a.minScore } : {}
1759
1807
  });
1808
+ tool(
1809
+ "get_consent_sync_secret",
1810
+ "Whether hosted consent sync is set up for a site: `configured`, `secretLast4`, `createdAt`. Never returns the secret. Read-only.",
1811
+ { cbid: import_zod5.z.string() },
1812
+ (a) => client.consentSyncSecret.get(a.cbid)
1813
+ );
1814
+ tool(
1815
+ "rotate_consent_sync_secret",
1816
+ "Mint a site\u2019s consent-sync signing secret, or rotate it. The answer carries `secret` this once; the site owner\u2019s server signs consent-sync tokens with it (mintConsentSyncToken in @cookiemunch/sdk). Rotating stops the old secret at once, so every page holding a token signed with it stops syncing until it gets a new token. Never put the secret in a page. Needs sites:write and consent:write.",
1817
+ { cbid: import_zod5.z.string() },
1818
+ (a) => client.consentSyncSecret.rotate(a.cbid)
1819
+ );
1820
+ tool(
1821
+ "remove_consent_sync_secret",
1822
+ "Remove a site\u2019s consent-sync secret: hosted consent sync stops until a new one is minted. Needs sites:write and consent:write.",
1823
+ { cbid: import_zod5.z.string() },
1824
+ (a) => client.consentSyncSecret.remove(a.cbid)
1825
+ );
1760
1826
  tool(
1761
1827
  "get_rights_captcha",
1762
1828
  "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.",
@@ -1998,8 +2064,9 @@ ${JSON.stringify(r, null, 2)}` : r;
1998
2064
  }
1999
2065
 
2000
2066
  // src/index.ts
2067
+ var MCP_VERSION = "0.5.0";
2001
2068
  function createCookieMunchMcp(opts) {
2002
- const client = opts.client ?? (0, import_sdk.createCookieMunch)({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });
2069
+ const client = opts.client ?? (0, import_sdk.createCookieMunch)({ apiKey: opts.apiKey, baseUrl: opts.baseUrl, userAgent: opts.userAgent ?? `cookiemunch-mcp/${MCP_VERSION}` });
2003
2070
  const server = new import_mcp.McpServer({ name: "cookiemunch", version: "1.0.0" });
2004
2071
  registerTools(server, client);
2005
2072
  return server;
@@ -2013,7 +2080,7 @@ async function main() {
2013
2080
  process.exit(1);
2014
2081
  }
2015
2082
  const baseUrl = process.env.COOKIEMUNCH_BASE_URL ?? "https://api.cookiemunch.net";
2016
- const server = createCookieMunchMcp({ apiKey, baseUrl });
2083
+ const server = createCookieMunchMcp({ apiKey, baseUrl, ...process.env.COOKIEMUNCH_USER_AGENT ? { userAgent: process.env.COOKIEMUNCH_USER_AGENT } : {} });
2017
2084
  const transport = new import_stdio.StdioServerTransport();
2018
2085
  await server.connect(transport);
2019
2086
  }