@kaminari-ad/mcp 0.1.0 → 0.2.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 +198 -1
- package/MIGRATION_0_2.md +139 -0
- package/README.md +8 -6
- package/dist/bin.js +181 -43
- package/dist/bin.js.map +1 -1
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,198 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.0] - 2026-05-17
|
|
11
|
+
|
|
12
|
+
Comprehensive parser-drift sweep across all `/api/v1/*` list
|
|
13
|
+
endpoints, a new tool for slim campaign selection, an MCP-client
|
|
14
|
+
interop fix, and small docs polish. Semver-minor because three list
|
|
15
|
+
tools changed output shape (breaking) and one new tool was added.
|
|
16
|
+
|
|
17
|
+
The MCP audit covered every `/api/v1/*` list endpoint. The MCP
|
|
18
|
+
already wrapped 21 of them — 18 were correctly wired, 3 had drift
|
|
19
|
+
(now fixed: `list_run_scans`, `list_custom_rules`, `list_policy_sets`).
|
|
20
|
+
One additional list endpoint (`/campaigns/picker`) had no MCP wrapper
|
|
21
|
+
and was added as the new `list_campaigns_picker` tool. The detail
|
|
22
|
+
endpoint `get_tag_definition` was also fixed to surface
|
|
23
|
+
`linked_rules`. See [MIGRATION_0_2.md](https://github.com/kaminari-ad/mcp/blob/main/MIGRATION_0_2.md)
|
|
24
|
+
for the agent-side migration notes.
|
|
25
|
+
|
|
26
|
+
### Breaking
|
|
27
|
+
|
|
28
|
+
- **`list_run_scans` output element type:** `ScanBriefResponse` →
|
|
29
|
+
`ScanTileResponse`. The slim DTO drops `url` / `created_at` /
|
|
30
|
+
`labels` / `campaign_id` / `campaign_name` / `is_ad_tag` and adds
|
|
31
|
+
`error`. The tool no longer fails on prod data with `malformed
|
|
32
|
+
scans page: items.0.url: Required`; agents needing full scan
|
|
33
|
+
details should call `get_scan` per tile.
|
|
34
|
+
- **`list_custom_rules` output shape:** `readonly CustomRuleResponse[]`
|
|
35
|
+
→ `PaginatedResponse<CustomRuleResponse>`. New optional
|
|
36
|
+
`page` / `limit` inputs (defaults `1` / `50`). Previously the tool
|
|
37
|
+
silently dropped pagination metadata; orgs with > 50 rules
|
|
38
|
+
appeared to have exactly 50.
|
|
39
|
+
- **`list_policy_sets` output shape:** `readonly PolicySetListItemResponse[]`
|
|
40
|
+
→ `PaginatedResponse<PolicySetListItemResponse>`. New optional
|
|
41
|
+
`page` / `limit` inputs (defaults `1` / `50`). Same pagination
|
|
42
|
+
drop as `list_custom_rules`.
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- **`list_run_scans` failed with `malformed scans page:
|
|
47
|
+
items.0.url: Required`.** Parser wired the wrong DTO
|
|
48
|
+
(`ScanBriefResponse`) for an endpoint that returns
|
|
49
|
+
`ScanTileResponse`. Same drift class as `list_policy_sets` v0.1.1.
|
|
50
|
+
- **`list_custom_rules` / `list_policy_sets` silently dropped
|
|
51
|
+
pagination metadata.** Now expose `total` / `page` / `limit` so
|
|
52
|
+
agents iterate correctly past the default page size.
|
|
53
|
+
- **`get_tag_definition` now returns `linked_rules`** (the custom
|
|
54
|
+
rules currently producing this tag — `id` / `name` / `is_active`).
|
|
55
|
+
Previously silently dropped because the parser reused the list-row
|
|
56
|
+
schema. Agents no longer need to grep `list_custom_rules` by
|
|
57
|
+
`tag_slug` themselves.
|
|
58
|
+
- **`invalid-input` (HTTP 400 / 422) error responses now preserve
|
|
59
|
+
the API's machine-readable `code` field.** Forward-compat for
|
|
60
|
+
`delete_policy_set` growing `code: "policies.in_use"` — agents
|
|
61
|
+
can branch programmatically as soon as the API ships the code,
|
|
62
|
+
no MCP release required.
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
|
|
66
|
+
- **`list_campaigns_picker`** (83rd tool — was 82, now 83) — slim
|
|
67
|
+
per-row campaign list for selection UIs (id, name, group_id,
|
|
68
|
+
is_archived). Cheaper than `list_campaigns` for orgs with thousands
|
|
69
|
+
of campaigns. Use `get_campaign(id)` after a selection.
|
|
70
|
+
- **Server now declares empty `resources` and `prompts` capabilities
|
|
71
|
+
with handlers returning `[]`.** Cursor / Claude Desktop / Cline
|
|
72
|
+
probe these at session start; previously the SDK responded with
|
|
73
|
+
`-32601 Method not found`, which Cursor's client mistranslated
|
|
74
|
+
as a misleading `"MCP error -32000: Connection closed"` warning.
|
|
75
|
+
Functional impact was zero (all tools remained callable) but
|
|
76
|
+
downstream agent logs filled with false positives once per session
|
|
77
|
+
per server. Now clean.
|
|
78
|
+
|
|
79
|
+
### Docs
|
|
80
|
+
|
|
81
|
+
- **README:** replaced the fictional `kad_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
|
|
82
|
+
API-key placeholder with `<your-kaminari-ad-api-key>` + a note
|
|
83
|
+
that keys are opaque (no required prefix or fixed length).
|
|
84
|
+
- **`create_custom_rule` / `update_custom_rule` / `test_custom_rule`:**
|
|
85
|
+
the `target` parameter description no longer claims a stale
|
|
86
|
+
`page | offer_url | html` enum (OpenAPI declares it as a freeform
|
|
87
|
+
string; `html` may not be currently valid). Defers to API docs.
|
|
88
|
+
- **`delete_policy_set`:** description now explicitly mentions the
|
|
89
|
+
API returns `HTTP 400` if campaigns are bound, and suggests the
|
|
90
|
+
unbind-via-`update_campaign` workflow before retry.
|
|
91
|
+
|
|
92
|
+
### Internal
|
|
93
|
+
|
|
94
|
+
- Comprehensive parser-drift audit across all `/api/v1/*` list
|
|
95
|
+
endpoints (run via parallel `explore` subagents covering API + MCP
|
|
96
|
+
sides). 21 endpoints already had MCP wrappers — 18 clean, 3 with
|
|
97
|
+
drift (now fixed); 1 additional list endpoint had no wrapper and
|
|
98
|
+
was added as a new tool. No remaining drift.
|
|
99
|
+
- New parser modules: `parse-run-scan-page.ts`, `parse-custom-rule-page.ts`,
|
|
100
|
+
`parse-policy-set-page.ts`, `parse-campaign-picker.ts`. The old
|
|
101
|
+
defensive bare-or-envelope helpers (`parseCustomRuleArray`,
|
|
102
|
+
`parsePolicySetList`) are gone; their files now expose only the
|
|
103
|
+
per-entity parsers. `parseTagDetail` moved out of `parse-generic.ts`
|
|
104
|
+
into `parse-tag.ts` because it now needs the detail schema's
|
|
105
|
+
`linked_rules` field which the list schema doesn't have.
|
|
106
|
+
- New shared helper `presentation/shared/declare-empty-caps.ts`
|
|
107
|
+
used by both stdio and HTTP bootstraps. Unit test against an
|
|
108
|
+
in-memory `Client` + `InMemoryTransport.createLinkedPair()` pair,
|
|
109
|
+
plus an end-to-end probe in the CLI smoke that hits a real HTTP
|
|
110
|
+
RPC after the `initialize` handshake.
|
|
111
|
+
|
|
112
|
+
## [0.1.5] - 2026-05-17
|
|
113
|
+
|
|
114
|
+
Re-release of v0.1.4 — the Corepack-based npm upgrade in v0.1.4
|
|
115
|
+
reported `Preparing npm@^11 for immediate activation...` but the
|
|
116
|
+
shell still showed bundled `npm 10.9.7`, because Corepack shims
|
|
117
|
+
were not in PATH priority. Publish failed at the same point (404).
|
|
118
|
+
|
|
119
|
+
### Fixed
|
|
120
|
+
|
|
121
|
+
- **Release workflow pinned to Node 24** (instead of .nvmrc Node 22)
|
|
122
|
+
so the bundled npm is 11.x, which has built-in Trusted Publisher
|
|
123
|
+
OIDC publish support. CI and local dev keep .nvmrc Node 22 — only
|
|
124
|
+
the release job overrides. Added an explicit `npm --version` gate
|
|
125
|
+
that fails the build if npm < 11.5.1 (defense against future Node
|
|
126
|
+
releases bundling older npm).
|
|
127
|
+
|
|
128
|
+
## [0.1.4] - 2026-05-17
|
|
129
|
+
|
|
130
|
+
Re-release of v0.1.3 — that release's `npm install -g npm@^11`
|
|
131
|
+
step broke mid-upgrade with `Cannot find module 'promise-retry'`
|
|
132
|
+
(npm 10 → 11 in-place self-upgrade leaves a broken state because
|
|
133
|
+
newer arborist references modules the old bundled tree never had).
|
|
134
|
+
|
|
135
|
+
### Fixed
|
|
136
|
+
|
|
137
|
+
- **Upgrade npm via Corepack instead of in-place self-upgrade.**
|
|
138
|
+
Corepack (bundled with Node 22+) manages the npm install via a
|
|
139
|
+
separate symlink layer and avoids the self-upgrade race. The
|
|
140
|
+
publish step now reliably runs against npm 11.x with full OIDC
|
|
141
|
+
Trusted Publisher support.
|
|
142
|
+
|
|
143
|
+
## [0.1.3] - 2026-05-17
|
|
144
|
+
|
|
145
|
+
Re-release of 0.1.1 / 0.1.2 (both failed at the npm publish step).
|
|
146
|
+
The 0.1.2 OIDC debug step revealed every JWT claim matches the
|
|
147
|
+
Trusted Publisher config perfectly — the failure was elsewhere.
|
|
148
|
+
|
|
149
|
+
### Fixed
|
|
150
|
+
|
|
151
|
+
- **npm CLI version too old for OIDC publishing.** GitHub Actions
|
|
152
|
+
Node 22 LTS runner ships with **npm 10.x bundled**, but npm
|
|
153
|
+
Trusted Publisher OIDC publish was introduced in **npm 11.5.1**
|
|
154
|
+
(Aug 2025). Without it, `npm publish --provenance` signs the
|
|
155
|
+
sigstore attestation BUT sends the actual PUT to the registry
|
|
156
|
+
unauthenticated → npm replies HTTP 404 "not found" (security
|
|
157
|
+
obscurity for "no auth"). Workflow now runs
|
|
158
|
+
`npm install -g npm@^11` before `npm ci` / publish, pinning the
|
|
159
|
+
latest npm 11.x line.
|
|
160
|
+
|
|
161
|
+
## [0.1.2] - 2026-05-17
|
|
162
|
+
|
|
163
|
+
Re-release of v0.1.1 — that tag's release pipeline failed at the
|
|
164
|
+
npm publish step (HTTP 404 — npm Trusted Publisher OIDC subject
|
|
165
|
+
mismatch we couldn't pre-diagnose). No 0.1.1 tarball ever landed
|
|
166
|
+
on the registry; users skip straight from 0.1.0 to 0.1.2. Bin
|
|
167
|
+
alias fix and OIDC switch from 0.1.1 carry forward; this release
|
|
168
|
+
adds a diagnostic step that prints the GitHub OIDC subject claim
|
|
169
|
+
before the publish attempt, so any future Trusted Publisher
|
|
170
|
+
mismatch is visible in workflow logs (not silently 404'd).
|
|
171
|
+
|
|
172
|
+
### Added
|
|
173
|
+
|
|
174
|
+
- `release.yml` "Debug OIDC subject claim" step — fetches the
|
|
175
|
+
`npm:registry.npmjs.org`-audience OIDC token, decodes the JWT
|
|
176
|
+
payload, prints the `sub` / `repository` / `workflow` /
|
|
177
|
+
`environment` claims. Sensitive data is the signed token itself
|
|
178
|
+
(logged claims are public metadata).
|
|
179
|
+
|
|
180
|
+
## [0.1.1] - 2026-05-17
|
|
181
|
+
|
|
182
|
+
### Fixed
|
|
183
|
+
|
|
184
|
+
- **`npx -y @kaminari-ad/mcp` failed with `command not found`.** npx
|
|
185
|
+
defaults the bin name to the **basename of the package** (`mcp` for
|
|
186
|
+
a scoped `@kaminari-ad/mcp`), but v0.1.0 declared bin
|
|
187
|
+
`kaminari-ad-mcp` only — so the documented Cursor / Claude Desktop
|
|
188
|
+
config in README literally did not start the server. Added `"mcp":
|
|
189
|
+
"./dist/bin.js"` as a second bin entry; both names now work
|
|
190
|
+
(`npx -y @kaminari-ad/mcp` and `npx -y -p @kaminari-ad/mcp
|
|
191
|
+
kaminari-ad-mcp`). No other changes — pure ergonomics.
|
|
192
|
+
|
|
193
|
+
### Changed
|
|
194
|
+
|
|
195
|
+
- **npm publish now uses GitHub Actions OIDC + provenance** instead
|
|
196
|
+
of a static `NPM_TOKEN`. Restored `publishConfig.provenance: true`
|
|
197
|
+
and `--provenance` flag in `release.yml`; the `npm-publish`
|
|
198
|
+
GitHub Environment + the Trusted Publisher registered on the npm
|
|
199
|
+
package settings page produce signed sigstore attestations
|
|
200
|
+
reachable from the npm package page.
|
|
201
|
+
|
|
10
202
|
## [0.1.0] - 2026-05-17
|
|
11
203
|
|
|
12
204
|
First public release of `@kaminari-ad/mcp`.
|
|
@@ -379,5 +571,10 @@ Initial public release. The first version that ships to npm under
|
|
|
379
571
|
need them.
|
|
380
572
|
- Invoice PDF fetcher — same reason.
|
|
381
573
|
|
|
382
|
-
[Unreleased]: https://github.com/kaminari-ad/mcp/compare/v0.1.
|
|
574
|
+
[Unreleased]: https://github.com/kaminari-ad/mcp/compare/v0.1.5...HEAD
|
|
575
|
+
[0.1.5]: https://github.com/kaminari-ad/mcp/compare/v0.1.0...v0.1.5
|
|
576
|
+
[0.1.4]: https://github.com/kaminari-ad/mcp/compare/v0.1.0...v0.1.4
|
|
577
|
+
[0.1.3]: https://github.com/kaminari-ad/mcp/compare/v0.1.0...v0.1.3
|
|
578
|
+
[0.1.2]: https://github.com/kaminari-ad/mcp/compare/v0.1.0...v0.1.2
|
|
579
|
+
[0.1.1]: https://github.com/kaminari-ad/mcp/compare/v0.1.0...v0.1.1
|
|
383
580
|
[0.1.0]: https://github.com/kaminari-ad/mcp/releases/tag/v0.1.0
|
package/MIGRATION_0_2.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Migrating from `@kaminari-ad/mcp` 0.1.x to 0.2.0
|
|
2
|
+
|
|
3
|
+
Two tools changed output shape and one tool changed its element type.
|
|
4
|
+
Everything else is wire-compatible.
|
|
5
|
+
|
|
6
|
+
If your agent calls **only** the unchanged tools, **no action is
|
|
7
|
+
required** — drop in v0.2.0 and continue.
|
|
8
|
+
|
|
9
|
+
## Breaking changes
|
|
10
|
+
|
|
11
|
+
### 1. `list_custom_rules` — bare array → paginated envelope
|
|
12
|
+
|
|
13
|
+
Before (≤ 0.1.5):
|
|
14
|
+
|
|
15
|
+
```jsonc
|
|
16
|
+
[
|
|
17
|
+
{ "id": "…", "name": "…", "tag_slug": "…", "rule_type": "…", "config": {...},
|
|
18
|
+
"target": "…", "is_active": true, "organization_id": "…", "created_at": "…" },
|
|
19
|
+
/* … */
|
|
20
|
+
]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
After (≥ 0.2.0):
|
|
24
|
+
|
|
25
|
+
```jsonc
|
|
26
|
+
{
|
|
27
|
+
"items": [
|
|
28
|
+
{ "id": "…", "name": "…", "tag_slug": "…", "rule_type": "…", "config": {...},
|
|
29
|
+
"target": "…", "is_active": true, "organization_id": "…", "created_at": "…" }
|
|
30
|
+
],
|
|
31
|
+
"total": 67,
|
|
32
|
+
"page": 1,
|
|
33
|
+
"limit": 50
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Why:** the API has always returned a `PaginatedResponse[CustomRuleResponse]`
|
|
38
|
+
envelope; v0.1.x silently dropped `total` / `page` / `limit`. Orgs with
|
|
39
|
+
|
|
40
|
+
> 50 rules saw exactly 50 with no signal there was more.
|
|
41
|
+
|
|
42
|
+
**Migration:** wherever you read `result.length` on a `list_custom_rules`
|
|
43
|
+
output, replace with `result.items.length` and check `result.total >
|
|
44
|
+
result.items.length` to know if you need to call the tool again with
|
|
45
|
+
`page: 2`. New optional inputs:
|
|
46
|
+
|
|
47
|
+
```jsonc
|
|
48
|
+
{ "page": 1, "limit": 50 }
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
// defaults; both optional
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. `list_policy_sets` — bare array → paginated envelope
|
|
55
|
+
|
|
56
|
+
Same shape change as `list_custom_rules`, same migration. The items
|
|
57
|
+
themselves are unchanged (slim — no `entries`; call `get_policy_set`
|
|
58
|
+
for those).
|
|
59
|
+
|
|
60
|
+
### 3. `list_run_scans` — `ScanBriefResponse` → `ScanTileResponse` per item
|
|
61
|
+
|
|
62
|
+
Before (≤ 0.1.5) — crashed in production with `malformed scans page:
|
|
63
|
+
items.0.url: Required`:
|
|
64
|
+
|
|
65
|
+
```jsonc
|
|
66
|
+
{ "items": [{ "id": "…", "url": "…", "country_code": "…", "status": "…",
|
|
67
|
+
"offer_url": "…", "screenshot_url": "…", "labels": {…},
|
|
68
|
+
"elapsed_ms": 1234, "campaign_id": "…", "campaign_name": "…",
|
|
69
|
+
"is_ad_tag": false, "created_at": "…" }], … }
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
After (≥ 0.2.0):
|
|
73
|
+
|
|
74
|
+
```jsonc
|
|
75
|
+
{ "items": [{ "id": "…", "country_code": "…", "status": "…",
|
|
76
|
+
"offer_url": "…", "screenshot_url": "…",
|
|
77
|
+
"elapsed_ms": 1234, "error": "" }], … }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Why:** the API endpoint returns `ScanTileResponse` (designed for
|
|
81
|
+
the run-detail UI's tile grid) — `url` / `created_at` / `labels` /
|
|
82
|
+
`campaign_*` / `is_ad_tag` are intentionally omitted because the
|
|
83
|
+
caller already knows the run's campaign and the tiles don't need to
|
|
84
|
+
re-render input URLs. `error` (the scan-failure reason) is **added**.
|
|
85
|
+
|
|
86
|
+
**Migration:** if your agent reads any of the removed fields off
|
|
87
|
+
`list_run_scans` items, call `get_scan(id)` per tile to fetch the
|
|
88
|
+
full `ScanResponse` (which has them all).
|
|
89
|
+
|
|
90
|
+
## Additions (non-breaking)
|
|
91
|
+
|
|
92
|
+
### `list_campaigns_picker` — new tool
|
|
93
|
+
|
|
94
|
+
Slim per-row campaign list for selection UIs:
|
|
95
|
+
|
|
96
|
+
```jsonc
|
|
97
|
+
{ "id": "…", "name": "…", "group_id": "…", "is_archived": false }
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Cheaper than `list_campaigns` for orgs with thousands of campaigns —
|
|
101
|
+
the API endpoint is non-paginated and intentionally omits heavy
|
|
102
|
+
fields. Use `get_campaign(id)` after a selection to fetch full
|
|
103
|
+
details.
|
|
104
|
+
|
|
105
|
+
### `get_tag_definition` — now returns `linked_rules`
|
|
106
|
+
|
|
107
|
+
The detail endpoint always returned `linked_rules` per OpenAPI; the
|
|
108
|
+
v0.1.x parser silently dropped them. v0.2.0 surfaces them:
|
|
109
|
+
|
|
110
|
+
```jsonc
|
|
111
|
+
{
|
|
112
|
+
"slug": "malware",
|
|
113
|
+
"category": "security",
|
|
114
|
+
/* … all existing fields … */
|
|
115
|
+
"linked_rules": [{ "id": "…", "name": "ad-detector", "is_active": true }],
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
No input change. Agents that need rules linked to a tag no longer
|
|
120
|
+
need to grep `list_custom_rules` by `tag_slug` themselves.
|
|
121
|
+
|
|
122
|
+
### `resources/list` and `prompts/list` now return `[]`
|
|
123
|
+
|
|
124
|
+
Most MCP clients (Cursor, Claude Desktop, Cline) probe these methods
|
|
125
|
+
at session start. v0.1.x returned the JSON-RPC standard `-32601
|
|
126
|
+
Method not found` (spec-compliant), but Cursor's client mistranslated
|
|
127
|
+
that into a misleading `"Connection closed"` warning. v0.2.0 declares
|
|
128
|
+
empty capabilities + handlers so the probe is silent.
|
|
129
|
+
|
|
130
|
+
Functional impact for callers: zero. No tool surface changed; the
|
|
131
|
+
fix is purely about client-side noise.
|
|
132
|
+
|
|
133
|
+
## Internal: forward-compat for `policies.in_use`
|
|
134
|
+
|
|
135
|
+
`invalid-input` MCP errors (HTTP 400 / 422) now preserve the API's
|
|
136
|
+
machine-readable `code` field when present. The API does not emit
|
|
137
|
+
`code` on `delete_policy_set` today, but `policies.in_use` is a known
|
|
138
|
+
candidate. When the API ships it, agents can branch on the code
|
|
139
|
+
without waiting for an MCP release.
|
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ Lets AI agents (Cursor, Claude Desktop, Cline, and any MCP-compatible client) la
|
|
|
19
19
|
2. Once signed in, go to **Settings → API Keys** and generate a new key, OR have an existing AI assistant (with a temporary login) call the [`create_api_key`](#tools) tool — both paths produce the same result.
|
|
20
20
|
3. The key is shown **once**. Copy it. The full key is hashed server-side immediately.
|
|
21
21
|
|
|
22
|
+
> Keys are opaque random strings — no required prefix or fixed length. Treat the whole value as a raw secret and paste it verbatim into your client config.
|
|
23
|
+
|
|
22
24
|
> Tip for evaluators / Anthropic Software Directory reviewers: ask the team at [hello@kaminari.ad](mailto:hello@kaminari.ad) for a sandboxed test account with seeded sample scans, campaigns, and alerts.
|
|
23
25
|
|
|
24
26
|
### 2a. Local install (stdio transport)
|
|
@@ -32,14 +34,14 @@ Add to your MCP client config (Cursor: `~/.cursor/mcp.json`; Claude Desktop: `~/
|
|
|
32
34
|
"command": "npx",
|
|
33
35
|
"args": ["-y", "@kaminari-ad/mcp"],
|
|
34
36
|
"env": {
|
|
35
|
-
"KAMINARI_AD_API_KEY": "
|
|
37
|
+
"KAMINARI_AD_API_KEY": "<your-kaminari-ad-api-key>",
|
|
36
38
|
},
|
|
37
39
|
},
|
|
38
40
|
},
|
|
39
41
|
}
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
Restart your client. You should see `kaminari-ad` in the MCP servers list with
|
|
44
|
+
Restart your client. You should see `kaminari-ad` in the MCP servers list with 83 tools exposed.
|
|
43
45
|
|
|
44
46
|
### 2b. Hosted HTTP transport (no install)
|
|
45
47
|
|
|
@@ -51,7 +53,7 @@ For cloud agents or clients without a local Node runtime, point at the hosted en
|
|
|
51
53
|
"kaminari-ad": {
|
|
52
54
|
"url": "https://mcp.kaminari.ad/mcp",
|
|
53
55
|
"headers": {
|
|
54
|
-
"Authorization": "Bearer
|
|
56
|
+
"Authorization": "Bearer <your-kaminari-ad-api-key>",
|
|
55
57
|
},
|
|
56
58
|
},
|
|
57
59
|
},
|
|
@@ -62,11 +64,11 @@ For cloud agents or clients without a local Node runtime, point at the hosted en
|
|
|
62
64
|
|
|
63
65
|
## Tools
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
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:
|
|
66
68
|
|
|
67
69
|
- **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`
|
|
68
70
|
- **Scans** (7) — `list_scans`, `get_scan`, `create_scan`, `create_bulk_scans`, `recheck_scans`, `cancel_scan`, `list_scan_tags`
|
|
69
|
-
- **Campaigns** (
|
|
71
|
+
- **Campaigns** (10) — `list_campaigns`, `list_campaigns_picker`, `get_campaign`, `create_campaign`, `update_campaign`, `archive_campaign`, `unarchive_campaign`, `cancel_campaign`, `run_campaign`, `list_campaign_runs`
|
|
70
72
|
- **Campaign groups** (10) — list/get/create/update/run/cancel/archive/unarchive + `pause_campaign_group_schedule`, `resume_campaign_group_schedule`
|
|
71
73
|
- **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)
|
|
72
74
|
- **Tags** (4) — `list_tags`, `get_tag_definition`, `update_tag_definition`, `delete_tag_definition`
|
|
@@ -79,7 +81,7 @@ For cloud agents or clients without a local Node runtime, point at the hosted en
|
|
|
79
81
|
- **Alert notifications** (5) — `list_alert_destinations`, `delete_alert_destination`, `set_alert_destination_version`, `get_campaign_alert_overrides`, `set_campaign_alert_overrides`
|
|
80
82
|
- **Reference data** (2) — `list_geos`, `list_emulators`
|
|
81
83
|
|
|
82
|
-
Not exposed (intentionally): binary scan-screenshot fetchers, invoice PDF,
|
|
84
|
+
Not exposed (intentionally): binary scan-screenshot fetchers, invoice PDF, and the public marketing forms (`/contact`, `/demo-inquiries`). Open an issue if you need one of those.
|
|
83
85
|
|
|
84
86
|
## Example agent prompts
|
|
85
87
|
|