@kaminari-ad/mcp 0.2.1 → 0.3.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 CHANGED
@@ -7,6 +7,126 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2026-05-20
11
+
12
+ Major-feature release — full parity with the API surface added in
13
+ COOP-13940 Phase 3 (custom taxonomies + 5-kind policy rules + binary
14
+ downloads). **Contains breaking changes for existing agents** —
15
+ review the migration notes below before upgrading.
16
+
17
+ ### Breaking
18
+
19
+ - **`update_tag_definition`**: input field `show_in_public_report`
20
+ (boolean) was removed; replaced by `visibility` (enum:
21
+ `hidden | internal | public`). Old payloads now fail zod
22
+ validation locally with a typed `invalid-input` error before
23
+ hitting the API. Migration: replace `show_in_public_report: true`
24
+ → `visibility: "public"`, and `show_in_public_report: false` →
25
+ `visibility: "internal"` (or `"hidden"` if you want the tag
26
+ fully suppressed).
27
+ - **`list_alerts`**: `status` filter no longer accepts the legacy
28
+ values `"ack"` / `"ignored"`. The canonical four are
29
+ `"open"`, `"acknowledged"`, `"resolved"`, `"dismissed"`. Mapping:
30
+ `"ack"` → `"acknowledged"`, `"ignored"` → `"dismissed"`.
31
+ - **`create_policy_set` / `update_policy_set`**: `entries[]` is now
32
+ a discriminated union over **five rule kinds**. Existing tag-only
33
+ callers MUST add `rule_type: "tag"` to every entry. Other kinds:
34
+ `"iab_v3"` (with `iab_v3: { tier1, tier2?, tier3?, tier4? }`),
35
+ `"brand"` (with `brand: string`), `"ai_category"` (with
36
+ `ai_category: { tier1, tier2?, tier3?, tier4? }`),
37
+ `"custom_taxonomy"` (with `custom_taxonomy: { taxonomy_id, tier1,
38
+ tier2?, tier3?, tier4? }`).
39
+ `country_codes` now accepts both ISO alpha-2 and alpha-3 (the
40
+ API normalises).
41
+
42
+ ### Added
43
+
44
+ - **`custom_taxonomies` tool suite (7 tools).** Per-org
45
+ classification trees with an `is_default` fallback node:
46
+ `list_custom_taxonomies`, `get_custom_taxonomy`,
47
+ `create_custom_taxonomy`, `update_custom_taxonomy`,
48
+ `delete_custom_taxonomy` (soft-delete), `restore_custom_taxonomy`,
49
+ `parse_custom_taxonomy_text` (no-persistence preview).
50
+ - **Account labels.** `list_account_labels` + `update_account_labels`
51
+ for the per-org metadata schema that backs `list_scans.labels`
52
+ filters. `update_account_labels` is hinted destructive — passing
53
+ `labels: []` wipes the catalogue.
54
+ - **`create_custom_role`** for `/api/v1/account/roles` POST.
55
+ - **Binary downloads** — `get_invoice_pdf` (MCP `resource` block),
56
+ `get_scan_screenshot`, `get_scan_creative_screenshot`,
57
+ `get_scan_landing_screenshot` (MCP `image` blocks). All four
58
+ return inline base64 with the API-supplied `mimeType` so agents
59
+ can save / forward without a second call.
60
+ - **`list_alerts` rule_type + matched_value.** Each alert row now
61
+ carries `rule_type` (one of the five kinds) and `matched_value`
62
+ (the canonical text the scan matched against). Lets agents
63
+ branch on rule kind without re-fetching the scan.
64
+ - **`list_policy_sets.visibility` filter.** Narrow to
65
+ `private` (org-owned) or `public` (Kaminari Ad-curated). Omit
66
+ the filter to see both combined.
67
+ - **`list_scans` filters.** Added `run_id`, `campaign_id`,
68
+ `group_id`, `timezone`, `ai_category`, `iab_v3_category`,
69
+ `iab_category`, `brand`, plus a typed `labels` record that
70
+ expands to `label_<key>=<value>` query params (snake_case keys
71
+ enforced by zod).
72
+ - **Misc query filters.** `list_campaigns` + `list_campaigns_picker`
73
+ gained `archived` / `q`; `list_invoices` gained `type` / `status`
74
+ enums; `list_balance_history` gained multi-select `type`;
75
+ `list_webhook_deliveries` gained `success` / `from_ts` / `to_ts`;
76
+ `list_usage` switched to ISO 8601 datetime bounds; `list_tags`
77
+ gained `category`.
78
+
79
+ ### Changed
80
+
81
+ - **OpenAPI types regenerated.** `src/shared/api/openapi.ts` and
82
+ `src/shared/api/zod-schemas.ts` are rebuilt from the prod API and
83
+ capture every Phase 3 schema (custom-taxonomies, 5-kind
84
+ PolicyEntry, AlertResponse `rule_type` / `matched_value`, tag
85
+ visibility rename).
86
+ - **Tool descriptions.** Policy-sets, alerts, and tag tools updated
87
+ to mention the new fields. `get_alert_stats` description uses the
88
+ canonical AlertStatus names.
89
+ - **Branding.** All user-visible tool descriptions and JSDoc use the
90
+ canonical `Kaminari Ad` (with space) per the updated branding
91
+ rule. The dotted form `Kaminari.Ad` is deprecated.
92
+
93
+ ### Quality gates
94
+
95
+ - 705 unit tests (was 623). Coverage 100% statements / 100% lines /
96
+ 100% functions / 97.89% branches (gate is 95% branches). Every
97
+ new tool has at least 3 cases (success / api-error /
98
+ zod-rejection); policy-set tools cover all five rule kinds with
99
+ per-kind missing-block rejection tests.
100
+ - All existing gates pass: lint, format, typecheck, tool-naming,
101
+ file-sizes (8 grandfathered, every new file <200 effective
102
+ lines), check-imports, check-shared-state,
103
+ check-no-handwritten-parsers.
104
+
105
+ ## [0.2.2] - 2026-05-20
106
+
107
+ Minor release — adds one-click install paths for Cursor and Claude
108
+ Desktop. No tool surface change, no breaking API behaviour change.
109
+
110
+ ### Added
111
+
112
+ - **Claude Desktop `.mcpb` extension bundle.** Each tag release now
113
+ builds a single-file `kaminari-ad-mcp.mcpb` (via the new
114
+ `tsup.mcpb.config.ts` + `mcpb pack`) and uploads it to the GitHub
115
+ Release. Stable download URL:
116
+ <https://github.com/kaminari-ad/mcp/releases/latest/download/kaminari-ad-mcp.mcpb>.
117
+ Double-click installs into Claude Desktop with a config form for
118
+ the API key and a ToS-acceptance checkbox.
119
+ - **Cursor one-click install badge.** README and the Kaminari Ad
120
+ marketing site link the official Cursor "Install in Cursor" badge
121
+ to a trampoline page (`https://kaminari.ad/mcp/install`) that
122
+ redirects to the `cursor://anysphere.cursor-deeplink/mcp/install`
123
+ URL with the npx-based stdio config pre-encoded.
124
+ - **`server.json`** for [registry.modelcontextprotocol.io][mcp-reg]
125
+ listing. Surface (npm stdio package, env vars) mirrors what the
126
+ README documents.
127
+
128
+ [mcp-reg]: https://registry.modelcontextprotocol.io
129
+
10
130
  ## [0.2.1] - 2026-05-18
