mcp-scraper 0.44.0 → 0.44.2

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/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.44.0`, SHA-256 `83ce32972445fc1b3b308d7e79d6ad7248fb1485d4a13635249b85ea47ac6a61`). 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.44.2`, SHA-256 `6ce5675c82d1fa0b7c645e0337aaac97de7760282067e5744259e8d0a4f03fc2`). 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
 
@@ -24602,6 +24602,7 @@ function ensureLocalSourcebookSchema() {
24602
24602
  metadata_json TEXT NOT NULL DEFAULT '{}',
24603
24603
  created_at TEXT NOT NULL DEFAULT (datetime('now'))
24604
24604
  )`);
24605
+ await publishEligibleEvidenceBackedLocalSourcebookRevisions(db);
24605
24606
  })().catch((error) => {
24606
24607
  schemaPromise3 = null;
24607
24608
  schemaDb3 = null;
@@ -24609,6 +24610,19 @@ function ensureLocalSourcebookSchema() {
24609
24610
  });
24610
24611
  return schemaPromise3;
24611
24612
  }
24613
+ async function publishEligibleEvidenceBackedLocalSourcebookRevisions(db = getDb()) {
24614
+ const result = await db.execute(`UPDATE local_sourcebook_submissions
24615
+ SET status = 'published', published_revision = draft_revision, updated_at = datetime('now')
24616
+ WHERE status = 'needs_review'
24617
+ AND EXISTS (
24618
+ SELECT 1 FROM local_sourcebook_revisions r
24619
+ WHERE r.submission_id = local_sourcebook_submissions.id
24620
+ AND r.revision = local_sourcebook_submissions.draft_revision
24621
+ AND r.actor_kind = 'system'
24622
+ AND r.actor_id = 'local-sourcebook-worker'
24623
+ )`);
24624
+ return Number(result.rowsAffected ?? 0);
24625
+ }
24612
24626
  function rowValue(row, key) {
24613
24627
  return row[key];
24614
24628
  }
@@ -24678,23 +24692,12 @@ async function getLocalSourcebookDraft(id, ownerUserId) {
24678
24692
  const result = await getDb().execute({ sql: `SELECT payload_json FROM local_sourcebook_revisions WHERE submission_id = ? AND revision = ?`, args: [id, submission.draftRevision] });
24679
24693
  return result.rows[0] ? parseJson2(result.rows[0].payload_json) : null;
24680
24694
  }
24681
- async function reviseLocalSourcebookDraft(id, ownerUserId, payload, baseRevision) {
24682
- const submission = await getLocalSourcebookSubmission(id, ownerUserId);
24683
- if (!submission) return null;
24684
- if (baseRevision !== void 0 && baseRevision !== submission.draftRevision) {
24685
- throw new Error(`Draft revision conflict: current revision is ${submission.draftRevision}, but the write targeted ${baseRevision}.`);
24686
- }
24687
- const revision = submission.draftRevision + 1;
24688
- await getDb().batch([
24689
- { sql: `INSERT INTO local_sourcebook_revisions (submission_id, revision, payload_json, actor_kind, actor_id) VALUES (?, ?, ?, 'owner', ?)`, args: [id, revision, JSON.stringify(payload), String(ownerUserId)] },
24690
- { sql: `UPDATE local_sourcebook_submissions SET draft_revision = ?, status = CASE WHEN status = 'published' THEN status ELSE 'needs_review' END, updated_at = datetime('now') WHERE id = ? AND owner_user_id = ?`, args: [revision, id, ownerUserId] }
24691
- ], "write");
24692
- await event(id, "draft.revised", "owner", String(ownerUserId), { revision });
24693
- return getLocalSourcebookSubmission(id, ownerUserId);
24694
- }
24695
24695
  async function queueLocalSourcebookRefresh(id, ownerUserId) {
24696
24696
  const existing = await getLocalSourcebookSubmission(id, ownerUserId);
24697
24697
  if (!existing) return null;
24698
+ if (existing.status === "rejected" || existing.status === "unpublished") {
24699
+ throw new Error(`A ${existing.status} Local Sourcebook listing cannot be refreshed by its owner.`);
24700
+ }
24698
24701
  const coverage = { ...existing.coverage, refreshRequestedAt: (/* @__PURE__ */ new Date()).toISOString() };
24699
24702
  await getDb().execute({ sql: `UPDATE local_sourcebook_submissions SET status = 'queued', coverage_json = ?, acquisition_claimed_at = NULL, acquisition_error = NULL, updated_at = datetime('now') WHERE id = ? AND owner_user_id = ?`, args: [JSON.stringify(coverage), id, ownerUserId] });
24700
24703
  await event(id, "enrichment.queued", "owner", String(ownerUserId));
@@ -24732,12 +24735,13 @@ async function completeLocalSourcebookAcquisition(id, payload, coverage, baseRev
24732
24735
  WHERE EXISTS (SELECT 1 FROM local_sourcebook_submissions WHERE id = ? AND status = 'enriching' AND draft_revision = ?)`,
