mcp-scraper 0.73.1 → 0.73.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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to MCP Scraper are documented here. The format is based on [
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.73.2] - 2026-08-28
8
+
9
+ ### Fixed
10
+
11
+ - Normalized every PostgreSQL-backed Journey timestamp to RFC 3339 at the report boundary, so confirmed totals, enhanced journeys, session chronology, and candidate-review dates satisfy the generated Web contract instead of surfacing a false unavailable state.
12
+
7
13
  ## [0.73.1] - 2026-08-28
8
14
 
9
15
  ### Fixed
@@ -1316,7 +1322,8 @@ All notable changes to MCP Scraper are documented here. The format is based on [
1316
1322
  - Write actions remain unavailable until the account owner explicitly enables them.
1317
1323
  - Provider-specific connection data is normalized into one agent-facing contract.
1318
1324
 
1319
- [Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.73.1...HEAD
1325
+ [Unreleased]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.73.2...HEAD
1326
+ [0.73.2]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.73.1...v0.73.2
1320
1327
  [0.73.1]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.73.0...v0.73.1
1321
1328
  [0.73.0]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.72.7...v0.73.0
1322
1329
  [0.72.7]: https://github.com/VilovietaSEO/mcp-scraper/compare/v0.72.6...v0.72.7
package/README.md CHANGED
@@ -173,7 +173,7 @@ Build the branded one-click bundle:
173
173
  npm run build:mcpb
174
174
  ```
175
175
 
176
- 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.73.1`, SHA-256 `6d28c003fa95efba8867529ea8b9546e1213bbbe0575f03342b8bbe054535550`). 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.
176
+ 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.73.2`, SHA-256 `427b5b11320d575eee064d4b9bc2b1995155439bb9ce669eae066a249807e70a`). 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.
177
177
 
178
178
  The MCPB install exposes every tool — web-intelligence plus all `browser_*` tools — through the one `mcp-scraper` server.
179
179
 
@@ -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-663CRTGY.js"),
20
+ import("../server-4DZD6ACE.js"),
21
21
  import("../worker-CBK5DWEE.js"),
22
22
  import("../db-566MOHHD.js")
23
23
  ]);
@@ -13,7 +13,7 @@ import "../chunk-VXLU74YZ.js";
13
13
  import "../chunk-GGZEC22A.js";
14
14
  import {
15
15
  PACKAGE_VERSION
16
- } from "../chunk-NLPFY2IF.js";
16
+ } from "../chunk-Q7OPT73D.js";
17
17
 
18
18
  // src/cli/human-cli.ts
19
19
  import { Command } from "commander";
@@ -4,7 +4,7 @@ import {
4
4
  } from "../chunk-Q2J23DHY.js";
5
5
  import {
6
6
  PACKAGE_VERSION
7
- } from "../chunk-NLPFY2IF.js";
7
+ } from "../chunk-Q7OPT73D.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;
@@ -13,7 +13,7 @@ import {
13
13
  registerScheduledResultsMcpTools,
14
14
  registerSerpIntelligenceCaptureTools,
15
15
  resolveDeploymentProfile
16
- } from "../chunk-G75QXTBE.js";
16
+ } from "../chunk-ODPUNZDK.js";
17
17
  import "../chunk-PGJQDMC2.js";
18
18
  import "../chunk-T3MZISOF.js";
19
19
  import "../chunk-7RQULQF3.js";
@@ -26,7 +26,7 @@ import "../chunk-VXLU74YZ.js";
26
26
  import "../chunk-GGZEC22A.js";
27
27
  import {
28
28
  PACKAGE_VERSION
29
- } from "../chunk-NLPFY2IF.js";
29
+ } from "../chunk-Q7OPT73D.js";
30
30
  import "../chunk-DNM65UCK.js";
31
31
  import "../chunk-EQJRPDUS.js";
32
32
  import "../chunk-WEFPBAAG.js";
@@ -32,7 +32,7 @@ import {
32
32
  } from "./chunk-VXLU74YZ.js";
33
33
  import {
34
34
  PACKAGE_VERSION
35
- } from "./chunk-NLPFY2IF.js";
35
+ } from "./chunk-Q7OPT73D.js";
36
36
  import {
37
37
  createPrivateArtifact,
38
38
  privateArtifactOwnerId,
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var PACKAGE_VERSION = "0.73.1";
2
+ var PACKAGE_VERSION = "0.73.2";
3
3
 
4
4
  export {
5
5
  PACKAGE_VERSION
@@ -280,7 +280,7 @@ import {
280
280
  resolveDeploymentProfile,
281
281
  resolveLocalSourcebookSchemaType,
282
282
  transcribeMediaUrl
283
- } from "./chunk-G75QXTBE.js";
283
+ } from "./chunk-ODPUNZDK.js";
284
284
  import {
285
285
  auditImageUrls,
286
286
  auditImages,
@@ -345,7 +345,7 @@ import {
345
345
  } from "./chunk-GGZEC22A.js";
346
346
  import {
347
347
  PACKAGE_VERSION
348
- } from "./chunk-NLPFY2IF.js";
348
+ } from "./chunk-Q7OPT73D.js";
349
349
  import {
350
350
  SITE_EXTRACT_ARTIFACT_PREFIX,
351
351
  abandonExtractSettlement,
@@ -34541,6 +34541,14 @@ function nullableNumber(value) {
34541
34541
  const number = Number(value);
34542
34542
  return Number.isFinite(number) ? number : null;
34543
34543
  }
34544
+ function isoTimestamp(value) {
34545
+ const timestamp3 = value instanceof Date ? value : new Date(value);
34546
+ if (!Number.isFinite(timestamp3.getTime())) throw new Error("analytics_timestamp_invalid");
34547
+ return timestamp3.toISOString();
34548
+ }
34549
+ function nullableIsoTimestamp(value) {
34550
+ return value === null ? null : isoTimestamp(value);
34551
+ }
34544
34552
  function page(siteId, rows, limit, map) {
34545
34553
  const hasNextPage = rows.length > limit;
34546
34554
  const visible = rows.slice(0, limit);
@@ -34607,16 +34615,16 @@ async function analyticsSessions(input, db = getAnalyticsPool()) {
34607
34615
  input.eventName?.slice(0, 160) ?? null,
34608
34616
  limit + 1
34609
34617
  ]);
34610
- const rows = result2.rows.map((row) => ({ ...row, _cursorAt: row.started_at, _cursorId: row.internal_id }));
34618
+ const rows = result2.rows.map((row) => ({ ...row, _cursorAt: isoTimestamp(row.started_at), _cursorId: row.internal_id }));
34611
34619
  return page(input.siteId, rows, limit, (row) => ({
34612
34620
  sessionRef: createAnalyticsReportReference("session", input.siteId, row.internal_id),
34613
34621
  visitorRef: createAnalyticsReportReference("visitor", input.siteId, `visitor:${row.visitor_hmac}`),
34614
34622
  personRef: row.person_id ? createAnalyticsReportReference("person", input.siteId, row.person_id) : null,
34615
34623
  returning: row.session_number > 1,
34616
34624
  sessionNumber: row.session_number,
34617
- startedAt: row.started_at,
34618
- lastActiveAt: row.last_active_at,
34619
- endedAt: row.ended_at,
34625
+ startedAt: isoTimestamp(row.started_at),
34626
+ lastActiveAt: isoTimestamp(row.last_active_at),
34627
+ endedAt: nullableIsoTimestamp(row.ended_at),
34620
34628
  durationMs: nullableNumber(row.duration_ms),
34621
34629
  landingPath: row.landing_path,
34622
34630
  exitPath: row.exit_path,
@@ -34663,7 +34671,7 @@ async function analyticsVisitors(input, db = getAnalyticsPool()) {
34663
34671
  input.converted ?? null,
34664
34672
  limit + 1
34665
34673
  ]);
34666
- const rows = result2.rows.map((row) => ({ ...row, _cursorAt: row.last_seen_at, _cursorId: row.last_session_id }));
34674
+ const rows = result2.rows.map((row) => ({ ...row, _cursorAt: isoTimestamp(row.last_seen_at), _cursorId: row.last_session_id }));
34667
34675
  return page(input.siteId, rows, limit, (row) => ({
34668
34676
  visitorRef: createAnalyticsReportReference(
34669
34677
  "visitor",
@@ -34674,8 +34682,8 @@ async function analyticsVisitors(input, db = getAnalyticsPool()) {
34674
34682
  known: Boolean(row.person_id),
34675
34683
  returning: row.session_count > 1,
34676
34684
  sessions: row.session_count,
34677
- firstSeenAt: row.first_seen_at,
34678
- lastSeenAt: row.last_seen_at,
34685
+ firstSeenAt: isoTimestamp(row.first_seen_at),
34686
+ lastSeenAt: isoTimestamp(row.last_seen_at),
34679
34687
  durationMs: nullableNumber(row.duration_ms),
34680
34688
  pages: row.pageview_count,
34681
34689
  events: row.event_count,
@@ -34917,9 +34925,9 @@ async function analyticsSessionTimeline(input, db = getAnalyticsPool()) {
34917
34925
  LEFT JOIN first_touch f ON f.session_id=s.session_hmac LEFT JOIN conversion_stats c ON c.session_id=s.session_hmac
34918
34926
  ORDER BY s.started_at DESC,s.id DESC LIMIT 50`, [...subjectValues])
