mcp-scraper 0.66.6 → 0.67.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.
Files changed (34) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/README.md +1 -1
  3. package/dist/bin/api-server.cjs +1122 -625
  4. package/dist/bin/api-server.js +3 -3
  5. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  6. package/dist/bin/mcp-scraper-cli.js +1 -1
  7. package/dist/bin/mcp-scraper-install.cjs +2 -2
  8. package/dist/bin/mcp-scraper-install.js +2 -2
  9. package/dist/bin/mcp-stdio-server.cjs +147 -17
  10. package/dist/bin/mcp-stdio-server.js +6 -6
  11. package/dist/bin/paa-harvest.cjs +20 -1
  12. package/dist/bin/paa-harvest.js +3 -3
  13. package/dist/{chunk-3EYALCYK.js → chunk-2L4C4DAZ.js} +1 -1
  14. package/dist/{chunk-CETDPNMZ.js → chunk-2LXTOAKS.js} +1 -1
  15. package/dist/{chunk-K7Y27ND3.js → chunk-62LEXS5O.js} +2 -2
  16. package/dist/{chunk-55B3T5L2.js → chunk-65FTMB7G.js} +92 -1
  17. package/dist/{chunk-3TKKJQB4.js → chunk-ES25GP6C.js} +1 -1
  18. package/dist/{chunk-NLEAYKOC.js → chunk-GT63KEUB.js} +1 -1
  19. package/dist/{chunk-KPE52NPT.js → chunk-IHDTONZV.js} +1 -1
  20. package/dist/{chunk-KXRWY7DZ.js → chunk-LCGTNWOT.js} +1 -1
  21. package/dist/{chunk-DBWWIK7O.js → chunk-LN6N3YLK.js} +1 -1
  22. package/dist/{chunk-ABYBPODM.js → chunk-UL4ZKAWZ.js} +1 -1
  23. package/dist/{chunk-VMWVEKZT.js → chunk-XOOKZYZG.js} +71 -18
  24. package/dist/{chunk-PMCT2YQM.js → chunk-Y46YNQMM.js} +1 -1
  25. package/dist/{db-4RVZ3NYZ.js → db-ZGZAKYBW.js} +1 -1
  26. package/dist/{extract-bundle-EA5URLXN.js → extract-bundle-QQIYJSBW.js} +3 -3
  27. package/dist/index.cjs +20 -1
  28. package/dist/index.js +3 -3
  29. package/dist/{lead-list-enrichment-repository-IBXNWM6H.js → lead-list-enrichment-repository-CXLVIV3R.js} +2 -2
  30. package/dist/{location-data-repository-WHHQUCUI.js → location-data-repository-G72M7DTN.js} +2 -2
  31. package/dist/{server-5WPS3LZD.js → server-MFVYRB6I.js} +818 -471
  32. package/dist/{site-extract-repository-NTM4MDQN.js → site-extract-repository-7EP6UX6I.js} +2 -2
  33. package/dist/{worker-UTBUWEXQ.js → worker-JGWV2LID.js} +5 -5
  34. package/package.json +1 -1
@@ -17,9 +17,9 @@ loadDotEnv();
17
17
  async function main() {
18
18
  const [{ serve }, { app }, { startWorker }, { migrate }] = await Promise.all([
19
19
  import("@hono/node-server"),
20
- import("../server-5WPS3LZD.js"),
21
- import("../worker-UTBUWEXQ.js"),
22
- import("../db-4RVZ3NYZ.js")
20
+ import("../server-MFVYRB6I.js"),
21
+ import("../worker-JGWV2LID.js"),
22
+ import("../db-ZGZAKYBW.js")
23
23
  ]);
24
24
  const PORT = parseInt(process.env.PORT ?? "3001");
25
25
  try {
@@ -30,7 +30,7 @@ var import_promises5 = require("fs/promises");
30
30
  var import_node_path3 = require("path");
31
31
 
32
32
  // src/version.ts
33
- var PACKAGE_VERSION = "0.66.6";
33
+ var PACKAGE_VERSION = "0.67.0";
34
34
 
35
35
  // src/cli/agent-config.ts
36
36
  function apiKeyValue(options) {
@@ -13,7 +13,7 @@ import "../chunk-VXLU74YZ.js";
13
13
  import "../chunk-GGZEC22A.js";
14
14
  import {
15
15
  PACKAGE_VERSION
16
- } from "../chunk-NLEAYKOC.js";
16
+ } from "../chunk-GT63KEUB.js";
17
17
 
18
18
  // src/cli/human-cli.ts
19
19
  import { Command } from "commander";
@@ -3,7 +3,7 @@
3
3
 
4
4
  // release-message.json
5
5
  var release_message_default = {
6
- message: "Search Console bulk URL Inspection now returns one ordered partial-result receipt without the former one-minute cutoff."
6
+ message: "Transparent Commons can now turn pasted images, generated image bytes, stored image artifacts, direct image URLs, or ordinary webpage URLs into one permanent Commons-hosted image before validation and publishing."
7
7
  };
8
8
 
9
9
  // src/install-terminal.ts
@@ -112,7 +112,7 @@ function renderInstallTerminal(options) {
112
112
  }
113
113
 
114
114
  // src/version.ts
115
- var PACKAGE_VERSION = "0.66.6";
115
+ var PACKAGE_VERSION = "0.67.0";
116
116
 
117
117
  // bin/mcp-scraper-install.ts
118
118
  var noColor = process.argv.includes("--no-color") || process.env.NO_COLOR !== void 0 || process.env.FORCE_COLOR === "0" || !process.stdout.isTTY;
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  renderInstallTerminal
4
- } from "../chunk-KPE52NPT.js";
4
+ } from "../chunk-IHDTONZV.js";
5
5
  import {
6
6
  PACKAGE_VERSION
7
- } from "../chunk-NLEAYKOC.js";
7
+ } from "../chunk-GT63KEUB.js";
8
8
 