24733
24736
  args: [id, revision, JSON.stringify(payload), id, expectedRevision]
24734
24737
  },
24735
- { sql: `UPDATE local_sourcebook_submissions SET draft_revision = ?, status = 'needs_review', coverage_json = ?, acquisition_claimed_at = NULL, acquisition_error = NULL, updated_at = datetime('now') WHERE id = ? AND status = 'enriching' AND draft_revision = ?`, args: [revision, JSON.stringify(coverage), id, expectedRevision] }
24738
+ { sql: `UPDATE local_sourcebook_submissions SET draft_revision = ?, published_revision = ?, status = 'published', coverage_json = ?, acquisition_claimed_at = NULL, acquisition_error = NULL, updated_at = datetime('now') WHERE id = ? AND status = 'enriching' AND draft_revision = ?`, args: [revision, revision, JSON.stringify(coverage), id, expectedRevision] }
24736
24739
  ], "write");
24737
24740
  if (Number(results[0]?.rowsAffected ?? 0) !== 1 || Number(results[1]?.rowsAffected ?? 0) !== 1) {
24738
24741
  throw new Error(`Local Sourcebook acquisition revision conflict: revision ${expectedRevision} changed before completion.`);
24739
24742
  }
24740
24743
  await event(id, "enrichment.completed", "system", "local-sourcebook-worker", { revision, coverage });
24744
+ await event(id, "publication.auto_published", "system", "local-sourcebook-worker", { revision });
24741
24745
  return getLocalSourcebookSubmission(id);
24742
24746
  }