34919
34927
  ]);
34920
- const rows = result2.rows.map((row) => ({ ...row, _cursorAt: row.occurred_at, _cursorId: row.stable_id }));
34928
+ const rows = result2.rows.map((row) => ({ ...row, _cursorAt: isoTimestamp(row.occurred_at), _cursorId: row.stable_id }));
34921
34929
  const timeline = page(input.siteId, rows, limit, (row) => ({
34922
- occurredAt: row.occurred_at,
34930
+ occurredAt: isoTimestamp(row.occurred_at),
34923
34931
  type: row.entry_type,
34924
34932
  name: row.name,
34925
34933
  path: row.path,
@@ -34982,8 +34990,8 @@ async function analyticsSessionTimeline(input, db = getAnalyticsPool()) {
34982
34990
  })),
34983
34991
  sessions: sessionsResult.rows.map((row) => ({
34984
34992
  sessionRef: createAnalyticsReportReference("session", input.siteId, row.internal_id),
34985
- startedAt: row.started_at,
34986
- endedAt: row.ended_at,
34993
+ startedAt: isoTimestamp(row.started_at),
34994
+ endedAt: nullableIsoTimestamp(row.ended_at),
34987
34995
  durationMs: nullableNumber(row.duration_ms),
34988
34996
  pageviews: Number(row.pageviews),
34989
34997
  events: Number(row.events),
@@ -35035,12 +35043,12 @@ async function analyticsConfirmedJourneys(input, db = getAnalyticsPool()) {
35035
35043
  cursor?.id ?? null,
35036
35044
  limit + 1
35037
35045
  ]);
35038
- const rows = result2.rows.map((row) => ({ ...row, _cursorAt: row.last_seen_at, _cursorId: row.person_id }));
35046
+ const rows = result2.rows.map((row) => ({ ...row, _cursorAt: isoTimestamp(row.last_seen_at), _cursorId: row.person_id }));
35039
35047
  const resultPage = page(input.siteId, rows, limit, (row) => ({
35040
35048
  journeyTier: "confirmed",
35041
35049
  personRef: createAnalyticsReportReference("person", input.siteId, row.person_id),
35042
- firstSeenAt: row.first_seen_at,
35043
- lastSeenAt: row.last_seen_at,
35050
+ firstSeenAt: isoTimestamp(row.first_seen_at),
35051
+ lastSeenAt: isoTimestamp(row.last_seen_at),
35044
35052
  sessions: row.session_count,
35045
35053
  events: row.event_count,
35046
35054
  conversions: row.conversion_count,
@@ -35113,7 +35121,7 @@ async function analyticsBestGuessJourneys(input, db = getAnalyticsPool()) {
35113
35121
  cursor?.id ?? null,
35114
35122
  limit + 1
35115
35123
  ]);
35116
- const rows = result2.rows.map((row) => ({ ...row, _cursorAt: row.updated_at, _cursorId: row.association_id }));
35124
+ const rows = result2.rows.map((row) => ({ ...row, _cursorAt: isoTimestamp(row.updated_at), _cursorId: row.association_id }));
35117
35125
  const resultPage = page(input.siteId, rows, limit, (row) => ({
35118
35126
  journeyTier: "candidate_assisted",
35119
35127
  inferenceRef: createAnalyticsReportReference("candidate", input.siteId, row.association_id),
@@ -35134,7 +35142,7 @@ async function analyticsBestGuessJourneys(input, db = getAnalyticsPool()) {
35134
35142
  modelVersion: row.model_version,
35135
35143
  featureClasses: row.feature_kinds,
35136
35144
  coverage: row.inferred_sessions > 0 ? "incremental_sessions_available" : "no_incremental_sessions",
35137
- expiresAt: row.expires_at,
35145
+ expiresAt: isoTimestamp(row.expires_at),
35138
35146
  provenance: "consented_high_confidence_candidate_association"
35139
35147
  }));
35140
35148
  return { journeyTier: "candidate_assisted", totalsAreSeparated: true, ...resultPage };
@@ -35162,15 +35170,15 @@ async function analyticsInferenceReview(input, db = getAnalyticsPool()) {
35162
35170
  cursor?.id ?? null,
35163
35171
  limit + 1
35164
35172
  ]);
35165
- const rows = result2.rows.map((row) => ({ ...row, _cursorAt: row.updated_at, _cursorId: row.association_id }));
35173
+ const rows = result2.rows.map((row) => ({ ...row, _cursorAt: isoTimestamp(row.updated_at), _cursorId: row.association_id }));
35166
35174
  return page(input.siteId, rows, limit, (row) => ({
35167
35175
  inferenceRef: createAnalyticsReportReference("candidate", input.siteId, row.association_id),
35168
35176
  confidenceBand: row.confidence_band,
35169
35177
  modelVersion: row.model_version,
35170
35178
  featureClasses: row.feature_kinds,
35171
- firstObservedAt: row.first_observed_at,
35172
- lastObservedAt: row.last_observed_at,
35173
- expiresAt: row.expires_at,
35179
+ firstObservedAt: isoTimestamp(row.first_observed_at),
35180
+ lastObservedAt: isoTimestamp(row.last_observed_at),
35181
+ expiresAt: isoTimestamp(row.expires_at),
35174
35182
  action: "diagnostic_only",
35175
35183
  eligibleForConfirmedMetrics: false,
35176
35184
  eligibleForCrmOrActivation: false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-scraper",
3
- "version": "0.73.1",
3
+ "version": "0.73.2",
4
4
  "description": "MCP server for MCP Scraper web intelligence tools",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",