11
131
 
12
132
  Patch release — clear Node-version error message, correct `engines`
package/README.md CHANGED
@@ -1,13 +1,35 @@
1
1
  # `@kaminari-ad/mcp`
2
2
 
3
- Official Model Context Protocol (MCP) server for [Kaminari Ad](https://kaminari.ad) — the ad verification platform from the team behind [Kaminari.Click](https://kaminari.click).
3
+ Official Model Context Protocol (MCP) server for [Kaminari Ad](https://kaminari.ad) — the ad verification platform from the team behind [Kaminari Click](https://kaminari.click).
4
4
 
5
5
  Lets AI agents (Cursor, Claude Desktop, Cline, and any MCP-compatible client) launch scans, inspect results, manage campaigns and policies, and read alerts directly against your Kaminari Ad workspace via your API key.
6
6
 
7
- [![npm](https://img.shields.io/npm/v/@kaminari-ad/mcp.svg)](https://www.npmjs.com/package/@kaminari-ad/mcp)
8
- [![CI](https://github.com/kaminari-ad/mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/kaminari-ad/mcp/actions/workflows/ci.yml)
7
+ [![npm version](https://img.shields.io/npm/v/@kaminari-ad/mcp)](https://www.npmjs.com/package/@kaminari-ad/mcp)
8
+ [![npm downloads](https://img.shields.io/npm/dm/@kaminari-ad/mcp)](https://www.npmjs.com/package/@kaminari-ad/mcp)
9
9
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
10
+ [![node](https://img.shields.io/node/v/@kaminari-ad/mcp)](https://nodejs.org)
11
+ [![CI](https://github.com/kaminari-ad/mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/kaminari-ad/mcp/actions/workflows/ci.yml)
10
12
  [![Provenance](https://img.shields.io/npm/v/@kaminari-ad/mcp?label=provenance&logo=github)](https://www.npmjs.com/package/@kaminari-ad/mcp)
13
+ [![MCP Registry](https://img.shields.io/badge/MCP_Registry-listed-blue)](https://registry.modelcontextprotocol.io)
14
+
15
+ ## Install (one click)
16
+
17
+ ### Cursor
18
+
19
+ <a href="https://kaminari.ad/mcp/install"><img alt="Install in Cursor" src="https://cursor.com/deeplink/mcp-install-dark.png" height="32" /></a>
20
+
21
+ ### Claude Desktop
22
+
23
+ [**Download `kaminari-ad-mcp.mcpb`**](https://github.com/kaminari-ad/mcp/releases/latest/download/kaminari-ad-mcp.mcpb) → double-click to install. Claude Desktop shows a config form for your API key.
24
+
25
+ ### Claude Code (CLI)
26
+
27
+ ```bash
28
+ claude mcp add kaminari-ad -- npx -y @kaminari-ad/mcp
29
+ export KAMINARI_AD_API_KEY=your-key
30
+ ```
31
+
32
+ Full installation docs — see [Quick start](#quick-start) below.
11
33
 
12
34
  ---
13
35
 
@@ -67,11 +89,11 @@ For cloud agents or clients without a local Node runtime, point at the hosted en
67
89
  83 tools mirroring most of the public `/api/v1` surface of Kaminari Ad. Every tool carries MCP behaviour annotations (`title`, `readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`) so MCP clients can warn before destructive actions. Highlights:
68
90
 
69
91
  - **Account** (11) — `get_account`, `update_org`, `list_org_users`, `invite_user`, `update_user_role`, `remove_user`, `transfer_ownership`, `list_org_roles`, `list_api_keys`, `create_api_key`, `revoke_api_key`
70
- - **Scans** (7) — `list_scans`, `get_scan`, `create_scan`, `create_bulk_scans`, `recheck_scans`, `cancel_scan`, `list_scan_tags`
92
+ - **Scans** (6) — `list_scans`, `get_scan`, `create_scan`, `create_bulk_scans`, `recheck_scans`, `cancel_scan`
71
93
  - **Campaigns** (10) — `list_campaigns`, `list_campaigns_picker`, `get_campaign`, `create_campaign`, `update_campaign`, `archive_campaign`, `unarchive_campaign`, `cancel_campaign`, `run_campaign`, `list_campaign_runs`
72
94
  - **Campaign groups** (10) — list/get/create/update/run/cancel/archive/unarchive + `pause_campaign_group_schedule`, `resume_campaign_group_schedule`
73
95
  - **Runs** (3) — `get_run`, `list_run_scans`, `cancel_run` (use `list_campaign_runs` to enumerate runs of a campaign — the API has no standalone `/runs` index)
74
- - **Tags** (4) — `list_tags`, `get_tag_definition`, `update_tag_definition`, `delete_tag_definition`
96
+ - **Tags** (5) — `list_tags`, `get_tag_definition`, `update_tag_definition`, `delete_tag_definition`, `list_scan_tags`
75
97
  - **Custom rules** (6) — `list_custom_rules`, `get_custom_rule`, `create_custom_rule`, `update_custom_rule`, `delete_custom_rule`, `test_custom_rule`
76
98
  - **Policy sets** (6) — `list_policy_sets`, `get_policy_set`, `create_policy_set`, `update_policy_set`, `delete_policy_set`, `request_policy_set_approval`
77
99
  - **Alerts** (3) — `list_alerts`, `update_alert_status`, `get_alert_stats`
package/dist/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { NAME, VERSION, err, ok } from './chunk-2H457UAT.js';
2
+ import { NAME, VERSION, err, ok } from './chunk-KTQBHJUB.js';
3
3
  import process from 'process';
4
4
  import { z } from 'zod';
5
5
 
@@ -119,10 +119,10 @@ async function main() {
119
119
  }
120
120
  const config = configResult.value;
121
121
  if (config.transport === "stdio") {
122
- const { bootstrapStdio } = await import('./stdio-bootstrap-V64J2Z55.js');
122
+ const { bootstrapStdio } = await import('./stdio-bootstrap-RBANZT6F.js');
123
123
  return bootstrapStdio(config);
124
124
  }
125
- const { bootstrapHttp } = await import('./http-bootstrap-4MLE6RO4.js');
125
+ const { bootstrapHttp } = await import('./http-bootstrap-FGGCFLRU.js');
126
126
  return bootstrapHttp(config);
127
127
  }
128
128
  main().then(
@@ -3,8 +3,8 @@ export { err, ok } from 'neverthrow';
3
3
 
4
4
  // src/shared/version.ts
5
5
  var NAME = "@kaminari-ad/mcp";
6
- var VERSION = "0.2.1";
6
+ var VERSION = "0.3.0";
7
7
 
8
8
  export { NAME, VERSION };
9
- //# sourceMappingURL=chunk-2H457UAT.js.map
10
- //# sourceMappingURL=chunk-2H457UAT.js.map
9
+ //# sourceMappingURL=chunk-KTQBHJUB.js.map
10
+ //# sourceMappingURL=chunk-KTQBHJUB.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";;;;AASO,IAAM,IAAA,GAAO;AACb,IAAM,OAAA,GAAU","file":"chunk-2H457UAT.js","sourcesContent":["/**\n * Package version and name. Hard-coded as constants here, asserted to\n * match `package.json` by a unit test.\n *\n * Why not import `package.json`: it would force JSON-module support at\n * runtime and tsup-bundling would inline the entire manifest. Two\n * constants + one assertion test is simpler and gives the same safety.\n */\n\nexport const NAME = \"@kaminari-ad/mcp\";\nexport const VERSION = \"0.2.1\";\n"]}
1
+ {"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";;;;AASO,IAAM,IAAA,GAAO;AACb,IAAM,OAAA,GAAU","file":"chunk-KTQBHJUB.js","sourcesContent":["/**\n * Package version and name. Hard-coded as constants here, asserted to\n * match `package.json` by a unit test.\n *\n * Why not import `package.json`: it would force JSON-module support at\n * runtime and tsup-bundling would inline the entire manifest. Two\n * constants + one assertion test is simpler and gives the same safety.\n */\n\nexport const NAME = \"@kaminari-ad/mcp\";\nexport const VERSION = \"0.3.0\";\n"]}