9
9
  // bin/mcp-scraper-install.ts
10
10
  var noColor = process.argv.includes("--no-color") || process.env.NO_COLOR !== void 0 || process.env.FORCE_COLOR === "0" || !process.stdout.isTTY;
@@ -96,7 +96,26 @@ var PUBLIC_ERROR_CODES = [
96
96
  "site_export_not_found",
97
97
  "site_export_format_unavailable",
98
98
  "site_export_read_failed",
99
- "site_export_image_not_found"
99
+ "site_export_image_not_found",
100
+ "image_url_invalid",
101
+ "image_url_not_https",
102
+ "image_host_unresolvable",
103
+ "image_host_blocked",
104
+ "image_redirect_invalid",
105
+ "image_source_unavailable",
106
+ "image_too_large",
107
+ "image_redirect_limit",
108
+ "image_base64_invalid",
109
+ "image_source_missing",
110
+ "image_source_ambiguous",
111
+ "image_source_type_invalid",
112
+ "image_artifact_not_found",
113
+ "image_page_too_large",
114
+ "page_image_not_found",
115
+ "page_image_candidates_unusable",
116
+ "image_format_unsupported",
117
+ "image_storage_unconfigured",
118
+ "featured_image_unhostable"
100
119
  ];
101
120
  var PUBLIC_ERROR_TYPES = [
102
121
  "request_aborted",
@@ -191,6 +210,26 @@ function publicErrorType(code) {
191
210
  case "site_export_read_failed":
192
211
  case "site_export_image_not_found":
193
212
  return "extraction";
213
+ case "image_url_invalid":
214
+ case "image_url_not_https":
215
+ case "image_host_unresolvable":
216
+ case "image_host_blocked":
217
+ case "image_redirect_invalid":
218
+ case "image_source_unavailable":
219
+ case "image_too_large":
220
+ case "image_redirect_limit":
221
+ case "image_base64_invalid":
222
+ case "image_source_missing":
223
+ case "image_source_ambiguous":
224
+ case "image_source_type_invalid":
225
+ case "image_artifact_not_found":
226
+ case "image_page_too_large":
227
+ case "page_image_not_found":
228
+ case "page_image_candidates_unusable":
229
+ case "image_format_unsupported":
230
+ case "image_storage_unconfigured":
231
+ case "featured_image_unhostable":
232
+ return "invalid_request";
194
233
  case "insufficient_balance":
195
234
  return "billing";
196
235
  case "vendor_unavailable":
@@ -264,6 +303,44 @@ function publicErrorMessage(code) {
264
303
  return "The stored site export could not be read or did not pass its integrity check.";
265
304
  case "site_export_image_not_found":
266
305
  return "The requested site-export image was not found, expired, or does not belong to this account.";
306
+ case "image_url_invalid":
307
+ return "The image source is not a valid URL. Use a stable public HTTPS URL or inline image bytes.";
308
+ case "image_url_not_https":
309
+ return "Commons image sources must use a public HTTPS URL or inline image bytes.";
310
+ case "image_host_unresolvable":
311
+ return "The image host could not be resolved. Use a different stable public URL or inline image bytes.";
312
+ case "image_host_blocked":
313
+ return "The image source resolves to a network address Commons cannot fetch safely.";
314
+ case "image_redirect_invalid":
315
+ return "The image source redirected to an invalid or unsafe destination.";
316
+ case "image_source_unavailable":
317
+ return "The image source could not be fetched. Host a different stable public URL or provide inline image bytes.";
318
+ case "image_too_large":
319
+ return "The image exceeds the Commons image size limit.";
320
+ case "image_redirect_limit":
321
+ return "The image source exceeded the Commons redirect limit.";
322
+ case "image_base64_invalid":
323
+ return "The supplied inline image bytes are invalid.";
324
+ case "image_source_missing":
325
+ return "Provide exactly one of a public image or webpage URL, inline image bytes, or an owner-scoped image artifact.";
326
+ case "image_source_ambiguous":
327
+ return "Provide only one image source: sourceUrl, imageBase64, or artifactId.";
328
+ case "image_source_type_invalid":
329
+ return "Use sourceType only with inline image bytes or an owner-scoped image artifact.";
330
+ case "image_artifact_not_found":
331
+ return "The image artifact was not found, expired, or does not belong to this account.";
332
+ case "image_page_too_large":
333
+ return "The webpage is too large for bounded Commons image discovery.";
334
+ case "page_image_not_found":
335
+ return "The webpage did not expose a usable featured or content image.";
336
+ case "page_image_candidates_unusable":
337
+ return "The webpage exposed image candidates, but none returned supported public image bytes.";
338
+ case "image_format_unsupported":
339
+ return "Commons accepts JPEG, PNG, GIF, or WebP image bytes.";
340
+ case "image_storage_unconfigured":
341
+ return "Commons image storage is temporarily unavailable.";
342
+ case "featured_image_unhostable":
343
+ return "The required featured image could not be hosted for Commons publication.";
267
344
  default:
268
345
  return PUBLIC_SERVICE_UNAVAILABLE_MESSAGE;
269
346
  }
@@ -1233,7 +1310,7 @@ render();
1233
1310
  }
1234
1311
 
1235
1312
  // src/version.ts
1236
- var PACKAGE_VERSION = "0.66.6";
1313
+ var PACKAGE_VERSION = "0.67.0";
1237
1314
 
1238
1315
  // src/mcp/input-field-descriptions.ts
1239
1316
  var import_zod = require("zod");
@@ -8217,11 +8294,21 @@ seam is noted so you can chain them.
8217
8294
  - Plan a new or edited entity -> **commons_prepare_entity**. This is the Commons equivalent of
8218
8295
  prepare-memory-write: it returns the live entity profile contract, duplicate candidates, tag reuse/review/create
8219
8296
  guidance, recommended sections, optional sections, and heading guidance before any write occurs.
8220
- - Validate a composed entity without writing -> **commons_validate_entity**. Use it after composing and before submit
8221
- to catch missing featured images, missing source/body evidence, duplicate candidates, and
8222
- unsupported placeholder sections.
8297
+ - Host a featured image -> **commons_host_image**. The normal write sequence is **commons_prepare_entity ->
8298
+ compose the payload -> commons_host_image -> commons_validate_entity -> commons_submit_entity**. Put the
8299
+ permanent returned URL in featuredImage.url. Use imageBase64 for pasted or AI-generated bytes, artifactId for an
8300
+ owner-scoped MCP Scraper image artifact, or sourceUrl for either a public HTTPS image or a webpage containing one.
8301
+ Webpage discovery tries Open Graph, Twitter, JSON-LD, then meaningful content images. Never pass a caller-local
8302
+ path, opaque chat attachment reference, or private/authenticated URL.
8303
+ - Validate a composed entity without writing -> **commons_validate_entity**. Use it after image hosting and before
8304
+ submit. Validation does not fetch or store image bytes; an external/unregistered featured image is reported in
8305
+ imageDiagnostics as not publishable until commons_host_image returns its permanent Commons URL. Validation also
8306
+ catches missing source/body evidence, duplicate candidates, and unsupported placeholder sections.
8223
8307
  - Create or edit a public wiki entity -> **commons_submit_entity**. This is a governed proposal write,
8224
- not direct rendered HTML editing. Normal workflow is prepare -> validate -> submit. Pick the closest entity type
8308
+ not direct rendered HTML editing. Submit retains defensive auto-hosting for a stable direct public HTTPS image,
8309
+ but image ingress failure returns an actionable tool error: host different bytes or a different stable source,
8310
+ replace featuredImage.url, validate again, and retry the same intended write with the same idempotency key.
8311
+ Pick the closest entity type
8225
8312
  first: SoftwareApplication, Organization, Person, Event, Place, Taxon, ScienceConcept, MathConcept, TechArticle,
8226
8313
  Trail, or PublicArticle.
8227
8314
  Creating a new entity costs 10 Credits; editing an existing entity costs 2 Credits. Preparation, validation,
@@ -10119,7 +10206,7 @@ var CommonsGetEntityLinksetInputSchema = {
10119
10206
  idOrSlug: import_zod8.z.string().trim().min(1).max(180).describe("Transparent Commons TPW-Q entity id or /wiki/ slug whose governed RFC 9264 linkset should be read.")
10120
10207
  };
10121
10208
  var CommonsFeaturedImageInputSchema = import_zod8.z.object({
10122
- url: import_zod8.z.string().url().describe("Required public image URL for a publishable entity. Use extract_url includeFeaturedImage or preserved media when available."),
10209
+ url: import_zod8.z.string().url().describe("For a publish-ready entity, use the permanent URL returned by commons_host_image. Validation reports any unregistered external URL as not ready. Do not use a chat attachment reference, caller-local path, private URL, or HTML page URL here; pass the original image or webpage source to commons_host_image first."),
10123
10210
  alt: import_zod8.z.string().trim().max(500).optional(),
10124
10211
  caption: import_zod8.z.string().trim().max(1e3).optional(),
10125
10212
  sourceUrl: import_zod8.z.string().url().optional(),
@@ -10211,14 +10298,14 @@ var CommonsPrepareEntityInputSchema = {
10211
10298
  maxCandidates: import_zod8.z.number().int().min(1).max(20).default(8).describe("Maximum duplicate candidates to return.")
10212
10299
  };
10213
10300
  var CommonsSubmitEntityInputSchema = {
10214
- idempotencyKey: import_zod8.z.string().trim().min(8).max(200).describe("Required unique opaque ID for this intended Commons write. Reuse only when retrying the same write after a timeout; use a new value for each intentional create or edit."),
10301
+ idempotencyKey: import_zod8.z.string().trim().min(8).max(200).describe("Required unique opaque ID for this intended Commons write. Reuse it when retrying the same intended write after a timeout or after correcting a pre-persistence image-ingress failure; use a new value for each intentional create or edit."),
10215
10302
  title: import_zod8.z.string().trim().min(3).max(180).describe("Public page title. This is also used for duplicate slug/entity checks when slug is omitted."),
10216
10303
  description: import_zod8.z.string().trim().min(8).max(600).describe("Short article summary and schema.org description."),
10217
10304
  slug: import_zod8.z.string().trim().max(180).optional().describe("Optional URL slug. Omit to derive one from title."),
10218
10305
  entityId: import_zod8.z.string().trim().max(80).optional().describe("Existing Transparent Public Wiki entity id when proposing an edit. New entities normally omit this and receive a TPW-Q id."),
10219
10306
  entityType: import_zod8.z.string().trim().max(120).default("PublicArticle").describe("Backend Wikidata-style type. Prefer precise entity classes such as SoftwareApplication, Organization, Person, Event, Place, Taxon, ScienceConcept, MathConcept, TechArticle, or PublicArticle; the public article structure should match the selected type."),
10220
10307
  disambiguationName: import_zod8.z.string().trim().max(240).optional().describe("Clarifying name used when the concept could be confused with another entity."),
10221
- featuredImage: CommonsFeaturedImageInputSchema.optional().describe("Required for auto-published public entities. The image is also added to the media manifest if absent."),
10308
+ featuredImage: CommonsFeaturedImageInputSchema.optional().describe("Required for auto-published public entities. First call commons_host_image with attachment bytes, an image artifact, a direct image URL, or a webpage URL, then place its returned permanent URL here. Validation does not fetch external images and reports unregistered URLs as not publishable. Submit retains a compatibility fallback for public URLs. The image is also added to the media manifest if absent."),
10222
10309
  source: CommonsSourceInputSchema.optional().describe("Source provenance. Store original URL, source byline, and origin canonical here; canonical does not replace rights review."),
10223
10310
  tags: import_zod8.z.array(import_zod8.z.string().trim().min(1).max(80)).max(24).optional().describe("Standardized topic tags. Use existing/searchable concepts when possible."),
10224
10311
  keywords: import_zod8.z.array(import_zod8.z.string().trim().min(1).max(120)).max(50).optional().describe("SEO and retrieval keywords."),
@@ -10280,12 +10367,31 @@ var CommonsGetEntityLedgerInputSchema = {
10280
10367
  idOrSlug: import_zod8.z.string().trim().min(1).max(180).describe("Published entity id or /wiki/ slug whose contribution ledger should be read.")
10281
10368
  };
10282
10369
  var CommonsHostImageInputSchema = {
10283
- sourceUrl: import_zod8.z.string().url().optional().describe("Public https image URL to download and host. The wiki never serves a third-party URL directly, so pass the original source here rather than putting it on the entity."),
10284
- imageBase64: import_zod8.z.string().min(16).optional().describe("Base64 image bytes for an image you already hold. Use for images under about 3 MB; larger files should be published from a URL."),
10370
+ sourceUrl: import_zod8.z.string().url().optional().describe("Public HTTPS direct image URL or webpage URL. A direct image is hosted as-is; an HTML page is inspected for Open Graph, Twitter, JSON-LD, and meaningful content images, then the first usable candidate is hosted. Temporary signed URLs are consumed immediately and query credentials are not retained as provenance."),
10371
+ imageBase64: import_zod8.z.string().min(16).optional().describe("Base64 image bytes for an image already available to the caller, including a pasted attachment or AI-generated image. Use sourceType to preserve whether it was uploaded or generated. Keep the complete serialized request within the client transport limit."),
10372
+ artifactId: import_zod8.z.string().trim().min(1).max(500).optional().describe("Owner-scoped image artifact returned by an MCP Scraper media or screenshot workflow. The server reauthorizes ownership and reads the bytes directly; do not construct an artifact ID."),
10373
+ sourceType: import_zod8.z.enum(["uploaded", "ai_generated"]).optional().describe("Provenance for imageBase64 or artifactId. Use ai_generated only when an image model created the supplied bytes; otherwise use uploaded or omit it."),
10285
10374
  alt: import_zod8.z.string().trim().max(500).optional().describe("Alt text describing the image for readers who cannot see it."),
10286
10375
  license: import_zod8.z.string().trim().max(240).optional().describe("License or usage terms of the original image, preserved with the hosted copy."),
10287
10376
  attribution: import_zod8.z.string().trim().max(500).optional().describe("Credit line for the original photographer, publication, or archive.")
10288
10377
  };
10378
+ var CommonsHostImageOutputSchema = {
10379
+ ok: import_zod8.z.boolean(),
10380
+ data: import_zod8.z.object({
10381
+ id: import_zod8.z.string().describe("Stable Commons image ID."),
10382
+ url: import_zod8.z.string().url().describe("Permanent Commons URL to use as featuredImage.url."),
10383
+ contentType: import_zod8.z.enum(["image/jpeg", "image/png", "image/gif", "image/webp"]),
10384
+ bytes: import_zod8.z.number().int().positive(),
10385
+ digest: import_zod8.z.string(),
10386
+ sourceUrl: import_zod8.z.string().url().nullable().describe("Sanitized direct asset URL that supplied the hosted bytes, when applicable."),
10387
+ sourcePageUrl: import_zod8.z.string().url().nullable().describe("Sanitized webpage URL from which the image was discovered, when applicable."),
10388
+ sourceKind: import_zod8.z.enum(["uploaded", "ai_generated", "artifact", "direct_url", "webpage", "registered"]),
10389
+ selectionSource: import_zod8.z.enum(["provided_bytes", "artifact", "direct_url", "og:image", "twitter:image", "json-ld", "content-image", "registered"]),
10390
+ reused: import_zod8.z.boolean().describe("True when identical image bytes were already stored.")
10391
+ }).optional(),
10392
+ error: import_zod8.z.string().optional(),
10393
+ message: import_zod8.z.string().optional()
10394
+ };
10289
10395
  var CommonsGetProposalInputSchema = {
10290
10396
  proposalId: import_zod8.z.string().trim().min(1).max(120).describe("Proposal id returned by commons_submit_entity, in the form commons-proposal-<uuid>.")
10291
10397
  };
@@ -10313,6 +10419,30 @@ var CommonsGenericOutputSchema = {
10313
10419
  error: import_zod8.z.string().optional(),
10314
10420
  message: import_zod8.z.string().optional()
10315
10421
  };
10422
+ var CommonsFeaturedImageDiagnosticsOutputSchema = import_zod8.z.object({
10423
+ state: import_zod8.z.enum(["missing", "external_unhosted", "commons_hosted"]).describe("Storage-readiness state for the candidate featured image."),
10424
+ url: import_zod8.z.string().url().nullable().describe("Normalized candidate featured-image URL, or null when none was supplied."),
10425
+ commonsImageId: import_zod8.z.string().nullable().describe("Registered Commons image ID when metadata proves the image is hosted, otherwise null."),
10426
+ readyForPublish: import_zod8.z.boolean().describe("Whether Commons storage metadata proves this featured image is ready to publish."),
10427
+ submitWillAttemptAutoHost: import_zod8.z.boolean().describe("Whether submit will use its compatibility fallback to try hosting this external image."),
10428
+ requiredAction: import_zod8.z.string().nullable().describe("Action the caller must take before submit, or null when the image is ready.")
10429
+ }).describe("Featured-image storage readiness determined without fetching or storing external bytes.");
10430
+ var CommonsValidateEntityOutputSchema = {
10431
+ ok: import_zod8.z.boolean(),
10432
+ data: import_zod8.z.object({
10433
+ ok: import_zod8.z.literal(true),
10434
+ valid: import_zod8.z.boolean(),
10435
+ publishable: import_zod8.z.boolean(),
10436
+ autoPublishEligible: import_zod8.z.boolean(),
10437
+ errors: import_zod8.z.array(import_zod8.z.string()),
10438
+ warnings: import_zod8.z.array(import_zod8.z.string()),
10439
+ imageDiagnostics: import_zod8.z.object({
10440
+ featuredImage: CommonsFeaturedImageDiagnosticsOutputSchema
10441
+ }).describe("Read-only image readiness and recovery guidance for this payload.")
10442
+ }).passthrough().optional(),
10443
+ error: import_zod8.z.string().optional(),
10444
+ message: import_zod8.z.string().optional()
10445
+ };
10316
10446
  var DirectoryWorkflowStatusInputSchema = {
10317
10447
  jobId: import_zod8.z.string().trim().min(1).describe("The jobId returned by directory_workflow. Poll until status is complete, partial, empty, or failed.")
10318
10448
  };
@@ -14019,9 +14149,9 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
14019
14149
  }, async (input) => executor.commonsPrepareEntity(input));
14020
14150
  server.registerTool("commons_validate_entity", {
14021
14151
  title: "Transparent Commons Validate Entity",
14022
- description: "Validate a proposed Transparent Commons entity payload without writing. Checks publishable basics, featured image, source/body evidence, existing-entity conflict state, heading profile alignment, and unsupported placeholder sections. Call this after composing the page and before commons_submit_entity.",
14152
+ description: "Read-only validation for a proposed Transparent Commons entity payload. Call it after commons_prepare_entity, composing the page, and commons_host_image. It does not fetch or store image bytes: an external or otherwise unregistered featured image remains not publishable until commons_host_image returns the permanent Commons URL. Inspect imageDiagnostics for readiness and the required action before commons_submit_entity. Also checks source/body evidence, existing-entity conflict state, heading profile alignment, and unsupported placeholder sections.",
14023
14153
  inputSchema: CommonsValidateEntityInputSchema,
14024
- outputSchema: recordOutputSchema("commons_validate_entity", CommonsGenericOutputSchema),
14154
+ outputSchema: recordOutputSchema("commons_validate_entity", CommonsValidateEntityOutputSchema),
14025
14155
  annotations: {
14026
14156
  title: "Transparent Commons Validate Entity",
14027
14157
  readOnlyHint: true,
@@ -14032,7 +14162,7 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
14032
14162
  }, async (input) => executor.commonsValidateEntity(input));
14033
14163
  server.registerTool("commons_submit_entity", {
14034
14164
  title: "Transparent Commons Governed Entity Write",
14035
- description: "Create or propose an edit to a Transparent Commons public wiki entity through the governed MCP Scraper write plane. A new entity costs 10 Credits; an edit to an existing entity costs 2 Credits. Preparation and validation are free, and idempotent retries are not charged twice. This never edits rendered HTML directly. Normal workflow is commons_prepare_entity, compose, commons_validate_entity, then submit. commons_prepare_entity returns the entity profile contract and section guidance to compose against. Transparent Commons is an open wiki: any account may edit any entity, and every edit publishes and is recorded on the public contribution ledger. Publishing requires a featured image and body/source evidence. Pass baseRevision when editing so the ledger can show whether the edit was written on top of a newer revision. Requires idempotencyKey.",
14165
+ description: "Charged governed write that creates or proposes an edit to a Transparent Commons public wiki entity. A new entity costs 10 Credits; an edit costs 2 Credits. Preparation, image hosting, and validation are free, and idempotent retries are not charged twice. Normal workflow is commons_prepare_entity, compose the page, commons_host_image, commons_validate_entity, then submit with the returned permanent featuredImage.url. Submit retains a compatibility fallback that auto-hosts a stable direct public HTTPS image URL; if image ingress fails, it returns an actionable image tool error so you can host different bytes or a different stable source, replace the URL, validate again, and retry the same intended write with the same idempotencyKey. This never edits rendered HTML directly. Transparent Commons is an open wiki: any account may edit any entity, and every applied edit is recorded on the public contribution ledger. Publishing requires a ready featured image and body/source evidence. Pass baseRevision when editing so the ledger can show whether the edit was written on top of a newer revision. Requires idempotencyKey.",
14036
14166
  inputSchema: CommonsSubmitEntityInputSchema,
14037
14167
  outputSchema: recordOutputSchema("commons_submit_entity", CommonsGenericOutputSchema),
14038
14168
  annotations: {
@@ -14058,9 +14188,9 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
14058
14188
  }, async (input) => executor.commonsGetEntityLedger(input));
14059
14189
  server.registerTool("commons_host_image", {
14060
14190
  title: "Host a Transparent Commons Image",
14061
- description: "Host an image from a public https URL or base64 bytes, returning a permanent Commons URL. Commons never serves a third-party image URL \u2014 commons_submit_entity hosts external images automatically, so use this only to host one before or independently of a write. JPEG, PNG, GIF, WebP up to 10 MB; SVG rejected. Identical bytes are stored once.",
14191
+ description: "Turn one supplied image source into a permanent Transparent Commons image before validation and submission. Provide exactly one of imageBase64 for a pasted or AI-generated image, artifactId for an owner-scoped MCP Scraper image artifact, or sourceUrl for either a direct public HTTPS image or a webpage containing the desired image. Webpages are inspected in deterministic order for Open Graph, Twitter, JSON-LD, and meaningful content images; unusable candidates fall through to the next candidate. Returns the permanent URL for featuredImage.url plus source and selection provenance. JPEG, PNG, GIF, and WebP are accepted up to 10 MB; SVG is rejected. Identical bytes are stored once. Never pass a caller-local path or private/authenticated URL.",
14062
14192
  inputSchema: CommonsHostImageInputSchema,
14063
- outputSchema: recordOutputSchema("commons_host_image", CommonsGenericOutputSchema),
14193
+ outputSchema: recordOutputSchema("commons_host_image", CommonsHostImageOutputSchema),
14064
14194
  annotations: {
14065
14195
  title: "Host a Transparent Commons Image",
14066
14196
  readOnlyHint: false,
@@ -18666,7 +18796,7 @@ var HostedMemoryMcpToolExecutor = class {
18666
18796
 
18667
18797
  // release-message.json
18668
18798
  var release_message_default = {
18669
- message: "Search Console bulk URL Inspection now returns one ordered partial-result receipt without the former one-minute cutoff."
18799
+ message: "Transparent Commons can now turn pasted images, generated image bytes, stored image artifacts, direct image URLs, or ordinary webpage URLs into one permanent Commons-hosted image before validation and publishing."
18670
18800
  };
18671
18801
 
18672
18802
  // src/install-terminal.ts
@@ -13,21 +13,21 @@ import {
13
13
  registerScheduledResultsMcpTools,
14
14
  registerSerpIntelligenceCaptureTools,
15
15
  resolveDeploymentProfile
16
- } from "../chunk-VMWVEKZT.js";
16
+ } from "../chunk-XOOKZYZG.js";
17
17
  import "../chunk-PGJQDMC2.js";
18
- import "../chunk-3EYALCYK.js";
19
- import "../chunk-3TKKJQB4.js";
18
+ import "../chunk-2L4C4DAZ.js";
19
+ import "../chunk-ES25GP6C.js";
20
20
  import {
21
21
  renderInstallTerminal
22
- } from "../chunk-KPE52NPT.js";
22
+ } from "../chunk-IHDTONZV.js";
23
23
  import "../chunk-VXLU74YZ.js";
24
24
  import "../chunk-GGZEC22A.js";
25
25
  import {
26
26
  PACKAGE_VERSION
27
- } from "../chunk-NLEAYKOC.js";
27
+ } from "../chunk-GT63KEUB.js";
28
28
  import "../chunk-DNM65UCK.js";
29
29
  import "../chunk-AYJHI2FK.js";
30
- import "../chunk-55B3T5L2.js";
30
+ import "../chunk-65FTMB7G.js";
31
31
 
32
32
  // bin/mcp-stdio-server.ts
33
33
  import { readFileSync } from "fs";
@@ -300,7 +300,26 @@ var PUBLIC_ERROR_CODES = [
300
300
  "site_export_not_found",
301
301
  "site_export_format_unavailable",
302
302
  "site_export_read_failed",
303
- "site_export_image_not_found"
303
+ "site_export_image_not_found",
304
+ "image_url_invalid",
305
+ "image_url_not_https",
306
+ "image_host_unresolvable",
307
+ "image_host_blocked",
308
+ "image_redirect_invalid",
309
+ "image_source_unavailable",
310
+ "image_too_large",
311
+ "image_redirect_limit",
312
+ "image_base64_invalid",
313
+ "image_source_missing",
314
+ "image_source_ambiguous",
315
+ "image_source_type_invalid",
316
+ "image_artifact_not_found",
317
+ "image_page_too_large",
318
+ "page_image_not_found",
319
+ "page_image_candidates_unusable",
320
+ "image_format_unsupported",
321
+ "image_storage_unconfigured",
322
+ "featured_image_unhostable"
304
323
  ];
305
324
  var PUBLIC_ERROR_TYPES = [
306
325
  "request_aborted",
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  harvest
4
- } from "../chunk-K7Y27ND3.js";
4
+ } from "../chunk-62LEXS5O.js";
5
5
  import {
6
6
  browserServiceApiKey
7
- } from "../chunk-3TKKJQB4.js";
7
+ } from "../chunk-ES25GP6C.js";
8
8
  import "../chunk-77LQV73B.js";
9
- import "../chunk-55B3T5L2.js";
9
+ import "../chunk-65FTMB7G.js";
10
10
 
11
11
  // src/cli.ts
12
12
  import { Command } from "commander";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  publicErrorMessage,
3
3
  sanitizeVendorName
4
- } from "./chunk-55B3T5L2.js";
4
+ } from "./chunk-65FTMB7G.js";
5
5
 
6
6
  // src/api/outbound-sanitize.ts
7
7
  var KEY_RENAMES = {
@@ -10,7 +10,7 @@ import {
10
10
  finishHarvestAttempt,
11
11
  publicErrorMessage,
12
12
  startHarvestAttempt
13
- } from "./chunk-55B3T5L2.js";
13
+ } from "./chunk-65FTMB7G.js";
14
14
 
15
15
  // src/api/harvest-problems.ts
16
16
  function errorMessage(err) {
@@ -6,7 +6,7 @@ import {
6
6
  currentCostContext,
7
7
  recordKernelSession,
8
8
  runWithCostContext
9
- } from "./chunk-3TKKJQB4.js";
9
+ } from "./chunk-ES25GP6C.js";
10
10
  import {
11
11
  DEFAULT_PROXY_MODE,
12
12
  HarvestOptionsSchema,
@@ -21,7 +21,7 @@ import {
21
21
  RECAPTCHA_INSTRUCTIONS,
22
22
  RequestAbortedError,
23
23
  sanitizeVendorName
24
- } from "./chunk-55B3T5L2.js";
24
+ } from "./chunk-65FTMB7G.js";
25
25
 
26
26
  // src/driver/BrowserDriver.ts
27
27
  import { chromium } from "playwright-extra";
@@ -42,7 +42,26 @@ var PUBLIC_ERROR_CODES = [
42
42
  "site_export_not_found",
43
43
  "site_export_format_unavailable",
44
44
  "site_export_read_failed",
45
- "site_export_image_not_found"
45
+ "site_export_image_not_found",
46
+ "image_url_invalid",
47
+ "image_url_not_https",
48
+ "image_host_unresolvable",
49
+ "image_host_blocked",
50
+ "image_redirect_invalid",
51
+ "image_source_unavailable",
52
+ "image_too_large",
53
+ "image_redirect_limit",
54
+ "image_base64_invalid",
55
+ "image_source_missing",
56
+ "image_source_ambiguous",
57
+ "image_source_type_invalid",
58
+ "image_artifact_not_found",
59
+ "image_page_too_large",
60
+ "page_image_not_found",
61
+ "page_image_candidates_unusable",
62
+ "image_format_unsupported",
63
+ "image_storage_unconfigured",
64
+ "featured_image_unhostable"
46
65
  ];
47
66
  var PUBLIC_ERROR_TYPES = [
48
67
  "request_aborted",
@@ -164,6 +183,26 @@ function publicErrorType(code) {
164
183
  case "site_export_read_failed":
165
184
  case "site_export_image_not_found":
166
185
  return "extraction";
186
+ case "image_url_invalid":
187
+ case "image_url_not_https":
188
+ case "image_host_unresolvable":
189
+ case "image_host_blocked":
190
+ case "image_redirect_invalid":
191
+ case "image_source_unavailable":
192
+ case "image_too_large":
193
+ case "image_redirect_limit":
194
+ case "image_base64_invalid":
195
+ case "image_source_missing":
196
+ case "image_source_ambiguous":
197
+ case "image_source_type_invalid":
198
+ case "image_artifact_not_found":
199
+ case "image_page_too_large":
200
+ case "page_image_not_found":
201
+ case "page_image_candidates_unusable":
202
+ case "image_format_unsupported":
203
+ case "image_storage_unconfigured":
204
+ case "featured_image_unhostable":
205
+ return "invalid_request";
167
206
  case "insufficient_balance":
168
207
  return "billing";
169
208
  case "vendor_unavailable":
@@ -237,6 +276,44 @@ function publicErrorMessage(code) {
237
276
  return "The stored site export could not be read or did not pass its integrity check.";
238
277
  case "site_export_image_not_found":
239
278
  return "The requested site-export image was not found, expired, or does not belong to this account.";
279
+ case "image_url_invalid":
280
+ return "The image source is not a valid URL. Use a stable public HTTPS URL or inline image bytes.";
281
+ case "image_url_not_https":
282
+ return "Commons image sources must use a public HTTPS URL or inline image bytes.";
283
+ case "image_host_unresolvable":
284
+ return "The image host could not be resolved. Use a different stable public URL or inline image bytes.";
285
+ case "image_host_blocked":
286
+ return "The image source resolves to a network address Commons cannot fetch safely.";
287
+ case "image_redirect_invalid":
288
+ return "The image source redirected to an invalid or unsafe destination.";
289
+ case "image_source_unavailable":
290
+ return "The image source could not be fetched. Host a different stable public URL or provide inline image bytes.";
291
+ case "image_too_large":
292
+ return "The image exceeds the Commons image size limit.";
293
+ case "image_redirect_limit":
294
+ return "The image source exceeded the Commons redirect limit.";
295
+ case "image_base64_invalid":
296
+ return "The supplied inline image bytes are invalid.";
297
+ case "image_source_missing":
298
+ return "Provide exactly one of a public image or webpage URL, inline image bytes, or an owner-scoped image artifact.";
299
+ case "image_source_ambiguous":
300
+ return "Provide only one image source: sourceUrl, imageBase64, or artifactId.";
301
+ case "image_source_type_invalid":
302
+ return "Use sourceType only with inline image bytes or an owner-scoped image artifact.";
303
+ case "image_artifact_not_found":
304
+ return "The image artifact was not found, expired, or does not belong to this account.";
305
+ case "image_page_too_large":
306
+ return "The webpage is too large for bounded Commons image discovery.";
307
+ case "page_image_not_found":
308
+ return "The webpage did not expose a usable featured or content image.";
309
+ case "page_image_candidates_unusable":
310
+ return "The webpage exposed image candidates, but none returned supported public image bytes.";
311
+ case "image_format_unsupported":
312
+ return "Commons accepts JPEG, PNG, GIF, or WebP image bytes.";
313
+ case "image_storage_unconfigured":
314
+ return "Commons image storage is temporarily unavailable.";
315
+ case "featured_image_unhostable":
316
+ return "The required featured image could not be hosted for Commons publication.";
240
317
  default:
241
318
  return PUBLIC_SERVICE_UNAVAILABLE_MESSAGE;
242
319
  }
@@ -921,6 +998,20 @@ async function migrate(options = {}) {
921
998
  PRIMARY KEY (user_id, connection_id, period_start)
922
999
  )
923
1000
  `);
1001
+ await db.execute(`
1002
+ CREATE TABLE IF NOT EXISTS connected_account_charge_transfers (
1003
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1004
+ user_id INTEGER NOT NULL,
1005
+ period_start TEXT NOT NULL,
1006
+ from_connection_id TEXT NOT NULL,
1007
+ to_connection_id TEXT NOT NULL,
1008
+ provider_config_key TEXT NOT NULL,
1009
+ transferred_at TEXT NOT NULL DEFAULT (datetime('now')),
1010
+ UNIQUE (user_id, period_start, from_connection_id),
1011
+ CHECK (from_connection_id <> to_connection_id)
1012
+ )
1013
+ `);
1014
+ await db.execute(`CREATE INDEX IF NOT EXISTS connected_account_charge_transfers_destination ON connected_account_charge_transfers(user_id, period_start, to_connection_id, transferred_at DESC)`);
924
1015
  await db.execute(`
925
1016
  CREATE TABLE IF NOT EXISTS billing_credits (
926
1017
  idempotency_key TEXT PRIMARY KEY,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDb
3
- } from "./chunk-55B3T5L2.js";
3
+ } from "./chunk-65FTMB7G.js";
4
4
 
5
5
  // src/lib/browser-service-env.ts
6
6
  function browserServiceApiKey() {
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var PACKAGE_VERSION = "0.66.6";
2
+ var PACKAGE_VERSION = "0.67.0";
3
3
 
4
4
  export {
5
5
  PACKAGE_VERSION
@@ -1,6 +1,6 @@
1
1
  // release-message.json
2
2
  var release_message_default = {
3
- message: "Search Console bulk URL Inspection now returns one ordered partial-result receipt without the former one-minute cutoff."
3
+ message: "Transparent Commons can now turn pasted images, generated image bytes, stored image artifacts, direct image URLs, or ordinary webpage URLs into one permanent Commons-hosted image before validation and publishing."
4
4
  };
5
5
 
6
6
  // src/install-terminal.ts
@@ -15,7 +15,7 @@ import {
15
15
  sanitizeVendorName,
16
16
  serializePublicErrorEnvelope,
17
17
  settleDebitMcIdempotent
18
- } from "./chunk-55B3T5L2.js";
18
+ } from "./chunk-65FTMB7G.js";
19
19
 
20
20
  // src/api/site-extract-content-store.ts
21
21
  import { createHash } from "crypto";
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  buildPublicErrorEnvelope,
10
10
  getDb
11
- } from "./chunk-55B3T5L2.js";
11
+ } from "./chunk-65FTMB7G.js";
12
12
 
13
13
  // src/lib/media-extractor.ts
14
14
  import { createWriteStream, mkdirSync, rmSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDb
3
- } from "./chunk-55B3T5L2.js";
3
+ } from "./chunk-65FTMB7G.js";
4
4
 
5
5
  // src/api/lead-list-enrichment-repository.ts
6
6
  import { createHash, randomUUID } from "crypto";