24743
24747
  async function failLocalSourcebookAcquisition(id, message) {
@@ -24760,6 +24764,15 @@ async function listQueuedLocalSourcebookSubmissionIds(limit = 25) {
24760
24764
  async function publishLocalSourcebookSubmission(id) {
24761
24765
  const submission = await getLocalSourcebookSubmission(id);
24762
24766
  if (!submission) return null;
24767
+ const revision = await getDb().execute({
24768
+ sql: `SELECT actor_kind, actor_id FROM local_sourcebook_revisions WHERE submission_id = ? AND revision = ? LIMIT 1`,
24769
+ args: [id, submission.draftRevision]
24770
+ });
24771
+ const actorKind = revision.rows[0] ? String(revision.rows[0].actor_kind) : "";
24772
+ const actorId = revision.rows[0] ? String(revision.rows[0].actor_id) : "";
24773
+ if (actorKind !== "system" || actorId !== "local-sourcebook-worker") {
24774
+ throw new Error("Only a system-compiled Local Sourcebook revision can be published.");
24775
+ }
24763
24776
  await getDb().execute({ sql: `UPDATE local_sourcebook_submissions SET status = 'published', published_revision = draft_revision, updated_at = datetime('now') WHERE id = ?`, args: [id] });
24764
24777
  await event(id, "publication.published", "admin", "admin", { revision: submission.draftRevision });
24765
24778
  return getLocalSourcebookSubmission(id);
@@ -26016,11 +26029,12 @@ async function runLocalSourcebookAcquisition(submission, provider = createDefaul
26016
26029
  await logRequestEvent({ userId: submission.ownerUserId, source: "local_sourcebook_maps", status: "done", query: submission.businessName, location: submission.state.toUpperCase(), resultCount: maps.reviews.length, result: { submissionId: submission.id, placeUrl: maps.placeUrl, cid: maps.cidDecimal ?? maps.cid, reviewsStatus: maps.reviewsStatus, reviewsRetained: maps.reviews.length, services: maps.services.length, areasServed: maps.areasServed.length } });
26017
26030
  } catch (error) {
26018
26031
  mapsError = errorMessage2(error);
26032
+ maps = null;
26019
26033
  await creditMcIdempotent(submission.ownerUserId, MC_COSTS.maps_place, LedgerOperation.REFUND, `Local Sourcebook failed exact-place acquisition: ${submission.id}`, `${billingCycle}:maps-failure-refund`);
26020
26034
  mapsRefunded = true;
26021
26035
  await logRequestEvent({ userId: submission.ownerUserId, source: "local_sourcebook_maps", status: "failed", query: submission.businessName, location: submission.state.toUpperCase(), error: mapsError });
26022
26036
  }
26023
- if (!site && !maps) throw new Error(`Website and exact-place acquisition both failed. Website: ${siteError || "not available"}. Maps: ${mapsError || "not available"}.`);
26037
+ if (!maps) throw new Error(`Exact-place acquisition is required before publication. Maps: ${mapsError || "not available"}. Website: ${siteError || (site ? "captured" : "not available")}.`);
26024
26038
  const compiled = compileLocalSourcebookListing({
26025
26039
  submission,
26026
26040
  site,
@@ -36602,18 +36616,18 @@ async function resolveLocalSourcebookTags(candidates) {
36602
36616
  function getLocalSourcebookContract(category) {
36603
36617
  return {
36604
36618
  name: "Local Sourcebook listing",
36605
- version: "local_sourcebook_listing_v1",
36619
+ version: "local_sourcebook_listing_v2",
36606
36620
  purpose: "An owner-scoped, evidence-backed local business record with a separate public profile and complete captured-review archive.",
36607
36621
  categories: LOCAL_SOURCEBOOK_CATEGORIES,
36608
36622
  selectedCategory: category ?? null,
36609
36623
  categoryTag: category ? CATEGORY_TAG[category] : null,
36610
36624
  canonicalRoutes: { profile: "/{state}/{business-slug}/", reviews: "/{state}/{business-slug}/reviews" },
36611
36625
  requiredCreateFields: ["category", "state", "businessName", "websiteUrl", "tags", "idempotencyKey"],
36612
- requiredDraftSections: ["identity", "services/products", "service areas/locations", "genuine media", "reviews and theme counts", "evidence", "answered FAQ", "collection receipts"],
36626
+ systemCompiledSections: ["identity", "services/products", "service areas/locations", "genuine media", "reviews and theme counts", "evidence", "answered FAQ", "collection receipts"],
36613
36627
  workflow: ["list-local-sourcebook-tags", "get-local-sourcebook-contract", "prepare-local-sourcebook-write", "validate-local-sourcebook-write", "local-sourcebook-capture", "local_sourcebook_submission_status"],
36614
- ownership: "Only the MCP Scraper account that captures a listing can read or revise its draft.",
36628
+ ownership: "Only the MCP Scraper account that captures a listing can read it or request a paid evidence refresh.",
36615
36629
  acquisition: { websitePagesMaximum: 100, reviewsMaximum: 500, exactMapsIdentityRequired: true, partialResultsRequireStoppingReasons: true },
36616
- publication: { automatic: false, adminReviewRequired: true, lastPublishedRevisionRemainsPublicDuringRefresh: true },
36630
+ publication: { automatic: true, evidenceCompiledOnly: true, ownerAuthoredClaimsAccepted: false, adminReviewRequired: false, lastPublishedRevisionRemainsPublicDuringRefresh: true },
36617
36631
  tagPolicy: { inspectVocabularyFirst: true, minimum: 1, maximum: 20, newTagsRequire: ["central=true", "reusable=true", "description"], newTagsStartAs: "pending" }
36618
36632
  };
36619
36633
  }
@@ -36636,7 +36650,8 @@ async function prepareLocalSourcebookWrite(input) {
36636
36650
  instructions: [
36637
36651
  "Resolve every review candidate before capture; do not silently create a near-duplicate tag.",
36638
36652
  "Call validate-local-sourcebook-write with the proposed identity, resolved tags, and any required tag decisions.",
36639
- "Call local-sourcebook-capture only after validation returns valid=true. Capture creates a private draft and queues paid acquisition; it does not publish."
36653
+ "Call local-sourcebook-capture only after validation returns valid=true. Capture queues paid acquisition and automatically publishes the resulting system-compiled evidence revision.",
36654
+ "Owners cannot supply public listing claims directly. Request local_sourcebook_refresh when source-backed public facts need to be reacquired."
36640
36655
  ]
36641
36656
  };
36642
36657
  }
@@ -36644,17 +36659,9 @@ async function validateLocalSourcebookWrite(input) {
36644
36659
  const errors = [];
36645
36660
  const warnings = [];
36646
36661
  let normalizedIdentity2;
36647
- let normalizedListing;
36648
- if (input.submissionId) {
36649
- if (!Number.isInteger(input.baseRevision) || Number(input.baseRevision) < 1) errors.push("baseRevision is required for an existing draft edit.");
36650
- const parsedListing = DirectoryListingDraftSchema.safeParse(input.listing);
36651
- if (!parsedListing.success) errors.push(...parsedListing.error.issues.map((issue) => `listing.${issue.path.join(".")}: ${issue.message}`));
36652
- else normalizedListing = parsedListing.data;
36653
- } else {
36654
- const parsedIdentity = DirectoryIdentitySchema.safeParse(input.identity);
36655
- if (!parsedIdentity.success) errors.push(...parsedIdentity.error.issues.map((issue) => `identity.${issue.path.join(".")}: ${issue.message}`));
36656
- else normalizedIdentity2 = parsedIdentity.data;
36657
- }
36662
+ const parsedIdentity = DirectoryIdentitySchema.safeParse(input.identity);
36663
+ if (!parsedIdentity.success) errors.push(...parsedIdentity.error.issues.map((issue) => `identity.${issue.path.join(".")}: ${issue.message}`));
36664
+ else normalizedIdentity2 = parsedIdentity.data;
36658
36665
  const candidates = input.tagCandidates ?? (normalizedIdentity2?.tags.map((tag) => ({ tag })) ?? []);
36659
36666
  const resolutions = await resolveLocalSourcebookTags(candidates);
36660
36667
  const decisions = new Map((input.tagDecisions ?? []).map((decision) => [normalizeTag(decision.tag), decision]));
@@ -36673,12 +36680,12 @@ async function validateLocalSourcebookWrite(input) {
36673
36680
  }
36674
36681
  if (resolution2.action === "omit") warnings.push(`Tag \u201C${resolution2.candidate}\u201D will be omitted: ${resolution2.reason}`);
36675
36682
  }
36676
- if (!input.submissionId && normalizedIdentity2) {
36683
+ if (normalizedIdentity2) {
36677
36684
  const categoryTag = CATEGORY_TAG[normalizedIdentity2.category];
36678
36685
  if (!normalizedTags.includes(categoryTag)) normalizedTags.unshift(categoryTag);
36679
36686
  }
36680
36687
  if (!normalizedTags.length) errors.push("At least one canonical directory tag is required.");
36681
- return { ok: true, valid: errors.length === 0, errors, warnings, normalizedIdentity: normalizedIdentity2, normalizedListing, normalizedTags: [...new Set(normalizedTags)], tagResolutions: resolutions };
36688
+ return { ok: true, valid: errors.length === 0, errors, warnings, normalizedIdentity: normalizedIdentity2, normalizedTags: [...new Set(normalizedTags)], tagResolutions: resolutions };
36682
36689
  }
36683
36690
  async function persistLocalSourcebookTags(submissionId, userId, tags, decisions = []) {
36684
36691
  await ensureLocalSourcebookTags();
@@ -36695,12 +36702,7 @@ async function persistLocalSourcebookTags(submissionId, userId, tags, decisions
36695
36702
  await db.execute({ sql: `INSERT OR IGNORE INTO local_sourcebook_submission_tags (submission_id, tag) VALUES (?, ?)`, args: [submissionId, tag] });
36696
36703
  }
36697
36704
  }
36698
- async function replaceLocalSourcebookTags(submissionId, userId, tags, decisions = []) {
36699
- await ensureLocalSourcebookTags();
36700
- await getDb().execute({ sql: `DELETE FROM local_sourcebook_submission_tags WHERE submission_id = ?`, args: [submissionId] });
36701
- await persistLocalSourcebookTags(submissionId, userId, tags, decisions);
36702
- }
36703
- var import_zod29, DIRECTORY_TAG_SEEDS, CATEGORY_TAG, DirectoryTagCandidateSchema, DirectoryTagDecisionSchema, DirectoryIdentitySchema, DirectoryListingDraftSchema;
36705
+ var import_zod29, DIRECTORY_TAG_SEEDS, CATEGORY_TAG, DirectoryTagCandidateSchema, DirectoryTagDecisionSchema, DirectoryIdentitySchema;
36704
36706
  var init_local_sourcebook_governance = __esm({
36705
36707
  "src/api/local-sourcebook-governance.ts"() {
36706
36708
  "use strict";
@@ -36753,23 +36755,6 @@ var init_local_sourcebook_governance = __esm({
36753
36755
  tags: import_zod29.z.array(import_zod29.z.string().trim().min(1).max(60)).max(20).default([]),
36754
36756
  idempotencyKey: import_zod29.z.string().trim().min(8).max(200)
36755
36757
  });
36756
- DirectoryListingDraftSchema = import_zod29.z.object({
36757
- id: import_zod29.z.string().min(1),
36758
- category: import_zod29.z.enum(LOCAL_SOURCEBOOK_CATEGORIES),
36759
- state: import_zod29.z.string().trim().length(2),
36760
- slug: import_zod29.z.string().trim().min(1),
36761
- name: import_zod29.z.string().trim().min(2),
36762
- summary: import_zod29.z.string().trim().min(20),
36763
- description: import_zod29.z.string().trim().min(20),
36764
- website: import_zod29.z.url(),
36765
- services: import_zod29.z.array(import_zod29.z.string()),
36766
- products: import_zod29.z.array(import_zod29.z.string()),
36767
- serviceAreas: import_zod29.z.array(import_zod29.z.string()),
36768
- media: import_zod29.z.array(import_zod29.z.record(import_zod29.z.string(), import_zod29.z.unknown())),
36769
- reviews: import_zod29.z.array(import_zod29.z.record(import_zod29.z.string(), import_zod29.z.unknown())),
36770
- evidence: import_zod29.z.array(import_zod29.z.record(import_zod29.z.string(), import_zod29.z.unknown())),
36771
- faq: import_zod29.z.array(import_zod29.z.object({ question: import_zod29.z.string().min(3), answer: import_zod29.z.string().min(12), evidenceIds: import_zod29.z.array(import_zod29.z.string()) }))
36772
- }).passthrough();
36773
36758
  }
36774
36759
  });
36775
36760
 
@@ -36779,10 +36764,10 @@ function acquisitionPlan(websiteUrl) {
36779
36764
  website: { startUrl: websiteUrl, mode: "broad_site_crawl", capture: ["homepage", "services", "products", "locations", "service_areas", "about", "team_staff", "contact", "policies"] },
36780
36765
  media: { requirement: "genuine_business_images_only", sources: ["business_website", "business_team_pages", "verified_business_profiles"] },
36781
36766
  reviews: { mode: "exhaust_accessible_continuation", requirement: "retain_each_review_and_source", disclosure: "report captured count, reported available count, and exact stopping reason" },
36782
- publication: { automatic: false, adminReviewRequired: true }
36767
+ publication: { automatic: true, evidenceCompiledOnly: true, adminReviewRequired: false }
36783
36768
  };
36784
36769
  }
36785
- var import_hono17, import_zod30, slug, SubmitSchema, DraftSchema, PrepareWriteSchema, ValidateWriteSchema, CaptureWriteSchema, localSourcebookApp, publicLocalSourcebookApp, adminLocalSourcebookApp;
36770
+ var import_hono17, import_zod30, slug, SubmitSchema, PrepareWriteSchema, ValidateWriteSchema, CaptureWriteSchema, localSourcebookApp, publicLocalSourcebookApp, adminLocalSourcebookApp;
36786
36771
  var init_local_sourcebook_routes = __esm({
36787
36772
  "src/api/local-sourcebook-routes.ts"() {
36788
36773
  "use strict";
@@ -36802,13 +36787,9 @@ var init_local_sourcebook_routes = __esm({
36802
36787
  slug: import_zod30.z.string().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(100).optional(),
36803
36788
  idempotencyKey: import_zod30.z.string().trim().min(8).max(200).optional()
36804
36789
  }).strict();
36805
- DraftSchema = import_zod30.z.object({ payload: import_zod30.z.record(import_zod30.z.string(), import_zod30.z.unknown()) }).strict();
36806
36790
  PrepareWriteSchema = DirectoryIdentitySchema.extend({ tagCandidates: import_zod30.z.array(DirectoryTagCandidateSchema).max(20).optional() });
36807
36791
  ValidateWriteSchema = import_zod30.z.object({
36808
36792
  identity: DirectoryIdentitySchema.optional(),
36809
- listing: import_zod30.z.record(import_zod30.z.string(), import_zod30.z.unknown()).optional(),
36810
- submissionId: import_zod30.z.string().trim().min(1).optional(),
36811
- baseRevision: import_zod30.z.number().int().min(1).optional(),
36812
36793
  tagCandidates: import_zod30.z.array(DirectoryTagCandidateSchema).max(20).optional(),
36813
36794
  tagDecisions: import_zod30.z.array(DirectoryTagDecisionSchema).max(20).optional()
36814
36795
  }).strict();
@@ -36840,13 +36821,6 @@ var init_local_sourcebook_routes = __esm({
36840
36821
  const validation = await validateLocalSourcebookWrite(parsed.data);
36841
36822
  if (!validation.valid) return c.json({ error: "invalid_directory_write", ...validation }, 400);
36842
36823
  try {
36843
- if (parsed.data.submissionId) {
36844
- const submission2 = await getLocalSourcebookSubmission(parsed.data.submissionId, Number(user.id));
36845
- if (!submission2) return c.json({ error: "not_found" }, 404);
36846
- const updated = await reviseLocalSourcebookDraft(submission2.id, Number(user.id), validation.normalizedListing, parsed.data.baseRevision);
36847
- await replaceLocalSourcebookTags(submission2.id, Number(user.id), validation.normalizedTags, parsed.data.tagDecisions);
36848
- return c.json({ ok: true, valid: true, submission: updated, normalizedTags: validation.normalizedTags, captured: "draft_revision", acquisitionQueued: false });
36849
- }
36850
36824
  const identity = validation.normalizedIdentity;
36851
36825
  if (!parsed.data.idempotencyKey && !identity.idempotencyKey) {
36852
36826
  return c.json({ error: "idempotency_key_required", message: "A stable idempotencyKey is required for a new Local Sourcebook capture." }, 400);
@@ -36924,22 +36898,21 @@ var init_local_sourcebook_routes = __esm({
36924
36898
  if (!submission) return c.json({ error: "not_found" }, 404);
36925
36899
  return c.json({ ok: true, submission, draft: await getLocalSourcebookDraft(submission.id, userId) });
36926
36900
  });
36927
- localSourcebookApp.on(["PATCH", "POST"], "/submissions/:id/draft", createApiKeyAuth(), async (c) => {
36928
- const user = c.get("user");
36929
- if (!user.subscription_tier) return c.json({ error: "subscription_required" }, 402);
36930
- const parsed = DraftSchema.safeParse(await c.req.json().catch(() => null));
36931
- if (!parsed.success) return c.json({ error: "invalid_draft", issues: parsed.error.issues }, 400);
36932
- const submission = await reviseLocalSourcebookDraft(c.req.param("id"), Number(user.id), parsed.data.payload);
36933
- if (!submission) return c.json({ error: "not_found" }, 404);
36934
- return c.json({ ok: true, submission });
36935
- });
36901
+ localSourcebookApp.on(["PATCH", "POST"], "/submissions/:id/draft", createApiKeyAuth(), (c) => c.json({
36902
+ error: "evidence_refresh_required",
36903
+ message: "Owner-authored listing payloads are not accepted. Request a refresh so MCP Scraper can reacquire and compile the public evidence."
36904
+ }, 409));
36936
36905
  localSourcebookApp.post("/submissions/:id/refresh", createApiKeyAuth(), async (c) => {
36937
36906
  const user = c.get("user");
36938
36907
  if (!user.subscription_tier) return c.json({ error: "subscription_required" }, 402);
36939
- const submission = await queueLocalSourcebookRefresh(c.req.param("id"), Number(user.id));
36940
- if (!submission) return c.json({ error: "not_found" }, 404);
36941
- const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
36942
- return c.json({ ok: true, submission, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(submission.websiteUrl) }, 202);
36908
+ try {
36909
+ const submission = await queueLocalSourcebookRefresh(c.req.param("id"), Number(user.id));
36910
+ if (!submission) return c.json({ error: "not_found" }, 404);
36911
+ const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
36912
+ return c.json({ ok: true, submission, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(submission.websiteUrl) }, 202);
36913
+ } catch (error) {
36914
+ return c.json({ error: "moderated_listing", message: error instanceof Error ? error.message : String(error) }, 409);
36915
+ }
36943
36916
  });
36944
36917
  publicLocalSourcebookApp = new import_hono17.Hono();
36945
36918
  publicLocalSourcebookApp.get("/:category/:state", async (c) => c.json({ ok: true, listings: await listPublicLocalSourcebook(c.req.param("category"), c.req.param("state").toLowerCase()) }));
@@ -40959,7 +40932,7 @@ var PACKAGE_VERSION;
40959
40932
  var init_version = __esm({
40960
40933
  "src/version.ts"() {
40961
40934
  "use strict";
40962
- PACKAGE_VERSION = "0.44.0";
40935
+ PACKAGE_VERSION = "0.44.2";
40963
40936
  }
40964
40937
  });
40965
40938
 
@@ -41125,13 +41098,13 @@ Multi-step orchestrations \u2014 prefer these over hand-chaining primitives when
41125
41098
  **get-local-sourcebook-contract**, then **prepare-local-sourcebook-write**, inspect every tag resolution,
41126
41099
  and call **validate-local-sourcebook-write**. Call **local-sourcebook-capture** only when validation returns
41127
41100
  \`valid:true\`.
41128
- - A new capture creates an owner-scoped private draft and queues paid broad website, exact Maps place,
41129
- maximum-accessible review, service-area, staff, and genuine-media acquisition. It does not publish.
41130
- - Read progress and the compiled draft with **local_sourcebook_submission_status**. Revise an existing draft
41131
- through **validate-local-sourcebook-write** and **local-sourcebook-capture** with its current \`baseRevision\`.
41132
- Use **local_sourcebook_refresh** only when the owner intentionally wants to pay for a new acquisition pass.
41133
- - The last approved revision remains public during refresh. Only an administrator can publish, reject, or
41134
- unpublish a listing.
41101
+ - A new capture queues paid broad website, exact Maps place, maximum-accessible review, service-area, staff,
41102
+ and genuine-media acquisition. When compilation succeeds, that exact system-authored evidence revision
41103
+ publishes automatically. Never supply owner-authored services, reviews, images, or other public claims.
41104
+ - Read progress and the compiled record with **local_sourcebook_submission_status**. Use
41105
+ **local_sourcebook_refresh** only when the owner intentionally wants to pay for a new acquisition pass.
41106
+ - The last published revision remains public during refresh. Administrators can reject or unpublish an
41107
+ exceptional record, but routine subscriber publication does not require administrator review.
41135
41108
 
41136
41109
  ## Notes
41137
41110
  - For current prices, balances, or limits, call \`credits_info\`. The public machine-readable rate contract is
@@ -41755,7 +41728,7 @@ var init_contracts = __esm({
41755
41728
  });
41756
41729
 
41757
41730
  // src/mcp/mcp-tool-schemas.ts
41758
- var import_zod41, 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, CommonsFeaturedImageInputSchema, CommonsMediaInputSchema, CommonsCitationInputSchema, CommonsSourceInputSchema, CommonsRelatedLinkInputSchema, CommonsPrepareEntityInputSchema, CommonsSubmitEntityInputSchema, CommonsValidateEntityInputSchema, CommonsGetEntityLedgerInputSchema, CommonsSaveFilterInputSchema, CommonsListFiltersInputSchema, CommonsListNeedsLinksInputSchema, CommonsGenericOutputSchema, DirectoryWorkflowStatusInputSchema, LocalSourcebookSubmitInputSchema, LocalSourcebookCategorySchema, LocalSourcebookTagCandidateObjectSchema, LocalSourcebookTagDecisionObjectSchema, LocalSourcebookIdentityObjectSchema, GetLocalSourcebookContractInputSchema, ListLocalSourcebookTagsInputSchema, ResolveLocalSourcebookTagsInputSchema, PrepareLocalSourcebookWriteInputSchema, ValidateLocalSourcebookWriteInputSchema, LocalSourcebookCaptureInputSchema, LocalSourcebookSubmissionStatusInputSchema, LocalSourcebookUpdateDraftInputSchema, LocalSourcebookRefreshInputSchema, LocalSourcebookOutputSchema, ArtifactPointerOutputSchema, EditorialReadingRoomSiteSchema, EditorialReadingRoomArticleSchema, EditorialReadingRoomGuideInputSchema, EditorialReadingRoomGuideOutputSchema, CreateEditorialReadingRoomInputSchema, EditorialReadingRoomArtifactSchema, CreateEditorialReadingRoomOutputSchema, RenewEditorialReadingRoomDownloadInputSchema, RenewEditorialReadingRoomDownloadOutputSchema, RankTrackerModeSchema, RankTrackerBlueprintInputSchema, NullableString, MapsSearchAttemptOutput, MapsSearchOutputSchema, DirectoryMapsBusinessOutput, DirectoryCsvArtifactOutput, DirectoryWorkflowOutputSchema, LocationDatasetProvenanceOutput, LocationMarketsOutputSchema, RankTrackerToolPlanOutput, RankTrackerTableOutput, RankTrackerCronJobOutput, RankTrackerBlueprintOutputSchema, OrganicResultOutput, AiOverviewOutput, EntityIdsOutput, HarvestPaaOutputSchema, SearchSerpOutputSchema, 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;
41731
+ var import_zod41, 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, CommonsFeaturedImageInputSchema, CommonsMediaInputSchema, CommonsCitationInputSchema, CommonsSourceInputSchema, CommonsRelatedLinkInputSchema, CommonsPrepareEntityInputSchema, CommonsSubmitEntityInputSchema, CommonsValidateEntityInputSchema, CommonsGetEntityLedgerInputSchema, CommonsSaveFilterInputSchema, CommonsListFiltersInputSchema, CommonsListNeedsLinksInputSchema, CommonsGenericOutputSchema, DirectoryWorkflowStatusInputSchema, LocalSourcebookSubmitInputSchema, LocalSourcebookCategorySchema, LocalSourcebookTagCandidateObjectSchema, LocalSourcebookTagDecisionObjectSchema, LocalSourcebookIdentityObjectSchema, GetLocalSourcebookContractInputSchema, ListLocalSourcebookTagsInputSchema, ResolveLocalSourcebookTagsInputSchema, PrepareLocalSourcebookWriteInputSchema, ValidateLocalSourcebookWriteInputSchema, LocalSourcebookCaptureInputSchema, LocalSourcebookSubmissionStatusInputSchema, LocalSourcebookRefreshInputSchema, LocalSourcebookOutputSchema, ArtifactPointerOutputSchema, EditorialReadingRoomSiteSchema, EditorialReadingRoomArticleSchema, EditorialReadingRoomGuideInputSchema, EditorialReadingRoomGuideOutputSchema, CreateEditorialReadingRoomInputSchema, EditorialReadingRoomArtifactSchema, CreateEditorialReadingRoomOutputSchema, RenewEditorialReadingRoomDownloadInputSchema, RenewEditorialReadingRoomDownloadOutputSchema, RankTrackerModeSchema, RankTrackerBlueprintInputSchema, NullableString, MapsSearchAttemptOutput, MapsSearchOutputSchema, DirectoryMapsBusinessOutput, DirectoryCsvArtifactOutput, DirectoryWorkflowOutputSchema, LocationDatasetProvenanceOutput, LocationMarketsOutputSchema, RankTrackerToolPlanOutput, RankTrackerTableOutput, RankTrackerCronJobOutput, RankTrackerBlueprintOutputSchema, OrganicResultOutput, AiOverviewOutput, EntityIdsOutput, HarvestPaaOutputSchema, SearchSerpOutputSchema, 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;
41759
41732
  var init_mcp_tool_schemas = __esm({
41760
41733
  "src/mcp/mcp-tool-schemas.ts"() {
41761
41734
  "use strict";
@@ -42276,24 +42249,17 @@ var init_mcp_tool_schemas = __esm({
42276
42249
  tagCandidates: import_zod41.z.array(LocalSourcebookTagCandidateObjectSchema).max(20).optional()
42277
42250
  };
42278
42251
  ValidateLocalSourcebookWriteInputSchema = {
42279
- identity: LocalSourcebookIdentityObjectSchema.optional().describe("New-listing identity returned by prepare-local-sourcebook-write."),
42280
- listing: import_zod41.z.record(import_zod41.z.string(), import_zod41.z.unknown()).optional().describe("Complete replacement listing draft for an existing owner-scoped submission."),
42281
- submissionId: import_zod41.z.string().trim().min(1).optional().describe("Existing owner-scoped submission being revised. Omit for a new capture."),
42282
- baseRevision: import_zod41.z.number().int().min(1).optional().describe("Required current draft revision for an edit, preventing silent overwrites."),
42252
+ identity: LocalSourcebookIdentityObjectSchema.describe("New-listing identity returned by prepare-local-sourcebook-write. Evidence-bearing public fields are compiled by MCP Scraper and cannot be supplied here."),
42283
42253
  tagCandidates: import_zod41.z.array(LocalSourcebookTagCandidateObjectSchema).max(20).optional(),
42284
42254
  tagDecisions: import_zod41.z.array(LocalSourcebookTagDecisionObjectSchema).max(20).optional()
42285
42255
  };
42286
42256
  LocalSourcebookCaptureInputSchema = {
42287
42257
  ...ValidateLocalSourcebookWriteInputSchema,
42288
- idempotencyKey: import_zod41.z.string().trim().min(8).max(200).optional().describe("Stable retry key for a new capture. Required for new listings; omit only when revising an existing submissionId.")
42258
+ idempotencyKey: import_zod41.z.string().trim().min(8).max(200).optional().describe("Stable retry key for a new capture. Required either here or in identity.")
42289
42259
  };
42290
42260
  LocalSourcebookSubmissionStatusInputSchema = {
42291
42261
  submissionId: import_zod41.z.string().trim().min(1).describe("The owner-scoped submission ID returned by local-sourcebook-capture.")
42292
42262
  };
42293
- LocalSourcebookUpdateDraftInputSchema = {
42294
- submissionId: import_zod41.z.string().trim().min(1),
42295
- payload: import_zod41.z.record(import_zod41.z.string(), import_zod41.z.unknown()).describe("Complete replacement draft. The previous revision remains immutable in the audit history.")
42296
- };
42297
42263
  LocalSourcebookRefreshInputSchema = {
42298
42264
  submissionId: import_zod41.z.string().trim().min(1).describe("Owner-scoped listing submission to re-crawl and refresh.")
42299
42265
  };
@@ -45244,14 +45210,14 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
45244
45210
  }, async (input) => executor.prepareLocalSourcebookWrite(input));
45245
45211
  server.registerTool("validate-local-sourcebook-write", {
45246
45212
  title: "Validate Local Sourcebook Write",
45247
- description: "Validate a proposed new listing or complete owner draft revision without writing it. Checks identity or listing completeness, canonical tags, tag decisions, and baseRevision requirements. Capture only when valid is true.",
45213
+ description: "Validate a proposed new listing identity without writing it. Checks business identity, canonical tags, and explicit tag decisions. Public facts are compiled from MCP Scraper evidence rather than accepted from the owner. Capture only when valid is true.",
45248
45214
  inputSchema: ValidateLocalSourcebookWriteInputSchema,
45249
45215
  outputSchema: recordOutputSchema("validate-local-sourcebook-write", LocalSourcebookOutputSchema),
45250
45216
  annotations: localPlanningToolAnnotations("Validate Local Sourcebook Write")
45251
45217
  }, async (input) => executor.validateLocalSourcebookWrite(input));
45252
45218
  server.registerTool("local-sourcebook-capture", {
45253
45219
  title: "Capture Governed Local Sourcebook Listing",
45254
- description: "Strict owner-scoped write path after list, contract, prepare, and validate. A new capture registers canonical tags and queues paid website, exact-place, review, service-area, staff, and genuine-media acquisition. An edit requires the current baseRevision. Capture never publishes; admin review remains required.",
45220
+ description: "Strict owner-scoped write path after list, contract, prepare, and validate. Capture registers canonical tags and queues paid website, exact-place, review, service-area, staff, and genuine-media acquisition. A successful system-compiled evidence revision publishes automatically; owner-authored public claims are not accepted.",
45255
45221
  inputSchema: LocalSourcebookCaptureInputSchema,
45256
45222
  outputSchema: recordOutputSchema("local-sourcebook-capture", LocalSourcebookOutputSchema),
45257
45223
  annotations: liveWebToolAnnotations("Capture Governed Local Sourcebook Listing")
@@ -45265,7 +45231,7 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
45265
45231
  }, async (input) => executor.localSourcebookSubmissionStatus(input));
45266
45232
  server.registerTool("local_sourcebook_refresh", {
45267
45233
  title: "Refresh a Local Sourcebook Listing",
45268
- description: "Queue a new broad crawl and review/media acquisition pass for a listing owned by the authenticated MCP Scraper account.",
45234
+ description: "Queue a new broad crawl and review/media acquisition pass for a listing owned by the authenticated MCP Scraper account. The last published revision remains public until the refreshed evidence revision completes and auto-publishes.",
45269
45235
  inputSchema: LocalSourcebookRefreshInputSchema,
45270
45236
  outputSchema: recordOutputSchema("local_sourcebook_refresh", LocalSourcebookOutputSchema),
45271
45237
  annotations: liveWebToolAnnotations("Refresh a Local Sourcebook Listing")
@@ -45891,9 +45857,6 @@ var init_http_mcp_tool_executor = __esm({
45891
45857
  localSourcebookSubmissionStatus(input) {
45892
45858
  return this.getJson(`/local-sourcebook/submissions/${encodeURIComponent(input.submissionId)}`);
45893
45859
  }
45894
- localSourcebookUpdateDraft(input) {
45895
- return this.call(`/local-sourcebook/submissions/${encodeURIComponent(input.submissionId)}/draft`, { payload: input.payload });
45896
- }
45897
45860
  localSourcebookRefresh(input) {
45898
45861
  return this.call(`/local-sourcebook/submissions/${encodeURIComponent(input.submissionId)}/refresh`, {});
45899
45862
  }