mcp-scraper 0.66.4 → 0.66.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -1
- package/README.md +1 -1
- package/dist/bin/api-server.cjs +63 -14
- package/dist/bin/api-server.js +1 -1
- package/dist/bin/mcp-scraper-cli.cjs +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-install.cjs +2 -2
- package/dist/bin/mcp-scraper-install.js +2 -2
- package/dist/bin/mcp-stdio-server.cjs +14 -8
- package/dist/bin/mcp-stdio-server.js +3 -3
- package/dist/{chunk-2XVDLF6H.js → chunk-KPE52NPT.js} +1 -1
- package/dist/{chunk-EGNT3AY2.js → chunk-NLEAYKOC.js} +1 -1
- package/dist/{chunk-UPN4W4SV.js → chunk-VMWVEKZT.js} +13 -7
- package/dist/{server-YATQ3WHT.js → server-5WPS3LZD.js} +51 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ All notable changes to MCP Scraper are documented here. The format is based on [
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.66.6] - 2026-08-26
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Google Search Console bulk URL Inspection now uses one bounded provider batch request, preserves successful URL results beside localized failures, and no longer inherits the former one-minute connected-tool cutoff.
|
|
12
|
+
|
|
13
|
+
## [0.66.5] - 2026-08-25
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Local Sourcebook submissions now distinguish accepted processing from publication, tell MCP clients to keep checking until the run is terminal, and return a plain-language completion message with the exact live listing URL.
|
|
18
|
+
|
|
7
19
|
## [0.66.4] - 2026-08-25
|
|
8
20
|
|
|
9
21
|
### Added
|
|
@@ -1109,7 +1121,9 @@ All notable changes to MCP Scraper are documented here. The format is based on [
|
|
|
1109
1121
|
- Write actions remain unavailable until the account owner explicitly enables them.
|
|
1110
1122
|
- Provider-specific connection data is normalized into one agent-facing contract.
|
|
1111
1123
|
|
|
1112
|
-
[Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.66.
|
|
1124
|
+
[Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.66.6...HEAD
|
|
1125
|
+
[0.66.6]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.66.5...v0.66.6
|
|
1126
|
+
[0.66.5]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.66.4...v0.66.5
|
|
1113
1127
|
[0.66.4]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.66.3...v0.66.4
|
|
1114
1128
|
[0.66.3]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.66.2...v0.66.3
|
|
1115
1129
|
[0.66.2]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.66.1...v0.66.2
|
package/README.md
CHANGED
|
@@ -159,7 +159,7 @@ Build the branded one-click bundle:
|
|
|
159
159
|
npm run build:mcpb
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.66.
|
|
162
|
+
The generated bundle is written to `build/mcpb/mcp-scraper-<version>.mcpb` and copied to `public/downloads/` for the hosted download. The current public bundle is `https://mcpscraper.dev/downloads/mcp-scraper.mcpb` (`0.66.6`, SHA-256 `828f1685c159314275c2ffd1ac437cc466801e1b0d4f43f09a65073581cb7db1`). Install it by opening or dragging it into Claude Desktop. Claude displays the `MCP Scraper` install card, icon, API-key configuration field, and manually curated current-release message from the bundle manifest.
|
|
163
163
|
|
|
164
164
|
The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
|
|
165
165
|
|
package/dist/bin/api-server.cjs
CHANGED
|
@@ -33148,12 +33148,39 @@ function localSourcebookPublicUrls(category, state, slug4) {
|
|
|
33148
33148
|
};
|
|
33149
33149
|
}
|
|
33150
33150
|
function localSourcebookPublicationLinks(submission) {
|
|
33151
|
+
const isLive = submission.publishedRevision !== null && submission.status !== "rejected" && submission.status !== "unpublished";
|
|
33151
33152
|
return {
|
|
33152
33153
|
...localSourcebookPublicUrls(submission.category, submission.state, submission.slug),
|
|
33153
33154
|
publicationStatus: submission.status,
|
|
33154
|
-
isLive
|
|
33155
|
+
isLive
|
|
33155
33156
|
};
|
|
33156
33157
|
}
|
|
33158
|
+
function localSourcebookPublicationMessage(submission) {
|
|
33159
|
+
const { profileUrl } = localSourcebookPublicUrls(submission.category, submission.state, submission.slug);
|
|
33160
|
+
if (submission.status === "published" && submission.publishedRevision !== null) {
|
|
33161
|
+
return `Your Local Sourcebook listing is live: ${profileUrl}`;
|
|
33162
|
+
}
|
|
33163
|
+
if (submission.status === "failed") {
|
|
33164
|
+
if (submission.publishedRevision !== null) {
|
|
33165
|
+
return `We couldn't refresh this Local Sourcebook listing, but the previous version is still live: ${profileUrl}`;
|
|
33166
|
+
}
|
|
33167
|
+
return "We couldn't publish this Local Sourcebook listing because evidence collection failed. Review the reported issue before trying again.";
|
|
33168
|
+
}
|
|
33169
|
+
if (submission.status === "rejected") {
|
|
33170
|
+
return "This Local Sourcebook listing was rejected and is not live.";
|
|
33171
|
+
}
|
|
33172
|
+
if (submission.status === "unpublished") {
|
|
33173
|
+
return "This Local Sourcebook listing has been unpublished and is not live.";
|
|
33174
|
+
}
|
|
33175
|
+
if (submission.publishedRevision !== null) {
|
|
33176
|
+
return `We are collecting and compiling refreshed evidence. The current Local Sourcebook listing remains live: ${profileUrl}`;
|
|
33177
|
+
}
|
|
33178
|
+
return "Submission received. We are collecting and compiling evidence, so this Local Sourcebook listing is not live yet. Check the submission status again in about 10 seconds.";
|
|
33179
|
+
}
|
|
33180
|
+
function localSourcebookStatusCheck(submission) {
|
|
33181
|
+
const required = submission.status === "queued" || submission.status === "enriching" || submission.status === "needs_review";
|
|
33182
|
+
return required ? { required: true, submissionId: submission.id, pollAfterSeconds: 10 } : { required: false, submissionId: submission.id };
|
|
33183
|
+
}
|
|
33157
33184
|
var DEFAULT_ROOT_DOMAIN, CATEGORY_PUBLIC_SLUGS;
|
|
33158
33185
|
var init_local_sourcebook_public_urls = __esm({
|
|
33159
33186
|
"src/api/local-sourcebook-public-urls.ts"() {
|
|
@@ -45265,7 +45292,7 @@ var init_local_sourcebook_routes = __esm({
|
|
|
45265
45292
|
persisted = true;
|
|
45266
45293
|
await persistLocalSourcebookTags(submission.id, Number(user.id), validation.normalizedTags, parsed.data.tagDecisions);
|
|
45267
45294
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
45268
|
-
return c.json({ ok: true, valid: true, submission, publicUrls: localSourcebookPublicationLinks(submission), normalizedTags: validation.normalizedTags, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(identity.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
45295
|
+
return c.json({ ok: true, valid: true, message: localSourcebookPublicationMessage(submission), statusCheck: localSourcebookStatusCheck(submission), submission, publicUrls: localSourcebookPublicationLinks(submission), normalizedTags: validation.normalizedTags, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(identity.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
45269
45296
|
} catch (error) {
|
|
45270
45297
|
if (billing && !persisted) await refundListingWrite(billing, "Local Sourcebook creation failed before persistence.").catch(() => null);
|
|
45271
45298
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -45314,7 +45341,7 @@ var init_local_sourcebook_routes = __esm({
|
|
|
45314
45341
|
});
|
|
45315
45342
|
persisted = true;
|
|
45316
45343
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
45317
|
-
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(input.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
45344
|
+
return c.json({ ok: true, message: localSourcebookPublicationMessage(submission), statusCheck: localSourcebookStatusCheck(submission), submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(input.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
45318
45345
|
} catch (error) {
|
|
45319
45346
|
if (billing && !persisted) await refundListingWrite(billing, "Local Sourcebook creation failed before persistence.").catch(() => null);
|
|
45320
45347
|
return c.json({ error: "submission_conflict", message: error instanceof Error ? error.message : String(error) }, 409);
|
|
@@ -45324,7 +45351,7 @@ var init_local_sourcebook_routes = __esm({
|
|
|
45324
45351
|
const userId = Number(c.get("user").id);
|
|
45325
45352
|
const submission = await getLocalSourcebookSubmission(c.req.param("id"), userId);
|
|
45326
45353
|
if (!submission) return c.json({ error: "not_found" }, 404);
|
|
45327
|
-
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), draft: await getLocalSourcebookDraft(submission.id, userId) });
|
|
45354
|
+
return c.json({ ok: true, message: localSourcebookPublicationMessage(submission), statusCheck: localSourcebookStatusCheck(submission), submission, publicUrls: localSourcebookPublicationLinks(submission), draft: await getLocalSourcebookDraft(submission.id, userId) });
|
|
45328
45355
|
});
|
|
45329
45356
|
localSourcebookApp.on(["PATCH", "POST"], "/submissions/:id/draft", createApiKeyAuth(), (c) => c.json({
|
|
45330
45357
|
error: "evidence_refresh_required",
|
|
@@ -45359,7 +45386,7 @@ var init_local_sourcebook_routes = __esm({
|
|
|
45359
45386
|
return c.json({ error: "not_found" }, 404);
|
|
45360
45387
|
}
|
|
45361
45388
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
45362
|
-
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(submission.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
45389
|
+
return c.json({ ok: true, message: localSourcebookPublicationMessage(submission), statusCheck: localSourcebookStatusCheck(submission), submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(submission.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
45363
45390
|
} catch (error) {
|
|
45364
45391
|
if (billing) await refundListingWrite(billing, "Local Sourcebook refresh failed before persistence.").catch(() => null);
|
|
45365
45392
|
return c.json({ error: "moderated_listing", message: error instanceof Error ? error.message : String(error) }, 409);
|
|
@@ -49679,7 +49706,7 @@ var PACKAGE_VERSION;
|
|
|
49679
49706
|
var init_version = __esm({
|
|
49680
49707
|
"src/version.ts"() {
|
|
49681
49708
|
"use strict";
|
|
49682
|
-
PACKAGE_VERSION = "0.66.
|
|
49709
|
+
PACKAGE_VERSION = "0.66.6";
|
|
49683
49710
|
}
|
|
49684
49711
|
});
|
|
49685
49712
|
|
|
@@ -49910,11 +49937,16 @@ Multi-step orchestrations \u2014 prefer these over hand-chaining primitives when
|
|
|
49910
49937
|
- A new capture costs 10 Credits total and includes broad website, exact Maps place, maximum-accessible review,
|
|
49911
49938
|
service-area, staff, and genuine-media acquisition. When compilation succeeds, that exact system-authored evidence revision
|
|
49912
49939
|
publishes automatically. Never supply owner-authored services, reviews, images, or other public claims.
|
|
49940
|
+
- An accepted capture is still processing, not complete. While its returned \`statusCheck.required\` is true,
|
|
49941
|
+
wait the suggested interval and call **local_sourcebook_submission_status** again before giving the user a
|
|
49942
|
+
final completion answer. When it publishes, say that the listing is live and include the exact clickable
|
|
49943
|
+
\`publicUrls.profileUrl\`; when it fails, report the returned failure message and cause.
|
|
49913
49944
|
- Read progress and the compiled record with **local_sourcebook_submission_status**. Use
|
|
49914
49945
|
**local_sourcebook_refresh** only when the owner intentionally wants to pay 2 Credits for a new acquisition pass.
|
|
49915
49946
|
Contract, tag, preparation, validation, and status tools are free; idempotent retries are not charged twice.
|
|
49916
|
-
- Capture and status responses return \`
|
|
49917
|
-
|
|
49947
|
+
- Capture and status responses return a plain-language \`message\`, a \`statusCheck\`, and exact public URLs. Do not
|
|
49948
|
+
describe a queued or enriching listing as complete, and do not report a listing as live without including its
|
|
49949
|
+
clickable \`publicUrls.profileUrl\`.
|
|
49918
49950
|
- The last published revision remains public during refresh. Administrators can reject or unpublish an
|
|
49919
49951
|
exceptional record, but routine subscriber publication does not require administrator review.
|
|
49920
49952
|
|
|
@@ -56210,14 +56242,14 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
|
|
|
56210
56242
|
}, async (input) => executor.validateLocalSourcebookWrite(input));
|
|
56211
56243
|
server.registerTool("local-sourcebook-capture", {
|
|
56212
56244
|
title: "Capture Governed Local Sourcebook Listing",
|
|
56213
|
-
description: "Strict owner-scoped LocalBusiness write path after list, contract, prepare, and validate. Creating a listing costs 10 Credits total, including website, exact-place, review, service-area, staff, genuine-media, and structured-data compilation; preparation and validation are free, and idempotent retries are not charged twice. Capture registers canonical tags and the accepted Schema.org LocalBusiness subtype,
|
|
56245
|
+
description: "Strict owner-scoped LocalBusiness write path after list, contract, prepare, and validate. Creating a listing costs 10 Credits total, including website, exact-place, review, service-area, staff, genuine-media, and structured-data compilation; preparation and validation are free, and idempotent retries are not charged twice. Capture registers canonical tags and the accepted Schema.org LocalBusiness subtype, then queues acquisition; an accepted capture is not yet live. Poll local_sourcebook_submission_status using statusCheck until it is terminal. When published, tell the user the returned message and exact publicUrls.profileUrl. MCP Scraper generates the final JSON-LD from source-backed evidence and publishes a successful system-compiled revision automatically; owner-authored public claims and arbitrary JSON-LD are not accepted.",
|
|
56214
56246
|
inputSchema: LocalSourcebookCaptureInputSchema,
|
|
56215
56247
|
outputSchema: recordOutputSchema("local-sourcebook-capture", LocalSourcebookOutputSchema),
|
|
56216
56248
|
annotations: liveWebToolAnnotations("Capture Governed Local Sourcebook Listing")
|
|
56217
56249
|
}, async (input) => executor.localSourcebookCapture(input));
|
|
56218
56250
|
server.registerTool("local_sourcebook_submission_status", {
|
|
56219
56251
|
title: "Local Sourcebook Submission Status",
|
|
56220
|
-
description: "Read the caller\u2019s listing draft, enrichment coverage, revision number, publication state, and
|
|
56252
|
+
description: "Read the caller\u2019s listing draft, enrichment coverage, revision number, publication state, and LocalSourcebook.com profile and reviews URLs. While statusCheck.required is true, wait the returned interval and check again before giving the user a final completion answer. When published, present the returned message and exact clickable publicUrls.profileUrl. When failed, present the failure message and read acquisitionError before retrying, since a refresh repeats the same acquisition. Coverage counters are written only on success, so zeroed counters on a failed listing do not mean the crawl never ran.",
|
|
56221
56253
|
inputSchema: LocalSourcebookSubmissionStatusInputSchema,
|
|
56222
56254
|
outputSchema: recordOutputSchema("local_sourcebook_submission_status", LocalSourcebookOutputSchema),
|
|
56223
56255
|
annotations: localPlanningToolAnnotations("Local Sourcebook Submission Status")
|
|
@@ -56586,7 +56618,8 @@ function httpErrorPayload(path6, res, data) {
|
|
|
56586
56618
|
const safeCode = privateUpstreamState ? "service_unavailable" : recognized ? candidateCode : normalizePublicErrorCode(candidateCode);
|
|
56587
56619
|
const bodyMessage = objectData ? objectData.message ?? objectData.error ?? rawCode : data;
|
|
56588
56620
|
return {
|
|
56589
|
-
...recognized && objectData ? objectData : {},
|
|
56621
|
+
...recognized && objectData && safeCode !== "mcp_request_timeout" ? objectData : {},
|
|
56622
|
+
...recognized ? { code: safeCode } : {},
|
|
56590
56623
|
error: safeCode,
|
|
56591
56624
|
error_code: safeCode,
|
|
56592
56625
|
error_type: recognized && typeof objectData?.error_type === "string" ? objectData.error_type : "http",
|
|
@@ -56594,7 +56627,7 @@ function httpErrorPayload(path6, res, data) {
|
|
|
56594
56627
|
status: res.status,
|
|
56595
56628
|
statusText: res.statusText,
|
|
56596
56629
|
path: path6,
|
|
56597
|
-
message: recognized && typeof bodyMessage === "string" && bodyMessage.trim() ? sanitizeVendorName(bodyMessage) : publicErrorMessage(safeCode)
|
|
56630
|
+
message: safeCode === "mcp_request_timeout" ? "The connected service operation timed out before returning a result. Retry failed items or use a smaller batch." : recognized && typeof bodyMessage === "string" && bodyMessage.trim() ? sanitizeVendorName(bodyMessage) : publicErrorMessage(safeCode)
|
|
56598
56631
|
};
|
|
56599
56632
|
}
|
|
56600
56633
|
function withDefaultHostedProfile(input) {
|
|
@@ -84412,6 +84445,15 @@ function retryAfterMsFromText(value) {
|
|
|
84412
84445
|
function normalizeNangoClientError(error) {
|
|
84413
84446
|
if (error instanceof MainNangoTransportError) return error;
|
|
84414
84447
|
const detail = nangoClientErrorText(error);
|
|
84448
|
+
const structured = error && typeof error === "object" ? error : null;
|
|
84449
|
+
if (structured?.code === -32001 || structured?.name === "RequestTimeout" || /Request timed out|RequestTimeout|Maximum total timeout exceeded/i.test(detail)) {
|
|
84450
|
+
return new MainNangoTransportError(
|
|
84451
|
+
"The connected service operation timed out before returning a result. Retry failed items or use a smaller batch.",
|
|
84452
|
+
503,
|
|
84453
|
+
"mcp_request_timeout",
|
|
84454
|
+
true
|
|
84455
|
+
);
|
|
84456
|
+
}
|
|
84415
84457
|
if (/SERVICE_DISABLED|accessNotConfigured/i.test(detail)) {
|
|
84416
84458
|
return new MainNangoTransportError(
|
|
84417
84459
|
"The provider API required by this connection is disabled. Enable it in the provider project, wait for propagation, then retry.",
|
|
@@ -84442,6 +84484,12 @@ function normalizeNangoClientError(error) {
|
|
|
84442
84484
|
}
|
|
84443
84485
|
return new MainNangoTransportError("The service connection is temporarily unavailable.", 503, "connection_transport_unavailable");
|
|
84444
84486
|
}
|
|
84487
|
+
async function callNangoToolWithBudget(client2, tool, input) {
|
|
84488
|
+
return client2.callTool(
|
|
84489
|
+
{ name: tool, arguments: input },
|
|
84490
|
+
{ timeout: NANGO_TOOL_CALL_TIMEOUT_MS }
|
|
84491
|
+
);
|
|
84492
|
+
}
|
|
84445
84493
|
function asRecord2(value) {
|
|
84446
84494
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
84447
84495
|
}
|
|
@@ -84885,7 +84933,7 @@ async function callNangoToolDirect(args) {
|
|
|
84885
84933
|
let result;
|
|
84886
84934
|
let providerError;
|
|
84887
84935
|
try {
|
|
84888
|
-
result = await withNangoClient(connection, (client2) => client2
|
|
84936
|
+
result = await withNangoClient(connection, (client2) => callNangoToolWithBudget(client2, args.tool, args.input));
|
|
84889
84937
|
} catch (error) {
|
|
84890
84938
|
providerError = error;
|
|
84891
84939
|
}
|
|
@@ -84950,7 +84998,7 @@ async function describeNangoToolDirect(identity, connectionId, toolName) {
|
|
|
84950
84998
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
84951
84999
|
};
|
|
84952
85000
|
}
|
|
84953
|
-
var import_node_crypto68, import_client13, DEFAULT_NANGO_MCP_URL, NANGO_TIMEOUT_MS, NANGO_CONNECTION_PAGE_SIZE, NANGO_CONNECTION_MAX_PAGES, PROVIDER_IDENTITY_RETRY_MS, MAIN_INTEGRATION_CONTRACT_VERSION, MAIN_INTEGRATION_CONTRACT_HASH, MainNangoTransportError, IDENTITY_SUPPORTED_PROVIDERS;
|
|
85001
|
+
var import_node_crypto68, import_client13, DEFAULT_NANGO_MCP_URL, NANGO_TIMEOUT_MS, NANGO_TOOL_CALL_TIMEOUT_MS, NANGO_CONNECTION_PAGE_SIZE, NANGO_CONNECTION_MAX_PAGES, PROVIDER_IDENTITY_RETRY_MS, MAIN_INTEGRATION_CONTRACT_VERSION, MAIN_INTEGRATION_CONTRACT_HASH, MainNangoTransportError, IDENTITY_SUPPORTED_PROVIDERS;
|
|
84954
85002
|
var init_main_nango_transport = __esm({
|
|
84955
85003
|
"src/api/main-nango-transport.ts"() {
|
|
84956
85004
|
"use strict";
|
|
@@ -84962,6 +85010,7 @@ var init_main_nango_transport = __esm({
|
|
|
84962
85010
|
init_connected_tool_policy();
|
|
84963
85011
|
DEFAULT_NANGO_MCP_URL = "https://api.nango.dev/mcp";
|
|
84964
85012
|
NANGO_TIMEOUT_MS = 2e4;
|
|
85013
|
+
NANGO_TOOL_CALL_TIMEOUT_MS = 24e4;
|
|
84965
85014
|
NANGO_CONNECTION_PAGE_SIZE = 100;
|
|
84966
85015
|
NANGO_CONNECTION_MAX_PAGES = 20;
|
|
84967
85016
|
PROVIDER_IDENTITY_RETRY_MS = 6 * 60 * 60 * 1e3;
|
package/dist/bin/api-server.js
CHANGED
|
@@ -17,7 +17,7 @@ loadDotEnv();
|
|
|
17
17
|
async function main() {
|
|
18
18
|
const [{ serve }, { app }, { startWorker }, { migrate }] = await Promise.all([
|
|
19
19
|
import("@hono/node-server"),
|
|
20
|
-
import("../server-
|
|
20
|
+
import("../server-5WPS3LZD.js"),
|
|
21
21
|
import("../worker-UTBUWEXQ.js"),
|
|
22
22
|
import("../db-4RVZ3NYZ.js")
|
|
23
23
|
]);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
// release-message.json
|
|
5
5
|
var release_message_default = {
|
|
6
|
-
message: "
|
|
6
|
+
message: "Search Console bulk URL Inspection now returns one ordered partial-result receipt without the former one-minute cutoff."
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
// src/install-terminal.ts
|
|
@@ -112,7 +112,7 @@ function renderInstallTerminal(options) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
// src/version.ts
|
|
115
|
-
var PACKAGE_VERSION = "0.66.
|
|
115
|
+
var PACKAGE_VERSION = "0.66.6";
|
|
116
116
|
|
|
117
117
|
// bin/mcp-scraper-install.ts
|
|
118
118
|
var noColor = process.argv.includes("--no-color") || process.env.NO_COLOR !== void 0 || process.env.FORCE_COLOR === "0" || !process.stdout.isTTY;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
renderInstallTerminal
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-KPE52NPT.js";
|
|
5
5
|
import {
|
|
6
6
|
PACKAGE_VERSION
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-NLEAYKOC.js";
|
|
8
8
|
|
|
9
9
|
// bin/mcp-scraper-install.ts
|
|
10
10
|
var noColor = process.argv.includes("--no-color") || process.env.NO_COLOR !== void 0 || process.env.FORCE_COLOR === "0" || !process.stdout.isTTY;
|
|
@@ -431,7 +431,8 @@ function httpErrorPayload(path, res, data) {
|
|
|
431
431
|
const safeCode = privateUpstreamState ? "service_unavailable" : recognized ? candidateCode : normalizePublicErrorCode(candidateCode);
|
|
432
432
|
const bodyMessage = objectData ? objectData.message ?? objectData.error ?? rawCode : data;
|
|
433
433
|
return {
|
|
434
|
-
...recognized && objectData ? objectData : {},
|
|
434
|
+
...recognized && objectData && safeCode !== "mcp_request_timeout" ? objectData : {},
|
|
435
|
+
...recognized ? { code: safeCode } : {},
|
|
435
436
|
error: safeCode,
|
|
436
437
|
error_code: safeCode,
|
|
437
438
|
error_type: recognized && typeof objectData?.error_type === "string" ? objectData.error_type : "http",
|
|
@@ -439,7 +440,7 @@ function httpErrorPayload(path, res, data) {
|
|
|
439
440
|
status: res.status,
|
|
440
441
|
statusText: res.statusText,
|
|
441
442
|
path,
|
|
442
|
-
message: recognized && typeof bodyMessage === "string" && bodyMessage.trim() ? sanitizeVendorName(bodyMessage) : publicErrorMessage(safeCode)
|
|
443
|
+
message: safeCode === "mcp_request_timeout" ? "The connected service operation timed out before returning a result. Retry failed items or use a smaller batch." : recognized && typeof bodyMessage === "string" && bodyMessage.trim() ? sanitizeVendorName(bodyMessage) : publicErrorMessage(safeCode)
|
|
443
444
|
};
|
|
444
445
|
}
|
|
445
446
|
function withDefaultHostedProfile(input) {
|
|
@@ -1232,7 +1233,7 @@ render();
|
|
|
1232
1233
|
}
|
|
1233
1234
|
|
|
1234
1235
|
// src/version.ts
|
|
1235
|
-
var PACKAGE_VERSION = "0.66.
|
|
1236
|
+
var PACKAGE_VERSION = "0.66.6";
|
|
1236
1237
|
|
|
1237
1238
|
// src/mcp/input-field-descriptions.ts
|
|
1238
1239
|
var import_zod = require("zod");
|
|
@@ -8378,11 +8379,16 @@ Multi-step orchestrations \u2014 prefer these over hand-chaining primitives when
|
|
|
8378
8379
|
- A new capture costs 10 Credits total and includes broad website, exact Maps place, maximum-accessible review,
|
|
8379
8380
|
service-area, staff, and genuine-media acquisition. When compilation succeeds, that exact system-authored evidence revision
|
|
8380
8381
|
publishes automatically. Never supply owner-authored services, reviews, images, or other public claims.
|
|
8382
|
+
- An accepted capture is still processing, not complete. While its returned \`statusCheck.required\` is true,
|
|
8383
|
+
wait the suggested interval and call **local_sourcebook_submission_status** again before giving the user a
|
|
8384
|
+
final completion answer. When it publishes, say that the listing is live and include the exact clickable
|
|
8385
|
+
\`publicUrls.profileUrl\`; when it fails, report the returned failure message and cause.
|
|
8381
8386
|
- Read progress and the compiled record with **local_sourcebook_submission_status**. Use
|
|
8382
8387
|
**local_sourcebook_refresh** only when the owner intentionally wants to pay 2 Credits for a new acquisition pass.
|
|
8383
8388
|
Contract, tag, preparation, validation, and status tools are free; idempotent retries are not charged twice.
|
|
8384
|
-
- Capture and status responses return \`
|
|
8385
|
-
|
|
8389
|
+
- Capture and status responses return a plain-language \`message\`, a \`statusCheck\`, and exact public URLs. Do not
|
|
8390
|
+
describe a queued or enriching listing as complete, and do not report a listing as live without including its
|
|
8391
|
+
clickable \`publicUrls.profileUrl\`.
|
|
8386
8392
|
- The last published revision remains public during refresh. Administrators can reject or unpublish an
|
|
8387
8393
|
exceptional record, but routine subscriber publication does not require administrator review.
|
|
8388
8394
|
|
|
@@ -14231,14 +14237,14 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
|
|
|
14231
14237
|
}, async (input) => executor.validateLocalSourcebookWrite(input));
|
|
14232
14238
|
server.registerTool("local-sourcebook-capture", {
|
|
14233
14239
|
title: "Capture Governed Local Sourcebook Listing",
|
|
14234
|
-
description: "Strict owner-scoped LocalBusiness write path after list, contract, prepare, and validate. Creating a listing costs 10 Credits total, including website, exact-place, review, service-area, staff, genuine-media, and structured-data compilation; preparation and validation are free, and idempotent retries are not charged twice. Capture registers canonical tags and the accepted Schema.org LocalBusiness subtype,
|
|
14240
|
+
description: "Strict owner-scoped LocalBusiness write path after list, contract, prepare, and validate. Creating a listing costs 10 Credits total, including website, exact-place, review, service-area, staff, genuine-media, and structured-data compilation; preparation and validation are free, and idempotent retries are not charged twice. Capture registers canonical tags and the accepted Schema.org LocalBusiness subtype, then queues acquisition; an accepted capture is not yet live. Poll local_sourcebook_submission_status using statusCheck until it is terminal. When published, tell the user the returned message and exact publicUrls.profileUrl. MCP Scraper generates the final JSON-LD from source-backed evidence and publishes a successful system-compiled revision automatically; owner-authored public claims and arbitrary JSON-LD are not accepted.",
|
|
14235
14241
|
inputSchema: LocalSourcebookCaptureInputSchema,
|
|
14236
14242
|
outputSchema: recordOutputSchema("local-sourcebook-capture", LocalSourcebookOutputSchema),
|
|
14237
14243
|
annotations: liveWebToolAnnotations("Capture Governed Local Sourcebook Listing")
|
|
14238
14244
|
}, async (input) => executor.localSourcebookCapture(input));
|
|
14239
14245
|
server.registerTool("local_sourcebook_submission_status", {
|
|
14240
14246
|
title: "Local Sourcebook Submission Status",
|
|
14241
|
-
description: "Read the caller\u2019s listing draft, enrichment coverage, revision number, publication state, and
|
|
14247
|
+
description: "Read the caller\u2019s listing draft, enrichment coverage, revision number, publication state, and LocalSourcebook.com profile and reviews URLs. While statusCheck.required is true, wait the returned interval and check again before giving the user a final completion answer. When published, present the returned message and exact clickable publicUrls.profileUrl. When failed, present the failure message and read acquisitionError before retrying, since a refresh repeats the same acquisition. Coverage counters are written only on success, so zeroed counters on a failed listing do not mean the crawl never ran.",
|
|
14242
14248
|
inputSchema: LocalSourcebookSubmissionStatusInputSchema,
|
|
14243
14249
|
outputSchema: recordOutputSchema("local_sourcebook_submission_status", LocalSourcebookOutputSchema),
|
|
14244
14250
|
annotations: localPlanningToolAnnotations("Local Sourcebook Submission Status")
|
|
@@ -18660,7 +18666,7 @@ var HostedMemoryMcpToolExecutor = class {
|
|
|
18660
18666
|
|
|
18661
18667
|
// release-message.json
|
|
18662
18668
|
var release_message_default = {
|
|
18663
|
-
message: "
|
|
18669
|
+
message: "Search Console bulk URL Inspection now returns one ordered partial-result receipt without the former one-minute cutoff."
|
|
18664
18670
|
};
|
|
18665
18671
|
|
|
18666
18672
|
// src/install-terminal.ts
|
|
@@ -13,18 +13,18 @@ import {
|
|
|
13
13
|
registerScheduledResultsMcpTools,
|
|
14
14
|
registerSerpIntelligenceCaptureTools,
|
|
15
15
|
resolveDeploymentProfile
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-VMWVEKZT.js";
|
|
17
17
|
import "../chunk-PGJQDMC2.js";
|
|
18
18
|
import "../chunk-3EYALCYK.js";
|
|
19
19
|
import "../chunk-3TKKJQB4.js";
|
|
20
20
|
import {
|
|
21
21
|
renderInstallTerminal
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-KPE52NPT.js";
|
|
23
23
|
import "../chunk-VXLU74YZ.js";
|
|
24
24
|
import "../chunk-GGZEC22A.js";
|
|
25
25
|
import {
|
|
26
26
|
PACKAGE_VERSION
|
|
27
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-NLEAYKOC.js";
|
|
28
28
|
import "../chunk-DNM65UCK.js";
|
|
29
29
|
import "../chunk-AYJHI2FK.js";
|
|
30
30
|
import "../chunk-55B3T5L2.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// release-message.json
|
|
2
2
|
var release_message_default = {
|
|
3
|
-
message: "
|
|
3
|
+
message: "Search Console bulk URL Inspection now returns one ordered partial-result receipt without the former one-minute cutoff."
|
|
4
4
|
};
|
|
5
5
|
|
|
6
6
|
// src/install-terminal.ts
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "./chunk-VXLU74YZ.js";
|
|
26
26
|
import {
|
|
27
27
|
PACKAGE_VERSION
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-NLEAYKOC.js";
|
|
29
29
|
import {
|
|
30
30
|
createPrivateArtifact,
|
|
31
31
|
privateArtifactOwnerId,
|
|
@@ -550,11 +550,16 @@ Multi-step orchestrations \u2014 prefer these over hand-chaining primitives when
|
|
|
550
550
|
- A new capture costs 10 Credits total and includes broad website, exact Maps place, maximum-accessible review,
|
|
551
551
|
service-area, staff, and genuine-media acquisition. When compilation succeeds, that exact system-authored evidence revision
|
|
552
552
|
publishes automatically. Never supply owner-authored services, reviews, images, or other public claims.
|
|
553
|
+
- An accepted capture is still processing, not complete. While its returned \`statusCheck.required\` is true,
|
|
554
|
+
wait the suggested interval and call **local_sourcebook_submission_status** again before giving the user a
|
|
555
|
+
final completion answer. When it publishes, say that the listing is live and include the exact clickable
|
|
556
|
+
\`publicUrls.profileUrl\`; when it fails, report the returned failure message and cause.
|
|
553
557
|
- Read progress and the compiled record with **local_sourcebook_submission_status**. Use
|
|
554
558
|
**local_sourcebook_refresh** only when the owner intentionally wants to pay 2 Credits for a new acquisition pass.
|
|
555
559
|
Contract, tag, preparation, validation, and status tools are free; idempotent retries are not charged twice.
|
|
556
|
-
- Capture and status responses return \`
|
|
557
|
-
|
|
560
|
+
- Capture and status responses return a plain-language \`message\`, a \`statusCheck\`, and exact public URLs. Do not
|
|
561
|
+
describe a queued or enriching listing as complete, and do not report a listing as live without including its
|
|
562
|
+
clickable \`publicUrls.profileUrl\`.
|
|
558
563
|
- The last published revision remains public during refresh. Administrators can reject or unpublish an
|
|
559
564
|
exceptional record, but routine subscriber publication does not require administrator review.
|
|
560
565
|
|
|
@@ -11740,14 +11745,14 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
|
|
|
11740
11745
|
}, async (input) => executor.validateLocalSourcebookWrite(input));
|
|
11741
11746
|
server.registerTool("local-sourcebook-capture", {
|
|
11742
11747
|
title: "Capture Governed Local Sourcebook Listing",
|
|
11743
|
-
description: "Strict owner-scoped LocalBusiness write path after list, contract, prepare, and validate. Creating a listing costs 10 Credits total, including website, exact-place, review, service-area, staff, genuine-media, and structured-data compilation; preparation and validation are free, and idempotent retries are not charged twice. Capture registers canonical tags and the accepted Schema.org LocalBusiness subtype,
|
|
11748
|
+
description: "Strict owner-scoped LocalBusiness write path after list, contract, prepare, and validate. Creating a listing costs 10 Credits total, including website, exact-place, review, service-area, staff, genuine-media, and structured-data compilation; preparation and validation are free, and idempotent retries are not charged twice. Capture registers canonical tags and the accepted Schema.org LocalBusiness subtype, then queues acquisition; an accepted capture is not yet live. Poll local_sourcebook_submission_status using statusCheck until it is terminal. When published, tell the user the returned message and exact publicUrls.profileUrl. MCP Scraper generates the final JSON-LD from source-backed evidence and publishes a successful system-compiled revision automatically; owner-authored public claims and arbitrary JSON-LD are not accepted.",
|
|
11744
11749
|
inputSchema: LocalSourcebookCaptureInputSchema,
|
|
11745
11750
|
outputSchema: recordOutputSchema("local-sourcebook-capture", LocalSourcebookOutputSchema),
|
|
11746
11751
|
annotations: liveWebToolAnnotations("Capture Governed Local Sourcebook Listing")
|
|
11747
11752
|
}, async (input) => executor.localSourcebookCapture(input));
|
|
11748
11753
|
server.registerTool("local_sourcebook_submission_status", {
|
|
11749
11754
|
title: "Local Sourcebook Submission Status",
|
|
11750
|
-
description: "Read the caller\u2019s listing draft, enrichment coverage, revision number, publication state, and
|
|
11755
|
+
description: "Read the caller\u2019s listing draft, enrichment coverage, revision number, publication state, and LocalSourcebook.com profile and reviews URLs. While statusCheck.required is true, wait the returned interval and check again before giving the user a final completion answer. When published, present the returned message and exact clickable publicUrls.profileUrl. When failed, present the failure message and read acquisitionError before retrying, since a refresh repeats the same acquisition. Coverage counters are written only on success, so zeroed counters on a failed listing do not mean the crawl never ran.",
|
|
11751
11756
|
inputSchema: LocalSourcebookSubmissionStatusInputSchema,
|
|
11752
11757
|
outputSchema: recordOutputSchema("local_sourcebook_submission_status", LocalSourcebookOutputSchema),
|
|
11753
11758
|
annotations: localPlanningToolAnnotations("Local Sourcebook Submission Status")
|
|
@@ -12089,7 +12094,8 @@ function httpErrorPayload(path, res, data) {
|
|
|
12089
12094
|
const safeCode = privateUpstreamState ? "service_unavailable" : recognized ? candidateCode : normalizePublicErrorCode(candidateCode);
|
|
12090
12095
|
const bodyMessage = objectData ? objectData.message ?? objectData.error ?? rawCode : data;
|
|
12091
12096
|
return {
|
|
12092
|
-
...recognized && objectData ? objectData : {},
|
|
12097
|
+
...recognized && objectData && safeCode !== "mcp_request_timeout" ? objectData : {},
|
|
12098
|
+
...recognized ? { code: safeCode } : {},
|
|
12093
12099
|
error: safeCode,
|
|
12094
12100
|
error_code: safeCode,
|
|
12095
12101
|
error_type: recognized && typeof objectData?.error_type === "string" ? objectData.error_type : "http",
|
|
@@ -12097,7 +12103,7 @@ function httpErrorPayload(path, res, data) {
|
|
|
12097
12103
|
status: res.status,
|
|
12098
12104
|
statusText: res.statusText,
|
|
12099
12105
|
path,
|
|
12100
|
-
message: recognized && typeof bodyMessage === "string" && bodyMessage.trim() ? sanitizeVendorName(bodyMessage) : publicErrorMessage(safeCode)
|
|
12106
|
+
message: safeCode === "mcp_request_timeout" ? "The connected service operation timed out before returning a result. Retry failed items or use a smaller batch." : recognized && typeof bodyMessage === "string" && bodyMessage.trim() ? sanitizeVendorName(bodyMessage) : publicErrorMessage(safeCode)
|
|
12101
12107
|
};
|
|
12102
12108
|
}
|
|
12103
12109
|
function withDefaultHostedProfile(input) {
|
|
@@ -199,7 +199,7 @@ import {
|
|
|
199
199
|
resolveDeploymentProfile,
|
|
200
200
|
resolveLocalSourcebookSchemaType,
|
|
201
201
|
transcribeMediaUrl
|
|
202
|
-
} from "./chunk-
|
|
202
|
+
} from "./chunk-VMWVEKZT.js";
|
|
203
203
|
import {
|
|
204
204
|
auditImageUrls,
|
|
205
205
|
auditImages,
|
|
@@ -256,7 +256,7 @@ import {
|
|
|
256
256
|
} from "./chunk-GGZEC22A.js";
|
|
257
257
|
import {
|
|
258
258
|
PACKAGE_VERSION
|
|
259
|
-
} from "./chunk-
|
|
259
|
+
} from "./chunk-NLEAYKOC.js";
|
|
260
260
|
import {
|
|
261
261
|
SITE_EXTRACT_ARTIFACT_PREFIX,
|
|
262
262
|
abandonExtractSettlement,
|
|
@@ -13665,12 +13665,39 @@ function localSourcebookPublicUrls(category, state, slug4) {
|
|
|
13665
13665
|
};
|
|
13666
13666
|
}
|
|
13667
13667
|
function localSourcebookPublicationLinks(submission) {
|
|
13668
|
+
const isLive = submission.publishedRevision !== null && submission.status !== "rejected" && submission.status !== "unpublished";
|
|
13668
13669
|
return {
|
|
13669
13670
|
...localSourcebookPublicUrls(submission.category, submission.state, submission.slug),
|
|
13670
13671
|
publicationStatus: submission.status,
|
|
13671
|
-
isLive
|
|
13672
|
+
isLive
|
|
13672
13673
|
};
|
|
13673
13674
|
}
|
|
13675
|
+
function localSourcebookPublicationMessage(submission) {
|
|
13676
|
+
const { profileUrl } = localSourcebookPublicUrls(submission.category, submission.state, submission.slug);
|
|
13677
|
+
if (submission.status === "published" && submission.publishedRevision !== null) {
|
|
13678
|
+
return `Your Local Sourcebook listing is live: ${profileUrl}`;
|
|
13679
|
+
}
|
|
13680
|
+
if (submission.status === "failed") {
|
|
13681
|
+
if (submission.publishedRevision !== null) {
|
|
13682
|
+
return `We couldn't refresh this Local Sourcebook listing, but the previous version is still live: ${profileUrl}`;
|
|
13683
|
+
}
|
|
13684
|
+
return "We couldn't publish this Local Sourcebook listing because evidence collection failed. Review the reported issue before trying again.";
|
|
13685
|
+
}
|
|
13686
|
+
if (submission.status === "rejected") {
|
|
13687
|
+
return "This Local Sourcebook listing was rejected and is not live.";
|
|
13688
|
+
}
|
|
13689
|
+
if (submission.status === "unpublished") {
|
|
13690
|
+
return "This Local Sourcebook listing has been unpublished and is not live.";
|
|
13691
|
+
}
|
|
13692
|
+
if (submission.publishedRevision !== null) {
|
|
13693
|
+
return `We are collecting and compiling refreshed evidence. The current Local Sourcebook listing remains live: ${profileUrl}`;
|
|
13694
|
+
}
|
|
13695
|
+
return "Submission received. We are collecting and compiling evidence, so this Local Sourcebook listing is not live yet. Check the submission status again in about 10 seconds.";
|
|
13696
|
+
}
|
|
13697
|
+
function localSourcebookStatusCheck(submission) {
|
|
13698
|
+
const required = submission.status === "queued" || submission.status === "enriching" || submission.status === "needs_review";
|
|
13699
|
+
return required ? { required: true, submissionId: submission.id, pollAfterSeconds: 10 } : { required: false, submissionId: submission.id };
|
|
13700
|
+
}
|
|
13674
13701
|
|
|
13675
13702
|
// src/api/local-sourcebook-compiler.ts
|
|
13676
13703
|
var CATEGORY_LABELS = {
|
|
@@ -24864,7 +24891,7 @@ localSourcebookApp.post("/capture", createApiKeyAuth(), async (c) => {
|
|
|
24864
24891
|
persisted = true;
|
|
24865
24892
|
await persistLocalSourcebookTags(submission.id, Number(user.id), validation.normalizedTags, parsed.data.tagDecisions);
|
|
24866
24893
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
24867
|
-
return c.json({ ok: true, valid: true, submission, publicUrls: localSourcebookPublicationLinks(submission), normalizedTags: validation.normalizedTags, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(identity.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
24894
|
+
return c.json({ ok: true, valid: true, message: localSourcebookPublicationMessage(submission), statusCheck: localSourcebookStatusCheck(submission), submission, publicUrls: localSourcebookPublicationLinks(submission), normalizedTags: validation.normalizedTags, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(identity.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
24868
24895
|
} catch (error) {
|
|
24869
24896
|
if (billing && !persisted) await refundListingWrite(billing, "Local Sourcebook creation failed before persistence.").catch(() => null);
|
|
24870
24897
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -24913,7 +24940,7 @@ localSourcebookApp.post("/submissions", createApiKeyAuth(), async (c) => {
|
|
|
24913
24940
|
});
|
|
24914
24941
|
persisted = true;
|
|
24915
24942
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
24916
|
-
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(input.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
24943
|
+
return c.json({ ok: true, message: localSourcebookPublicationMessage(submission), statusCheck: localSourcebookStatusCheck(submission), submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(input.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
24917
24944
|
} catch (error) {
|
|
24918
24945
|
if (billing && !persisted) await refundListingWrite(billing, "Local Sourcebook creation failed before persistence.").catch(() => null);
|
|
24919
24946
|
return c.json({ error: "submission_conflict", message: error instanceof Error ? error.message : String(error) }, 409);
|
|
@@ -24923,7 +24950,7 @@ localSourcebookApp.get("/submissions/:id", createApiKeyAuth(), async (c) => {
|
|
|
24923
24950
|
const userId = Number(c.get("user").id);
|
|
24924
24951
|
const submission = await getLocalSourcebookSubmission(c.req.param("id"), userId);
|
|
24925
24952
|
if (!submission) return c.json({ error: "not_found" }, 404);
|
|
24926
|
-
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), draft: await getLocalSourcebookDraft(submission.id, userId) });
|
|
24953
|
+
return c.json({ ok: true, message: localSourcebookPublicationMessage(submission), statusCheck: localSourcebookStatusCheck(submission), submission, publicUrls: localSourcebookPublicationLinks(submission), draft: await getLocalSourcebookDraft(submission.id, userId) });
|
|
24927
24954
|
});
|
|
24928
24955
|
localSourcebookApp.on(["PATCH", "POST"], "/submissions/:id/draft", createApiKeyAuth(), (c) => c.json({
|
|
24929
24956
|
error: "evidence_refresh_required",
|
|
@@ -24958,7 +24985,7 @@ localSourcebookApp.post("/submissions/:id/refresh", createApiKeyAuth(), async (c
|
|
|
24958
24985
|
return c.json({ error: "not_found" }, 404);
|
|
24959
24986
|
}
|
|
24960
24987
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
24961
|
-
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(submission.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
24988
|
+
return c.json({ ok: true, message: localSourcebookPublicationMessage(submission), statusCheck: localSourcebookStatusCheck(submission), submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(submission.websiteUrl), billing: publicListingWriteBilling(billing) }, 202);
|
|
24962
24989
|
} catch (error) {
|
|
24963
24990
|
if (billing) await refundListingWrite(billing, "Local Sourcebook refresh failed before persistence.").catch(() => null);
|
|
24964
24991
|
return c.json({ error: "moderated_listing", message: error instanceof Error ? error.message : String(error) }, 409);
|
|
@@ -44176,6 +44203,7 @@ function connectedToolPolicyOrThrow(registry, toolName) {
|
|
|
44176
44203
|
// src/api/main-nango-transport.ts
|
|
44177
44204
|
var DEFAULT_NANGO_MCP_URL = "https://api.nango.dev/mcp";
|
|
44178
44205
|
var NANGO_TIMEOUT_MS = 2e4;
|
|
44206
|
+
var NANGO_TOOL_CALL_TIMEOUT_MS = 24e4;
|
|
44179
44207
|
var NANGO_CONNECTION_PAGE_SIZE = 100;
|
|
44180
44208
|
var NANGO_CONNECTION_MAX_PAGES = 20;
|
|
44181
44209
|
var PROVIDER_IDENTITY_RETRY_MS = 6 * 60 * 60 * 1e3;
|
|
@@ -44214,6 +44242,15 @@ function retryAfterMsFromText(value) {
|
|
|
44214
44242
|
function normalizeNangoClientError(error) {
|
|
44215
44243
|
if (error instanceof MainNangoTransportError) return error;
|
|
44216
44244
|
const detail = nangoClientErrorText(error);
|
|
44245
|
+
const structured = error && typeof error === "object" ? error : null;
|
|
44246
|
+
if (structured?.code === -32001 || structured?.name === "RequestTimeout" || /Request timed out|RequestTimeout|Maximum total timeout exceeded/i.test(detail)) {
|
|
44247
|
+
return new MainNangoTransportError(
|
|
44248
|
+
"The connected service operation timed out before returning a result. Retry failed items or use a smaller batch.",
|
|
44249
|
+
503,
|
|
44250
|
+
"mcp_request_timeout",
|
|
44251
|
+
true
|
|
44252
|
+
);
|
|
44253
|
+
}
|
|
44217
44254
|
if (/SERVICE_DISABLED|accessNotConfigured/i.test(detail)) {
|
|
44218
44255
|
return new MainNangoTransportError(
|
|
44219
44256
|
"The provider API required by this connection is disabled. Enable it in the provider project, wait for propagation, then retry.",
|
|
@@ -44244,6 +44281,12 @@ function normalizeNangoClientError(error) {
|
|
|
44244
44281
|
}
|
|
44245
44282
|
return new MainNangoTransportError("The service connection is temporarily unavailable.", 503, "connection_transport_unavailable");
|
|
44246
44283
|
}
|
|
44284
|
+
async function callNangoToolWithBudget(client2, tool, input) {
|
|
44285
|
+
return client2.callTool(
|
|
44286
|
+
{ name: tool, arguments: input },
|
|
44287
|
+
{ timeout: NANGO_TOOL_CALL_TIMEOUT_MS }
|
|
44288
|
+
);
|
|
44289
|
+
}
|
|
44247
44290
|
function asRecord(value) {
|
|
44248
44291
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
44249
44292
|
}
|
|
@@ -44703,7 +44746,7 @@ async function callNangoToolDirect(args) {
|
|
|
44703
44746
|
let result;
|
|
44704
44747
|
let providerError;
|
|
44705
44748
|
try {
|
|
44706
|
-
result = await withNangoClient(connection, (client2) => client2
|
|
44749
|
+
result = await withNangoClient(connection, (client2) => callNangoToolWithBudget(client2, args.tool, args.input));
|
|
44707
44750
|
} catch (error) {
|
|
44708
44751
|
providerError = error;
|
|
44709
44752
|
}
|