@kaminari-ad/mcp 0.16.0 → 0.17.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 +51 -0
- package/dist/bin.js +3 -3
- package/dist/{chunk-LTUO4SP6.js → chunk-HZDWYWEN.js} +3 -3
- package/dist/{chunk-LTUO4SP6.js.map → chunk-HZDWYWEN.js.map} +1 -1
- package/dist/{chunk-YYS2HD6K.js → chunk-WOYPDCIR.js} +37 -36
- package/dist/chunk-WOYPDCIR.js.map +1 -0
- package/dist/{http-bootstrap-PDCTS4IS.js → http-bootstrap-MEVOCFTE.js} +4 -4
- package/dist/{http-bootstrap-PDCTS4IS.js.map → http-bootstrap-MEVOCFTE.js.map} +1 -1
- package/dist/{stdio-bootstrap-LLCHIZ4X.js → stdio-bootstrap-UYBS3TK4.js} +4 -4
- package/dist/{stdio-bootstrap-LLCHIZ4X.js.map → stdio-bootstrap-UYBS3TK4.js.map} +1 -1
- package/package.json +1 -1
- package/dist/chunk-YYS2HD6K.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,57 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.17.1] - 2026-09-03
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **The screenshot tools said PNG; the API has only ever sent WebP.**
|
|
15
|
+
`get_scan_screenshot` and `get_scan_creative_screenshot` advertised
|
|
16
|
+
"base64-encoded PNG", while every screenshot route on the API side
|
|
17
|
+
hardcodes `image/webp` — the crawler writes WebP and the legacy `.png`
|
|
18
|
+
keys were backfilled long ago. `get_scan_landing_screenshot` named no
|
|
19
|
+
format at all. All three now name WebP and say outright that the
|
|
20
|
+
client has to be able to decode it.
|
|
21
|
+
|
|
22
|
+
No transcoding was added, deliberately: this server does no image
|
|
23
|
+
processing at all — it base64-encodes the bytes it received and passes
|
|
24
|
+
the response's own content type through. A client that cannot read
|
|
25
|
+
WebP has to handle that on its own side, and an error such as
|
|
26
|
+
`webp codec not registered: registerWebpCodec() must be called by a
|
|
27
|
+
Node server` comes from the client, not from here and not from the
|
|
28
|
+
API.
|
|
29
|
+
|
|
30
|
+
## [0.17.0] - 2026-09-03
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- **`regexp_request_body` — rules can match what a page's sub-resources
|
|
35
|
+
contain.** The three custom-rule writers (`create_custom_rule`,
|
|
36
|
+
`update_custom_rule`, `test_custom_rule`) now accept the new rule type
|
|
37
|
+
and enforce its contract locally: the same `{pattern, flags}` config as
|
|
38
|
+
`regexp_request_url` and the same fixed `page` target, rejected before
|
|
39
|
+
the request leaves the process.
|
|
40
|
+
|
|
41
|
+
It exists because address-based matching stopped being enough. The
|
|
42
|
+
malvertising kits rotate every filename on every visit, so a
|
|
43
|
+
`regexp_request_url` pattern matches the names it was written against
|
|
44
|
+
and nothing after; the code inside those files changes far more slowly.
|
|
45
|
+
|
|
46
|
+
Two limits the tool descriptions now state, because both look like a
|
|
47
|
+
non-match when they bite: only the scripts, fetch/XHR responses and
|
|
48
|
+
iframe documents are captured (never images, video, fonts or
|
|
49
|
+
stylesheets), up to 400 resources, 128 KB each and 8 MB per scan — and
|
|
50
|
+
the captured contents are kept for **one day**, so
|
|
51
|
+
`test_custom_rule` against an older scan reports no match with nothing
|
|
52
|
+
left to read.
|
|
53
|
+
|
|
54
|
+
Needs the api and crawler sides deployed first.
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
|
|
58
|
+
- The internal request-URL rule guard is now a shared pattern-rule guard
|
|
59
|
+
covering both types, so their contracts cannot drift apart.
|
|
60
|
+
|
|
10
61
|
## [0.16.0] - 2026-08-26
|
|
11
62
|
|
|
12
63
|
### Added
|
package/dist/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { NAME, VERSION, err, ok } from './chunk-
|
|
2
|
+
import { NAME, VERSION, err, ok } from './chunk-HZDWYWEN.js';
|
|
3
3
|
import process from 'process';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
|
|
@@ -160,10 +160,10 @@ async function main() {
|
|
|
160
160
|
}
|
|
161
161
|
const config = configResult.value;
|
|
162
162
|
if (config.transport === "stdio") {
|
|
163
|
-
const { bootstrapStdio } = await import('./stdio-bootstrap-
|
|
163
|
+
const { bootstrapStdio } = await import('./stdio-bootstrap-UYBS3TK4.js');
|
|
164
164
|
return bootstrapStdio(config);
|
|
165
165
|
}
|
|
166
|
-
const { bootstrapHttp } = await import('./http-bootstrap-
|
|
166
|
+
const { bootstrapHttp } = await import('./http-bootstrap-MEVOCFTE.js');
|
|
167
167
|
return bootstrapHttp(config);
|
|
168
168
|
}
|
|
169
169
|
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.
|
|
6
|
+
var VERSION = "0.17.1";
|
|
7
7
|
|
|
8
8
|
export { NAME, VERSION };
|
|
9
|
-
//# sourceMappingURL=chunk-
|
|
10
|
-
//# sourceMappingURL=chunk-
|
|
9
|
+
//# sourceMappingURL=chunk-HZDWYWEN.js.map
|
|
10
|
+
//# sourceMappingURL=chunk-HZDWYWEN.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";;;;AASO,IAAM,IAAA,GAAO;AACb,IAAM,OAAA,GAAU","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";;;;AASO,IAAM,IAAA,GAAO;AACb,IAAM,OAAA,GAAU","file":"chunk-HZDWYWEN.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.17.1\";\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { err, ok } from './chunk-
|
|
2
|
+
import { err, ok } from './chunk-HZDWYWEN.js';
|
|
3
3
|
import { createHash, randomUUID } from 'crypto';
|
|
4
4
|
import createClient from 'openapi-fetch';
|
|
5
5
|
import { fetch } from 'undici';
|
|
@@ -4223,28 +4223,32 @@ var updateCampaignTool = {
|
|
|
4223
4223
|
return ok(result.value);
|
|
4224
4224
|
}
|
|
4225
4225
|
};
|
|
4226
|
-
var
|
|
4227
|
-
|
|
4226
|
+
var PATTERN_RULE_TYPES = ["regexp_request_url", "regexp_request_body"];
|
|
4227
|
+
var patternRuleConfigSchema = z.object({
|
|
4228
|
+
pattern: z.string().min(1).max(4096).describe("Non-empty regular expression, at most 4,096 characters."),
|
|
4228
4229
|
flags: z.enum(["", "i"]).optional().describe("Omit or use '' for case-sensitive matching; use 'i' to ignore case.")
|
|
4229
4230
|
}).strict();
|
|
4230
|
-
var
|
|
4231
|
-
function
|
|
4232
|
-
|
|
4231
|
+
var PATTERN_RULE_CONFIG_DOC = "For `rule_type='regexp_request_url'` and `rule_type='regexp_request_body'`, `config` must be exactly `{ pattern: string, flags?: '' | 'i' }`: pattern is non-empty and at most 4,096 characters; omit flags or use `''` for case-sensitive matching, or `'i'` for case-insensitive matching. `target` must be `'page'` for both. `regexp_request_url` inspects up to 5,000 captured request URLs on a fresh scan; tests and rechecks of stored scans reconstruct main-frame hops plus up to 200 persisted subrequests with selected resource types omitted, so historical matching is best-effort. `regexp_request_body` inspects the CONTENTS of the page's scripts, fetch/XHR responses and iframe documents \u2014 never images, video, fonts or stylesheets \u2014 capped at 400 resources, 128 KB each and 8 MB per scan. Those contents are kept for ONE DAY, so a test or recheck against an older scan reports no match because there is nothing left to read.";
|
|
4232
|
+
function isPatternRuleType(ruleType) {
|
|
4233
|
+
return PATTERN_RULE_TYPES.some((known) => known === ruleType);
|
|
4234
|
+
}
|
|
4235
|
+
function patternRuleInputError(input) {
|
|
4236
|
+
if (!isPatternRuleType(input.rule_type)) return null;
|
|
4233
4237
|
if (input.target !== void 0 && input.target !== "page") {
|
|
4234
4238
|
return {
|
|
4235
4239
|
kind: "invalid-input",
|
|
4236
|
-
message:
|
|
4237
|
-
fieldErrors: { target: [
|
|
4240
|
+
message: `${input.rule_type} requires target='page'.`,
|
|
4241
|
+
fieldErrors: { target: [`Must be 'page' for ${input.rule_type}.`] }
|
|
4238
4242
|
};
|
|
4239
4243
|
}
|
|
4240
|
-
const parsed =
|
|
4244
|
+
const parsed = patternRuleConfigSchema.safeParse(input.config);
|
|
4241
4245
|
if (parsed.success) return null;
|
|
4242
4246
|
const issue = parsed.error.issues[0];
|
|
4243
4247
|
const field = issue?.path.length ? `config.${issue.path.join(".")}` : "config";
|
|
4244
|
-
const message = issue?.message ?? "Invalid
|
|
4248
|
+
const message = issue?.message ?? "Invalid pattern rule config.";
|
|
4245
4249
|
return {
|
|
4246
4250
|
kind: "invalid-input",
|
|
4247
|
-
message: `Invalid
|
|
4251
|
+
message: `Invalid ${input.rule_type} config: ${message}`,
|
|
4248
4252
|
fieldErrors: { [field]: [message] }
|
|
4249
4253
|
};
|
|
4250
4254
|
}
|
|
@@ -4260,10 +4264,7 @@ var ruleConfigField = z.record(z.unknown()).superRefine((config, ctx) => {
|
|
|
4260
4264
|
});
|
|
4261
4265
|
}
|
|
4262
4266
|
});
|
|
4263
|
-
var
|
|
4264
|
-
requestUrlRuleConfigSchema,
|
|
4265
|
-
ruleConfigField
|
|
4266
|
-
]);
|
|
4267
|
+
var patternAwareRuleConfigField = z.union([patternRuleConfigSchema, ruleConfigField]);
|
|
4267
4268
|
|
|
4268
4269
|
// src/application/tools/custom-rules/create-custom-rule.tool.ts
|
|
4269
4270
|
var CreateCustomRuleInputShape = {
|
|
@@ -4274,18 +4275,18 @@ var CreateCustomRuleInputShape = {
|
|
|
4274
4275
|
"Tag slug to assign on match. Empty = create-only (advanced). The API auto-registers a custom tag definition for this slug with `display_name = name`. **MUST NOT collide with a built-in system tag slug** (see `list_tags` where `scope=system`); colliding requests return 422 with code `checking.system_slug_reserved`. For `rule_type='llm'` use `config.tags` keys instead and leave `tag_slug` empty."
|
|
4275
4276
|
),
|
|
4276
4277
|
rule_type: z.string().max(50).describe(
|
|
4277
|
-
"Rule engine. One of: `stopword_content`, `stopword_url`, `regexp_content`, `regexp_url`, `regexp_request_url`, `blacklist_domain`, `combo`, `llm`. `regexp_url` checks redirect-chain URLs only; `regexp_request_url` checks captured network and subresource URLs. The API validates."
|
|
4278
|
+
"Rule engine. One of: `stopword_content`, `stopword_url`, `regexp_content`, `regexp_url`, `regexp_request_url`, `regexp_request_body`, `blacklist_domain`, `combo`, `llm`. `regexp_url` checks redirect-chain URLs only; `regexp_request_url` checks captured network and subresource URLs; `regexp_request_body` checks what those sub-resources contained. The API validates."
|
|
4278
4279
|
),
|
|
4279
|
-
config:
|
|
4280
|
-
"Rule-type-specific configuration object. Shape depends on `rule_type`. " +
|
|
4280
|
+
config: patternAwareRuleConfigField.describe(
|
|
4281
|
+
"Rule-type-specific configuration object. Shape depends on `rule_type`. " + PATTERN_RULE_CONFIG_DOC + " `regexp_url` remains redirect-chain-only. For `rule_type='llm'` the shape is `{ prompt: string, tags: { <tag_slug>: <description>, ... } }`; each key in `config.tags` is auto-registered as a custom tag definition AND must not collide with a system slug (same 422 contract as `tag_slug`). " + COMBO_MATCH_SCOPE_DOC
|
|
4281
4282
|
),
|
|
4282
4283
|
target: z.string().max(30).optional().describe(
|
|
4283
|
-
"Where to apply the rule (e.g. 'page' for landing HTML). `regexp_request_url`
|
|
4284
|
+
"Where to apply the rule (e.g. 'page' for landing HTML). `regexp_request_url` and `regexp_request_body` require `target='page'`. Default: page. See API docs for the full set of valid values."
|
|
4284
4285
|
)
|
|
4285
4286
|
};
|
|
4286
4287
|
var createCustomRuleTool = {
|
|
4287
4288
|
name: "create_custom_rule",
|
|
4288
|
-
description: "Define a custom tag-detection rule. Use `rule_type='regexp_request_url'` to match captured network and subresource URLs on the fixed `page` target; fresh scans carry up to 5,000 URLs, while later tests/rechecks use a reduced persisted request tree and are best-effort. `rule_type='regexp_url'` remains redirect-chain-only. The API auto-registers a tag definition for each emitted slug and rejects built-in system-slug collisions with HTTP 422 / `checking.system_slug_reserved`. Matches tag future scans; existing scans are untouched until `recheck_scans`.",
|
|
4289
|
+
description: "Define a custom tag-detection rule. Use `rule_type='regexp_request_url'` to match captured network and subresource URLs on the fixed `page` target; fresh scans carry up to 5,000 URLs, while later tests/rechecks use a reduced persisted request tree and are best-effort. Use `rule_type='regexp_request_body'` to match the CONTENTS of those sub-resources instead \u2014 the right choice when the code you want to catch keeps changing its filename; those contents are kept for one day. `rule_type='regexp_url'` remains redirect-chain-only. The API auto-registers a tag definition for each emitted slug and rejects built-in system-slug collisions with HTTP 422 / `checking.system_slug_reserved`. Matches tag future scans; existing scans are untouched until `recheck_scans`.",
|
|
4289
4290
|
annotations: {
|
|
4290
4291
|
title: "Create Custom Rule",
|
|
4291
4292
|
readOnlyHint: false,
|
|
@@ -4295,7 +4296,7 @@ var createCustomRuleTool = {
|
|
|
4295
4296
|
},
|
|
4296
4297
|
inputSchema: z.object(CreateCustomRuleInputShape),
|
|
4297
4298
|
handler: async (input, ctx) => {
|
|
4298
|
-
const inputError =
|
|
4299
|
+
const inputError = patternRuleInputError(input);
|
|
4299
4300
|
if (inputError) return err(inputError);
|
|
4300
4301
|
const body = {
|
|
4301
4302
|
name: input.name,
|
|
@@ -4370,19 +4371,19 @@ var listCustomRulesTool = {
|
|
|
4370
4371
|
};
|
|
4371
4372
|
var TestCustomRuleInputShape = {
|
|
4372
4373
|
rule_type: z.string().max(50).describe(
|
|
4373
|
-
"Rule engine type. One of: `stopword_content`, `stopword_url`, `regexp_content`, `regexp_url`, `regexp_request_url`, `blacklist_domain`, `combo`, `llm`. `regexp_url` checks redirect-chain URLs only; `regexp_request_url` checks captured network and subresource URLs."
|
|
4374
|
+
"Rule engine type. One of: `stopword_content`, `stopword_url`, `regexp_content`, `regexp_url`, `regexp_request_url`, `regexp_request_body`, `blacklist_domain`, `combo`, `llm`. `regexp_url` checks redirect-chain URLs only; `regexp_request_url` checks captured network and subresource URLs; `regexp_request_body` checks what those sub-resources contained."
|
|
4374
4375
|
),
|
|
4375
|
-
config:
|
|
4376
|
-
"Rule-type-specific config to test. Same shape as `create_custom_rule`'s `config`. " +
|
|
4376
|
+
config: patternAwareRuleConfigField.describe(
|
|
4377
|
+
"Rule-type-specific config to test. Same shape as `create_custom_rule`'s `config`. " + PATTERN_RULE_CONFIG_DOC + " `regexp_url` remains redirect-chain-only. NOTE: `test_custom_rule` evaluates the rule against a scan WITHOUT persisting it, so slug-collision validation does NOT run here \u2014 verify slugs against `list_tags` (`scope=system`) before promoting to `create_custom_rule`. " + COMBO_MATCH_SCOPE_DOC
|
|
4377
4378
|
),
|
|
4378
4379
|
target: z.string().max(30).describe(
|
|
4379
|
-
"Where to apply the rule (e.g. 'page' for landing HTML). `regexp_request_url`
|
|
4380
|
+
"Where to apply the rule (e.g. 'page' for landing HTML). `regexp_request_url` and `regexp_request_body` require `target='page'`. See API docs for the full set of valid values."
|
|
4380
4381
|
),
|
|
4381
4382
|
scan_id: z.string().uuid().describe("Existing scan UUID to evaluate the rule against.")
|
|
4382
4383
|
};
|
|
4383
4384
|
var testCustomRuleTool = {
|
|
4384
4385
|
name: "test_custom_rule",
|
|
4385
|
-
description: "Preview-test a rule definition against a stored scan without persisting it. For `regexp_request_url`, the historical snapshot contains main-frame hops plus at most 200 persisted subrequests with selected resource types omitted, so a no-match does not prove the original fresh scan lacked the request. Returns match state, elapsed time, and per-tag detail; the preview response does not expose the matched request URL separately. Slug-collision validation does not run in preview mode.",
|
|
4386
|
+
description: "Preview-test a rule definition against a stored scan without persisting it. For `regexp_request_url`, the historical snapshot contains main-frame hops plus at most 200 persisted subrequests with selected resource types omitted, so a no-match does not prove the original fresh scan lacked the request. For `regexp_request_body`, the captured contents live for ONE DAY \u2014 pick a scan from the last 24 hours, because an older one reports no match with nothing left to read. Returns match state, elapsed time, and per-tag detail; the preview response does not expose the matched request URL separately. Slug-collision validation does not run in preview mode.",
|
|
4386
4387
|
annotations: {
|
|
4387
4388
|
title: "Test Custom Rule",
|
|
4388
4389
|
readOnlyHint: true,
|
|
@@ -4392,7 +4393,7 @@ var testCustomRuleTool = {
|
|
|
4392
4393
|
},
|
|
4393
4394
|
inputSchema: z.object(TestCustomRuleInputShape),
|
|
4394
4395
|
handler: async (input, ctx) => {
|
|
4395
|
-
const inputError =
|
|
4396
|
+
const inputError = patternRuleInputError(input);
|
|
4396
4397
|
if (inputError) return err(inputError);
|
|
4397
4398
|
const result = await ctx.api.testCustomRule({
|
|
4398
4399
|
rule_type: input.rule_type,
|
|
@@ -4412,17 +4413,17 @@ var UpdateCustomRuleInputShape = {
|
|
|
4412
4413
|
tag_slug: z.string().max(100).optional().describe(
|
|
4413
4414
|
"New tag slug to assign on match. **MUST NOT collide with a built-in system tag slug** (see `list_tags` where `scope=system`); colliding requests return 422 with code `checking.system_slug_reserved`. Leaving a GLOBAL rule on the same slug preserves its admin-managed tag metadata."
|
|
4414
4415
|
),
|
|
4415
|
-
config:
|
|
4416
|
-
"New rule-type-specific config object. Replaces the stored config wholesale \u2014 resend every key you want to keep, including a combo rule's `match_scope`. For `rule_type='llm'` the keys of `config.tags` are auto-registered as tag definitions; any key that collides with a system slug returns the same 422 contract. " +
|
|
4416
|
+
config: patternAwareRuleConfigField.optional().describe(
|
|
4417
|
+
"New rule-type-specific config object. Replaces the stored config wholesale \u2014 resend every key you want to keep, including a combo rule's `match_scope`. For `rule_type='llm'` the keys of `config.tags` are auto-registered as tag definitions; any key that collides with a system slug returns the same 422 contract. " + PATTERN_RULE_CONFIG_DOC + " Read the rule first because `rule_type` is immutable and is not repeated in this update input. " + COMBO_MATCH_SCOPE_DOC
|
|
4417
4418
|
),
|
|
4418
4419
|
target: z.string().max(30).optional().describe(
|
|
4419
|
-
"Where to apply the rule. `regexp_request_url`
|
|
4420
|
+
"Where to apply the rule. `regexp_request_url` and `regexp_request_body` are fixed to `page`; do not change it. See API docs for the valid targets of other rule types."
|
|
4420
4421
|
),
|
|
4421
4422
|
is_active: z.boolean().optional().describe("Enable/disable the rule.")
|
|
4422
4423
|
};
|
|
4423
4424
|
var updateCustomRuleTool = {
|
|
4424
4425
|
name: "update_custom_rule",
|
|
4425
|
-
description: "Update a custom tag-detection rule. Only supplied fields are sent, but `config` replaces the stored object wholesale; read the rule first and resend every required key. `regexp_request_url`
|
|
4426
|
+
description: "Update a custom tag-detection rule. Only supplied fields are sent, but `config` replaces the stored object wholesale; read the rule first and resend every required key. `regexp_request_url` and `regexp_request_body` need a non-empty pattern (max 4,096), flags `''`/`'i'`, and the fixed `page` target. Same-slug GLOBAL rule edits preserve separately managed tag metadata; use `update_tag_definition` to change it. Existing scans are not re-evaluated until `recheck_scans`.",
|
|
4426
4427
|
annotations: {
|
|
4427
4428
|
title: "Update Custom Rule",
|
|
4428
4429
|
readOnlyHint: false,
|
|
@@ -5398,7 +5399,7 @@ var GetScanCreativeScreenshotInputShape = {
|
|
|
5398
5399
|
};
|
|
5399
5400
|
var getScanCreativeScreenshotTool = {
|
|
5400
5401
|
name: "get_scan_creative_screenshot",
|
|
5401
|
-
description: "Fetch the creative screenshot for an ad-tag scan as an inline image (base64-encoded
|
|
5402
|
+
description: "Fetch the creative screenshot for an ad-tag scan as an inline image (base64-encoded WebP \u2014 the API stores and serves every screenshot as WebP, so the client must be able to decode it). Returns 404 if the scan is not an ad-tag scan or has no creative captured yet.",
|
|
5402
5403
|
annotations: {
|
|
5403
5404
|
title: "Get Scan Creative Screenshot",
|
|
5404
5405
|
readOnlyHint: true,
|
|
@@ -5443,7 +5444,7 @@ var GetScanLandingScreenshotInputShape = {
|
|
|
5443
5444
|
};
|
|
5444
5445
|
var getScanLandingScreenshotTool = {
|
|
5445
5446
|
name: "get_scan_landing_screenshot",
|
|
5446
|
-
description: "Fetch the screenshot of one landing tab on an ad-tag scan as an inline image. Use `get_scan` first to discover available `landings[*].ord` values.",
|
|
5447
|
+
description: "Fetch the screenshot of one landing tab on an ad-tag scan as an inline image (base64-encoded WebP \u2014 the API stores and serves every screenshot as WebP, so the client must be able to decode it). Use `get_scan` first to discover available `landings[*].ord` values.",
|
|
5447
5448
|
annotations: {
|
|
5448
5449
|
title: "Get Scan Landing Screenshot",
|
|
5449
5450
|
readOnlyHint: true,
|
|
@@ -5470,7 +5471,7 @@ var GetScanScreenshotInputShape = {
|
|
|
5470
5471
|
};
|
|
5471
5472
|
var getScanScreenshotTool = {
|
|
5472
5473
|
name: "get_scan_screenshot",
|
|
5473
|
-
description: "Fetch the primary screenshot for a scan as an inline image (base64-encoded
|
|
5474
|
+
description: "Fetch the primary screenshot for a scan as an inline image (base64-encoded WebP \u2014 the API stores and serves every screenshot as WebP, so the client must be able to decode it). Pass `width` to request a resized version (50-2000 px). Returns one MCP image content block.",
|
|
5474
5475
|
annotations: {
|
|
5475
5476
|
title: "Get Scan Screenshot",
|
|
5476
5477
|
readOnlyHint: true,
|
|
@@ -6226,5 +6227,5 @@ function formatToolError(error) {
|
|
|
6226
6227
|
}
|
|
6227
6228
|
|
|
6228
6229
|
export { BearerToken, SERVER_INSTRUCTIONS, createHttpApiGateway, createPinoLogger, declareEmptyResourcesAndPrompts, newRequestId, wireToolsIntoMcpServer };
|
|
6229
|
-
//# sourceMappingURL=chunk-
|
|
6230
|
-
//# sourceMappingURL=chunk-
|
|
6230
|
+
//# sourceMappingURL=chunk-WOYPDCIR.js.map
|
|
6231
|
+
//# sourceMappingURL=chunk-WOYPDCIR.js.map
|