mcp-scraper 0.57.3 → 0.58.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 (36) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +2 -2
  3. package/dist/bin/api-server.cjs +136 -9
  4. package/dist/bin/api-server.cjs.map +1 -1
  5. package/dist/bin/api-server.js +2 -2
  6. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  7. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  8. package/dist/bin/mcp-scraper-cli.js +1 -1
  9. package/dist/bin/mcp-scraper-install.cjs +2 -2
  10. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  11. package/dist/bin/mcp-scraper-install.js +2 -2
  12. package/dist/bin/mcp-stdio-server.cjs +31 -4
  13. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  14. package/dist/bin/mcp-stdio-server.js +4 -4
  15. package/dist/{chunk-R6CO77BN.js → chunk-2U2ZDDSI.js} +3 -3
  16. package/dist/{chunk-R6CO77BN.js.map → chunk-2U2ZDDSI.js.map} +1 -1
  17. package/dist/chunk-EJ6KU4PC.js +7 -0
  18. package/dist/chunk-EJ6KU4PC.js.map +1 -0
  19. package/dist/{chunk-HU4R6BP2.js → chunk-IMBMDZUO.js} +2 -2
  20. package/dist/{chunk-HU4R6BP2.js.map → chunk-IMBMDZUO.js.map} +1 -1
  21. package/dist/{chunk-5XYBKE3X.js → chunk-KMGRM4FL.js} +2 -2
  22. package/dist/{chunk-QSUSTYB3.js → chunk-P32KEY3D.js} +33 -5
  23. package/dist/chunk-P32KEY3D.js.map +1 -0
  24. package/dist/{extract-bundle-H7JEELY7.js → extract-bundle-XRRN6NAZ.js} +3 -3
  25. package/dist/{server-EP2SK2ID.js → server-J4YGBOTS.js} +113 -12
  26. package/dist/{server-EP2SK2ID.js.map → server-J4YGBOTS.js.map} +1 -1
  27. package/dist/{site-extract-repository-CFMSWAVL.js → site-extract-repository-XAA2FVDN.js} +3 -3
  28. package/dist/{worker-S2WXELUC.js → worker-QFSOMF2N.js} +2 -2
  29. package/package.json +1 -1
  30. package/dist/chunk-LHH3GX3W.js +0 -7
  31. package/dist/chunk-LHH3GX3W.js.map +0 -1
  32. package/dist/chunk-QSUSTYB3.js.map +0 -1
  33. /package/dist/{chunk-5XYBKE3X.js.map → chunk-KMGRM4FL.js.map} +0 -0
  34. /package/dist/{extract-bundle-H7JEELY7.js.map → extract-bundle-XRRN6NAZ.js.map} +0 -0
  35. /package/dist/{site-extract-repository-CFMSWAVL.js.map → site-extract-repository-XAA2FVDN.js.map} +0 -0
  36. /package/dist/{worker-S2WXELUC.js.map → worker-QFSOMF2N.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@ All notable changes to MCP Scraper are documented here. The format is based on [
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.58.0] - 2026-08-17
8
+
9
+ ### Added
10
+
11
+ - `commons_update_editorial_article` replaces the Markdown of one article in a published edition without resupplying the others. Every edition already stored each article's source; the edit reads them, swaps the named article, re-renders, and publishes the next revision with the rest byte-identical. Guarded by `baseRevision` and `idempotencyKey`.
12
+ - `commons_get_publication` accepts `includeArticles` to return stored article sources and slugs. Owner-only and off by default: reading a publication by name never returns sources, and the payload is large.
13
+
14
+ ### Fixed
15
+
16
+ - Published editions never returned their article sources. `articles_json` was written on every publish and omitted from the edition mapper, so no API response carried it — which made a single-article edit look impossible and forced a full 100-article resubmission to change one paragraph.
17
+
7
18
  ## [0.57.3] - 2026-08-16
8
19
 
9
20
  ### Fixed
package/README.md CHANGED
@@ -90,7 +90,7 @@ Build the branded one-click bundle:
90
90
  npm run build:mcpb
91
91
  ```
92
92
 
93
- 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.57.3`, SHA-256 `b1edddd21790e7e5f24bacad85d992d8e995199c5d7e1d314500ba0abaab117c`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, and API-key configuration field from the bundle manifest.
93
+ 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.58.0`, SHA-256 `9d483b81b2e3c5825c2cee385d7e2d2220b6c56e1ed31b047be6b3dc03216894`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, and API-key configuration field from the bundle manifest.
94
94
 
95
95
  The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
96
96
 
@@ -248,7 +248,7 @@ The `mcp-scraper` server (and the MCPB bundle, which runs it) exposes both secti
248
248
 
249
249
  All MCP tools expose output schemas and return `structuredContent` with the IDs, URLs, CSV paths, transcripts, browser session handles, replay paths, artifacts, recipe fields, or blueprint fields needed by the next step. Browser Agent tools keep a JSON text block for older clients, but structured data is the primary contract. All tools carry MCP annotations; file-writing tools such as replay downloads and annotations state their filesystem side effects.
250
250
 
251
- The canonical tool inventory is generated at `docs/mcp-tool-manifest.generated.json`. The unified server exposes 251 tools: 150 scraper, browser, workflow, billing, and connected-service tools plus 101 durable-memory tools. The scraper-side inventory includes governed Local Sourcebook tools, Transparent Commons entity, linkset, and publication tools, the searchable News Publisher and Editorial Reading Room template workflow, and 24 X-Ray tools for pixel administration, reporting, attribution journeys, campaign links, exports, and scheduled reports. Successful evidence-compiled Local Sourcebook revisions publish automatically to their canonical `localsourcebook.com` category profile and review URLs; administrator controls handle exceptional rejection or unpublishing. Release verification compares the exact local and hosted tool-name sets, not only the count.
251
+ The canonical tool inventory is generated at `docs/mcp-tool-manifest.generated.json`. The unified server exposes 252 tools: 151 scraper, browser, workflow, billing, and connected-service tools plus 101 durable-memory tools. The scraper-side inventory includes governed Local Sourcebook tools, Transparent Commons entity, linkset, and publication tools, the searchable News Publisher and Editorial Reading Room template workflow, and 24 X-Ray tools for pixel administration, reporting, attribution journeys, campaign links, exports, and scheduled reports. Successful evidence-compiled Local Sourcebook revisions publish automatically to their canonical `localsourcebook.com` category profile and review URLs; administrator controls handle exceptional rejection or unpublishing. Release verification compares the exact local and hosted tool-name sets, not only the count.
252
252
 
253
253
  For contract parity, stdio and MCPB memory calls invoke the matching public tool on the hosted MCP Scraper `/mcp` endpoint. The hosted aggregate runtime owns MCP Scraper-specific billing, scheduling, credential, and in-process cutover policy; its internal `/memory/mcp-call` bridge is a fallback to the standalone memory service, not the public stdio execution path. Direct `mcp-memory` OAuth and stdio clients continue to use `memory.mcpscraper.dev` and must be verified as a separate dependent release surface.
254
254
 
@@ -12455,8 +12455,8 @@ var init_product_contract_generated = __esm({
12455
12455
  "freeSignupCredits": 0
12456
12456
  },
12457
12457
  "inventory": {
12458
- "totalTools": 251,
12459
- "scraperTools": 150,
12458
+ "totalTools": 252,
12459
+ "scraperTools": 151,
12460
12460
  "memoryTools": 101
12461
12461
  },
12462
12462
  "concurrencyPack": {
@@ -44650,7 +44650,7 @@ var PACKAGE_VERSION;
44650
44650
  var init_version = __esm({
44651
44651
  "src/version.ts"() {
44652
44652
  "use strict";
44653
- PACKAGE_VERSION = "0.57.3";
44653
+ PACKAGE_VERSION = "0.58.0";
44654
44654
  }
44655
44655
  });
44656
44656
 
@@ -46479,7 +46479,7 @@ var init_contracts = __esm({
46479
46479
  });
46480
46480
 
46481
46481
  // src/mcp/mcp-tool-schemas.ts
46482
- var import_zod43, WEBSITE_URL_OR_DOMAIN_ERROR, WebsiteUrlOrDomainSchema, HarvestPaaInputSchema, ExtractUrlBaseInputSchema, ExtractUrlInputSchema, ExtractUrlLocalInputSchema, DiffPageBaseInputSchema, DiffPageInputSchema, DiffPageLocalInputSchema, MapSiteUrlsInputSchema, MapWaybackSnapshotsInputSchema, ExtractSiteInputSchema, AuditSiteInputSchema, CheckSiteExportInputSchema, ArchiveReadInputSchema, YoutubeHarvestInputSchema, YoutubeTranscribeInputSchema, FacebookPageIntelInputSchema, FacebookAdSearchInputSchema, RedditThreadInputSchema, RedditTrendingInputSchema, VideoFrameAnalysisInputSchema, VideoFrameAnalysisStatusInputSchema, FacebookAdTranscribeInputSchema, FacebookVideoTranscribeInputSchema, GoogleAdsSearchInputSchema, GoogleAdsPageIntelInputSchema, GoogleAdsTranscribeInputSchema, InstagramProfileContentInputSchema, InstagramMediaDownloadInputSchema, MapsPlaceIntelInputSchema, TrustpilotReviewsInputSchema, G2ReviewsInputSchema, ReviewCardSchema, MapsSearchInputSchema, DirectoryWorkflowInputSchema, LocationMarketsInputSchema, CommonsSearchEntitiesInputSchema, CommonsGetEntityInputSchema, CommonsGetEntityLinksetInputSchema, CommonsFeaturedImageInputSchema, CommonsMediaInputSchema, CommonsCitationInputSchema, CommonsSourceInputSchema, CommonsRelatedLinkInputSchema, CommonsClaimInputSchema, CommonsPrepareEntityInputSchema, CommonsSubmitEntityInputSchema, CommonsValidateEntityInputSchema, CommonsGetEntityLedgerInputSchema, CommonsHostImageInputSchema, CommonsGetProposalInputSchema, CommonsSaveFilterInputSchema, CommonsListFiltersInputSchema, CommonsListNeedsLinksInputSchema, CommonsGenericOutputSchema, 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, CommonsGetPublicationInputSchema, RankTrackerModeSchema, RankTrackerBlueprintInputSchema, NullableString, MapsSearchAttemptOutput, MapsSearchOutputSchema, DirectoryMapsBusinessOutput, DirectoryCsvArtifactOutput, DirectoryWorkflowOutputSchema, LocationDatasetProvenanceOutput, LocationMarketsOutputSchema, RankTrackerToolPlanOutput, RankTrackerTableOutput, RankTrackerCronJobOutput, RankTrackerBlueprintOutputSchema, OrganicResultOutput, AiOverviewOutput, EntityIdsOutput, HarvestPaaOutputSchema, SearchSerpOutputSchema, PageMediaAssetOutput, PageMediaArtifactOutput, ExtractUrlOutputSchema, DiffPageOutputSchema, ExtractSiteOutputSchema, AuditSiteOutputSchema, CheckSiteExportOutputSchema, 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;
46482
+ var import_zod43, WEBSITE_URL_OR_DOMAIN_ERROR, WebsiteUrlOrDomainSchema, HarvestPaaInputSchema, ExtractUrlBaseInputSchema, ExtractUrlInputSchema, ExtractUrlLocalInputSchema, DiffPageBaseInputSchema, DiffPageInputSchema, DiffPageLocalInputSchema, MapSiteUrlsInputSchema, MapWaybackSnapshotsInputSchema, ExtractSiteInputSchema, AuditSiteInputSchema, CheckSiteExportInputSchema, ArchiveReadInputSchema, YoutubeHarvestInputSchema, YoutubeTranscribeInputSchema, FacebookPageIntelInputSchema, FacebookAdSearchInputSchema, RedditThreadInputSchema, RedditTrendingInputSchema, VideoFrameAnalysisInputSchema, VideoFrameAnalysisStatusInputSchema, FacebookAdTranscribeInputSchema, FacebookVideoTranscribeInputSchema, GoogleAdsSearchInputSchema, GoogleAdsPageIntelInputSchema, GoogleAdsTranscribeInputSchema, InstagramProfileContentInputSchema, InstagramMediaDownloadInputSchema, MapsPlaceIntelInputSchema, TrustpilotReviewsInputSchema, G2ReviewsInputSchema, ReviewCardSchema, MapsSearchInputSchema, DirectoryWorkflowInputSchema, LocationMarketsInputSchema, CommonsSearchEntitiesInputSchema, CommonsGetEntityInputSchema, CommonsGetEntityLinksetInputSchema, CommonsFeaturedImageInputSchema, CommonsMediaInputSchema, CommonsCitationInputSchema, CommonsSourceInputSchema, CommonsRelatedLinkInputSchema, CommonsClaimInputSchema, CommonsPrepareEntityInputSchema, CommonsSubmitEntityInputSchema, CommonsValidateEntityInputSchema, CommonsGetEntityLedgerInputSchema, CommonsHostImageInputSchema, CommonsGetProposalInputSchema, CommonsSaveFilterInputSchema, CommonsListFiltersInputSchema, CommonsListNeedsLinksInputSchema, CommonsGenericOutputSchema, 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, LocationDatasetProvenanceOutput, LocationMarketsOutputSchema, RankTrackerToolPlanOutput, RankTrackerTableOutput, RankTrackerCronJobOutput, RankTrackerBlueprintOutputSchema, OrganicResultOutput, AiOverviewOutput, EntityIdsOutput, HarvestPaaOutputSchema, SearchSerpOutputSchema, PageMediaAssetOutput, PageMediaArtifactOutput, ExtractUrlOutputSchema, DiffPageOutputSchema, ExtractSiteOutputSchema, AuditSiteOutputSchema, CheckSiteExportOutputSchema, 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;
46483
46483
  var init_mcp_tool_schemas = __esm({
46484
46484
  "src/mcp/mcp-tool-schemas.ts"() {
46485
46485
  "use strict";
@@ -47190,7 +47190,21 @@ var init_mcp_tool_schemas = __esm({
47190
47190
  baseRevision: import_zod43.z.number().int().positive().optional().describe("Required when revising an existing edition; use the current revision from commons_get_publication."),
47191
47191
  ...CreateEditorialReadingRoomInputSchema
47192
47192
  };
47193
+ CommonsUpdateEditorialArticleInputSchema = {
47194
+ publicationSubdomain: CommonsPublicationSubdomainSchema.describe("Publication owned by the authenticated account."),
47195
+ editionSlug: import_zod43.z.string().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(80).optional().describe("Edition holding the article. Defaults to the publication\u2019s latest edition."),
47196
+ articleSlug: import_zod43.z.string().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(80).describe("Slug of the one article to replace, from commons_get_publication with includeArticles."),
47197
+ idempotencyKey: import_zod43.z.string().trim().min(8).max(200).describe("Unique key for this intended edit. Reuse it only when retrying the same edit."),
47198
+ baseRevision: import_zod43.z.number().int().positive().describe("Current edition revision from commons_get_publication. The edit is refused if the edition moved on."),
47199
+ markdown: import_zod43.z.string().trim().min(1).max(4e5).optional().describe("Replacement Markdown body for this article. Omit to change only the metadata fields below."),
47200
+ title: import_zod43.z.string().trim().min(1).max(180).optional().describe("Replacement article title."),
47201
+ summary: import_zod43.z.string().trim().min(1).max(500).optional().describe("Replacement one or two sentence summary."),
47202
+ category: import_zod43.z.string().trim().min(1).max(80).optional().describe("Replacement section label."),
47203
+ kicker: import_zod43.z.string().trim().min(1).max(140).optional().describe("Replacement framing line above the title."),
47204
+ order: import_zod43.z.number().int().min(1).max(1e3).optional().describe("Replacement reading-order position.")
47205
+ };
47193
47206
  CommonsGetPublicationInputSchema = {
47207
+ includeArticles: import_zod43.z.boolean().optional().describe("Return every stored article\u2019s Markdown source alongside each edition. Large payload; request it only when you intend to edit an article. Owner-only: a publication read by name never returns sources."),
47194
47208
  subdomain: CommonsPublicationSubdomainSchema.optional().describe("Public publication name to inspect. Omit to return the publication owned by the authenticated account."),
47195
47209
  includeEditions: import_zod43.z.boolean().default(true).describe("Include the latest revision of every published edition.")
47196
47210
  };
@@ -50590,9 +50604,16 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
50590
50604
  outputSchema: recordOutputSchema("commons_publish_editorial", CommonsGenericOutputSchema),
50591
50605
  annotations: { title: "Publish Transparent Commons Editorial Edition", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true }
50592
50606
  }, async (input) => executor.commonsPublishEditorial(input));
50607
+ server.registerTool("commons_update_editorial_article", {
50608
+ title: "Edit One Transparent Commons Article",
50609
+ description: "Replace the Markdown of a single article in a published edition without resupplying the others. The edition already stores every article\u2019s source, so this reads them, swaps the one you name, re-renders, and publishes the next revision with the rest byte-identical. Use commons_get_publication with includeArticles to read current sources and the revision first; commons_publish_editorial remains the full-replace path for a wholesale rewrite. Requires baseRevision and idempotencyKey.",
50610
+ inputSchema: CommonsUpdateEditorialArticleInputSchema,
50611
+ outputSchema: recordOutputSchema("commons_update_editorial_article", CommonsGenericOutputSchema),
50612
+ annotations: { title: "Edit One Transparent Commons Article", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true }
50613
+ }, async (input) => executor.commonsUpdateEditorialArticle(input));
50593
50614
  server.registerTool("commons_get_publication", {
50594
50615
  title: "Get Transparent Commons Publication",
50595
- description: "Read a Transparent Commons publication and its latest edition revisions. Omit subdomain to inspect the caller-owned publication; pass a name to inspect a public publication. Returns the permanent public and archive URLs needed for sharing or later edits.",
50616
+ description: "Read a Transparent Commons publication and its latest edition revisions. Omit subdomain to inspect the caller-owned publication; pass a name to inspect a public publication. Returns the permanent public and archive URLs needed for sharing or later edits. Set includeArticles to also return every stored article\u2019s Markdown source and slug, which is what commons_update_editorial_article edits \u2014 the payload is large, so request it only when you intend to edit.",
50596
50617
  inputSchema: CommonsGetPublicationInputSchema,
50597
50618
  outputSchema: recordOutputSchema("commons_get_publication", CommonsGenericOutputSchema),
50598
50619
  annotations: { title: "Get Transparent Commons Publication", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }
@@ -51589,6 +51610,12 @@ var init_http_mcp_tool_executor = __esm({
51589
51610
  commonsHostImage(input) {
51590
51611
  return this.call("/commons/images", input);
51591
51612
  }
51613
+ commonsUpdateEditorialArticle(input) {
51614
+ const { idempotencyKey: idempotencyKey3, ...body } = input;
51615
+ return this.call("/commons/publications/articles", { ...body, idempotencyKey: idempotencyKey3 }, this.timeoutMs, "POST", {
51616
+ "Idempotency-Key": `commons-article-${(0, import_node_crypto28.createHash)("sha256").update(idempotencyKey3).digest("hex")}`
51617
+ });
51618
+ }
51592
51619
  commonsSaveFilter(input) {
51593
51620
  return this.call("/commons/filters", input);
51594
51621
  }
@@ -51617,7 +51644,7 @@ var init_http_mcp_tool_executor = __esm({
51617
51644
  });
51618
51645
  }
51619
51646
  commonsGetPublication(input) {
51620
- const query = new URLSearchParams({ includeEditions: String(input.includeEditions ?? true) });
51647
+ const query = new URLSearchParams({ includeEditions: String(input.includeEditions ?? true), includeArticles: String(input.includeArticles ?? false) });
51621
51648
  return this.getJson(input.subdomain ? `/commons/publications/${encodeURIComponent(input.subdomain)}?${query}` : `/commons/publications/me?${query}`);
51622
51649
  }
51623
51650
  async captureSerpSnapshot(input) {
@@ -67241,6 +67268,92 @@ async function publishCommonsEditorial(input, user) {
67241
67268
  if (!edition) throw new CommonsPublicationError("publication_publish_failed", "The published edition was not persisted.");
67242
67269
  return publicationResult({ ...publication, latestEditionId: editionId, updatedAt: now }, edition, false);
67243
67270
  }
67271
+ async function updateCommonsEditorialArticle(input, user) {
67272
+ await ensureCommonsSchema();
67273
+ const subdomain = normalizePublicationSubdomain(input.publicationSubdomain);
67274
+ const publication = await getCommonsPublicationBySubdomain(subdomain);
67275
+ if (!publication) throw new CommonsPublicationError("publication_not_found", "Claim this publication name before editing an edition.", 404);
67276
+ if (publication.ownerUserId !== Number(user.id)) {
67277
+ throw new CommonsPublicationError("publication_not_owned", "Only the account that claimed this publication can edit it.", 404);
67278
+ }
67279
+ const idempotencyKey3 = requiredIdempotencyKey(input.idempotencyKey);
67280
+ const replay = await getEditionByIdempotency(Number(user.id), idempotencyKey3);
67281
+ if (replay) return publicationResult(publication, replay, true);
67282
+ const latestOverall = publication.latestEditionId ? await getPublicationEditionById(publication.latestEditionId) : null;
67283
+ const editionSlug = normalizeEditionSlug(input.editionSlug || latestOverall?.editionSlug || "");
67284
+ if (!editionSlug) throw new CommonsPublicationError("publication_edition_required", "This publication has no edition yet; publish one before editing an article.", 409);
67285
+ const latest = await getLatestEdition(publication.id, editionSlug);
67286
+ if (!latest) throw new CommonsPublicationError("publication_edition_not_found", `Edition ${editionSlug} does not exist.`, 404);
67287
+ if (input.baseRevision !== latest.revision) {
67288
+ throw new CommonsPublicationError("publication_revision_conflict", `Edition ${editionSlug} is revision ${latest.revision}; read it again before editing.`, 409);
67289
+ }
67290
+ const articles = latest.articles;
67291
+ const index = articles.findIndex((article) => article.slug === input.articleSlug);
67292
+ if (index === -1) {
67293
+ throw new CommonsPublicationError("publication_article_not_found", `Edition ${editionSlug} has no article with slug ${input.articleSlug}. Known slugs: ${articles.map((article) => article.slug).join(", ")}.`, 404);
67294
+ }
67295
+ const current = articles[index];
67296
+ const nextArticles = [...articles];
67297
+ nextArticles[index] = {
67298
+ ...current,
67299
+ ...input.markdown === void 0 ? {} : { markdown: input.markdown },
67300
+ ...input.title === void 0 ? {} : { title: input.title },
67301
+ ...input.summary === void 0 ? {} : { summary: input.summary },
67302
+ ...input.category === void 0 ? {} : { category: input.category },
67303
+ ...input.kicker === void 0 ? {} : { kicker: input.kicker },
67304
+ ...input.order === void 0 ? {} : { order: input.order }
67305
+ };
67306
+ const editionInput = { site: latest.site, deck: latest.deck, articles: nextArticles };
67307
+ const canonicalUrl = editionPublicUrl(subdomain, editionSlug);
67308
+ const rendered = renderEditorialReadingRoom(editionInput);
67309
+ const html = addPublicMetadata(rendered.html, canonicalUrl, publication.title);
67310
+ const editionId = `tced_${(0, import_node_crypto40.randomUUID)()}`;
67311
+ const revision = latest.revision + 1;
67312
+ const now = (/* @__PURE__ */ new Date()).toISOString();
67313
+ await getDb().batch([
67314
+ {
67315
+ sql: `
67316
+ INSERT INTO commons_publication_editions (
67317
+ id, publication_id, owner_user_id, edition_slug, revision, title, site_json, deck,
67318
+ articles_json, html, filename, sha256, article_count, word_count, bytes, warnings_json,
67319
+ idempotency_key, created_at, published_at
67320
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
67321
+ `,
67322
+ args: [
67323
+ editionId,
67324
+ publication.id,
67325
+ Number(user.id),
67326
+ editionSlug,
67327
+ revision,
67328
+ latest.site.title,
67329
+ JSON.stringify(latest.site),
67330
+ latest.deck,
67331
+ JSON.stringify(nextArticles),
67332
+ html,
67333
+ rendered.filename,
67334
+ (0, import_node_crypto40.createHash)("sha256").update(html).digest("hex"),
67335
+ rendered.articleCount,
67336
+ rendered.wordCount,
67337
+ Buffer.byteLength(html),
67338
+ JSON.stringify(rendered.warnings),
67339
+ idempotencyKey3,
67340
+ now,
67341
+ now
67342
+ ]
67343
+ },
67344
+ {
67345
+ sql: "UPDATE commons_publications SET latest_edition_id = ?, updated_at = ? WHERE id = ? AND owner_user_id = ?",
67346
+ args: [editionId, now, publication.id, Number(user.id)]
67347
+ }
67348
+ ], "write");
67349
+ const edition = await getPublicationEditionById(editionId);
67350
+ if (!edition) throw new CommonsPublicationError("publication_publish_failed", "The edited edition was not persisted.");
67351
+ return {
67352
+ ...publicationResult({ ...publication, latestEditionId: editionId, updatedAt: now }, edition, false),
67353
+ updatedArticle: { slug: input.articleSlug, previousRevision: latest.revision, revision },
67354
+ unchangedArticles: articles.length - 1
67355
+ };
67356
+ }
67244
67357
  async function getCommonsPublicationBySubdomain(subdomainInput) {
67245
67358
  await ensureCommonsSchema();
67246
67359
  const subdomain = normalizePublicationSubdomain(subdomainInput);
@@ -67338,6 +67451,7 @@ function rowToEdition(row, subdomain) {
67338
67451
  revision: Number(row.revision),
67339
67452
  title: String(row.title),
67340
67453
  site: parseJson4(row.site_json, {}),
67454
+ articles: parseJson4(row.articles_json, []),
67341
67455
  deck: String(row.deck),
67342
67456
  filename: String(row.filename),
67343
67457
  sha256: String(row.sha256),
@@ -67510,10 +67624,17 @@ function publicationError(c, error) {
67510
67624
  }
67511
67625
  throw error;
67512
67626
  }
67627
+ function withArticleSources(editions, include) {
67628
+ if (include) return editions;
67629
+ return editions.map((edition) => {
67630
+ const { articles: _articles, ...rest } = edition;
67631
+ return rest;
67632
+ });
67633
+ }
67513
67634
  function xmlEscape(value) {
67514
67635
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
67515
67636
  }
67516
- var import_hono31, import_zod52, commonsApp, auth2, SearchBodySchema, FeaturedImageSchema, MediaSchema, CitationSchema, RelatedLinkSchema, SubmitEntitySchema, PrepareEntitySchema, ValidateEntitySchema, SaveFilterSchema, NeedsLinkBodySchema, PreparePublicationSchema, ValidatePublicationSchema, ClaimPublicationSchema, PublishEditorialSchema, HostImageSchema;
67637
+ var import_hono31, import_zod52, commonsApp, auth2, SearchBodySchema, FeaturedImageSchema, MediaSchema, CitationSchema, RelatedLinkSchema, SubmitEntitySchema, PrepareEntitySchema, ValidateEntitySchema, SaveFilterSchema, NeedsLinkBodySchema, PreparePublicationSchema, ValidatePublicationSchema, ClaimPublicationSchema, PublishEditorialSchema, UpdateEditorialArticleSchema, HostImageSchema;
67517
67638
  var init_commons_routes = __esm({
67518
67639
  "src/api/commons-routes.ts"() {
67519
67640
  "use strict";
@@ -67691,6 +67812,7 @@ var init_commons_routes = __esm({
67691
67812
  ValidatePublicationSchema = import_zod52.z.object(CommonsValidatePublicationInputSchema).strict();
67692
67813
  ClaimPublicationSchema = import_zod52.z.object(CommonsClaimPublicationInputSchema).strict();
67693
67814
  PublishEditorialSchema = import_zod52.z.object(CommonsPublishEditorialInputSchema).strict();
67815
+ UpdateEditorialArticleSchema = import_zod52.z.object(CommonsUpdateEditorialArticleInputSchema).strict();
67694
67816
  commonsApp.get("/health", async (c) => {
67695
67817
  await ensureCommonsSchema();
67696
67818
  return c.json({ ok: true, data: commonsDatabaseReport() });
@@ -67726,11 +67848,16 @@ var init_commons_routes = __esm({
67726
67848
  if (!parsed.success) return validationError(c, parsed.error);
67727
67849
  return publicationOperation(c, () => publishCommonsEditorial(parsed.data, c.get("user")), 201);
67728
67850
  });
67851
+ commonsApp.post("/publications/articles", auth2, async (c) => {
67852
+ const parsed = UpdateEditorialArticleSchema.safeParse(await c.req.json().catch(() => ({})));
67853
+ if (!parsed.success) return validationError(c, parsed.error);
67854
+ return publicationOperation(c, () => updateCommonsEditorialArticle(parsed.data, c.get("user")), 201);
67855
+ });
67729
67856
  commonsApp.get("/publications/me", auth2, async (c) => {
67730
67857
  const publication = await getCommonsPublicationForOwner(Number(c.get("user").id));
67731
67858
  if (!publication) return c.json({ ok: false, error: "publication_not_found", message: "This account has not claimed a Commons publication yet." }, 404);
67732
67859
  const editions = c.req.query("includeEditions") === "false" ? [] : await listCommonsPublicationEditions(publication.id);
67733
- return c.json({ ok: true, data: { publication, editions } });
67860
+ return c.json({ ok: true, data: { publication, editions: withArticleSources(editions, c.req.query("includeArticles") === "true") } });
67734
67861
  });
67735
67862
  commonsApp.get("/publications/:subdomain/site", async (c) => {
67736
67863
  try {
@@ -67770,7 +67897,7 @@ var init_commons_routes = __esm({
67770
67897
  const publication = await getCommonsPublicationBySubdomain(c.req.param("subdomain"));
67771
67898
  if (!publication) return c.json({ ok: false, error: "publication_not_found", message: "No Commons publication matched that name." }, 404);
67772
67899
  const editions = c.req.query("includeEditions") === "false" ? [] : await listCommonsPublicationEditions(publication.id);
67773
- return c.json({ ok: true, data: { publication, editions } });
67900
+ return c.json({ ok: true, data: { publication, editions: withArticleSources(editions, false) } });
67774
67901
  } catch (error) {
67775
67902
  return publicationError(c, error);
67776
67903
  }