@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 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-LTUO4SP6.js';
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-LLCHIZ4X.js');
163
+ const { bootstrapStdio } = await import('./stdio-bootstrap-UYBS3TK4.js');
164
164
  return bootstrapStdio(config);
165
165
  }
166
- const { bootstrapHttp } = await import('./http-bootstrap-PDCTS4IS.js');
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.16.0";
6
+ var VERSION = "0.17.1";
7
7
 
8
8
  export { NAME, VERSION };
9
- //# sourceMappingURL=chunk-LTUO4SP6.js.map
10
- //# sourceMappingURL=chunk-LTUO4SP6.js.map
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-LTUO4SP6.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.16.0\";\n"]}
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-LTUO4SP6.js';
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 requestUrlRuleConfigSchema = z.object({
4227
- pattern: z.string().min(1).max(4096).describe("Non-empty request-URL regular expression, at most 4,096 characters."),
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 REQUEST_URL_RULE_CONFIG_DOC = "For `rule_type='regexp_request_url'`, `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'`. Fresh scans inspect up to 5,000 captured request URLs. 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.";
4231
- function requestUrlRuleInputError(input) {
4232
- if (input.rule_type !== "regexp_request_url") return null;
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: "regexp_request_url requires target='page'.",
4237
- fieldErrors: { target: ["Must be 'page' for regexp_request_url."] }
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 = requestUrlRuleConfigSchema.safeParse(input.config);
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 request-URL rule config.";
4248
+ const message = issue?.message ?? "Invalid pattern rule config.";
4245
4249
  return {
4246
4250
  kind: "invalid-input",
4247
- message: `Invalid regexp_request_url config: ${message}`,
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 requestUrlAwareRuleConfigField = z.union([
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: requestUrlAwareRuleConfigField.describe(
4280
- "Rule-type-specific configuration object. Shape depends on `rule_type`. " + REQUEST_URL_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
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` requires `target='page'`. Default: page. See API docs for the full set of valid values."
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 = requestUrlRuleInputError(input);
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: requestUrlAwareRuleConfigField.describe(
4376
- "Rule-type-specific config to test. Same shape as `create_custom_rule`'s `config`. " + REQUEST_URL_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
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` requires `target='page'`. See API docs for the full set of valid values."
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 = requestUrlRuleInputError(input);
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: requestUrlAwareRuleConfigField.optional().describe(
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. " + REQUEST_URL_RULE_CONFIG_DOC + " Read the rule first because `rule_type` is immutable and is not repeated in this update input. " + COMBO_MATCH_SCOPE_DOC
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` is fixed to `page`; do not change it. See API docs for the valid targets of other rule types."
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` needs 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
+ 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 PNG). Returns 404 if the scan is not an ad-tag scan or has no creative captured yet.",
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 PNG). Pass `width` to request a resized version (50-2000 px). Returns one MCP image content block.",
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-YYS2HD6K.js.map
6230
- //# sourceMappingURL=chunk-YYS2HD6K.js.map
6230
+ //# sourceMappingURL=chunk-WOYPDCIR.js.map
6231
+ //# sourceMappingURL=chunk-WOYPDCIR.js.map