mcp-scraper 0.66.7 → 0.67.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 +16 -1
- package/README.md +1 -1
- package/dist/bin/api-server.cjs +260 -43
- package/dist/bin/api-server.js +3 -3
- package/dist/bin/mcp-scraper-cli.cjs +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-install.cjs +2 -2
- package/dist/bin/mcp-scraper-install.js +2 -2
- package/dist/bin/mcp-stdio-server.cjs +70 -14
- package/dist/bin/mcp-stdio-server.js +6 -6
- package/dist/bin/paa-harvest.cjs +6 -0
- package/dist/bin/paa-harvest.js +3 -3
- package/dist/{chunk-F434YJPV.js → chunk-2L4C4DAZ.js} +1 -1
- package/dist/{chunk-LVXRWJJJ.js → chunk-2LXTOAKS.js} +1 -1
- package/dist/{chunk-CGOMGGOF.js → chunk-62LEXS5O.js} +2 -2
- package/dist/{chunk-HZDJ5UZ4.js → chunk-65FTMB7G.js} +25 -1
- package/dist/{chunk-U2UHJWFW.js → chunk-ES25GP6C.js} +1 -1
- package/dist/{chunk-O7ZC5Y3Z.js → chunk-HUNXSVKU.js} +1 -1
- package/dist/{chunk-HWGQVP3Q.js → chunk-LCGTNWOT.js} +1 -1
- package/dist/{chunk-EVOBJYBE.js → chunk-LN6N3YLK.js} +1 -1
- package/dist/{chunk-Z5QQEWXA.js → chunk-STQQOEHC.js} +47 -15
- package/dist/{chunk-JZPSG4NR.js → chunk-UL4ZKAWZ.js} +1 -1
- package/dist/{chunk-7KB5QTHP.js → chunk-VES63X4Q.js} +1 -1
- package/dist/{chunk-HBZENASD.js → chunk-Y46YNQMM.js} +1 -1
- package/dist/{db-MNNNIWVS.js → db-ZGZAKYBW.js} +1 -1
- package/dist/{extract-bundle-RW7CVIRF.js → extract-bundle-QQIYJSBW.js} +3 -3
- package/dist/index.cjs +6 -0
- package/dist/index.js +3 -3
- package/dist/{lead-list-enrichment-repository-PZYE6TDP.js → lead-list-enrichment-repository-CXLVIV3R.js} +2 -2
- package/dist/{location-data-repository-EPCNGMOM.js → location-data-repository-G72M7DTN.js} +2 -2
- package/dist/{server-KSVJ4X4V.js → server-ROIJWWJG.js} +206 -48
- package/dist/{site-extract-repository-CZ7SVT3Z.js → site-extract-repository-7EP6UX6I.js} +2 -2
- package/dist/{worker-IBLGV272.js → worker-JGWV2LID.js} +5 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ All notable changes to MCP Scraper are documented here. The format is based on [
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.67.1] - 2026-08-26
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `commons_host_image` now returns its complete success payload through both readable JSON text and MCP `structuredContent`, so typed clients can consume permanent image provenance without reparsing text.
|
|
12
|
+
|
|
13
|
+
## [0.67.0] - 2026-08-26
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- `commons_host_image` now accepts pasted or AI-generated bytes, owner-scoped image artifacts, direct image URLs, and webpage URLs through one workflow. Webpage inputs try Open Graph, Twitter, JSON-LD, and meaningful content images, return source-selection provenance, and omit temporary URL query credentials from durable image metadata.
|
|
18
|
+
- `mcpscraper.dev` now publishes its complete generated LLM discovery profile and bounded semantic authority-retrieval endpoints from the site-owned Next.js authority layer.
|
|
19
|
+
|
|
7
20
|
## [0.66.7] - 2026-08-26
|
|
8
21
|
|
|
9
22
|
### Fixed
|
|
@@ -1128,7 +1141,9 @@ All notable changes to MCP Scraper are documented here. The format is based on [
|
|
|
1128
1141
|
- Write actions remain unavailable until the account owner explicitly enables them.
|
|
1129
1142
|
- Provider-specific connection data is normalized into one agent-facing contract.
|
|
1130
1143
|
|
|
1131
|
-
[Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.
|
|
1144
|
+
[Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.67.1...HEAD
|
|
1145
|
+
[0.67.1]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.67.0...v0.67.1
|
|
1146
|
+
[0.67.0]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.66.7...v0.67.0
|
|
1132
1147
|
[0.66.7]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.66.6...v0.66.7
|
|
1133
1148
|
[0.66.6]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.66.5...v0.66.6
|
|
1134
1149
|
[0.66.5]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.66.4...v0.66.5
|
package/README.md
CHANGED
|
@@ -159,7 +159,7 @@ Build the branded one-click bundle:
|
|
|
159
159
|
npm run build:mcpb
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.
|
|
162
|
+
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.67.1`, SHA-256 `257eb19b72d228cc4aec4973778036cfc7c13419da6de35391ea7179ce629a03`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, API-key configuration field, and manually curated current-release message from the bundle manifest.
|
|
163
163
|
|
|
164
164
|
The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
|
|
165
165
|
|
package/dist/bin/api-server.cjs
CHANGED
|
@@ -174,6 +174,12 @@ function publicErrorType(code) {
|
|
|
174
174
|
case "image_redirect_limit":
|
|
175
175
|
case "image_base64_invalid":
|
|
176
176
|
case "image_source_missing":
|
|
177
|
+
case "image_source_ambiguous":
|
|
178
|
+
case "image_source_type_invalid":
|
|
179
|
+
case "image_artifact_not_found":
|
|
180
|
+
case "image_page_too_large":
|
|
181
|
+
case "page_image_not_found":
|
|
182
|
+
case "page_image_candidates_unusable":
|
|
177
183
|
case "image_format_unsupported":
|
|
178
184
|
case "image_storage_unconfigured":
|
|
179
185
|
case "featured_image_unhostable":
|
|
@@ -270,7 +276,19 @@ function publicErrorMessage(code) {
|
|
|
270
276
|
case "image_base64_invalid":
|
|
271
277
|
return "The supplied inline image bytes are invalid.";
|
|
272
278
|
case "image_source_missing":
|
|
273
|
-
return "Provide
|
|
279
|
+
return "Provide exactly one of a public image or webpage URL, inline image bytes, or an owner-scoped image artifact.";
|
|
280
|
+
case "image_source_ambiguous":
|
|
281
|
+
return "Provide only one image source: sourceUrl, imageBase64, or artifactId.";
|
|
282
|
+
case "image_source_type_invalid":
|
|
283
|
+
return "Use sourceType only with inline image bytes or an owner-scoped image artifact.";
|
|
284
|
+
case "image_artifact_not_found":
|
|
285
|
+
return "The image artifact was not found, expired, or does not belong to this account.";
|
|
286
|
+
case "image_page_too_large":
|
|
287
|
+
return "The webpage is too large for bounded Commons image discovery.";
|
|
288
|
+
case "page_image_not_found":
|
|
289
|
+
return "The webpage did not expose a usable featured or content image.";
|
|
290
|
+
case "page_image_candidates_unusable":
|
|
291
|
+
return "The webpage exposed image candidates, but none returned supported public image bytes.";
|
|
274
292
|
case "image_format_unsupported":
|
|
275
293
|
return "Commons accepts JPEG, PNG, GIF, or WebP image bytes.";
|
|
276
294
|
case "image_storage_unconfigured":
|
|
@@ -350,6 +368,12 @@ var init_errors = __esm({
|
|
|
350
368
|
"image_redirect_limit",
|
|
351
369
|
"image_base64_invalid",
|
|
352
370
|
"image_source_missing",
|
|
371
|
+
"image_source_ambiguous",
|
|
372
|
+
"image_source_type_invalid",
|
|
373
|
+
"image_artifact_not_found",
|
|
374
|
+
"image_page_too_large",
|
|
375
|
+
"page_image_not_found",
|
|
376
|
+
"page_image_candidates_unusable",
|
|
353
377
|
"image_format_unsupported",
|
|
354
378
|
"image_storage_unconfigured",
|
|
355
379
|
"featured_image_unhostable"
|
|
@@ -11394,7 +11418,8 @@ function firstJsonLdImage(value) {
|
|
|
11394
11418
|
}
|
|
11395
11419
|
return null;
|
|
11396
11420
|
}
|
|
11397
|
-
function
|
|
11421
|
+
function contentImages(html) {
|
|
11422
|
+
const images = [];
|
|
11398
11423
|
for (const match of html.matchAll(/<img\b[^>]*>/gi)) {
|
|
11399
11424
|
const tag = match[0];
|
|
11400
11425
|
const attr = (name) => tag.match(new RegExp(`\\b${name}\\s*=\\s*(?:"([^"]+)"|'([^']+)'|([^\\s>]+))`, "i"))?.slice(1).find(Boolean) ?? null;
|
|
@@ -11405,30 +11430,36 @@ function firstContentImage(html) {
|
|
|
11405
11430
|
const width = Number(attr("width") ?? 0);
|
|
11406
11431
|
const height = Number(attr("height") ?? 0);
|
|
11407
11432
|
if (width > 0 && width < 200 || height > 0 && height < 120) continue;
|
|
11408
|
-
|
|
11433
|
+
images.push(candidate);
|
|
11409
11434
|
}
|
|
11410
|
-
return
|
|
11435
|
+
return images;
|
|
11411
11436
|
}
|
|
11412
|
-
function
|
|
11437
|
+
function resolveFeaturedImageCandidates(input) {
|
|
11413
11438
|
const replay = parseWaybackReplayUrl(input.pageUrl);
|
|
11414
11439
|
const baseUrl = replay?.originalUrl ?? input.pageUrl;
|
|
11415
11440
|
const candidates = [
|
|
11416
11441
|
{ value: input.meta["og:image"] ?? input.meta["og:image:url"] ?? input.meta["og:image:secure_url"], source: "og:image" },
|
|
11417
11442
|
{ value: input.meta["twitter:image"] ?? input.meta["twitter:image:src"], source: "twitter:image" },
|
|
11418
11443
|
{ value: firstJsonLdImage(input.schema), source: "json-ld" },
|
|
11419
|
-
|
|
11444
|
+
...contentImages(input.html).map((value) => ({ value, source: "content-image" }))
|
|
11420
11445
|
];
|
|
11446
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11447
|
+
const resolved = [];
|
|
11421
11448
|
for (const candidate of candidates) {
|
|
11422
11449
|
if (!candidate.value) continue;
|
|
11423
11450
|
const url = safeHttpUrl2(candidate.value, baseUrl);
|
|
11424
|
-
if (!url) continue;
|
|
11425
|
-
|
|
11451
|
+
if (!url || seen.has(url)) continue;
|
|
11452
|
+
seen.add(url);
|
|
11453
|
+
resolved.push({
|
|
11426
11454
|
url,
|
|
11427
11455
|
archivedUrl: replay ? buildWaybackReplayUrl(replay.timestamp, url, "im_") : null,
|
|
11428
11456
|
source: candidate.source
|
|
11429
|
-
};
|
|
11457
|
+
});
|
|
11430
11458
|
}
|
|
11431
|
-
return
|
|
11459
|
+
return resolved;
|
|
11460
|
+
}
|
|
11461
|
+
function resolveFeaturedImage(input) {
|
|
11462
|
+
return resolveFeaturedImageCandidates(input)[0] ?? null;
|
|
11432
11463
|
}
|
|
11433
11464
|
var import_p_limit, WAYBACK_HOSTS, MAX_CDX_RESPONSE_BYTES, MAX_CDX_ROWS, MAX_ARCHIVE_URL_CHARS, MAX_SELECTED_TIMELINE_CELLS, TIMELINE_CDX_CONCURRENCY;
|
|
11434
11465
|
var init_wayback = __esm({
|
|
@@ -50207,7 +50238,7 @@ var PACKAGE_VERSION;
|
|
|
50207
50238
|
var init_version = __esm({
|
|
50208
50239
|
"src/version.ts"() {
|
|
50209
50240
|
"use strict";
|
|
50210
|
-
PACKAGE_VERSION = "0.
|
|
50241
|
+
PACKAGE_VERSION = "0.67.1";
|
|
50211
50242
|
}
|
|
50212
50243
|
});
|
|
50213
50244
|
|
|
@@ -50278,9 +50309,10 @@ seam is noted so you can chain them.
|
|
|
50278
50309
|
guidance, recommended sections, optional sections, and heading guidance before any write occurs.
|
|
50279
50310
|
- Host a featured image -> **commons_host_image**. The normal write sequence is **commons_prepare_entity ->
|
|
50280
50311
|
compose the payload -> commons_host_image -> commons_validate_entity -> commons_submit_entity**. Put the
|
|
50281
|
-
permanent returned URL in featuredImage.url. Use imageBase64 for
|
|
50282
|
-
|
|
50283
|
-
|
|
50312
|
+
permanent returned URL in featuredImage.url. Use imageBase64 for pasted or AI-generated bytes, artifactId for an
|
|
50313
|
+
owner-scoped MCP Scraper image artifact, or sourceUrl for either a public HTTPS image or a webpage containing one.
|
|
50314
|
+
Webpage discovery tries Open Graph, Twitter, JSON-LD, then meaningful content images. Never pass a caller-local
|
|
50315
|
+
path, opaque chat attachment reference, or private/authenticated URL.
|
|
50284
50316
|
- Validate a composed entity without writing -> **commons_validate_entity**. Use it after image hosting and before
|
|
50285
50317
|
submit. Validation does not fetch or store image bytes; an external/unregistered featured image is reported in
|
|
50286
50318
|
imageDiagnostics as not publishable until commons_host_image returns its permanent Commons URL. Validation also
|
|
@@ -52031,7 +52063,7 @@ var init_contracts = __esm({
|
|
|
52031
52063
|
});
|
|
52032
52064
|
|
|
52033
52065
|
// src/mcp/mcp-tool-schemas.ts
|
|
52034
|
-
var import_zod45, WEBSITE_URL_OR_DOMAIN_ERROR, WebsiteUrlOrDomainSchema, HarvestPaaInputSchema, HarvestPaaHostedInputSchema, ExtractUrlBaseInputSchema, ExtractUrlInputSchema, ExtractUrlLocalInputSchema, DiffPageBaseInputSchema, DiffPageInputSchema, DiffPageLocalInputSchema, MapSiteUrlsInputSchema, MapWaybackSnapshotsInputSchema, ExtractSiteInputSchema, AnalyzeSiteSimilarityInputSchema, AuditSiteInputSchema, CheckSiteExportInputSchema, SiteExportReadInputSchema, SiteExportImageInputSchema, ArchiveReadInputSchema, YoutubeHarvestInputSchema, YoutubeTranscribeInputSchema, FacebookPageIntelInputSchema, FacebookAdSearchInputSchema, RedditThreadInputSchema, RedditTrendingInputSchema, VideoFrameAnalysisInputSchema, VideoFrameAnalysisStatusInputSchema, FacebookAdTranscribeInputSchema, FacebookVideoTranscribeInputSchema, GoogleAdsSearchInputSchema, GoogleAdsPageIntelInputSchema, GoogleAdsTranscribeInputSchema, InstagramProfileContentInputSchema, InstagramMediaDownloadInputSchema, MapsPlaceIntelInputSchema, TrustpilotReviewsInputSchema, G2ReviewsInputSchema, ReviewCardSchema, MapsSearchInputSchema, DirectoryWorkflowInputSchema, LeadScalarSchema2, LeadRowSchema, LeadColumnMapSchema2, LeadRowsImportSourceSchema, LeadCsvTextImportSourceSchema, LeadUploadImportSourceSchema, LeadListUploadStartInputSchema, LeadListImportInputSchema, LeadRowsEnrichmentSourceSchema, ImportedLeadListSourceSchema, LeadListEnrichInputSchema, LeadListEnrichStatusInputSchema, LocationMarketsInputSchema, CommonsSearchEntitiesInputSchema, CommonsGetEntityInputSchema, CommonsGetEntityLinksetInputSchema, CommonsFeaturedImageInputSchema, CommonsMediaInputSchema, CommonsCitationInputSchema, CommonsSourceInputSchema, CommonsRelatedLinkInputSchema, CommonsClaimInputSchema, CommonsPrepareEntityInputSchema, CommonsSubmitEntityInputSchema, CommonsValidateEntityInputSchema, CommonsGetEntityLedgerInputSchema, CommonsHostImageInputSchema, CommonsGetProposalInputSchema, CommonsSaveFilterInputSchema, CommonsListFiltersInputSchema, CommonsListNeedsLinksInputSchema, CommonsGenericOutputSchema, CommonsFeaturedImageDiagnosticsOutputSchema, CommonsValidateEntityOutputSchema, DirectoryWorkflowStatusInputSchema, LocalSourcebookSubmitInputSchema, LocalSourcebookCategorySchema, LocalSourcebookSchemaTypeInputSchema, LocalSourcebookTagCandidateObjectSchema, LocalSourcebookTagDecisionObjectSchema, LocalSourcebookIdentityObjectSchema, GetLocalSourcebookContractInputSchema, ListLocalSourcebookTagsInputSchema, ResolveLocalSourcebookTagsInputSchema, PrepareLocalSourcebookWriteInputSchema, ValidateLocalSourcebookWriteInputSchema, LocalSourcebookCaptureInputSchema, LocalSourcebookSubmissionStatusInputSchema, LocalSourcebookRefreshInputSchema, LocalSourcebookOutputSchema, ArtifactPointerOutputSchema, EditorialReadingRoomSiteSchema, EditorialReadingRoomImageSchema, EditorialReadingRoomArticleSchema, EditorialReadingRoomGuideInputSchema, EditorialReadingRoomGuideOutputSchema, CreateEditorialReadingRoomInputSchema, EditorialReadingRoomArtifactSchema, CreateEditorialReadingRoomOutputSchema, RenewEditorialReadingRoomDownloadInputSchema, RenewEditorialReadingRoomDownloadOutputSchema, CommonsPublicationSubdomainSchema, CommonsPreparePublicationInputSchema, CommonsValidatePublicationInputSchema, CommonsClaimPublicationInputSchema, CommonsPublishEditorialInputSchema, CommonsUpdateEditorialArticleInputSchema, CommonsGetPublicationInputSchema, RankTrackerModeSchema, RankTrackerBlueprintInputSchema, NullableString, MapsSearchAttemptOutput, MapsSearchOutputSchema, DirectoryMapsBusinessOutput, DirectoryCsvArtifactOutput, DirectoryWorkflowOutputSchema, LeadSuggestedColumnOutputSchema, LeadColumnMapSuggestionOutputSchema, LeadArtifactOutputSchema, LeadListUploadStartOutputSchema, LeadListImportOutputSchema, LeadCandidateOutputSchema, LeadProgressOutputSchema, LeadBillingOutputSchema, LeadAssociatedPersonSourceOutputSchema, LeadAssociatedPersonOutputSchema, LeadSampleRowOutputSchema, LeadListEnrichmentOutputSchema, LocationDatasetProvenanceOutput, LocationMarketsOutputSchema, RankTrackerToolPlanOutput, RankTrackerTableOutput, RankTrackerCronJobOutput, RankTrackerBlueprintOutputSchema, OrganicResultOutput, AiOverviewOutput, EntityIdsOutput, HarvestPaaOutputSchema, SearchSerpOutputSchema, PageMediaAssetOutput, PageMediaArtifactOutput, ExtractUrlOutputSchema, DiffPageOutputSchema, ExtractSiteOutputSchema, AuditSiteOutputSchema, CheckSiteExportOutputSchema, SiteExportReadOutputSchema, SiteExportImageOutputSchema, ArchiveEntryOutputSchema, ArchiveReadOutputSchema, MapsPlaceIntelOutputSchema, TrustpilotReviewsOutputSchema, G2ReviewsOutputSchema, CreditsInfoOutputSchema, MapSiteUrlsOutputSchema, WaybackCaptureOutputSchema, MapWaybackSnapshotsOutputSchema, YoutubeHarvestOutputSchema, FacebookAdSearchOutputSchema, VideoFrameAnalysisOutputSchema, VideoFrameAnalysisStatusOutputSchema, RedditThreadOutputSchema, RedditTrendingOutputSchema, FacebookPageIntelOutputSchema, GoogleAdsSearchOutputSchema, GoogleAdsPageIntelOutputSchema, TranscriptSignalOutput, FacebookVideoTranscribeOutputSchema, TranscriptChunkOutput, InstagramBrowserOutput, InstagramPaginationOutput, InstagramProfileContentOutputSchema, InstagramMediaTrackOutput, InstagramDownloadOutput, InstagramMediaDownloadOutputSchema, YoutubeTranscribeOutputSchema, FacebookAdTranscribeOutputSchema, GoogleAdsTranscribeOutputSchema, CaptureSerpSnapshotOutputSchema, CaptureSerpPageSnapshotsOutputSchema, CreditsInfoInputSchema, WorkflowIdSchema2, WorkflowListInputSchema, WorkflowSuggestInputSchema, WorkflowRunInputSchema, WorkflowStepInputSchema, WorkflowStatusInputSchema, WorkflowArtifactReadInputSchema, WorkflowRecipeOutput, WorkflowDefinitionOutput, WorkflowArtifactOutput, WorkflowListOutputSchema, WorkflowSuggestOutputSchema, WorkflowRunOutputSchema, WorkflowStepOutputSchema, WorkflowStatusOutputSchema, WorkflowArtifactReadOutputSchema, SearchSerpInputSchema, CaptureSerpSnapshotInputSchema, ScreenshotInputSchema, CaptureSerpPageSnapshotsInputSchema, ReportArtifactReadInputSchema, ReportArtifactReadOutputSchema, ListServiceConnectionsInputSchema, ListServiceConnectionsOutputSchema, TestServiceConnectionInputSchema, TestServiceConnectionOutputSchema, ReadServiceConnectionInputSchema, ReadServiceConnectionOutputSchema, MetaAdCreativeMediaInputSchema, MetaAdCreativeMediaOutputSchema, ImportServiceConnectionToMemoryInputSchema, ImportServiceConnectionToMemoryOutputSchema, DescribeServiceConnectionToolInputSchema, DescribeServiceConnectionToolOutputSchema, ConnectedDataContinuationSchema, ExportConnectedServiceDataInputSchema, ConnectedDataArtifactSchema, ExportConnectedServiceDataOutputSchema, SearchConsoleTableColumnSchema, SearchConsoleTableFilterSchema, ExportSearchConsoleTableDataInputSchema, ExportSearchConsoleTableDataOutputSchema, RenewConnectedDataExportDownloadInputSchema, RenewConnectedDataExportDownloadOutputSchema, CallServiceConnectionActionInputSchema, CallServiceConnectionActionOutputSchema, SetScheduledActionConnectionsInputSchema, SetScheduledActionConnectionsOutputSchema, SlackSendMessageInputSchema, SlackSendMessageOutputSchema, GmailSendMessageInputSchema, GmailSendMessageOutputSchema, GmailSearchContactsInputSchema, GmailSearchContactsOutputSchema, GoogleCalendarCreateEventInputSchema, GoogleCalendarCreateEventOutputSchema, ZoomCreateMeetingInputSchema, ZoomCreateMeetingOutputSchema;
|
|
52066
|
+
var import_zod45, WEBSITE_URL_OR_DOMAIN_ERROR, WebsiteUrlOrDomainSchema, HarvestPaaInputSchema, HarvestPaaHostedInputSchema, ExtractUrlBaseInputSchema, ExtractUrlInputSchema, ExtractUrlLocalInputSchema, DiffPageBaseInputSchema, DiffPageInputSchema, DiffPageLocalInputSchema, MapSiteUrlsInputSchema, MapWaybackSnapshotsInputSchema, ExtractSiteInputSchema, AnalyzeSiteSimilarityInputSchema, AuditSiteInputSchema, CheckSiteExportInputSchema, SiteExportReadInputSchema, SiteExportImageInputSchema, ArchiveReadInputSchema, YoutubeHarvestInputSchema, YoutubeTranscribeInputSchema, FacebookPageIntelInputSchema, FacebookAdSearchInputSchema, RedditThreadInputSchema, RedditTrendingInputSchema, VideoFrameAnalysisInputSchema, VideoFrameAnalysisStatusInputSchema, FacebookAdTranscribeInputSchema, FacebookVideoTranscribeInputSchema, GoogleAdsSearchInputSchema, GoogleAdsPageIntelInputSchema, GoogleAdsTranscribeInputSchema, InstagramProfileContentInputSchema, InstagramMediaDownloadInputSchema, MapsPlaceIntelInputSchema, TrustpilotReviewsInputSchema, G2ReviewsInputSchema, ReviewCardSchema, MapsSearchInputSchema, DirectoryWorkflowInputSchema, LeadScalarSchema2, LeadRowSchema, LeadColumnMapSchema2, LeadRowsImportSourceSchema, LeadCsvTextImportSourceSchema, LeadUploadImportSourceSchema, LeadListUploadStartInputSchema, LeadListImportInputSchema, LeadRowsEnrichmentSourceSchema, ImportedLeadListSourceSchema, LeadListEnrichInputSchema, LeadListEnrichStatusInputSchema, LocationMarketsInputSchema, CommonsSearchEntitiesInputSchema, CommonsGetEntityInputSchema, CommonsGetEntityLinksetInputSchema, CommonsFeaturedImageInputSchema, CommonsMediaInputSchema, CommonsCitationInputSchema, CommonsSourceInputSchema, CommonsRelatedLinkInputSchema, CommonsClaimInputSchema, CommonsPrepareEntityInputSchema, CommonsSubmitEntityInputSchema, CommonsValidateEntityInputSchema, CommonsGetEntityLedgerInputSchema, CommonsHostImageInputSchema, CommonsHostImageOutputSchema, CommonsGetProposalInputSchema, CommonsSaveFilterInputSchema, CommonsListFiltersInputSchema, CommonsListNeedsLinksInputSchema, CommonsGenericOutputSchema, CommonsFeaturedImageDiagnosticsOutputSchema, CommonsValidateEntityOutputSchema, DirectoryWorkflowStatusInputSchema, LocalSourcebookSubmitInputSchema, LocalSourcebookCategorySchema, LocalSourcebookSchemaTypeInputSchema, LocalSourcebookTagCandidateObjectSchema, LocalSourcebookTagDecisionObjectSchema, LocalSourcebookIdentityObjectSchema, GetLocalSourcebookContractInputSchema, ListLocalSourcebookTagsInputSchema, ResolveLocalSourcebookTagsInputSchema, PrepareLocalSourcebookWriteInputSchema, ValidateLocalSourcebookWriteInputSchema, LocalSourcebookCaptureInputSchema, LocalSourcebookSubmissionStatusInputSchema, LocalSourcebookRefreshInputSchema, LocalSourcebookOutputSchema, ArtifactPointerOutputSchema, EditorialReadingRoomSiteSchema, EditorialReadingRoomImageSchema, EditorialReadingRoomArticleSchema, EditorialReadingRoomGuideInputSchema, EditorialReadingRoomGuideOutputSchema, CreateEditorialReadingRoomInputSchema, EditorialReadingRoomArtifactSchema, CreateEditorialReadingRoomOutputSchema, RenewEditorialReadingRoomDownloadInputSchema, RenewEditorialReadingRoomDownloadOutputSchema, CommonsPublicationSubdomainSchema, CommonsPreparePublicationInputSchema, CommonsValidatePublicationInputSchema, CommonsClaimPublicationInputSchema, CommonsPublishEditorialInputSchema, CommonsUpdateEditorialArticleInputSchema, CommonsGetPublicationInputSchema, RankTrackerModeSchema, RankTrackerBlueprintInputSchema, NullableString, MapsSearchAttemptOutput, MapsSearchOutputSchema, DirectoryMapsBusinessOutput, DirectoryCsvArtifactOutput, DirectoryWorkflowOutputSchema, LeadSuggestedColumnOutputSchema, LeadColumnMapSuggestionOutputSchema, LeadArtifactOutputSchema, LeadListUploadStartOutputSchema, LeadListImportOutputSchema, LeadCandidateOutputSchema, LeadProgressOutputSchema, LeadBillingOutputSchema, LeadAssociatedPersonSourceOutputSchema, LeadAssociatedPersonOutputSchema, LeadSampleRowOutputSchema, LeadListEnrichmentOutputSchema, LocationDatasetProvenanceOutput, LocationMarketsOutputSchema, RankTrackerToolPlanOutput, RankTrackerTableOutput, RankTrackerCronJobOutput, RankTrackerBlueprintOutputSchema, OrganicResultOutput, AiOverviewOutput, EntityIdsOutput, HarvestPaaOutputSchema, SearchSerpOutputSchema, PageMediaAssetOutput, PageMediaArtifactOutput, ExtractUrlOutputSchema, DiffPageOutputSchema, ExtractSiteOutputSchema, AuditSiteOutputSchema, CheckSiteExportOutputSchema, SiteExportReadOutputSchema, SiteExportImageOutputSchema, ArchiveEntryOutputSchema, ArchiveReadOutputSchema, MapsPlaceIntelOutputSchema, TrustpilotReviewsOutputSchema, G2ReviewsOutputSchema, CreditsInfoOutputSchema, MapSiteUrlsOutputSchema, WaybackCaptureOutputSchema, MapWaybackSnapshotsOutputSchema, YoutubeHarvestOutputSchema, FacebookAdSearchOutputSchema, VideoFrameAnalysisOutputSchema, VideoFrameAnalysisStatusOutputSchema, RedditThreadOutputSchema, RedditTrendingOutputSchema, FacebookPageIntelOutputSchema, GoogleAdsSearchOutputSchema, GoogleAdsPageIntelOutputSchema, TranscriptSignalOutput, FacebookVideoTranscribeOutputSchema, TranscriptChunkOutput, InstagramBrowserOutput, InstagramPaginationOutput, InstagramProfileContentOutputSchema, InstagramMediaTrackOutput, InstagramDownloadOutput, InstagramMediaDownloadOutputSchema, YoutubeTranscribeOutputSchema, FacebookAdTranscribeOutputSchema, GoogleAdsTranscribeOutputSchema, CaptureSerpSnapshotOutputSchema, CaptureSerpPageSnapshotsOutputSchema, CreditsInfoInputSchema, WorkflowIdSchema2, WorkflowListInputSchema, WorkflowSuggestInputSchema, WorkflowRunInputSchema, WorkflowStepInputSchema, WorkflowStatusInputSchema, WorkflowArtifactReadInputSchema, WorkflowRecipeOutput, WorkflowDefinitionOutput, WorkflowArtifactOutput, WorkflowListOutputSchema, WorkflowSuggestOutputSchema, WorkflowRunOutputSchema, WorkflowStepOutputSchema, WorkflowStatusOutputSchema, WorkflowArtifactReadOutputSchema, SearchSerpInputSchema, CaptureSerpSnapshotInputSchema, ScreenshotInputSchema, CaptureSerpPageSnapshotsInputSchema, ReportArtifactReadInputSchema, ReportArtifactReadOutputSchema, ListServiceConnectionsInputSchema, ListServiceConnectionsOutputSchema, TestServiceConnectionInputSchema, TestServiceConnectionOutputSchema, ReadServiceConnectionInputSchema, ReadServiceConnectionOutputSchema, MetaAdCreativeMediaInputSchema, MetaAdCreativeMediaOutputSchema, ImportServiceConnectionToMemoryInputSchema, ImportServiceConnectionToMemoryOutputSchema, DescribeServiceConnectionToolInputSchema, DescribeServiceConnectionToolOutputSchema, ConnectedDataContinuationSchema, ExportConnectedServiceDataInputSchema, ConnectedDataArtifactSchema, ExportConnectedServiceDataOutputSchema, SearchConsoleTableColumnSchema, SearchConsoleTableFilterSchema, ExportSearchConsoleTableDataInputSchema, ExportSearchConsoleTableDataOutputSchema, RenewConnectedDataExportDownloadInputSchema, RenewConnectedDataExportDownloadOutputSchema, CallServiceConnectionActionInputSchema, CallServiceConnectionActionOutputSchema, SetScheduledActionConnectionsInputSchema, SetScheduledActionConnectionsOutputSchema, SlackSendMessageInputSchema, SlackSendMessageOutputSchema, GmailSendMessageInputSchema, GmailSendMessageOutputSchema, GmailSearchContactsInputSchema, GmailSearchContactsOutputSchema, GoogleCalendarCreateEventInputSchema, GoogleCalendarCreateEventOutputSchema, ZoomCreateMeetingInputSchema, ZoomCreateMeetingOutputSchema;
|
|
52035
52067
|
var init_mcp_tool_schemas = __esm({
|
|
52036
52068
|
"src/mcp/mcp-tool-schemas.ts"() {
|
|
52037
52069
|
"use strict";
|
|
@@ -52444,7 +52476,7 @@ var init_mcp_tool_schemas = __esm({
|
|
|
52444
52476
|
idOrSlug: import_zod45.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.")
|
|
52445
52477
|
};
|
|
52446
52478
|
CommonsFeaturedImageInputSchema = import_zod45.z.object({
|
|
52447
|
-
url: import_zod45.z.string().url().describe("For a publish-ready entity, use the permanent URL returned by commons_host_image.
|
|
52479
|
+
url: import_zod45.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."),
|
|
52448
52480
|
alt: import_zod45.z.string().trim().max(500).optional(),
|
|
52449
52481
|
caption: import_zod45.z.string().trim().max(1e3).optional(),
|
|
52450
52482
|
sourceUrl: import_zod45.z.string().url().optional(),
|
|
@@ -52543,7 +52575,7 @@ var init_mcp_tool_schemas = __esm({
|
|
|
52543
52575
|
entityId: import_zod45.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."),
|
|
52544
52576
|
entityType: import_zod45.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."),
|
|
52545
52577
|
disambiguationName: import_zod45.z.string().trim().max(240).optional().describe("Clarifying name used when the concept could be confused with another entity."),
|
|
52546
|
-
featuredImage: CommonsFeaturedImageInputSchema.optional().describe("Required for auto-published public entities. First call commons_host_image
|
|
52578
|
+
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."),
|
|
52547
52579
|
source: CommonsSourceInputSchema.optional().describe("Source provenance. Store original URL, source byline, and origin canonical here; canonical does not replace rights review."),
|
|
52548
52580
|
tags: import_zod45.z.array(import_zod45.z.string().trim().min(1).max(80)).max(24).optional().describe("Standardized topic tags. Use existing/searchable concepts when possible."),
|
|
52549
52581
|
keywords: import_zod45.z.array(import_zod45.z.string().trim().min(1).max(120)).max(50).optional().describe("SEO and retrieval keywords."),
|
|
@@ -52605,12 +52637,31 @@ var init_mcp_tool_schemas = __esm({
|
|
|
52605
52637
|
idOrSlug: import_zod45.z.string().trim().min(1).max(180).describe("Published entity id or /wiki/ slug whose contribution ledger should be read.")
|
|
52606
52638
|
};
|
|
52607
52639
|
CommonsHostImageInputSchema = {
|
|
52608
|
-
sourceUrl: import_zod45.z.string().url().optional().describe("
|
|
52609
|
-
imageBase64: import_zod45.z.string().min(16).optional().describe("Base64 image bytes for an image
|
|
52640
|
+
sourceUrl: import_zod45.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."),
|
|
52641
|
+
imageBase64: import_zod45.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."),
|
|
52642
|
+
artifactId: import_zod45.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."),
|
|
52643
|
+
sourceType: import_zod45.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."),
|
|
52610
52644
|
alt: import_zod45.z.string().trim().max(500).optional().describe("Alt text describing the image for readers who cannot see it."),
|
|
52611
52645
|
license: import_zod45.z.string().trim().max(240).optional().describe("License or usage terms of the original image, preserved with the hosted copy."),
|
|
52612
52646
|
attribution: import_zod45.z.string().trim().max(500).optional().describe("Credit line for the original photographer, publication, or archive.")
|
|
52613
52647
|
};
|
|
52648
|
+
CommonsHostImageOutputSchema = {
|
|
52649
|
+
ok: import_zod45.z.boolean(),
|
|
52650
|
+
data: import_zod45.z.object({
|
|
52651
|
+
id: import_zod45.z.string().describe("Stable Commons image ID."),
|
|
52652
|
+
url: import_zod45.z.string().url().describe("Permanent Commons URL to use as featuredImage.url."),
|
|
52653
|
+
contentType: import_zod45.z.enum(["image/jpeg", "image/png", "image/gif", "image/webp"]),
|
|
52654
|
+
bytes: import_zod45.z.number().int().positive(),
|
|
52655
|
+
digest: import_zod45.z.string(),
|
|
52656
|
+
sourceUrl: import_zod45.z.string().url().nullable().describe("Sanitized direct asset URL that supplied the hosted bytes, when applicable."),
|
|
52657
|
+
sourcePageUrl: import_zod45.z.string().url().nullable().describe("Sanitized webpage URL from which the image was discovered, when applicable."),
|
|
52658
|
+
sourceKind: import_zod45.z.enum(["uploaded", "ai_generated", "artifact", "direct_url", "webpage", "registered"]),
|
|
52659
|
+
selectionSource: import_zod45.z.enum(["provided_bytes", "artifact", "direct_url", "og:image", "twitter:image", "json-ld", "content-image", "registered"]),
|
|
52660
|
+
reused: import_zod45.z.boolean().describe("True when identical image bytes were already stored.")
|
|
52661
|
+
}).optional(),
|
|
52662
|
+
error: import_zod45.z.string().optional(),
|
|
52663
|
+
message: import_zod45.z.string().optional()
|
|
52664
|
+
};
|
|
52614
52665
|
CommonsGetProposalInputSchema = {
|
|
52615
52666
|
proposalId: import_zod45.z.string().trim().min(1).max(120).describe("Proposal id returned by commons_submit_entity, in the form commons-proposal-<uuid>.")
|
|
52616
52667
|
};
|
|
@@ -56597,9 +56648,9 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
|
|
|
56597
56648
|
}, async (input) => executor.commonsGetEntityLedger(input));
|
|
56598
56649
|
server.registerTool("commons_host_image", {
|
|
56599
56650
|
title: "Host a Transparent Commons Image",
|
|
56600
|
-
description: "
|
|
56651
|
+
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.",
|
|
56601
56652
|
inputSchema: CommonsHostImageInputSchema,
|
|
56602
|
-
outputSchema: recordOutputSchema("commons_host_image",
|
|
56653
|
+
outputSchema: recordOutputSchema("commons_host_image", CommonsHostImageOutputSchema),
|
|
56603
56654
|
annotations: {
|
|
56604
56655
|
title: "Host a Transparent Commons Image",
|
|
56605
56656
|
readOnlyHint: false,
|
|
@@ -57141,6 +57192,18 @@ async function readResponseData(res) {
|
|
|
57141
57192
|
return text2;
|
|
57142
57193
|
}
|
|
57143
57194
|
}
|
|
57195
|
+
function attachJsonStructuredContent(result) {
|
|
57196
|
+
if (result.isError || result.structuredContent) return result;
|
|
57197
|
+
const text2 = result.content.find((part) => part.type === "text");
|
|
57198
|
+
if (!text2 || text2.type !== "text") return result;
|
|
57199
|
+
try {
|
|
57200
|
+
const parsed = JSON.parse(text2.text);
|
|
57201
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return result;
|
|
57202
|
+
return { ...result, structuredContent: parsed };
|
|
57203
|
+
} catch {
|
|
57204
|
+
return result;
|
|
57205
|
+
}
|
|
57206
|
+
}
|
|
57144
57207
|
function httpErrorPayload(path6, res, data) {
|
|
57145
57208
|
const objectData = data && typeof data === "object" && !Array.isArray(data) ? data : null;
|
|
57146
57209
|
const rawCode = objectData?.code ?? objectData?.errorCode ?? objectData?.error_code;
|
|
@@ -57760,8 +57823,8 @@ var init_http_mcp_tool_executor = __esm({
|
|
|
57760
57823
|
commonsGetProposal(input) {
|
|
57761
57824
|
return this.getJson(`/commons/proposals/${encodeURIComponent(input.proposalId)}`);
|
|
57762
57825
|
}
|
|
57763
|
-
commonsHostImage(input) {
|
|
57764
|
-
return this.call("/commons/images", input);
|
|
57826
|
+
async commonsHostImage(input) {
|
|
57827
|
+
return attachJsonStructuredContent(await this.call("/commons/images", input));
|
|
57765
57828
|
}
|
|
57766
57829
|
commonsUpdateEditorialArticle(input) {
|
|
57767
57830
|
const { idempotencyKey: idempotencyKey4, ...body } = input;
|
|
@@ -72162,6 +72225,9 @@ async function assertPublicHttpsUrl(rawUrl) {
|
|
|
72162
72225
|
if (url.protocol !== "https:") {
|
|
72163
72226
|
throw new CommonsImageError("image_url_not_https", "Commons image sources must be https URLs.");
|
|
72164
72227
|
}
|
|
72228
|
+
if (url.username || url.password) {
|
|
72229
|
+
throw new CommonsImageError("image_url_invalid", "Commons image source URLs cannot contain embedded credentials.");
|
|
72230
|
+
}
|
|
72165
72231
|
const hostname = url.hostname.replace(/^\[|\]$/g, "");
|
|
72166
72232
|
const addresses = (0, import_node_net2.isIP)(hostname) ? [{ address: hostname }] : await (0, import_promises16.lookup)(hostname, { all: true }).catch(() => []);
|
|
72167
72233
|
if (!addresses.length) {
|
|
@@ -72172,7 +72238,28 @@ async function assertPublicHttpsUrl(rawUrl) {
|
|
|
72172
72238
|
}
|
|
72173
72239
|
return url;
|
|
72174
72240
|
}
|
|
72175
|
-
async function
|
|
72241
|
+
async function readResponseBytes(response, maxBytes) {
|
|
72242
|
+
const declaredLength = Number(response.headers.get("content-length") ?? "0");
|
|
72243
|
+
if (declaredLength > maxBytes) {
|
|
72244
|
+
throw new CommonsImageError("image_too_large", `Source exceeds the ${maxBytes} byte limit.`, 413);
|
|
72245
|
+
}
|
|
72246
|
+
if (!response.body) return Buffer.alloc(0);
|
|
72247
|
+
const reader = response.body.getReader();
|
|
72248
|
+
const chunks = [];
|
|
72249
|
+
let total = 0;
|
|
72250
|
+
while (true) {
|
|
72251
|
+
const { done, value } = await reader.read();
|
|
72252
|
+
if (done) break;
|
|
72253
|
+
total += value.byteLength;
|
|
72254
|
+
if (total > maxBytes) {
|
|
72255
|
+
await reader.cancel().catch(() => void 0);
|
|
72256
|
+
throw new CommonsImageError("image_too_large", `Source exceeds the ${maxBytes} byte limit.`, 413);
|
|
72257
|
+
}
|
|
72258
|
+
chunks.push(Buffer.from(value));
|
|
72259
|
+
}
|
|
72260
|
+
return Buffer.concat(chunks, total);
|
|
72261
|
+
}
|
|
72262
|
+
async function downloadPublicSource(sourceUrl) {
|
|
72176
72263
|
let current = sourceUrl;
|
|
72177
72264
|
for (let redirect = 0; redirect <= COMMONS_IMAGE_MAX_REDIRECTS; redirect += 1) {
|
|
72178
72265
|
const url = await assertPublicHttpsUrl(current);
|
|
@@ -72207,15 +72294,11 @@ async function downloadImage(sourceUrl) {
|
|
|
72207
72294
|
retryable
|
|
72208
72295
|
);
|
|
72209
72296
|
}
|
|
72210
|
-
|
|
72211
|
-
|
|
72212
|
-
|
|
72213
|
-
|
|
72214
|
-
|
|
72215
|
-
if (bytes.length > COMMONS_IMAGE_MAX_BYTES) {
|
|
72216
|
-
throw new CommonsImageError("image_too_large", `Image exceeds the ${COMMONS_IMAGE_MAX_BYTES} byte limit.`, 413);
|
|
72217
|
-
}
|
|
72218
|
-
return bytes;
|
|
72297
|
+
return {
|
|
72298
|
+
bytes: await readResponseBytes(response, COMMONS_IMAGE_MAX_BYTES),
|
|
72299
|
+
finalUrl: url.toString(),
|
|
72300
|
+
contentType: (response.headers.get("content-type") ?? "").split(";")[0].trim().toLowerCase()
|
|
72301
|
+
};
|
|
72219
72302
|
}
|
|
72220
72303
|
throw new CommonsImageError("image_redirect_limit", "Image source exceeded the redirect limit.");
|
|
72221
72304
|
}
|
|
@@ -72228,6 +72311,114 @@ function decodeBase64Image(value) {
|
|
|
72228
72311
|
}
|
|
72229
72312
|
return bytes;
|
|
72230
72313
|
}
|
|
72314
|
+
function safeProvenanceUrl(rawUrl) {
|
|
72315
|
+
try {
|
|
72316
|
+
const url = new URL(rawUrl);
|
|
72317
|
+
url.username = "";
|
|
72318
|
+
url.password = "";
|
|
72319
|
+
url.search = "";
|
|
72320
|
+
url.hash = "";
|
|
72321
|
+
return url.toString();
|
|
72322
|
+
} catch {
|
|
72323
|
+
return null;
|
|
72324
|
+
}
|
|
72325
|
+
}
|
|
72326
|
+
function looksLikeHtml(bytes, declaredType) {
|
|
72327
|
+
if (declaredType === "text/html" || declaredType === "application/xhtml+xml") return true;
|
|
72328
|
+
const prefix = bytes.subarray(0, 512).toString("utf8").trimStart().toLowerCase();
|
|
72329
|
+
return prefix.startsWith("<!doctype html") || prefix.startsWith("<html") || prefix.startsWith("<head");
|
|
72330
|
+
}
|
|
72331
|
+
async function resolveCommonsImageSource(input) {
|
|
72332
|
+
const supplied = [input.sourceUrl, input.imageBase64, input.artifactId].filter((value) => Boolean(value)).length;
|
|
72333
|
+
if (supplied === 0) {
|
|
72334
|
+
throw new CommonsImageError("image_source_missing", "Provide exactly one of sourceUrl, imageBase64, or artifactId.");
|
|
72335
|
+
}
|
|
72336
|
+
if (supplied !== 1) {
|
|
72337
|
+
throw new CommonsImageError("image_source_ambiguous", "Provide only one image source: sourceUrl, imageBase64, or artifactId.");
|
|
72338
|
+
}
|
|
72339
|
+
if (input.sourceUrl && input.sourceType) {
|
|
72340
|
+
throw new CommonsImageError("image_source_type_invalid", "sourceType applies only to imageBase64 or artifactId, not sourceUrl.");
|
|
72341
|
+
}
|
|
72342
|
+
if (input.imageBase64) {
|
|
72343
|
+
return {
|
|
72344
|
+
bytes: decodeBase64Image(input.imageBase64),
|
|
72345
|
+
sourceUrl: null,
|
|
72346
|
+
sourcePageUrl: null,
|
|
72347
|
+
sourceKind: input.sourceType ?? "uploaded",
|
|
72348
|
+
selectionSource: "provided_bytes"
|
|
72349
|
+
};
|
|
72350
|
+
}
|
|
72351
|
+
if (input.artifactId) {
|
|
72352
|
+
const bytes = await readOwnedImageSourceArtifact({ artifactId: input.artifactId, ownerId: String(input.userId) });
|
|
72353
|
+
if (!bytes) {
|
|
72354
|
+
throw new CommonsImageError("image_artifact_not_found", "The image artifact was not found, expired, or is not owned by this account.", 422);
|
|
72355
|
+
}
|
|
72356
|
+
if (bytes.length > COMMONS_IMAGE_MAX_BYTES) {
|
|
72357
|
+
throw new CommonsImageError("image_too_large", `Image exceeds the ${COMMONS_IMAGE_MAX_BYTES} byte limit.`, 413);
|
|
72358
|
+
}
|
|
72359
|
+
return {
|
|
72360
|
+
bytes,
|
|
72361
|
+
sourceUrl: null,
|
|
72362
|
+
sourcePageUrl: null,
|
|
72363
|
+
sourceKind: input.sourceType ?? "artifact",
|
|
72364
|
+
selectionSource: "artifact"
|
|
72365
|
+
};
|
|
72366
|
+
}
|
|
72367
|
+
const requestedUrl = String(input.sourceUrl);
|
|
72368
|
+
const downloaded = await downloadPublicSource(requestedUrl);
|
|
72369
|
+
if (sniffImageFormat(downloaded.bytes)) {
|
|
72370
|
+
return {
|
|
72371
|
+
bytes: downloaded.bytes,
|
|
72372
|
+
sourceUrl: safeProvenanceUrl(downloaded.finalUrl),
|
|
72373
|
+
sourcePageUrl: null,
|
|
72374
|
+
sourceKind: "direct_url",
|
|
72375
|
+
selectionSource: "direct_url"
|
|
72376
|
+
};
|
|
72377
|
+
}
|
|
72378
|
+
if (!looksLikeHtml(downloaded.bytes, downloaded.contentType)) {
|
|
72379
|
+
throw new CommonsImageError(
|
|
72380
|
+
"image_format_unsupported",
|
|
72381
|
+
"The supplied URL returned neither a supported image nor an HTML webpage with a discoverable image.",
|
|
72382
|
+
415
|
|
72383
|
+
);
|
|
72384
|
+
}
|
|
72385
|
+
if (downloaded.bytes.length > COMMONS_IMAGE_PAGE_MAX_BYTES) {
|
|
72386
|
+
throw new CommonsImageError("image_page_too_large", `Webpage exceeds the ${COMMONS_IMAGE_PAGE_MAX_BYTES} byte discovery limit.`, 413);
|
|
72387
|
+
}
|
|
72388
|
+
const html = downloaded.bytes.toString("utf8");
|
|
72389
|
+
const document2 = loadHtmlDocument(html);
|
|
72390
|
+
const candidates = resolveFeaturedImageCandidates({
|
|
72391
|
+
html,
|
|
72392
|
+
meta: document2.meta,
|
|
72393
|
+
schema: document2.schema,
|
|
72394
|
+
pageUrl: downloaded.finalUrl
|
|
72395
|
+
}).slice(0, COMMONS_IMAGE_MAX_PAGE_CANDIDATES);
|
|
72396
|
+
if (!candidates.length) {
|
|
72397
|
+
throw new CommonsImageError("page_image_not_found", "The webpage did not expose a usable featured or content image.", 422);
|
|
72398
|
+
}
|
|
72399
|
+
let sawRetryableFailure = false;
|
|
72400
|
+
for (const candidate of candidates) {
|
|
72401
|
+
try {
|
|
72402
|
+
const image = await downloadPublicSource(candidate.url);
|
|
72403
|
+
if (!sniffImageFormat(image.bytes)) continue;
|
|
72404
|
+
return {
|
|
72405
|
+
bytes: image.bytes,
|
|
72406
|
+
sourceUrl: safeProvenanceUrl(image.finalUrl),
|
|
72407
|
+
sourcePageUrl: safeProvenanceUrl(downloaded.finalUrl),
|
|
72408
|
+
sourceKind: "webpage",
|
|
72409
|
+
selectionSource: candidate.source
|
|
72410
|
+
};
|
|
72411
|
+
} catch (error) {
|
|
72412
|
+
if (error instanceof CommonsImageError && error.retryable) sawRetryableFailure = true;
|
|
72413
|
+
}
|
|
72414
|
+
}
|
|
72415
|
+
throw new CommonsImageError(
|
|
72416
|
+
"page_image_candidates_unusable",
|
|
72417
|
+
"The webpage exposed image candidates, but none returned supported public image bytes.",
|
|
72418
|
+
422,
|
|
72419
|
+
sawRetryableFailure
|
|
72420
|
+
);
|
|
72421
|
+
}
|
|
72231
72422
|
function commonsImageBlobStore() {
|
|
72232
72423
|
const token6 = process.env.COMMONS_IMAGE_READ_WRITE_TOKEN?.trim() || process.env.COMMONS_IMAGE_BLOB_READ_WRITE_TOKEN?.trim() || process.env.BLOB_READ_WRITE_TOKEN?.trim();
|
|
72233
72424
|
return token6 ? new VercelBlobStore(token6) : getBlobStore();
|
|
@@ -72259,16 +72450,21 @@ async function findCommonsHostedImageByUrl(rawUrl) {
|
|
|
72259
72450
|
bytes: Number(row.bytes),
|
|
72260
72451
|
digest: String(row.digest),
|
|
72261
72452
|
sourceUrl: row.source_url ? String(row.source_url) : null,
|
|
72453
|
+
sourcePageUrl: null,
|
|
72454
|
+
sourceKind: "registered",
|
|
72455
|
+
selectionSource: "registered",
|
|
72262
72456
|
reused: true
|
|
72263
72457
|
};
|
|
72264
72458
|
}
|
|
72265
72459
|
async function hostCommonsImage(input) {
|
|
72266
72460
|
if (hostOverride) return hostOverride(input);
|
|
72267
72461
|
await ensureCommonsImageSchema();
|
|
72268
|
-
if (
|
|
72269
|
-
|
|
72462
|
+
if (input.sourceUrl && !input.imageBase64 && !input.artifactId && !input.sourceType) {
|
|
72463
|
+
const registered6 = await findCommonsHostedImageByUrl(input.sourceUrl);
|
|
72464
|
+
if (registered6) return registered6;
|
|
72270
72465
|
}
|
|
72271
|
-
const
|
|
72466
|
+
const resolved = await resolveCommonsImageSource(input);
|
|
72467
|
+
const bytes = resolved.bytes;
|
|
72272
72468
|
const contentType = sniffImageFormat(bytes);
|
|
72273
72469
|
if (!contentType) {
|
|
72274
72470
|
throw new CommonsImageError(
|
|
@@ -72290,7 +72486,10 @@ async function hostCommonsImage(input) {
|
|
|
72290
72486
|
contentType: String(reusable.content_type),
|
|
72291
72487
|
bytes: Number(reusable.bytes),
|
|
72292
72488
|
digest: digest2,
|
|
72293
|
-
sourceUrl:
|
|
72489
|
+
sourceUrl: resolved.sourceUrl,
|
|
72490
|
+
sourcePageUrl: resolved.sourcePageUrl,
|
|
72491
|
+
sourceKind: resolved.sourceKind,
|
|
72492
|
+
selectionSource: resolved.selectionSource,
|
|
72294
72493
|
reused: true
|
|
72295
72494
|
};
|
|
72296
72495
|
}
|
|
@@ -72319,14 +72518,25 @@ async function hostCommonsImage(input) {
|
|
|
72319
72518
|
stored.url,
|
|
72320
72519
|
contentType,
|
|
72321
72520
|
bytes.length,
|
|
72322
|
-
|
|
72521
|
+
resolved.sourceUrl,
|
|
72323
72522
|
input.alt ?? null,
|
|
72324
72523
|
input.license ?? null,
|
|
72325
72524
|
input.attribution ?? null,
|
|
72326
72525
|
(/* @__PURE__ */ new Date()).toISOString()
|
|
72327
72526
|
]
|
|
72328
72527
|
});
|
|
72329
|
-
return {
|
|
72528
|
+
return {
|
|
72529
|
+
id,
|
|
72530
|
+
url: stored.url,
|
|
72531
|
+
contentType,
|
|
72532
|
+
bytes: bytes.length,
|
|
72533
|
+
digest: digest2,
|
|
72534
|
+
sourceUrl: resolved.sourceUrl,
|
|
72535
|
+
sourcePageUrl: resolved.sourcePageUrl,
|
|
72536
|
+
sourceKind: resolved.sourceKind,
|
|
72537
|
+
selectionSource: resolved.selectionSource,
|
|
72538
|
+
reused: false
|
|
72539
|
+
};
|
|
72330
72540
|
}
|
|
72331
72541
|
async function hostEntityImages(input) {
|
|
72332
72542
|
const rewrite = { mediaUrls: /* @__PURE__ */ new Map(), dropped: [] };
|
|
@@ -72368,7 +72578,7 @@ async function hostEntityImages(input) {
|
|
|
72368
72578
|
}
|
|
72369
72579
|
return rewrite;
|
|
72370
72580
|
}
|
|
72371
|
-
var import_node_crypto46, import_promises16, import_node_net2, COMMONS_IMAGE_MAX_BYTES, COMMONS_IMAGE_MAX_REDIRECTS, COMMONS_IMAGE_FETCH_TIMEOUT_MS, COMMONS_IMAGE_RETRY_GUIDANCE, CommonsImageError, imageSchemaReady, imageSchemaDb, hostOverride;
|
|
72581
|
+
var import_node_crypto46, import_promises16, import_node_net2, COMMONS_IMAGE_MAX_BYTES, COMMONS_IMAGE_MAX_REDIRECTS, COMMONS_IMAGE_FETCH_TIMEOUT_MS, COMMONS_IMAGE_PAGE_MAX_BYTES, COMMONS_IMAGE_MAX_PAGE_CANDIDATES, COMMONS_IMAGE_RETRY_GUIDANCE, CommonsImageError, imageSchemaReady, imageSchemaDb, hostOverride;
|
|
72372
72582
|
var init_commons_image_store = __esm({
|
|
72373
72583
|
"src/api/commons-image-store.ts"() {
|
|
72374
72584
|
"use strict";
|
|
@@ -72377,10 +72587,15 @@ var init_commons_image_store = __esm({
|
|
|
72377
72587
|
import_node_net2 = require("net");
|
|
72378
72588
|
init_blob_store();
|
|
72379
72589
|
init_db();
|
|
72590
|
+
init_image_source_artifacts();
|
|
72591
|
+
init_html_document();
|
|
72592
|
+
init_wayback();
|
|
72380
72593
|
COMMONS_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
72381
72594
|
COMMONS_IMAGE_MAX_REDIRECTS = 3;
|
|
72382
72595
|
COMMONS_IMAGE_FETCH_TIMEOUT_MS = 2e4;
|
|
72383
|
-
|
|
72596
|
+
COMMONS_IMAGE_PAGE_MAX_BYTES = 2 * 1024 * 1024;
|
|
72597
|
+
COMMONS_IMAGE_MAX_PAGE_CANDIDATES = 12;
|
|
72598
|
+
COMMONS_IMAGE_RETRY_GUIDANCE = "Call commons_host_image with imageBase64, an owner-authorized artifactId, a public HTTPS image URL, or a public HTTPS webpage containing a usable featured image. Replace featuredImage.url with the returned permanent URL, validate again, then retry commons_submit_entity with the same idempotency key.";
|
|
72384
72599
|
CommonsImageError = class extends Error {
|
|
72385
72600
|
constructor(code, message, httpStatus = 400, retryable = false, retryGuidance = COMMONS_IMAGE_RETRY_GUIDANCE) {
|
|
72386
72601
|
super(message);
|
|
@@ -75926,11 +76141,13 @@ var init_commons_routes = __esm({
|
|
|
75926
76141
|
HostImageSchema = import_zod54.z.object({
|
|
75927
76142
|
sourceUrl: import_zod54.z.string().url().optional(),
|
|
75928
76143
|
imageBase64: import_zod54.z.string().min(16).optional(),
|
|
76144
|
+
artifactId: import_zod54.z.string().min(1).max(500).optional(),
|
|
76145
|
+
sourceType: import_zod54.z.enum(["uploaded", "ai_generated"]).optional(),
|
|
75929
76146
|
alt: import_zod54.z.string().max(500).optional(),
|
|
75930
76147
|
license: import_zod54.z.string().max(240).optional(),
|
|
75931
76148
|
attribution: import_zod54.z.string().max(500).optional()
|
|
75932
|
-
}).strict().refine((body) =>
|
|
75933
|
-
message: "Provide
|
|
76149
|
+
}).strict().refine((body) => [body.sourceUrl, body.imageBase64, body.artifactId].filter(Boolean).length === 1, {
|
|
76150
|
+
message: "Provide exactly one of sourceUrl, imageBase64, or artifactId."
|
|
75934
76151
|
});
|
|
75935
76152
|
commonsApp.post("/images", auth2, async (c) => {
|
|
75936
76153
|
const parsed = HostImageSchema.safeParse(await c.req.json().catch(() => ({})));
|
package/dist/bin/api-server.js
CHANGED
|
@@ -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-
|
|
21
|
-
import("../worker-
|
|
22
|
-
import("../db-
|
|
20
|
+
import("../server-ROIJWWJG.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 {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
// release-message.json
|
|
5
5
|
var release_message_default = {
|
|
6
|
-
message: "Transparent Commons now
|
|
6
|
+
message: "Transparent Commons image hosting now accepts the source a user has and returns the same permanent-image result in both readable and typed MCP channels."
|
|
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.
|
|
115
|
+
var PACKAGE_VERSION = "0.67.1";
|
|
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;
|