mcp-scraper 0.44.2 → 0.44.4
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 +2 -2
- package/dist/bin/api-server.cjs +103 -14
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +1 -1
- package/dist/bin/mcp-scraper-cli.cjs +1 -1
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-install.cjs +1 -1
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +1 -1
- package/dist/bin/mcp-stdio-server.cjs +6 -4
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/chunk-HFCIHZHA.js +7 -0
- package/dist/chunk-HFCIHZHA.js.map +1 -0
- package/dist/{chunk-M27QGXUM.js → chunk-ZVOVPXDL.js} +7 -5
- package/dist/chunk-ZVOVPXDL.js.map +1 -0
- package/dist/{server-RTQUTQZE.js → server-W4JLSNKW.js} +93 -13
- package/dist/server-W4JLSNKW.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-M27QGXUM.js.map +0 -1
- package/dist/chunk-OEW4VBS2.js +0 -7
- package/dist/chunk-OEW4VBS2.js.map +0 -1
- package/dist/server-RTQUTQZE.js.map +0 -1
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.
|
|
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.4`, SHA-256 `707dbcce1bafc04fc49f3a12cfc4ab43710e686e2f31102767ed120a3e8ff474`). 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
|
|
|
@@ -233,7 +233,7 @@ The `mcp-scraper` server (and the MCPB bundle, which runs it) exposes both secti
|
|
|
233
233
|
|
|
234
234
|
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.
|
|
235
235
|
|
|
236
|
-
The canonical tool inventory is generated at `docs/mcp-tool-manifest.generated.json`. The unified server exposes 215 tools: 114 scraper, browser, workflow, billing, and connected-service tools plus 101 durable-memory tools. The scraper inventory includes governed Local Sourcebook tools that follow a Memory-style contract/tag/prepare/validate/capture sequence before paid acquisition, plus Transparent Commons tools for public entity search, planning, validation, governed contribution, ledgers, needs-link discovery, and saved filters. Local Sourcebook
|
|
236
|
+
The canonical tool inventory is generated at `docs/mcp-tool-manifest.generated.json`. The unified server exposes 215 tools: 114 scraper, browser, workflow, billing, and connected-service tools plus 101 durable-memory tools. The scraper inventory includes governed Local Sourcebook tools that follow a Memory-style contract/tag/prepare/validate/capture sequence before paid acquisition, plus Transparent Commons tools for public entity search, planning, validation, governed contribution, ledgers, needs-link discovery, and saved filters. 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.
|
|
237
237
|
|
|
238
238
|
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.
|
|
239
239
|
|
package/dist/bin/api-server.cjs
CHANGED
|
@@ -24789,6 +24789,14 @@ async function listPublicLocalSourcebook(category, state) {
|
|
|
24789
24789
|
const result = await getDb().execute({ sql: `SELECT r.payload_json FROM local_sourcebook_submissions s JOIN local_sourcebook_revisions r ON r.submission_id = s.id AND r.revision = s.published_revision WHERE s.category = ? AND s.state = ? AND s.published_revision IS NOT NULL AND s.status NOT IN ('unpublished', 'rejected') ORDER BY s.business_name`, args: [category, state] });
|
|
24790
24790
|
return result.rows.map((row) => parseJson2(row.payload_json));
|
|
24791
24791
|
}
|
|
24792
|
+
async function listAllPublicLocalSourcebook(category) {
|
|
24793
|
+
await ensureLocalSourcebookSchema();
|
|
24794
|
+
const result = category ? await getDb().execute({
|
|
24795
|
+
sql: `SELECT r.payload_json FROM local_sourcebook_submissions s JOIN local_sourcebook_revisions r ON r.submission_id = s.id AND r.revision = s.published_revision WHERE s.category = ? AND s.published_revision IS NOT NULL AND s.status NOT IN ('unpublished', 'rejected') ORDER BY s.state, s.business_name`,
|
|
24796
|
+
args: [category]
|
|
24797
|
+
}) : await getDb().execute(`SELECT r.payload_json FROM local_sourcebook_submissions s JOIN local_sourcebook_revisions r ON r.submission_id = s.id AND r.revision = s.published_revision WHERE s.published_revision IS NOT NULL AND s.status NOT IN ('unpublished', 'rejected') ORDER BY s.category, s.state, s.business_name`);
|
|
24798
|
+
return result.rows.map((row) => parseJson2(row.payload_json));
|
|
24799
|
+
}
|
|
24792
24800
|
async function getPublicLocalSourcebook(category, state, slug2) {
|
|
24793
24801
|
await ensureLocalSourcebookSchema();
|
|
24794
24802
|
const result = await getDb().execute({ sql: `SELECT r.payload_json FROM local_sourcebook_submissions s JOIN local_sourcebook_revisions r ON r.submission_id = s.id AND r.revision = s.published_revision WHERE s.category = ? AND s.state = ? AND s.slug = ? AND s.published_revision IS NOT NULL AND s.status NOT IN ('unpublished', 'rejected') LIMIT 1`, args: [category, state, slug2] });
|
|
@@ -25444,6 +25452,50 @@ var init_MapsExtractor = __esm({
|
|
|
25444
25452
|
}
|
|
25445
25453
|
});
|
|
25446
25454
|
|
|
25455
|
+
// src/api/local-sourcebook-public-urls.ts
|
|
25456
|
+
function rootDomain() {
|
|
25457
|
+
const configured = process.env.LOCAL_SOURCEBOOK_PUBLIC_ROOT_DOMAIN?.trim() || DEFAULT_ROOT_DOMAIN;
|
|
25458
|
+
return configured.replace(/^https?:\/\//i, "").replace(/^www\./i, "").replace(/\/.*$/, "").replace(/\.+$/, "").toLowerCase();
|
|
25459
|
+
}
|
|
25460
|
+
function localSourcebookPublicUrls(category, state, slug2) {
|
|
25461
|
+
const categoryUrl = `https://${CATEGORY_PUBLIC_SLUGS[category]}.${rootDomain()}`;
|
|
25462
|
+
const statePath = `/${state.toLowerCase()}`;
|
|
25463
|
+
const profilePath = `${statePath}/${slug2}/`;
|
|
25464
|
+
const reviewsPath = `${statePath}/${slug2}/reviews`;
|
|
25465
|
+
return {
|
|
25466
|
+
categoryUrl,
|
|
25467
|
+
nationwideDirectoryUrl: `${categoryUrl}/directory`,
|
|
25468
|
+
stateUrl: `${categoryUrl}${statePath}`,
|
|
25469
|
+
profileUrl: `${categoryUrl}${profilePath}`,
|
|
25470
|
+
reviewsUrl: `${categoryUrl}${reviewsPath}`,
|
|
25471
|
+
profilePath,
|
|
25472
|
+
reviewsPath
|
|
25473
|
+
};
|
|
25474
|
+
}
|
|
25475
|
+
function localSourcebookPublicationLinks(submission) {
|
|
25476
|
+
return {
|
|
25477
|
+
...localSourcebookPublicUrls(submission.category, submission.state, submission.slug),
|
|
25478
|
+
publicationStatus: submission.status,
|
|
25479
|
+
isLive: submission.status === "published" && submission.publishedRevision !== null
|
|
25480
|
+
};
|
|
25481
|
+
}
|
|
25482
|
+
var DEFAULT_ROOT_DOMAIN, CATEGORY_PUBLIC_SLUGS;
|
|
25483
|
+
var init_local_sourcebook_public_urls = __esm({
|
|
25484
|
+
"src/api/local-sourcebook-public-urls.ts"() {
|
|
25485
|
+
"use strict";
|
|
25486
|
+
DEFAULT_ROOT_DOMAIN = "localsourcebook.com";
|
|
25487
|
+
CATEGORY_PUBLIC_SLUGS = {
|
|
25488
|
+
home: "home-services",
|
|
25489
|
+
professional: "professional",
|
|
25490
|
+
restaurants: "restaurants",
|
|
25491
|
+
financial: "financial",
|
|
25492
|
+
realestate: "realestate",
|
|
25493
|
+
auto: "auto",
|
|
25494
|
+
wellness: "wellness"
|
|
25495
|
+
};
|
|
25496
|
+
}
|
|
25497
|
+
});
|
|
25498
|
+
|
|
25447
25499
|
// src/api/local-sourcebook-compiler.ts
|
|
25448
25500
|
function digest(value) {
|
|
25449
25501
|
return (0, import_node_crypto13.createHash)("sha256").update(value).digest("hex").slice(0, 20);
|
|
@@ -25719,6 +25771,7 @@ function compileLocalSourcebookListing(input) {
|
|
|
25719
25771
|
evidenceIds: mapsEvidenceId ? [mapsEvidenceId] : []
|
|
25720
25772
|
}
|
|
25721
25773
|
];
|
|
25774
|
+
const publicUrls = localSourcebookPublicUrls(input.submission.category, input.submission.state, input.submission.slug);
|
|
25722
25775
|
const listing = {
|
|
25723
25776
|
id: input.submission.id,
|
|
25724
25777
|
publicationRevision: input.submission.draftRevision + 1,
|
|
@@ -25727,6 +25780,14 @@ function compileLocalSourcebookListing(input) {
|
|
|
25727
25780
|
state: input.submission.state.toLowerCase(),
|
|
25728
25781
|
stateName: STATE_NAMES[input.submission.state.toUpperCase()] ?? input.submission.state.toUpperCase(),
|
|
25729
25782
|
slug: input.submission.slug,
|
|
25783
|
+
canonicalPaths: {
|
|
25784
|
+
profile: publicUrls.profilePath,
|
|
25785
|
+
reviews: publicUrls.reviewsPath
|
|
25786
|
+
},
|
|
25787
|
+
canonicalUrls: {
|
|
25788
|
+
profile: publicUrls.profileUrl,
|
|
25789
|
+
reviews: publicUrls.reviewsUrl
|
|
25790
|
+
},
|
|
25730
25791
|
name: maps?.name || input.submission.businessName,
|
|
25731
25792
|
summary,
|
|
25732
25793
|
description,
|
|
@@ -25790,6 +25851,7 @@ var init_local_sourcebook_compiler = __esm({
|
|
|
25790
25851
|
"src/api/local-sourcebook-compiler.ts"() {
|
|
25791
25852
|
"use strict";
|
|
25792
25853
|
import_node_crypto13 = require("crypto");
|
|
25854
|
+
init_local_sourcebook_public_urls();
|
|
25793
25855
|
CATEGORY_LABELS = {
|
|
25794
25856
|
home: "Home & property services",
|
|
25795
25857
|
professional: "Professional services",
|
|
@@ -36621,7 +36683,11 @@ function getLocalSourcebookContract(category) {
|
|
|
36621
36683
|
categories: LOCAL_SOURCEBOOK_CATEGORIES,
|
|
36622
36684
|
selectedCategory: category ?? null,
|
|
36623
36685
|
categoryTag: category ? CATEGORY_TAG[category] : null,
|
|
36624
|
-
canonicalRoutes: {
|
|
36686
|
+
canonicalRoutes: {
|
|
36687
|
+
nationwideDirectory: "https://{category}.localsourcebook.com/directory",
|
|
36688
|
+
profile: "https://{category}.localsourcebook.com/{state}/{business-slug}/",
|
|
36689
|
+
reviews: "https://{category}.localsourcebook.com/{state}/{business-slug}/reviews"
|
|
36690
|
+
},
|
|
36625
36691
|
requiredCreateFields: ["category", "state", "businessName", "websiteUrl", "tags", "idempotencyKey"],
|
|
36626
36692
|
systemCompiledSections: ["identity", "services/products", "service areas/locations", "genuine media", "reviews and theme counts", "evidence", "answered FAQ", "collection receipts"],
|
|
36627
36693
|
workflow: ["list-local-sourcebook-tags", "get-local-sourcebook-contract", "prepare-local-sourcebook-write", "validate-local-sourcebook-write", "local-sourcebook-capture", "local_sourcebook_submission_status"],
|
|
@@ -36641,9 +36707,10 @@ async function prepareLocalSourcebookWrite(input) {
|
|
|
36641
36707
|
...parsed.tags.filter((tag) => tag !== categoryTag).map((tag) => ({ tag }))
|
|
36642
36708
|
];
|
|
36643
36709
|
const tagResolutions = await resolveLocalSourcebookTags(candidates);
|
|
36710
|
+
const publicUrls = localSourcebookPublicUrls(parsed.category, parsed.state, slug2);
|
|
36644
36711
|
return {
|
|
36645
36712
|
ok: true,
|
|
36646
|
-
route: { category: parsed.category, state: parsed.state, slug: slug2,
|
|
36713
|
+
route: { category: parsed.category, state: parsed.state, slug: slug2, ...publicUrls },
|
|
36647
36714
|
proposedWrite: { ...parsed, slug: slug2, tags: tagResolutions.filter((item) => item.action === "reuse").map((item) => item.tag) },
|
|
36648
36715
|
contract: getLocalSourcebookContract(parsed.category),
|
|
36649
36716
|
tagResolutions,
|
|
@@ -36709,6 +36776,7 @@ var init_local_sourcebook_governance = __esm({
|
|
|
36709
36776
|
import_zod29 = require("zod");
|
|
36710
36777
|
init_db();
|
|
36711
36778
|
init_local_sourcebook_repository();
|
|
36779
|
+
init_local_sourcebook_public_urls();
|
|
36712
36780
|
DIRECTORY_TAG_SEEDS = [
|
|
36713
36781
|
{ tag: "home-services", description: "Businesses that maintain, repair, improve, or protect homes and property.", aliases: ["home service", "home and property services"] },
|
|
36714
36782
|
{ tag: "professional-services", description: "Local professional and business service providers.", aliases: ["professional service"] },
|
|
@@ -36759,6 +36827,18 @@ var init_local_sourcebook_governance = __esm({
|
|
|
36759
36827
|
});
|
|
36760
36828
|
|
|
36761
36829
|
// src/api/local-sourcebook-routes.ts
|
|
36830
|
+
function withCanonicalLocalSourcebookUrls(listing) {
|
|
36831
|
+
const category = import_zod30.z.enum(LOCAL_SOURCEBOOK_CATEGORIES).safeParse(listing.category);
|
|
36832
|
+
const state = typeof listing.state === "string" ? listing.state : "";
|
|
36833
|
+
const listingSlug = typeof listing.slug === "string" ? listing.slug : "";
|
|
36834
|
+
if (!category.success || !state || !listingSlug) return listing;
|
|
36835
|
+
const publicUrls = localSourcebookPublicUrls(category.data, state, listingSlug);
|
|
36836
|
+
return {
|
|
36837
|
+
...listing,
|
|
36838
|
+
canonicalPaths: { profile: publicUrls.profilePath, reviews: publicUrls.reviewsPath },
|
|
36839
|
+
canonicalUrls: { profile: publicUrls.profileUrl, reviews: publicUrls.reviewsUrl }
|
|
36840
|
+
};
|
|
36841
|
+
}
|
|
36762
36842
|
function acquisitionPlan(websiteUrl) {
|
|
36763
36843
|
return {
|
|
36764
36844
|
website: { startUrl: websiteUrl, mode: "broad_site_crawl", capture: ["homepage", "services", "products", "locations", "service_areas", "about", "team_staff", "contact", "policies"] },
|
|
@@ -36778,6 +36858,7 @@ var init_local_sourcebook_routes = __esm({
|
|
|
36778
36858
|
init_local_sourcebook_dispatch();
|
|
36779
36859
|
init_local_sourcebook_governance();
|
|
36780
36860
|
init_local_sourcebook_repository();
|
|
36861
|
+
init_local_sourcebook_public_urls();
|
|
36781
36862
|
slug = (value) => value.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 100);
|
|
36782
36863
|
SubmitSchema = import_zod30.z.object({
|
|
36783
36864
|
category: import_zod30.z.enum(LOCAL_SOURCEBOOK_CATEGORIES),
|
|
@@ -36826,6 +36907,7 @@ var init_local_sourcebook_routes = __esm({
|
|
|
36826
36907
|
return c.json({ error: "idempotency_key_required", message: "A stable idempotencyKey is required for a new Local Sourcebook capture." }, 400);
|
|
36827
36908
|
}
|
|
36828
36909
|
const listingSlug = identity.slug ?? slug(identity.businessName);
|
|
36910
|
+
const publicUrls = localSourcebookPublicUrls(identity.category, identity.state, listingSlug);
|
|
36829
36911
|
const submission = await createLocalSourcebookSubmission({
|
|
36830
36912
|
ownerUserId: Number(user.id),
|
|
36831
36913
|
category: identity.category,
|
|
@@ -36842,7 +36924,8 @@ var init_local_sourcebook_routes = __esm({
|
|
|
36842
36924
|
name: identity.businessName,
|
|
36843
36925
|
websiteUrl: identity.websiteUrl,
|
|
36844
36926
|
tags: validation.normalizedTags,
|
|
36845
|
-
canonicalPaths: { profile:
|
|
36927
|
+
canonicalPaths: { profile: publicUrls.profilePath, reviews: publicUrls.reviewsPath },
|
|
36928
|
+
canonicalUrls: { profile: publicUrls.profileUrl, reviews: publicUrls.reviewsUrl },
|
|
36846
36929
|
verificationState: "submitted",
|
|
36847
36930
|
acquisitionPlan: acquisitionPlan(identity.websiteUrl),
|
|
36848
36931
|
evidence: [],
|
|
@@ -36852,7 +36935,7 @@ var init_local_sourcebook_routes = __esm({
|
|
|
36852
36935
|
});
|
|
36853
36936
|
await persistLocalSourcebookTags(submission.id, Number(user.id), validation.normalizedTags, parsed.data.tagDecisions);
|
|
36854
36937
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
36855
|
-
return c.json({ ok: true, valid: true, submission, normalizedTags: validation.normalizedTags, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(identity.websiteUrl) }, 202);
|
|
36938
|
+
return c.json({ ok: true, valid: true, submission, publicUrls: localSourcebookPublicationLinks(submission), normalizedTags: validation.normalizedTags, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(identity.websiteUrl) }, 202);
|
|
36856
36939
|
} catch (error) {
|
|
36857
36940
|
const message = error instanceof Error ? error.message : String(error);
|
|
36858
36941
|
const conflict = message.includes("revision conflict") ? "revision_conflict" : message.includes("idempotency key conflicts") ? "idempotency_conflict" : null;
|
|
@@ -36866,6 +36949,7 @@ var init_local_sourcebook_routes = __esm({
|
|
|
36866
36949
|
if (!parsed.success) return c.json({ error: "invalid_submission", issues: parsed.error.issues }, 400);
|
|
36867
36950
|
const input = parsed.data;
|
|
36868
36951
|
const listingSlug = input.slug ?? slug(input.businessName);
|
|
36952
|
+
const publicUrls = localSourcebookPublicUrls(input.category, input.state, listingSlug);
|
|
36869
36953
|
try {
|
|
36870
36954
|
const submission = await createLocalSourcebookSubmission({
|
|
36871
36955
|
ownerUserId: Number(user.id),
|
|
@@ -36878,7 +36962,8 @@ var init_local_sourcebook_routes = __esm({
|
|
|
36878
36962
|
slug: listingSlug,
|
|
36879
36963
|
name: input.businessName,
|
|
36880
36964
|
websiteUrl: input.websiteUrl,
|
|
36881
|
-
canonicalPaths: { profile:
|
|
36965
|
+
canonicalPaths: { profile: publicUrls.profilePath, reviews: publicUrls.reviewsPath },
|
|
36966
|
+
canonicalUrls: { profile: publicUrls.profileUrl, reviews: publicUrls.reviewsUrl },
|
|
36882
36967
|
verificationState: "submitted",
|
|
36883
36968
|
acquisitionPlan: acquisitionPlan(input.websiteUrl),
|
|
36884
36969
|
evidence: [],
|
|
@@ -36887,7 +36972,7 @@ var init_local_sourcebook_routes = __esm({
|
|
|
36887
36972
|
}
|
|
36888
36973
|
});
|
|
36889
36974
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
36890
|
-
return c.json({ ok: true, submission, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(input.websiteUrl) }, 202);
|
|
36975
|
+
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(input.websiteUrl) }, 202);
|
|
36891
36976
|
} catch (error) {
|
|
36892
36977
|
return c.json({ error: "submission_conflict", message: error instanceof Error ? error.message : String(error) }, 409);
|
|
36893
36978
|
}
|
|
@@ -36896,7 +36981,7 @@ var init_local_sourcebook_routes = __esm({
|
|
|
36896
36981
|
const userId = Number(c.get("user").id);
|
|
36897
36982
|
const submission = await getLocalSourcebookSubmission(c.req.param("id"), userId);
|
|
36898
36983
|
if (!submission) return c.json({ error: "not_found" }, 404);
|
|
36899
|
-
return c.json({ ok: true, submission, draft: await getLocalSourcebookDraft(submission.id, userId) });
|
|
36984
|
+
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), draft: await getLocalSourcebookDraft(submission.id, userId) });
|
|
36900
36985
|
});
|
|
36901
36986
|
localSourcebookApp.on(["PATCH", "POST"], "/submissions/:id/draft", createApiKeyAuth(), (c) => c.json({
|
|
36902
36987
|
error: "evidence_refresh_required",
|
|
@@ -36909,16 +36994,18 @@ var init_local_sourcebook_routes = __esm({
|
|
|
36909
36994
|
const submission = await queueLocalSourcebookRefresh(c.req.param("id"), Number(user.id));
|
|
36910
36995
|
if (!submission) return c.json({ error: "not_found" }, 404);
|
|
36911
36996
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
36912
|
-
return c.json({ ok: true, submission, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(submission.websiteUrl) }, 202);
|
|
36997
|
+
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(submission.websiteUrl) }, 202);
|
|
36913
36998
|
} catch (error) {
|
|
36914
36999
|
return c.json({ error: "moderated_listing", message: error instanceof Error ? error.message : String(error) }, 409);
|
|
36915
37000
|
}
|
|
36916
37001
|
});
|
|
36917
37002
|
publicLocalSourcebookApp = new import_hono17.Hono();
|
|
36918
|
-
publicLocalSourcebookApp.get("
|
|
37003
|
+
publicLocalSourcebookApp.get("/", async (c) => c.json({ ok: true, listings: (await listAllPublicLocalSourcebook()).map(withCanonicalLocalSourcebookUrls) }));
|
|
37004
|
+
publicLocalSourcebookApp.get("/:category", async (c) => c.json({ ok: true, listings: (await listAllPublicLocalSourcebook(c.req.param("category"))).map(withCanonicalLocalSourcebookUrls) }));
|
|
37005
|
+
publicLocalSourcebookApp.get("/:category/:state", async (c) => c.json({ ok: true, listings: (await listPublicLocalSourcebook(c.req.param("category"), c.req.param("state").toLowerCase())).map(withCanonicalLocalSourcebookUrls) }));
|
|
36919
37006
|
publicLocalSourcebookApp.get("/:category/:state/:slug", async (c) => {
|
|
36920
37007
|
const listing = await getPublicLocalSourcebook(c.req.param("category"), c.req.param("state").toLowerCase(), c.req.param("slug"));
|
|
36921
|
-
return listing ? c.json({ ok: true, listing }) : c.json({ error: "not_found" }, 404);
|
|
37008
|
+
return listing ? c.json({ ok: true, listing: withCanonicalLocalSourcebookUrls(listing) }) : c.json({ error: "not_found" }, 404);
|
|
36922
37009
|
});
|
|
36923
37010
|
adminLocalSourcebookApp = new import_hono17.Hono();
|
|
36924
37011
|
adminLocalSourcebookApp.use("*", adminAuth);
|
|
@@ -40932,7 +41019,7 @@ var PACKAGE_VERSION;
|
|
|
40932
41019
|
var init_version = __esm({
|
|
40933
41020
|
"src/version.ts"() {
|
|
40934
41021
|
"use strict";
|
|
40935
|
-
PACKAGE_VERSION = "0.44.
|
|
41022
|
+
PACKAGE_VERSION = "0.44.4";
|
|
40936
41023
|
}
|
|
40937
41024
|
});
|
|
40938
41025
|
|
|
@@ -41103,6 +41190,8 @@ Multi-step orchestrations \u2014 prefer these over hand-chaining primitives when
|
|
|
41103
41190
|
publishes automatically. Never supply owner-authored services, reviews, images, or other public claims.
|
|
41104
41191
|
- Read progress and the compiled record with **local_sourcebook_submission_status**. Use
|
|
41105
41192
|
**local_sourcebook_refresh** only when the owner intentionally wants to pay for a new acquisition pass.
|
|
41193
|
+
- Capture and status responses return \`publicUrls.profileUrl\` and \`publicUrls.reviewsUrl\`. Always give those
|
|
41194
|
+
exact links to the user; do not report a listing as live without including its clickable profile URL.
|
|
41106
41195
|
- The last published revision remains public during refresh. Administrators can reject or unpublish an
|
|
41107
41196
|
exceptional record, but routine subscriber publication does not require administrator review.
|
|
41108
41197
|
|
|
@@ -45182,7 +45271,7 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
|
|
|
45182
45271
|
}, async (input) => formatDirectoryWorkflow(await executor.directoryWorkflowStatus(input), input, ctx));
|
|
45183
45272
|
server.registerTool("get-local-sourcebook-contract", {
|
|
45184
45273
|
title: "Get Local Sourcebook Contract",
|
|
45185
|
-
description: "Read the governed listing purpose, supported categories,
|
|
45274
|
+
description: "Read the governed listing purpose, supported categories, exact LocalSourcebook.com profile/review URLs, nationwide directory URL, required sections, acquisition limits, tag policy, ownership boundary, and automatic evidence-publication rule. Call this before composing a listing when its required shape is uncertain.",
|
|
45186
45275
|
inputSchema: GetLocalSourcebookContractInputSchema,
|
|
45187
45276
|
outputSchema: recordOutputSchema("get-local-sourcebook-contract", LocalSourcebookOutputSchema),
|
|
45188
45277
|
annotations: localPlanningToolAnnotations("Get Local Sourcebook Contract")
|
|
@@ -45217,14 +45306,14 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
|
|
|
45217
45306
|
}, async (input) => executor.validateLocalSourcebookWrite(input));
|
|
45218
45307
|
server.registerTool("local-sourcebook-capture", {
|
|
45219
45308
|
title: "Capture Governed Local Sourcebook Listing",
|
|
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.",
|
|
45309
|
+
description: "Strict owner-scoped write path after list, contract, prepare, and validate. Capture registers canonical tags, returns the exact LocalSourcebook.com profile and reviews URLs, 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.",
|
|
45221
45310
|
inputSchema: LocalSourcebookCaptureInputSchema,
|
|
45222
45311
|
outputSchema: recordOutputSchema("local-sourcebook-capture", LocalSourcebookOutputSchema),
|
|
45223
45312
|
annotations: liveWebToolAnnotations("Capture Governed Local Sourcebook Listing")
|
|
45224
45313
|
}, async (input) => executor.localSourcebookCapture(input));
|
|
45225
45314
|
server.registerTool("local_sourcebook_submission_status", {
|
|
45226
45315
|
title: "Local Sourcebook Submission Status",
|
|
45227
|
-
description: "Read the authenticated caller\u2019s listing draft, enrichment coverage, immutable revision number, and
|
|
45316
|
+
description: "Read the authenticated caller\u2019s listing draft, enrichment coverage, immutable revision number, publication state, and exact live LocalSourcebook.com profile and reviews URLs.",
|
|
45228
45317
|
inputSchema: LocalSourcebookSubmissionStatusInputSchema,
|
|
45229
45318
|
outputSchema: recordOutputSchema("local_sourcebook_submission_status", LocalSourcebookOutputSchema),
|
|
45230
45319
|
annotations: localPlanningToolAnnotations("Local Sourcebook Submission Status")
|